diff --git a/backend/2of5inter_based.c b/backend/2of5inter_based.c index 7914463c..24441925 100644 --- a/backend/2of5inter_based.c +++ b/backend/2of5inter_based.c @@ -43,9 +43,20 @@ INTERNAL int c25_inter_common(struct zint_symbol *symbol, unsigned char source[] INTERNAL int itf14(struct zint_symbol *symbol, unsigned char source[], int length) { int i, error_number, zeroes; unsigned char local_source[14]; + unsigned char have_check_digit = '\0'; + unsigned char check_digit; - if (length > 13) { - return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 311, "Input length %d too long (maximum 13)", length); + /* Allow and ignore any AI prefix, but only if have check digit */ + if (length == 18 && (memcmp(source, "[01]", 4) == 0 || memcmp(source, "(01)", 4) == 0)) { + source += 4; + length -= 4; + /* Likewise initial '01', if have check digit */ + } else if (length == 16 && source[0] == '0' && source[1] == '1') { + source += 2; + length -= 2; + } + if (length > 14) { + return errtxtf(ZINT_ERROR_TOO_LONG, symbol, 311, "Input length %d too long (maximum 14)", length); } if ((i = not_sane(NEON_F, source, length))) { @@ -53,6 +64,11 @@ INTERNAL int itf14(struct zint_symbol *symbol, unsigned char source[], int lengt "Invalid character at position %d in input (digits only)", i); } + if (length == 14) { + have_check_digit = source[13]; + length--; + } + /* Add leading zeros as required */ zeroes = 13 - length; for (i = 0; i < zeroes; i++) { @@ -61,7 +77,12 @@ INTERNAL int itf14(struct zint_symbol *symbol, unsigned char source[], int lengt memcpy(local_source + zeroes, source, length); /* Calculate the check digit - the same method used for EAN-13 */ - local_source[13] = gs1_check_digit(local_source, 13); + check_digit = (unsigned char) gs1_check_digit(local_source, 13); + if (have_check_digit && have_check_digit != check_digit) { + return ZEXT errtxtf(ZINT_ERROR_INVALID_CHECK, symbol, 850, "Invalid check digit '%1$c', expecting '%2$c'", + have_check_digit, check_digit); + } + local_source[13] = check_digit; error_number = c25_inter_common(symbol, local_source, 14, 0 /*checkdigit_option*/, 1 /*dont_set_height*/); if (error_number < ZINT_ERROR) { diff --git a/backend/code128_based.c b/backend/code128_based.c index bfdac605..9db440b9 100644 --- a/backend/code128_based.c +++ b/backend/code128_based.c @@ -42,32 +42,53 @@ INTERNAL int gs1_128(struct zint_symbol *symbol, unsigned char source[], int length); /* Helper to do NVE18 or EAN14 */ -static int nve18_or_ean14(struct zint_symbol *symbol, unsigned char source[], const int length, const int data_len) { +static int nve18_or_ean14(struct zint_symbol *symbol, const unsigned char source[], int length, const int data_len) { static const char prefix[2][2][5] = { { "(01)", "[01]" }, /* EAN14 */ { "(00)", "[00]" }, /* NVE18 */ }; + const int idx = data_len == 17; unsigned char ean128_equiv[23]; int i, zeroes; + unsigned char have_check_digit = '\0'; + unsigned char check_digit; int error_number; - if (length > data_len) { - return ZEXT errtxtf(ZINT_ERROR_TOO_LONG, symbol, 345, "Input length %1$d too long (maximum %2$d)", length, - data_len); + /* Allow and ignore any AI prefix, but only if have check digit */ + if (length == data_len + 1 + 4 + && (memcmp(source, prefix[idx][0], 4) == 0 || memcmp(source, prefix[idx][1], 4) == 0)) { + source += 4; + length -= 4; + /* Likewise initial '01' (EAN-14) or '00' (NVE-18), if have check digit */ + } else if (length == data_len + 1 + 2 && source[0] == prefix[idx][0][1] && source[1] == prefix[idx][0][2]) { + source += 2; + length -= 2; + } + if (length > data_len + 1) { + return ZEXT errtxtf(ZINT_ERROR_TOO_LONG, symbol, 345, "Input length %1$d too long (maximum %2$d)", + length, data_len + 1); } - if ((i = not_sane(NEON_F, source, length))) { /* Note: for all "at position" error messages, escape sequences not accounted for */ return errtxtf(ZINT_ERROR_INVALID_DATA, symbol, 346, "Invalid character at position %d in input (digits only)", i); } + if (length == data_len + 1) { + have_check_digit = source[data_len]; + length--; + } zeroes = data_len - length; - memcpy(ean128_equiv, prefix[data_len == 17][!(symbol->input_mode & GS1PARENS_MODE)], 4); + memcpy(ean128_equiv, prefix[idx][!(symbol->input_mode & GS1PARENS_MODE)], 4); memset(ean128_equiv + 4, '0', zeroes); memcpy(ean128_equiv + 4 + zeroes, source, length); - ean128_equiv[data_len + 4] = gs1_check_digit(ean128_equiv + 4, data_len); + check_digit = (unsigned char) gs1_check_digit(ean128_equiv + 4, data_len); + if (have_check_digit && have_check_digit != check_digit) { + return ZEXT errtxtf(ZINT_ERROR_INVALID_CHECK, symbol, 347, "Invalid check digit '%1$c', expecting '%2$c'", + have_check_digit, check_digit); + } + ean128_equiv[data_len + 4] = check_digit; ean128_equiv[data_len + 5] = '\0'; /* Terminating NUL required by `c128_cost()` */ error_number = gs1_128(symbol, ean128_equiv, data_len + 5); diff --git a/backend/tests/test_2of5.c b/backend/tests/test_2of5.c index 0bac2404..e451007f 100644 --- a/backend/tests/test_2of5.c +++ b/backend/tests/test_2of5.c @@ -70,8 +70,8 @@ static void test_large(const testCtx *const p_ctx) { /* 21*/ { BARCODE_DPLEIT, -1, "1", 14, ZINT_ERROR_TOO_LONG, -1, -1, "Error 313: Input length 14 too long (maximum 13)" }, /* 22*/ { BARCODE_DPIDENT, -1, "1", 11, 0, 1, 117, "" }, /* 23*/ { BARCODE_DPIDENT, -1, "1", 12, ZINT_ERROR_TOO_LONG, -1, -1, "Error 315: Input length 12 too long (maximum 11)" }, - /* 24*/ { BARCODE_ITF14, -1, "1", 13, 0, 1, 135, "" }, - /* 25*/ { BARCODE_ITF14, -1, "1", 14, ZINT_ERROR_TOO_LONG, -1, -1, "Error 311: Input length 14 too long (maximum 13)" }, + /* 24*/ { BARCODE_ITF14, -1, "0", 14, 0, 1, 135, "" }, + /* 25*/ { BARCODE_ITF14, -1, "0", 15, ZINT_ERROR_TOO_LONG, -1, -1, "Error 311: Input length 15 too long (maximum 14)" }, }; const int data_size = ARRAY_SIZE(data); int i, length, ret; @@ -89,18 +89,26 @@ static void test_large(const testCtx *const p_ctx) { assert_nonnull(symbol, "Symbol not created\n"); testUtilStrCpyRepeat(data_buf, data[i].pattern, data[i].length); - assert_equal(data[i].length, (int) strlen(data_buf), "i:%d length %d != strlen(data_buf) %d\n", i, data[i].length, (int) strlen(data_buf)); + assert_equal(data[i].length, (int) strlen(data_buf), "i:%d length %d != strlen(data_buf) %d\n", + i, data[i].length, (int) strlen(data_buf)); - length = testUtilSetSymbol(symbol, data[i].symbology, -1 /*input_mode*/, -1 /*eci*/, -1 /*option_1*/, data[i].option_2, -1, -1 /*output_options*/, data_buf, data[i].length, debug); + length = testUtilSetSymbol(symbol, data[i].symbology, -1 /*input_mode*/, -1 /*eci*/, + -1 /*option_1*/, data[i].option_2, -1, -1 /*output_options*/, + data_buf, data[i].length, debug); ret = ZBarcode_Encode(symbol, TCU(data_buf), 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 strcmp(%s, %s) != 0\n", i, symbol->errtxt, data[i].expected_errtxt); + 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 strcmp(%s, %s) != 0\n", + i, symbol->errtxt, data[i].expected_errtxt); if (ret < ZINT_ERROR) { - assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d\n", i, symbol->rows, data[i].expected_rows); - assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d\n", i, symbol->width, data[i].expected_width); + assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d\n", + i, symbol->rows, data[i].expected_rows); + assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d\n", + i, symbol->width, data[i].expected_width); } ZBarcode_Delete(symbol); @@ -242,6 +250,19 @@ static void test_input(const testCtx *const p_ctx) { /* 8*/ { BARCODE_DPIDENT, -1, "A", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 316: Invalid character at position 1 in input (digits only)" }, /* 9*/ { BARCODE_DPIDENT, -1, "1234567890A", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 316: Invalid character at position 11 in input (digits only)" }, /* 10*/ { BARCODE_ITF14, -1, "A", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 312: Invalid character at position 1 in input (digits only)" }, + /* 11*/ { BARCODE_ITF14, -1, "1234567890123", 0, 1, 135, "" }, + /* 12*/ { BARCODE_ITF14, -1, "12345678901231", 0, 1, 135, "" }, + /* 13*/ { BARCODE_ITF14, -1, "12345678901234", ZINT_ERROR_INVALID_CHECK, -1, -1, "Error 850: Invalid check digit '4', expecting '1'" }, + /* 14*/ { BARCODE_ITF14, -1, "1234567890123A", ZINT_ERROR_INVALID_DATA, -1, -1, "Error 312: Invalid character at position 14 in input (digits only)" }, + /* 15*/ { BARCODE_ITF14, -1, "0112345678901231", 0, 1, 135, "" }, /* Allow '01' prefix if have check digit */ + /* 16*/ { BARCODE_ITF14, -1, "011234567890123", ZINT_ERROR_TOO_LONG, -1, -1, "Error 311: Input length 15 too long (maximum 14)" }, /* But not without */ + /* 17*/ { BARCODE_ITF14, -1, "[01]12345678901231", 0, 1, 135, "" }, /* Allow '[01]' prefix if have check digit */ + /* 18*/ { BARCODE_ITF14, -1, "[01]1234567890123", ZINT_ERROR_TOO_LONG, -1, -1, "Error 311: Input length 17 too long (maximum 14)" }, /* But not without */ + /* 19*/ { BARCODE_ITF14, -1, "(01)12345678901231", 0, 1, 135, "" }, /* Allow '(01)' prefix if have check digit */ + /* 20*/ { BARCODE_ITF14, -1, "(01)1234567890123", ZINT_ERROR_TOO_LONG, -1, -1, "Error 311: Input length 17 too long (maximum 14)" }, /* But not without */ + /* 21*/ { BARCODE_ITF14, -1, "0012345678901231", ZINT_ERROR_TOO_LONG, -1, -1, "Error 311: Input length 16 too long (maximum 14)" }, + /* 22*/ { BARCODE_ITF14, -1, "[00]12345678901231", ZINT_ERROR_TOO_LONG, -1, -1, "Error 311: Input length 18 too long (maximum 14)" }, + /* 23*/ { BARCODE_ITF14, -1, "[01)12345678901231", ZINT_ERROR_TOO_LONG, -1, -1, "Error 311: Input length 18 too long (maximum 14)" }, }; const int data_size = ARRAY_SIZE(data); int i, length, ret; @@ -256,16 +277,23 @@ static void test_input(const testCtx *const p_ctx) { symbol = ZBarcode_Create(); assert_nonnull(symbol, "Symbol not created\n"); - length = testUtilSetSymbol(symbol, data[i].symbology, data[i].input_mode, -1 /*eci*/, -1 /*option_1*/, -1 /*option_2*/, -1, -1 /*output_options*/, data[i].data, -1, debug); + length = testUtilSetSymbol(symbol, data[i].symbology, data[i].input_mode, -1 /*eci*/, + -1 /*option_1*/, -1 /*option_2*/, -1, -1 /*output_options*/, + data[i].data, -1, 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 strcmp(%s, %s) != 0\n", i, symbol->errtxt, data[i].expected_errtxt); + 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 strcmp(%s, %s) != 0\n", + i, symbol->errtxt, data[i].expected_errtxt); if (ret < ZINT_ERROR) { - assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d\n", i, symbol->rows, data[i].expected_rows); - assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d\n", i, symbol->width, data[i].expected_width); + assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d\n", + i, symbol->rows, data[i].expected_rows); + assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d\n", + i, symbol->width, data[i].expected_width); } ZBarcode_Delete(symbol); diff --git a/backend/tests/test_code128.c b/backend/tests/test_code128.c index 9c0755fe..275e3d72 100644 --- a/backend/tests/test_code128.c +++ b/backend/tests/test_code128.c @@ -87,10 +87,10 @@ static void test_large(const testCtx *const p_ctx) { /* 32*/ { BARCODE_GS1_128, -1, -1, "[90]123456789012345678901234567890[91]1234567890123456789012345678901234567890123456789012345678901234567890[92]123456789012345678901234567890123456789012345678901234567890123456789012345678901234[93]123", -1, ZINT_ERROR_TOO_LONG, -1, "Error 344: Input too long, requires 104 symbol characters (maximum 102)", 1 }, /* StartC + 194 nos + CodeA + single no. + 3 FNC1s */ /* 33*/ { BARCODE_GS1_128, -1, -1, "[90]123456789012345678901234567890[91]1234567890123456789012345678901234567890123456789012345678901234567890[92]1234567890123456789012345678901234567890123456789012345678901234567890[92]12345678901234567890123456789012345678901234567890123456789012345[93]1", -1, ZINT_ERROR_TOO_LONG, -1, "Error 344: Input too long, requires 132 symbol characters (maximum 102)", 1 }, /* 34*/ { BARCODE_GS1_128, -1, -1, "[90]123456789012345678901234567890[91]1234567890123456789012345678901234567890123456789012345678901234567890[92]1234567890123456789012345678901234567890123456789012345678901234567890[92]12345678901234567890123456789012345678901234567890123456789012345[93]12", -1, ZINT_ERROR_TOO_LONG, -1, "Error 342: Input length 257 too long (maximum 256)", 1 }, - /* 35*/ { BARCODE_EAN14, -1, -1, "1234567890123", -1, 0, 134, "", 1 }, - /* 36*/ { BARCODE_EAN14, -1, -1, "12345678901234", -1, ZINT_ERROR_TOO_LONG, -1, "Error 345: Input length 14 too long (maximum 13)", 1 }, - /* 37*/ { BARCODE_NVE18, -1, -1, "12345678901234567", -1, 0, 156, "", 1 }, - /* 38*/ { BARCODE_NVE18, -1, -1, "123456789012345678", -1, ZINT_ERROR_TOO_LONG, -1, "Error 345: Input length 18 too long (maximum 17)", 1 }, + /* 35*/ { BARCODE_EAN14, -1, -1, "12345678901231", -1, 0, 134, "", 1 }, + /* 36*/ { BARCODE_EAN14, -1, -1, "123456789012315", -1, ZINT_ERROR_TOO_LONG, -1, "Error 345: Input length 15 too long (maximum 14)", 1 }, + /* 37*/ { BARCODE_NVE18, -1, -1, "123456789012345675", -1, 0, 156, "", 1 }, + /* 38*/ { BARCODE_NVE18, -1, -1, "1234567890123456759", -1, ZINT_ERROR_TOO_LONG, -1, "Error 345: Input length 19 too long (maximum 18)", 1 }, /* 39*/ { BARCODE_HIBC_128, -1, -1, "1", 110, 0, 684, "", 1 }, /* 40*/ { BARCODE_HIBC_128, -1, -1, "1", 111, ZINT_ERROR_TOO_LONG, -1, "Error 202: Input length 111 too long for HIBC LIC (maximum 110)", 1 }, }; @@ -1018,9 +1018,23 @@ static void test_nve18_input(const testCtx *const p_ctx) { const char *comment; }; static const struct item data[] = { - /* 0*/ { -1, "123456789012345678", ZINT_ERROR_TOO_LONG, -1, "Error 345: Input length 18 too long (maximum 17)", "" }, - /* 1*/ { -1, "1234A568901234567", ZINT_ERROR_INVALID_DATA, -1, "Error 346: Invalid character at position 5 in input (digits only)", "" }, - /* 2*/ { ESCAPE_MODE, "\\d049\\d050\\d051\\d052A568901234567", ZINT_ERROR_INVALID_DATA, -1, "Error 346: Invalid character at position 5 in input (digits only)", "Position does not account for escape sequences" }, + /* 0*/ { -1, "1234567890123456789", ZINT_ERROR_TOO_LONG, -1, "Error 345: Input length 19 too long (maximum 18)", "" }, + /* 1*/ { -1, "12345678901234567A", ZINT_ERROR_INVALID_DATA, -1, "Error 346: Invalid character at position 18 in input (digits only)", "" }, + /* 2*/ { -1, "123456789012345678", ZINT_ERROR_INVALID_CHECK, -1, "Error 347: Invalid check digit '8', expecting '5'", "" }, + /* 3*/ { -1, "1234A568901234567", ZINT_ERROR_INVALID_DATA, -1, "Error 346: Invalid character at position 5 in input (digits only)", "" }, + /* 4*/ { ESCAPE_MODE, "\\d049\\d050\\d051\\d052A568901234567", ZINT_ERROR_INVALID_DATA, -1, "Error 346: Invalid character at position 5 in input (digits only)", "Position does not account for escape sequences" }, + /* 5*/ { -1, "123456789012345675", 0, 156, "(14) 105 102 0 12 34 56 78 90 12 34 56 75 42 106", "" }, + /* 6*/ { -1, "12345678901234567", 0, 156, "(14) 105 102 0 12 34 56 78 90 12 34 56 75 42 106", "" }, + /* 7*/ { -1, "00123456789012345675", 0, 156, "(14) 105 102 0 12 34 56 78 90 12 34 56 75 42 106", "'00' prefix allowed if check digit" }, + /* 8*/ { -1, "0012345678901234567", ZINT_ERROR_TOO_LONG, -1, "Error 345: Input length 19 too long (maximum 18)", "But not without" }, + /* 9*/ { -1, "[00]123456789012345675", 0, 156, "(14) 105 102 0 12 34 56 78 90 12 34 56 75 42 106", "'[00]' prefix allowed if check digit" }, + /* 10*/ { -1, "[00]12345678901234567", ZINT_ERROR_TOO_LONG, -1, "Error 345: Input length 21 too long (maximum 18)", "But not without" }, + /* 11*/ { -1, "(00)123456789012345675", 0, 156, "(14) 105 102 0 12 34 56 78 90 12 34 56 75 42 106", "'(00)' prefix allowed if check digit" }, + /* 12*/ { -1, "(00)12345678901234567", ZINT_ERROR_TOO_LONG, -1, "Error 345: Input length 21 too long (maximum 18)", "But not without" }, + /* 13*/ { -1, "01123456789012345675", ZINT_ERROR_TOO_LONG, -1, "Error 345: Input length 20 too long (maximum 18)", "" }, + /* 14*/ { -1, "[01]123456789012345675", ZINT_ERROR_TOO_LONG, -1, "Error 345: Input length 22 too long (maximum 18)", "" }, + /* 15*/ { -1, "(01)123456789012345675", ZINT_ERROR_TOO_LONG, -1, "Error 345: Input length 22 too long (maximum 18)", "" }, + /* 16*/ { -1, "(00]123456789012345675", ZINT_ERROR_TOO_LONG, -1, "Error 345: Input length 22 too long (maximum 18)", "" }, }; const int data_size = ARRAY_SIZE(data); int i, length, ret; @@ -1044,18 +1058,21 @@ static void test_nve18_input(const testCtx *const p_ctx) { data[i].data, -1, 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_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", + i, ret, data[i].ret, symbol->errtxt); if (p_ctx->generate) { - printf(" /*%3d*/ { \"%s\", %s, %d, \"%s\", \"%s\" },\n", - i, testUtilEscape(data[i].data, length, escaped, sizeof(escaped)), + printf(" /*%3d*/ { %s, \"%s\", %s, %d, \"%s\", \"%s\" },\n", + i, testUtilInputModeName(data[i].input_mode), + testUtilEscape(data[i].data, length, escaped, sizeof(escaped)), testUtilErrorName(data[i].ret), symbol->width, symbol->errtxt, data[i].comment); } else { - assert_zero(strcmp(symbol->errtxt, data[i].expected), "i:%d strcmp(%s, %s) != 0\n", i, symbol->errtxt, data[i].expected); if (ret < ZINT_ERROR) { - 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); + 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); } + assert_zero(strcmp(symbol->errtxt, data[i].expected), "i:%d strcmp(%s, %s) != 0\n", + i, symbol->errtxt, data[i].expected); } ZBarcode_Delete(symbol); @@ -1075,8 +1092,22 @@ static void test_ean14_input(const testCtx *const p_ctx) { const char *comment; }; static const struct item data[] = { - /* 0*/ { "12345678901234", ZINT_ERROR_TOO_LONG, -1, "Error 345: Input length 14 too long (maximum 13)", "" }, - /* 1*/ { "123456789012A", ZINT_ERROR_INVALID_DATA, -1, "Error 346: Invalid character at position 13 in input (digits only)", "" }, + /* 0*/ { "123456789012345", ZINT_ERROR_TOO_LONG, -1, "Error 345: Input length 15 too long (maximum 14)", "" }, + /* 1*/ { "1234567890123A", ZINT_ERROR_INVALID_DATA, -1, "Error 346: Invalid character at position 14 in input (digits only)", "" }, + /* 2*/ { "12345678901234", ZINT_ERROR_INVALID_CHECK, -1, "Error 347: Invalid check digit '4', expecting '1'", "" }, + /* 3*/ { "123456789012A", ZINT_ERROR_INVALID_DATA, -1, "Error 346: Invalid character at position 13 in input (digits only)", "" }, + /* 4*/ { "1234567890123", 0, 134, "(12) 105 102 1 12 34 56 78 90 12 31 74 106", "" }, + /* 5*/ { "12345678901231", 0, 134, "(12) 105 102 1 12 34 56 78 90 12 31 74 106", "" }, + /* 6*/ { "0112345678901231", 0, 134, "(12) 105 102 1 12 34 56 78 90 12 31 74 106", "'01' prefix allowed if check digit" }, + /* 7*/ { "011234567890123", ZINT_ERROR_TOO_LONG, -1, "Error 345: Input length 15 too long (maximum 14)", "But not without" }, + /* 8*/ { "[01]12345678901231", 0, 134, "(12) 105 102 1 12 34 56 78 90 12 31 74 106", "'[01]' prefix allowed if check digit" }, + /* 9*/ { "[01]1234567890123", ZINT_ERROR_TOO_LONG, -1, "Error 345: Input length 17 too long (maximum 14)", "But not without" }, + /* 10*/ { "(01)12345678901231", 0, 134, "(12) 105 102 1 12 34 56 78 90 12 31 74 106", "'(01)' prefix allowed if check digit" }, + /* 11*/ { "(01)1234567890123", ZINT_ERROR_TOO_LONG, -1, "Error 345: Input length 17 too long (maximum 14)", "But not without" }, + /* 12*/ { "0012345678901231", ZINT_ERROR_TOO_LONG, -1, "Error 345: Input length 16 too long (maximum 14)", "" }, + /* 13*/ { "[00]12345678901231", ZINT_ERROR_TOO_LONG, -1, "Error 345: Input length 18 too long (maximum 14)", "" }, + /* 14*/ { "(00)12345678901231", ZINT_ERROR_TOO_LONG, -1, "Error 345: Input length 18 too long (maximum 14)", "" }, + /* 15*/ { "(01]12345678901231", ZINT_ERROR_TOO_LONG, -1, "Error 345: Input length 18 too long (maximum 14)", "" }, }; const int data_size = ARRAY_SIZE(data); int i, length, ret; @@ -1100,7 +1131,8 @@ static void test_ean14_input(const testCtx *const p_ctx) { data[i].data, -1, 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(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", + i, ret, data[i].ret, symbol->errtxt); if (p_ctx->generate) { printf(" /*%3d*/ { \"%s\", %s, %d, \"%s\", \"%s\" },\n", @@ -1108,9 +1140,11 @@ static void test_ean14_input(const testCtx *const p_ctx) { testUtilErrorName(data[i].ret), symbol->width, symbol->errtxt, data[i].comment); } else { if (ret < ZINT_ERROR) { - 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); + 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); } - assert_zero(strcmp(symbol->errtxt, data[i].expected), "i:%d strcmp(%s, %s) != 0\n", i, symbol->errtxt, data[i].expected); + assert_zero(strcmp(symbol->errtxt, data[i].expected), "i:%d strcmp(%s, %s) != 0\n", + i, symbol->errtxt, data[i].expected); } ZBarcode_Delete(symbol); diff --git a/docs/manual.html b/docs/manual.html index 2830fb7d..df6537f0 100644 --- a/docs/manual.html +++ b/docs/manual.html @@ -4472,9 +4472,10 @@ aria-hidden="true">zint -b ITF14 --compliantheight -d "9212320967145"

ITF-14, also known as UPC Shipping Container Symbol or Case Code, is based on Interleaved Code 2 of 5 and is designed to encode a GTIN-14. It -takes a 13-digit numeric input (digits 0-9), which will be prefixed with -leading zeroes if less than 13 digits entered. One modulo-10 check digit -is added by Zint.

+takes a 13-digit input, which will be prefixed with leading zeroes if +less than 13 digits entered, or a 14-digit input if the standard GS1 +check digit is given, in which case the check digit will be verified. A +standard GS1 check digit is added by Zint unless already given.

If no border option is specified Zint defaults to adding a bounding box with a border width of 5. This behaviour can be overridden by using the --bind option (API @@ -5011,9 +5012,12 @@ alt="zint -b EAN14 --compliantheight -d "9889876543210"" />

-

A shorter version of GS1-128 which encodes GTIN data only. A 13-digit -number is required. The GTIN check digit and HRT-only AI -"(01)" are added by Zint.

+

A shorter version of GS1-128 which encodes GTIN-14 data only, EAN-14 +takes a 13-digit input, which will be prefixed with leading zeroes if +less than 13 digits entered, or a 14-digit number if the standard GS1 +check digit is given, in which case the check digit will be verified. +The GS1 check digit (if not given) and HRT-only AI "(01)" +are added by Zint.

6.1.10.5 NVE-18 (SSCC-18)

zint -b NVE18 --compliantheight -d "37612345000001003"<

A variation of Code 128 the ‘Nummer der Versandeinheit’ standard, also known as SSCC-18 (Serial Shipping Container Code), includes both a -visible modulo-10 and a hidden modulo-103 check digit. NVE-18 requires a -17-digit numerical input. Check digits and HRT-only AI -"(00)" are added by Zint.

+visible standard GS1 check digit and a hidden modulo-103 check digit. +NVE-18 takes a 17-digit input, which will be prefixed with leading zeros +if less than 17 digits given, or an 18-digit input if the GS1 check +digit is included, in which case the check digit will be verified. Check +digit(s) and HRT-only AI "(00)" are added by Zint.

6.1.10.6 HIBC Code 128

zint -b DBAR_OMN --compliantheight -d "0950110153001"Previously known as RSS-14 this standard encodes a 13-digit item code. A check digit and HRT-only Application Identifier of "(01)" are added by Zint. (A 14-digit code that appends the -check digit may be given, in which case the check digit will be -verified.)

+standard GS1 check digit may be given, in which case the check digit +will be verified.)

GS1 DataBar Omnidirectional symbols should have a height of 33 or greater. To produce a GS1 DataBar Truncated symbol set the symbol height to a value between 13 and 32. Truncated symbols may not be scannable by @@ -5171,10 +5177,11 @@ inclusion of parentheses in the data to be encoded. If the data does not include parentheses, the AIs may alternatively be encased in parentheses using the --gs1parens switch. See 6.1.10.3 GS1-128.

-

GTIN data AI (01) should also include the check digit data as this is -not calculated by Zint when this symbology is encoded. Fixed length data -should be entered at the appropriate length for correct encoding. The -following is an example of a valid GS1 DataBar Expanded input:

+

GTIN data AI (01) should also include the standard GS1 check digit +data as this is not calculated by Zint when this symbology is encoded. +Fixed length data should be entered at the appropriate length for +correct encoding. The following is an example of a valid GS1 DataBar +Expanded input:

zint -b 31 -d "[01]98898765432106[3202]012345[15]991231"

6.1.12 Korea Post Barcode

diff --git a/docs/manual.pmd b/docs/manual.pmd index 06d375a4..0458ec73 100644 --- a/docs/manual.pmd +++ b/docs/manual.pmd @@ -2828,8 +2828,10 @@ same as for [6.1.2.1 Standard Code 2 of 5]. ITF-14, also known as UPC Shipping Container Symbol or Case Code, is based on Interleaved Code 2 of 5 and is designed to encode a GTIN-14. It takes a 13-digit -numeric input (digits 0-9), which will be prefixed with leading zeroes if less -than 13 digits entered. One modulo-10 check digit is added by Zint. +input, which will be prefixed with leading zeroes if less than 13 digits +entered, or a 14-digit input if the standard GS1 check digit is given, in which +case the check digit will be verified. A standard GS1 check digit is added by +Zint unless already given. If no border option is specified Zint defaults to adding a bounding box with a border width of 5. This behaviour can be overridden by using the `--bind` option @@ -3296,8 +3298,13 @@ zint -b 16 --gs1parens -d "(01)98898765432106(3202)012345(15)991231" ![`zint -b EAN14 --compliantheight -d "9889876543210"`](images/ean14.svg){.lin} -A shorter version of GS1-128 which encodes GTIN data only. A 13-digit number is -required. The GTIN check digit and HRT-only AI `"(01)"` are added by Zint. +A shorter version of GS1-128 which encodes GTIN-14 data only, EAN-14 takes a +13-digit input, which will be prefixed with leading zeroes if less than 13 +digits entered, or a 14-digit number if the standard GS1 check digit is given, +in which case the check digit will be verified. The GS1 check digit (if not +given) and HRT-only AI `"(01)"` are added by Zint. + +\clearpage #### 6.1.10.5 NVE-18 (SSCC-18) @@ -3305,9 +3312,11 @@ required. The GTIN check digit and HRT-only AI `"(01)"` are added by Zint. "37612345000001003"`](images/nve18.svg){.lin} A variation of Code 128 the 'Nummer der Versandeinheit' standard, also known as -SSCC-18 (Serial Shipping Container Code), includes both a visible modulo-10 and -a hidden modulo-103 check digit. NVE-18 requires a 17-digit numerical input. -Check digits and HRT-only AI `"(00)"` are added by Zint. +SSCC-18 (Serial Shipping Container Code), includes both a visible standard GS1 +check digit and a hidden modulo-103 check digit. NVE-18 takes a 17-digit input, +which will be prefixed with leading zeros if less than 17 digits given, or an +18-digit input if the GS1 check digit is included, in which case the check digit +will be verified. Check digit(s) and HRT-only AI `"(00)"` are added by Zint. #### 6.1.10.6 HIBC Code 128 @@ -3388,8 +3397,8 @@ GS1 DataBar symbol is to be printed with a 2D component as specified in ISO/IEC Previously known as RSS-14 this standard encodes a 13-digit item code. A check digit and HRT-only Application Identifier of `"(01)"` are added by Zint. (A -14-digit code that appends the check digit may be given, in which case the check -digit will be verified.) +14-digit code that appends the standard GS1 check digit may be given, in which +case the check digit will be verified.) GS1 DataBar Omnidirectional symbols should have a height of 33 or greater. To produce a GS1 DataBar Truncated symbol set the symbol height to a value between @@ -3423,10 +3432,10 @@ the symbol. This method allows the inclusion of parentheses in the data to be encoded. If the data does not include parentheses, the AIs may alternatively be encased in parentheses using the `--gs1parens` switch. See [6.1.10.3 GS1-128]. -GTIN data AI (01) should also include the check digit data as this is not -calculated by Zint when this symbology is encoded. Fixed length data should be -entered at the appropriate length for correct encoding. The following is an -example of a valid GS1 DataBar Expanded input: +GTIN data AI (01) should also include the standard GS1 check digit data as this +is not calculated by Zint when this symbology is encoded. Fixed length data +should be entered at the appropriate length for correct encoding. The following +is an example of a valid GS1 DataBar Expanded input: ```bash zint -b 31 -d "[01]98898765432106[3202]012345[15]991231" diff --git a/docs/manual.txt b/docs/manual.txt index 66ab8656..dae8603f 100644 --- a/docs/manual.txt +++ b/docs/manual.txt @@ -2748,8 +2748,10 @@ same as for 6.1.2.1 Standard Code 2 of 5. ITF-14, also known as UPC Shipping Container Symbol or Case Code, is based on Interleaved Code 2 of 5 and is designed to encode a GTIN-14. It takes a 13-digit -numeric input (digits 0-9), which will be prefixed with leading zeroes if less -than 13 digits entered. One modulo-10 check digit is added by Zint. +input, which will be prefixed with leading zeroes if less than 13 digits +entered, or a 14-digit input if the standard GS1 check digit is given, in which +case the check digit will be verified. A standard GS1 check digit is added by +Zint unless already given. If no border option is specified Zint defaults to adding a bounding box with a border width of 5. This behaviour can be overridden by using the --bind option @@ -3162,17 +3164,22 @@ or using the --gs1parens option: [zint -b EAN14 --compliantheight -d "9889876543210"] -A shorter version of GS1-128 which encodes GTIN data only. A 13-digit number is -required. The GTIN check digit and HRT-only AI "(01)" are added by Zint. +A shorter version of GS1-128 which encodes GTIN-14 data only, EAN-14 takes a +13-digit input, which will be prefixed with leading zeroes if less than 13 +digits entered, or a 14-digit number if the standard GS1 check digit is given, +in which case the check digit will be verified. The GS1 check digit (if not +given) and HRT-only AI "(01)" are added by Zint. 6.1.10.5 NVE-18 (SSCC-18) [zint -b NVE18 --compliantheight -d "37612345000001003"] A variation of Code 128 the ‘Nummer der Versandeinheit’ standard, also known as -SSCC-18 (Serial Shipping Container Code), includes both a visible modulo-10 and -a hidden modulo-103 check digit. NVE-18 requires a 17-digit numerical input. -Check digits and HRT-only AI "(00)" are added by Zint. +SSCC-18 (Serial Shipping Container Code), includes both a visible standard GS1 +check digit and a hidden modulo-103 check digit. NVE-18 takes a 17-digit input, +which will be prefixed with leading zeros if less than 17 digits given, or an +18-digit input if the GS1 check digit is included, in which case the check digit +will be verified. Check digit(s) and HRT-only AI "(00)" are added by Zint. 6.1.10.6 HIBC Code 128 @@ -3248,8 +3255,8 @@ to find out how to generate DataBar symbols with 2D components. Previously known as RSS-14 this standard encodes a 13-digit item code. A check digit and HRT-only Application Identifier of "(01)" are added by Zint. (A -14-digit code that appends the check digit may be given, in which case the check -digit will be verified.) +14-digit code that appends the standard GS1 check digit may be given, in which +case the check digit will be verified.) GS1 DataBar Omnidirectional symbols should have a height of 33 or greater. To produce a GS1 DataBar Truncated symbol set the symbol height to a value between @@ -3281,10 +3288,10 @@ the symbol. This method allows the inclusion of parentheses in the data to be encoded. If the data does not include parentheses, the AIs may alternatively be encased in parentheses using the --gs1parens switch. See 6.1.10.3 GS1-128. -GTIN data AI (01) should also include the check digit data as this is not -calculated by Zint when this symbology is encoded. Fixed length data should be -entered at the appropriate length for correct encoding. The following is an -example of a valid GS1 DataBar Expanded input: +GTIN data AI (01) should also include the standard GS1 check digit data as this +is not calculated by Zint when this symbology is encoded. Fixed length data +should be entered at the appropriate length for correct encoding. The following +is an example of a valid GS1 DataBar Expanded input: zint -b 31 -d "[01]98898765432106[3202]012345[15]991231"