aws configure set: UnboundLocalError (crash) when updating an empty nested config section
Describe the bug
ConfigFileWriter._update_subattributes (awscli/customizations/configure/writer.py) is responsible for writing values into a nested config section, e.g.:
[default]
s3 =
signature_version = s3v4def _update_subattributes(self, index, contents, values, starting_indent):
index += 1
for i in range(index, len(contents)):
line = contents[i]
match = self.OPTION_REGEX.search(line)
if match is not None:
current_indent = len(
match.group(1)) - len(match.group(1).lstrip())
key_name = match.group(1).strip()
if key_name in values:
...
if starting_indent == current_indent or \
self.SECTION_REGEX.search(line) is not None:
...current_indent is only assigned inside if match is not None:. If the nested section is currently empty (e.g. s3 = with no sub-keys yet under it — a completely valid, documented config state, e.g. right after s3 = is first created, or hand-edited), then on the very first loop iteration:
- If the next line is another
[section]header (noOPTION_REGEXmatch),current_indentwas never assigned, and the reference atif starting_indent == current_indentraisesUnboundLocalError. - If the empty
s3 =stanza is the last line in the file, theforloop range is empty, socurrent_indent(andi) are never assigned, and theelseclause of thefor/elseraises the same error.
Repro
import tempfile, os
from awscli.customizations.configure.writer import ConfigFileWriter
content = "[default]\ns3 =\n[profile foo]\nfoo = bar\n"
fd, path = tempfile.mkstemp()
open(path, 'w').write(content)
w = ConfigFileWriter()
w.update_config({'__section__': 'default', 's3': {'addressing_style': 'path'}}, path)Output:
Traceback (most recent call last):
...
File "awscli/customizations/configure/writer.py", line 231, in _update_subattributes
if starting_indent == current_indent or \
^^^^^^^^^^^^^^
UnboundLocalError: cannot access local variable 'current_indent' where it is not associated with a valueSame crash (different line) when s3 = is the last line of the file with nothing after it.
Real-world trigger
Running aws configure set s3.<key> <value> (or s3api.<key>, or any nested <section>.<key> set) against a config file where the target nested section exists but has no sub-keys under it yet throws an unhandled UnboundLocalError instead of writing the value.
Suggested fix
Initialize current_indent = None (and i = index - 1) before the loop, so a line/range with no OPTION_REGEX match doesn't leave the variables unbound, while preserving the existing control flow (None never equals starting_indent, so behavior for all previously-passing cases is unchanged).
I have a PR ready with this fix plus two new regression tests covering both empty-stanza cases (followed by another section, and at end-of-file). Both new tests reproduce the UnboundLocalError against the current code and pass with the fix; full tests/unit/customizations/configure/ (109) and tests/functional/configure/ (33) suites pass with no regressions.
Environment
aws-clidevelop branch (current)
Source: aws/aws-cli