aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandroid-build-team Robot <android-build-team-robot@google.com>2021-03-11 02:06:06 +0000
committerandroid-build-team Robot <android-build-team-robot@google.com>2021-03-11 02:06:06 +0000
commit0d6252e25ed126462b1a2814d7ee3f936d7f8fd7 (patch)
tree68bc188ac714366f1f7dbb559fc661b97de3ec70
parentd2c9cce93e05993fd24978f8e9104a6c387836dd (diff)
parentdf11b64fef81eac90b45956b7c4967a74bf7dc8a (diff)
downloadtoybox-0d6252e25ed126462b1a2814d7ee3f936d7f8fd7.tar.gz
Snap for 7199033 from df11b64fef81eac90b45956b7c4967a74bf7dc8a to sc-release
Change-Id: I12cc01ee12860f3c26813d70176543c473e5495a
-rw-r--r--tests/sh.test22
-rw-r--r--tests/tar.test5
-rw-r--r--toys/posix/tar.c17
3 files changed, 39 insertions, 5 deletions
diff --git a/tests/sh.test b/tests/sh.test
index 58fd6dad..0fed3d06 100644
--- a/tests/sh.test
+++ b/tests/sh.test
@@ -89,6 +89,10 @@ testing 'exec exitval' "$SH -c 'exec echo hello' && echo \$?" "hello\n0\n" "" ""
testing 'simple script' '$SH input' 'input\n' 'echo $0' ''
testing 'simple script2' '$SH ./input two;echo $?' './input+two\n42\n' \
'\necho $0+$1\n\nexit 42' ''
+# this segfaults bash
+toyonly testing 'recursion guard' \
+ '$SH input 2>/dev/null; [ $? -lt 128 ] && echo pass' 'pass\n' \
+ 'source input' ''
testing '$LINENO 1' "$SH input" "1\n" 'echo $LINENO' ''
mkdir sub
@@ -112,6 +116,8 @@ testing "leading assignment fail" \
testing "lineno" "$SH input" "5 one\n6 one\n5 two\n6 two\n" \
'#!/bin/bash\n\nfor i in one two\ndo\n echo $LINENO $i\n echo $LINENO $i\ndone\n' ""
+testing "eval0" "sh -c 'eval echo \$*' one two three" "two three\n" "" ""
+
#########################################################################
# Change EVAL to call sh -c for us, using "bash" explicitly for the host.
export EVAL="$SH -c"
@@ -201,6 +207,8 @@ testing 'quote' "echo \"'\"" "'\n" "" ""
# Loops and flow control
testing "case" 'for i in A C J B; do case "$i" in A) echo got A ;; B) echo and B ;; C) echo then C ;; *) echo default ;; esac; done' \
"got A\nthen C\ndefault\nand B\n" "" ""
+testing 'case;;&' 'case wow in w?w) echo ok;;& wow) echo no; esac' 'ok\nno\n' \
+ "" ""
testing "case newlines" \
$'case i\n\nin\n\na) echo one\n\n;;\n\ni)\n\necho two\n\n;;\n\nesac' \
"two\n" "" ""
@@ -498,6 +506,20 @@ shxpect 'trace redirect' I$'set -x; echo one\n' E$'+ echo one\n'"$P" O$'one\n' \
testing 'source file' 'source input' 'hello\n' 'echo hello \\\n' ''
testing '. file' '. input' 'hello\n' 'echo hello \\\n' ''
testing 'source no newline' 'source input' 'hello \\\n' 'echo hello \\' ''
+testing 'source is live' \
+ 'for i in one two three; do echo "echo $i" > input; source input; done' \
+ 'one\ntwo\nthree\n' 'x' ''
+testing 'source is live in functions' \
+ 'func() { source input; }; for i in one two three; do echo echo $i > input; func; done' \
+ 'one\ntwo\nthree\n' 'x' ''
+testing 'subshell inheritance' \
+ 'func() { source input; cat <(echo $xx; xx=456; echo $xx); echo $xx;}; echo local xx=123 > input; func; echo $xx' \
+ '123\n456\n123\n\n' 'x' ''
+
+testing 'functions() {} in same PID' \
+ '{ echo $BASHPID; chicken() { echo $BASHPID;}; chicken;} | sort -u | wc -l' '1\n' '' ''
+testing 'functions() () different PID' \
+ '{ echo $BASHPID; chicken() ( echo $BASHPID;); chicken;} | sort -u | wc -l' '2\n' '' ''
# TODO finish variable list from shell init
diff --git a/tests/tar.test b/tests/tar.test
index 4b2f2120..70668c9c 100644
--- a/tests/tar.test
+++ b/tests/tar.test
@@ -59,6 +59,11 @@ skipnot id nobody >/dev/null
testing "pass group" "tar c --owner root --group nobody --mtime @0 file | LST" \
"-rw-rw-r-- root/nobody 0 1970-01-01 00:00 file\n" "" ""
+# Historically we output a "base 256" format that _we_ could decode but that
+# GNU tar choked on, so check the exact bytes with SUM, not a LST round trip.
+testing "huge values" "tar c --owner 9999999 --group 8888888 --mtime @0 file | SUM 3" \
+ "396b07fd2f80eeb312462e3bfb7dc1325dc6bcfb\n" "" ""
+
touch -t 198701231234.56 file
testing "pass mtime" \
"tar c --owner root --group root file | LST --full-time" \
diff --git a/toys/posix/tar.c b/toys/posix/tar.c
index f31640c5..c4fb4fa2 100644
--- a/toys/posix/tar.c
+++ b/toys/posix/tar.c
@@ -85,14 +85,19 @@ struct tar_hdr {
prefix[155], padd[12];
};
+// Tar uses ASCII octal when it fits, base-256 otherwise.
+static int ascii_fits(unsigned long long val, int len)
+{
+ return !(val>>(3*(len-1)));
+}
+
// convert from int to octal (or base-256)
static void itoo(char *str, int len, unsigned long long val)
{
- // Do we need binary encoding?
- if (!(val>>(3*(len-1)))) sprintf(str, "%0*llo", len-1, val);
+ if (ascii_fits(val, len)) sprintf(str, "%0*llo", len-1, val);
else {
+ for (str += len; len--; val >>= 8) *--str = val;
*str = 128;
- while (--len) *++str = val>>(3*len);
}
}
#define ITOO(x, y) itoo(x, sizeof(x), y)
@@ -288,9 +293,11 @@ static int add_to_tar(struct dirtree *node)
if (strlen(hname) > sizeof(hdr.name)) write_longname(hname, 'L');
if (!FLAG(numeric_owner)) {
- if (TT.owner || (pw = bufgetpwuid(st->st_uid)))
+ if ((TT.owner || (pw = bufgetpwuid(st->st_uid))) &&
+ ascii_fits(st->st_uid, sizeof(hdr.uid)))
strncpy(hdr.uname, TT.owner ? TT.owner : pw->pw_name, sizeof(hdr.uname));
- if (TT.group || (gr = bufgetgrgid(st->st_gid)))
+ if ((TT.group || (gr = bufgetgrgid(st->st_gid))) &&
+ ascii_fits(st->st_gid, sizeof(hdr.gid)))
strncpy(hdr.gname, TT.group ? TT.group : gr->gr_name, sizeof(hdr.gname));
}