diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Gets.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Gets.qll index 1c227684e4f..732958675dc 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Gets.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Gets.qll @@ -110,3 +110,21 @@ private class GetsFunction extends DataFlowFunction, ArrayFunction, AliasFunctio override predicate hasArrayOutput(int bufParam) { bufParam = 0 } } + +/** + * A model for `getc` and similar functions that are flow sources. + */ +private class GetcSource extends SourceModelCsv { + override predicate row(string row) { + row = + [ + ";;false;getc;;;ReturnValue;remote", ";;false;getwc;;;ReturnValue;remote", + ";;false;_getc_nolock;;;ReturnValue;remote", ";;false;_getwc_nolock;;;ReturnValue;remote", + ";;false;getch;;;ReturnValue;local", ";;false;_getch;;;ReturnValue;local", + ";;false;_getwch;;;ReturnValue;local", ";;false;_getch_nolock;;;ReturnValue;local", + ";;false;_getwch_nolock;;;ReturnValue;local", ";;false;getchar;;;ReturnValue;local", + ";;false;getwchar;;;ReturnValue;local", ";;false;_getchar_nolock;;;ReturnValue;local", + ";;false;_getwchar_nolock;;;ReturnValue;local", + ] + } +} diff --git a/cpp/ql/test/library-tests/dataflow/source-sink-tests/local-flow.expected b/cpp/ql/test/library-tests/dataflow/source-sink-tests/local-flow.expected index 48de9172b36..8ec8033d086 100644 --- a/cpp/ql/test/library-tests/dataflow/source-sink-tests/local-flow.expected +++ b/cpp/ql/test/library-tests/dataflow/source-sink-tests/local-flow.expected @@ -1,2 +1,2 @@ -failures testFailures +failures diff --git a/cpp/ql/test/library-tests/dataflow/source-sink-tests/sources-and-sinks.cpp b/cpp/ql/test/library-tests/dataflow/source-sink-tests/sources-and-sinks.cpp index 38c6b701f8a..68fe9ed015a 100644 --- a/cpp/ql/test/library-tests/dataflow/source-sink-tests/sources-and-sinks.cpp +++ b/cpp/ql/test/library-tests/dataflow/source-sink-tests/sources-and-sinks.cpp @@ -70,18 +70,18 @@ int _getchar_nolock(void); wint_t _getwchar_nolock(void); void test_getchar(FILE *stream) { - int a = getc(stream); // $ MISSING: remote_source - wint_t b = getwc(stream); // $ MISSING: remote_source - int c = _getc_nolock(stream); // $ MISSING: remote_source - wint_t d = _getwc_nolock(stream); // $ MISSING: remote_source + int a = getc(stream); // $ remote_source + wint_t b = getwc(stream); // $ remote_source + int c = _getc_nolock(stream); // $ remote_source + wint_t d = _getwc_nolock(stream); // $ remote_source - int e = getch(); // $ MISSING: local_source - int f = _getch(); // $ MISSING: local_source - wint_t g = _getwch(); // $ MISSING: local_source - int h = _getch_nolock(); // $ MISSING: local_source - wint_t i = _getwch_nolock(); // $ MISSING: local_source - int j = getchar(); // $ MISSING: local_source - wint_t k = getwchar(); // $ MISSING: local_source - int l = _getchar_nolock(); // $ MISSING: local_source - wint_t m = _getwchar_nolock(); // $ MISSING: local_source + int e = getch(); // $ local_source + int f = _getch(); // $ local_source + wint_t g = _getwch(); // $ local_source + int h = _getch_nolock(); // $ local_source + wint_t i = _getwch_nolock(); // $ local_source + int j = getchar(); // $ local_source + wint_t k = getwchar(); // $ local_source + int l = _getchar_nolock(); // $ local_source + wint_t m = _getwchar_nolock(); // $ local_source }