|
3 | 3 | * @name RULE-1-5: Disallowed obsolescent usage of 'ungetc' on a file stream at position zero
|
4 | 4 | * @description Calling the function 'ungetc' on a file stream with a position of zero is an
|
5 | 5 | * obsolescent language feature.
|
6 |
| - * @kind problem |
| 6 | + * @kind path-problem |
7 | 7 | * @precision medium
|
8 | 8 | * @problem.severity error
|
9 | 9 | * @tags external/misra/id/rule-1-5
|
@@ -52,18 +52,30 @@ class MoveStreamPositionCall extends FunctionCall {
|
52 | 52 | Expr getStreamArgument() { result = streamArgument }
|
53 | 53 | }
|
54 | 54 |
|
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 |
56 | 77 | 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