Skip to content

Commit e0c8ce0

Browse files
committed
build: fix C string encoding for PRODUCT_DIR_ABS
Since the `PRODUCT_DIR_ABS` gyp variable is meant to be used in a C string in the OpenSSL config, provide a version of it that actually provides it in a way that is always usable as a C string. Otherwise, unescaped characters in the path can mess with the string definitions; for example, building in paths on Windows whose directories start with valid or invalid escape sequences (e.g.: `C:\...\x61foobar\...` or `C:\...\456789\...`) can result in failing builds or incorrect paths provided to OpenSSL.
1 parent 61e4ad5 commit e0c8ce0

File tree

2 files changed

+23
-17
lines changed

2 files changed

+23
-17
lines changed

deps/openssl/openssl.gyp

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,13 @@
55
'nasm_version%': '0.0',
66
'openssl-cli': '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)openssl-cli<(EXECUTABLE_SUFFIX)',
77
'conditions': [
8-
['OS == "win"', {
9-
'obj_dir_abs': '<(PRODUCT_DIR_ABS)/obj',
10-
}],
118
['GENERATOR == "ninja"', {
12-
'obj_dir_abs': '<(PRODUCT_DIR_ABS)/obj',
13-
'modules_dir': '<(PRODUCT_DIR_ABS)/obj/lib/openssl-modules',
9+
'modules_dir': '<(PRODUCT_DIR_ABS_CSTR)/obj/lib/openssl-modules',
1410
}, {
15-
'obj_dir_abs%': '<(PRODUCT_DIR_ABS)/obj.target',
16-
'modules_dir': '<(PRODUCT_DIR_ABS)/obj.target/deps/openssl/lib/openssl-modules',
11+
'modules_dir': '<(PRODUCT_DIR_ABS_CSTR)/obj.target/deps/openssl/lib/openssl-modules',
1712
}],
1813
['OS=="mac"', {
19-
'obj_dir_abs%': '<(PRODUCT_DIR_ABS)/obj.target',
20-
'modules_dir': '<(PRODUCT_DIR_ABS)/obj.target/deps/openssl/lib/openssl-modules',
14+
'modules_dir': '<(PRODUCT_DIR_ABS_CSTR)/obj.target/deps/openssl/lib/openssl-modules',
2115
}],
2216
],
2317
},

tools/gyp/pylib/gyp/__init__.py

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,17 @@
2424
DEBUG_VARIABLES = "variables"
2525
DEBUG_INCLUDES = "includes"
2626

27+
def EscapeForCString(string):
28+
if isinstance(string, str):
29+
string = string.encode(encoding='utf8')
30+
31+
result = ''
32+
for char in string:
33+
if not (32 <= char < 127) or char in (ord('\\'), ord('"')):
34+
result += '\\%03o' % char
35+
else:
36+
result += chr(char)
37+
return result
2738

2839
def DebugOutput(mode, message, *args):
2940
if "all" in gyp.debug or mode in gyp.debug:
@@ -106,18 +117,19 @@ def Load(
106117

107118
output_dir = params["options"].generator_output or params["options"].toplevel_dir
108119
if default_variables["GENERATOR"] == "ninja":
109-
default_variables.setdefault(
110-
"PRODUCT_DIR_ABS",
111-
os.path.join(
112-
output_dir, "out", default_variables.get("build_type", "default")
113-
),
120+
product_dir_abs = os.path.join(
121+
output_dir, "out", default_variables.get("build_type", "default")
114122
)
115123
else:
116-
default_variables.setdefault(
117-
"PRODUCT_DIR_ABS",
118-
os.path.join(output_dir, default_variables["CONFIGURATION_NAME"]),
124+
product_dir_abs = os.path.join(
125+
output_dir, default_variables["CONFIGURATION_NAME"]
119126
)
120127

128+
default_variables.setdefault("PRODUCT_DIR_ABS", product_dir_abs)
129+
default_variables.setdefault(
130+
"PRODUCT_DIR_ABS_CSTR", EscapeForCString(product_dir_abs)
131+
)
132+
121133
# Give the generator the opportunity to set additional variables based on
122134
# the params it will receive in the output phase.
123135
if getattr(generator, "CalculateVariables", None):

0 commit comments

Comments
 (0)