aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoergen Ibsen <ji@ibse.dk>2017-11-23 11:53:34 +0100
committerJussi Pakkanen <jpakkane@gmail.com>2017-11-26 13:21:21 +0200
commit91a01265900c6ee6bf805a7d860f7cde86ccff08 (patch)
tree7ef97d83d7c05ba542a7817a11d753cfc5aa87fc
parent325b2c25b611d1e00a753cefe38f6dd24a988575 (diff)
downloadmeson-91a01265900c6ee6bf805a7d860f7cde86ccff08.zip
meson-91a01265900c6ee6bf805a7d860f7cde86ccff08.tar.gz
meson-91a01265900c6ee6bf805a7d860f7cde86ccff08.tar.bz2
Improve escaping in configuration files
Replace pairs of backslashes before '@' or '\@' with singles (allows escaping the escape character). Do not consume next '@' after '\@'.
-rw-r--r--mesonbuild/mesonlib.py35
-rw-r--r--test cases/common/16 configure file/config6.h.in19
-rw-r--r--test cases/common/16 configure file/meson.build11
-rw-r--r--test cases/common/16 configure file/prog6.c11
4 files changed, 63 insertions, 13 deletions
diff --git a/mesonbuild/mesonlib.py b/mesonbuild/mesonlib.py
index 56d347e..b432bf3 100644
--- a/mesonbuild/mesonlib.py
+++ b/mesonbuild/mesonlib.py
@@ -428,19 +428,28 @@ def do_replacement(regex, line, confdata):
missing_variables = set()
def variable_replace(match):
- varname = match.group(1)
- if varname in confdata:
- (var, desc) = confdata.get(varname)
- if isinstance(var, str):
- pass
- elif isinstance(var, int):
- var = str(var)
- else:
- raise RuntimeError('Tried to replace a variable with something other than a string or int.')
+ # Pairs of escape characters before '@' or '\@'
+ if match.group(0).endswith('\\'):
+ num_escapes = match.end(0) - match.start(0)
+ return '\\' * (num_escapes // 2)
+ # Single escape character and '@'
+ elif match.group(0) == '\\@':
+ return '@'
+ # Template variable to be replaced
else:
- missing_variables.add(varname)
- var = ''
- return var
+ varname = match.group(1)
+ if varname in confdata:
+ (var, desc) = confdata.get(varname)
+ if isinstance(var, str):
+ pass
+ elif isinstance(var, int):
+ var = str(var)
+ else:
+ raise RuntimeError('Tried to replace a variable with something other than a string or int.')
+ else:
+ missing_variables.add(varname)
+ var = ''
+ return var
return re.sub(regex, variable_replace, line), missing_variables
def do_mesondefine(line, confdata):
@@ -473,7 +482,7 @@ def do_conf_file(src, dst, confdata):
raise MesonException('Could not read input file %s: %s' % (src, str(e)))
# Only allow (a-z, A-Z, 0-9, _, -) as valid characters for a define
# Also allow escaping '@' with '\@'
- regex = re.compile(r'(?<!\\)@([-a-zA-Z0-9_]+)@')
+ regex = re.compile(r'(?:\\\\)+(?=\\?@)|\\@|@([-a-zA-Z0-9_]+)@')
result = []
missing_variables = set()
for line in data:
diff --git a/test cases/common/16 configure file/config6.h.in b/test cases/common/16 configure file/config6.h.in
new file mode 100644
index 0000000..9719f87
--- /dev/null
+++ b/test cases/common/16 configure file/config6.h.in
@@ -0,0 +1,19 @@
+/* No escape */
+#define MESSAGE1 "@var1@"
+
+/* Single escape means no replace */
+#define MESSAGE2 "\@var1@"
+
+/* Replace pairs of escapes before '@' or '\@' with escape characters
+ * (note we have to double number of pairs due to C string escaping)
+ */
+#define MESSAGE3 "\\\\@var1@"
+
+/* Pairs of escapes and then single escape to avoid replace */
+#define MESSAGE4 "\\\\\@var1@"
+
+/* Check escaped variable does not overlap following variable */
+#define MESSAGE5 "\@var1@var2@"
+
+/* Check escape character outside variables */
+#define MESSAGE6 "\\ @ \@ \\\\@ \\\\\@"
diff --git a/test cases/common/16 configure file/meson.build b/test cases/common/16 configure file/meson.build
index 4264d07..eda0a8f 100644
--- a/test cases/common/16 configure file/meson.build
+++ b/test cases/common/16 configure file/meson.build
@@ -120,3 +120,14 @@ configure_file(
configuration : conf5
)
test('test5', executable('prog5', 'prog5.c'))
+
+# Test escaping
+conf6 = configuration_data()
+conf6.set('var1', 'foo')
+conf6.set('var2', 'bar')
+configure_file(
+ input : 'config6.h.in',
+ output : '@BASENAME@',
+ configuration : conf6
+)
+test('test6', executable('prog6', 'prog6.c'))
diff --git a/test cases/common/16 configure file/prog6.c b/test cases/common/16 configure file/prog6.c
new file mode 100644
index 0000000..7412404
--- /dev/null
+++ b/test cases/common/16 configure file/prog6.c
@@ -0,0 +1,11 @@
+#include <string.h>
+#include <config6.h>
+
+int main(int argc, char **argv) {
+ return strcmp(MESSAGE1, "foo")
+ || strcmp(MESSAGE2, "@var1@")
+ || strcmp(MESSAGE3, "\\foo")
+ || strcmp(MESSAGE4, "\\@var1@")
+ || strcmp(MESSAGE5, "@var1bar")
+ || strcmp(MESSAGE6, "\\ @ @ \\@ \\@");
+}