From f4e410f47f92199def4494525d121528b4504bc0 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Thu, 5 Feb 2026 14:56:43 +0100 Subject: [PATCH] [ci] Block new scanf() usage to prevent ~9.8KB flash bloat (#13657) --- script/ci-custom.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/script/ci-custom.py b/script/ci-custom.py index b146c9867e..b5bec74fa7 100755 --- a/script/ci-custom.py +++ b/script/ci-custom.py @@ -756,6 +756,28 @@ def lint_no_sprintf(fname, match): ) +@lint_re_check( + # Match scanf family functions: scanf, sscanf, fscanf, vscanf, vsscanf, vfscanf + # Also match std:: prefixed versions + # [^\w] ensures we match function calls, not substrings + r"[^\w]((?:std::)?v?[fs]?scanf)\s*\(" + CPP_RE_EOL, + include=cpp_include, +) +def lint_no_scanf(fname, match): + func = match.group(1) + return ( + f"{highlight(func + '()')} is not allowed in new ESPHome code. The scanf family " + f"pulls in ~7KB flash on ESP8266 and ~9KB on ESP32, and ESPHome doesn't otherwise " + f"need this code.\n" + f"Please use alternatives:\n" + f" - {highlight('parse_number(str)')} for parsing integers/floats from strings\n" + f" - {highlight('strtol()/strtof()')} for C-style number parsing with error checking\n" + f" - {highlight('parse_hex()')} for hex string parsing\n" + f" - Manual parsing for simple fixed formats\n" + f"(If strictly necessary, add `// NOLINT` to the end of the line)" + ) + + @lint_content_find_check( "ESP_LOG", include=["*.h", "*.tcc"],