CPP: Handle %s/%c/%S/%C correctly on non-MS platforms.

This commit is contained in:
Geoffrey White
2019-03-13 12:05:47 +00:00
parent 648cdbab6c
commit 975a0bbf0d
13 changed files with 50 additions and 44 deletions

View File

@@ -675,7 +675,7 @@ class FormatLiteral extends Literal {
* Gets the char type required by the nth conversion specifier.
* - in the base case this is the default for the formatting function
* (e.g. `char` for `printf`, `wchar_t` for `wprintf`).
* - the `%S` format character reverses wideness.
* - the `%C` format character reverses wideness on some platforms.
* - the size prefixes 'l'/'w' and 'h' override the type character
* to wide or single-byte characters respectively.
*/
@@ -722,7 +722,7 @@ class FormatLiteral extends Literal {
* Gets the string type required by the nth conversion specifier.
* - in the base case this is the default for the formatting function
* (e.g. `char` for `printf`, `wchar_t` for `wprintf`).
* - the `%S` format character reverses wideness.
* - the `%S` format character reverses wideness on some platforms.
* - the size prefixes 'l'/'w' and 'h' override the type character
* to wide or single-byte characters respectively.
*/

View File

@@ -22,7 +22,7 @@ private Type stripTopLevelSpecifiersOnly(Type t) {
*/
Type getAFormatterWideType() {
exists(FormattingFunction ff |
result = stripTopLevelSpecifiersOnly(ff.getDefaultCharType()) and
result = stripTopLevelSpecifiersOnly(ff.getFormatCharType()) and
result.getSize() != 1
)
}
@@ -46,6 +46,14 @@ abstract class FormattingFunction extends Function {
/** Gets the position at which the format parameter occurs. */
abstract int getFormatParameterIndex();
/**
* Holds if this `FormattingFunction` is in a context that supports
* Microsoft rules and extensions.
*/
predicate isMicrosoft() {
getFile().compiledAsMicrosoft()
}
/**
* Holds if the default meaning of `%s` is a `wchar_t *`, rather than
* a `char *` (either way, `%S` will have the opposite meaning).
@@ -71,12 +79,13 @@ abstract class FormattingFunction extends Function {
* `char` or `wchar_t`.
*/
Type getDefaultCharType() {
result =
stripTopLevelSpecifiersOnly(
stripTopLevelSpecifiersOnly(
getParameter(getFormatParameterIndex()).getType().getUnderlyingType()
).(PointerType).getBaseType()
)
(
isMicrosoft() and
result = getFormatCharType()
) or (
not isMicrosoft() and
result instanceof PlainCharType
)
}
/**