CPP: Make getAFormatterWideType more general and move it into FormattingFunction.qll.

This commit is contained in:
Geoffrey White
2018-09-10 18:41:12 +01:00
parent 580471ab1d
commit 2841897e3a
5 changed files with 25 additions and 30 deletions

View File

@@ -28,25 +28,6 @@ class AttributeFormattingFunction extends FormattingFunction {
}
}
/**
* A type that is used as a format string by a wide variadic formatter such as
* `vwprintf` or by a user-defined formatting function with the GNU `format`
* attribute.
*/
Type getAFormatterWideType() {
exists(TopLevelFunction f, int formatParamIndex |
primitiveVariadicFormatter(f, formatParamIndex, true) and
result = f.getParameter(formatParamIndex).getType().getUnspecifiedType() and
result.(PointerType).getBaseType().getSize() != 1 and
f.hasDefinition()
)
or
exists(AttributeFormattingFunction f, int formatParamIndex |
result = f.getParameter(formatParamIndex).getType().getUnspecifiedType() and
result.(PointerType).getBaseType().getSize() != 1
)
}
/**
* A standard function such as `vprintf` that has a format parameter
* and a variable argument list of type `va_arg`.

View File

@@ -7,6 +7,27 @@
*/
import semmle.code.cpp.Function
private Type stripTopLevelSpecifiersOnly(Type t) {
(
result = stripTopLevelSpecifiersOnly(t.(SpecifiedType).getBaseType())
) or (
result = t and
not t instanceof SpecifiedType
)
}
/**
* A type that is used as a format string by any formatting function.
*/
Type getAFormatterWideType() {
exists(FormattingFunction ff, Type t |
t = stripTopLevelSpecifiersOnly(ff.getDefaultCharType()) and
t.getSize() != 1 and
result.(PointerType).getBaseType() = t
)
}
/**
* A type that is used as a format string by any formatting function, or `wchar_t` if
* there is none.
@@ -19,15 +40,6 @@ private Type getAFormatterWideTypeOrDefault() {
)
}
private Type stripTopLevelSpecifiersOnly(Type t) {
(
result = stripTopLevelSpecifiersOnly(t.(SpecifiedType).getBaseType())
) or (
result = t and
not t instanceof SpecifiedType
)
}
/**
* A standard library function that uses a `printf`-like formatting string.
*/

View File

@@ -1,7 +1,9 @@
| tests.cpp:18:15:18:22 | Hello | This argument should be of type 'char *' but is of type 'char16_t *' |
| tests.cpp:19:15:19:22 | Hello | This argument should be of type 'char *' but is of type 'wchar_t *' |
| tests.cpp:21:15:21:21 | Hello | This argument should be of type 'char16_t *' but is of type 'char *' |
| tests.cpp:21:15:21:21 | Hello | This argument should be of type 'wchar_t *' but is of type 'char *' |
| tests.cpp:22:15:22:22 | Hello | This argument should be of type 'wchar_t *' but is of type 'char16_t *' |
| tests.cpp:23:15:23:22 | Hello | This argument should be of type 'char16_t *' but is of type 'wchar_t *' |
| tests.cpp:25:17:25:23 | Hello | This argument should be of type 'wchar_t *' but is of type 'char *' |
| tests.cpp:26:17:26:24 | Hello | This argument should be of type 'wchar_t *' but is of type 'char16_t *' |
| tests.cpp:30:17:30:24 | Hello | This argument should be of type 'char *' but is of type 'char16_t *' |

View File

@@ -1,3 +1,3 @@
| tests.cpp:8:5:8:10 | printf | char | wchar_t | wchar_t |
| tests.cpp:8:5:8:10 | printf | char | char16_t, wchar_t | char16_t, wchar_t |
| tests.cpp:9:5:9:11 | wprintf | wchar_t | char | wchar_t |
| tests.cpp:10:5:10:12 | swprintf | char16_t | char | char16_t |

View File

@@ -20,7 +20,7 @@ void tests() {
printf("%S", "Hello"); // BAD: expecting wchar_t or char16_t
printf("%S", u"Hello"); // GOOD [FALSE POSITIVE]
printf("%S", L"Hello"); // GOOD
printf("%S", L"Hello"); // GOOD [FALSE POSITIVE]
wprintf(L"%s", "Hello"); // BAD: expecting wchar_t
wprintf(L"%s", u"Hello"); // BAD: expecting wchar_t