A quoted include path keeps its hash in the shared-configuration scan

This commit is contained in:
J. Nick Koston
2026-10-17 10:37:14 -10:00
parent 4165dbb534
commit 73564dbebd
2 changed files with 34 additions and 3 deletions
+12 -3
View File
@@ -67,7 +67,6 @@ _INDENT_RE = re.compile(r"\s*")
_KEY_FIELD_RE = re.compile(rf"^\s*{CONF_KEY}\s*:")
_BARE_BLOCK_RE = re.compile(rf"^\s*{CONF_ENCRYPTION}\s*:\s*(#.*)?$")
_YAML_SUFFIXES = (".yaml", ".yml")
_COMMENT_RE = re.compile(r"(?:^|\s)#.*$")
_INCLUDE_DIR_RE = re.compile(r"!include_dir_\w+\s+(?P<dir>[^\s#]+)")
# An include or package file whose path holds a substitution
_SUBSTITUTED_INCLUDE_RE = re.compile(
@@ -100,8 +99,18 @@ def _indent(text: str) -> str:
def _without_comment(text: str) -> str:
"""The line up to its comment, which starts at a `#` after whitespace."""
return _COMMENT_RE.sub("", text)
"""The line up to its comment: a `#` after whitespace that is not inside
a quoted scalar, so `!include "shared # ota.yaml"` keeps its name."""
quote = ""
for i, char in enumerate(text):
if quote:
if char == quote:
quote = ""
elif char in "\"'":
quote = char
elif char == "#" and (i == 0 or text[i - 1].isspace()):
return text[:i]
return text
def _file_use_re(file_name: str) -> re.Pattern[str]:
+22
View File
@@ -729,6 +729,28 @@ def test_shared_secret_scan_covers_yml_and_skips_unreadable_files(
assert [e.shared_with for e in edits] == [[tmp_path.resolve() / "other.yml"]]
def test_shared_include_with_a_hash_in_its_quoted_name_is_reported(
tmp_path: Path,
) -> None:
"""A `#` inside a quoted include path is part of the name, not a comment."""
(tmp_path / "shared # ota.yaml").write_bytes(
f'encryption:\n key: "{OLD_KEY}"\n'.encode()
)
(tmp_path / "other.yaml").write_bytes(
b'api: !include "shared # ota.yaml" # the device next door\n'
)
_setup(
tmp_path,
"esphome:\n name: test\n\napi: !include 'shared # ota.yaml'\n\n"
"ota:\n - platform: esphome\n encryption:\n",
)
edits = locate_key_edits(OLD_KEY, NEW_KEY)
with_sharers(edits)
assert [(e.path.name, e.shared_with) for e in edits] == [
("shared # ota.yaml", [tmp_path.resolve() / "other.yaml"])
]
def test_literal_key_in_a_shared_include_is_reported(tmp_path: Path) -> None:
"""Another configuration including the file that holds the key is
listed, like a shared secret."""