Address an ambiguity in @WrappedPath() in GN generate_wrapper.

In the GN generate_wrapper() template, it turns out there is
an ambiguity with the @WrappedPath() syntax: if you pass in
something (say, @WrappedPath(./foo)) that ends up resolving to
the current directory, it's unclear if the resolved path should be
'./foo' or 'foo'. The prior code would resolve it to 'foo', but
that causes a problem for scripts like test_env.py that want to
invoke the path as an executable; passing the result to something
like os.Popen() will cause the interpreter to search $PATH for
'foo', rather than invoking './foo' directly, and if '.' isn't in
PATH, you get an error as a result.

This CL changes the logic to return './foo' instead; hopefully
there are no cases where the value needs to be 'foo'. If there are;
we'll need to adopt a different approach.

Change-Id: I4905eba1280ed39e79140a6a850ef8139279dfdd
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2264931
Commit-Queue: Dirk Pranke <dpranke@google.com>
Reviewed-by: Stephen Martinis <martiniss@chromium.org>
Reviewed-by: Andrew Grieve <agrieve@chromium.org>
Cr-Commit-Position: refs/heads/master@{#783670}
GitOrigin-RevId: ef048c0d1b29619e5f526744357a7525e95e3b30
This commit is contained in:
Dirk Pranke 2020-06-29 21:07:13 +00:00 коммит произвёл Copybara-Service
Родитель c356f93853
Коммит 7e8525df8d
1 изменённых файлов: 22 добавлений и 3 удалений

Просмотреть файл

@ -42,8 +42,7 @@ SCRIPT_TEMPLATES = {
}
PY_TEMPLATE = textwrap.dedent(
"""\
PY_TEMPLATE = textwrap.dedent("""\
import os
import re
import subprocess
@ -59,7 +58,27 @@ PY_TEMPLATE = textwrap.dedent(
if m:
relpath = os.path.join(
os.path.relpath(_SCRIPT_DIR), _PATH_TO_OUTPUT_DIR, m.group(1))
return os.path.normpath(relpath)
npath = os.path.normpath(relpath)
if os.path.sep not in npath:
# If the original path points to something in the current directory,
# returning the normalized version of it can be a problem.
# normpath() strips off the './' part of the path
# ('./foo' becomes 'foo'), which can be a problem if the result
# is passed to something like os.execvp(); in that case
# osexecvp() will search $PATH for the executable, rather than
# just execing the arg directly, and if '.' isn't in $PATH, this
# results in an error.
#
# So, we need to explicitly return './foo' (or '.\\foo' on windows)
# instead of 'foo'.
#
# Hopefully there are no cases where this causes a problem; if
# there are, we will either need to change the interface to
# WrappedPath() somehow to distinguish between the two, or
# somehow ensure that the wrapped executable doesn't hit cases
# like this.
return '.' + os.path.sep + npath
return npath
return arg