| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -192,6 +192,37 @@ private class UnsignedMulExpr extends MulExpr { | |||
| 192 | 192 | } | |
| 193 | 193 | } | |
| 194 | 194 | ||
| 195 | + /** | ||
| 196 | + * Gets the value of the `EOF` macro. | ||
| 197 | + * | ||
| 198 | + * This is typically `"-1"`, but this is not guaranteed to be the case on all | ||
| 199 | + * systems. | ||
| 200 | + */ | ||
| 201 | + private int getEofValue() { | ||
| 202 | + exists(MacroInvocation mi | | ||
| 203 | + mi.getMacroName() = "EOF" and | ||
| 204 | + result = unique( | | mi.getExpr().getValue().toInt()) | ||
| 205 | + ) | ||
| 206 | + } | ||
| 207 | + | ||
| 208 | + /** Get standard `getc` function or related variants. */ | ||
| 209 | + private class Getc extends Function { | ||
| 210 | + Getc() { this.hasGlobalOrStdOrBslName(["fgetc", "getc"]) } | ||
| 211 | + } | ||
| 212 | + | ||
| 213 | + /** A call to `getc` */ | ||
| 214 | + private class CallToGetc extends FunctionCall { | ||
| 215 | + CallToGetc() { this.getTarget() instanceof Getc } | ||
| 216 | + } | ||
| 217 | + | ||
| 218 | + /** | ||
| 219 | + * A call to `getc` that we can analyze because we know | ||
| 220 | + * the value of the `EOF` macro. | ||
| 221 | + */ | ||
| 222 | + private class AnalyzableCallToGetc extends CallToGetc { | ||
| 223 | + AnalyzableCallToGetc() { exists(getEofValue()) } | ||
| 224 | + } | ||
| 225 | + | ||
| 195 | 226 | /** | |
| 196 | 227 | * Holds if `expr` is effectively a multiplication of `operand` with the | |
| 197 | 228 | * positive constant `positive`. | |
@@ -287,6 +318,8 @@ private predicate analyzableExpr(Expr e) { | |||
| 287 | 318 | or | |
| 288 | 319 | e instanceof RemExpr | |
| 289 | 320 | or | |
| 321 | + e instanceof AnalyzableCallToGetc | ||
| 322 | + or | ||
| 290 | 323 | // A conversion is analyzable, provided that its child has an arithmetic | |
| 291 | 324 | // type. (Sometimes the child is a reference type, and so does not get | |
| 292 | 325 | // any bounds.) Rather than checking whether the type of the child is | |
@@ -861,6 +894,14 @@ private float getLowerBoundsImpl(Expr expr) { | |||
| 861 | 894 | ) | |
| 862 | 895 | ) | |
| 863 | 896 | or | |
| 897 | + exists(AnalyzableCallToGetc getc | | ||
| 898 | + expr = getc and | ||
| 899 | + // from https://en.cppreference.com/w/c/io/fgetc: | ||
| 900 | + // On success, returns the obtained character as an unsigned char | ||
| 901 | + // converted to an int. On failure, returns EOF. | ||
| 902 | + result = min([typeLowerBound(any(UnsignedCharType pct)), getEofValue()]) | ||
| 903 | + ) | ||
| 904 | + or | ||
| 864 | 905 | // If the conversion is to an arithmetic type then we just return the | |
| 865 | 906 | // lower bound of the child. We do not need to handle truncation and | |
| 866 | 907 | // overflow here, because that is done in `getTruncatedLowerBounds`. | |
@@ -1055,6 +1096,14 @@ private float getUpperBoundsImpl(Expr expr) { | |||
| 1055 | 1096 | ) | |
| 1056 | 1097 | ) | |
| 1057 | 1098 | or | |
| 1099 | + exists(AnalyzableCallToGetc getc | | ||
| 1100 | + expr = getc and | ||
| 1101 | + // from https://en.cppreference.com/w/c/io/fgetc: | ||
| 1102 | + // On success, returns the obtained character as an unsigned char | ||
| 1103 | + // converted to an int. On failure, returns EOF. | ||
| 1104 | + result = max([typeUpperBound(any(UnsignedCharType pct)), getEofValue()]) | ||
| 1105 | + ) | ||
| 1106 | + or | ||
| 1058 | 1107 | // If the conversion is to an arithmetic type then we just return the | |
| 1059 | 1108 | // upper bound of the child. We do not need to handle truncation and | |
| 1060 | 1109 | // overflow here, because that is done in `getTruncatedUpperBounds`. | |
| Back | FazBrowse Home | New Git URL |
0 commit comments