From 22a91d18b8e94f36a194f1943ad21721c1aaec8b Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Mon, 27 Nov 2023 18:30:27 +0000 Subject: [PATCH] C++: Make the sequence container classes public. --- .../models/implementations/StdContainer.qll | 75 +++++++++++++++++-- .../cpp/models/implementations/StdString.qll | 4 +- 2 files changed, 71 insertions(+), 8 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/StdContainer.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/StdContainer.qll index 9d74f4ac051..1fb42010caf 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/StdContainer.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/StdContainer.qll @@ -123,7 +123,7 @@ private class StdSequenceContainerData extends TaintFunction { /** * The standard container functions `push_back` and `push_front`. */ -private class StdSequenceContainerPush extends TaintFunction { +class StdSequenceContainerPush extends MemberFunction { StdSequenceContainerPush() { this.getClassAndName("push_back") instanceof Vector or this.getClassAndName(["push_back", "push_front"]) instanceof Deque or @@ -131,6 +131,17 @@ private class StdSequenceContainerPush extends TaintFunction { this.getClassAndName(["push_back", "push_front"]) instanceof List } + /** + * Gets the index of a parameter to this function that is a reference to the + * value type of the container. + */ + int getAValueTypeParameterIndex() { + this.getParameter(result).getUnspecifiedType().(ReferenceType).getBaseType() = + this.getDeclaringType().getTemplateArgument(0).(Type).getUnspecifiedType() // i.e. the `T` of this `std::vector` + } +} + +private class StdSequenceContainerPushModel extends StdSequenceContainerPush, TaintFunction { override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { // flow from parameter to qualifier input.isParameterDeref(0) and @@ -160,7 +171,7 @@ private class StdSequenceContainerFrontBack extends TaintFunction { /** * The standard container functions `insert` and `insert_after`. */ -private class StdSequenceContainerInsert extends TaintFunction { +class StdSequenceContainerInsert extends MemberFunction { StdSequenceContainerInsert() { this.getClassAndName("insert") instanceof Deque or this.getClassAndName("insert") instanceof List or @@ -181,7 +192,9 @@ private class StdSequenceContainerInsert extends TaintFunction { * Gets the index of a parameter to this function that is an iterator. */ int getAnIteratorParameterIndex() { this.getParameter(result).getType() instanceof Iterator } +} +private class StdSequenceContainerInsertModel extends StdSequenceContainerInsert, TaintFunction { override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { // flow from parameter to container itself (qualifier) and return value ( @@ -253,11 +266,28 @@ private class StdSequenceContainerAt extends TaintFunction { } /** - * The standard vector `emplace` function. + * The standard `emplace` function. */ -class StdVectorEmplace extends TaintFunction { - StdVectorEmplace() { this.getClassAndName("emplace") instanceof Vector } +class StdSequenceEmplace extends MemberFunction { + StdSequenceEmplace() { + this.getClassAndName("emplace") instanceof Vector + or + this.getClassAndName("emplace") instanceof List + or + this.getClassAndName("emplace") instanceof Deque + } + /** + * Gets the index of a parameter to this function that is a reference to the + * value type of the container. + */ + int getAValueTypeParameterIndex() { + this.getParameter(result).getUnspecifiedType().(ReferenceType).getBaseType() = + this.getDeclaringType().getTemplateArgument(0).(Type).getUnspecifiedType() // i.e. the `T` of this `std::vector` + } +} + +private class StdSequenceEmplaceModel extends StdSequenceEmplace, TaintFunction { override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { // flow from any parameter except the position iterator to qualifier and return value // (here we assume taint flow from any constructor parameter to the constructed object) @@ -269,12 +299,36 @@ class StdVectorEmplace extends TaintFunction { } } +/** + * The standard vector `emplace` function. + */ +class StdVectorEmplace extends StdSequenceEmplace { + StdVectorEmplace() { this.getDeclaringType() instanceof Vector } +} + /** * The standard vector `emplace_back` function. */ -class StdVectorEmplaceBack extends TaintFunction { - StdVectorEmplaceBack() { this.getClassAndName("emplace_back") instanceof Vector } +class StdSequenceEmplaceBack extends MemberFunction { + StdSequenceEmplaceBack() { + this.getClassAndName("emplace_back") instanceof Vector + or + this.getClassAndName("emplace_back") instanceof List + or + this.getClassAndName("emplace_back") instanceof Deque + } + /** + * Gets the index of a parameter to this function that is a reference to the + * value type of the container. + */ + int getAValueTypeParameterIndex() { + this.getParameter(result).getUnspecifiedType().(ReferenceType).getBaseType() = + this.getDeclaringType().getTemplateArgument(0).(Type).getUnspecifiedType() // i.e. the `T` of this `std::vector` + } +} + +private class StdSequenceEmplaceBackModel extends StdSequenceEmplaceBack, TaintFunction { override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { // flow from any parameter to qualifier // (here we assume taint flow from any constructor parameter to the constructed object) @@ -282,3 +336,10 @@ class StdVectorEmplaceBack extends TaintFunction { output.isQualifierObject() } } + +/** + * The standard vector `emplace_back` function. + */ +class StdVectorEmplaceBack extends StdSequenceEmplaceBack { + StdVectorEmplaceBack() { this.getDeclaringType() instanceof Vector } +} diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/StdString.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/StdString.qll index 225422b9a46..90cc90606d3 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/StdString.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/StdString.qll @@ -99,9 +99,11 @@ private class StdStringConstructor extends Constructor, StdStringTaintFunction { /** * The `std::string` function `c_str`. */ -private class StdStringCStr extends StdStringTaintFunction { +class StdStringCStr extends MemberFunction { StdStringCStr() { this.getClassAndName("c_str") instanceof StdBasicString } +} +private class StdStringCStrModel extends StdStringCStr, StdStringTaintFunction { override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { // flow from string itself (qualifier) to return value input.isQualifierObject() and