From 90012ab23fb54b05dc7203d593977f05d326164f Mon Sep 17 00:00:00 2001 From: gitlost Date: Mon, 5 Oct 2020 23:22:06 +0100 Subject: [PATCH] EANX_CC: allow for check digit + buffer overflow for too long add-on; GUI text colour; cmake 3.0 --- CMakeLists.txt | 64 ++++--- backend/composite.c | 21 ++- backend/emf.c | 5 +- backend/qr.c | 2 + backend/tests/test_composite.c | 12 ++ backend/tests/test_imail.c | 17 +- backend/tests/test_mailmark.c | 7 +- backend/tests/test_upcean.c | 306 ++++++++++++++++++++++++++++++--- backend/tests/testcommon.c | 4 +- backend/upcean.c | 93 ++++++---- backend_qt/qzint.cpp | 3 + docs/manual.txt | 4 +- 12 files changed, 431 insertions(+), 107 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b673c1d6..f5a11c22 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,7 @@ # (c) 2008 by BogDan Vatra < bogdan@licentia.eu > +# vim: set ts=4 sw=4 et : -cmake_minimum_required(VERSION 2.6) +cmake_minimum_required(VERSION 3.0) project(zint-package) set(CMAKE_INCLUDE_CURRENT_DIR ON) @@ -14,7 +15,7 @@ set (ZINT_VERSION_RELEASE 1) set (ZINT_VERSION_BUILD ".9") # Set to "" before release, set to ".9" after release set (ZINT_VERSION "${ZINT_VERSION_MAJOR}.${ZINT_VERSION_MINOR}.${ZINT_VERSION_RELEASE}${ZINT_VERSION_BUILD}" ) -add_definitions (-DZINT_VERSION=\"${ZINT_VERSION}\" -Wall) +add_definitions(-DZINT_VERSION=\"${ZINT_VERSION}\") set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/modules" ) @@ -25,31 +26,50 @@ set(ZINT_STATIC FALSE CACHE BOOL "Build static library") include (SetPaths.cmake) -INCLUDE (CheckCXXCompilerFlag) +include(CheckCXXCompilerFlag) -if (CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_GNUCC) - check_cxx_compiler_flag("-Wall" CXX_COMPILER_FLAG_WALL) - if (CXX_COMPILER_FLAG_WALL) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall") - endif (CXX_COMPILER_FLAG_WALL) - if (ZINT_DEBUG) +check_cxx_compiler_flag("-Wall" CXX_COMPILER_FLAG_WALL) +if(CXX_COMPILER_FLAG_WALL) + add_compile_options("-Wall") +endif() + +check_cxx_compiler_flag("-Wextra" CXX_COMPILER_FLAG_WEXTRA) +if(CXX_COMPILER_FLAG_WEXTRA) + add_compile_options("-Wextra") +endif() + +check_cxx_compiler_flag("-Wpedantic" CXX_COMPILER_FLAG_WPEDANTIC) +if(CXX_COMPILER_FLAG_WPEDANTIC) + add_compile_options("-Wpedantic") +endif() + +if(ZINT_DEBUG) + check_cxx_compiler_flag("-g" CXX_COMPILER_FLAG_G) + if(CXX_COMPILER_FLAG_G) add_compile_options("-g") + endif() + check_cxx_compiler_flag("-O0" CXX_COMPILER_FLAG_O0) + if(CXX_COMPILER_FLAG_O0) add_compile_options("-O0") - endif (ZINT_DEBUG) - if (ZINT_SANITIZE) - add_compile_options("-fsanitize=undefined") - add_compile_options("-fsanitize=address") - set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=undefined -fsanitize=address") - endif (ZINT_SANITIZE) - if (ZINT_TEST) - add_definitions("-DZINT_TEST") - endif (ZINT_TEST) -endif (CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_GNUCC) + endif() +endif() +if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_GNUCC) + if(ZINT_SANITIZE) + add_compile_options(-fsanitize=undefined -fsanitize=address) + link_libraries(-fsanitize=undefined -fsanitize=address) + # Gives warning on MainWindow::setupUI() and retries (and takes forever) if var-tracking-assignments enabled + add_compile_options(-fno-var-tracking-assignments) + endif() +endif() + +if(ZINT_TEST) + add_definitions("-DZINT_TEST") +endif() IF(APPLE) - IF (UNIVERSAL) # TODO: make univeral binary - IF(NOT ZINT_HAS_BEEN_RUN_BEFORE and UNIVERAL) + IF (UNIVERSAL) # TODO: make universal binary + IF(NOT ZINT_HAS_BEEN_RUN_BEFORE) IF(EXISTS /Developer/SDKs/MacOSX10.5.sdk OR EXISTS /SDKs/MacOSX10.5.sdk) SET(CMAKE_OSX_ARCHITECTURES "ppc;i386;ppc64;x86_64" CACHE STRING "Build architectures for OSX" FORCE) SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility-inlines-hidden -Wl -single_module " CACHE STRING "Flags used by the compiler during all build types." FORCE) @@ -125,5 +145,3 @@ install(FILES cmake/modules/FindZint.cmake DESTINATION ${CMAKE_MODULES_INSTALL_P IF(NOT ZINT_HAS_BEEN_RUN_BEFORE) SET(ZINT_HAS_BEEN_RUN_BEFORE 1 CACHE INTERNAL "Flag to track whether this is the first time running CMake or if CMake has been configured before") ENDIF(NOT ZINT_HAS_BEEN_RUN_BEFORE) - - diff --git a/backend/composite.c b/backend/composite.c index d41619cf..30c7a7f0 100644 --- a/backend/composite.c +++ b/backend/composite.c @@ -65,7 +65,7 @@ INTERNAL int eanx(struct zint_symbol *symbol, unsigned char source[], int length); INTERNAL int ean_128(struct zint_symbol *symbol, unsigned char source[], const size_t length); -INTERNAL void ean_leading_zeroes(struct zint_symbol *symbol, unsigned char source[], unsigned char local_source[]); +INTERNAL void ean_leading_zeroes(struct zint_symbol *symbol, unsigned char source[], unsigned char local_source[], int *p_with_addon); INTERNAL int rss14(struct zint_symbol *symbol, unsigned char source[], int length); INTERNAL int rsslimited(struct zint_symbol *symbol, unsigned char source[], int length); INTERNAL int rssexpanded(struct zint_symbol *symbol, unsigned char source[], int length); @@ -1276,7 +1276,7 @@ static int cc_binary_string(struct zint_symbol *symbol, const char source[], cha } if (target_bitsize == 0) { - strcpy(symbol->errtxt, "442: Input too long for selected 2d component"); + strcpy(symbol->errtxt, "442: Input too long for selected 2D component"); return ZINT_ERROR_TOO_LONG; } @@ -1317,7 +1317,7 @@ static int cc_binary_string(struct zint_symbol *symbol, const char source[], cha } if (target_bitsize == 0) { - strcpy(symbol->errtxt, "444: Input too long for selected 2d component"); + strcpy(symbol->errtxt, "444: Input too long for selected 2D component"); return ZINT_ERROR_TOO_LONG; } @@ -1423,28 +1423,33 @@ INTERNAL int composite(struct zint_symbol *symbol, unsigned char source[], int l cc_width = 0; if (pri_len < 20) { int padded_pri_len; - char padded_pri[20]; + int with_addon; + char padded_pri[21]; padded_pri[0] = '\0'; - ean_leading_zeroes(symbol, (unsigned char *) symbol->primary, (unsigned char *) padded_pri); + ean_leading_zeroes(symbol, (unsigned char *) symbol->primary, (unsigned char *) padded_pri, &with_addon); padded_pri_len = strlen(padded_pri); if (padded_pri_len <= 7) { /* EAN-8 */ cc_width = 3; } else { switch (padded_pri_len) { case 10: /* EAN-8 + 2 */ - case 13: /* EAN-8 + 5 */ cc_width = 3; break; + case 13: /* EAN-13 CHK or EAN-8 + 5 */ + cc_width = with_addon ? 3 : 4; + break; case 12: /* EAN-13 */ case 15: /* EAN-13 + 2 */ + case 16: /* EAN-13 CHK + 2 */ case 18: /* EAN-13 + 5 */ + case 19: /* EAN-13 CHK + 5 */ cc_width = 4; break; } } } if (cc_width == 0) { - strcpy(symbol->errtxt, "449: Invalid length EAN input in linear component"); + strcpy(symbol->errtxt, "449: Input wrong length in linear component"); return ZINT_ERROR_TOO_LONG; } break; @@ -1647,7 +1652,7 @@ INTERNAL int composite(struct zint_symbol *symbol, unsigned char source[], int l } if (top_shift != 0) { - /* Move the 2d component of the symbol horizontally */ + /* Move the 2D component of the symbol horizontally */ for (i = 0; i <= symbol->rows; i++) { for (j = (symbol->width + top_shift); j >= top_shift; j--) { if (module_is_set(symbol, i, j - top_shift)) { diff --git a/backend/emf.c b/backend/emf.c index d66640f1..1c89d3f7 100644 --- a/backend/emf.c +++ b/backend/emf.c @@ -756,13 +756,10 @@ INTERNAL int emf_plot(struct zint_symbol *symbol, int rotate_angle) { fwrite(&emr_settextcolor, sizeof (emr_settextcolor_t), 1, emf_file); } - /* Suppresses clang-tidy clang-analyzer-core.UndefinedBinaryOperatorResult warning */ - assert((symbol->vector->strings == NULL && string_count == 0) || (symbol->vector->strings != NULL && string_count > 0)); - current_fsize = fsize; current_halign = -1; for (i = 0; i < string_count; i++) { - if (text_fsizes[i] != current_fsize) { + if (text_fsizes[i] != current_fsize) { // NOLINT(clang-analyzer-core.UndefinedBinaryOperatorResult) suppress clang-tidy warning: text_fsizes fully set current_fsize = text_fsizes[i]; fwrite(&emr_selectobject_font2, sizeof (emr_selectobject_t), 1, emf_file); } diff --git a/backend/qr.c b/backend/qr.c index e82c8fb8..6c67a135 100644 --- a/backend/qr.c +++ b/backend/qr.c @@ -2822,9 +2822,11 @@ static void setup_rmqr_grid(unsigned char* grid, const int h_size, const int v_s /* Add alignment patterns */ if (h_size > 27) { + h_version = 0; // Suppress compiler warning [-Wmaybe-uninitialized] for(i = 0; i < 5; i++) { if (h_size == rmqr_width[i]) { h_version = i; + break; } } diff --git a/backend/tests/test_composite.c b/backend/tests/test_composite.c index 726bb8a9..83985fbe 100644 --- a/backend/tests/test_composite.c +++ b/backend/tests/test_composite.c @@ -71,6 +71,9 @@ static void test_eanx_leading_zeroes(int index, int debug) { /*21*/ { BARCODE_EANX_CC, "123456+123", "[21]A12345678", 0, 8, 126 }, /*22*/ { BARCODE_EANX_CC, "1234567+123", "[21]A12345678", 0, 8, 126 }, /*23*/ { BARCODE_EANX_CC, "12345678+123", "[21]A12345678", 0, 7, 153 }, // EAN-13 + EAN-5 + /*24*/ { BARCODE_EANX_CC, "1234567890128", "[21]A12345678", 0, 7, 99 }, // EAN-13 + CHK + /*25*/ { BARCODE_EANX_CC, "1234567890128+12", "[21]A12345678", 0, 7, 126 }, // EAN-13 + CHK + EAN-2 + /*26*/ { BARCODE_EANX_CC, "1234567890128+12345", "[21]A12345678", 0, 7, 153 }, // EAN-13 + CHK + EAN-5 }; int data_size = sizeof(data) / sizeof(struct item); @@ -1216,6 +1219,15 @@ static void test_examples(int index, int generate, int debug) { "0000000000000010000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000" "0000000000000010100010110110111011101101011110101010011101011100100001011100101010000000101101110110100111010100011010101101110101000010" }, + /*64*/ { BARCODE_EANX_CC, 1, "1234567890128+65", "[91]1234567", 0, 7, 126, "Example of EAN-13 + CHK with 2-digit addon, CC-A 3 cols, 4 rows", + "110110111011110011010011100101110111000100001001110100101110111001000001100001100101000011011000101000000000000000000000000000" + "110110110010011001011111100111110110010000101001100100111111011100101001101011100010000011001000101000000000000000000000000000" + "110110100011010111111001000110111010000111001001100110100010010011110001010000110111110011101000101000000000000000000000000000" + "000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000" + "001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000" + "000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000" + "000101001001101111010011101011000100001010010001010101001000111010011100101100110110110010010001010000000101101011110101110010" + }, }; int data_size = sizeof(data) / sizeof(struct item); diff --git a/backend/tests/test_imail.c b/backend/tests/test_imail.c index d8a79c41..aaf3ec8f 100644 --- a/backend/tests/test_imail.c +++ b/backend/tests/test_imail.c @@ -27,6 +27,7 @@ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* vim: set ts=4 sw=4 et : */ /* * Intelligent Mail barcode Encoder Test Case Reference Set (csv file) * Copyright (C) 2009 U.S. Postal Service @@ -262,17 +263,17 @@ static void test_encode(int index, int generate, int debug) { assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d (%s)\n", i, symbol->rows, data[i].expected_rows, data[i].data); assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d (%s)\n", i, symbol->width, data[i].expected_width, data[i].data); - int width, row; - ret = testUtilModulesCmp(symbol, data[i].expected, &width, &row); - assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n", i, ret, width, row, data[i].data); + int width, row; + ret = testUtilModulesCmp(symbol, data[i].expected, &width, &row); + assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n", i, ret, width, row, data[i].data); if (do_bwipp && testUtilCanBwipp(symbol->symbology, -1, -1, -1, debug)) { - ret = testUtilBwipp(i, symbol, -1, -1, -1, data[i].data, length, NULL, bwipp_buf, sizeof(bwipp_buf)); - assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); + ret = testUtilBwipp(i, symbol, -1, -1, -1, data[i].data, length, NULL, bwipp_buf, sizeof(bwipp_buf)); + assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret); - ret = testUtilBwippCmp(symbol, bwipp_msg, bwipp_buf, data[i].expected); - assert_zero(ret, "i:%d %s testUtilBwippCmp %d != 0 %s\n actual: %s\nexpected: %s\n", - i, testUtilBarcodeName(symbol->symbology), ret, bwipp_msg, bwipp_buf, data[i].expected); + ret = testUtilBwippCmp(symbol, bwipp_msg, bwipp_buf, data[i].expected); + assert_zero(ret, "i:%d %s testUtilBwippCmp %d != 0 %s\n actual: %s\nexpected: %s\n", + i, testUtilBarcodeName(symbol->symbology), ret, bwipp_msg, bwipp_buf, data[i].expected); } } } diff --git a/backend/tests/test_mailmark.c b/backend/tests/test_mailmark.c index db61a0a9..5e509bcb 100644 --- a/backend/tests/test_mailmark.c +++ b/backend/tests/test_mailmark.c @@ -27,6 +27,7 @@ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* vim: set ts=4 sw=4 et : */ #include "testcommon.h" @@ -245,9 +246,9 @@ static void test_encode(int index, int generate, int debug) { assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d (%s)\n", i, symbol->rows, data[i].expected_rows, data[i].data); assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d (%s)\n", i, symbol->width, data[i].expected_width, data[i].data); - int width, row; - ret = testUtilModulesCmp(symbol, data[i].expected, &width, &row); - assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n", i, ret, width, row, data[i].data); + int width, row; + ret = testUtilModulesCmp(symbol, data[i].expected, &width, &row); + assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n", i, ret, width, row, data[i].data); } } diff --git a/backend/tests/test_upcean.c b/backend/tests/test_upcean.c index a80a9812..fe848226 100644 --- a/backend/tests/test_upcean.c +++ b/backend/tests/test_upcean.c @@ -31,7 +31,7 @@ #include "testcommon.h" -static void test_upce_length(int index, int debug) { +static void test_upce_input(int index, int debug) { testStart(""); @@ -41,23 +41,51 @@ static void test_upce_length(int index, int debug) { char *data; int ret; }; - // s/\/\*[ 0-9]*\*\//\=printf("\/*%2d*\/", line(".") - line("'<")) + // s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<")) struct item data[] = { - /* 0*/ { BARCODE_UPCE, "12345", 0 }, - /* 1*/ { BARCODE_UPCE_CHK, "12345", ZINT_ERROR_INVALID_CHECK }, - /* 2*/ { BARCODE_UPCE_CHK, "12344", 0 }, // 4 is correct check digit - /* 3*/ { BARCODE_UPCE, "123456", 0 }, - /* 4*/ { BARCODE_UPCE_CHK, "123456", ZINT_ERROR_INVALID_CHECK }, - /* 5*/ { BARCODE_UPCE_CHK, "123457", 0 }, // 7 is correct check digit - /* 6*/ { BARCODE_UPCE, "1234567", 0 }, - /* 7*/ { BARCODE_UPCE_CHK, "1234567", ZINT_ERROR_INVALID_CHECK }, - /* 8*/ { BARCODE_UPCE_CHK, "1234565", 0 }, // 5 is correct check digit - /* 9*/ { BARCODE_UPCE, "12345678", ZINT_ERROR_TOO_LONG }, - /*10*/ { BARCODE_UPCE_CHK, "12345678", ZINT_ERROR_INVALID_CHECK }, - /*11*/ { BARCODE_UPCE_CHK, "12345670", 0 }, // 0 is correct check digit - /*12*/ { BARCODE_UPCE, "123456789", ZINT_ERROR_TOO_LONG }, - /*13*/ { BARCODE_UPCE_CHK, "123456789", ZINT_ERROR_TOO_LONG }, - /*14*/ { BARCODE_UPCE, "123406", ZINT_ERROR_INVALID_DATA }, // If last digit (emode) 6, 2nd last can't be zero + /* 0*/ { BARCODE_UPCE, "12345", 0 }, // equivalent: 00123400005, hrt: 00123457, Check digit: 7 + /* 1*/ { BARCODE_UPCE_CHK, "12345", ZINT_ERROR_INVALID_CHECK }, + /* 2*/ { BARCODE_UPCE_CHK, "12344", 0 }, // equivalent: 00012000003, hrt: 00012344, Check digit: 4 + /* 3*/ { BARCODE_UPCE, "123456", 0 }, // equivalent: 01234500006, hrt: 01234565, Check digit: 5 + /* 4*/ { BARCODE_UPCE_CHK, "123456", ZINT_ERROR_INVALID_CHECK }, + /* 5*/ { BARCODE_UPCE_CHK, "123457", 0 }, // equivalent: 00123400005, hrt: 00123457, Check digit: 7 + /* 6*/ { BARCODE_UPCE, "1234567", 0 }, // equivalent: 12345600007, hrt: 12345670, Check digit: 0 + /* 7*/ { BARCODE_UPCE_CHK, "1234567", ZINT_ERROR_INVALID_CHECK }, + /* 8*/ { BARCODE_UPCE_CHK, "1234565", 0 }, // equivalent: 01234500006, hrt: 01234565, Check digit: 5 + /* 9*/ { BARCODE_UPCE, "12345678", ZINT_ERROR_TOO_LONG }, + /* 10*/ { BARCODE_UPCE_CHK, "12345678", ZINT_ERROR_INVALID_CHECK }, + /* 11*/ { BARCODE_UPCE_CHK, "12345670", 0 }, // equivalent: 12345600007, hrt: 12345670, Check digit: 0 + /* 12*/ { BARCODE_UPCE, "123456789", ZINT_ERROR_TOO_LONG }, + /* 13*/ { BARCODE_UPCE_CHK, "123456789", ZINT_ERROR_TOO_LONG }, + /* 14*/ { BARCODE_UPCE, "2345678", 0 }, // 2 ignored, equivalent: 03456700008, hrt: 03456781, Check digit: 1 + /* 15*/ { BARCODE_UPCE_CHK, "23456781", 0 }, // 2 ignored, equivalent: 03456700008, hrt: 03456781, Check digit: 1 + /* 16*/ { BARCODE_UPCE, "123455", 0 }, // equivalent: 01234500005, hrt: 01234558, Check digit: 8 (BS 797 Rule 3 (a)) + /* 17*/ { BARCODE_UPCE_CHK, "1234558", 0 }, // equivalent: 01234500005, hrt: 01234558, Check digit: 8 (BS 797 Rule 3 (a)) + /* 18*/ { BARCODE_UPCE, "456784", 0 }, // equivalent: 04567000008, hrt: 04567840, Check digit: 0 (BS 797 Rule 3 (b)) + /* 19*/ { BARCODE_UPCE_CHK, "4567840", 0 }, // equivalent: 04567000008, hrt: 04567840, Check digit: 0 (BS 797 Rule 3 (b)) + /* 20*/ { BARCODE_UPCE, "345670", 0 }, // equivalent: 03400000567, hrt: 03456703, Check digit: 3 (BS 797 Rule 3 (c)) + /* 21*/ { BARCODE_UPCE_CHK, "3456703", 0 }, // equivalent: 03400000567, hrt: 03456703, Check digit: 3 (BS 797 Rule 3 (c)) + /* 22*/ { BARCODE_UPCE, "984753", 0 }, // equivalent: 09840000075, hrt: 09847531, Check digit: 1 (BS 797 Rule 3 (d)) + /* 23*/ { BARCODE_UPCE_CHK, "9847531", 0 }, // equivalent: 09840000075, hrt: 09847531, Check digit: 1 (BS 797 Rule 3 (d)) + /* 24*/ { BARCODE_UPCE, "120453", ZINT_ERROR_INVALID_DATA }, // If last digit (emode) 3, 3rd can't be 0, 1 or 2 (BS 787 Table 5 NOTE 1) + /* 25*/ { BARCODE_UPCE, "121453", ZINT_ERROR_INVALID_DATA }, // If last digit (emode) 3, 3rd can't be 0, 1 or 2 (BS 787 Table 5 NOTE 1) + /* 26*/ { BARCODE_UPCE, "122453", ZINT_ERROR_INVALID_DATA }, // If last digit (emode) 3, 3rd can't be 0, 1 or 2 (BS 787 Table 5 NOTE 1) + /* 27*/ { BARCODE_UPCE, "123453", 0 }, + /* 28*/ { BARCODE_UPCE, "123054", ZINT_ERROR_INVALID_DATA }, // If last digit (emode) 4, 4th can't be 0 (BS 787 Table 5 NOTE 2) + /* 29*/ { BARCODE_UPCE, "123154", 0 }, + /* 30*/ { BARCODE_UPCE, "123405", ZINT_ERROR_INVALID_DATA }, // If last digit (emode) 5, 5th can't be 0 (BS 787 Table 5 NOTE 3) + /* 31*/ { BARCODE_UPCE, "123455", 0 }, + /* 32*/ { BARCODE_UPCE, "123406", ZINT_ERROR_INVALID_DATA }, // If last digit (emode) 6, 5th can't be 0 (BS 787 Table 5 NOTE 3) + /* 33*/ { BARCODE_UPCE, "123456", 0 }, + /* 34*/ { BARCODE_UPCE, "123407", ZINT_ERROR_INVALID_DATA }, // If last digit (emode) 7, 5th can't be 0 (BS 787 Table 5 NOTE 3) + /* 35*/ { BARCODE_UPCE, "123457", 0 }, + /* 36*/ { BARCODE_UPCE, "123408", ZINT_ERROR_INVALID_DATA }, // If last digit (emode) 8, 5th can't be 0 (BS 787 Table 5 NOTE 3) + /* 37*/ { BARCODE_UPCE, "123458", 0 }, + /* 38*/ { BARCODE_UPCE, "123409", ZINT_ERROR_INVALID_DATA }, // If last digit (emode) 9, 5th can't be 0 (BS 787 Table 5 NOTE 3) + /* 39*/ { BARCODE_UPCE, "123459", 0 }, + /* 40*/ { BARCODE_UPCE, "000000", 0 }, + /* 41*/ { BARCODE_UPCE, "000001", 0 }, + /* 42*/ { BARCODE_UPCE, "000002", 0 }, }; int data_size = sizeof(data) / sizeof(struct item); @@ -126,7 +154,243 @@ static void test_upca_print(int index, int debug) { testFinish(); } -static void test_isbn(int index, int debug) { +static void test_upca_input(int index, int debug) { + + testStart(""); + + int ret; + struct item { + int symbology; + char *data; + int ret; + }; + // s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<")) + struct item data[] = { + /* 0*/ { BARCODE_UPCA, "12345678901", 0 }, + /* 1*/ { BARCODE_UPCA, "1234567890", 0 }, + /* 2*/ { BARCODE_UPCA, "123456789012", 0 }, // UPC-A accepts CHK + /* 3*/ { BARCODE_UPCA, "123456789011", ZINT_ERROR_INVALID_CHECK }, + /* 4*/ { BARCODE_UPCA, "12345678901+1", 0 }, + /* 5*/ { BARCODE_UPCA, "123456789012+1", 0 }, + /* 6*/ { BARCODE_UPCA, "123456789013+1", ZINT_ERROR_INVALID_CHECK }, + /* 7*/ { BARCODE_UPCA, "12345678901+12", 0 }, + /* 8*/ { BARCODE_UPCA, "123456789012+12", 0 }, + /* 9*/ { BARCODE_UPCA, "123456789014+12", ZINT_ERROR_INVALID_CHECK }, + /* 10*/ { BARCODE_UPCA, "12345678901+123", 0 }, + /* 11*/ { BARCODE_UPCA, "123456789012+123", 0 }, + /* 12*/ { BARCODE_UPCA, "123456789015+123", ZINT_ERROR_INVALID_CHECK }, + /* 13*/ { BARCODE_UPCA, "123456789012+1234", 0 }, + /* 14*/ { BARCODE_UPCA, "123456789016+1234", ZINT_ERROR_INVALID_CHECK }, + /* 15*/ { BARCODE_UPCA, "123456789012+12345", 0 }, + /* 16*/ { BARCODE_UPCA, "123456789017+12345", ZINT_ERROR_INVALID_CHECK }, + /* 17*/ { BARCODE_UPCA, "123456789012+123456", ZINT_ERROR_TOO_LONG }, + /* 18*/ { BARCODE_UPCA, "123456789017+123456", ZINT_ERROR_INVALID_CHECK }, + /* 19*/ { BARCODE_UPCA_CHK, "123456789012", 0 }, + /* 20*/ { BARCODE_UPCA_CHK, "123456789011", ZINT_ERROR_INVALID_CHECK }, + /* 21*/ { BARCODE_UPCA_CHK, "12345678901", ZINT_ERROR_INVALID_CHECK }, + /* 22*/ { BARCODE_UPCA_CHK, "12345678905", 0 }, + /* 23*/ { BARCODE_UPCA_CHK, "1234567890", ZINT_ERROR_INVALID_CHECK }, + /* 24*/ { BARCODE_UPCA_CHK, "1234567895", 0 }, + /* 25*/ { BARCODE_UPCA_CHK, "123456789", ZINT_ERROR_INVALID_CHECK }, + /* 26*/ { BARCODE_UPCA_CHK, "123456784", 0 }, + /* 27*/ { BARCODE_UPCA_CHK, "12345678", ZINT_ERROR_INVALID_CHECK }, + /* 28*/ { BARCODE_UPCA_CHK, "12345670", 0 }, + /* 29*/ { BARCODE_UPCA_CHK, "1234567", ZINT_ERROR_INVALID_CHECK }, + /* 30*/ { BARCODE_UPCA_CHK, "1234565", 0 }, + /* 31*/ { BARCODE_UPCA_CHK, "123456", ZINT_ERROR_INVALID_CHECK }, + /* 32*/ { BARCODE_UPCA_CHK, "123457", 0 }, + /* 33*/ { BARCODE_UPCA_CHK, "12345", ZINT_ERROR_INVALID_CHECK }, + /* 34*/ { BARCODE_UPCA_CHK, "12348", 0 }, + /* 35*/ { BARCODE_UPCA_CHK, "1234", ZINT_ERROR_INVALID_CHECK }, + /* 36*/ { BARCODE_UPCA_CHK, "1236", 0 }, + /* 37*/ { BARCODE_UPCA_CHK, "123", 0 }, // Happens to be correct check digit + /* 38*/ { BARCODE_UPCA_CHK, "124", ZINT_ERROR_INVALID_CHECK }, + /* 39*/ { BARCODE_UPCA_CHK, "12", ZINT_ERROR_INVALID_CHECK }, + /* 40*/ { BARCODE_UPCA_CHK, "17", 0 }, + /* 41*/ { BARCODE_UPCA_CHK, "1", ZINT_ERROR_INVALID_CHECK }, + /* 42*/ { BARCODE_UPCA_CHK, "0", 0 }, + /* 43*/ { BARCODE_UPCA_CHK, "12345678905+12", 0 }, + /* 44*/ { BARCODE_UPCA_CHK, "12345678905+12345", 0 }, + /* 45*/ { BARCODE_UPCA_CHK, "1234567895+12345", 0 }, + /* 46*/ { BARCODE_UPCA_CHK, "1234567891+12345", ZINT_ERROR_INVALID_CHECK }, + /* 47*/ { BARCODE_UPCA_CHK, "123456784+12345", 0 }, + /* 48*/ { BARCODE_UPCA_CHK, "123456782+12345", ZINT_ERROR_INVALID_CHECK }, + /* 49*/ { BARCODE_UPCA_CHK, "12345670+12345", 0 }, + /* 50*/ { BARCODE_UPCA_CHK, "12345673+12345", ZINT_ERROR_INVALID_CHECK }, + /* 51*/ { BARCODE_UPCA_CHK, "1234565+12345", 0 }, + /* 52*/ { BARCODE_UPCA_CHK, "1234564+12345", ZINT_ERROR_INVALID_CHECK }, + /* 53*/ { BARCODE_UPCA_CHK, "123457+12345", 0 }, + /* 54*/ { BARCODE_UPCA_CHK, "123455+12345", ZINT_ERROR_INVALID_CHECK }, + /* 55*/ { BARCODE_UPCA_CHK, "12348+12345", 0 }, + /* 56*/ { BARCODE_UPCA_CHK, "12346+12345", ZINT_ERROR_INVALID_CHECK }, + /* 57*/ { BARCODE_UPCA_CHK, "1236+12345", 0 }, + /* 58*/ { BARCODE_UPCA_CHK, "1237+12345", ZINT_ERROR_INVALID_CHECK }, + /* 59*/ { BARCODE_UPCA_CHK, "123+12345", 0 }, + /* 60*/ { BARCODE_UPCA_CHK, "128+12345", ZINT_ERROR_INVALID_CHECK }, + /* 61*/ { BARCODE_UPCA_CHK, "17+12345", 0 }, + /* 62*/ { BARCODE_UPCA_CHK, "19+12345", ZINT_ERROR_INVALID_CHECK }, + /* 63*/ { BARCODE_UPCA_CHK, "1+12345", ZINT_ERROR_INVALID_CHECK }, + /* 64*/ { BARCODE_UPCA_CHK, "0+12345", 0 }, + }; + int data_size = ARRAY_SIZE(data); + + for (int i = 0; i < data_size; i++) { + + if (index != -1 && i != index) continue; + + struct zint_symbol *symbol = ZBarcode_Create(); + assert_nonnull(symbol, "Symbol not created\n"); + + int length = testUtilSetSymbol(symbol, data[i].symbology, -1 /*input_mode*/, -1 /*eci*/, -1 /*option_1*/, -1, -1, -1 /*output_options*/, data[i].data, -1, debug); + + ret = ZBarcode_Encode(symbol, (unsigned char *) data[i].data, length); + assert_equal(ret, data[i].ret, "i:%d ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); + + ZBarcode_Delete(symbol); + } + + testFinish(); +} + +static void test_eanx_input(int index, int debug) { + + testStart(""); + + int ret; + struct item { + int symbology; + char *data; + int ret; + }; + // s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<")) + struct item data[] = { + /* 0*/ { BARCODE_EANX, "123456789012", 0 }, + /* 1*/ { BARCODE_EANX, "12345678901", 0 }, + /* 2*/ { BARCODE_EANX, "1234567890128", 0 }, // EANX accepts CHK (treated as such if no leading zeroes required) + /* 3*/ { BARCODE_EANX, "1234567890120", ZINT_ERROR_INVALID_CHECK }, + /* 4*/ { BARCODE_EANX, "123456789012+1", 0 }, + /* 5*/ { BARCODE_EANX, "1234567890128+1", 0 }, + /* 6*/ { BARCODE_EANX, "1234567890121+1", ZINT_ERROR_INVALID_CHECK }, + /* 7*/ { BARCODE_EANX, "123456789012+12", 0 }, + /* 8*/ { BARCODE_EANX, "1234567890128+12", 0 }, + /* 9*/ { BARCODE_EANX, "1234567890122+12", ZINT_ERROR_INVALID_CHECK }, + /* 10*/ { BARCODE_EANX, "123456789012+123", 0 }, + /* 11*/ { BARCODE_EANX, "1234567890128+123", 0 }, + /* 12*/ { BARCODE_EANX, "1234567890123+123", ZINT_ERROR_INVALID_CHECK }, + /* 13*/ { BARCODE_EANX, "123456789012+1234", 0 }, + /* 14*/ { BARCODE_EANX, "1234567890128+1234", 0 }, + /* 15*/ { BARCODE_EANX, "1234567890124+1234", ZINT_ERROR_INVALID_CHECK }, + /* 16*/ { BARCODE_EANX, "123456789012+12345", 0 }, + /* 17*/ { BARCODE_EANX, "1234567890128+12345", 0 }, + /* 18*/ { BARCODE_EANX, "1234567890125+12345", ZINT_ERROR_INVALID_CHECK }, + /* 19*/ { BARCODE_EANX, "123456789012+123456", ZINT_ERROR_TOO_LONG }, + /* 20*/ { BARCODE_EANX, "1234567890128+123456", ZINT_ERROR_TOO_LONG }, + /* 21*/ { BARCODE_EANX, "12345678901+123456", ZINT_ERROR_TOO_LONG }, + /* 22*/ { BARCODE_EANX, "12345678901+1234567", ZINT_ERROR_TOO_LONG }, + /* 23*/ { BARCODE_EANX, "1234567890+123456", ZINT_ERROR_TOO_LONG }, + /* 24*/ { BARCODE_EANX, "1234567890+1234567", ZINT_ERROR_TOO_LONG }, + /* 25*/ { BARCODE_EANX, "123456789+123456", ZINT_ERROR_TOO_LONG }, + /* 26*/ { BARCODE_EANX, "123456789+1234567", ZINT_ERROR_TOO_LONG }, + /* 27*/ { BARCODE_EANX, "12345678+123456", ZINT_ERROR_TOO_LONG }, + /* 28*/ { BARCODE_EANX, "1234567+123456", ZINT_ERROR_TOO_LONG }, // EAN-8 + /* 29*/ { BARCODE_EANX, "123456+123456", ZINT_ERROR_TOO_LONG }, + /* 30*/ { BARCODE_EANX, "12345+123456", ZINT_ERROR_TOO_LONG }, + /* 31*/ { BARCODE_EANX, "1234+123456", ZINT_ERROR_TOO_LONG }, + /* 32*/ { BARCODE_EANX, "123+123456", ZINT_ERROR_TOO_LONG }, + /* 33*/ { BARCODE_EANX, "12+123456", ZINT_ERROR_TOO_LONG }, + /* 34*/ { BARCODE_EANX, "1+123456", ZINT_ERROR_TOO_LONG }, + /* 35*/ { BARCODE_EANX, "1+12345678901234", ZINT_ERROR_TOO_LONG }, + /* 36*/ { BARCODE_EANX, "1+12345", 0 }, + /* 37*/ { BARCODE_EANX, "1+", 0 }, // EAN-2 + /* 38*/ { BARCODE_EANX, "+1", 0 }, // EAN-8 + /* 39*/ { BARCODE_EANX, "+", 0 }, // EAN-2 + /* 40*/ { BARCODE_EANX, "1", 0 }, // EAN-2 + /* 41*/ { BARCODE_EANX, "12", 0 }, // EAN-2 + /* 42*/ { BARCODE_EANX, "123", 0 }, // EAN-5 + /* 43*/ { BARCODE_EANX, "1234567890123456789", ZINT_ERROR_TOO_LONG }, + /* 44*/ { BARCODE_EANX_CHK, "123456789012", 0 }, // EANX_CHK accepts no CHK + /* 45*/ { BARCODE_EANX_CHK, "12345678901", ZINT_ERROR_INVALID_CHECK }, // But only if no leading zeroes required + /* 46*/ { BARCODE_EANX_CHK, "12345678905", 0 }, + /* 47*/ { BARCODE_EANX_CHK, "1234567890", ZINT_ERROR_INVALID_CHECK }, + /* 48*/ { BARCODE_EANX_CHK, "123456789", ZINT_ERROR_INVALID_CHECK }, + /* 49*/ { BARCODE_EANX_CHK, "12345678", ZINT_ERROR_INVALID_CHECK }, // EAN-8 + /* 50*/ { BARCODE_EANX_CHK, "1234567", ZINT_ERROR_INVALID_CHECK }, + /* 51*/ { BARCODE_EANX_CHK, "123456", ZINT_ERROR_INVALID_CHECK }, + /* 52*/ { BARCODE_EANX_CHK, "12345", 0 }, // EAN-5 + /* 53*/ { BARCODE_EANX_CHK, "1234", 0 }, + /* 54*/ { BARCODE_EANX_CHK, "123", 0 }, + /* 55*/ { BARCODE_EANX_CHK, "12", 0 }, // EAN-2 + /* 56*/ { BARCODE_EANX_CHK, "1", 0 }, + /* 57*/ { BARCODE_EANX_CHK, "1234567890128", 0 }, + /* 58*/ { BARCODE_EANX_CHK, "1234567890126", ZINT_ERROR_INVALID_CHECK }, + /* 59*/ { BARCODE_EANX_CHK, "123456789012+1", 0 }, + /* 60*/ { BARCODE_EANX_CHK, "1234567890128+1", 0 }, + /* 61*/ { BARCODE_EANX_CHK, "1234567890127+1", ZINT_ERROR_INVALID_CHECK }, + /* 62*/ { BARCODE_EANX_CHK, "123456789012+12", 0 }, + /* 63*/ { BARCODE_EANX_CHK, "1234567890128+12", 0 }, + /* 64*/ { BARCODE_EANX_CHK, "1234567890129+12", ZINT_ERROR_INVALID_CHECK }, + /* 65*/ { BARCODE_EANX_CHK, "123456789012+123", 0 }, + /* 66*/ { BARCODE_EANX_CHK, "1234567890128+123", 0 }, + /* 67*/ { BARCODE_EANX_CHK, "1234567890120+1234", ZINT_ERROR_INVALID_CHECK }, + /* 68*/ { BARCODE_EANX_CHK, "123456789012+1234", 0 }, + /* 69*/ { BARCODE_EANX_CHK, "1234567890128+1234", 0 }, + /* 70*/ { BARCODE_EANX_CHK, "1234567890121+1234", ZINT_ERROR_INVALID_CHECK }, + /* 71*/ { BARCODE_EANX_CHK, "123456789012+12345", 0 }, + /* 72*/ { BARCODE_EANX_CHK, "1234567890128+12345", 0 }, + /* 73*/ { BARCODE_EANX_CHK, "1234567890122+12345", ZINT_ERROR_INVALID_CHECK }, + /* 74*/ { BARCODE_EANX_CHK, "123456789012+123456", ZINT_ERROR_TOO_LONG }, + /* 75*/ { BARCODE_EANX_CHK, "1234567890128+123456", ZINT_ERROR_TOO_LONG }, + /* 76*/ { BARCODE_EANX_CHK, "12345678901+123456", ZINT_ERROR_INVALID_CHECK }, // Note different behaviour than EANX due to leading zeroes added + /* 77*/ { BARCODE_EANX_CHK, "12345678901+1234567", ZINT_ERROR_INVALID_CHECK }, + /* 78*/ { BARCODE_EANX_CHK, "12345678901+12345", ZINT_ERROR_INVALID_CHECK }, + /* 79*/ { BARCODE_EANX_CHK, "1234567890+12345", ZINT_ERROR_INVALID_CHECK }, + /* 80*/ { BARCODE_EANX_CHK, "1234567890+123456", ZINT_ERROR_INVALID_CHECK }, + /* 81*/ { BARCODE_EANX_CHK, "123456789+12345", ZINT_ERROR_INVALID_CHECK }, + /* 82*/ { BARCODE_EANX_CHK, "12345678+12345", ZINT_ERROR_INVALID_CHECK }, // EAN-8 + /* 83*/ { BARCODE_EANX_CHK, "12345670+12345", 0 }, + /* 84*/ { BARCODE_EANX_CHK, "1234567+12345", ZINT_ERROR_INVALID_CHECK }, + /* 85*/ { BARCODE_EANX_CHK, "1234565+12345", 0 }, + /* 86*/ { BARCODE_EANX_CHK, "123456+12345", ZINT_ERROR_INVALID_CHECK }, + /* 87*/ { BARCODE_EANX_CHK, "123457+12345", 0 }, + /* 88*/ { BARCODE_EANX_CHK, "12345+12345", ZINT_ERROR_INVALID_CHECK }, + /* 89*/ { BARCODE_EANX_CHK, "12348+12345", 0 }, + /* 90*/ { BARCODE_EANX_CHK, "1234+12345", ZINT_ERROR_INVALID_CHECK }, + /* 91*/ { BARCODE_EANX_CHK, "1236+12345", 0 }, + /* 92*/ { BARCODE_EANX_CHK, "123+12345", 0 }, // 3 happens to be correct check digit + /* 93*/ { BARCODE_EANX_CHK, "124+12345", ZINT_ERROR_INVALID_CHECK }, + /* 94*/ { BARCODE_EANX_CHK, "12+12345", ZINT_ERROR_INVALID_CHECK }, + /* 95*/ { BARCODE_EANX_CHK, "17+12345", 0 }, + /* 96*/ { BARCODE_EANX_CHK, "1+12345", ZINT_ERROR_INVALID_CHECK }, + /* 97*/ { BARCODE_EANX_CHK, "0+12345", 0 }, + /* 98*/ { BARCODE_EANX_CHK, "0+123456", ZINT_ERROR_TOO_LONG }, + /* 99*/ { BARCODE_EANX_CHK, "1+12345678901234", ZINT_ERROR_INVALID_CHECK }, + /*100*/ { BARCODE_EANX_CHK, "0+12345678901234", ZINT_ERROR_TOO_LONG }, + /*101*/ { BARCODE_EANX_CHK, "1+", 0 }, // EAN-2 + /*102*/ { BARCODE_EANX_CHK, "+1", 0 }, // EAN-8 + /*103*/ { BARCODE_EANX_CHK, "+", 0 }, // EAN-2 + /*104*/ { BARCODE_EANX_CHK, "1234567890123456789", ZINT_ERROR_TOO_LONG }, + }; + int data_size = ARRAY_SIZE(data); + + for (int i = 0; i < data_size; i++) { + + if (index != -1 && i != index) continue; + + struct zint_symbol *symbol = ZBarcode_Create(); + assert_nonnull(symbol, "Symbol not created\n"); + + int length = testUtilSetSymbol(symbol, data[i].symbology, -1 /*input_mode*/, -1 /*eci*/, -1 /*option_1*/, -1, -1, -1 /*output_options*/, data[i].data, -1, debug); + + ret = ZBarcode_Encode(symbol, (unsigned char *) data[i].data, length); + assert_equal(ret, data[i].ret, "i:%d ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt); + + ZBarcode_Delete(symbol); + } + + testFinish(); +} + +static void test_isbn_input(int index, int debug) { testStart(""); @@ -503,9 +767,11 @@ static void test_fuzz(int index, int debug) { int main(int argc, char *argv[]) { testFunction funcs[] = { /* name, func, has_index, has_generate, has_debug */ - { "test_upce_length", test_upce_length, 1, 0, 1 }, + { "test_upce_input", test_upce_input, 1, 0, 1 }, { "test_upca_print", test_upca_print, 1, 0, 1 }, - { "test_isbn", test_isbn, 1, 0, 1 }, + { "test_upca_input", test_upca_input, 1, 0, 1 }, + { "test_eanx_input", test_eanx_input, 1, 0, 1 }, + { "test_isbn_input", test_isbn_input, 1, 0, 1 }, { "test_vector_same", test_vector_same, 1, 0, 1 }, { "test_encode", test_encode, 1, 1, 1 }, { "test_fuzz", test_fuzz, 1, 0, 1 }, diff --git a/backend/tests/testcommon.c b/backend/tests/testcommon.c index ea71faf1..32165ca6 100644 --- a/backend/tests/testcommon.c +++ b/backend/tests/testcommon.c @@ -115,8 +115,10 @@ void testReport() { } if (skipped) { printf("Total %d tests, %d skipped.\n", tests, skipped); - } else { + } else if (tests) { printf("Total %d tests, all passed.\n", tests); + } else { + printf("Total %d tests.\n", tests); } } diff --git a/backend/upcean.c b/backend/upcean.c index 1aa27a56..99044fc0 100644 --- a/backend/upcean.c +++ b/backend/upcean.c @@ -138,15 +138,19 @@ static int upca(struct zint_symbol *symbol, unsigned char source[], char dest[]) gtin[length - 1] = '\0'; if (source[length - 1] != upc_check(gtin)) { if (symbol->debug & ZINT_DEBUG_PRINT) { - printf("UPC-A: %s, Check digit: %c\n", gtin, upc_check(gtin)); + printf("UPC-A: Invalid check digit %s, gtin: %s, Check digit: %c\n", source, gtin, upc_check(gtin)); } strcpy(symbol->errtxt, "270: Invalid check digit"); return ZINT_ERROR_INVALID_CHECK; } gtin[length - 1] = upc_check(gtin); } + if (symbol->debug & ZINT_DEBUG_PRINT) { + printf("UPC-A: %s, gtin: %s, Check digit: %c\n", source, gtin, length == 11 ? gtin[length] : gtin[length - 1]); + } + upca_draw(gtin, dest); - ustrcpy(symbol->text, (unsigned char*) gtin); + ustrcpy(symbol->text, gtin); return error_number; } @@ -168,7 +172,7 @@ static int upce(struct zint_symbol *symbol, unsigned char source[], char dest[]) case '1': num_system = 1; break; default: num_system = 0; - source[0] = '0'; + /* First source char ignored */ break; } strcpy(temp, (char*) source); @@ -191,7 +195,7 @@ static int upce(struct zint_symbol *symbol, unsigned char source[], char dest[]) case '1': num_system = 1; break; default: num_system = 0; - source[0] = '0'; + /* First source char ignored */ break; } strcpy(temp, (char*) source); @@ -269,10 +273,6 @@ static int upce(struct zint_symbol *symbol, unsigned char source[], char dest[]) check_digit = upc_check(equivalent); - if (symbol->debug & ZINT_DEBUG_PRINT) { - printf("UPC-E: %s, Check digit: %c\n", equivalent, check_digit); - } - /* Use the number system and check digit information to choose a parity scheme */ if (num_system == 1) { strcpy(parity, UPCParity1[ctoi(check_digit)]); @@ -302,11 +302,18 @@ static int upce(struct zint_symbol *symbol, unsigned char source[], char dest[]) hrt[8] = '\0'; } else { if (hrt[7] != check_digit) { + if (symbol->debug & ZINT_DEBUG_PRINT) { + printf("UPC-E: Invalid check digit %s, equivalent: %s, hrt: %s, Check digit: %c\n", source, equivalent, hrt, check_digit); + } strcpy(symbol->errtxt, "274: Invalid check digit"); return ZINT_ERROR_INVALID_CHECK; } } - ustrcpy(symbol->text, (unsigned char*) hrt); + if (symbol->debug & ZINT_DEBUG_PRINT) { + printf("UPC-E: %s, equivalent: %s, hrt: %s, Check digit: %c\n", source, equivalent, hrt, check_digit); + } + + ustrcpy(symbol->text, hrt); return error_number; } @@ -413,11 +420,17 @@ static int ean13(struct zint_symbol *symbol, unsigned char source[], char dest[] } else { gtin[length - 1] = '\0'; if (source[length - 1] != ean_check(gtin)) { + if (symbol->debug & ZINT_DEBUG_PRINT) { + printf("EAN-13 Invalid check digit: %s, gtin: %s, Check digit: %c\n", source, gtin, ean_check(gtin)); + } strcpy(symbol->errtxt, "275: Invalid check digit"); - return ZINT_ERROR_INVALID_DATA; + return ZINT_ERROR_INVALID_CHECK; } gtin[length - 1] = ean_check(gtin); } + if (symbol->debug & ZINT_DEBUG_PRINT) { + printf("EAN-13: %s, gtin: %s, Check digit: %c\n", source, gtin, length == 12 ? gtin[length] : gtin[length - 1]); + } /* Get parity for first half of the symbol */ lookup(SODIUM, EAN13Parity, gtin[0], parity); @@ -444,7 +457,7 @@ static int ean13(struct zint_symbol *symbol, unsigned char source[], char dest[] /* stop character */ strcat(dest, "111"); - ustrcpy(symbol->text, (unsigned char*) gtin); + ustrcpy(symbol->text, gtin); return error_number; } @@ -465,13 +478,20 @@ static int ean8(struct zint_symbol *symbol, unsigned char source[], char dest[]) } else { gtin[length - 1] = '\0'; if (source[length - 1] != upc_check(gtin)) { + if (symbol->debug & ZINT_DEBUG_PRINT) { + printf("EAN-8: Invalid check digit %s, gtin: %s, Check digit: %c\n", source, gtin, upc_check(gtin)); + } strcpy(symbol->errtxt, "276: Invalid check digit"); - return ZINT_ERROR_INVALID_DATA; + return ZINT_ERROR_INVALID_CHECK; } gtin[length - 1] = upc_check(gtin); } + if (symbol->debug & ZINT_DEBUG_PRINT) { + printf("EAN-8: %s, gtin: %s, Check digit: %c\n", source, gtin, length == 7 ? gtin[length] : gtin[length - 1]); + } + upca_draw(gtin, dest); - ustrcpy(symbol->text, (unsigned char*) gtin); + ustrcpy(symbol->text, gtin); return error_number; } @@ -578,8 +598,8 @@ static int isbn(struct zint_symbol *symbol, unsigned char source[], const size_t } /* Add leading zeroes to EAN and UPC strings */ -INTERNAL void ean_leading_zeroes(struct zint_symbol *symbol, unsigned char source[], unsigned char local_source[]) { - unsigned char first_part[20], second_part[20], zfirst_part[20], zsecond_part[20]; +INTERNAL void ean_leading_zeroes(struct zint_symbol *symbol, unsigned char source[], unsigned char local_source[], int *p_with_addon) { + unsigned char first_part[20], second_part[7], zfirst_part[20], zsecond_part[7]; int with_addon = 0; int first_len = 0, second_len = 0, zfirst_len = 0, zsecond_len = 0, i, h; @@ -596,24 +616,19 @@ INTERNAL void ean_leading_zeroes(struct zint_symbol *symbol, unsigned char sourc } } - ustrcpy(first_part, (unsigned char *) ""); - ustrcpy(second_part, (unsigned char *) ""); - ustrcpy(zfirst_part, (unsigned char *) ""); - ustrcpy(zsecond_part, (unsigned char *) ""); - /* Split input into two strings */ for (i = 0; i < first_len; i++) { first_part[i] = source[i]; - first_part[i + 1] = '\0'; } + first_part[first_len] = '\0'; if (second_len >= 6) { /* Allow 6 (actual max 5) so as to trigger too long error */ second_len = 6; } for (i = 0; i < second_len; i++) { second_part[i] = source[i + first_len + 1]; - second_part[i + 1] = '\0'; } + second_part[second_len] = '\0'; /* Calculate target lengths */ if (second_len <= 5) { @@ -692,10 +707,13 @@ INTERNAL void ean_leading_zeroes(struct zint_symbol *symbol, unsigned char sourc /* Add leading zeroes */ + zfirst_part[0] = '\0'; for (i = 0; i < (zfirst_len - first_len); i++) { strcat((char*) zfirst_part, "0"); } strcat((char*) zfirst_part, (char*) first_part); + + zsecond_part[0] = '\0'; for (i = 0; i < (zsecond_len - second_len); i++) { strcat((char*) zsecond_part, "0"); } @@ -707,17 +725,21 @@ INTERNAL void ean_leading_zeroes(struct zint_symbol *symbol, unsigned char sourc strcat((char*) local_source, "+"); strcat((char*) local_source, (char*) zsecond_part); } + + if (p_with_addon) { + *p_with_addon = with_addon; + } } /* splits string to parts before and after '+' parts */ INTERNAL int eanx(struct zint_symbol *symbol, unsigned char source[], int src_len) { unsigned char first_part[20] = {0}, second_part[7] = {0}, dest[1000] = {0}; - unsigned char local_source[20] = {0}; - unsigned int latch, reader, writer, with_addon; + unsigned char local_source[21] = {0}; /* Allow 13 + "+" + 6 (too long add-on) + 1 */ + unsigned int latch, reader, writer; + int with_addon; int error_number, i, plus_count; int addon_gap = 0; - with_addon = FALSE; latch = FALSE; writer = 0; @@ -753,13 +775,7 @@ INTERNAL int eanx(struct zint_symbol *symbol, unsigned char source[], int src_le } /* Add leading zeroes */ - ean_leading_zeroes(symbol, source, local_source); - - for (reader = 0; reader < ustrlen(local_source); reader++) { - if (local_source[reader] == '+') { - with_addon = TRUE; - } - } + ean_leading_zeroes(symbol, source, local_source, &with_addon); reader = 0; if (with_addon) { @@ -807,7 +823,7 @@ INTERNAL int eanx(struct zint_symbol *symbol, unsigned char source[], int src_le case 12: case 13: error_number = ean13(symbol, first_part, (char*) dest); break; - default: strcpy(symbol->errtxt, "286: Invalid length input"); + default: strcpy(symbol->errtxt, "286: Input wrong length"); return ZINT_ERROR_TOO_LONG; } break; @@ -825,7 +841,8 @@ INTERNAL int eanx(struct zint_symbol *symbol, unsigned char source[], int src_le symbol->rows += 3; error_number = ean8(symbol, first_part, (char*) dest); break; - case 12:set_module(symbol, symbol->rows, 1); + case 12: + case 13:set_module(symbol, symbol->rows, 1); set_module(symbol, symbol->rows, 95); set_module(symbol, symbol->rows + 1, 0); set_module(symbol, symbol->rows + 1, 96); @@ -837,7 +854,7 @@ INTERNAL int eanx(struct zint_symbol *symbol, unsigned char source[], int src_le symbol->rows += 3; error_number = ean13(symbol, first_part, (char*) dest); break; - default: strcpy(symbol->errtxt, "287: Invalid length EAN input"); + default: strcpy(symbol->errtxt, "287: Input wrong length"); return ZINT_ERROR_TOO_LONG; } break; @@ -864,7 +881,7 @@ INTERNAL int eanx(struct zint_symbol *symbol, unsigned char source[], int src_le symbol->rows += 3; error_number = upca(symbol, first_part, (char*) dest); } else { - strcpy(symbol->errtxt, "289: UPCA input wrong length"); + strcpy(symbol->errtxt, "289: Input wrong length"); return ZINT_ERROR_TOO_LONG; } break; @@ -891,7 +908,7 @@ INTERNAL int eanx(struct zint_symbol *symbol, unsigned char source[], int src_le symbol->rows += 3; error_number = upce(symbol, first_part, (char*) dest); } else { - strcpy(symbol->errtxt, "291: UPCE input wrong length"); + strcpy(symbol->errtxt, "291: Input wrong length"); return ZINT_ERROR_TOO_LONG; } break; @@ -917,7 +934,7 @@ INTERNAL int eanx(struct zint_symbol *symbol, unsigned char source[], int src_le strcat((char*) symbol->text, (char*) second_part); break; default: - strcpy(symbol->errtxt, "292: Invalid length input"); + strcpy(symbol->errtxt, "292: Add-on input wrong length"); return ZINT_ERROR_TOO_LONG; } diff --git a/backend_qt/qzint.cpp b/backend_qt/qzint.cpp index 8dbf8ffc..2de11d45 100644 --- a/backend_qt/qzint.cpp +++ b/backend_qt/qzint.cpp @@ -532,6 +532,9 @@ namespace Zint { string = m_zintSymbol->vector->strings; if (string) { painter.setRenderHint(QPainter::Antialiasing); + QPen p; + p.setColor(m_fgColor); + painter.setPen(p); bool bold = (m_zintSymbol->output_options & BOLD_TEXT) && (!isExtendable() || (m_zintSymbol->output_options & SMALL_TEXT)); QFont font(fontStyle, -1 /*pointSize*/, bold ? QFont::Bold : -1); while (string) { diff --git a/docs/manual.txt b/docs/manual.txt index 07931114..07b5f209 100644 --- a/docs/manual.txt +++ b/docs/manual.txt @@ -1275,7 +1275,7 @@ if (cap & ZINT_CAP_ECI) { printf("PDF417 does not support ECI\n"); } -5.11 Zint Version +5.12 Zint Version ----------------- Lastly, the version of the Zint library linked to is returned by: @@ -1968,7 +1968,7 @@ and automatic mail sorting. Data input can consist of numbers 0-9 and letters A-Z and needs to be 11 characters in length. No check digit is included. 6.5.3 Royal Mail 4-State Customer Code (RM4SCC) ----------------------------------------------- +----------------------------------------------- The RM4SCC standard is used by the Royal Mail in the UK to encode postcode and customer data on mail items. Data input can consist of numbers 0-9 and letters A-Z and usually includes delivery postcode followed by house number. For