Skip to content

Commit e518976

Browse files
committed
C++: Restrict BDE conversion models to pointer instantiations
1 parent 57c92ea commit e518976

5 files changed

Lines changed: 163 additions & 19 deletions

File tree

‎cpp/ql/lib/ext/bdlde.model.yml‎

Lines changed: 0 additions & 18 deletions
This file was deleted.

‎cpp/ql/lib/semmle/code/cpp/models/Models.qll‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
private import implementations.Allocation
2+
private import implementations.Bdlde
23
private import implementations.Deallocation
34
private import implementations.Fopen
45
private import implementations.Fread
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/**
2+
* Models direct pointer-buffer conversions in the BDE bdlde library.
3+
* See https://github.com/bloomberg/bde/tree/ec310b87e008199ecbdbc00a0b0264a53d806a0a/groups/bdl/bdlde.
4+
*/
5+
6+
import semmle.code.cpp.models.interfaces.Taint
7+
8+
/** A conversion whose input and output iterators are pointers. */
9+
private class BdldePointerConversion extends TaintFunction {
10+
int beginIndex;
11+
12+
BdldePointerConversion() {
13+
this.hasName("convert") and
14+
this.getDeclaringType()
15+
.hasQualifiedName("BloombergLP::bdlde",
16+
["Base64Encoder", "Base64Decoder", "HexEncoder", "HexDecoder"]) and
17+
(
18+
this.getNumberOfParameters() = 3 and beginIndex = 1
19+
or
20+
this.getNumberOfParameters() = 6 and beginIndex = 3
21+
) and
22+
// Check instantiated types. A generic template signature would also match
23+
// iterator objects and replace their bodies with an inapplicable summary.
24+
this.getParameter(0).getUnspecifiedType() instanceof PointerType and
25+
this.getParameter(beginIndex).getUnspecifiedType() instanceof PointerType and
26+
this.getParameter(beginIndex + 1).getUnspecifiedType() instanceof PointerType
27+
}
28+
29+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
30+
input.isParameterDeref(beginIndex) and output.isParameterDeref(0)
31+
}
32+
}
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
#include "bdlde.h"
2+
3+
char source();
4+
void sink(char);
5+
6+
// Reduced iterator access bodies: the object instantiations must remain
7+
// analyzable rather than being replaced by pointer-buffer summaries.
8+
struct InputIterator {
9+
char value;
10+
char operator*() const { return value; }
11+
};
12+
13+
struct OutputIterator {
14+
OutputIterator &operator*() { return *this; }
15+
void operator=(char value) { sink(value); } // $ ir
16+
};
17+
18+
namespace BloombergLP {
19+
namespace bdlde {
20+
template <class OUT, class IN>
21+
int Base64Encoder::convert(OUT out, IN begin, IN end) {
22+
*out = *begin;
23+
return 0;
24+
}
25+
26+
template <class OUT, class IN>
27+
int Base64Encoder::convert(OUT out, int *numOut, int *numIn, IN begin, IN end, int limit) {
28+
*out = *begin;
29+
return 0;
30+
}
31+
template <class OUT, class IN>
32+
int Base64Decoder::convert(OUT out, IN begin, IN end) {
33+
*out = *begin;
34+
return 0;
35+
}
36+
37+
template <class OUT, class IN>
38+
int Base64Decoder::convert(OUT out, int *numOut, int *numIn, IN begin, IN end, int limit) {
39+
*out = *begin;
40+
return 0;
41+
}
42+
template <class OUT, class IN>
43+
int HexEncoder::convert(OUT out, IN begin, IN end) {
44+
*out = *begin;
45+
return 0;
46+
}
47+
48+
template <class OUT, class IN>
49+
int HexEncoder::convert(OUT out, int *numOut, int *numIn, IN begin, IN end, int limit) {
50+
*out = *begin;
51+
return 0;
52+
}
53+
template <class OUT, class IN>
54+
int HexDecoder::convert(OUT out, IN begin, IN end) {
55+
*out = *begin;
56+
return 0;
57+
}
58+
59+
template <class OUT, class IN>
60+
int HexDecoder::convert(OUT out, int *numOut, int *numIn, IN begin, IN end, int limit) {
61+
*out = *begin;
62+
return 0;
63+
}
64+
}
65+
}
66+
67+
void iteratorBase64Encoder() {
68+
BloombergLP::bdlde::Base64Encoder converter;
69+
InputIterator begin = {source()}, end = {0};
70+
char shortOutput[4] = {};
71+
converter.convert(shortOutput, begin, end);
72+
sink(shortOutput[0]); // $ ir
73+
int numOut = 0, numIn = 0;
74+
char longOutput[4] = {};
75+
converter.convert(longOutput, &numOut, &numIn, begin, end);
76+
sink(longOutput[0]); // $ ir
77+
}
78+
79+
void iteratorBase64Decoder() {
80+
BloombergLP::bdlde::Base64Decoder converter;
81+
InputIterator begin = {source()}, end = {0};
82+
char shortOutput[4] = {};
83+
converter.convert(shortOutput, begin, end);
84+
sink(shortOutput[0]); // $ ir
85+
int numOut = 0, numIn = 0;
86+
char longOutput[4] = {};
87+
converter.convert(longOutput, &numOut, &numIn, begin, end);
88+
sink(longOutput[0]); // $ ir
89+
}
90+
91+
void iteratorHexEncoder() {
92+
BloombergLP::bdlde::HexEncoder converter;
93+
InputIterator begin = {source()}, end = {0};
94+
char shortOutput[4] = {};
95+
converter.convert(shortOutput, begin, end);
96+
sink(shortOutput[0]); // $ ir
97+
int numOut = 0, numIn = 0;
98+
char longOutput[4] = {};
99+
converter.convert(longOutput, &numOut, &numIn, begin, end);
100+
sink(longOutput[0]); // $ ir
101+
}
102+
103+
void iteratorHexDecoder() {
104+
BloombergLP::bdlde::HexDecoder converter;
105+
InputIterator begin = {source()}, end = {0};
106+
char shortOutput[4] = {};
107+
converter.convert(shortOutput, begin, end);
108+
sink(shortOutput[0]); // $ ir
109+
int numOut = 0, numIn = 0;
110+
char longOutput[4] = {};
111+
converter.convert(longOutput, &numOut, &numIn, begin, end);
112+
sink(longOutput[0]); // $ ir
113+
}
114+
115+
template <class CONVERTER>
116+
void outputIterator() {
117+
CONVERTER converter;
118+
char input[] = {source()};
119+
OutputIterator out;
120+
converter.convert(out, input, input + 1);
121+
int numOut = 0, numIn = 0;
122+
converter.convert(out, &numOut, &numIn, input, input + 1);
123+
}
124+
125+
void testOutputIterators() {
126+
outputIterator<BloombergLP::bdlde::Base64Encoder>();
127+
outputIterator<BloombergLP::bdlde::Base64Decoder>();
128+
outputIterator<BloombergLP::bdlde::HexEncoder>();
129+
outputIterator<BloombergLP::bdlde::HexDecoder>();
130+
}

‎cpp/ql/test/library-tests/dataflow/external-models/validatemodels.expected‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1873,7 +1873,6 @@
18731873
| Dubious signature "(OTHERNAME *)" in summary model. |
18741874
| Dubious signature "(OTHERNAME **,const unsigned char **,long)" in summary model. |
18751875
| Dubious signature "(OTHERNAME *,OTHERNAME *)" in summary model. |
1876-
| Dubious signature "(OUT,int *,int *,IN,IN,int)" in summary model. |
18771876
| Dubious signature "(OperationConfig *)" in summary model. |
18781877
| Dubious signature "(OperationConfig *,HttpReq,HttpReq *)" in summary model. |
18791878
| Dubious signature "(OperationConfig *,const char *,tool_mime **,tool_mime **,bool)" in summary model. |

0 commit comments

Comments
 (0)