mirror of
https://git.code.sf.net/p/zint/code
synced 2026-05-01 19:55:29 +00:00
raster/vector: EAN/UPC: fix calculation of image/vector height to
allow for heights smaller than `textoffset` when have add-on (buffer overflow for raster, outside vector height for vector) raster: EAN/UPC: make sure don't overwrite add-on stuff when line-copying guard descenders by limiting copy width ZBarcode_Encode_Segs: allow for multiple (stacked) rows when setting absolute minimum height; state stacked symbols max in error message DBAR_EXP: check length on encoding method 6 before trying to parse 3-digit currency string with `z_to_int()` CLI: stop looping over data args when have error; suppress taint warning by using fixed `malloc()` size for `arg_opts` instead of `argc` general: use `vsnprintf()` instead of `vsprintf()` if not C89 ULTRACODE: don't call `ult_generate_codewords()` if `length` 0 from fragment processing (avoids `assert()`) clang-tidy -> 23 & suppress some warnings test suite: fuzz: leave Z_FUZZ_DEBUG to compiler, fix comment general: some minor code-formatting on touched files README.deb -> README.debian (avoid confusion with actual ".deb") BWIPP: update to latest
This commit is contained in:
@@ -1489,7 +1489,9 @@ static int do_exit(const int error_number) {
|
||||
return error_number; /* Not reached */
|
||||
}
|
||||
|
||||
typedef struct { const char *arg; int opt; } arg_opt;
|
||||
struct arg_opt { const char *arg; int opt; };
|
||||
|
||||
#define OPT_ARGS_MAX 300 /* Make greater than 200 (max no. of stacked rows) as that's a better error message */
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
struct zint_symbol *my_symbol;
|
||||
@@ -1519,7 +1521,7 @@ int main(int argc, char **argv) {
|
||||
float x_dim_mm = 0.0f, dpmm = 0.0f;
|
||||
float float_opt;
|
||||
char errbuf[ERRBUF_SIZE]; /* For `validate_float/()`, `validate_scalexdimdp()` etc. */
|
||||
arg_opt *const arg_opts = (arg_opt *) z_alloca(sizeof(arg_opt) * argc);
|
||||
struct arg_opt *const arg_opts = (struct arg_opt *) z_alloca(sizeof(struct arg_opt) * OPT_ARGS_MAX);
|
||||
|
||||
const int no_png = ZBarcode_NoPng();
|
||||
const int have_gs1syntaxengine = ZBarcode_HaveGS1SyntaxEngine();
|
||||
@@ -1970,7 +1972,7 @@ int main(int argc, char **argv) {
|
||||
break;
|
||||
case OPT_SCALEXDIM:
|
||||
if (!validate_scalexdimdp(optarg, &x_dim_mm, &dpmm, errbuf)) {
|
||||
fprintf(stderr, "Error 184: %s\n", errbuf);
|
||||
fprintf(stderr, "Error 189: %s\n", errbuf);
|
||||
return do_exit(ZINT_ERROR_INVALID_OPTION);
|
||||
}
|
||||
if (x_dim_mm > 10.0f || dpmm > 1000.0f) {
|
||||
@@ -2173,6 +2175,11 @@ int main(int argc, char **argv) {
|
||||
|
||||
case 'd': /* we have some data! */
|
||||
if (batch_mode == 0) {
|
||||
if (data_arg_num == OPT_ARGS_MAX) {
|
||||
fprintf(stderr, "Error 129: Too many data args (maximum %d)\n", OPT_ARGS_MAX);
|
||||
return do_exit(ZINT_ERROR_INVALID_OPTION);
|
||||
|
||||
}
|
||||
arg_opts[data_arg_num].arg = optarg;
|
||||
arg_opts[data_arg_num].opt = opt;
|
||||
data_arg_num++;
|
||||
@@ -2186,6 +2193,11 @@ int main(int argc, char **argv) {
|
||||
|
||||
case 'i': /* Take data from file */
|
||||
if (batch_mode == 0 || input_cnt == 0) {
|
||||
if (data_arg_num == OPT_ARGS_MAX) {
|
||||
fprintf(stderr, "Error 130: Too many data args (maximum %d)\n", OPT_ARGS_MAX);
|
||||
return do_exit(ZINT_ERROR_INVALID_OPTION);
|
||||
|
||||
}
|
||||
arg_opts[data_arg_num].arg = optarg;
|
||||
arg_opts[data_arg_num].opt = opt;
|
||||
data_arg_num++;
|
||||
@@ -2211,6 +2223,7 @@ int main(int argc, char **argv) {
|
||||
case '?': {
|
||||
/* Workaround musl `optind` bug - see https://www.openwall.com/lists/musl/2025/12/19/1 */
|
||||
const int idx = optind <= argc ? optind - 1 : argc - 1;
|
||||
/* NOLINTNEXTLINE(clang-analyzer-security.ArrayBound) disable clang-tidy-23 warning */
|
||||
const char *const arg = argv[idx] ? argv[idx] : "?";
|
||||
if (optopt) {
|
||||
for (i = 0; i < ARRAY_SIZE(long_options) && long_options[i].val != optopt; i++);
|
||||
@@ -2327,7 +2340,7 @@ int main(int argc, char **argv) {
|
||||
warn_number = ZINT_WARN_INVALID_OPTION;
|
||||
}
|
||||
error_number = batch_process(my_symbol, arg_opts[0].arg, mirror_mode, filetype, output_given,
|
||||
rotate_angle);
|
||||
rotate_angle);
|
||||
} else {
|
||||
if (seg_count) {
|
||||
if (data_arg_num > 1) {
|
||||
@@ -2398,6 +2411,9 @@ int main(int argc, char **argv) {
|
||||
if (error_number < ZINT_ERROR) {
|
||||
error_number = ret;
|
||||
}
|
||||
if (error_number >= ZINT_ERROR) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (error_number < ZINT_ERROR) {
|
||||
|
||||
@@ -1065,15 +1065,15 @@ static void test_other_opts(const testCtx *const p_ctx) {
|
||||
/* 54*/ { -1, NULL, -1, " -h", NULL, "Encode input data in a barcode ", 1 },
|
||||
/* 55*/ { -1, NULL, -1, " -e", NULL, "3: ISO/IEC 8859-1 ", 1 },
|
||||
/* 56*/ { -1, NULL, -1, " -t", NULL, "1 CODE11 ", 1 },
|
||||
/* 57*/ { BARCODE_EANX, "501234567890", -1, " --scalexdimdp=", "12345678", "Error 184: scalexdimdp X-dim invalid floating point: integer part must be 7 digits maximum", 0 },
|
||||
/* 58*/ { BARCODE_EANX, "501234567890", -1, " --scalexdimdp=", "1234567890123", "Error 184: scalexdimdp X-dim too long", 0 },
|
||||
/* 59*/ { BARCODE_EANX, "501234567890", -1, " --scalexdimdp=", "123456.12", "Error 184: scalexdimdp X-dim invalid floating point: 7 significant digits maximum", 0 },
|
||||
/* 60*/ { BARCODE_EANX, "501234567890", -1, " --scalexdimdp=", ",12.34", "Error 184: scalexdimdp X-dim too short", 0 },
|
||||
/* 61*/ { BARCODE_EANX, "501234567890", -1, " --scalexdimdp=", "12.34,", "Error 184: scalexdimdp resolution too short", 0 },
|
||||
/* 62*/ { BARCODE_EANX, "501234567890", -1, " --scalexdimdp=", "12mm1", "Error 184: scalexdimdp X-dim unknown units: mm1", 0 },
|
||||
/* 63*/ { BARCODE_EANX, "501234567890", -1, " --scalexdimdp=", "1inc", "Error 184: scalexdimdp X-dim unknown units: inc", 0 },
|
||||
/* 64*/ { BARCODE_EANX, "501234567890", -1, " --scalexdimdp=", "12.34in,123x", "Error 184: scalexdimdp resolution unknown units: x", 0 },
|
||||
/* 65*/ { BARCODE_EANX, "501234567890", -1, " --scalexdimdp=", "12,123.45678", "Error 184: scalexdimdp resolution invalid floating point: 7 significant digits maximum", 0 },
|
||||
/* 57*/ { BARCODE_EANX, "501234567890", -1, " --scalexdimdp=", "12345678", "Error 189: scalexdimdp X-dim invalid floating point: integer part must be 7 digits maximum", 0 },
|
||||
/* 58*/ { BARCODE_EANX, "501234567890", -1, " --scalexdimdp=", "1234567890123", "Error 189: scalexdimdp X-dim too long", 0 },
|
||||
/* 59*/ { BARCODE_EANX, "501234567890", -1, " --scalexdimdp=", "123456.12", "Error 189: scalexdimdp X-dim invalid floating point: 7 significant digits maximum", 0 },
|
||||
/* 60*/ { BARCODE_EANX, "501234567890", -1, " --scalexdimdp=", ",12.34", "Error 189: scalexdimdp X-dim too short", 0 },
|
||||
/* 61*/ { BARCODE_EANX, "501234567890", -1, " --scalexdimdp=", "12.34,", "Error 189: scalexdimdp resolution too short", 0 },
|
||||
/* 62*/ { BARCODE_EANX, "501234567890", -1, " --scalexdimdp=", "12mm1", "Error 189: scalexdimdp X-dim unknown units: mm1", 0 },
|
||||
/* 63*/ { BARCODE_EANX, "501234567890", -1, " --scalexdimdp=", "1inc", "Error 189: scalexdimdp X-dim unknown units: inc", 0 },
|
||||
/* 64*/ { BARCODE_EANX, "501234567890", -1, " --scalexdimdp=", "12.34in,123x", "Error 189: scalexdimdp resolution unknown units: x", 0 },
|
||||
/* 65*/ { BARCODE_EANX, "501234567890", -1, " --scalexdimdp=", "12,123.45678", "Error 189: scalexdimdp resolution invalid floating point: 7 significant digits maximum", 0 },
|
||||
/* 66*/ { BARCODE_EANX, "501234567890", -1, " --scalexdimdp=", "10.1,1000", "Warning 185: scalexdimdp X-dim '10.1' out of range (greater than 10), **IGNORED**", 0 },
|
||||
/* 67*/ { BARCODE_EANX, "501234567890", -1, " --scalexdimdp=", "10,1000.1", "Warning 186: scalexdimdp resolution '1000.1' out of range (greater than 1000), **IGNORED**", 0 },
|
||||
};
|
||||
@@ -1286,6 +1286,73 @@ static void test_bad_args(const testCtx *const p_ctx) {
|
||||
testFinish();
|
||||
}
|
||||
|
||||
static void test_too_many_args(const testCtx *const p_ctx) {
|
||||
int debug = p_ctx->debug;
|
||||
|
||||
struct item {
|
||||
int b;
|
||||
const char *args0;
|
||||
const char *args1;
|
||||
const char *args2;
|
||||
const char *args3;
|
||||
|
||||
const char *expected;
|
||||
};
|
||||
/* s/\v(\/\*)[ 0-9]*(\*\/)/\=printf("%s%3d%s", submatch(1), (@z+setreg('z',@z+1)), submatch(2))/ | let @z=0: */
|
||||
struct item data[] = {
|
||||
/* 0*/ { BARCODE_CODE128,
|
||||
" -d 000 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 010 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 020 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 030 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 040 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 050 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 060 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 070 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 080 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 090 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9",
|
||||
" -d 100 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 110 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 120 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 130 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 140 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 150 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 160 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 170 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 180 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 190 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9",
|
||||
"",
|
||||
"",
|
||||
""
|
||||
},
|
||||
/* 1*/ { BARCODE_CODE128,
|
||||
" -d 000 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 010 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 020 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 030 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 040 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 050 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 060 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 070 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 080 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 090 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9",
|
||||
" -d 100 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 110 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 120 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 130 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 140 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 150 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 160 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 170 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 180 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 190 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9",
|
||||
" -d 200",
|
||||
"",
|
||||
"Error 770: Too many stacked symbols (maximum 200)"
|
||||
},
|
||||
/* 1*/ { BARCODE_CODE128,
|
||||
" -d 000 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 010 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 020 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 030 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 040 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 050 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 060 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 070 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 080 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 090 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9",
|
||||
" -d 100 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 110 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 120 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 130 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 140 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 150 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 160 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 170 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 180 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 190 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9",
|
||||
" -d 200 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 210 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 220 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 230 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 240 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 250 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 260 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 270 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 280 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9 -d 290 -d 1 -d 2 -d 3 -d 4 -d 5 -d 6 -d 7 -d 8 -d 9",
|
||||
" -d 300",
|
||||
"Error 129: Too many data args (maximum 300)"
|
||||
},
|
||||
};
|
||||
int data_size = ARRAY_SIZE(data);
|
||||
int i;
|
||||
int exit_status;
|
||||
|
||||
char cmd[4096];
|
||||
char buf[8192];
|
||||
|
||||
testStart("test_too_many_args");
|
||||
|
||||
for (i = 0; i < data_size; i++) {
|
||||
|
||||
if (testContinue(p_ctx, i)) continue;
|
||||
|
||||
strcpy(cmd, "zint");
|
||||
*buf = '\0';
|
||||
|
||||
arg_int(cmd, "-b ", data[i].b);
|
||||
strcat(cmd, data[i].args0);
|
||||
strcat(cmd, data[i].args1);
|
||||
strcat(cmd, data[i].args2);
|
||||
strcat(cmd, data[i].args3);
|
||||
|
||||
strcat(cmd, " 2>&1");
|
||||
|
||||
assert_nonnull(exec(cmd, buf, sizeof(buf) - 1, debug, i, &exit_status), "i:%d exec(%s) == NULL\n", i, cmd);
|
||||
assert_zero(strcmp(buf, data[i].expected), "i:%d buf (%s) != expected (%s) (%s)\n", i, buf, data[i].expected, cmd);
|
||||
}
|
||||
|
||||
testFinish();
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
|
||||
testFunction funcs[] = { /* name, func */
|
||||
@@ -1301,6 +1368,7 @@ int main(int argc, char *argv[]) {
|
||||
{ "test_combos", test_combos },
|
||||
{ "test_exit_status", test_exit_status },
|
||||
{ "test_bad_args", test_bad_args },
|
||||
{ "test_too_many_args", test_too_many_args },
|
||||
};
|
||||
|
||||
testRun(argc, argv, funcs, ARRAY_SIZE(funcs));
|
||||
|
||||
Reference in New Issue
Block a user