Description
When calling dict2xml() with an indent string that contains a substring like {1111} (i.e., a placeholder with a numeric index) and the input data contains nested structures (dict or list), the library raises an IndexError:
IndexError: Replacement index 1111 out of range for positional args tuple
This happens because the library internally uses str.format() to build the indentation string, and does not escape curly braces before substitution. As a result, the {1111} inside the indent parameter is interpreted as an index placeholder, causing the error.
The indent parameter is documented as accepting a string (not just integer), so any string should be handled safely.
Version of dict2xml
Steps to Reproduce
from dict2xml import dict2xml
data = {'outer': {'inner': 'value'}}
xml = dict2xml(data, wrap='root', indent='{1111}')
Minimal reproducible example – save as bug.py and run.
Expected behavior:
The library should either:
- Escape the curly braces and use the string literally as the indentation, or
- Reject the string with a meaningful validation error (e.g., ValueError: indent contains invalid characters).
Actual behavior:
IndexError: Replacement index 1111 out of range for positional args tuple
Additional Context
- This issue was discovered via fuzzing.
Description
When calling dict2xml() with an indent string that contains a substring like {1111} (i.e., a placeholder with a numeric index) and the input data contains nested structures (dict or list), the library raises an IndexError:
This happens because the library internally uses str.format() to build the indentation string, and does not escape curly braces before substitution. As a result, the {1111} inside the indent parameter is interpreted as an index placeholder, causing the error.
The indent parameter is documented as accepting a string (not just integer), so any string should be handled safely.
Version of dict2xml
Steps to Reproduce
Minimal reproducible example – save as bug.py and run.
Expected behavior:
The library should either:
Actual behavior:
Additional Context