Skip to content

Commit b010593

Browse files
committed
core: Fix latent @go.printf infinite loop bug
Noticed the bug when trying to run: time COLUMNS=27 ./go help builtins The script would loop infinitely when trying to print the line for the `path` builtin. When the `@go.printf` loop would reach the point where the `prefix` variable contained: 'script, [alias] or' the expression: line="${line#$prefix}" would cause `[alias]` to be interpreted as a set of characters to match per standard Bash pattern matching, rather than as a literal string in its own right. Consequently, the prefix would not get removed from `line`, so `line` would remain constant and the loop condition `"${#line}" -gt "$COLUMNS"` would never fail. The fix was to use index notation and the length of `prefix` to trim `line` instead: line="${line:${#prefix}}" The included test case reproduces the bug and verifies its fix.
1 parent e033875 commit b010593

File tree

2 files changed

+18
-1
lines changed

2 files changed

+18
-1
lines changed

go-core.bash

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,9 @@ declare _GO_INJECT_MODULE_PATH="$_GO_INJECT_MODULE_PATH"
166166
while [[ "${#line}" -gt "$COLUMNS" ]]; do
167167
prefix="${line:0:$COLUMNS}"
168168
prefix="${prefix%[[:space:]]*}"
169-
line="${line#$prefix}"
169+
170+
# Trim `line` using an index in case `prefix` contains pattern characters.
171+
line="${line:${#prefix}}"
170172

171173
if [[ "$prefix" =~ [[:space:]]+$ ]]; then
172174
prefix="${prefix%${BASH_REMATCH[0]}}"

tests/core/printf.bats

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,3 +57,18 @@ teardown() {
5757
run "$TEST_GO_SCRIPT"
5858
assert_success 'foobarbaz'
5959
}
60+
61+
@test "$SUITE: don't loop infinitely if line contains pattern characters" {
62+
# `[alias]` and `[builtin]` were previously interpreted as character sets, not
63+
# literal strings in and of themselves, when appering in `$prefix` in the
64+
# expression `${line#$prefix}`.
65+
local test_string=' path '
66+
test_string+='Prints the path to the <command> script, [alias] or [builtin]'
67+
68+
@go.create_test_go_script "@go.printf '%s' '$test_string'"
69+
COLUMNS=27 run "$TEST_GO_SCRIPT"
70+
assert_success ' path Prints the' \
71+
'path to the <command>' \
72+
'script, [alias] or' \
73+
'[builtin]'
74+
}

0 commit comments

Comments
 (0)