From 545d54dd268bf5d5638c524086879d031919fc3f Mon Sep 17 00:00:00 2001 From: Frank Hunleth Date: Sun, 28 Jan 2024 22:20:06 -0500 Subject: [PATCH] Remove escaping of backslashes to support literal ${var} THIS IS A BACKWARDS INCOMPATIBLE CHANGE THAT AFFECTS FW FILE CREATION. It does not affect processing of fw files so you don't need to worry about change fwup versions on existing devices or worry about applying .fw files created with old versions of fwup. Automatic escaping of backslashes made it impossible to write `${var}` to a U-Boot variable. Here's why. When doing this, you have to remember that `fwup` evaluates variable substitution twice - once when making the .fw file and once when applying it. You obviously have to escape the `$` when creating the .fw file. That made sense. Then to survive the apply step, you'd think that you could double escape the `$`. You'd be wrong, though, since `fwup` was escaping the backslashes that you were adding writing the configuration to the .fw file. Therefore, the variable substitution was guaranteed to happen since you couldn't double escape a `$`. Amazingly, the auto-escaping behavior was only tested in the regression tests via the exec test on Windows - a combination that would never be used for real. When you run into this issue, it's weird enough to be pretty confusing, imho. Hopefully that and how rare should have been in real uses cases makes this something that no one actually did. This changes string processing to not automatically escape backslashes when creating the .fw file. It is possible to escape a `$` through to the end. This allows you to write a U-Boot environment variable with a `${var}` in it. This also locks down string processing behaviors by adding unit tests. --- src/cfgprint.c | 7 ++++-- tests/004_env_vars.test | 8 ++++++ tests/135_execute.test | 5 +++- tests/201_string_handling.test | 45 ++++++++++++++++++++++++++++++++++ tests/Makefile.am | 3 ++- 5 files changed, 64 insertions(+), 4 deletions(-) create mode 100755 tests/201_string_handling.test diff --git a/src/cfgprint.c b/src/cfgprint.c index 6652d47d..00aaf58d 100644 --- a/src/cfgprint.c +++ b/src/cfgprint.c @@ -70,12 +70,15 @@ static void fwup_cfg_opt_nprint_var(cfg_opt_t *opt, unsigned int index, struct s case CFGT_STR: { const char *str = cfg_opt_getnstr(opt, index); + // Fwup's feature of re-evaluating strings when applying firmware + // updates is a feature and used to modify behavior when applying + // firmware updates (aka runtime). Fwup has always escaped double + // quotes, though, since it really messes up error messages when + // double quotes aren't escaped. ssprintf(s, "\""); while (str && *str) { if (*str == '"') ssprintf(s, "\\\""); - else if (*str == '\\') - ssprintf(s, "\\\\"); else ssprintf(s, "%c", *str); str++; diff --git a/tests/004_env_vars.test b/tests/004_env_vars.test index 64d7cdad..89ac3c6f 100755 --- a/tests/004_env_vars.test +++ b/tests/004_env_vars.test @@ -16,6 +16,12 @@ cat >"$CONFIG" <"$EXPECTED_META_CONF" <$LOCAL_FILE <$CONFIG <$EXPECTED_META_CONF <