diff --git a/ChangeLog b/ChangeLog index bc340323..7df39453 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,4 @@ -Version 2.16.0.9 (dev) not released yet (2025-12-31) +Version 2.16.0.9 (dev) not released yet (2025-01-12) ==================================================== **Incompatible changes** @@ -15,6 +15,8 @@ Changes Bugs ---- +- CODE128: fix not handling FNC1 at end of data when in manual switching mode + or any FNC1 after manual C mode selected and no other non-C data - CLI: fix "--scalexdimdp" X-dim inch units being divided instead of multiplied on conversion to mm diff --git a/backend/code128.c b/backend/code128.c index 24e357cb..53500f6e 100644 --- a/backend/code128.c +++ b/backend/code128.c @@ -1,7 +1,7 @@ /* code128.c - Handles Code 128 and GS1-128 */ /* libzint - the open source barcode library - Copyright (C) 2008-2025 Robin Stuart + Copyright (C) 2008-2026 Robin Stuart Bugfixes thanks to Christian Sakowski and BogDan Vatra Redistribution and use in source and binary forms, with or without @@ -446,21 +446,24 @@ INTERNAL int zint_code128(struct zint_symbol *symbol, unsigned char source[], in have_a |= !mask_0x60; have_b |= mask_0x60 == 0x60; } + } else if (have_fnc1) { + have_a = have_b = have_c = 1; + for (i = 0; i < length; i++) { + have_extended |= src[i] & 0x80; + } } else { int prev_digit, digit = 0; for (i = 0; i < length; i++) { const unsigned char ch = src[i]; - const int is_fnc1 = ch == '\x1D' && fncs[i]; - if (!is_fnc1) { - const unsigned char mask_0x60 = ch & 0x60; /* 0 for (ch & 0x7F) < 32, 0x60 for (ch & 0x7F) >= 96 */ - const int manual = manuals[i]; - have_extended |= ch & 0x80; - have_a |= !mask_0x60 || manual == C128_A0; - have_b |= mask_0x60 == 0x60 || manual == C128_B0; - prev_digit = digit; - digit = z_isdigit(ch); - have_c |= prev_digit && digit; - } + const unsigned char mask_0x60 = ch & 0x60; /* 0 for (ch & 0x7F) < 32, 0x60 for (ch & 0x7F) >= 96 */ + const int manual = manuals[i]; + assert(!(ch == '\x1D' && fncs[i])); /* Can't be FNC1 */ + have_extended |= ch & 0x80; + have_a |= !mask_0x60 || manual == C128_A0; + have_b |= mask_0x60 == 0x60 || manual == C128_B0; + prev_digit = digit; + digit = z_isdigit(ch); + have_c |= prev_digit && digit; } } c128_set_priority(priority, have_a, have_b, have_c, have_extended); diff --git a/backend/qr.h b/backend/qr.h index 4fc3bb89..495bda12 100644 --- a/backend/qr.h +++ b/backend/qr.h @@ -336,7 +336,7 @@ static const unsigned int rmqr_format_info_right[64] = { }; /* Pre-calculated QR and MicroQR mask tables, generated by "backend/tools/gen_qr_masks.php", - based on lowest common periodicy of the masks (6x12): + based on lowest common periodicity of the masks (6x12): QR: 000: 2x2, 001: 1x2, 010: 3x1, 011: 3x3, 100: 6x4, 101: 6x6, 110: 6x6, 111: 6x6 MicroQR: 00 (001), 01 (100), 10 (110), 11 (111) Taken from Barcode Writer in Pure PostScript (BWIPP) diff --git a/backend/tests/fuzz/fuzz_data_seed_corpus.zip b/backend/tests/fuzz/fuzz_data_seed_corpus.zip index 86420bd5..d2a53dfd 100644 Binary files a/backend/tests/fuzz/fuzz_data_seed_corpus.zip and b/backend/tests/fuzz/fuzz_data_seed_corpus.zip differ diff --git a/backend/tests/fuzz/fuzz_gs1_seed_corpus.zip b/backend/tests/fuzz/fuzz_gs1_seed_corpus.zip index 7f070aaa..378a9c8d 100644 Binary files a/backend/tests/fuzz/fuzz_gs1_seed_corpus.zip and b/backend/tests/fuzz/fuzz_gs1_seed_corpus.zip differ diff --git a/backend/tests/fuzz/gen_corpora.c b/backend/tests/fuzz/gen_corpora.c index 0a8f2816..246ab1f2 100644 --- a/backend/tests/fuzz/gen_corpora.c +++ b/backend/tests/fuzz/gen_corpora.c @@ -14,7 +14,7 @@ /* NOLINTEND(clang-diagnostic-comment) */ /* libzint - the open source barcode library - Copyright (C) 2024-2025 Robin Stuart + Copyright (C) 2024-2026 Robin Stuart Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -866,6 +866,15 @@ static const struct item data_data[] = { /* 40*/ { 6, BARCODE_DOTCODE, -1, -1, -1, -1, -1, "\237", -1 }, /* As above L1090 */ /* 41*/ { 0, BARCODE_MAXICODE, -1, -1, -1, -1, -1, "\223\223\223\223\223\200\000\060\060\020\122\104\060\343\000\000\040\104\104\104\104\177\377\040\000\324\336\000\000\000\000\104\060\060\060\060\104\104\104\104\104\104\104\104\104\104\104\104\104\104\104\104\104\104\104\104\104\104\104\104\104\104\104\060\104\104\000\000\000\040\104\104\104\104\177\377\377\377\324\336\000\000\000\000\104\377\104\001\104\104\104\104\104\104\233\233\060\060\060\060\060\060\060\060\060\325\074", 107 }, /* #181 Nico Gunkel OSS-Fuzz - original OSS-Fuzz triggering data */ /* 42*/ { 1, BARCODE_MAXICODE, -1, -1, -1, -1, -1, "AaAaAaAaAaAaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA123456789", -1 }, /* Add 6 lowercase a's so 6 SHIFTS inserted so 6 + 138 (max input len) = 144 and numbers come at end of buffer */ + /* 43*/ { 0, BARCODE_CODE128, DATA_MODE | EXTRA_ESCAPE_MODE, -1, -1, -1, -1, + "\003\134\136\103\103\103\103\103\103\103\103\103\103\103\103\103\103\103\103\103\103\000\000\051\000\054\103\103\103\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\242\053\134\136\061\067\242\242\242\242\242" + "\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242" + "\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242" + "\136\136", + 162 + }, /* fuzz_data (1st) */ }; /* GS1_MODE data */ diff --git a/backend/tests/test_code128.c b/backend/tests/test_code128.c index 2b2241c1..f4abc997 100644 --- a/backend/tests/test_code128.c +++ b/backend/tests/test_code128.c @@ -1,6 +1,6 @@ /* libzint - the open source barcode library - Copyright (C) 2020-2025 Robin Stuart + Copyright (C) 2020-2026 Robin Stuart Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -106,7 +106,7 @@ static void test_large(const testCtx *const p_ctx) { char cmp_msg[1024]; char ret_buf[8192] = {0}; /* Suppress clang -fsanitize=memory false positive */ - /* Only do BWIPP/ZXing-C++ tests if asked, too slow otherwise */ + /* Only do BWIPP/zxing-cpp tests if asked, too slow otherwise */ int do_bwipp = (debug & ZINT_DEBUG_TEST_BWIPP) && testUtilHaveGhostscript(); int do_zxingcpp = (debug & ZINT_DEBUG_TEST_ZXINGCPP) && testUtilHaveZXingCPPDecoder(); @@ -294,7 +294,7 @@ static void test_hrt(const testCtx *const p_ctx) { char cmp_msg[1024]; char ret_buf[8192]; - /* Only do BWIPP/ZXing-C++ tests if asked, too slow otherwise */ + /* Only do BWIPP/zxing-cpp tests if asked, too slow otherwise */ int do_bwipp = (debug & ZINT_DEBUG_TEST_BWIPP) && testUtilHaveGhostscript(); int do_zxingcpp = (debug & ZINT_DEBUG_TEST_ZXINGCPP) && testUtilHaveZXingCPPDecoder(); @@ -419,7 +419,7 @@ static void test_reader_init(const testCtx *const p_ctx) { char cmp_msg[1024]; char ret_buf[8192]; - /* Only do ZXing-C++ test if asked, too slow otherwise */ + /* Only do zxing-cpp test if asked, too slow otherwise */ int do_zxingcpp = (debug & ZINT_DEBUG_TEST_ZXINGCPP) && testUtilHaveZXingCPPDecoder(); testStartSymbol(p_ctx->func_name, &symbol); @@ -649,6 +649,17 @@ static void test_input(const testCtx *const p_ctx) { /*139*/ { UNICODE_MODE, "12é12é", -1, 0, 123, 0, 1, "(11) 105 12 100 100 73 17 18 100 73 17 106", "StartC 12 CodeB FNC4 é 1 2 FNC4 é; BWIPP different encodation (StartB)" }, /*140*/ { UNICODE_MODE, "1234é123456é", -1, 0, 167, 1, 1, "(15) 105 12 34 100 100 73 99 12 34 56 100 100 73 15 106", "StartC 12 34 CodeB FNC4 é CodeC 12 34 56 CodeB FNC4 é" }, /*141*/ { DATA_MODE, "\256^a\357\033\270\017,\274u$B\305\311\006\011]\273\025u\315\2638\263\333", -1, 0, 453, 1, 899, "(41) 104 100 14 62 65 100 79 101 91 101 24 79 12 101 28 98 85 4 34 101 37 101 41 70 73 61", "" }, + /*142*/ { DATA_MODE | EXTRA_ESCAPE_MODE, "\\^C\\^1", -1, 0, 46, 0, 0, "(4) 105 102 1 106", "StartC FNC1; From fuzz 2026-01-12; BWIPP see below; zxing-cpp empty text" }, + /*143*/ { DATA_MODE | EXTRA_ESCAPE_MODE, "\\^A\\^1", -1, 0, 46, 0, 0, "(4) 103 102 102 106", "StartA FNC1; From fuzz 2026-01-12; BWIPP see below; zxing-cpp empty text" }, + /*144*/ { DATA_MODE | EXTRA_ESCAPE_MODE, "\\^B\\^1", -1, 0, 46, 1, 0, "(4) 104 102 0 106", "StartB FNC1; From fuzz 2026-01-12; zxing-cpp empty text" }, + /*145*/ { DATA_MODE | EXTRA_ESCAPE_MODE, "\\^1", -1, 0, 46, 0, 0, "(4) 105 102 1 106", "StartC FNC1; BWIPP see above; zxing-cpp empty text" }, + /*146*/ { DATA_MODE | EXTRA_ESCAPE_MODE, "\\^C\\^1A", -1, 0, 68, 0, 3, "(6) 105 102 100 33 94 106", "StartC CodeB FNC1 A; BWIPP see below" }, + /*147*/ { DATA_MODE | EXTRA_ESCAPE_MODE, "\\^A\\^1A", -1, 0, 57, 0, 3, "(5) 103 102 33 65 106", "StartA FNC1 A; BWIPP see below" }, + /*148*/ { DATA_MODE | EXTRA_ESCAPE_MODE, "\\^B\\^1A", -1, 0, 57, 1, 3, "(5) 104 102 33 66 106", "StartB FNC1 A" }, + /*149*/ { DATA_MODE | EXTRA_ESCAPE_MODE, "\\^1A", -1, 0, 57, 1, 3, "(5) 104 102 33 66 106", "StartB FNC1 A" }, + /*150*/ { DATA_MODE | EXTRA_ESCAPE_MODE, "A\\^1", -1, 0, 57, 1, 3, "(5) 104 33 102 32 106", "StartB A FNC1" }, + /*151*/ { DATA_MODE | EXTRA_ESCAPE_MODE, "\\^C\\^112", -1, 0, 57, 1, 3, "(5) 105 102 12 25 106", "StartC FNC1 12" }, + /*152*/ { UNICODE_MODE | EXTRA_ESCAPE_MODE, "\\^C\\^1é", -1, 0, 79, 0, 1, "(7) 105 102 100 100 73 72 106", "StartC FNC1 CodeB FNC4 é; BWIPP different encodation (StartB)" }, }; const int data_size = ARRAY_SIZE(data); int i, length, ret; @@ -660,7 +671,7 @@ static void test_input(const testCtx *const p_ctx) { char cmp_msg[1024]; char ret_buf[8192]; - /* Only do BWIPP/ZXing-C++ tests if asked, too slow otherwise */ + /* Only do BWIPP/zxing-cpp tests if asked, too slow otherwise */ int do_bwipp = (debug & ZINT_DEBUG_TEST_BWIPP) && testUtilHaveGhostscript(); int do_zxingcpp = (debug & ZINT_DEBUG_TEST_ZXINGCPP) && testUtilHaveZXingCPPDecoder(); @@ -719,22 +730,28 @@ static void test_input(const testCtx *const p_ctx) { } } if (do_zxingcpp && testUtilCanZXingCPP(i, symbol, data[i].data, length, debug)) { - int cmp_len, ret_len; - char modules_dump[4096]; - assert_nonzero(data[i].zxingcpp_cmp, "i:%d data[i].zxingcpp_cmp == 0", i); - assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, - "i:%d testUtilModulesDump == -1\n", i); - ret = testUtilZXingCPP(i, symbol, data[i].data, length, modules_dump, data[i].zxingcpp_cmp, - cmp_buf, sizeof(cmp_buf), &cmp_len); - assert_zero(ret, "i:%d %s testUtilZXingCPP ret %d != 0\n", - i, testUtilBarcodeName(symbol->symbology), ret); + if (!data[i].zxingcpp_cmp) { + if (debug & ZINT_DEBUG_TEST_PRINT) { + printf("i:%d %s not zxing-cpp compatible (%s)\n", + i, testUtilBarcodeName(symbol->symbology), data[i].comment); + } + } else { + int cmp_len, ret_len; + char modules_dump[4096]; + assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, + "i:%d testUtilModulesDump == -1\n", i); + ret = testUtilZXingCPP(i, symbol, data[i].data, length, modules_dump, data[i].zxingcpp_cmp, + cmp_buf, sizeof(cmp_buf), &cmp_len); + assert_zero(ret, "i:%d %s testUtilZXingCPP ret %d != 0\n", + i, testUtilBarcodeName(symbol->symbology), ret); - ret = testUtilZXingCPPCmp(symbol, cmp_msg, cmp_buf, cmp_len, data[i].data, length, - NULL /*primary*/, ret_buf, &ret_len); - assert_zero(ret, "i:%d %s testUtilZXingCPPCmp %d != 0 %s\n actual: %s\nexpected: %s\n", - i, testUtilBarcodeName(symbol->symbology), ret, cmp_msg, - testUtilEscape(cmp_buf, cmp_len, escaped, sizeof(escaped)), - testUtilEscape(ret_buf, ret_len, escaped2, sizeof(escaped2))); + ret = testUtilZXingCPPCmp(symbol, cmp_msg, cmp_buf, cmp_len, data[i].data, length, + NULL /*primary*/, ret_buf, &ret_len); + assert_zero(ret, "i:%d %s testUtilZXingCPPCmp %d != 0 %s\n actual: %s\nexpected: %s\n", + i, testUtilBarcodeName(symbol->symbology), ret, cmp_msg, + testUtilEscape(cmp_buf, cmp_len, escaped, sizeof(escaped)), + testUtilEscape(ret_buf, ret_len, escaped2, sizeof(escaped2))); + } } } } @@ -798,7 +815,7 @@ static void test_gs1_128_input(const testCtx *const p_ctx) { char cmp_msg[1024]; char ret_buf[8192]; - /* Only do BWIPP/ZXing-C++ tests if asked, too slow otherwise */ + /* Only do BWIPP/zxing-cpp tests if asked, too slow otherwise */ int do_bwipp = (debug & ZINT_DEBUG_TEST_BWIPP) && testUtilHaveGhostscript(); int do_zxingcpp = (debug & ZINT_DEBUG_TEST_ZXINGCPP) && testUtilHaveZXingCPPDecoder(); @@ -924,7 +941,7 @@ static void test_hibc_input(const testCtx *const p_ctx) { char cmp_msg[1024]; char ret_buf[8192]; - /* Only do BWIPP/ZXing-C++ tests if asked, too slow otherwise */ + /* Only do BWIPP/zxing-cpp tests if asked, too slow otherwise */ int do_bwipp = (debug & ZINT_DEBUG_TEST_BWIPP) && testUtilHaveGhostscript(); int do_zxingcpp = (debug & ZINT_DEBUG_TEST_ZXINGCPP) && testUtilHaveZXingCPPDecoder(); @@ -1215,7 +1232,7 @@ static void test_dpd_input(const testCtx *const p_ctx) { char cmp_msg[1024]; char ret_buf[8192]; - /* Only do BWIPP/ZXing-C++ tests if asked, too slow otherwise */ + /* Only do BWIPP/zxing-cpp tests if asked, too slow otherwise */ int do_bwipp = (debug & ZINT_DEBUG_TEST_BWIPP) && testUtilHaveGhostscript(); int do_zxingcpp = (debug & ZINT_DEBUG_TEST_ZXINGCPP) && testUtilHaveZXingCPPDecoder(); @@ -1340,8 +1357,8 @@ static void test_upu_s10_input(const testCtx *const p_ctx) { char cmp_msg[1024]; char ret_buf[8192]; - /* Only do ZXing-C++ test if asked, too slow otherwise */ - /* Only do ZXing-C++ test if asked, too slow otherwise */ + /* Only do zxing-cpp test if asked, too slow otherwise */ + /* Only do zxing-cpp test if asked, too slow otherwise */ int do_zxingcpp = (debug & ZINT_DEBUG_TEST_ZXINGCPP) && testUtilHaveZXingCPPDecoder(); testStartSymbol(p_ctx->func_name, &symbol); @@ -1587,7 +1604,7 @@ static void test_encode(const testCtx *const p_ctx) { char cmp_msg[1024]; char ret_buf[8192]; - /* Only do BWIPP/ZXing-C++ tests if asked, too slow otherwise */ + /* Only do BWIPP/zxing-cpp tests if asked, too slow otherwise */ int do_bwipp = (debug & ZINT_DEBUG_TEST_BWIPP) && testUtilHaveGhostscript(); int do_zxingcpp = (debug & ZINT_DEBUG_TEST_ZXINGCPP) && testUtilHaveZXingCPPDecoder(); @@ -1673,6 +1690,91 @@ static void test_encode(const testCtx *const p_ctx) { testFinish(); } +static void test_fuzz(const testCtx *const p_ctx) { + int debug = p_ctx->debug; + + struct item { + int symbology; + int input_mode; + int option_1; + int option_2; + const char *data; + int length; + int ret; + const char *expected_errtxt; + int zxingcpp_cmp; + }; + /* s/\/\*[ 0-9]*\*\//\=printf("\/\*%3d*\/", line(".") - line("'<")): */ + static const struct item data[] = { + /* 0*/ { BARCODE_CODE128, DATA_MODE | EXTRA_ESCAPE_MODE, -1, -1, + "\003\134\136\103\103\103\103\103\103\103\103\103\103\103\103\103\103\103\103\103\103\000\000\051\000\054\103\103\103\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\242\053\134\136\061\067\242\242\242\242\242" + "\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242" + "\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242\242" + "\136\136", + 162, ZINT_ERROR_TOO_LONG, "Error 341: Input too long, requires 167 symbol characters (maximum 102)", 3 + }, /* fuzz_data (2nd, 2026-01-12) */ + }; + const int data_size = ARRAY_SIZE(data); + int i, length, ret; + struct zint_symbol *symbol = NULL; + + char escaped[8192]; + char cmp_buf[32768]; + char cmp_msg[8192]; + + /* Only do zxing-cpp test if asked, too slow otherwise */ + int do_zxingcpp = (debug & ZINT_DEBUG_TEST_ZXINGCPP) && testUtilHaveZXingCPPDecoder(); + + testStartSymbol(p_ctx->func_name, &symbol); + + for (i = 0; i < data_size; i++) { + + if (testContinue(p_ctx, i)) continue; + + symbol = ZBarcode_Create(); + assert_nonnull(symbol, "Symbol not created\n"); + + length = testUtilSetSymbol(symbol, data[i].symbology, data[i].input_mode, -1 /*eci*/, + data[i].option_1, data[i].option_2, -1 /*option_3*/, -1 /*output_options*/, + data[i].data, data[i].length, debug); + + ret = ZBarcode_Encode(symbol, TCU(data[i].data), length); + assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", + i, ret, data[i].ret, symbol->errtxt); + assert_equal(symbol->errtxt[0] == '\0', ret == 0, "i:%d symbol->errtxt not %s (%s)\n", + i, ret ? "set" : "empty", symbol->errtxt); + assert_zero(strcmp(symbol->errtxt, data[i].expected_errtxt), "i:%d symbol->errtxt %s != %s\n", + i, symbol->errtxt, data[i].expected_errtxt); + + if (ret < ZINT_ERROR) { + + if (do_zxingcpp && testUtilCanZXingCPP(i, symbol, data[i].data, length, debug)) { + int cmp_len, ret_len; + char modules_dump[22801 + 1]; + assert_nonzero(data[i].zxingcpp_cmp, "i:%d data[i].zxingcpp_cmp == 0", i); + assert_notequal(testUtilModulesDump(symbol, modules_dump, sizeof(modules_dump)), -1, + "i:%d testUtilModulesDump == -1\n", i); + ret = testUtilZXingCPP(i, symbol, data[i].data, length, modules_dump, data[i].zxingcpp_cmp, + cmp_buf, sizeof(cmp_buf), &cmp_len); + assert_zero(ret, "i:%d %s testUtilZXingCPP ret %d != 0\n", + i, testUtilBarcodeName(symbol->symbology), ret); + + ret = testUtilZXingCPPCmp(symbol, cmp_msg, cmp_buf, cmp_len, data[i].data, length, NULL /*primary*/, + escaped, &ret_len); + assert_zero(ret, "i:%d %s testUtilZXingCPPCmp %d != 0 %s\n actual: %.*s\nexpected: %.*s\n", + i, testUtilBarcodeName(symbol->symbology), ret, cmp_msg, cmp_len, cmp_buf, ret_len, + escaped); + } + } + + ZBarcode_Delete(symbol); + } + + testFinish(); +} + int main(int argc, char *argv[]) { testFunction funcs[] = { /* name, func */ @@ -1687,6 +1789,7 @@ int main(int argc, char *argv[]) { { "test_dpd_input", test_dpd_input }, { "test_upu_s10_input", test_upu_s10_input }, { "test_encode", test_encode }, + { "test_fuzz", test_fuzz }, }; testRun(argc, argv, funcs, ARRAY_SIZE(funcs)); diff --git a/backend/tests/tools/bwipp_dump.ps.tar.xz b/backend/tests/tools/bwipp_dump.ps.tar.xz index 36a06224..b8522156 100644 Binary files a/backend/tests/tools/bwipp_dump.ps.tar.xz and b/backend/tests/tools/bwipp_dump.ps.tar.xz differ