From 1395a28f016f9b4771dd6c9af20e3fb4afd4bf44 Mon Sep 17 00:00:00 2001 From: Rob Landley Date: Thu, 20 Aug 2026 15:56:57 -0500 Subject: [PATCH] Redo xzcat tests, minor xzcat cleanup. --- scripts/runtest.sh | 7 ++-- tests/xzcat.test | 59 +++++++++++++++++------------ toys/pending/xzcat.c | 88 ++++++++++++-------------------------------- 3 files changed, 63 insertions(+), 91 deletions(-) diff --git a/scripts/runtest.sh b/scripts/runtest.sh index 48cebca7..90ce4696 100644 --- a/scripts/runtest.sh +++ b/scripts/runtest.sh @@ -90,11 +90,12 @@ optional() # Evalute command line and skip next test when false skipnot() { - if verbose_has quiet + if verbose_has spam then - eval "$@" >/dev/null 2>&1 - else + echo "$@" eval "$@" + else + eval "$@" >/dev/null 2>&1 fi [ $? -eq 0 ] || { ((++SKIP)); return 1; } } diff --git a/tests/xzcat.test b/tests/xzcat.test index 97804c1f..c0db3a2f 100755 --- a/tests/xzcat.test +++ b/tests/xzcat.test @@ -5,28 +5,41 @@ [ -f testing.sh ] && . testing.sh -#testing "name" "command" "result" "infile" "stdin" -echo "hello" > file -tar -cJf file.xz file -# Get system xzcat -xzcatExe=`which xzcat` -$xzcatExe file.xz > xzcatOut -testcmd "- decompresses a single file" "file.xz > Tempfile && echo "yes"; diff Tempfile xzcatOut && echo "yes"; rm -rf file* xzcatOut Tempfile" "yes\nyes\n" "" "" +testcmd 'canned data basic smoketest' "< $FILES/tar/tar.txz | sha1sum" \ + 'a059548362f0f980febbed50783b6e1359ed4411 -\n' '' '' + +roundtrip() { + skipnot [ -n $(which xz) ] + if [ $SKIP -eq 0 ]; then + local RES="" ONE="$1" LIST="" X=0 + while [ $# -gt 1 ]; do + shift + printf "$1" > file-$((++X)) + xz file-$X + RES+="$1" + LIST+=" file-$X.xz" + done + fi + testcmd "$1" "$LIST && echo yes" "${RES}yes\n" '' '' + rm -f file-* +} #testing "name" "command" "result" "infile" "stdin" -echo "hello" > file1 -echo "hi" > file2 -echo "Hi, Good morning !! I am a xzcat tester" > file3 -tar -cJf file1.xz file1 -tar -cJf file2.xz file2 -tar -cJf file3.xz file3 -# Get system xzcat -xzcatExe=`which xzcat` -$xzcatExe file1.xz file2.xz file3.xz > xzcatOut -testcmd "- decompresses multiple files" "file1.xz file2.xz file3.xz > Tempfile && echo "yes" ; diff Tempfile xzcatOut && echo "yes"; rm -rf file* xzcatOut Tempfile " "yes\nyes\n" "" "" -echo "This is NOT a XZ file!!!" > file -testcmd "bad file" "file 2>/dev/null || echo yes" "yes\n" "" "" -echo "Surely nothing bad will happen to this compressed data!" > file -tar -cJf file.xz file -truncate -s 16 file.xz -testcmd "corrupted file" "file.xz 2>/dev/null || echo yes" "yes\n" "" "" + +# need a compressor for non-canned data tests +[ -z "$(which xz)" ] && SKIP=999 +roundtrip 'hello' 'hello\n' +roundtrip 'multiple files' 'hello\n' 'hi\n' 'This is an xzcat test' +testing 'bad file' \ + 'head -c 32 $FILES/tar/tar.txz | { xzcat 2>/dev/null || echo no;}'\ + 'no\n' '' '' + +# Let's feed it a reasonable sized input +skipnot [ -n "$(which xz)" ] +[ $SKIP -eq 0 ] && { + tar cCf $TOPDIR out.tar toys lib tests + xz > out.txz < out.tar + tar tJf out.txz >/dev/null || ((++SKIP)) +} +testcmd "extract tarball" "out.txz | sha1sum" "$(sha1sum < out.tar)\n" "" "" +rm -f out.tar out.txz diff --git a/toys/pending/xzcat.c b/toys/pending/xzcat.c index 32137854..6406f4bb 100644 --- a/toys/pending/xzcat.c +++ b/toys/pending/xzcat.c @@ -852,11 +852,9 @@ static enum xz_ret xz_dec_bcj_run(struct xz_dec_bcj *s, struct xz_dec_lzma2 *lzm */ if (s->temp.filtered > 0) { bcj_flush(s, b); - if (s->temp.filtered > 0) - return XZ_OK; + if (s->temp.filtered > 0) return XZ_OK; - if (s->ret == XZ_STREAM_END) - return XZ_STREAM_END; + if (s->ret == XZ_STREAM_END) return XZ_STREAM_END; } /* @@ -877,9 +875,7 @@ static enum xz_ret xz_dec_bcj_run(struct xz_dec_bcj *s, struct xz_dec_lzma2 *lzm b->out_pos += s->temp.size; s->ret = xz_dec_lzma2_run(lzma2, b); - if (s->ret != XZ_STREAM_END - && (s->ret != XZ_OK )) - return s->ret; + if (s->ret != XZ_STREAM_END && (s->ret != XZ_OK )) return s->ret; bcj_apply(s, b->out, &out_start, b->out_pos); @@ -888,8 +884,7 @@ static enum xz_ret xz_dec_bcj_run(struct xz_dec_bcj *s, struct xz_dec_lzma2 *lzm * we can do that too, since the last few bytes that remain * unfiltered are meant to remain unfiltered. */ - if (s->ret == XZ_STREAM_END) - return XZ_STREAM_END; + if (s->ret == XZ_STREAM_END) return XZ_STREAM_END; s->temp.size = b->out_pos - out_start; b->out_pos -= s->temp.size; @@ -968,22 +963,10 @@ enum xz_ret xz_dec_bcj_reset(struct xz_dec_bcj *s, char id) return XZ_OK; } -/* - * LZMA2 decoder - */ - - -// BEGIN xz_lzma2.h -/* - * LZMA2 definitions - * - */ +// LZMA2 decoder /* Range coder constants */ -#define RC_SHIFT_BITS 8 -#define RC_TOP_BITS 24 -#define RC_TOP_VALUE (1 << RC_TOP_BITS) #define RC_BIT_MODEL_TOTAL_BITS 11 #define RC_BIT_MODEL_TOTAL (1 << RC_BIT_MODEL_TOTAL_BITS) #define RC_MOVE_BITS 5 @@ -1231,23 +1214,13 @@ static int rc_limit_exceeded(const struct rc_dec *rc) /* Read the next input byte if needed. */ static void rc_normalize(struct rc_dec *rc) { - if (rc->range < RC_TOP_VALUE) { - rc->range <<= RC_SHIFT_BITS; - rc->code = (rc->code << RC_SHIFT_BITS) + rc->in[rc->in_pos++]; + if (rc->range < (1<<24)) { + rc->range <<= 8; + rc->code = (rc->code << 8) + rc->in[rc->in_pos++]; } } -/* - * Decode one bit. In some versions, this function has been splitted in three - * functions so that the compiler is supposed to be able to more easily avoid - * an extra branch. In this particular version of the LZMA decoder, this - * doesn't seem to be a good idea (tested with GCC 3.3.6, 3.4.6, and 4.3.3 - * on x86). Using a non-splitted version results in nicer looking code too. - * - * NOTE: This must return an int. Do not make it return a bool or the speed - * of the code generated by GCC 3.x decreases 10-15 %. (GCC 4.3 doesn't care, - * and it generates 10-20 % faster code than GCC 3.x from this file anyway.) - */ +// decode one bit static int rc_bit(struct rc_dec *rc, uint16_t *prob) { unsigned bound; @@ -1270,16 +1243,13 @@ static int rc_bit(struct rc_dec *rc, uint16_t *prob) } /* Decode a bittree starting from the most significant bit. */ -static unsigned rc_bittree(struct rc_dec *rc, - uint16_t *probs, unsigned limit) +static unsigned rc_bittree(struct rc_dec *rc, uint16_t *probs, unsigned limit) { unsigned symbol = 1; do { - if (rc_bit(rc, &probs[symbol])) - symbol = (symbol << 1) + 1; - else - symbol <<= 1; + if (rc_bit(rc, &probs[symbol])) symbol = (symbol << 1) + 1; + else symbol <<= 1; } while (symbol < limit); return symbol; @@ -1290,8 +1260,7 @@ static void rc_bittree_reverse(struct rc_dec *rc, uint16_t *probs, unsigned *dest, unsigned limit) { - unsigned symbol = 1; - unsigned i = 0; + unsigned symbol = 1, i = 0; do { if (rc_bit(rc, &probs[symbol])) { @@ -2412,8 +2381,7 @@ static enum xz_ret dec_main(struct xz_dec *s, struct xz_buf *b) * simple. Similar approach is used in many places * in this file. */ - if (!fill_temp(s, b)) - return XZ_OK; + if (!fill_temp(s, b)) return XZ_OK; /* * If dec_stream_header() returns @@ -2425,13 +2393,11 @@ static enum xz_ret dec_main(struct xz_dec *s, struct xz_buf *b) s->sequence = SEQ_BLOCK_START; ret = dec_stream_header(s); - if (ret != XZ_OK) - return ret; + if (ret != XZ_OK) return ret; case SEQ_BLOCK_START: /* We need one byte of input to continue. */ - if (b->in_pos == b->in_size) - return XZ_OK; + if (b->in_pos == b->in_size) return XZ_OK; /* See if this is the beginning of the Index field. */ if (!b->in[b->in_pos]) { @@ -2444,27 +2410,23 @@ static enum xz_ret dec_main(struct xz_dec *s, struct xz_buf *b) * Calculate the size of the Block Header and * prepare to decode it. */ - s->block_header.size - = ((unsigned)b->in[b->in_pos] + 1) * 4; + s->block_header.size = (b->in[b->in_pos]+1)<<2; s->temp.size = s->block_header.size; s->temp.pos = 0; s->sequence = SEQ_BLOCK_HEADER; case SEQ_BLOCK_HEADER: - if (!fill_temp(s, b)) - return XZ_OK; + if (!fill_temp(s, b)) return XZ_OK; ret = dec_block_header(s); - if (ret != XZ_OK) - return ret; + if (ret != XZ_OK) return ret; s->sequence = SEQ_BLOCK_UNCOMPRESS; case SEQ_BLOCK_UNCOMPRESS: ret = dec_block(s, b); - if (ret != XZ_STREAM_END) - return ret; + if (ret != XZ_STREAM_END) return ret; s->sequence = SEQ_BLOCK_PADDING; @@ -2489,17 +2451,13 @@ static enum xz_ret dec_main(struct xz_dec *s, struct xz_buf *b) case SEQ_BLOCK_CHECK: if (s->check_type == XZ_CHECK_CRC32) { ret = crc_validate(s, b, 32); - if (ret != XZ_STREAM_END) - return ret; + if (ret != XZ_STREAM_END) return ret; } else if (s->check_type == XZ_CHECK_CRC64) { ret = crc_validate(s, b, 64); - if (ret != XZ_STREAM_END) - return ret; - } - else if (!check_skip(s, b)) { - return XZ_OK; + if (ret != XZ_STREAM_END) return ret; } + else if (!check_skip(s, b)) return XZ_OK; s->sequence = SEQ_BLOCK_START; break; -- 2.39.5