diff options
author | kevans <kevans@FreeBSD.org> | 2018-01-27 23:20:01 +0000 |
---|---|---|
committer | kevans <kevans@FreeBSD.org> | 2018-01-27 23:20:01 +0000 |
commit | 20076fb14b4aa19b8a383135f86c29c1ea19574d (patch) | |
tree | ddc93e71a1d3adef3362376885202a1408af5a1b /usr.bin | |
parent | 4bc066c359fc4c862855cfd1e3a26977680b7951 (diff) | |
download | FreeBSD-src-20076fb14b4aa19b8a383135f86c29c1ea19574d.zip FreeBSD-src-20076fb14b4aa19b8a383135f86c29c1ea19574d.tar.gz |
MFC r328188,r328189,r328200: Fix wrong output for multibyte corner cases
MFC r328188: od(1): Fix wrong output for corner cases in multibyte locales.
Restore the original character to print if we used the look-ahead
buffer, but that didn't help -- we either got an illegal sequence
or still can't complete.
MFC r328189: od(1): Fix mis-patch from r328188
od_test.sh got duplicated erroneously when it was added in r328188. Dedup.
MFC r328200: Silence the gcc warning: 'op' may be used uninitialized in this
function
PR: 224552
Diffstat (limited to 'usr.bin')
-rw-r--r-- | usr.bin/hexdump/conv.c | 15 | ||||
-rw-r--r-- | usr.bin/hexdump/tests/Makefile | 4 | ||||
-rw-r--r-- | usr.bin/hexdump/tests/d_od_cflag_a.out | 3 | ||||
-rw-r--r-- | usr.bin/hexdump/tests/d_od_cflag_b.out | 3 | ||||
-rwxr-xr-x | usr.bin/hexdump/tests/od_test.sh | 49 |
5 files changed, 72 insertions, 2 deletions
diff --git a/usr.bin/hexdump/conv.c b/usr.bin/hexdump/conv.c index 8ba1311..5a04fc4 100644 --- a/usr.bin/hexdump/conv.c +++ b/usr.bin/hexdump/conv.c @@ -54,6 +54,9 @@ conv_c(PR *pr, u_char *p, size_t bufsize) size_t clen, oclen; int converr, pad, width; u_char peekbuf[MB_LEN_MAX]; + u_char *op; + + op = NULL; if (pr->mbleft > 0) { str = "**"; @@ -105,6 +108,15 @@ retry: else if (clen == (size_t)-1 || (clen == (size_t)-2 && p == peekbuf)) { memset(&pr->mbstate, 0, sizeof(pr->mbstate)); + if (p == peekbuf) { + /* + * We peeked ahead, but that didn't help -- + * we either got an illegal sequence or still + * can't complete; restore original character. + */ + oclen = 0; + p = op; + } wc = *p; clen = 1; converr = 1; @@ -114,6 +126,7 @@ retry: * can complete it. */ oclen = bufsize; + op = p; bufsize = peek(p = peekbuf, MB_CUR_MAX); goto retry; } @@ -126,7 +139,7 @@ retry: if (!odmode) { *pr->cchar = 'c'; (void)printf(pr->fmt, (int)wc); - } else { + } else { *pr->cchar = 'C'; assert(strcmp(pr->fmt, "%3C") == 0); width = wcwidth(wc); diff --git a/usr.bin/hexdump/tests/Makefile b/usr.bin/hexdump/tests/Makefile index 192e106..4c81860 100644 --- a/usr.bin/hexdump/tests/Makefile +++ b/usr.bin/hexdump/tests/Makefile @@ -2,7 +2,7 @@ PACKAGE= tests -ATF_TESTS_SH= hexdump_test +ATF_TESTS_SH= hexdump_test od_test ${PACKAGE}FILES+= d_hexdump_a.in ${PACKAGE}FILES+= d_hexdump_b.in @@ -27,5 +27,7 @@ ${PACKAGE}FILES+= d_hexdump_UCflag_c.out ${PACKAGE}FILES+= d_hexdump_xflag_a.out ${PACKAGE}FILES+= d_hexdump_xflag_b.out ${PACKAGE}FILES+= d_hexdump_xflag_c.out +${PACKAGE}FILES+= d_od_cflag_a.out +${PACKAGE}FILES+= d_od_cflag_b.out .include <bsd.test.mk> diff --git a/usr.bin/hexdump/tests/d_od_cflag_a.out b/usr.bin/hexdump/tests/d_od_cflag_a.out new file mode 100644 index 0000000..db8037f --- /dev/null +++ b/usr.bin/hexdump/tests/d_od_cflag_a.out @@ -0,0 +1,3 @@ +0000000 T e s t T e s t T e s t T e s 345 +0000020 T e s t 345 +0000025 diff --git a/usr.bin/hexdump/tests/d_od_cflag_b.out b/usr.bin/hexdump/tests/d_od_cflag_b.out new file mode 100644 index 0000000..bd9e9d1 --- /dev/null +++ b/usr.bin/hexdump/tests/d_od_cflag_b.out @@ -0,0 +1,3 @@ +0000000 T e s t T e s t T e s t T e s т +0000020 ** Т ** е ** с ** т ** +0000031 diff --git a/usr.bin/hexdump/tests/od_test.sh b/usr.bin/hexdump/tests/od_test.sh new file mode 100755 index 0000000..430c353 --- /dev/null +++ b/usr.bin/hexdump/tests/od_test.sh @@ -0,0 +1,49 @@ +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright 2018 (C) Yuri Pankov +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# $FreeBSD$ + +atf_test_case c_flag +c_flag_head() +{ + atf_set "descr" "Verify -c output (PR 224552)" +} +c_flag_body() +{ + export LC_ALL="en_US.UTF-8" + + printf 'TestTestTestTes\345Test\345' > d_od_cflag.in + atf_check -o file:"$(atf_get_srcdir)/d_od_cflag_a.out" \ + od -c d_od_cflag.in + printf 'TestTestTestTesтТест' > d_od_cflag.in + atf_check -o file:"$(atf_get_srcdir)/d_od_cflag_b.out" \ + od -c d_od_cflag.in +} + +atf_init_test_cases() +{ + atf_add_test_case c_flag +} |