summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bin/sh/expand.c16
-rw-r--r--tools/regression/bin/sh/expansion/length7.014
-rw-r--r--tools/regression/bin/sh/expansion/length8.014
3 files changed, 41 insertions, 3 deletions
diff --git a/bin/sh/expand.c b/bin/sh/expand.c
index c343977..dcef74e 100644
--- a/bin/sh/expand.c
+++ b/bin/sh/expand.c
@@ -665,6 +665,7 @@ evalvar(char *p, int flag)
int special;
int startloc;
int varlen;
+ int varlenb;
int easy;
int quotes = flag & (EXP_FULL | EXP_CASE | EXP_REDIR);
@@ -712,8 +713,15 @@ again: /* jump here after setting a variable with ${var=text} */
if (special) {
varvalue(var, varflags & VSQUOTE, subtype, flag);
if (subtype == VSLENGTH) {
- varlen = expdest - stackblock() - startloc;
- STADJUST(-varlen, expdest);
+ varlenb = expdest - stackblock() - startloc;
+ varlen = varlenb;
+ if (localeisutf8) {
+ val = stackblock() + startloc;
+ for (;val != expdest; val++)
+ if ((*val & 0xC0) == 0x80)
+ varlen--;
+ }
+ STADJUST(-varlenb, expdest);
}
} else {
char const *syntax = (varflags & VSQUOTE) ? DQSYNTAX
@@ -721,7 +729,9 @@ again: /* jump here after setting a variable with ${var=text} */
if (subtype == VSLENGTH) {
for (;*val; val++)
- varlen++;
+ if (!localeisutf8 ||
+ (*val & 0xC0) != 0x80)
+ varlen++;
}
else {
if (quotes)
diff --git a/tools/regression/bin/sh/expansion/length7.0 b/tools/regression/bin/sh/expansion/length7.0
new file mode 100644
index 0000000..b79b116
--- /dev/null
+++ b/tools/regression/bin/sh/expansion/length7.0
@@ -0,0 +1,14 @@
+# $FreeBSD$
+
+unset LC_ALL
+LC_CTYPE=en_US.UTF-8
+export LC_CTYPE
+
+# a umlaut
+s=$(printf '\303\244')
+# euro sign
+s=$s$(printf '\342\202\254')
+# some sort of 't' outside BMP
+s=$s$(printf '\360\235\225\245')
+set -- "$s"
+[ ${#s} = 3 ] && [ ${#1} = 3 ]
diff --git a/tools/regression/bin/sh/expansion/length8.0 b/tools/regression/bin/sh/expansion/length8.0
new file mode 100644
index 0000000..3cc6c15
--- /dev/null
+++ b/tools/regression/bin/sh/expansion/length8.0
@@ -0,0 +1,14 @@
+# $FreeBSD$
+
+unset LC_ALL
+LC_CTYPE=en_US.ISO8859-1
+export LC_CTYPE
+
+# a umlaut
+s=$(printf '\303\244')
+# euro sign
+s=$s$(printf '\342\202\254')
+# some sort of 't' outside BMP
+s=$s$(printf '\360\235\225\245')
+set -- "$s"
+[ ${#s} = 9 ] && [ ${#1} = 9 ]
OpenPOWER on IntegriCloud