Check for printf related issues. Args: filename: The name of the current file. clean_lines: A CleansedLines instance containing the file. linenum: The number of the line to check. error: The function to call with any errors found.
(filename, clean_lines, linenum, error)
| 6193 | |
| 6194 | |
| 6195 | def CheckPrintf(filename, clean_lines, linenum, error): |
| 6196 | """Check for printf related issues. |
| 6197 | |
| 6198 | Args: |
| 6199 | filename: The name of the current file. |
| 6200 | clean_lines: A CleansedLines instance containing the file. |
| 6201 | linenum: The number of the line to check. |
| 6202 | error: The function to call with any errors found. |
| 6203 | """ |
| 6204 | line = clean_lines.elided[linenum] |
| 6205 | |
| 6206 | # When snprintf is used, the second argument shouldn't be a literal. |
| 6207 | match = re.search(r"snprintf\s*\(([^,]*),\s*([0-9]*)\s*,", line) |
| 6208 | if match and match.group(2) != "0": |
| 6209 | # If 2nd arg is zero, snprintf is used to calculate size. |
| 6210 | error( |
| 6211 | filename, |
| 6212 | linenum, |
| 6213 | "runtime/printf", |
| 6214 | 3, |
| 6215 | "If you can, use" |
| 6216 | f" sizeof({match.group(1)}) instead of {match.group(2)}" |
| 6217 | " as the 2nd arg to snprintf.", |
| 6218 | ) |
| 6219 | |
| 6220 | # Check if some verboten C functions are being used. |
| 6221 | if re.search(r"\bsprintf\s*\(", line): |
| 6222 | error(filename, linenum, "runtime/printf", 5, "Never use sprintf. Use snprintf instead.") |
| 6223 | match = re.search(r"\b(strcpy|strcat)\s*\(", line) |
| 6224 | if match: |
| 6225 | error( |
| 6226 | filename, |
| 6227 | linenum, |
| 6228 | "runtime/printf", |
| 6229 | 4, |
| 6230 | f"Almost always, snprintf is better than {match.group(1)}", |
| 6231 | ) |
| 6232 | |
| 6233 | |
| 6234 | def IsDerivedFunction(clean_lines, linenum): |