Improve escaping in configuration files

Replace pairs of backslashes before '@' or '\@' with singles (allows
escaping the escape character). Do not consume next '@' after '\@'.
pull/2691/head
Joergen Ibsen 7 years ago committed by Jussi Pakkanen
parent 325b2c25b6
commit 91a0126590
  1. 35
      mesonbuild/mesonlib.py
  2. 19
      test cases/common/16 configure file/config6.h.in
  3. 11
      test cases/common/16 configure file/meson.build
  4. 11
      test cases/common/16 configure file/prog6.c

@ -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:

@ -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 "\\ @ \@ \\\\@ \\\\\@"

@ -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'))

@ -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, "\\ @ @ \\@ \\@");
}
Loading…
Cancel
Save