From 38bc4fbfe22bfa862ee0a36f17f5b0bad3d9ed92 Mon Sep 17 00:00:00 2001 From: Dan Helfman Date: Tue, 30 Apr 2024 09:36:26 -0700 Subject: [PATCH] Fix interaction between environment variable interpolation in constants and shell escaping (#860). --- NEWS | 3 +++ borgmatic/config/constants.py | 15 +++++++++------ setup.py | 2 +- tests/unit/config/test_constants.py | 11 +++++++++++ 4 files changed, 24 insertions(+), 7 deletions(-) diff --git a/NEWS b/NEWS index a416b683b..9cdb2b03a 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,6 @@ +1.8.12.dev0 + * #860: Fix interaction between environment variable interpolation in constants and shell escaping. + 1.8.11 * #815: Add optional Healthchecks auto-provisioning via "create_slug" option. * #851: Fix lack of file extraction when using "extract --strip-components all" on a path with a diff --git a/borgmatic/config/constants.py b/borgmatic/config/constants.py index 99f461bfb..7a345ea8e 100644 --- a/borgmatic/config/constants.py +++ b/borgmatic/config/constants.py @@ -50,12 +50,15 @@ def apply_constants(value, constants, shell_escape=False): value[index] = apply_constants(list_value, constants, shell_escape) elif isinstance(value, dict): for option_name, option_value in value.items(): - shell_escape = ( - shell_escape - or option_name.startswith('before_') - or option_name.startswith('after_') - or option_name == 'on_error' + value[option_name] = apply_constants( + option_value, + constants, + shell_escape=( + shell_escape + or option_name.startswith('before_') + or option_name.startswith('after_') + or option_name == 'on_error' + ), ) - value[option_name] = apply_constants(option_value, constants, shell_escape) return value diff --git a/setup.py b/setup.py index 05076e7bc..3e34d7e78 100644 --- a/setup.py +++ b/setup.py @@ -1,6 +1,6 @@ from setuptools import find_packages, setup -VERSION = '1.8.11' +VERSION = '1.8.12.dev0' setup( diff --git a/tests/unit/config/test_constants.py b/tests/unit/config/test_constants.py index dbb3b7727..a4c696310 100644 --- a/tests/unit/config/test_constants.py +++ b/tests/unit/config/test_constants.py @@ -50,6 +50,16 @@ def test_apply_constants_with_empty_constants_passes_through_value(): ({'before_backup': '{inject}'}, {'before_backup': "'echo hi; naughty-command'"}), ({'after_backup': '{inject}'}, {'after_backup': "'echo hi; naughty-command'"}), ({'on_error': '{inject}'}, {'on_error': "'echo hi; naughty-command'"}), + ( + { + 'before_backup': '{env_pass}', + 'postgresql_databases': [{'name': 'users', 'password': '{env_pass}'}], + }, + { + 'before_backup': "'${PASS}'", + 'postgresql_databases': [{'name': 'users', 'password': '${PASS}'}], + }, + ), (3, 3), (True, True), (False, False), @@ -63,6 +73,7 @@ def test_apply_constants_makes_string_substitutions(value, expected_value): 'int': 3, 'bool': True, 'inject': 'echo hi; naughty-command', + 'env_pass': '${PASS}', } assert module.apply_constants(value, constants) == expected_value