fix URL-encode targets in -t browse

The browse tool did not correctly encode targets containing '%', causing them to be interpreted incorrectly after URL decoding.
Fix this by URL-encoding targets using urllib.parse.quote when generating links.

The import changes are compatible with both Python 2.7 and Python 3.x.

Additionally included a test to ensure complex target names are preserved exactly during parsing.

Fixes #2652
This commit is contained in:
lklivingstone
2026-03-23 22:50:11 +05:30
parent 5ff92d8a51
commit ec78f22847
2 changed files with 19 additions and 4 deletions

View File

@@ -37,9 +37,9 @@ if sys.version_info >= (3, 2):
else:
from cgi import escape
try:
from urllib.request import unquote # type: ignore # Module "urllib.request" has no attribute "unquote"
from urllib.parse import quote, unquote
except ImportError:
from urllib2 import unquote
from urllib import quote, unquote
from collections import namedtuple
from typing import Tuple, Any
@@ -144,7 +144,7 @@ def generate_html(node: Node) -> str:
if type:
extra = ' (%s)' % html_escape(type)
document.append('<tt><a href="?%s">%s</a>%s</tt><br>' %
(html_escape(input), html_escape(input), extra))
(quote(input), html_escape(input), extra))
document.append('</div>')
if node.outputs:
@@ -152,7 +152,7 @@ def generate_html(node: Node) -> str:
document.append('<div class=filelist>')
for output in sorted(node.outputs):
document.append('<tt><a href="?%s">%s</a></tt><br>' %
(html_escape(output), html_escape(output)))
(quote(output), html_escape(output)))
document.append('</div>')
return '\n'.join(document)

View File

@@ -4405,3 +4405,18 @@ TEST_F(BuildTest, ValidationWithCircularDependency) {
EXPECT_FALSE(builder_.AddTarget("out", &err));
EXPECT_EQ("dependency cycle: validate -> validate_in -> validate", err);
}
TEST_F(StateTestWithBuiltinRules, ComplexTargetPreserved) {
// Ensure targets containing spaces, percent-encoded sequences,
// and URL-reserved characters are preserved exactly during parsing.
ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
"rule copy\n"
" command = cp $in $out\n"
"name = foo %2F bar?baz&x=1\n"
"build $name: copy foo\n"));
Node* node = state_.LookupNode("foo %2F bar?baz&x=1");
ASSERT_NE(node, nullptr);
EXPECT_EQ(node->path(), "foo %2F bar?baz&x=1");
}