C++: Share parameter logic in std::string model

This commit is contained in:
Jeroen Ketema
2022-11-11 08:30:22 +01:00
parent 23e29e993b
commit ba00a0f370

View File

@@ -16,21 +16,14 @@ private class StdBasicString extends ClassTemplateInstantiation {
} }
/** /**
* Additional model for `std::string` constructors that reference the character * A `std::string` function for which taint should be propagated.
* type of the container, or an iterator. For example construction from
* iterators:
* ```
* std::string b(a.begin(), a.end());
* ```
*/ */
private class StdStringConstructor extends Constructor, TaintFunction { abstract private class StdStringTaintFunction extends TaintFunction {
StdStringConstructor() { this.getDeclaringType() instanceof StdBasicString }
/** /**
* Gets the index of a parameter to this function that is a string (or * Gets the index of a parameter to this function that is a string (or
* character). * character).
*/ */
int getAStringParameterIndex() { final int getAStringParameterIndex() {
exists(Type paramType | paramType = this.getParameter(result).getUnspecifiedType() | exists(Type paramType | paramType = this.getParameter(result).getUnspecifiedType() |
// e.g. `std::basic_string::CharT *` // e.g. `std::basic_string::CharT *`
paramType instanceof PointerType paramType instanceof PointerType
@@ -41,15 +34,28 @@ private class StdStringConstructor extends Constructor, TaintFunction {
this.getDeclaringType().getTemplateArgument(2).(Type).getUnspecifiedType() this.getDeclaringType().getTemplateArgument(2).(Type).getUnspecifiedType()
or or
// i.e. `std::basic_string::CharT` // i.e. `std::basic_string::CharT`
this.getParameter(result).getUnspecifiedType() = paramType = this.getDeclaringType().getTemplateArgument(0).(Type).getUnspecifiedType()
this.getDeclaringType().getTemplateArgument(0).(Type).getUnspecifiedType()
) )
} }
/** /**
* Gets the index of a parameter to this function that is an iterator. * Gets the index of a parameter to this function that is an iterator.
*/ */
int getAnIteratorParameterIndex() { this.getParameter(result).getType() instanceof Iterator } final int getAnIteratorParameterIndex() {
this.getParameter(result).getType() instanceof Iterator
}
}
/**
* Additional model for `std::string` constructors that reference the character
* type of the container, or an iterator. For example construction from
* iterators:
* ```
* std::string b(a.begin(), a.end());
* ```
*/
private class StdStringConstructor extends Constructor, StdStringTaintFunction {
StdStringConstructor() { this.getDeclaringType() instanceof StdBasicString }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// taint flow from any parameter of the value type to the returned object // taint flow from any parameter of the value type to the returned object
@@ -68,7 +74,7 @@ private class StdStringConstructor extends Constructor, TaintFunction {
/** /**
* The `std::string` function `c_str`. * The `std::string` function `c_str`.
*/ */
private class StdStringCStr extends TaintFunction { private class StdStringCStr extends StdStringTaintFunction {
StdStringCStr() { this.getClassAndName("c_str") instanceof StdBasicString } StdStringCStr() { this.getClassAndName("c_str") instanceof StdBasicString }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
@@ -81,7 +87,7 @@ private class StdStringCStr extends TaintFunction {
/** /**
* The `std::string` function `data`. * The `std::string` function `data`.
*/ */
private class StdStringData extends TaintFunction { private class StdStringData extends StdStringTaintFunction {
StdStringData() { this.getClassAndName("data") instanceof StdBasicString } StdStringData() { this.getClassAndName("data") instanceof StdBasicString }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
@@ -99,7 +105,7 @@ private class StdStringData extends TaintFunction {
/** /**
* The `std::string` function `push_back`. * The `std::string` function `push_back`.
*/ */
private class StdStringPush extends TaintFunction { private class StdStringPush extends StdStringTaintFunction {
StdStringPush() { this.getClassAndName("push_back") instanceof StdBasicString } StdStringPush() { this.getClassAndName("push_back") instanceof StdBasicString }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
@@ -112,7 +118,7 @@ private class StdStringPush extends TaintFunction {
/** /**
* The `std::string` functions `front` and `back`. * The `std::string` functions `front` and `back`.
*/ */
private class StdStringFrontBack extends TaintFunction { private class StdStringFrontBack extends StdStringTaintFunction {
StdStringFrontBack() { this.getClassAndName(["front", "back"]) instanceof StdBasicString } StdStringFrontBack() { this.getClassAndName(["front", "back"]) instanceof StdBasicString }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
@@ -125,7 +131,7 @@ private class StdStringFrontBack extends TaintFunction {
/** /**
* The (non-member) `std::string` function `operator+`. * The (non-member) `std::string` function `operator+`.
*/ */
private class StdStringPlus extends TaintFunction { private class StdStringPlus extends StdStringTaintFunction {
StdStringPlus() { StdStringPlus() {
this.hasQualifiedName(["std", "bsl"], "operator+") and this.hasQualifiedName(["std", "bsl"], "operator+") and
this.getUnspecifiedType() instanceof StdBasicString this.getUnspecifiedType() instanceof StdBasicString
@@ -146,27 +152,11 @@ private class StdStringPlus extends TaintFunction {
* All of these functions combine the existing string with a new * All of these functions combine the existing string with a new
* string (or character) from one of the arguments. * string (or character) from one of the arguments.
*/ */
private class StdStringAppend extends TaintFunction { private class StdStringAppend extends StdStringTaintFunction {
StdStringAppend() { StdStringAppend() {
this.getClassAndName(["operator+=", "append", "replace"]) instanceof StdBasicString this.getClassAndName(["operator+=", "append", "replace"]) instanceof StdBasicString
} }
/**
* Gets the index of a parameter to this function that is a string (or
* character).
*/
int getAStringParameterIndex() {
this.getParameter(result).getType() instanceof PointerType or // e.g. `std::basic_string::CharT *`
this.getParameter(result).getType() instanceof ReferenceType or // e.g. `std::basic_string &`
this.getParameter(result).getUnspecifiedType() =
this.getDeclaringType().getTemplateArgument(0).(Type).getUnspecifiedType() // i.e. `std::basic_string::CharT`
}
/**
* Gets the index of a parameter to this function that is an iterator.
*/
int getAnIteratorParameterIndex() { this.getParameter(result).getType() instanceof Iterator }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// flow from string and parameter to string (qualifier) and return value // flow from string and parameter to string (qualifier) and return value
( (
@@ -189,26 +179,8 @@ private class StdStringAppend extends TaintFunction {
/** /**
* The `std::string` function `insert`. * The `std::string` function `insert`.
*/ */
private class StdStringInsert extends TaintFunction { private class StdStringInsert extends StdStringTaintFunction {
StdStringInsert() { StdStringInsert() { this.getClassAndName("insert") instanceof StdBasicString }
this.getClassAndName("insert") instanceof StdBasicString
}
/**
* Gets the index of a parameter to this function that is a string (or
* character).
*/
int getAStringParameterIndex() {
this.getParameter(result).getType() instanceof PointerType or // e.g. `std::basic_string::CharT *`
this.getParameter(result).getType() instanceof ReferenceType or // e.g. `std::basic_string &`
this.getParameter(result).getUnspecifiedType() =
this.getDeclaringType().getTemplateArgument(0).(Type).getUnspecifiedType() // i.e. `std::basic_string::CharT`
}
/**
* Gets the index of a parameter to this function that is an iterator.
*/
int getAnIteratorParameterIndex() { this.getParameter(result).getType() instanceof Iterator }
/** /**
* Holds if the return type is an iterator. * Holds if the return type is an iterator.
@@ -239,25 +211,9 @@ private class StdStringInsert extends TaintFunction {
/** /**
* The standard function `std::string.assign`. * The standard function `std::string.assign`.
*/ */
private class StdStringAssign extends TaintFunction { private class StdStringAssign extends StdStringTaintFunction {
StdStringAssign() { this.getClassAndName("assign") instanceof StdBasicString } StdStringAssign() { this.getClassAndName("assign") instanceof StdBasicString }
/**
* Gets the index of a parameter to this function that is a string (or
* character).
*/
int getAStringParameterIndex() {
this.getParameter(result).getType() instanceof PointerType or // e.g. `std::basic_string::CharT *`
this.getParameter(result).getType() instanceof ReferenceType or // e.g. `std::basic_string &`
this.getParameter(result).getUnspecifiedType() =
this.getDeclaringType().getTemplateArgument(0).(Type).getUnspecifiedType() // i.e. `std::basic_string::CharT`
}
/**
* Gets the index of a parameter to this function that is an iterator.
*/
int getAnIteratorParameterIndex() { this.getParameter(result).getType() instanceof Iterator }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// flow from parameter to string itself (qualifier) and return value // flow from parameter to string itself (qualifier) and return value
( (
@@ -279,7 +235,7 @@ private class StdStringAssign extends TaintFunction {
/** /**
* The standard function `std::string.copy`. * The standard function `std::string.copy`.
*/ */
private class StdStringCopy extends TaintFunction { private class StdStringCopy extends StdStringTaintFunction {
StdStringCopy() { this.getClassAndName("copy") instanceof StdBasicString } StdStringCopy() { this.getClassAndName("copy") instanceof StdBasicString }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
@@ -292,7 +248,7 @@ private class StdStringCopy extends TaintFunction {
/** /**
* The standard function `std::string.substr`. * The standard function `std::string.substr`.
*/ */
private class StdStringSubstr extends TaintFunction { private class StdStringSubstr extends StdStringTaintFunction {
StdStringSubstr() { this.getClassAndName("substr") instanceof StdBasicString } StdStringSubstr() { this.getClassAndName("substr") instanceof StdBasicString }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
@@ -305,7 +261,7 @@ private class StdStringSubstr extends TaintFunction {
/** /**
* The `std::string` functions `at` and `operator[]`. * The `std::string` functions `at` and `operator[]`.
*/ */
private class StdStringAt extends TaintFunction { private class StdStringAt extends StdStringTaintFunction {
StdStringAt() { this.getClassAndName(["at", "operator[]"]) instanceof StdBasicString } StdStringAt() { this.getClassAndName(["at", "operator[]"]) instanceof StdBasicString }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {