From 9828037ff189331fc2980cd4156c7ce94c78210c Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 11 Sep 2026 14:18:53 -0500 Subject: [PATCH] [core] Let the scanf buffer argument contain a call with commas --- esphome/code_scan.py | 5 +++-- tests/unit_tests/test_code_scan.py | 3 +++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/esphome/code_scan.py b/esphome/code_scan.py index eede0f7747a..4d0342f872c 100644 --- a/esphome/code_scan.py +++ b/esphome/code_scan.py @@ -23,9 +23,10 @@ from esphome.types import ConfigType _LOGGER = logging.getLogger(__name__) # The string literal handed to a scanf family call as its format: an optional -# first argument (sscanf/fscanf, possibly a literal itself) then the literal. +# first argument (sscanf/fscanf; a literal or a call with its own commas is +# fine) then the literal. _SCANF_FORMAT_RE = re.compile( - r'scanf\s*\((?:(?:"(?:[^"\\]|\\.)*"|[^,;"])*,)?\s*"((?:[^"\\]|\\.)*)"' + r'scanf\s*\((?:(?:"(?:[^"\\]|\\.)*"|\([^()]*\)|[^,;"()])*,)?\s*"((?:[^"\\]|\\.)*)"' ) # Standard scanf float conversions %f %F %e %E %g %G %a %A with optional # suppression, width and length; also the invalid %.2f users write by analogy diff --git a/tests/unit_tests/test_code_scan.py b/tests/unit_tests/test_code_scan.py index fa8efdf14a0..6ba602d6364 100644 --- a/tests/unit_tests/test_code_scan.py +++ b/tests/unit_tests/test_code_scan.py @@ -43,6 +43,9 @@ from esphome.types import ConfigType # Escaped quotes, nested calls, a ')' inside the format, an unterminated call ('sscanf(buf, "\\"%f\\"", &v)', True), ('sscanf(f(x), "%f", &v)', True), + ('sscanf(s.substr(0, 2).c_str(), "%f", &v)', True), + ('sscanf(strtok(s, ","), "%f", &v)', True), + ('sscanf(strtok(s, ","), "%d", &v)', False), ('sscanf(buf, "%d)", &a); g("%f")', False), ('sscanf(buf, "%d", &a; g("%f")', False), ('sscanf(buf, "%f"', True),