From 6de14caa4d36f6fd9d19a97987c8e1ef55004fc1 Mon Sep 17 00:00:00 2001 From: Mike Fairhurst Date: Thu, 3 Oct 2024 15:38:08 -0700 Subject: [PATCH 01/15] Implement Language4 package, banning obsolete language features. Many of the cases outlined in the amendment are covered by other rules. Add support for new cases where possible (was not possible for ID 3, storage class specifiers not at beginning of declaration, or ID 2, which is a feature of the implementation not determinable by static analysis), and reference existing rules in one comprehensive test for maximal clarity that those parts of rule 1-5 are indeed supported by our existing queries. --- .../RULE-1-5/CallToReallocWithSizeZero.ql | 24 +++++++ .../InvalidDefineOrUndefOfStdBoolMacro.ql | 31 +++++++++ .../UseOfObsoleteMacroAtomicVarInit.ql | 24 +++++++ .../CallToReallocWithSizeZero.expected | 1 + .../RULE-1-5/CallToReallocWithSizeZero.qlref | 1 + .../FunctionTypesNotInPrototypeForm.expected | 2 + .../FunctionTypesNotInPrototypeForm.qlref | 1 + ...nvalidDefineOrUndefOfStdBoolMacro.expected | 6 ++ .../InvalidDefineOrUndefOfStdBoolMacro.qlref | 1 + ...llocDeallocFunctionsOfStdlibhUsed.expected | 3 + ...ryAllocDeallocFunctionsOfStdlibhUsed.qlref | 1 + ...aticSpecifierObjectRedeclarationC.expected | 1 + ...gStaticSpecifierObjectRedeclarationC.qlref | 1 + ...rdLibraryInputoutputFunctionsUsed.expected | 3 + ...ndardLibraryInputoutputFunctionsUsed.qlref | 1 + .../UseOfObsoleteMacroAtomicVarInit.expected | 1 + .../UseOfObsoleteMacroAtomicVarInit.qlref | 1 + c/misra/test/rules/RULE-1-5/options | 1 + c/misra/test/rules/RULE-1-5/test.c | 63 +++++++++++++++++++ .../cpp/exclusions/c/Language4.qll | 61 ++++++++++++++++++ .../cpp/exclusions/c/RuleMetadata.qll | 3 + rule_packages/c/Language4.json | 47 ++++++++++++++ 22 files changed, 278 insertions(+) create mode 100644 c/misra/src/rules/RULE-1-5/CallToReallocWithSizeZero.ql create mode 100644 c/misra/src/rules/RULE-1-5/InvalidDefineOrUndefOfStdBoolMacro.ql create mode 100644 c/misra/src/rules/RULE-1-5/UseOfObsoleteMacroAtomicVarInit.ql create mode 100644 c/misra/test/rules/RULE-1-5/CallToReallocWithSizeZero.expected create mode 100644 c/misra/test/rules/RULE-1-5/CallToReallocWithSizeZero.qlref create mode 100644 c/misra/test/rules/RULE-1-5/FunctionTypesNotInPrototypeForm.expected create mode 100644 c/misra/test/rules/RULE-1-5/FunctionTypesNotInPrototypeForm.qlref create mode 100644 c/misra/test/rules/RULE-1-5/InvalidDefineOrUndefOfStdBoolMacro.expected create mode 100644 c/misra/test/rules/RULE-1-5/InvalidDefineOrUndefOfStdBoolMacro.qlref create mode 100644 c/misra/test/rules/RULE-1-5/MemoryAllocDeallocFunctionsOfStdlibhUsed.expected create mode 100644 c/misra/test/rules/RULE-1-5/MemoryAllocDeallocFunctionsOfStdlibhUsed.qlref create mode 100644 c/misra/test/rules/RULE-1-5/MissingStaticSpecifierObjectRedeclarationC.expected create mode 100644 c/misra/test/rules/RULE-1-5/MissingStaticSpecifierObjectRedeclarationC.qlref create mode 100644 c/misra/test/rules/RULE-1-5/StandardLibraryInputoutputFunctionsUsed.expected create mode 100644 c/misra/test/rules/RULE-1-5/StandardLibraryInputoutputFunctionsUsed.qlref create mode 100644 c/misra/test/rules/RULE-1-5/UseOfObsoleteMacroAtomicVarInit.expected create mode 100644 c/misra/test/rules/RULE-1-5/UseOfObsoleteMacroAtomicVarInit.qlref create mode 100644 c/misra/test/rules/RULE-1-5/options create mode 100644 c/misra/test/rules/RULE-1-5/test.c create mode 100644 cpp/common/src/codingstandards/cpp/exclusions/c/Language4.qll create mode 100644 rule_packages/c/Language4.json diff --git a/c/misra/src/rules/RULE-1-5/CallToReallocWithSizeZero.ql b/c/misra/src/rules/RULE-1-5/CallToReallocWithSizeZero.ql new file mode 100644 index 0000000000..224ca2a6bf --- /dev/null +++ b/c/misra/src/rules/RULE-1-5/CallToReallocWithSizeZero.ql @@ -0,0 +1,24 @@ +/** + * @id c/misra/call-to-realloc-with-size-zero + * @name RULE-1-5: Disallowed size argument value equal to zero in call to realloc + * @description Invoking realloc with a size argument set to zero is implementation-defined behavior + * and declared as an obsolete feature in C18. + * @kind problem + * @precision very-high + * @problem.severity error + * @tags external/misra/id/rule-1-5 + * correctness + * external/misra/obligation/required + */ + +import cpp +import codingstandards.c.misra +import semmle.code.cpp.rangeanalysis.new.RangeAnalysis + +from FunctionCall call, Expr arg +where + not isExcluded(call, Language4Package::callToReallocWithSizeZeroQuery()) and + call.getTarget().hasGlobalOrStdName("realloc") and + arg = call.getArgument(1) and + upperBound(arg) = 0 +select arg, "Calling realloc with size zero results in implementation-defined behavior." diff --git a/c/misra/src/rules/RULE-1-5/InvalidDefineOrUndefOfStdBoolMacro.ql b/c/misra/src/rules/RULE-1-5/InvalidDefineOrUndefOfStdBoolMacro.ql new file mode 100644 index 0000000000..3d33103988 --- /dev/null +++ b/c/misra/src/rules/RULE-1-5/InvalidDefineOrUndefOfStdBoolMacro.ql @@ -0,0 +1,31 @@ +/** + * @id c/misra/invalid-define-or-undef-of-std-bool-macro + * @name RULE-1-5: Programs may not undefine or redefine the macros bool, true, or false + * @description Directives that undefine and/or redefine the standard boolean macros has been + * declared an obsolescent language feature since C99. + * @kind problem + * @precision very-high + * @problem.severity warning + * @tags external/misra/id/rule-1-5 + * maintainability + * readability + * external/misra/obligation/required + */ + +import cpp +import codingstandards.c.misra + +string getABoolMacroName() { result = ["true", "false", "bool"] } + +from PreprocessorDirective directive, string opString, string macroName +where + not isExcluded(directive, Language4Package::invalidDefineOrUndefOfStdBoolMacroQuery()) and + macroName = getABoolMacroName() and + ( + macroName = directive.(Macro).getName() and + opString = "define" + or + macroName = directive.(PreprocessorUndef).getName() and + opString = "undefine" + ) +select directive, "Invalid " + opString + " of boolean standard macro " + macroName diff --git a/c/misra/src/rules/RULE-1-5/UseOfObsoleteMacroAtomicVarInit.ql b/c/misra/src/rules/RULE-1-5/UseOfObsoleteMacroAtomicVarInit.ql new file mode 100644 index 0000000000..38dd7c0386 --- /dev/null +++ b/c/misra/src/rules/RULE-1-5/UseOfObsoleteMacroAtomicVarInit.ql @@ -0,0 +1,24 @@ +/** + * @id c/misra/use-of-obsolete-macro-atomic-var-init + * @name RULE-1-5: Disallowed usage of obsolete macro ATOMIC_VAR_INIT compiled as C18 + * @description The macro ATOMIC_VAR_INIT is has been declared an obsolescent language feature since + * C18. + * @kind problem + * @precision very-high + * @problem.severity recommendation + * @tags external/misra/id/rule-1-5 + * maintainability + * readability + * external/misra/obligation/required + */ + +import cpp +import codingstandards.c.misra + +from MacroInvocation invoke, Compilation c, string flag +where + not isExcluded(invoke, Language4Package::useOfObsoleteMacroAtomicVarInitQuery()) and + invoke.getMacroName() = "ATOMIC_VAR_INIT" and + flag = c.getAnArgument() and + flag.regexpMatch("-std=c1[78]") +select invoke, "Usage of macro ATOMIC_VAR_INIT() is considered obsolete for c version " + flag diff --git a/c/misra/test/rules/RULE-1-5/CallToReallocWithSizeZero.expected b/c/misra/test/rules/RULE-1-5/CallToReallocWithSizeZero.expected new file mode 100644 index 0000000000..0e58d0cd0d --- /dev/null +++ b/c/misra/test/rules/RULE-1-5/CallToReallocWithSizeZero.expected @@ -0,0 +1 @@ +| test.c:13:14:13:14 | 0 | Calling realloc with size zero results in implementation-defined behavior. | diff --git a/c/misra/test/rules/RULE-1-5/CallToReallocWithSizeZero.qlref b/c/misra/test/rules/RULE-1-5/CallToReallocWithSizeZero.qlref new file mode 100644 index 0000000000..218be6b3ef --- /dev/null +++ b/c/misra/test/rules/RULE-1-5/CallToReallocWithSizeZero.qlref @@ -0,0 +1 @@ +rules/RULE-1-5/CallToReallocWithSizeZero.ql \ No newline at end of file diff --git a/c/misra/test/rules/RULE-1-5/FunctionTypesNotInPrototypeForm.expected b/c/misra/test/rules/RULE-1-5/FunctionTypesNotInPrototypeForm.expected new file mode 100644 index 0000000000..9f9157ca8e --- /dev/null +++ b/c/misra/test/rules/RULE-1-5/FunctionTypesNotInPrototypeForm.expected @@ -0,0 +1,2 @@ +| test.c:40:6:40:7 | f2 | Function f2 does not specify void for no parameters present. | +| test.c:44:5:44:6 | f5 | Function f5 declares parameter in unsupported declaration list. | \ No newline at end of file diff --git a/c/misra/test/rules/RULE-1-5/FunctionTypesNotInPrototypeForm.qlref b/c/misra/test/rules/RULE-1-5/FunctionTypesNotInPrototypeForm.qlref new file mode 100644 index 0000000000..0a6121b324 --- /dev/null +++ b/c/misra/test/rules/RULE-1-5/FunctionTypesNotInPrototypeForm.qlref @@ -0,0 +1 @@ +rules/RULE-8-2/FunctionTypesNotInPrototypeForm.ql \ No newline at end of file diff --git a/c/misra/test/rules/RULE-1-5/InvalidDefineOrUndefOfStdBoolMacro.expected b/c/misra/test/rules/RULE-1-5/InvalidDefineOrUndefOfStdBoolMacro.expected new file mode 100644 index 0000000000..a29c5efe56 --- /dev/null +++ b/c/misra/test/rules/RULE-1-5/InvalidDefineOrUndefOfStdBoolMacro.expected @@ -0,0 +1,6 @@ +| test.c:23:1:23:14 | #define true 3 | Invalid define of boolean standard macro true | +| test.c:24:1:24:15 | #define false 3 | Invalid define of boolean standard macro false | +| test.c:25:1:25:18 | #define bool int * | Invalid define of boolean standard macro bool | +| test.c:26:1:26:11 | #undef true | Invalid undefine of boolean standard macro true | +| test.c:27:1:27:12 | #undef false | Invalid undefine of boolean standard macro false | +| test.c:28:1:28:11 | #undef bool | Invalid undefine of boolean standard macro bool | diff --git a/c/misra/test/rules/RULE-1-5/InvalidDefineOrUndefOfStdBoolMacro.qlref b/c/misra/test/rules/RULE-1-5/InvalidDefineOrUndefOfStdBoolMacro.qlref new file mode 100644 index 0000000000..5b112609cc --- /dev/null +++ b/c/misra/test/rules/RULE-1-5/InvalidDefineOrUndefOfStdBoolMacro.qlref @@ -0,0 +1 @@ +rules/RULE-1-5/InvalidDefineOrUndefOfStdBoolMacro.ql \ No newline at end of file diff --git a/c/misra/test/rules/RULE-1-5/MemoryAllocDeallocFunctionsOfStdlibhUsed.expected b/c/misra/test/rules/RULE-1-5/MemoryAllocDeallocFunctionsOfStdlibhUsed.expected new file mode 100644 index 0000000000..3f8fa3cf3f --- /dev/null +++ b/c/misra/test/rules/RULE-1-5/MemoryAllocDeallocFunctionsOfStdlibhUsed.expected @@ -0,0 +1,3 @@ +| test.c:10:12:10:17 | call to malloc | Use of banned dynamic memory allocation. | +| test.c:13:3:13:9 | call to realloc | Use of banned dynamic memory allocation. | +| test.c:16:3:16:9 | call to realloc | Use of banned dynamic memory allocation. | diff --git a/c/misra/test/rules/RULE-1-5/MemoryAllocDeallocFunctionsOfStdlibhUsed.qlref b/c/misra/test/rules/RULE-1-5/MemoryAllocDeallocFunctionsOfStdlibhUsed.qlref new file mode 100644 index 0000000000..8f64b81ced --- /dev/null +++ b/c/misra/test/rules/RULE-1-5/MemoryAllocDeallocFunctionsOfStdlibhUsed.qlref @@ -0,0 +1 @@ +rules/RULE-21-3/MemoryAllocDeallocFunctionsOfStdlibhUsed.ql \ No newline at end of file diff --git a/c/misra/test/rules/RULE-1-5/MissingStaticSpecifierObjectRedeclarationC.expected b/c/misra/test/rules/RULE-1-5/MissingStaticSpecifierObjectRedeclarationC.expected new file mode 100644 index 0000000000..4c3d4614fa --- /dev/null +++ b/c/misra/test/rules/RULE-1-5/MissingStaticSpecifierObjectRedeclarationC.expected @@ -0,0 +1 @@ +| test.c:37:12:37:13 | declaration of g5 | The redeclaration of $@ with internal linkage misses the static specifier. | test.c:36:12:36:13 | definition of g5 | g5 | diff --git a/c/misra/test/rules/RULE-1-5/MissingStaticSpecifierObjectRedeclarationC.qlref b/c/misra/test/rules/RULE-1-5/MissingStaticSpecifierObjectRedeclarationC.qlref new file mode 100644 index 0000000000..70b6073e14 --- /dev/null +++ b/c/misra/test/rules/RULE-1-5/MissingStaticSpecifierObjectRedeclarationC.qlref @@ -0,0 +1 @@ +rules/RULE-8-8/MissingStaticSpecifierObjectRedeclarationC.ql \ No newline at end of file diff --git a/c/misra/test/rules/RULE-1-5/StandardLibraryInputoutputFunctionsUsed.expected b/c/misra/test/rules/RULE-1-5/StandardLibraryInputoutputFunctionsUsed.expected new file mode 100644 index 0000000000..ca49894238 --- /dev/null +++ b/c/misra/test/rules/RULE-1-5/StandardLibraryInputoutputFunctionsUsed.expected @@ -0,0 +1,3 @@ +| test.c:57:3:57:8 | call to ungetc | Call to banned function ungetc. | +| test.c:60:3:60:7 | call to fread | Call to banned function fread. | +| test.c:62:3:62:8 | call to ungetc | Call to banned function ungetc. | diff --git a/c/misra/test/rules/RULE-1-5/StandardLibraryInputoutputFunctionsUsed.qlref b/c/misra/test/rules/RULE-1-5/StandardLibraryInputoutputFunctionsUsed.qlref new file mode 100644 index 0000000000..0a8cd754ef --- /dev/null +++ b/c/misra/test/rules/RULE-1-5/StandardLibraryInputoutputFunctionsUsed.qlref @@ -0,0 +1 @@ +rules/RULE-21-6/StandardLibraryInputoutputFunctionsUsed.ql \ No newline at end of file diff --git a/c/misra/test/rules/RULE-1-5/UseOfObsoleteMacroAtomicVarInit.expected b/c/misra/test/rules/RULE-1-5/UseOfObsoleteMacroAtomicVarInit.expected new file mode 100644 index 0000000000..6fe4cee5f4 --- /dev/null +++ b/c/misra/test/rules/RULE-1-5/UseOfObsoleteMacroAtomicVarInit.expected @@ -0,0 +1 @@ +| test.c:30:18:30:36 | ATOMIC_VAR_INIT(value) | Usage of macro ATOMIC_VAR_INIT() is considered obsolete for c version -std=c17 | diff --git a/c/misra/test/rules/RULE-1-5/UseOfObsoleteMacroAtomicVarInit.qlref b/c/misra/test/rules/RULE-1-5/UseOfObsoleteMacroAtomicVarInit.qlref new file mode 100644 index 0000000000..9a54fdc83a --- /dev/null +++ b/c/misra/test/rules/RULE-1-5/UseOfObsoleteMacroAtomicVarInit.qlref @@ -0,0 +1 @@ +rules/RULE-1-5/UseOfObsoleteMacroAtomicVarInit.ql \ No newline at end of file diff --git a/c/misra/test/rules/RULE-1-5/options b/c/misra/test/rules/RULE-1-5/options new file mode 100644 index 0000000000..2ba2218a05 --- /dev/null +++ b/c/misra/test/rules/RULE-1-5/options @@ -0,0 +1 @@ +semmle-extractor-options:-std=c17 -I../../../../common/test/includes/standard-library \ No newline at end of file diff --git a/c/misra/test/rules/RULE-1-5/test.c b/c/misra/test/rules/RULE-1-5/test.c new file mode 100644 index 0000000000..43faa71f3c --- /dev/null +++ b/c/misra/test/rules/RULE-1-5/test.c @@ -0,0 +1,63 @@ +// Compiled with -std=c17 + +#include "stdatomic.h" +#include "stdbool.h" +#include "stdio.h" +#include "stdlib.h" + +void f1(void) { + // malloc() is not obsolete, but banned by Rule 21.3 + int *t = malloc(10); // COMPLIANT[False Negative] + + // Obsolete usage of realloc. + realloc(t, 0); // NON-COMPLIANT + + // Valid usage of realloc, but all use of realloc is banned by Rule 21.3 + realloc(t, 20); // NON-COMPLIANT +} + +extern const int g1; // COMPLIANT +const extern int g2; // NON-COMPLIANT + +#define MY_TRUE 3 // COMPLIANT +#define true 3 // NON-COMPLIANT +#define false 3 // NON-COMPLIANT +#define bool int * // NON-COMPLIANT +#undef true // NON-COMPLIANT +#undef false // NON-COMPLIANT +#undef bool // NON-COMPLIANT + +_Atomic int g3 = ATOMIC_VAR_INIT(18); // NON-COMPLIANT +_Atomic int g4 = 18; // COMPLIANT + +// The following cases are already covered by other rules: + +// Rule 8.8: +static int g5 = 3; // COMPLIANT +extern int g5; // NON-COMPLIANT + +// Rule 8.2: +void f2(); // NON-COMPLIANT +void f3(void); // COMPLIANT + +void f4(int p1) {}; // COMPLIANT +int f5(x) // NON_COMPLIANT +int x; +{ + return 1; +} + +// Rule 21.6 covers the below cases: +void f6(void) { + // `gets` was removed from C11. + // gets(stdin); // NON_COMPLIANT + + FILE *file = fopen("", 0); + // Obsolete usage of ungetc. + ungetc('c', file); // NON-COMPLIANT + + char buf[10]; + fread(buf, sizeof(buf), 10, file); + // This is not an obsolete usage of ungetc, but ungetc isn't allowed. + ungetc('c', file); // NON-COMPLIANT[FALSE NEGATIVE] +} \ No newline at end of file diff --git a/cpp/common/src/codingstandards/cpp/exclusions/c/Language4.qll b/cpp/common/src/codingstandards/cpp/exclusions/c/Language4.qll new file mode 100644 index 0000000000..f26cae3e9a --- /dev/null +++ b/cpp/common/src/codingstandards/cpp/exclusions/c/Language4.qll @@ -0,0 +1,61 @@ +//** THIS FILE IS AUTOGENERATED, DO NOT MODIFY DIRECTLY. **/ +import cpp +import RuleMetadata +import codingstandards.cpp.exclusions.RuleMetadata + +newtype Language4Query = + TUseOfObsoleteMacroAtomicVarInitQuery() or + TInvalidDefineOrUndefOfStdBoolMacroQuery() or + TCallToReallocWithSizeZeroQuery() + +predicate isLanguage4QueryMetadata(Query query, string queryId, string ruleId, string category) { + query = + // `Query` instance for the `useOfObsoleteMacroAtomicVarInit` query + Language4Package::useOfObsoleteMacroAtomicVarInitQuery() and + queryId = + // `@id` for the `useOfObsoleteMacroAtomicVarInit` query + "c/misra/use-of-obsolete-macro-atomic-var-init" and + ruleId = "RULE-1-5" and + category = "required" + or + query = + // `Query` instance for the `invalidDefineOrUndefOfStdBoolMacro` query + Language4Package::invalidDefineOrUndefOfStdBoolMacroQuery() and + queryId = + // `@id` for the `invalidDefineOrUndefOfStdBoolMacro` query + "c/misra/invalid-define-or-undef-of-std-bool-macro" and + ruleId = "RULE-1-5" and + category = "required" + or + query = + // `Query` instance for the `callToReallocWithSizeZero` query + Language4Package::callToReallocWithSizeZeroQuery() and + queryId = + // `@id` for the `callToReallocWithSizeZero` query + "c/misra/call-to-realloc-with-size-zero" and + ruleId = "RULE-1-5" and + category = "required" +} + +module Language4Package { + Query useOfObsoleteMacroAtomicVarInitQuery() { + //autogenerate `Query` type + result = + // `Query` type for `useOfObsoleteMacroAtomicVarInit` query + TQueryC(TLanguage4PackageQuery(TUseOfObsoleteMacroAtomicVarInitQuery())) + } + + Query invalidDefineOrUndefOfStdBoolMacroQuery() { + //autogenerate `Query` type + result = + // `Query` type for `invalidDefineOrUndefOfStdBoolMacro` query + TQueryC(TLanguage4PackageQuery(TInvalidDefineOrUndefOfStdBoolMacroQuery())) + } + + Query callToReallocWithSizeZeroQuery() { + //autogenerate `Query` type + result = + // `Query` type for `callToReallocWithSizeZero` query + TQueryC(TLanguage4PackageQuery(TCallToReallocWithSizeZeroQuery())) + } +} diff --git a/cpp/common/src/codingstandards/cpp/exclusions/c/RuleMetadata.qll b/cpp/common/src/codingstandards/cpp/exclusions/c/RuleMetadata.qll index b10fbf0a2f..cff145d562 100644 --- a/cpp/common/src/codingstandards/cpp/exclusions/c/RuleMetadata.qll +++ b/cpp/common/src/codingstandards/cpp/exclusions/c/RuleMetadata.qll @@ -39,6 +39,7 @@ import InvalidMemory2 import Language1 import Language2 import Language3 +import Language4 import Memory1 import Memory2 import Memory3 @@ -112,6 +113,7 @@ newtype TCQuery = TLanguage1PackageQuery(Language1Query q) or TLanguage2PackageQuery(Language2Query q) or TLanguage3PackageQuery(Language3Query q) or + TLanguage4PackageQuery(Language4Query q) or TMemory1PackageQuery(Memory1Query q) or TMemory2PackageQuery(Memory2Query q) or TMemory3PackageQuery(Memory3Query q) or @@ -185,6 +187,7 @@ predicate isQueryMetadata(Query query, string queryId, string ruleId, string cat isLanguage1QueryMetadata(query, queryId, ruleId, category) or isLanguage2QueryMetadata(query, queryId, ruleId, category) or isLanguage3QueryMetadata(query, queryId, ruleId, category) or + isLanguage4QueryMetadata(query, queryId, ruleId, category) or isMemory1QueryMetadata(query, queryId, ruleId, category) or isMemory2QueryMetadata(query, queryId, ruleId, category) or isMemory3QueryMetadata(query, queryId, ruleId, category) or diff --git a/rule_packages/c/Language4.json b/rule_packages/c/Language4.json new file mode 100644 index 0000000000..ff85927a61 --- /dev/null +++ b/rule_packages/c/Language4.json @@ -0,0 +1,47 @@ +{ + "MISRA-C-2012": { + "RULE-1-5": { + "properties": { + "obligation": "required" + }, + "queries": [ + { + "description": "The macro ATOMIC_VAR_INIT is has been declared an obsolescent language feature since C18.", + "kind": "problem", + "name": "Disallowed usage of obsolete macro ATOMIC_VAR_INIT compiled as C18", + "precision": "very-high", + "severity": "recommendation", + "short_name": "UseOfObsoleteMacroAtomicVarInit", + "tags": [ + "maintainability", + "readability" + ] + }, + { + "description": "Directives that undefine and/or redefine the standard boolean macros has been declared an obsolescent language feature since C99.", + "kind": "problem", + "name": "Programs may not undefine or redefine the macros bool, true, or false", + "precision": "very-high", + "severity": "warning", + "short_name": "InvalidDefineOrUndefOfStdBoolMacro", + "tags": [ + "maintainability", + "readability" + ] + }, + { + "description": "Invoking realloc with a size argument set to zero is implementation-defined behavior and declared as an obsolete feature in C18.", + "kind": "problem", + "name": "Disallowed size argument value equal to zero in call to realloc", + "precision": "very-high", + "severity": "error", + "short_name": "CallToReallocWithSizeZero", + "tags": [ + "correctness" + ] + } + ], + "title": "Obsolencent language features shall not be used" + } + } +} \ No newline at end of file From 3adf181c92efb89e3d8fc4fa4b58f0ebb076a712 Mon Sep 17 00:00:00 2001 From: Mike Fairhurst Date: Thu, 3 Oct 2024 15:49:44 -0700 Subject: [PATCH 02/15] Add full stops to query messages. --- .../RULE-1-5/InvalidDefineOrUndefOfStdBoolMacro.ql | 2 +- .../RULE-1-5/UseOfObsoleteMacroAtomicVarInit.ql | 3 ++- .../InvalidDefineOrUndefOfStdBoolMacro.expected | 12 ++++++------ .../UseOfObsoleteMacroAtomicVarInit.expected | 2 +- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/c/misra/src/rules/RULE-1-5/InvalidDefineOrUndefOfStdBoolMacro.ql b/c/misra/src/rules/RULE-1-5/InvalidDefineOrUndefOfStdBoolMacro.ql index 3d33103988..8b6abe47dd 100644 --- a/c/misra/src/rules/RULE-1-5/InvalidDefineOrUndefOfStdBoolMacro.ql +++ b/c/misra/src/rules/RULE-1-5/InvalidDefineOrUndefOfStdBoolMacro.ql @@ -28,4 +28,4 @@ where macroName = directive.(PreprocessorUndef).getName() and opString = "undefine" ) -select directive, "Invalid " + opString + " of boolean standard macro " + macroName +select directive, "Invalid " + opString + " of boolean standard macro '" + macroName + "'." diff --git a/c/misra/src/rules/RULE-1-5/UseOfObsoleteMacroAtomicVarInit.ql b/c/misra/src/rules/RULE-1-5/UseOfObsoleteMacroAtomicVarInit.ql index 38dd7c0386..82bde8471a 100644 --- a/c/misra/src/rules/RULE-1-5/UseOfObsoleteMacroAtomicVarInit.ql +++ b/c/misra/src/rules/RULE-1-5/UseOfObsoleteMacroAtomicVarInit.ql @@ -21,4 +21,5 @@ where invoke.getMacroName() = "ATOMIC_VAR_INIT" and flag = c.getAnArgument() and flag.regexpMatch("-std=c1[78]") -select invoke, "Usage of macro ATOMIC_VAR_INIT() is considered obsolete for c version " + flag +select invoke, + "Usage of macro ATOMIC_VAR_INIT() is considered obsolete for c version '" + flag + "'." diff --git a/c/misra/test/rules/RULE-1-5/InvalidDefineOrUndefOfStdBoolMacro.expected b/c/misra/test/rules/RULE-1-5/InvalidDefineOrUndefOfStdBoolMacro.expected index a29c5efe56..e2a072d2b4 100644 --- a/c/misra/test/rules/RULE-1-5/InvalidDefineOrUndefOfStdBoolMacro.expected +++ b/c/misra/test/rules/RULE-1-5/InvalidDefineOrUndefOfStdBoolMacro.expected @@ -1,6 +1,6 @@ -| test.c:23:1:23:14 | #define true 3 | Invalid define of boolean standard macro true | -| test.c:24:1:24:15 | #define false 3 | Invalid define of boolean standard macro false | -| test.c:25:1:25:18 | #define bool int * | Invalid define of boolean standard macro bool | -| test.c:26:1:26:11 | #undef true | Invalid undefine of boolean standard macro true | -| test.c:27:1:27:12 | #undef false | Invalid undefine of boolean standard macro false | -| test.c:28:1:28:11 | #undef bool | Invalid undefine of boolean standard macro bool | +| test.c:23:1:23:14 | #define true 3 | Invalid define of boolean standard macro 'true'. | +| test.c:24:1:24:15 | #define false 3 | Invalid define of boolean standard macro 'false'. | +| test.c:25:1:25:18 | #define bool int * | Invalid define of boolean standard macro 'bool'. | +| test.c:26:1:26:11 | #undef true | Invalid undefine of boolean standard macro 'true'. | +| test.c:27:1:27:12 | #undef false | Invalid undefine of boolean standard macro 'false'. | +| test.c:28:1:28:11 | #undef bool | Invalid undefine of boolean standard macro 'bool'. | diff --git a/c/misra/test/rules/RULE-1-5/UseOfObsoleteMacroAtomicVarInit.expected b/c/misra/test/rules/RULE-1-5/UseOfObsoleteMacroAtomicVarInit.expected index 6fe4cee5f4..c38a6263a9 100644 --- a/c/misra/test/rules/RULE-1-5/UseOfObsoleteMacroAtomicVarInit.expected +++ b/c/misra/test/rules/RULE-1-5/UseOfObsoleteMacroAtomicVarInit.expected @@ -1 +1 @@ -| test.c:30:18:30:36 | ATOMIC_VAR_INIT(value) | Usage of macro ATOMIC_VAR_INIT() is considered obsolete for c version -std=c17 | +| test.c:30:18:30:36 | ATOMIC_VAR_INIT(value) | Usage of macro ATOMIC_VAR_INIT() is considered obsolete for c version '-std=c17'. | From 31dc8bc08c49e8872f6ebf79fc7bf46059a172b5 Mon Sep 17 00:00:00 2001 From: Mike Fairhurst Date: Thu, 3 Oct 2024 15:56:04 -0700 Subject: [PATCH 03/15] Fix test.c format --- .../StandardLibraryInputoutputFunctionsUsed.expected | 6 +++--- c/misra/test/rules/RULE-1-5/test.c | 8 +++----- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/c/misra/test/rules/RULE-1-5/StandardLibraryInputoutputFunctionsUsed.expected b/c/misra/test/rules/RULE-1-5/StandardLibraryInputoutputFunctionsUsed.expected index ca49894238..d0cf1351c7 100644 --- a/c/misra/test/rules/RULE-1-5/StandardLibraryInputoutputFunctionsUsed.expected +++ b/c/misra/test/rules/RULE-1-5/StandardLibraryInputoutputFunctionsUsed.expected @@ -1,3 +1,3 @@ -| test.c:57:3:57:8 | call to ungetc | Call to banned function ungetc. | -| test.c:60:3:60:7 | call to fread | Call to banned function fread. | -| test.c:62:3:62:8 | call to ungetc | Call to banned function ungetc. | +| test.c:55:3:55:8 | call to ungetc | Call to banned function ungetc. | +| test.c:58:3:58:7 | call to fread | Call to banned function fread. | +| test.c:60:3:60:8 | call to ungetc | Call to banned function ungetc. | diff --git a/c/misra/test/rules/RULE-1-5/test.c b/c/misra/test/rules/RULE-1-5/test.c index 43faa71f3c..51399e32c6 100644 --- a/c/misra/test/rules/RULE-1-5/test.c +++ b/c/misra/test/rules/RULE-1-5/test.c @@ -40,12 +40,10 @@ extern int g5; // NON-COMPLIANT void f2(); // NON-COMPLIANT void f3(void); // COMPLIANT -void f4(int p1) {}; // COMPLIANT -int f5(x) // NON_COMPLIANT +void f4(int p1){}; // COMPLIANT +int f5(x) // NON_COMPLIANT int x; -{ - return 1; -} +{ return 1; } // Rule 21.6 covers the below cases: void f6(void) { From d077885f68d65ee72c17614aa41c066ddf4c7c3b Mon Sep 17 00:00:00 2001 From: Mike Fairhurst Date: Fri, 4 Oct 2024 07:51:44 -0700 Subject: [PATCH 04/15] Add tag misra c 2012 amendment 3 --- c/misra/src/rules/RULE-1-5/CallToReallocWithSizeZero.ql | 1 + .../rules/RULE-1-5/InvalidDefineOrUndefOfStdBoolMacro.ql | 1 + .../rules/RULE-1-5/UseOfObsoleteMacroAtomicVarInit.ql | 1 + rule_packages/c/Language4.json | 9 ++++++--- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/c/misra/src/rules/RULE-1-5/CallToReallocWithSizeZero.ql b/c/misra/src/rules/RULE-1-5/CallToReallocWithSizeZero.ql index 224ca2a6bf..2ea90e8b12 100644 --- a/c/misra/src/rules/RULE-1-5/CallToReallocWithSizeZero.ql +++ b/c/misra/src/rules/RULE-1-5/CallToReallocWithSizeZero.ql @@ -8,6 +8,7 @@ * @problem.severity error * @tags external/misra/id/rule-1-5 * correctness + * external/misra/c/2012/amendment3 * external/misra/obligation/required */ diff --git a/c/misra/src/rules/RULE-1-5/InvalidDefineOrUndefOfStdBoolMacro.ql b/c/misra/src/rules/RULE-1-5/InvalidDefineOrUndefOfStdBoolMacro.ql index 8b6abe47dd..9d10522ecf 100644 --- a/c/misra/src/rules/RULE-1-5/InvalidDefineOrUndefOfStdBoolMacro.ql +++ b/c/misra/src/rules/RULE-1-5/InvalidDefineOrUndefOfStdBoolMacro.ql @@ -9,6 +9,7 @@ * @tags external/misra/id/rule-1-5 * maintainability * readability + * external/misra/c/2012/amendment3 * external/misra/obligation/required */ diff --git a/c/misra/src/rules/RULE-1-5/UseOfObsoleteMacroAtomicVarInit.ql b/c/misra/src/rules/RULE-1-5/UseOfObsoleteMacroAtomicVarInit.ql index 82bde8471a..b2fb5f0167 100644 --- a/c/misra/src/rules/RULE-1-5/UseOfObsoleteMacroAtomicVarInit.ql +++ b/c/misra/src/rules/RULE-1-5/UseOfObsoleteMacroAtomicVarInit.ql @@ -9,6 +9,7 @@ * @tags external/misra/id/rule-1-5 * maintainability * readability + * external/misra/c/2012/amendment3 * external/misra/obligation/required */ diff --git a/rule_packages/c/Language4.json b/rule_packages/c/Language4.json index ff85927a61..a9f5ddde92 100644 --- a/rule_packages/c/Language4.json +++ b/rule_packages/c/Language4.json @@ -14,7 +14,8 @@ "short_name": "UseOfObsoleteMacroAtomicVarInit", "tags": [ "maintainability", - "readability" + "readability", + "external/misra/c/2012/amendment3" ] }, { @@ -26,7 +27,8 @@ "short_name": "InvalidDefineOrUndefOfStdBoolMacro", "tags": [ "maintainability", - "readability" + "readability", + "external/misra/c/2012/amendment3" ] }, { @@ -37,7 +39,8 @@ "severity": "error", "short_name": "CallToReallocWithSizeZero", "tags": [ - "correctness" + "correctness", + "external/misra/c/2012/amendment3" ] } ], From e27e49a004f4ac240535d9cc4971c3261d32208b Mon Sep 17 00:00:00 2001 From: Mike Fairhurst Date: Fri, 4 Oct 2024 12:10:22 -0700 Subject: [PATCH 05/15] Add implementation scope to Language4.json --- rule_packages/c/Language4.json | 5 ++++- schemas/rule-package.schema.json | 12 ++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/rule_packages/c/Language4.json b/rule_packages/c/Language4.json index a9f5ddde92..0ba6bfcc55 100644 --- a/rule_packages/c/Language4.json +++ b/rule_packages/c/Language4.json @@ -44,7 +44,10 @@ ] } ], - "title": "Obsolencent language features shall not be used" + "title": "Obsolencent language features shall not be used", + "implementation_scope": { + "description": "Usage of obsolescent language features that are already disallowed by Rule 8.2, Rule 8.8, and 21.6 are not redundantly checked by this rule." + } } } } \ No newline at end of file diff --git a/schemas/rule-package.schema.json b/schemas/rule-package.schema.json index b27815163e..087a6087ea 100644 --- a/schemas/rule-package.schema.json +++ b/schemas/rule-package.schema.json @@ -207,6 +207,18 @@ }, "title": { "type": "string" + }, + "implementation_scope": { + "type": "object", + "properties": { + "description": { + "type": "string" + } + }, + "required": [ + "description" + ], + "additionalProperties": false } }, "required": [ From cca63e439ff2d3bf9a0dd9124a77c6f311838095 Mon Sep 17 00:00:00 2001 From: Mike Fairhurst Date: Fri, 4 Oct 2024 12:22:22 -0700 Subject: [PATCH 06/15] Report ATOMIC_VAR_INIT for all C versions. --- .../RULE-1-5/UseOfObsoleteMacroAtomicVarInit.ql | 8 +++----- .../RULE-1-5/CallToReallocWithSizeZero.expected | 2 +- .../FunctionTypesNotInPrototypeForm.expected | 4 ++-- .../InvalidDefineOrUndefOfStdBoolMacro.expected | 12 ++++++------ ...MemoryAllocDeallocFunctionsOfStdlibhUsed.expected | 6 +++--- ...ssingStaticSpecifierObjectRedeclarationC.expected | 2 +- .../StandardLibraryInputoutputFunctionsUsed.expected | 6 +++--- .../UseOfObsoleteMacroAtomicVarInit.expected | 2 +- c/misra/test/rules/RULE-1-5/options | 1 - c/misra/test/rules/RULE-1-5/test.c | 2 -- 10 files changed, 20 insertions(+), 25 deletions(-) delete mode 100644 c/misra/test/rules/RULE-1-5/options diff --git a/c/misra/src/rules/RULE-1-5/UseOfObsoleteMacroAtomicVarInit.ql b/c/misra/src/rules/RULE-1-5/UseOfObsoleteMacroAtomicVarInit.ql index b2fb5f0167..e8abf1bbfb 100644 --- a/c/misra/src/rules/RULE-1-5/UseOfObsoleteMacroAtomicVarInit.ql +++ b/c/misra/src/rules/RULE-1-5/UseOfObsoleteMacroAtomicVarInit.ql @@ -16,11 +16,9 @@ import cpp import codingstandards.c.misra -from MacroInvocation invoke, Compilation c, string flag +from MacroInvocation invoke where not isExcluded(invoke, Language4Package::useOfObsoleteMacroAtomicVarInitQuery()) and - invoke.getMacroName() = "ATOMIC_VAR_INIT" and - flag = c.getAnArgument() and - flag.regexpMatch("-std=c1[78]") + invoke.getMacroName() = "ATOMIC_VAR_INIT" select invoke, - "Usage of macro ATOMIC_VAR_INIT() is considered obsolete for c version '" + flag + "'." + "Usage of macro ATOMIC_VAR_INIT() is declared obscelescent in C18, and discouraged in earlier C versions." diff --git a/c/misra/test/rules/RULE-1-5/CallToReallocWithSizeZero.expected b/c/misra/test/rules/RULE-1-5/CallToReallocWithSizeZero.expected index 0e58d0cd0d..89e54a38c2 100644 --- a/c/misra/test/rules/RULE-1-5/CallToReallocWithSizeZero.expected +++ b/c/misra/test/rules/RULE-1-5/CallToReallocWithSizeZero.expected @@ -1 +1 @@ -| test.c:13:14:13:14 | 0 | Calling realloc with size zero results in implementation-defined behavior. | +| test.c:11:14:11:14 | 0 | Calling realloc with size zero results in implementation-defined behavior. | diff --git a/c/misra/test/rules/RULE-1-5/FunctionTypesNotInPrototypeForm.expected b/c/misra/test/rules/RULE-1-5/FunctionTypesNotInPrototypeForm.expected index 9f9157ca8e..29faec8b55 100644 --- a/c/misra/test/rules/RULE-1-5/FunctionTypesNotInPrototypeForm.expected +++ b/c/misra/test/rules/RULE-1-5/FunctionTypesNotInPrototypeForm.expected @@ -1,2 +1,2 @@ -| test.c:40:6:40:7 | f2 | Function f2 does not specify void for no parameters present. | -| test.c:44:5:44:6 | f5 | Function f5 declares parameter in unsupported declaration list. | \ No newline at end of file +| test.c:38:6:38:7 | f2 | Function f2 does not specify void for no parameters present. | +| test.c:42:5:42:6 | f5 | Function f5 declares parameter in unsupported declaration list. | \ No newline at end of file diff --git a/c/misra/test/rules/RULE-1-5/InvalidDefineOrUndefOfStdBoolMacro.expected b/c/misra/test/rules/RULE-1-5/InvalidDefineOrUndefOfStdBoolMacro.expected index e2a072d2b4..7a6ca9824e 100644 --- a/c/misra/test/rules/RULE-1-5/InvalidDefineOrUndefOfStdBoolMacro.expected +++ b/c/misra/test/rules/RULE-1-5/InvalidDefineOrUndefOfStdBoolMacro.expected @@ -1,6 +1,6 @@ -| test.c:23:1:23:14 | #define true 3 | Invalid define of boolean standard macro 'true'. | -| test.c:24:1:24:15 | #define false 3 | Invalid define of boolean standard macro 'false'. | -| test.c:25:1:25:18 | #define bool int * | Invalid define of boolean standard macro 'bool'. | -| test.c:26:1:26:11 | #undef true | Invalid undefine of boolean standard macro 'true'. | -| test.c:27:1:27:12 | #undef false | Invalid undefine of boolean standard macro 'false'. | -| test.c:28:1:28:11 | #undef bool | Invalid undefine of boolean standard macro 'bool'. | +| test.c:21:1:21:14 | #define true 3 | Invalid define of boolean standard macro 'true'. | +| test.c:22:1:22:15 | #define false 3 | Invalid define of boolean standard macro 'false'. | +| test.c:23:1:23:18 | #define bool int * | Invalid define of boolean standard macro 'bool'. | +| test.c:24:1:24:11 | #undef true | Invalid undefine of boolean standard macro 'true'. | +| test.c:25:1:25:12 | #undef false | Invalid undefine of boolean standard macro 'false'. | +| test.c:26:1:26:11 | #undef bool | Invalid undefine of boolean standard macro 'bool'. | diff --git a/c/misra/test/rules/RULE-1-5/MemoryAllocDeallocFunctionsOfStdlibhUsed.expected b/c/misra/test/rules/RULE-1-5/MemoryAllocDeallocFunctionsOfStdlibhUsed.expected index 3f8fa3cf3f..de87fc8542 100644 --- a/c/misra/test/rules/RULE-1-5/MemoryAllocDeallocFunctionsOfStdlibhUsed.expected +++ b/c/misra/test/rules/RULE-1-5/MemoryAllocDeallocFunctionsOfStdlibhUsed.expected @@ -1,3 +1,3 @@ -| test.c:10:12:10:17 | call to malloc | Use of banned dynamic memory allocation. | -| test.c:13:3:13:9 | call to realloc | Use of banned dynamic memory allocation. | -| test.c:16:3:16:9 | call to realloc | Use of banned dynamic memory allocation. | +| test.c:8:12:8:17 | call to malloc | Use of banned dynamic memory allocation. | +| test.c:11:3:11:9 | call to realloc | Use of banned dynamic memory allocation. | +| test.c:14:3:14:9 | call to realloc | Use of banned dynamic memory allocation. | diff --git a/c/misra/test/rules/RULE-1-5/MissingStaticSpecifierObjectRedeclarationC.expected b/c/misra/test/rules/RULE-1-5/MissingStaticSpecifierObjectRedeclarationC.expected index 4c3d4614fa..48275eb504 100644 --- a/c/misra/test/rules/RULE-1-5/MissingStaticSpecifierObjectRedeclarationC.expected +++ b/c/misra/test/rules/RULE-1-5/MissingStaticSpecifierObjectRedeclarationC.expected @@ -1 +1 @@ -| test.c:37:12:37:13 | declaration of g5 | The redeclaration of $@ with internal linkage misses the static specifier. | test.c:36:12:36:13 | definition of g5 | g5 | +| test.c:35:12:35:13 | declaration of g5 | The redeclaration of $@ with internal linkage misses the static specifier. | test.c:34:12:34:13 | definition of g5 | g5 | diff --git a/c/misra/test/rules/RULE-1-5/StandardLibraryInputoutputFunctionsUsed.expected b/c/misra/test/rules/RULE-1-5/StandardLibraryInputoutputFunctionsUsed.expected index d0cf1351c7..396b181150 100644 --- a/c/misra/test/rules/RULE-1-5/StandardLibraryInputoutputFunctionsUsed.expected +++ b/c/misra/test/rules/RULE-1-5/StandardLibraryInputoutputFunctionsUsed.expected @@ -1,3 +1,3 @@ -| test.c:55:3:55:8 | call to ungetc | Call to banned function ungetc. | -| test.c:58:3:58:7 | call to fread | Call to banned function fread. | -| test.c:60:3:60:8 | call to ungetc | Call to banned function ungetc. | +| test.c:53:3:53:8 | call to ungetc | Call to banned function ungetc. | +| test.c:56:3:56:7 | call to fread | Call to banned function fread. | +| test.c:58:3:58:8 | call to ungetc | Call to banned function ungetc. | diff --git a/c/misra/test/rules/RULE-1-5/UseOfObsoleteMacroAtomicVarInit.expected b/c/misra/test/rules/RULE-1-5/UseOfObsoleteMacroAtomicVarInit.expected index c38a6263a9..bc903de094 100644 --- a/c/misra/test/rules/RULE-1-5/UseOfObsoleteMacroAtomicVarInit.expected +++ b/c/misra/test/rules/RULE-1-5/UseOfObsoleteMacroAtomicVarInit.expected @@ -1 +1 @@ -| test.c:30:18:30:36 | ATOMIC_VAR_INIT(value) | Usage of macro ATOMIC_VAR_INIT() is considered obsolete for c version '-std=c17'. | +| test.c:28:18:28:36 | ATOMIC_VAR_INIT(value) | Usage of macro ATOMIC_VAR_INIT() is declared obscelescent in C18, and discouraged in earlier C versions. | diff --git a/c/misra/test/rules/RULE-1-5/options b/c/misra/test/rules/RULE-1-5/options deleted file mode 100644 index 2ba2218a05..0000000000 --- a/c/misra/test/rules/RULE-1-5/options +++ /dev/null @@ -1 +0,0 @@ -semmle-extractor-options:-std=c17 -I../../../../common/test/includes/standard-library \ No newline at end of file diff --git a/c/misra/test/rules/RULE-1-5/test.c b/c/misra/test/rules/RULE-1-5/test.c index 51399e32c6..4709381898 100644 --- a/c/misra/test/rules/RULE-1-5/test.c +++ b/c/misra/test/rules/RULE-1-5/test.c @@ -1,5 +1,3 @@ -// Compiled with -std=c17 - #include "stdatomic.h" #include "stdbool.h" #include "stdio.h" From 794e97ab06f22edcad8759ae167463ffdd9d0aa9 Mon Sep 17 00:00:00 2001 From: Mike Fairhurst Date: Fri, 4 Oct 2024 12:42:55 -0700 Subject: [PATCH 07/15] Reuse implementation_scope schema, detailed items for 1.5 --- rule_packages/c/Language4.json | 12 +++++++++- schemas/rule-package.schema.json | 38 ++++++++++++++------------------ 2 files changed, 28 insertions(+), 22 deletions(-) diff --git a/rule_packages/c/Language4.json b/rule_packages/c/Language4.json index 0ba6bfcc55..54708d73da 100644 --- a/rule_packages/c/Language4.json +++ b/rule_packages/c/Language4.json @@ -46,7 +46,17 @@ ], "title": "Obsolencent language features shall not be used", "implementation_scope": { - "description": "Usage of obsolescent language features that are already disallowed by Rule 8.2, Rule 8.8, and 21.6 are not redundantly checked by this rule." + "description": "Not all items from Appendix F are covered by this rule. Some are not supportable and some are covered already by other rules.", + "items": [ + "Appendix F, item ID 1 is covered by Rule 8.8 and not reported as part of this implementation of Rule 1.5.", + "Appendix F, item ID 2 refers to compiler behavior which cannot be statically analyzed.", + "Appendix F, item ID 3, which states that storage-class specifiers may not be used except in the beginning of a declaration, is not supportable without additional changes to the CodeQL CLI.", + "Appendix F, item ID 6 is reported for all C versions, though the macro ATOMIC_VAR_INIT was not officially declared obsolescent until C18.", + "Appendix F, item IDs 4 and 5 are covered by Rule 8.2 and not reported as part of this implementation of Rule 1.5.", + "Appendix F, item IDs 8 and 9 is covered by Rule 21.6 and not reported as part of this implementation of Rule 1.5.", + "Appendix F, item ID 10 is checked by this implementation of 1.5, though it is a redundant subset of cases reported by Rule 21.3.", + "Appendix F, item ID 10 is reported for all C versions, as realloc() with a size argument of zero was implementation-defined behavior in C99 and C11." + ] } } } diff --git a/schemas/rule-package.schema.json b/schemas/rule-package.schema.json index 087a6087ea..63cbbf3ac5 100644 --- a/schemas/rule-package.schema.json +++ b/schemas/rule-package.schema.json @@ -209,16 +209,7 @@ "type": "string" }, "implementation_scope": { - "type": "object", - "properties": { - "description": { - "type": "string" - } - }, - "required": [ - "description" - ], - "additionalProperties": false + "$ref": "#/$defs/implementation_scope" } }, "required": [ @@ -360,6 +351,20 @@ "minLength": 1 }, "implementation_scope": { + "$ref": "#/$defs/implementation_scope" + } + }, + "required": [ + "description", + "name", + "precision", + "severity", + "short_name", + "tags" + ] + }, + "implementation_scope": { + "$id": "/schemas/implementation_scope", "type": "object", "properties": { "description": { @@ -374,17 +379,8 @@ }, "required": [ "description" - ] + ], + "additionalProperties": false } - }, - "required": [ - "description", - "name", - "precision", - "severity", - "short_name", - "tags" - ] - } } } \ No newline at end of file From 38a467ddd5c08caa083cbf66a220b6190cbda6d6 Mon Sep 17 00:00:00 2001 From: Mike Fairhurst Date: Fri, 4 Oct 2024 12:52:25 -0700 Subject: [PATCH 08/15] Add cross-linking comments to tests referencing other rules. --- ...moryAllocDeallocFunctionsOfStdlibhUsed.expected | 10 +++++----- c/misra/test/rules/RULE-21-3/test.c | 5 +++++ ...tandardLibraryInputoutputFunctionsUsed.expected | 14 +++++++------- c/misra/test/rules/RULE-21-6/test.c | 5 +++++ .../FunctionTypesNotInPrototypeForm.expected | 8 ++++---- c/misra/test/rules/RULE-8-2/test.c | 5 +++++ ...ingStaticSpecifierObjectRedeclarationC.expected | 2 +- c/misra/test/rules/RULE-8-8/test.c | 5 +++++ 8 files changed, 37 insertions(+), 17 deletions(-) diff --git a/c/misra/test/rules/RULE-21-3/MemoryAllocDeallocFunctionsOfStdlibhUsed.expected b/c/misra/test/rules/RULE-21-3/MemoryAllocDeallocFunctionsOfStdlibhUsed.expected index 0215c2e5b8..e9ea6daecc 100644 --- a/c/misra/test/rules/RULE-21-3/MemoryAllocDeallocFunctionsOfStdlibhUsed.expected +++ b/c/misra/test/rules/RULE-21-3/MemoryAllocDeallocFunctionsOfStdlibhUsed.expected @@ -1,5 +1,5 @@ -| test.c:8:15:8:20 | call to malloc | Use of banned dynamic memory allocation. | -| test.c:9:15:9:20 | call to calloc | Use of banned dynamic memory allocation. | -| test.c:10:8:10:14 | call to realloc | Use of banned dynamic memory allocation. | -| test.c:11:3:11:6 | call to free | Use of banned dynamic memory deallocation. | -| test.c:12:3:12:6 | call to free | Use of banned dynamic memory deallocation. | +| test.c:13:15:13:20 | call to malloc | Use of banned dynamic memory allocation. | +| test.c:14:15:14:20 | call to calloc | Use of banned dynamic memory allocation. | +| test.c:15:8:15:14 | call to realloc | Use of banned dynamic memory allocation. | +| test.c:16:3:16:6 | call to free | Use of banned dynamic memory deallocation. | +| test.c:17:3:17:6 | call to free | Use of banned dynamic memory deallocation. | diff --git a/c/misra/test/rules/RULE-21-3/test.c b/c/misra/test/rules/RULE-21-3/test.c index d9aee3a322..fd4543faaf 100644 --- a/c/misra/test/rules/RULE-21-3/test.c +++ b/c/misra/test/rules/RULE-21-3/test.c @@ -1,3 +1,8 @@ +// Note: A subset of these cases are also tested in c/misra/test/rules/RULE-1-5 +// via a MemoryAllocDeallocFunctionsOfStdlibhUsed.qlref and .expected file in +// that directory. Changes to these tests may require updating the test code or +// expectations in that directory as well. + #include #include void f2(); diff --git a/c/misra/test/rules/RULE-21-6/StandardLibraryInputoutputFunctionsUsed.expected b/c/misra/test/rules/RULE-21-6/StandardLibraryInputoutputFunctionsUsed.expected index 0dee7e9b3d..672480db33 100644 --- a/c/misra/test/rules/RULE-21-6/StandardLibraryInputoutputFunctionsUsed.expected +++ b/c/misra/test/rules/RULE-21-6/StandardLibraryInputoutputFunctionsUsed.expected @@ -1,7 +1,7 @@ -| test.c:8:10:8:14 | call to scanf | Call to banned function scanf. | -| test.c:9:5:9:10 | call to printf | Call to banned function printf. | -| test.c:16:16:16:21 | call to fgetwc | Call to banned function fgetwc. | -| test.c:17:5:17:12 | call to putwchar | Call to banned function putwchar. | -| test.c:22:7:22:10 | call to puts | Call to banned function puts. | -| test.c:24:7:24:10 | call to puts | Call to banned function puts. | -| test.c:26:5:26:8 | call to puts | Call to banned function puts. | +| test.c:13:10:13:14 | call to scanf | Call to banned function scanf. | +| test.c:14:5:14:10 | call to printf | Call to banned function printf. | +| test.c:21:16:21:21 | call to fgetwc | Call to banned function fgetwc. | +| test.c:22:5:22:12 | call to putwchar | Call to banned function putwchar. | +| test.c:27:7:27:10 | call to puts | Call to banned function puts. | +| test.c:29:7:29:10 | call to puts | Call to banned function puts. | +| test.c:31:5:31:8 | call to puts | Call to banned function puts. | diff --git a/c/misra/test/rules/RULE-21-6/test.c b/c/misra/test/rules/RULE-21-6/test.c index 0ae580164e..b66bb9b6b7 100644 --- a/c/misra/test/rules/RULE-21-6/test.c +++ b/c/misra/test/rules/RULE-21-6/test.c @@ -1,3 +1,8 @@ +// Note: A subset of these cases are also tested in c/misra/test/rules/RULE-1-5 +// via a StandardLibraryInputoutputFunctionsUsed.qlref and .expected file in +// that directory. Changes to these tests may require updating the test code or +// expectations in that directory as well. + #include #include #include diff --git a/c/misra/test/rules/RULE-8-2/FunctionTypesNotInPrototypeForm.expected b/c/misra/test/rules/RULE-8-2/FunctionTypesNotInPrototypeForm.expected index f2c08897b8..1264797088 100644 --- a/c/misra/test/rules/RULE-8-2/FunctionTypesNotInPrototypeForm.expected +++ b/c/misra/test/rules/RULE-8-2/FunctionTypesNotInPrototypeForm.expected @@ -1,4 +1,4 @@ -| test.c:3:6:3:7 | f1 | Function f1 declares parameter that is unnamed. | -| test.c:4:6:4:7 | f2 | Function f2 does not specify void for no parameters present. | -| test.c:5:6:5:7 | f3 | Function f3 does not specify void for no parameters present. | -| test.c:7:5:7:6 | f5 | Function f5 declares parameter in unsupported declaration list. | +| test.c:8:6:8:7 | f1 | Function f1 declares parameter that is unnamed. | +| test.c:9:6:9:7 | f2 | Function f2 does not specify void for no parameters present. | +| test.c:10:6:10:7 | f3 | Function f3 does not specify void for no parameters present. | +| test.c:12:5:12:6 | f5 | Function f5 declares parameter in unsupported declaration list. | diff --git a/c/misra/test/rules/RULE-8-2/test.c b/c/misra/test/rules/RULE-8-2/test.c index c254a221d9..1ed64c0011 100644 --- a/c/misra/test/rules/RULE-8-2/test.c +++ b/c/misra/test/rules/RULE-8-2/test.c @@ -1,3 +1,8 @@ +// Note: A subset of these cases are also tested in c/misra/test/rules/RULE-1-5 +// via a FunctionTypesNotInPrototypeForm.qlref and .expected file in that +// directory. Changes to these tests may require updating the test code or +// expectations in that directory as well. + void f(int x); // COMPLIANT void f0(void); // COMPLIANT void f1(int); // NON_COMPLIANT diff --git a/c/misra/test/rules/RULE-8-8/MissingStaticSpecifierObjectRedeclarationC.expected b/c/misra/test/rules/RULE-8-8/MissingStaticSpecifierObjectRedeclarationC.expected index 34a7723bcd..9c357cf38f 100644 --- a/c/misra/test/rules/RULE-8-8/MissingStaticSpecifierObjectRedeclarationC.expected +++ b/c/misra/test/rules/RULE-8-8/MissingStaticSpecifierObjectRedeclarationC.expected @@ -1 +1 @@ -| test.c:2:12:2:12 | declaration of g | The redeclaration of $@ with internal linkage misses the static specifier. | test.c:1:12:1:12 | definition of g | g | +| test.c:7:12:7:12 | declaration of g | The redeclaration of $@ with internal linkage misses the static specifier. | test.c:6:12:6:12 | definition of g | g | diff --git a/c/misra/test/rules/RULE-8-8/test.c b/c/misra/test/rules/RULE-8-8/test.c index d98d71c6f0..ba78432a40 100644 --- a/c/misra/test/rules/RULE-8-8/test.c +++ b/c/misra/test/rules/RULE-8-8/test.c @@ -1,3 +1,8 @@ +// Note: A subset of these cases are also tested in c/misra/test/rules/RULE-1-5 +// via a MissingStaticSpecifierObjectRedeclarationC.qlref and .expected file in +// that directory. Changes to these tests may require updating the test code or +// expectations in that directory as well. + static int g = 0; extern int g; // NON_COMPLIANT From 730341f99138ca5451dc62e8db19d77a980266d7 Mon Sep 17 00:00:00 2001 From: Mike Fairhurst Date: Fri, 4 Oct 2024 13:03:25 -0700 Subject: [PATCH 09/15] Fix rule schema for implementation_scope in queries. --- schemas/rule-package.schema.json | 36 ++++++++++++++++---------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/schemas/rule-package.schema.json b/schemas/rule-package.schema.json index 63cbbf3ac5..a43deb2141 100644 --- a/schemas/rule-package.schema.json +++ b/schemas/rule-package.schema.json @@ -351,7 +351,7 @@ "minLength": 1 }, "implementation_scope": { - "$ref": "#/$defs/implementation_scope" + "$ref": "/schemas/implementation_scope" } }, "required": [ @@ -363,24 +363,24 @@ "tags" ] }, - "implementation_scope": { + "implementation_scope": { "$id": "/schemas/implementation_scope", - "type": "object", - "properties": { - "description": { - "kind": "string" - }, - "items": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "required": [ - "description" - ], - "additionalProperties": false + "type": "object", + "properties": { + "description": { + "kind": "string" + }, + "items": { + "type": "array", + "items": { + "type": "string" + } } + }, + "required": [ + "description" + ], + "additionalProperties": false + } } } \ No newline at end of file From b7783606813a27a79cfec71e6fc1de62a980f5df Mon Sep 17 00:00:00 2001 From: Mike Fairhurst Date: Thu, 17 Oct 2024 15:05:20 -0700 Subject: [PATCH 10/15] Use shared queries / generally report obsolescent features even if redundant. Redundant reports should not be a common user issue; these features are obsolescent and likely rarely used and less often to be excepted. Implement ungetc() on a zero-offset stream and specific banning of gets(), as the redundant rules for those obsolescent features report a far wider set of issues than banned by RULE-1-5. Implementation of banning ungetc() on a zero-offset stream is not thorough or comprehensive. This should be fine. False positives should not create any user issues because the call of the function overall is banned. And false negatives should not be an issue, for the same reason. --- ...tionTypesNotInPrototypeFormShared.expected | 4 + ...esNotInPrototypeFormShared.expected.clang} | 0 .../FunctionTypesNotInPrototypeFormShared.ql | 4 + .../test.c | 5 -- .../test.c.clang | 0 ...pecifierObjectRedeclarationShared.expected | 1 + ...taticSpecifierObjectRedeclarationShared.ql | 5 ++ .../test.c | 8 ++ .../RULE-1-5/CallToObsolescentFunctionGets.ql | 22 +++++ ...FunctionTypesNotInPrototypeFormObsolete.ql | 23 +++++ ...taticSpecifierFuncRedeclarationObsolete.ql | 23 +++++ ...ticSpecifierObjectRedeclarationObsolete.ql | 23 +++++ .../UngetcCallOnStreamPositionZero.ql | 69 +++++++++++++++ .../FunctionTypesNotInPrototypeForm.ql | 46 ++-------- ...singStaticSpecifierObjectRedeclarationC.ql | 17 ++-- .../CallToObsolescentFunctionGets.expected | 1 + .../CallToObsolescentFunctionGets.qlref | 1 + .../FunctionTypesNotInPrototypeForm.expected | 2 - .../FunctionTypesNotInPrototypeForm.qlref | 1 - ...ionTypesNotInPrototypeFormObsolete.testref | 1 + ...llocDeallocFunctionsOfStdlibhUsed.expected | 3 - ...ryAllocDeallocFunctionsOfStdlibhUsed.qlref | 1 - ...SpecifierFuncRedeclarationObsolete.testref | 1 + ...aticSpecifierObjectRedeclarationC.expected | 1 - ...gStaticSpecifierObjectRedeclarationC.qlref | 1 - ...ecifierObjectRedeclarationObsolete.testref | 1 + ...rdLibraryInputoutputFunctionsUsed.expected | 3 - ...ndardLibraryInputoutputFunctionsUsed.qlref | 1 - .../UngetcCallOnStreamPositionZero.expected | 1 + .../UngetcCallOnStreamPositionZero.qlref | 1 + c/misra/test/rules/RULE-1-5/test.c | 27 ++---- .../FunctionTypesNotInPrototypeForm.expected | 4 - .../FunctionTypesNotInPrototypeForm.qlref | 1 - .../FunctionTypesNotInPrototypeForm.testref | 1 + ...aticSpecifierObjectRedeclarationC.expected | 1 - ...gStaticSpecifierObjectRedeclarationC.qlref | 1 - ...taticSpecifierObjectRedeclarationC.testref | 1 + c/misra/test/rules/RULE-8-8/test.c | 13 --- .../cpp/exclusions/c/Language4.qll | 85 +++++++++++++++++++ .../FunctionTypesNotInPrototypeFormShared.qll | 54 ++++++++++++ ...aticSpecifierObjectRedeclarationShared.qll | 27 ++++++ rule_packages/c/Declarations4.json | 1 + rule_packages/c/Declarations5.json | 1 + rule_packages/c/Language4.json | 77 ++++++++++++++++- 44 files changed, 450 insertions(+), 114 deletions(-) create mode 100644 c/common/test/rules/functiontypesnotinprototypeformshared/FunctionTypesNotInPrototypeFormShared.expected rename c/{misra/test/rules/RULE-8-2/FunctionTypesNotInPrototypeForm.expected.clang => common/test/rules/functiontypesnotinprototypeformshared/FunctionTypesNotInPrototypeFormShared.expected.clang} (100%) create mode 100644 c/common/test/rules/functiontypesnotinprototypeformshared/FunctionTypesNotInPrototypeFormShared.ql rename c/{misra/test/rules/RULE-8-2 => common/test/rules/functiontypesnotinprototypeformshared}/test.c (50%) rename c/{misra/test/rules/RULE-8-2 => common/test/rules/functiontypesnotinprototypeformshared}/test.c.clang (100%) create mode 100644 c/common/test/rules/missingstaticspecifierobjectredeclarationshared/MissingStaticSpecifierObjectRedeclarationShared.expected create mode 100644 c/common/test/rules/missingstaticspecifierobjectredeclarationshared/MissingStaticSpecifierObjectRedeclarationShared.ql create mode 100644 c/common/test/rules/missingstaticspecifierobjectredeclarationshared/test.c create mode 100644 c/misra/src/rules/RULE-1-5/CallToObsolescentFunctionGets.ql create mode 100644 c/misra/src/rules/RULE-1-5/FunctionTypesNotInPrototypeFormObsolete.ql create mode 100644 c/misra/src/rules/RULE-1-5/MissingStaticSpecifierFuncRedeclarationObsolete.ql create mode 100644 c/misra/src/rules/RULE-1-5/MissingStaticSpecifierObjectRedeclarationObsolete.ql create mode 100644 c/misra/src/rules/RULE-1-5/UngetcCallOnStreamPositionZero.ql create mode 100644 c/misra/test/rules/RULE-1-5/CallToObsolescentFunctionGets.expected create mode 100644 c/misra/test/rules/RULE-1-5/CallToObsolescentFunctionGets.qlref delete mode 100644 c/misra/test/rules/RULE-1-5/FunctionTypesNotInPrototypeForm.expected delete mode 100644 c/misra/test/rules/RULE-1-5/FunctionTypesNotInPrototypeForm.qlref create mode 100644 c/misra/test/rules/RULE-1-5/FunctionTypesNotInPrototypeFormObsolete.testref delete mode 100644 c/misra/test/rules/RULE-1-5/MemoryAllocDeallocFunctionsOfStdlibhUsed.expected delete mode 100644 c/misra/test/rules/RULE-1-5/MemoryAllocDeallocFunctionsOfStdlibhUsed.qlref create mode 100644 c/misra/test/rules/RULE-1-5/MissingStaticSpecifierFuncRedeclarationObsolete.testref delete mode 100644 c/misra/test/rules/RULE-1-5/MissingStaticSpecifierObjectRedeclarationC.expected delete mode 100644 c/misra/test/rules/RULE-1-5/MissingStaticSpecifierObjectRedeclarationC.qlref create mode 100644 c/misra/test/rules/RULE-1-5/MissingStaticSpecifierObjectRedeclarationObsolete.testref delete mode 100644 c/misra/test/rules/RULE-1-5/StandardLibraryInputoutputFunctionsUsed.expected delete mode 100644 c/misra/test/rules/RULE-1-5/StandardLibraryInputoutputFunctionsUsed.qlref create mode 100644 c/misra/test/rules/RULE-1-5/UngetcCallOnStreamPositionZero.expected create mode 100644 c/misra/test/rules/RULE-1-5/UngetcCallOnStreamPositionZero.qlref delete mode 100644 c/misra/test/rules/RULE-8-2/FunctionTypesNotInPrototypeForm.expected delete mode 100644 c/misra/test/rules/RULE-8-2/FunctionTypesNotInPrototypeForm.qlref create mode 100644 c/misra/test/rules/RULE-8-2/FunctionTypesNotInPrototypeForm.testref delete mode 100644 c/misra/test/rules/RULE-8-8/MissingStaticSpecifierObjectRedeclarationC.expected delete mode 100644 c/misra/test/rules/RULE-8-8/MissingStaticSpecifierObjectRedeclarationC.qlref create mode 100644 c/misra/test/rules/RULE-8-8/MissingStaticSpecifierObjectRedeclarationC.testref delete mode 100644 c/misra/test/rules/RULE-8-8/test.c create mode 100644 cpp/common/src/codingstandards/cpp/rules/functiontypesnotinprototypeformshared/FunctionTypesNotInPrototypeFormShared.qll create mode 100644 cpp/common/src/codingstandards/cpp/rules/missingstaticspecifierobjectredeclarationshared/MissingStaticSpecifierObjectRedeclarationShared.qll diff --git a/c/common/test/rules/functiontypesnotinprototypeformshared/FunctionTypesNotInPrototypeFormShared.expected b/c/common/test/rules/functiontypesnotinprototypeformshared/FunctionTypesNotInPrototypeFormShared.expected new file mode 100644 index 0000000000..f2c08897b8 --- /dev/null +++ b/c/common/test/rules/functiontypesnotinprototypeformshared/FunctionTypesNotInPrototypeFormShared.expected @@ -0,0 +1,4 @@ +| test.c:3:6:3:7 | f1 | Function f1 declares parameter that is unnamed. | +| test.c:4:6:4:7 | f2 | Function f2 does not specify void for no parameters present. | +| test.c:5:6:5:7 | f3 | Function f3 does not specify void for no parameters present. | +| test.c:7:5:7:6 | f5 | Function f5 declares parameter in unsupported declaration list. | diff --git a/c/misra/test/rules/RULE-8-2/FunctionTypesNotInPrototypeForm.expected.clang b/c/common/test/rules/functiontypesnotinprototypeformshared/FunctionTypesNotInPrototypeFormShared.expected.clang similarity index 100% rename from c/misra/test/rules/RULE-8-2/FunctionTypesNotInPrototypeForm.expected.clang rename to c/common/test/rules/functiontypesnotinprototypeformshared/FunctionTypesNotInPrototypeFormShared.expected.clang diff --git a/c/common/test/rules/functiontypesnotinprototypeformshared/FunctionTypesNotInPrototypeFormShared.ql b/c/common/test/rules/functiontypesnotinprototypeformshared/FunctionTypesNotInPrototypeFormShared.ql new file mode 100644 index 0000000000..25d273354d --- /dev/null +++ b/c/common/test/rules/functiontypesnotinprototypeformshared/FunctionTypesNotInPrototypeFormShared.ql @@ -0,0 +1,4 @@ +// GENERATED FILE - DO NOT MODIFY +import codingstandards.cpp.rules.functiontypesnotinprototypeformshared.FunctionTypesNotInPrototypeFormShared + +class TestFileQuery extends FunctionTypesNotInPrototypeFormSharedSharedQuery, TestQuery { } diff --git a/c/misra/test/rules/RULE-8-2/test.c b/c/common/test/rules/functiontypesnotinprototypeformshared/test.c similarity index 50% rename from c/misra/test/rules/RULE-8-2/test.c rename to c/common/test/rules/functiontypesnotinprototypeformshared/test.c index 1ed64c0011..c254a221d9 100644 --- a/c/misra/test/rules/RULE-8-2/test.c +++ b/c/common/test/rules/functiontypesnotinprototypeformshared/test.c @@ -1,8 +1,3 @@ -// Note: A subset of these cases are also tested in c/misra/test/rules/RULE-1-5 -// via a FunctionTypesNotInPrototypeForm.qlref and .expected file in that -// directory. Changes to these tests may require updating the test code or -// expectations in that directory as well. - void f(int x); // COMPLIANT void f0(void); // COMPLIANT void f1(int); // NON_COMPLIANT diff --git a/c/misra/test/rules/RULE-8-2/test.c.clang b/c/common/test/rules/functiontypesnotinprototypeformshared/test.c.clang similarity index 100% rename from c/misra/test/rules/RULE-8-2/test.c.clang rename to c/common/test/rules/functiontypesnotinprototypeformshared/test.c.clang diff --git a/c/common/test/rules/missingstaticspecifierobjectredeclarationshared/MissingStaticSpecifierObjectRedeclarationShared.expected b/c/common/test/rules/missingstaticspecifierobjectredeclarationshared/MissingStaticSpecifierObjectRedeclarationShared.expected new file mode 100644 index 0000000000..34a7723bcd --- /dev/null +++ b/c/common/test/rules/missingstaticspecifierobjectredeclarationshared/MissingStaticSpecifierObjectRedeclarationShared.expected @@ -0,0 +1 @@ +| test.c:2:12:2:12 | declaration of g | The redeclaration of $@ with internal linkage misses the static specifier. | test.c:1:12:1:12 | definition of g | g | diff --git a/c/common/test/rules/missingstaticspecifierobjectredeclarationshared/MissingStaticSpecifierObjectRedeclarationShared.ql b/c/common/test/rules/missingstaticspecifierobjectredeclarationshared/MissingStaticSpecifierObjectRedeclarationShared.ql new file mode 100644 index 0000000000..3d6d2019fb --- /dev/null +++ b/c/common/test/rules/missingstaticspecifierobjectredeclarationshared/MissingStaticSpecifierObjectRedeclarationShared.ql @@ -0,0 +1,5 @@ +// GENERATED FILE - DO NOT MODIFY +import codingstandards.cpp.rules.missingstaticspecifierobjectredeclarationshared.MissingStaticSpecifierObjectRedeclarationShared + +class TestFileQuery extends MissingStaticSpecifierObjectRedeclarationSharedSharedQuery, TestQuery { +} diff --git a/c/common/test/rules/missingstaticspecifierobjectredeclarationshared/test.c b/c/common/test/rules/missingstaticspecifierobjectredeclarationshared/test.c new file mode 100644 index 0000000000..d98d71c6f0 --- /dev/null +++ b/c/common/test/rules/missingstaticspecifierobjectredeclarationshared/test.c @@ -0,0 +1,8 @@ +static int g = 0; +extern int g; // NON_COMPLIANT + +static int g1; +static int g1 = 0; // COMPLIANT + +int g2; +int g2 = 0; // COMPLIANT diff --git a/c/misra/src/rules/RULE-1-5/CallToObsolescentFunctionGets.ql b/c/misra/src/rules/RULE-1-5/CallToObsolescentFunctionGets.ql new file mode 100644 index 0000000000..4994c4ea6e --- /dev/null +++ b/c/misra/src/rules/RULE-1-5/CallToObsolescentFunctionGets.ql @@ -0,0 +1,22 @@ +/** + * @id c/misra/call-to-obsolescent-function-gets + * @name RULE-1-5: Disallowed usage of obsolescent function 'gets' + * @description The function 'gets' is an obsolescent language feature which was removed in C11. + * @kind problem + * @precision very-high + * @problem.severity error + * @tags external/misra/id/rule-1-5 + * external/misra/c/2012/amendment3 + * security + * maintainability + * external/misra/obligation/required + */ + +import cpp +import codingstandards.c.misra + +from FunctionCall fc +where + not isExcluded(fc, Language4Package::callToObsolescentFunctionGetsQuery()) and + fc.getTarget().hasGlobalOrStdName("gets") +select fc, "Call to obsolescent function 'gets'." diff --git a/c/misra/src/rules/RULE-1-5/FunctionTypesNotInPrototypeFormObsolete.ql b/c/misra/src/rules/RULE-1-5/FunctionTypesNotInPrototypeFormObsolete.ql new file mode 100644 index 0000000000..8f0e626bc8 --- /dev/null +++ b/c/misra/src/rules/RULE-1-5/FunctionTypesNotInPrototypeFormObsolete.ql @@ -0,0 +1,23 @@ +/** + * @id c/misra/function-types-not-in-prototype-form-obsolete + * @name RULE-1-5: Function types shall be in prototype form with named parameters + * @description The use of non-prototype format parameter type declarators is an obsolescent + * language feature. + * @kind problem + * @precision medium + * @problem.severity error + * @tags external/misra/id/rule-1-5 + * correctness + * external/misra/c/2012/amendment3 + * external/misra/obligation/required + */ + +import cpp +import codingstandards.c.misra +import codingstandards.cpp.rules.functiontypesnotinprototypeformshared.FunctionTypesNotInPrototypeFormShared + +class FunctionTypesNotInPrototypeFormObsoleteQuery extends FunctionTypesNotInPrototypeFormSharedSharedQuery { + FunctionTypesNotInPrototypeFormObsoleteQuery() { + this = Language4Package::functionTypesNotInPrototypeFormObsoleteQuery() + } +} diff --git a/c/misra/src/rules/RULE-1-5/MissingStaticSpecifierFuncRedeclarationObsolete.ql b/c/misra/src/rules/RULE-1-5/MissingStaticSpecifierFuncRedeclarationObsolete.ql new file mode 100644 index 0000000000..5a70e0287a --- /dev/null +++ b/c/misra/src/rules/RULE-1-5/MissingStaticSpecifierFuncRedeclarationObsolete.ql @@ -0,0 +1,23 @@ +/** + * @id c/misra/missing-static-specifier-func-redeclaration-obsolete + * @name RULE-1-5: If a function has internal linkage then all re-declarations shall include the static storage class + * @description Declaring a function with internal linkage without the static storage class + * specifier is an obselescent feature. + * @kind problem + * @precision very-high + * @problem.severity warning + * @tags external/misra/id/rule-1-5 + * readability + * external/misra/c/2012/amendment3 + * external/misra/obligation/required + */ + +import cpp +import codingstandards.c.misra +import codingstandards.cpp.rules.missingstaticspecifierfunctionredeclarationshared.MissingStaticSpecifierFunctionRedeclarationShared + +class MissingStaticSpecifierFuncRedeclarationObsoleteQuery extends MissingStaticSpecifierFunctionRedeclarationSharedSharedQuery { + MissingStaticSpecifierFuncRedeclarationObsoleteQuery() { + this = Language4Package::missingStaticSpecifierFuncRedeclarationObsoleteQuery() + } +} diff --git a/c/misra/src/rules/RULE-1-5/MissingStaticSpecifierObjectRedeclarationObsolete.ql b/c/misra/src/rules/RULE-1-5/MissingStaticSpecifierObjectRedeclarationObsolete.ql new file mode 100644 index 0000000000..5e32d57c6a --- /dev/null +++ b/c/misra/src/rules/RULE-1-5/MissingStaticSpecifierObjectRedeclarationObsolete.ql @@ -0,0 +1,23 @@ +/** + * @id c/misra/missing-static-specifier-object-redeclaration-obsolete + * @name RULE-1-5: If an object has internal linkage then all re-declarations shall include the static storage class + * @description Declaring an identifier with internal linkage without the static storage class + * specifier is an obselescent feature. + * @kind problem + * @precision very-high + * @problem.severity warning + * @tags external/misra/id/rule-1-5 + * readability + * external/misra/c/2012/amendment3 + * external/misra/obligation/required + */ + +import cpp +import codingstandards.c.misra +import codingstandards.cpp.rules.missingstaticspecifierobjectredeclarationshared.MissingStaticSpecifierObjectRedeclarationShared + +class MissingStaticSpecifierObjectRedeclarationObsoleteQuery extends MissingStaticSpecifierObjectRedeclarationSharedSharedQuery { + MissingStaticSpecifierObjectRedeclarationObsoleteQuery() { + this = Language4Package::missingStaticSpecifierObjectRedeclarationObsoleteQuery() + } +} diff --git a/c/misra/src/rules/RULE-1-5/UngetcCallOnStreamPositionZero.ql b/c/misra/src/rules/RULE-1-5/UngetcCallOnStreamPositionZero.ql new file mode 100644 index 0000000000..a973442203 --- /dev/null +++ b/c/misra/src/rules/RULE-1-5/UngetcCallOnStreamPositionZero.ql @@ -0,0 +1,69 @@ +/** + * @id c/misra/ungetc-call-on-stream-position-zero + * @name RULE-1-5: Disallowed obsolescent usage of 'ungetc' on a file stream at position zero + * @description Calling the function 'ungetc' on a file stream with a position of zero is an + * obsolescent language feature. + * @kind problem + * @precision medium + * @problem.severity error + * @tags external/misra/id/rule-1-5 + * external/misra/c/2012/amendment3 + * security + * maintainability + * external/misra/obligation/required + */ + +import cpp +import semmle.code.cpp.dataflow.new.DataFlow +import semmle.code.cpp.controlflow.Dominance +import codingstandards.c.misra + +/** + * This is an inconclusive list, which is adequate, as RULE-21-3 provides + * assurance we won't have false negatives, or care too much about false + * positives. + */ +class MoveStreamPositionCall extends FunctionCall { + Expr streamArgument; + + MoveStreamPositionCall() { + getTarget().hasGlobalOrStdName("fgetc") and + streamArgument = getArgument(0) + or + getTarget().hasGlobalOrStdName("getc") and + streamArgument = getArgument(0) + or + getTarget().hasGlobalOrStdName("fget") and + streamArgument = getArgument(2) + or + getTarget().hasGlobalOrStdName("fscanf") and + streamArgument = getArgument(0) + or + getTarget().hasGlobalOrStdName("fsetpos") and + streamArgument = getArgument(0) + or + getTarget().hasGlobalOrStdName("fseek") and + streamArgument = getArgument(0) + or + getTarget().hasGlobalOrStdName("fread") and + streamArgument = getArgument(3) + } + + Expr getStreamArgument() { result = streamArgument } +} + +from FunctionCall ungetc, DataFlow::Node file +where + not isExcluded(ungetc, Language4Package::ungetcCallOnStreamPositionZeroQuery()) and + // ungetc() called on file stream + ungetc.getTarget().hasGlobalOrStdName("ungetc") and + DataFlow::localFlow(file, DataFlow::exprNode(ungetc.getArgument(1))) and + // ungetc() is not dominated by a fread() etc to that file stream + not exists(MoveStreamPositionCall moveStreamCall | + DataFlow::localFlow(file, DataFlow::exprNode(moveStreamCall.getStreamArgument())) and + dominates(moveStreamCall, ungetc) + ) + // the file stream is the root of the local data flow + and not DataFlow::localFlow(any(DataFlow::Node n | not n = file), file) +select ungetc, "Obsolescent call to ungetc on file stream $@ at position zero.", file, + file.toString() diff --git a/c/misra/src/rules/RULE-8-2/FunctionTypesNotInPrototypeForm.ql b/c/misra/src/rules/RULE-8-2/FunctionTypesNotInPrototypeForm.ql index 73294d776b..1136dd714e 100644 --- a/c/misra/src/rules/RULE-8-2/FunctionTypesNotInPrototypeForm.ql +++ b/c/misra/src/rules/RULE-8-2/FunctionTypesNotInPrototypeForm.ql @@ -14,46 +14,10 @@ import cpp import codingstandards.c.misra -import codingstandards.cpp.Identifiers +import codingstandards.cpp.rules.functiontypesnotinprototypeformshared.FunctionTypesNotInPrototypeFormShared -/** - * `Parameter`s without names - */ -class UnnamedParameter extends Parameter { - UnnamedParameter() { not this.isNamed() } +class FunctionTypesNotInPrototypeFormQuery extends FunctionTypesNotInPrototypeFormSharedSharedQuery { + FunctionTypesNotInPrototypeFormQuery() { + this = Declarations4Package::functionTypesNotInPrototypeFormQuery() + } } - -/* - * This is a copy of the private `hasZeroParamDecl` predicate from the standard set of - * queries as of the `codeql-cli/2.11.2` tag in `github/codeql`. - */ - -predicate hasZeroParamDecl(Function f) { - exists(FunctionDeclarationEntry fde | fde = f.getADeclarationEntry() | - not fde.isImplicit() and - not fde.hasVoidParamList() and - fde.getNumberOfParameters() = 0 and - not fde.isDefinition() - ) -} - -from Function f, string msg -where - not isExcluded(f, Declarations4Package::functionTypesNotInPrototypeFormQuery()) and - f instanceof InterestingIdentifiers and - ( - f.getAParameter() instanceof UnnamedParameter and - msg = "Function " + f + " declares parameter that is unnamed." - or - hasZeroParamDecl(f) and - msg = "Function " + f + " does not specify void for no parameters present." - or - //parameters declared in declaration list (not in function signature) - //have placeholder file location associated only - exists(Parameter p | - p.getFunction() = f and - not p.getFile() = f.getFile() and - msg = "Function " + f + " declares parameter in unsupported declaration list." - ) - ) -select f, msg diff --git a/c/misra/src/rules/RULE-8-8/MissingStaticSpecifierObjectRedeclarationC.ql b/c/misra/src/rules/RULE-8-8/MissingStaticSpecifierObjectRedeclarationC.ql index 65c878e883..6f731c636f 100644 --- a/c/misra/src/rules/RULE-8-8/MissingStaticSpecifierObjectRedeclarationC.ql +++ b/c/misra/src/rules/RULE-8-8/MissingStaticSpecifierObjectRedeclarationC.ql @@ -14,15 +14,10 @@ import cpp import codingstandards.c.misra +import codingstandards.cpp.rules.missingstaticspecifierobjectredeclarationshared.MissingStaticSpecifierObjectRedeclarationShared -from VariableDeclarationEntry redeclaration, VariableDeclarationEntry de -where - not isExcluded(redeclaration, - Declarations5Package::missingStaticSpecifierObjectRedeclarationCQuery()) and - //following implies de != redeclaration - de.hasSpecifier("static") and - not redeclaration.hasSpecifier("static") and - de.getDeclaration().isTopLevel() and - redeclaration.getDeclaration() = de.getDeclaration() -select redeclaration, "The redeclaration of $@ with internal linkage misses the static specifier.", - de, de.getName() +class MissingStaticSpecifierObjectRedeclarationCQuery extends MissingStaticSpecifierObjectRedeclarationSharedSharedQuery { + MissingStaticSpecifierObjectRedeclarationCQuery() { + this = Declarations5Package::missingStaticSpecifierObjectRedeclarationCQuery() + } +} diff --git a/c/misra/test/rules/RULE-1-5/CallToObsolescentFunctionGets.expected b/c/misra/test/rules/RULE-1-5/CallToObsolescentFunctionGets.expected new file mode 100644 index 0000000000..6e0088f4ac --- /dev/null +++ b/c/misra/test/rules/RULE-1-5/CallToObsolescentFunctionGets.expected @@ -0,0 +1 @@ +| test.c:36:3:36:6 | call to gets | Call to obsolescent function 'gets'. | diff --git a/c/misra/test/rules/RULE-1-5/CallToObsolescentFunctionGets.qlref b/c/misra/test/rules/RULE-1-5/CallToObsolescentFunctionGets.qlref new file mode 100644 index 0000000000..1a2ec096cf --- /dev/null +++ b/c/misra/test/rules/RULE-1-5/CallToObsolescentFunctionGets.qlref @@ -0,0 +1 @@ +rules/RULE-1-5/CallToObsolescentFunctionGets.ql \ No newline at end of file diff --git a/c/misra/test/rules/RULE-1-5/FunctionTypesNotInPrototypeForm.expected b/c/misra/test/rules/RULE-1-5/FunctionTypesNotInPrototypeForm.expected deleted file mode 100644 index 29faec8b55..0000000000 --- a/c/misra/test/rules/RULE-1-5/FunctionTypesNotInPrototypeForm.expected +++ /dev/null @@ -1,2 +0,0 @@ -| test.c:38:6:38:7 | f2 | Function f2 does not specify void for no parameters present. | -| test.c:42:5:42:6 | f5 | Function f5 declares parameter in unsupported declaration list. | \ No newline at end of file diff --git a/c/misra/test/rules/RULE-1-5/FunctionTypesNotInPrototypeForm.qlref b/c/misra/test/rules/RULE-1-5/FunctionTypesNotInPrototypeForm.qlref deleted file mode 100644 index 0a6121b324..0000000000 --- a/c/misra/test/rules/RULE-1-5/FunctionTypesNotInPrototypeForm.qlref +++ /dev/null @@ -1 +0,0 @@ -rules/RULE-8-2/FunctionTypesNotInPrototypeForm.ql \ No newline at end of file diff --git a/c/misra/test/rules/RULE-1-5/FunctionTypesNotInPrototypeFormObsolete.testref b/c/misra/test/rules/RULE-1-5/FunctionTypesNotInPrototypeFormObsolete.testref new file mode 100644 index 0000000000..1a6a69fc24 --- /dev/null +++ b/c/misra/test/rules/RULE-1-5/FunctionTypesNotInPrototypeFormObsolete.testref @@ -0,0 +1 @@ +c/common/test/rules/functiontypesnotinprototypeformshared/FunctionTypesNotInPrototypeFormShared.ql \ No newline at end of file diff --git a/c/misra/test/rules/RULE-1-5/MemoryAllocDeallocFunctionsOfStdlibhUsed.expected b/c/misra/test/rules/RULE-1-5/MemoryAllocDeallocFunctionsOfStdlibhUsed.expected deleted file mode 100644 index de87fc8542..0000000000 --- a/c/misra/test/rules/RULE-1-5/MemoryAllocDeallocFunctionsOfStdlibhUsed.expected +++ /dev/null @@ -1,3 +0,0 @@ -| test.c:8:12:8:17 | call to malloc | Use of banned dynamic memory allocation. | -| test.c:11:3:11:9 | call to realloc | Use of banned dynamic memory allocation. | -| test.c:14:3:14:9 | call to realloc | Use of banned dynamic memory allocation. | diff --git a/c/misra/test/rules/RULE-1-5/MemoryAllocDeallocFunctionsOfStdlibhUsed.qlref b/c/misra/test/rules/RULE-1-5/MemoryAllocDeallocFunctionsOfStdlibhUsed.qlref deleted file mode 100644 index 8f64b81ced..0000000000 --- a/c/misra/test/rules/RULE-1-5/MemoryAllocDeallocFunctionsOfStdlibhUsed.qlref +++ /dev/null @@ -1 +0,0 @@ -rules/RULE-21-3/MemoryAllocDeallocFunctionsOfStdlibhUsed.ql \ No newline at end of file diff --git a/c/misra/test/rules/RULE-1-5/MissingStaticSpecifierFuncRedeclarationObsolete.testref b/c/misra/test/rules/RULE-1-5/MissingStaticSpecifierFuncRedeclarationObsolete.testref new file mode 100644 index 0000000000..7d9f2ebc04 --- /dev/null +++ b/c/misra/test/rules/RULE-1-5/MissingStaticSpecifierFuncRedeclarationObsolete.testref @@ -0,0 +1 @@ +c/common/test/rules/missingstaticspecifierfunctionredeclarationshared/MissingStaticSpecifierFunctionRedeclarationShared.ql \ No newline at end of file diff --git a/c/misra/test/rules/RULE-1-5/MissingStaticSpecifierObjectRedeclarationC.expected b/c/misra/test/rules/RULE-1-5/MissingStaticSpecifierObjectRedeclarationC.expected deleted file mode 100644 index 48275eb504..0000000000 --- a/c/misra/test/rules/RULE-1-5/MissingStaticSpecifierObjectRedeclarationC.expected +++ /dev/null @@ -1 +0,0 @@ -| test.c:35:12:35:13 | declaration of g5 | The redeclaration of $@ with internal linkage misses the static specifier. | test.c:34:12:34:13 | definition of g5 | g5 | diff --git a/c/misra/test/rules/RULE-1-5/MissingStaticSpecifierObjectRedeclarationC.qlref b/c/misra/test/rules/RULE-1-5/MissingStaticSpecifierObjectRedeclarationC.qlref deleted file mode 100644 index 70b6073e14..0000000000 --- a/c/misra/test/rules/RULE-1-5/MissingStaticSpecifierObjectRedeclarationC.qlref +++ /dev/null @@ -1 +0,0 @@ -rules/RULE-8-8/MissingStaticSpecifierObjectRedeclarationC.ql \ No newline at end of file diff --git a/c/misra/test/rules/RULE-1-5/MissingStaticSpecifierObjectRedeclarationObsolete.testref b/c/misra/test/rules/RULE-1-5/MissingStaticSpecifierObjectRedeclarationObsolete.testref new file mode 100644 index 0000000000..23ed7c9fc5 --- /dev/null +++ b/c/misra/test/rules/RULE-1-5/MissingStaticSpecifierObjectRedeclarationObsolete.testref @@ -0,0 +1 @@ +c/common/test/rules/missingstaticspecifierobjectredeclarationshared/MissingStaticSpecifierObjectRedeclarationShared.ql \ No newline at end of file diff --git a/c/misra/test/rules/RULE-1-5/StandardLibraryInputoutputFunctionsUsed.expected b/c/misra/test/rules/RULE-1-5/StandardLibraryInputoutputFunctionsUsed.expected deleted file mode 100644 index 396b181150..0000000000 --- a/c/misra/test/rules/RULE-1-5/StandardLibraryInputoutputFunctionsUsed.expected +++ /dev/null @@ -1,3 +0,0 @@ -| test.c:53:3:53:8 | call to ungetc | Call to banned function ungetc. | -| test.c:56:3:56:7 | call to fread | Call to banned function fread. | -| test.c:58:3:58:8 | call to ungetc | Call to banned function ungetc. | diff --git a/c/misra/test/rules/RULE-1-5/StandardLibraryInputoutputFunctionsUsed.qlref b/c/misra/test/rules/RULE-1-5/StandardLibraryInputoutputFunctionsUsed.qlref deleted file mode 100644 index 0a8cd754ef..0000000000 --- a/c/misra/test/rules/RULE-1-5/StandardLibraryInputoutputFunctionsUsed.qlref +++ /dev/null @@ -1 +0,0 @@ -rules/RULE-21-6/StandardLibraryInputoutputFunctionsUsed.ql \ No newline at end of file diff --git a/c/misra/test/rules/RULE-1-5/UngetcCallOnStreamPositionZero.expected b/c/misra/test/rules/RULE-1-5/UngetcCallOnStreamPositionZero.expected new file mode 100644 index 0000000000..4dd298197f --- /dev/null +++ b/c/misra/test/rules/RULE-1-5/UngetcCallOnStreamPositionZero.expected @@ -0,0 +1 @@ +| test.c:40:3:40:8 | call to ungetc | Obsolescent call to ungetc on file stream $@ at position zero. | test.c:38:16:38:20 | call to fopen | call to fopen | diff --git a/c/misra/test/rules/RULE-1-5/UngetcCallOnStreamPositionZero.qlref b/c/misra/test/rules/RULE-1-5/UngetcCallOnStreamPositionZero.qlref new file mode 100644 index 0000000000..8c28919dcb --- /dev/null +++ b/c/misra/test/rules/RULE-1-5/UngetcCallOnStreamPositionZero.qlref @@ -0,0 +1 @@ +rules/RULE-1-5/UngetcCallOnStreamPositionZero.ql \ No newline at end of file diff --git a/c/misra/test/rules/RULE-1-5/test.c b/c/misra/test/rules/RULE-1-5/test.c index 4709381898..7632e0a727 100644 --- a/c/misra/test/rules/RULE-1-5/test.c +++ b/c/misra/test/rules/RULE-1-5/test.c @@ -4,8 +4,8 @@ #include "stdlib.h" void f1(void) { - // malloc() is not obsolete, but banned by Rule 21.3 - int *t = malloc(10); // COMPLIANT[False Negative] + // malloc() is not obsolete, though it is banned by Rule 21.3 + int *t = malloc(10); // COMPLIANT // Obsolete usage of realloc. realloc(t, 0); // NON-COMPLIANT @@ -28,25 +28,12 @@ const extern int g2; // NON-COMPLIANT _Atomic int g3 = ATOMIC_VAR_INIT(18); // NON-COMPLIANT _Atomic int g4 = 18; // COMPLIANT -// The following cases are already covered by other rules: - -// Rule 8.8: -static int g5 = 3; // COMPLIANT -extern int g5; // NON-COMPLIANT - -// Rule 8.2: -void f2(); // NON-COMPLIANT -void f3(void); // COMPLIANT - -void f4(int p1){}; // COMPLIANT -int f5(x) // NON_COMPLIANT -int x; -{ return 1; } +// `gets` was removed from C11. +extern char* gets(FILE *stream); // Rule 21.6 covers the below cases: void f6(void) { - // `gets` was removed from C11. - // gets(stdin); // NON_COMPLIANT + gets(stdin); // NON_COMPLIANT FILE *file = fopen("", 0); // Obsolete usage of ungetc. @@ -54,6 +41,6 @@ void f6(void) { char buf[10]; fread(buf, sizeof(buf), 10, file); - // This is not an obsolete usage of ungetc, but ungetc isn't allowed. - ungetc('c', file); // NON-COMPLIANT[FALSE NEGATIVE] + // This is not an obsolete usage of ungetc, though ungetc isn't allowed by 21-3. + ungetc('c', file); // COMPLIANT } \ No newline at end of file diff --git a/c/misra/test/rules/RULE-8-2/FunctionTypesNotInPrototypeForm.expected b/c/misra/test/rules/RULE-8-2/FunctionTypesNotInPrototypeForm.expected deleted file mode 100644 index 1264797088..0000000000 --- a/c/misra/test/rules/RULE-8-2/FunctionTypesNotInPrototypeForm.expected +++ /dev/null @@ -1,4 +0,0 @@ -| test.c:8:6:8:7 | f1 | Function f1 declares parameter that is unnamed. | -| test.c:9:6:9:7 | f2 | Function f2 does not specify void for no parameters present. | -| test.c:10:6:10:7 | f3 | Function f3 does not specify void for no parameters present. | -| test.c:12:5:12:6 | f5 | Function f5 declares parameter in unsupported declaration list. | diff --git a/c/misra/test/rules/RULE-8-2/FunctionTypesNotInPrototypeForm.qlref b/c/misra/test/rules/RULE-8-2/FunctionTypesNotInPrototypeForm.qlref deleted file mode 100644 index 0a6121b324..0000000000 --- a/c/misra/test/rules/RULE-8-2/FunctionTypesNotInPrototypeForm.qlref +++ /dev/null @@ -1 +0,0 @@ -rules/RULE-8-2/FunctionTypesNotInPrototypeForm.ql \ No newline at end of file diff --git a/c/misra/test/rules/RULE-8-2/FunctionTypesNotInPrototypeForm.testref b/c/misra/test/rules/RULE-8-2/FunctionTypesNotInPrototypeForm.testref new file mode 100644 index 0000000000..1a6a69fc24 --- /dev/null +++ b/c/misra/test/rules/RULE-8-2/FunctionTypesNotInPrototypeForm.testref @@ -0,0 +1 @@ +c/common/test/rules/functiontypesnotinprototypeformshared/FunctionTypesNotInPrototypeFormShared.ql \ No newline at end of file diff --git a/c/misra/test/rules/RULE-8-8/MissingStaticSpecifierObjectRedeclarationC.expected b/c/misra/test/rules/RULE-8-8/MissingStaticSpecifierObjectRedeclarationC.expected deleted file mode 100644 index 9c357cf38f..0000000000 --- a/c/misra/test/rules/RULE-8-8/MissingStaticSpecifierObjectRedeclarationC.expected +++ /dev/null @@ -1 +0,0 @@ -| test.c:7:12:7:12 | declaration of g | The redeclaration of $@ with internal linkage misses the static specifier. | test.c:6:12:6:12 | definition of g | g | diff --git a/c/misra/test/rules/RULE-8-8/MissingStaticSpecifierObjectRedeclarationC.qlref b/c/misra/test/rules/RULE-8-8/MissingStaticSpecifierObjectRedeclarationC.qlref deleted file mode 100644 index 70b6073e14..0000000000 --- a/c/misra/test/rules/RULE-8-8/MissingStaticSpecifierObjectRedeclarationC.qlref +++ /dev/null @@ -1 +0,0 @@ -rules/RULE-8-8/MissingStaticSpecifierObjectRedeclarationC.ql \ No newline at end of file diff --git a/c/misra/test/rules/RULE-8-8/MissingStaticSpecifierObjectRedeclarationC.testref b/c/misra/test/rules/RULE-8-8/MissingStaticSpecifierObjectRedeclarationC.testref new file mode 100644 index 0000000000..23ed7c9fc5 --- /dev/null +++ b/c/misra/test/rules/RULE-8-8/MissingStaticSpecifierObjectRedeclarationC.testref @@ -0,0 +1 @@ +c/common/test/rules/missingstaticspecifierobjectredeclarationshared/MissingStaticSpecifierObjectRedeclarationShared.ql \ No newline at end of file diff --git a/c/misra/test/rules/RULE-8-8/test.c b/c/misra/test/rules/RULE-8-8/test.c deleted file mode 100644 index ba78432a40..0000000000 --- a/c/misra/test/rules/RULE-8-8/test.c +++ /dev/null @@ -1,13 +0,0 @@ -// Note: A subset of these cases are also tested in c/misra/test/rules/RULE-1-5 -// via a MissingStaticSpecifierObjectRedeclarationC.qlref and .expected file in -// that directory. Changes to these tests may require updating the test code or -// expectations in that directory as well. - -static int g = 0; -extern int g; // NON_COMPLIANT - -static int g1; -static int g1 = 0; // COMPLIANT - -int g2; -int g2 = 0; // COMPLIANT diff --git a/cpp/common/src/codingstandards/cpp/exclusions/c/Language4.qll b/cpp/common/src/codingstandards/cpp/exclusions/c/Language4.qll index f26cae3e9a..7bca9feefc 100644 --- a/cpp/common/src/codingstandards/cpp/exclusions/c/Language4.qll +++ b/cpp/common/src/codingstandards/cpp/exclusions/c/Language4.qll @@ -4,11 +4,43 @@ import RuleMetadata import codingstandards.cpp.exclusions.RuleMetadata newtype Language4Query = + TMissingStaticSpecifierFuncRedeclarationObsoleteQuery() or + TMissingStaticSpecifierObjectRedeclarationObsoleteQuery() or + TFunctionTypesNotInPrototypeFormObsoleteQuery() or TUseOfObsoleteMacroAtomicVarInitQuery() or TInvalidDefineOrUndefOfStdBoolMacroQuery() or + TCallToObsolescentFunctionGetsQuery() or + TUngetcCallOnStreamPositionZeroQuery() or TCallToReallocWithSizeZeroQuery() predicate isLanguage4QueryMetadata(Query query, string queryId, string ruleId, string category) { + query = + // `Query` instance for the `missingStaticSpecifierFuncRedeclarationObsolete` query + Language4Package::missingStaticSpecifierFuncRedeclarationObsoleteQuery() and + queryId = + // `@id` for the `missingStaticSpecifierFuncRedeclarationObsolete` query + "c/misra/missing-static-specifier-func-redeclaration-obsolete" and + ruleId = "RULE-1-5" and + category = "required" + or + query = + // `Query` instance for the `missingStaticSpecifierObjectRedeclarationObsolete` query + Language4Package::missingStaticSpecifierObjectRedeclarationObsoleteQuery() and + queryId = + // `@id` for the `missingStaticSpecifierObjectRedeclarationObsolete` query + "c/misra/missing-static-specifier-object-redeclaration-obsolete" and + ruleId = "RULE-1-5" and + category = "required" + or + query = + // `Query` instance for the `functionTypesNotInPrototypeFormObsolete` query + Language4Package::functionTypesNotInPrototypeFormObsoleteQuery() and + queryId = + // `@id` for the `functionTypesNotInPrototypeFormObsolete` query + "c/misra/function-types-not-in-prototype-form-obsolete" and + ruleId = "RULE-1-5" and + category = "required" + or query = // `Query` instance for the `useOfObsoleteMacroAtomicVarInit` query Language4Package::useOfObsoleteMacroAtomicVarInitQuery() and @@ -27,6 +59,24 @@ predicate isLanguage4QueryMetadata(Query query, string queryId, string ruleId, s ruleId = "RULE-1-5" and category = "required" or + query = + // `Query` instance for the `callToObsolescentFunctionGets` query + Language4Package::callToObsolescentFunctionGetsQuery() and + queryId = + // `@id` for the `callToObsolescentFunctionGets` query + "c/misra/call-to-obsolescent-function-gets" and + ruleId = "RULE-1-5" and + category = "required" + or + query = + // `Query` instance for the `ungetcCallOnStreamPositionZero` query + Language4Package::ungetcCallOnStreamPositionZeroQuery() and + queryId = + // `@id` for the `ungetcCallOnStreamPositionZero` query + "c/misra/ungetc-call-on-stream-position-zero" and + ruleId = "RULE-1-5" and + category = "required" + or query = // `Query` instance for the `callToReallocWithSizeZero` query Language4Package::callToReallocWithSizeZeroQuery() and @@ -38,6 +88,27 @@ predicate isLanguage4QueryMetadata(Query query, string queryId, string ruleId, s } module Language4Package { + Query missingStaticSpecifierFuncRedeclarationObsoleteQuery() { + //autogenerate `Query` type + result = + // `Query` type for `missingStaticSpecifierFuncRedeclarationObsolete` query + TQueryC(TLanguage4PackageQuery(TMissingStaticSpecifierFuncRedeclarationObsoleteQuery())) + } + + Query missingStaticSpecifierObjectRedeclarationObsoleteQuery() { + //autogenerate `Query` type + result = + // `Query` type for `missingStaticSpecifierObjectRedeclarationObsolete` query + TQueryC(TLanguage4PackageQuery(TMissingStaticSpecifierObjectRedeclarationObsoleteQuery())) + } + + Query functionTypesNotInPrototypeFormObsoleteQuery() { + //autogenerate `Query` type + result = + // `Query` type for `functionTypesNotInPrototypeFormObsolete` query + TQueryC(TLanguage4PackageQuery(TFunctionTypesNotInPrototypeFormObsoleteQuery())) + } + Query useOfObsoleteMacroAtomicVarInitQuery() { //autogenerate `Query` type result = @@ -52,6 +123,20 @@ module Language4Package { TQueryC(TLanguage4PackageQuery(TInvalidDefineOrUndefOfStdBoolMacroQuery())) } + Query callToObsolescentFunctionGetsQuery() { + //autogenerate `Query` type + result = + // `Query` type for `callToObsolescentFunctionGets` query + TQueryC(TLanguage4PackageQuery(TCallToObsolescentFunctionGetsQuery())) + } + + Query ungetcCallOnStreamPositionZeroQuery() { + //autogenerate `Query` type + result = + // `Query` type for `ungetcCallOnStreamPositionZero` query + TQueryC(TLanguage4PackageQuery(TUngetcCallOnStreamPositionZeroQuery())) + } + Query callToReallocWithSizeZeroQuery() { //autogenerate `Query` type result = diff --git a/cpp/common/src/codingstandards/cpp/rules/functiontypesnotinprototypeformshared/FunctionTypesNotInPrototypeFormShared.qll b/cpp/common/src/codingstandards/cpp/rules/functiontypesnotinprototypeformshared/FunctionTypesNotInPrototypeFormShared.qll new file mode 100644 index 0000000000..ecc84f8651 --- /dev/null +++ b/cpp/common/src/codingstandards/cpp/rules/functiontypesnotinprototypeformshared/FunctionTypesNotInPrototypeFormShared.qll @@ -0,0 +1,54 @@ +/** + * Provides a library with a `problems` predicate for the following issue: + * The use of non-prototype format parameter type declarators is an obsolescent + * language feature. + */ + +import cpp +import codingstandards.cpp.Customizations +import codingstandards.cpp.Exclusions +import codingstandards.cpp.Identifiers + +abstract class FunctionTypesNotInPrototypeFormSharedSharedQuery extends Query { } + +/** + * `Parameter`s without names + */ +class UnnamedParameter extends Parameter { + UnnamedParameter() { not this.isNamed() } +} + +/* + * This is a copy of the private `hasZeroParamDecl` predicate from the standard set of + * queries as of the `codeql-cli/2.11.2` tag in `github/codeql`. + */ +predicate hasZeroParamDecl(Function f) { + exists(FunctionDeclarationEntry fde | fde = f.getADeclarationEntry() | + not fde.isImplicit() and + not fde.hasVoidParamList() and + fde.getNumberOfParameters() = 0 and + not fde.isDefinition() + ) +} + +Query getQuery() { result instanceof FunctionTypesNotInPrototypeFormSharedSharedQuery } + +query predicate problems(Function f, string msg) { +not isExcluded(f, getQuery()) and + f instanceof InterestingIdentifiers and + ( + f.getAParameter() instanceof UnnamedParameter and + msg = "Function " + f + " declares parameter that is unnamed." + or + hasZeroParamDecl(f) and + msg = "Function " + f + " does not specify void for no parameters present." + or + //parameters declared in declaration list (not in function signature) + //have placeholder file location associated only + exists(Parameter p | + p.getFunction() = f and + not p.getFile() = f.getFile() and + msg = "Function " + f + " declares parameter in unsupported declaration list." + ) + ) +} \ No newline at end of file diff --git a/cpp/common/src/codingstandards/cpp/rules/missingstaticspecifierobjectredeclarationshared/MissingStaticSpecifierObjectRedeclarationShared.qll b/cpp/common/src/codingstandards/cpp/rules/missingstaticspecifierobjectredeclarationshared/MissingStaticSpecifierObjectRedeclarationShared.qll new file mode 100644 index 0000000000..90f28e6cc8 --- /dev/null +++ b/cpp/common/src/codingstandards/cpp/rules/missingstaticspecifierobjectredeclarationshared/MissingStaticSpecifierObjectRedeclarationShared.qll @@ -0,0 +1,27 @@ +/** + * Provides a library with a `problems` predicate for the following issue: + * Declaring an identifier with internal linkage without the static storage class + * specifier is an obselescent feature. + */ + +import cpp +import codingstandards.cpp.Customizations +import codingstandards.cpp.Exclusions + +abstract class MissingStaticSpecifierObjectRedeclarationSharedSharedQuery extends Query { } + +Query getQuery() { result instanceof MissingStaticSpecifierObjectRedeclarationSharedSharedQuery } + +query predicate problems( + VariableDeclarationEntry redeclaration, string message, VariableDeclarationEntry de, + string deString +) { + not isExcluded(redeclaration, getQuery()) and + //following implies de != redeclaration + de.hasSpecifier("static") and + not redeclaration.hasSpecifier("static") and + de.getDeclaration().isTopLevel() and + redeclaration.getDeclaration() = de.getDeclaration() and + message = "The redeclaration of $@ with internal linkage misses the static specifier." and + deString = de.getName() +} diff --git a/rule_packages/c/Declarations4.json b/rule_packages/c/Declarations4.json index 06475706f4..dedc6a73d4 100644 --- a/rule_packages/c/Declarations4.json +++ b/rule_packages/c/Declarations4.json @@ -12,6 +12,7 @@ "precision": "medium", "severity": "error", "short_name": "FunctionTypesNotInPrototypeForm", + "shared_implementation_short_name": "FunctionTypesNotInPrototypeFormShared", "tags": [ "correctness", "external/misra/c/2012/third-edition-first-revision" diff --git a/rule_packages/c/Declarations5.json b/rule_packages/c/Declarations5.json index 1106a1d705..36591e575b 100644 --- a/rule_packages/c/Declarations5.json +++ b/rule_packages/c/Declarations5.json @@ -71,6 +71,7 @@ "precision": "very-high", "severity": "warning", "short_name": "MissingStaticSpecifierObjectRedeclarationC", + "shared_implementation_short_name": "MissingStaticSpecifierObjectRedeclarationShared", "tags": [ "readability", "external/misra/c/2012/third-edition-first-revision" diff --git a/rule_packages/c/Language4.json b/rule_packages/c/Language4.json index 54708d73da..8698407b5f 100644 --- a/rule_packages/c/Language4.json +++ b/rule_packages/c/Language4.json @@ -5,6 +5,48 @@ "obligation": "required" }, "queries": [ + { + "description": "Declaring a function with internal linkage without the static storage class specifier is an obselescent feature.", + "kind": "problem", + "name": "If a function has internal linkage then all re-declarations shall include the static storage class", + "precision": "very-high", + "severity": "warning", + "short_name": "MissingStaticSpecifierFuncRedeclarationObsolete", + "shared_implementation_short_name": "MissingStaticSpecifierFunctionRedeclarationShared", + "tags": [ + "readability", + "external/misra/c/2012/amendment3" + ] + }, + { + "description": "Declaring an identifier with internal linkage without the static storage class specifier is an obselescent feature.", + "kind": "problem", + "name": "If an object has internal linkage then all re-declarations shall include the static storage class", + "precision": "very-high", + "severity": "warning", + "short_name": "MissingStaticSpecifierObjectRedeclarationObsolete", + "shared_implementation_short_name": "MissingStaticSpecifierObjectRedeclarationShared", + "tags": [ + "readability", + "external/misra/c/2012/amendment3" + ] + }, + { + "description": "The use of non-prototype format parameter type declarators is an obsolescent language feature.", + "kind": "problem", + "name": "Function types shall be in prototype form with named parameters", + "precision": "medium", + "severity": "error", + "short_name": "FunctionTypesNotInPrototypeFormObsolete", + "shared_implementation_short_name": "FunctionTypesNotInPrototypeFormShared", + "tags": [ + "correctness", + "external/misra/c/2012/amendment3" + ], + "implementation_scope": { + "description": "This query does not check for implicitly typed parameters and checks function declarations and definitions but not function pointer types." + } + }, { "description": "The macro ATOMIC_VAR_INIT is has been declared an obsolescent language feature since C18.", "kind": "problem", @@ -31,6 +73,32 @@ "external/misra/c/2012/amendment3" ] }, + { + "description": "The function 'gets' is an obsolescent language feature which was removed in C11.", + "kind": "problem", + "name": "Disallowed usage of obsolescent function 'gets'", + "precision": "very-high", + "severity": "error", + "short_name": "CallToObsolescentFunctionGets", + "tags": [ + "external/misra/c/2012/amendment3", + "security", + "maintainability" + ] + }, + { + "description": "Calling the function 'ungetc' on a file stream with a position of zero is an obsolescent language feature.", + "kind": "problem", + "name": "Disallowed obsolescent usage of 'ungetc' on a file stream at position zero", + "precision": "medium", + "severity": "error", + "short_name": "UngetcCallOnStreamPositionZero", + "tags": [ + "external/misra/c/2012/amendment3", + "security", + "maintainability" + ] + }, { "description": "Invoking realloc with a size argument set to zero is implementation-defined behavior and declared as an obsolete feature in C18.", "kind": "problem", @@ -48,13 +116,14 @@ "implementation_scope": { "description": "Not all items from Appendix F are covered by this rule. Some are not supportable and some are covered already by other rules.", "items": [ - "Appendix F, item ID 1 is covered by Rule 8.8 and not reported as part of this implementation of Rule 1.5.", + "Appendix F, item ID 1 is reported by both Rule 8.8 and by this implementation of Rule 1.5.", "Appendix F, item ID 2 refers to compiler behavior which cannot be statically analyzed.", "Appendix F, item ID 3, which states that storage-class specifiers may not be used except in the beginning of a declaration, is not supportable without additional changes to the CodeQL CLI.", + "Appendix F, item IDs 4 and 5 are reported by both Rule 8.2 and by this implementation of Rule 1.5.", "Appendix F, item ID 6 is reported for all C versions, though the macro ATOMIC_VAR_INIT was not officially declared obsolescent until C18.", - "Appendix F, item IDs 4 and 5 are covered by Rule 8.2 and not reported as part of this implementation of Rule 1.5.", - "Appendix F, item IDs 8 and 9 is covered by Rule 21.6 and not reported as part of this implementation of Rule 1.5.", - "Appendix F, item ID 10 is checked by this implementation of 1.5, though it is a redundant subset of cases reported by Rule 21.3.", + "Appendix F, item ID 8 is reported by both Rule 21.6 and by this implementation of Rule 1.5.", + "Appendix F, item ID 9 is reported by this implementation of 1.5, though all uses of ungetc() are also reported by Rule 21.3.", + "Appendix F, item ID 10 is reported by this implementation of 1.5, though all uses of realloc() are also reported by Rule 21.3.", "Appendix F, item ID 10 is reported for all C versions, as realloc() with a size argument of zero was implementation-defined behavior in C99 and C11." ] } From 1908bbf71887d9a1e118f36276cdc6ffadeb1ffc Mon Sep 17 00:00:00 2001 From: Mike Fairhurst Date: Thu, 17 Oct 2024 16:25:08 -0700 Subject: [PATCH 11/15] Format queries and tests --- .../RULE-1-5/FunctionTypesNotInPrototypeFormObsolete.ql | 3 ++- .../MissingStaticSpecifierFuncRedeclarationObsolete.ql | 3 ++- .../MissingStaticSpecifierObjectRedeclarationObsolete.ql | 3 ++- .../MissingStaticSpecifierObjectRedeclarationC.ql | 3 ++- .../RULE-1-5/UngetcCallOnStreamPositionZero.expected | 9 ++++++++- c/misra/test/rules/RULE-1-5/test.c | 5 +++-- 6 files changed, 19 insertions(+), 7 deletions(-) diff --git a/c/misra/src/rules/RULE-1-5/FunctionTypesNotInPrototypeFormObsolete.ql b/c/misra/src/rules/RULE-1-5/FunctionTypesNotInPrototypeFormObsolete.ql index 8f0e626bc8..645285f438 100644 --- a/c/misra/src/rules/RULE-1-5/FunctionTypesNotInPrototypeFormObsolete.ql +++ b/c/misra/src/rules/RULE-1-5/FunctionTypesNotInPrototypeFormObsolete.ql @@ -16,7 +16,8 @@ import cpp import codingstandards.c.misra import codingstandards.cpp.rules.functiontypesnotinprototypeformshared.FunctionTypesNotInPrototypeFormShared -class FunctionTypesNotInPrototypeFormObsoleteQuery extends FunctionTypesNotInPrototypeFormSharedSharedQuery { +class FunctionTypesNotInPrototypeFormObsoleteQuery extends FunctionTypesNotInPrototypeFormSharedSharedQuery +{ FunctionTypesNotInPrototypeFormObsoleteQuery() { this = Language4Package::functionTypesNotInPrototypeFormObsoleteQuery() } diff --git a/c/misra/src/rules/RULE-1-5/MissingStaticSpecifierFuncRedeclarationObsolete.ql b/c/misra/src/rules/RULE-1-5/MissingStaticSpecifierFuncRedeclarationObsolete.ql index 5a70e0287a..ba800885ef 100644 --- a/c/misra/src/rules/RULE-1-5/MissingStaticSpecifierFuncRedeclarationObsolete.ql +++ b/c/misra/src/rules/RULE-1-5/MissingStaticSpecifierFuncRedeclarationObsolete.ql @@ -16,7 +16,8 @@ import cpp import codingstandards.c.misra import codingstandards.cpp.rules.missingstaticspecifierfunctionredeclarationshared.MissingStaticSpecifierFunctionRedeclarationShared -class MissingStaticSpecifierFuncRedeclarationObsoleteQuery extends MissingStaticSpecifierFunctionRedeclarationSharedSharedQuery { +class MissingStaticSpecifierFuncRedeclarationObsoleteQuery extends MissingStaticSpecifierFunctionRedeclarationSharedSharedQuery +{ MissingStaticSpecifierFuncRedeclarationObsoleteQuery() { this = Language4Package::missingStaticSpecifierFuncRedeclarationObsoleteQuery() } diff --git a/c/misra/src/rules/RULE-1-5/MissingStaticSpecifierObjectRedeclarationObsolete.ql b/c/misra/src/rules/RULE-1-5/MissingStaticSpecifierObjectRedeclarationObsolete.ql index 5e32d57c6a..9f9953aa6f 100644 --- a/c/misra/src/rules/RULE-1-5/MissingStaticSpecifierObjectRedeclarationObsolete.ql +++ b/c/misra/src/rules/RULE-1-5/MissingStaticSpecifierObjectRedeclarationObsolete.ql @@ -16,7 +16,8 @@ import cpp import codingstandards.c.misra import codingstandards.cpp.rules.missingstaticspecifierobjectredeclarationshared.MissingStaticSpecifierObjectRedeclarationShared -class MissingStaticSpecifierObjectRedeclarationObsoleteQuery extends MissingStaticSpecifierObjectRedeclarationSharedSharedQuery { +class MissingStaticSpecifierObjectRedeclarationObsoleteQuery extends MissingStaticSpecifierObjectRedeclarationSharedSharedQuery +{ MissingStaticSpecifierObjectRedeclarationObsoleteQuery() { this = Language4Package::missingStaticSpecifierObjectRedeclarationObsoleteQuery() } diff --git a/c/misra/src/rules/RULE-8-8/MissingStaticSpecifierObjectRedeclarationC.ql b/c/misra/src/rules/RULE-8-8/MissingStaticSpecifierObjectRedeclarationC.ql index 6f731c636f..877ef19d2a 100644 --- a/c/misra/src/rules/RULE-8-8/MissingStaticSpecifierObjectRedeclarationC.ql +++ b/c/misra/src/rules/RULE-8-8/MissingStaticSpecifierObjectRedeclarationC.ql @@ -16,7 +16,8 @@ import cpp import codingstandards.c.misra import codingstandards.cpp.rules.missingstaticspecifierobjectredeclarationshared.MissingStaticSpecifierObjectRedeclarationShared -class MissingStaticSpecifierObjectRedeclarationCQuery extends MissingStaticSpecifierObjectRedeclarationSharedSharedQuery { +class MissingStaticSpecifierObjectRedeclarationCQuery extends MissingStaticSpecifierObjectRedeclarationSharedSharedQuery +{ MissingStaticSpecifierObjectRedeclarationCQuery() { this = Declarations5Package::missingStaticSpecifierObjectRedeclarationCQuery() } diff --git a/c/misra/test/rules/RULE-1-5/UngetcCallOnStreamPositionZero.expected b/c/misra/test/rules/RULE-1-5/UngetcCallOnStreamPositionZero.expected index 4dd298197f..3a6f6bc821 100644 --- a/c/misra/test/rules/RULE-1-5/UngetcCallOnStreamPositionZero.expected +++ b/c/misra/test/rules/RULE-1-5/UngetcCallOnStreamPositionZero.expected @@ -1 +1,8 @@ -| test.c:40:3:40:8 | call to ungetc | Obsolescent call to ungetc on file stream $@ at position zero. | test.c:38:16:38:20 | call to fopen | call to fopen | +edges +| test.c:38:16:38:20 | call to fopen indirection | test.c:40:15:40:18 | file indirection | +nodes +| test.c:38:16:38:20 | call to fopen indirection | semmle.label | call to fopen indirection | +| test.c:40:15:40:18 | file indirection | semmle.label | file indirection | +subpaths +#select +| test.c:40:15:40:18 | file indirection | test.c:38:16:38:20 | call to fopen indirection | test.c:40:15:40:18 | file indirection | Obsolescent call to ungetc on file stream $@ at position zero. | test.c:38:16:38:20 | call to fopen indirection | call to fopen indirection | diff --git a/c/misra/test/rules/RULE-1-5/test.c b/c/misra/test/rules/RULE-1-5/test.c index 7632e0a727..38d701c44b 100644 --- a/c/misra/test/rules/RULE-1-5/test.c +++ b/c/misra/test/rules/RULE-1-5/test.c @@ -29,7 +29,7 @@ _Atomic int g3 = ATOMIC_VAR_INIT(18); // NON-COMPLIANT _Atomic int g4 = 18; // COMPLIANT // `gets` was removed from C11. -extern char* gets(FILE *stream); +extern char *gets(FILE *stream); // Rule 21.6 covers the below cases: void f6(void) { @@ -41,6 +41,7 @@ void f6(void) { char buf[10]; fread(buf, sizeof(buf), 10, file); - // This is not an obsolete usage of ungetc, though ungetc isn't allowed by 21-3. + // This is not an obsolete usage of ungetc, though ungetc isn't allowed by + // 21-3. ungetc('c', file); // COMPLIANT } \ No newline at end of file From fd9eb8a0ee86cd53ec1c82c202756aba71c9140a Mon Sep 17 00:00:00 2001 From: Mike Fairhurst Date: Thu, 17 Oct 2024 16:25:30 -0700 Subject: [PATCH 12/15] Remodel ungetc() query as a sanitization/path problem --- .../UngetcCallOnStreamPositionZero.ql | 42 ++++++++++++------- 1 file changed, 27 insertions(+), 15 deletions(-) diff --git a/c/misra/src/rules/RULE-1-5/UngetcCallOnStreamPositionZero.ql b/c/misra/src/rules/RULE-1-5/UngetcCallOnStreamPositionZero.ql index a973442203..8a1615d08c 100644 --- a/c/misra/src/rules/RULE-1-5/UngetcCallOnStreamPositionZero.ql +++ b/c/misra/src/rules/RULE-1-5/UngetcCallOnStreamPositionZero.ql @@ -3,7 +3,7 @@ * @name RULE-1-5: Disallowed obsolescent usage of 'ungetc' on a file stream at position zero * @description Calling the function 'ungetc' on a file stream with a position of zero is an * obsolescent language feature. - * @kind problem + * @kind path-problem * @precision medium * @problem.severity error * @tags external/misra/id/rule-1-5 @@ -52,18 +52,30 @@ class MoveStreamPositionCall extends FunctionCall { Expr getStreamArgument() { result = streamArgument } } -from FunctionCall ungetc, DataFlow::Node file +module FilePositionZeroFlowConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node node) { + node.asIndirectExpr().(FunctionCall).getTarget().hasGlobalOrStdName("fopen") + } + + predicate isSink(DataFlow::Node node) { + exists(FunctionCall fc | + fc.getTarget().hasGlobalOrStdName("ungetc") and + node.asIndirectExpr() = fc.getArgument(1) + ) + } + + predicate isBarrierIn(DataFlow::Node node) { + exists(MoveStreamPositionCall fc | node.asIndirectExpr() = fc.getStreamArgument()) + } +} + +module FilePositionZeroFlow = DataFlow::Global; + +import FilePositionZeroFlow::PathGraph + +from FilePositionZeroFlow::PathNode sink, FilePositionZeroFlow::PathNode source where - not isExcluded(ungetc, Language4Package::ungetcCallOnStreamPositionZeroQuery()) and - // ungetc() called on file stream - ungetc.getTarget().hasGlobalOrStdName("ungetc") and - DataFlow::localFlow(file, DataFlow::exprNode(ungetc.getArgument(1))) and - // ungetc() is not dominated by a fread() etc to that file stream - not exists(MoveStreamPositionCall moveStreamCall | - DataFlow::localFlow(file, DataFlow::exprNode(moveStreamCall.getStreamArgument())) and - dominates(moveStreamCall, ungetc) - ) - // the file stream is the root of the local data flow - and not DataFlow::localFlow(any(DataFlow::Node n | not n = file), file) -select ungetc, "Obsolescent call to ungetc on file stream $@ at position zero.", file, - file.toString() + not isExcluded(sink.getNode().asExpr(), Language4Package::ungetcCallOnStreamPositionZeroQuery()) and + FilePositionZeroFlow::flowPath(source, sink) +select sink.getNode(), source, sink, + "Obsolescent call to ungetc on file stream $@ at position zero.", source, source.toString() From 46b272ac2833b15984686eb6cb5569d03cfe177b Mon Sep 17 00:00:00 2001 From: Mike Fairhurst Date: Thu, 17 Oct 2024 16:30:12 -0700 Subject: [PATCH 13/15] Fix query metadata --- c/misra/src/rules/RULE-1-5/UngetcCallOnStreamPositionZero.ql | 2 +- rule_packages/c/Language4.json | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/c/misra/src/rules/RULE-1-5/UngetcCallOnStreamPositionZero.ql b/c/misra/src/rules/RULE-1-5/UngetcCallOnStreamPositionZero.ql index 8a1615d08c..6a10c94030 100644 --- a/c/misra/src/rules/RULE-1-5/UngetcCallOnStreamPositionZero.ql +++ b/c/misra/src/rules/RULE-1-5/UngetcCallOnStreamPositionZero.ql @@ -4,7 +4,7 @@ * @description Calling the function 'ungetc' on a file stream with a position of zero is an * obsolescent language feature. * @kind path-problem - * @precision medium + * @precision high * @problem.severity error * @tags external/misra/id/rule-1-5 * external/misra/c/2012/amendment3 diff --git a/rule_packages/c/Language4.json b/rule_packages/c/Language4.json index 8698407b5f..fb448bd8a3 100644 --- a/rule_packages/c/Language4.json +++ b/rule_packages/c/Language4.json @@ -88,9 +88,9 @@ }, { "description": "Calling the function 'ungetc' on a file stream with a position of zero is an obsolescent language feature.", - "kind": "problem", + "kind": "path-problem", "name": "Disallowed obsolescent usage of 'ungetc' on a file stream at position zero", - "precision": "medium", + "precision": "high", "severity": "error", "short_name": "UngetcCallOnStreamPositionZero", "tags": [ From 9dc3c2a154d70f7171ed204907ed5173b95389b4 Mon Sep 17 00:00:00 2001 From: Mike Fairhurst Date: Fri, 18 Oct 2024 18:15:06 -0700 Subject: [PATCH 14/15] Use range analysis to detect realloc() where size may be zero, vs, is exactly zero. --- ...SizeZero.ql => SizeInReallocCallIsZero.ql} | 17 +++++----- .../RULE-1-5/SizeInReallocCallMayBeZero.ql | 26 +++++++++++++++ .../CallToObsolescentFunctionGets.expected | 2 +- .../CallToReallocWithSizeZero.expected | 1 - .../RULE-1-5/CallToReallocWithSizeZero.qlref | 1 - ...nvalidDefineOrUndefOfStdBoolMacro.expected | 12 +++---- .../RULE-1-5/SizeInReallocCallIsZero.expected | 1 + .../RULE-1-5/SizeInReallocCallIsZero.qlref | 1 + .../SizeInReallocCallMayBeZero.expected | 1 + .../RULE-1-5/SizeInReallocCallMayBeZero.qlref | 1 + .../UngetcCallOnStreamPositionZero.expected | 8 ++--- .../UseOfObsoleteMacroAtomicVarInit.expected | 2 +- c/misra/test/rules/RULE-1-5/test.c | 9 ++--- .../src/codingstandards/cpp/Realloc.qll | 18 ++++++++++ .../cpp/exclusions/c/Language4.qll | 33 ++++++++++++++----- rule_packages/c/Language4.json | 16 +++++++-- 16 files changed, 113 insertions(+), 36 deletions(-) rename c/misra/src/rules/RULE-1-5/{CallToReallocWithSizeZero.ql => SizeInReallocCallIsZero.ql} (50%) create mode 100644 c/misra/src/rules/RULE-1-5/SizeInReallocCallMayBeZero.ql delete mode 100644 c/misra/test/rules/RULE-1-5/CallToReallocWithSizeZero.expected delete mode 100644 c/misra/test/rules/RULE-1-5/CallToReallocWithSizeZero.qlref create mode 100644 c/misra/test/rules/RULE-1-5/SizeInReallocCallIsZero.expected create mode 100644 c/misra/test/rules/RULE-1-5/SizeInReallocCallIsZero.qlref create mode 100644 c/misra/test/rules/RULE-1-5/SizeInReallocCallMayBeZero.expected create mode 100644 c/misra/test/rules/RULE-1-5/SizeInReallocCallMayBeZero.qlref create mode 100644 cpp/common/src/codingstandards/cpp/Realloc.qll diff --git a/c/misra/src/rules/RULE-1-5/CallToReallocWithSizeZero.ql b/c/misra/src/rules/RULE-1-5/SizeInReallocCallIsZero.ql similarity index 50% rename from c/misra/src/rules/RULE-1-5/CallToReallocWithSizeZero.ql rename to c/misra/src/rules/RULE-1-5/SizeInReallocCallIsZero.ql index 2ea90e8b12..2b5cdaa851 100644 --- a/c/misra/src/rules/RULE-1-5/CallToReallocWithSizeZero.ql +++ b/c/misra/src/rules/RULE-1-5/SizeInReallocCallIsZero.ql @@ -1,6 +1,6 @@ /** - * @id c/misra/call-to-realloc-with-size-zero - * @name RULE-1-5: Disallowed size argument value equal to zero in call to realloc + * @id c/misra/size-in-realloc-call-is-zero + * @name RULE-1-5: Size argument value in realloc call is equal zero * @description Invoking realloc with a size argument set to zero is implementation-defined behavior * and declared as an obsolete feature in C18. * @kind problem @@ -15,11 +15,12 @@ import cpp import codingstandards.c.misra import semmle.code.cpp.rangeanalysis.new.RangeAnalysis +import codingstandards.cpp.Realloc -from FunctionCall call, Expr arg +from ReallocCall call where - not isExcluded(call, Language4Package::callToReallocWithSizeZeroQuery()) and - call.getTarget().hasGlobalOrStdName("realloc") and - arg = call.getArgument(1) and - upperBound(arg) = 0 -select arg, "Calling realloc with size zero results in implementation-defined behavior." + not isExcluded(call, Language4Package::sizeInReallocCallIsZeroQuery()) and + call.sizeIsExactlyZero() +select call, + "Size argument '$@' may equal zero in realloc call, resulting in obsolescent and/or implementation-defined behavior.", + call.getSizeArgument(), call.getSizeArgument().toString() diff --git a/c/misra/src/rules/RULE-1-5/SizeInReallocCallMayBeZero.ql b/c/misra/src/rules/RULE-1-5/SizeInReallocCallMayBeZero.ql new file mode 100644 index 0000000000..3e883e45f4 --- /dev/null +++ b/c/misra/src/rules/RULE-1-5/SizeInReallocCallMayBeZero.ql @@ -0,0 +1,26 @@ +/** + * @id c/misra/size-in-realloc-call-may-be-zero + * @name RULE-1-5: Size argument value in realloc call may equal zero + * @description Invoking realloc with a size argument set to zero is implementation-defined behavior + * and declared as an obsolete feature in C18. + * @kind problem + * @precision medium + * @problem.severity error + * @tags external/misra/id/rule-1-5 + * correctness + * external/misra/c/2012/amendment3 + * external/misra/obligation/required + */ + +import cpp +import codingstandards.c.misra +import codingstandards.cpp.Realloc + +from ReallocCall call +where + not isExcluded(call, Language4Package::sizeInReallocCallMayBeZeroQuery()) and + call.sizeMayBeZero() and + not call.sizeIsExactlyZero() +select call, + "Size argument '$@' equals zero in realloc call, resulting in obsolescent and/or implementation-defined behavior.", + call.getSizeArgument(), call.getSizeArgument().toString() diff --git a/c/misra/test/rules/RULE-1-5/CallToObsolescentFunctionGets.expected b/c/misra/test/rules/RULE-1-5/CallToObsolescentFunctionGets.expected index 6e0088f4ac..4c8fdc27cf 100644 --- a/c/misra/test/rules/RULE-1-5/CallToObsolescentFunctionGets.expected +++ b/c/misra/test/rules/RULE-1-5/CallToObsolescentFunctionGets.expected @@ -1 +1 @@ -| test.c:36:3:36:6 | call to gets | Call to obsolescent function 'gets'. | +| test.c:37:3:37:6 | call to gets | Call to obsolescent function 'gets'. | diff --git a/c/misra/test/rules/RULE-1-5/CallToReallocWithSizeZero.expected b/c/misra/test/rules/RULE-1-5/CallToReallocWithSizeZero.expected deleted file mode 100644 index 89e54a38c2..0000000000 --- a/c/misra/test/rules/RULE-1-5/CallToReallocWithSizeZero.expected +++ /dev/null @@ -1 +0,0 @@ -| test.c:11:14:11:14 | 0 | Calling realloc with size zero results in implementation-defined behavior. | diff --git a/c/misra/test/rules/RULE-1-5/CallToReallocWithSizeZero.qlref b/c/misra/test/rules/RULE-1-5/CallToReallocWithSizeZero.qlref deleted file mode 100644 index 218be6b3ef..0000000000 --- a/c/misra/test/rules/RULE-1-5/CallToReallocWithSizeZero.qlref +++ /dev/null @@ -1 +0,0 @@ -rules/RULE-1-5/CallToReallocWithSizeZero.ql \ No newline at end of file diff --git a/c/misra/test/rules/RULE-1-5/InvalidDefineOrUndefOfStdBoolMacro.expected b/c/misra/test/rules/RULE-1-5/InvalidDefineOrUndefOfStdBoolMacro.expected index 7a6ca9824e..854b200553 100644 --- a/c/misra/test/rules/RULE-1-5/InvalidDefineOrUndefOfStdBoolMacro.expected +++ b/c/misra/test/rules/RULE-1-5/InvalidDefineOrUndefOfStdBoolMacro.expected @@ -1,6 +1,6 @@ -| test.c:21:1:21:14 | #define true 3 | Invalid define of boolean standard macro 'true'. | -| test.c:22:1:22:15 | #define false 3 | Invalid define of boolean standard macro 'false'. | -| test.c:23:1:23:18 | #define bool int * | Invalid define of boolean standard macro 'bool'. | -| test.c:24:1:24:11 | #undef true | Invalid undefine of boolean standard macro 'true'. | -| test.c:25:1:25:12 | #undef false | Invalid undefine of boolean standard macro 'false'. | -| test.c:26:1:26:11 | #undef bool | Invalid undefine of boolean standard macro 'bool'. | +| test.c:22:1:22:14 | #define true 3 | Invalid define of boolean standard macro 'true'. | +| test.c:23:1:23:15 | #define false 3 | Invalid define of boolean standard macro 'false'. | +| test.c:24:1:24:18 | #define bool int * | Invalid define of boolean standard macro 'bool'. | +| test.c:25:1:25:11 | #undef true | Invalid undefine of boolean standard macro 'true'. | +| test.c:26:1:26:12 | #undef false | Invalid undefine of boolean standard macro 'false'. | +| test.c:27:1:27:11 | #undef bool | Invalid undefine of boolean standard macro 'bool'. | diff --git a/c/misra/test/rules/RULE-1-5/SizeInReallocCallIsZero.expected b/c/misra/test/rules/RULE-1-5/SizeInReallocCallIsZero.expected new file mode 100644 index 0000000000..7b05a5fc0a --- /dev/null +++ b/c/misra/test/rules/RULE-1-5/SizeInReallocCallIsZero.expected @@ -0,0 +1 @@ +| test.c:14:3:14:9 | call to realloc | Size argument '$@' may equal zero in realloc call, resulting in obsolescent and/or implementation-defined behavior. | test.c:14:14:14:14 | 0 | 0 | diff --git a/c/misra/test/rules/RULE-1-5/SizeInReallocCallIsZero.qlref b/c/misra/test/rules/RULE-1-5/SizeInReallocCallIsZero.qlref new file mode 100644 index 0000000000..cef5e76d54 --- /dev/null +++ b/c/misra/test/rules/RULE-1-5/SizeInReallocCallIsZero.qlref @@ -0,0 +1 @@ +rules/RULE-1-5/SizeInReallocCallIsZero.ql \ No newline at end of file diff --git a/c/misra/test/rules/RULE-1-5/SizeInReallocCallMayBeZero.expected b/c/misra/test/rules/RULE-1-5/SizeInReallocCallMayBeZero.expected new file mode 100644 index 0000000000..f86ad4c57c --- /dev/null +++ b/c/misra/test/rules/RULE-1-5/SizeInReallocCallMayBeZero.expected @@ -0,0 +1 @@ +| test.c:15:3:15:9 | call to realloc | Size argument '$@' equals zero in realloc call, resulting in obsolescent and/or implementation-defined behavior. | test.c:15:14:15:15 | p0 | p0 | diff --git a/c/misra/test/rules/RULE-1-5/SizeInReallocCallMayBeZero.qlref b/c/misra/test/rules/RULE-1-5/SizeInReallocCallMayBeZero.qlref new file mode 100644 index 0000000000..1287327c5d --- /dev/null +++ b/c/misra/test/rules/RULE-1-5/SizeInReallocCallMayBeZero.qlref @@ -0,0 +1 @@ +rules/RULE-1-5/SizeInReallocCallMayBeZero.ql \ No newline at end of file diff --git a/c/misra/test/rules/RULE-1-5/UngetcCallOnStreamPositionZero.expected b/c/misra/test/rules/RULE-1-5/UngetcCallOnStreamPositionZero.expected index 3a6f6bc821..98e7b34fbe 100644 --- a/c/misra/test/rules/RULE-1-5/UngetcCallOnStreamPositionZero.expected +++ b/c/misra/test/rules/RULE-1-5/UngetcCallOnStreamPositionZero.expected @@ -1,8 +1,8 @@ edges -| test.c:38:16:38:20 | call to fopen indirection | test.c:40:15:40:18 | file indirection | +| test.c:39:16:39:20 | call to fopen indirection | test.c:41:15:41:18 | file indirection | nodes -| test.c:38:16:38:20 | call to fopen indirection | semmle.label | call to fopen indirection | -| test.c:40:15:40:18 | file indirection | semmle.label | file indirection | +| test.c:39:16:39:20 | call to fopen indirection | semmle.label | call to fopen indirection | +| test.c:41:15:41:18 | file indirection | semmle.label | file indirection | subpaths #select -| test.c:40:15:40:18 | file indirection | test.c:38:16:38:20 | call to fopen indirection | test.c:40:15:40:18 | file indirection | Obsolescent call to ungetc on file stream $@ at position zero. | test.c:38:16:38:20 | call to fopen indirection | call to fopen indirection | +| test.c:41:15:41:18 | file indirection | test.c:39:16:39:20 | call to fopen indirection | test.c:41:15:41:18 | file indirection | Obsolescent call to ungetc on file stream $@ at position zero. | test.c:39:16:39:20 | call to fopen indirection | call to fopen indirection | diff --git a/c/misra/test/rules/RULE-1-5/UseOfObsoleteMacroAtomicVarInit.expected b/c/misra/test/rules/RULE-1-5/UseOfObsoleteMacroAtomicVarInit.expected index bc903de094..edd607c52f 100644 --- a/c/misra/test/rules/RULE-1-5/UseOfObsoleteMacroAtomicVarInit.expected +++ b/c/misra/test/rules/RULE-1-5/UseOfObsoleteMacroAtomicVarInit.expected @@ -1 +1 @@ -| test.c:28:18:28:36 | ATOMIC_VAR_INIT(value) | Usage of macro ATOMIC_VAR_INIT() is declared obscelescent in C18, and discouraged in earlier C versions. | +| test.c:29:18:29:36 | ATOMIC_VAR_INIT(value) | Usage of macro ATOMIC_VAR_INIT() is declared obscelescent in C18, and discouraged in earlier C versions. | diff --git a/c/misra/test/rules/RULE-1-5/test.c b/c/misra/test/rules/RULE-1-5/test.c index 38d701c44b..52144bad13 100644 --- a/c/misra/test/rules/RULE-1-5/test.c +++ b/c/misra/test/rules/RULE-1-5/test.c @@ -3,15 +3,16 @@ #include "stdio.h" #include "stdlib.h" -void f1(void) { +void f1(int p0) { // malloc() is not obsolete, though it is banned by Rule 21.3 int *t = malloc(10); // COMPLIANT - // Obsolete usage of realloc. - realloc(t, 0); // NON-COMPLIANT - // Valid usage of realloc, but all use of realloc is banned by Rule 21.3 realloc(t, 20); // NON-COMPLIANT + + // Obsolete usage of realloc. + realloc(t, 0); // NON-COMPLIANT + realloc(t, p0); // NON-COMPLIANT } extern const int g1; // COMPLIANT diff --git a/cpp/common/src/codingstandards/cpp/Realloc.qll b/cpp/common/src/codingstandards/cpp/Realloc.qll new file mode 100644 index 0000000000..71acb7d7b1 --- /dev/null +++ b/cpp/common/src/codingstandards/cpp/Realloc.qll @@ -0,0 +1,18 @@ +import cpp +import codingstandards.cpp.CodingStandards + +class ReallocCall extends FunctionCall { + ReallocCall() { getTarget().hasGlobalOrStdName("realloc") } + + Expr getSizeArgument() { result = getArgument(1) } + + predicate sizeIsExactlyZero() { + upperBound(getSizeArgument().getConversion()) = 0 and + lowerBound(getSizeArgument().getConversion()) = 0 + } + + predicate sizeMayBeZero() { + upperBound(getSizeArgument().getConversion()) >= 0 and + lowerBound(getSizeArgument().getConversion()) <= 0 + } +} diff --git a/cpp/common/src/codingstandards/cpp/exclusions/c/Language4.qll b/cpp/common/src/codingstandards/cpp/exclusions/c/Language4.qll index 7bca9feefc..b4391ff5c2 100644 --- a/cpp/common/src/codingstandards/cpp/exclusions/c/Language4.qll +++ b/cpp/common/src/codingstandards/cpp/exclusions/c/Language4.qll @@ -11,7 +11,8 @@ newtype Language4Query = TInvalidDefineOrUndefOfStdBoolMacroQuery() or TCallToObsolescentFunctionGetsQuery() or TUngetcCallOnStreamPositionZeroQuery() or - TCallToReallocWithSizeZeroQuery() + TSizeInReallocCallMayBeZeroQuery() or + TSizeInReallocCallIsZeroQuery() predicate isLanguage4QueryMetadata(Query query, string queryId, string ruleId, string category) { query = @@ -78,11 +79,20 @@ predicate isLanguage4QueryMetadata(Query query, string queryId, string ruleId, s category = "required" or query = - // `Query` instance for the `callToReallocWithSizeZero` query - Language4Package::callToReallocWithSizeZeroQuery() and + // `Query` instance for the `sizeInReallocCallMayBeZero` query + Language4Package::sizeInReallocCallMayBeZeroQuery() and queryId = - // `@id` for the `callToReallocWithSizeZero` query - "c/misra/call-to-realloc-with-size-zero" and + // `@id` for the `sizeInReallocCallMayBeZero` query + "c/misra/size-in-realloc-call-may-be-zero" and + ruleId = "RULE-1-5" and + category = "required" + or + query = + // `Query` instance for the `sizeInReallocCallIsZero` query + Language4Package::sizeInReallocCallIsZeroQuery() and + queryId = + // `@id` for the `sizeInReallocCallIsZero` query + "c/misra/size-in-realloc-call-is-zero" and ruleId = "RULE-1-5" and category = "required" } @@ -137,10 +147,17 @@ module Language4Package { TQueryC(TLanguage4PackageQuery(TUngetcCallOnStreamPositionZeroQuery())) } - Query callToReallocWithSizeZeroQuery() { + Query sizeInReallocCallMayBeZeroQuery() { + //autogenerate `Query` type + result = + // `Query` type for `sizeInReallocCallMayBeZero` query + TQueryC(TLanguage4PackageQuery(TSizeInReallocCallMayBeZeroQuery())) + } + + Query sizeInReallocCallIsZeroQuery() { //autogenerate `Query` type result = - // `Query` type for `callToReallocWithSizeZero` query - TQueryC(TLanguage4PackageQuery(TCallToReallocWithSizeZeroQuery())) + // `Query` type for `sizeInReallocCallIsZero` query + TQueryC(TLanguage4PackageQuery(TSizeInReallocCallIsZeroQuery())) } } diff --git a/rule_packages/c/Language4.json b/rule_packages/c/Language4.json index fb448bd8a3..fdc11924f4 100644 --- a/rule_packages/c/Language4.json +++ b/rule_packages/c/Language4.json @@ -102,10 +102,22 @@ { "description": "Invoking realloc with a size argument set to zero is implementation-defined behavior and declared as an obsolete feature in C18.", "kind": "problem", - "name": "Disallowed size argument value equal to zero in call to realloc", + "name": "Size argument value in realloc call may equal zero", + "precision": "medium", + "severity": "error", + "short_name": "SizeInReallocCallMayBeZero", + "tags": [ + "correctness", + "external/misra/c/2012/amendment3" + ] + }, + { + "description": "Invoking realloc with a size argument set to zero is implementation-defined behavior and declared as an obsolete feature in C18.", + "kind": "problem", + "name": "Size argument value in realloc call is equal zero", "precision": "very-high", "severity": "error", - "short_name": "CallToReallocWithSizeZero", + "short_name": "SizeInReallocCallIsZero", "tags": [ "correctness", "external/misra/c/2012/amendment3" From b1c76190f42c28f51edceadb944b83c3daa7a28c Mon Sep 17 00:00:00 2001 From: Mike Fairhurst Date: Thu, 14 Nov 2024 20:56:51 -0800 Subject: [PATCH 15/15] Fix broken test --- .../RULE-1-5/UngetcCallOnStreamPositionZero.expected | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/c/misra/test/rules/RULE-1-5/UngetcCallOnStreamPositionZero.expected b/c/misra/test/rules/RULE-1-5/UngetcCallOnStreamPositionZero.expected index 98e7b34fbe..ff25a58e3c 100644 --- a/c/misra/test/rules/RULE-1-5/UngetcCallOnStreamPositionZero.expected +++ b/c/misra/test/rules/RULE-1-5/UngetcCallOnStreamPositionZero.expected @@ -1,8 +1,8 @@ edges -| test.c:39:16:39:20 | call to fopen indirection | test.c:41:15:41:18 | file indirection | +| test.c:39:16:39:20 | *call to fopen | test.c:41:15:41:18 | *file | provenance | | nodes -| test.c:39:16:39:20 | call to fopen indirection | semmle.label | call to fopen indirection | -| test.c:41:15:41:18 | file indirection | semmle.label | file indirection | +| test.c:39:16:39:20 | *call to fopen | semmle.label | *call to fopen | +| test.c:41:15:41:18 | *file | semmle.label | *file | subpaths #select -| test.c:41:15:41:18 | file indirection | test.c:39:16:39:20 | call to fopen indirection | test.c:41:15:41:18 | file indirection | Obsolescent call to ungetc on file stream $@ at position zero. | test.c:39:16:39:20 | call to fopen indirection | call to fopen indirection | +| test.c:41:15:41:18 | *file | test.c:39:16:39:20 | *call to fopen | test.c:41:15:41:18 | *file | Obsolescent call to ungetc on file stream $@ at position zero. | test.c:39:16:39:20 | *call to fopen | *call to fopen |