Skip to content

Commit fd9eb8a

Browse files
Remodel ungetc() query as a sanitization/path problem
1 parent 1908bbf commit fd9eb8a

File tree

1 file changed

+27
-15
lines changed

1 file changed

+27
-15
lines changed

c/misra/src/rules/RULE-1-5/UngetcCallOnStreamPositionZero.ql

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* @name RULE-1-5: Disallowed obsolescent usage of 'ungetc' on a file stream at position zero
44
* @description Calling the function 'ungetc' on a file stream with a position of zero is an
55
* obsolescent language feature.
6-
* @kind problem
6+
* @kind path-problem
77
* @precision medium
88
* @problem.severity error
99
* @tags external/misra/id/rule-1-5
@@ -52,18 +52,30 @@ class MoveStreamPositionCall extends FunctionCall {
5252
Expr getStreamArgument() { result = streamArgument }
5353
}
5454

55-
from FunctionCall ungetc, DataFlow::Node file
55+
module FilePositionZeroFlowConfig implements DataFlow::ConfigSig {
56+
predicate isSource(DataFlow::Node node) {
57+
node.asIndirectExpr().(FunctionCall).getTarget().hasGlobalOrStdName("fopen")
58+
}
59+
60+
predicate isSink(DataFlow::Node node) {
61+
exists(FunctionCall fc |
62+
fc.getTarget().hasGlobalOrStdName("ungetc") and
63+
node.asIndirectExpr() = fc.getArgument(1)
64+
)
65+
}
66+
67+
predicate isBarrierIn(DataFlow::Node node) {
68+
exists(MoveStreamPositionCall fc | node.asIndirectExpr() = fc.getStreamArgument())
69+
}
70+
}
71+
72+
module FilePositionZeroFlow = DataFlow::Global<FilePositionZeroFlowConfig>;
73+
74+
import FilePositionZeroFlow::PathGraph
75+
76+
from FilePositionZeroFlow::PathNode sink, FilePositionZeroFlow::PathNode source
5677
where
57-
not isExcluded(ungetc, Language4Package::ungetcCallOnStreamPositionZeroQuery()) and
58-
// ungetc() called on file stream
59-
ungetc.getTarget().hasGlobalOrStdName("ungetc") and
60-
DataFlow::localFlow(file, DataFlow::exprNode(ungetc.getArgument(1))) and
61-
// ungetc() is not dominated by a fread() etc to that file stream
62-
not exists(MoveStreamPositionCall moveStreamCall |
63-
DataFlow::localFlow(file, DataFlow::exprNode(moveStreamCall.getStreamArgument())) and
64-
dominates(moveStreamCall, ungetc)
65-
)
66-
// the file stream is the root of the local data flow
67-
and not DataFlow::localFlow(any(DataFlow::Node n | not n = file), file)
68-
select ungetc, "Obsolescent call to ungetc on file stream $@ at position zero.", file,
69-
file.toString()
78+
not isExcluded(sink.getNode().asExpr(), Language4Package::ungetcCallOnStreamPositionZeroQuery()) and
79+
FilePositionZeroFlow::flowPath(source, sink)
80+
select sink.getNode(), source, sink,
81+
"Obsolescent call to ungetc on file stream $@ at position zero.", source, source.toString()

0 commit comments

Comments
 (0)