1
0
mirror of https://git.code.sf.net/p/zint/code synced 2026-07-31 02:19:50 +00:00

CLI: make --mirror available in standard non-batch mode via

new routines `mirror_start()`, `mirror_outfile()` & limit
  substitutions on Unix to backslash (Windows remains the same);
  restrict "borderwidth", "textgap", "vwhitesp", "whitesp" < 100
CODEONE: fix `ceilf()` -> `C1_MULT_CEIL()` in FAST_MODE encodation
  (improves/changes some encodation)
composite: preserve `gs1_verify()` warning using `warn_level` hack;
  fix wrong name `zint_dbar_omnstk_set_height()` ->
  `zint_dbar_stk_set_height()`;
  use new `zint_micropdf_variant()` & `zint_micropdf_expand()`
  routines (see below)
MICROPDF417: move variant determination into new shareable routine
  `zint_micropdf_variant()` & expansion into `zint_micropdf_expand()`
qzint: add helper methods `setbordertypevalue()`,
  `encodedinputmode()`, `encodedoutputoptions()`,
  `ecivaluetoeciindex()` and `eciindextoecivalue()`
dbar: for performance pre-calculate `combins()` as array
coverage: add `malloc()`-type failure testing to AZTEC,
  CONTENT_SEGS, MEMORY_FILE, raster, Reed-Solomon & vector;
  numerous changes to remove unused code and test more branches
common: add `isxdigit()`
general: various code fiddlings
manual: add char names to sequence and batch format char tables;
  mention long options can be shortened (& use "--compliantheight"
  -> "--compliant");
  expand mirror explanation & document substitutions in footnote;
  workaround xecjk putting space after double quote when quoting
  cjk chars & rejig input mode examples;
  workaround html alignment bug in table gs1-enabled symbologies by
  adding extra rh dashes to header cols;
  add "figure nn: " to txt image tags via sed:
  various other small fixes and rephrasings
This commit is contained in:
gitlost
2026-06-23 23:25:23 +01:00
parent 4a60a0b068
commit a81c9d9258
91 changed files with 6879 additions and 4368 deletions
+55 -24
View File
@@ -60,6 +60,33 @@
# endif
#endif
#ifdef ZINT_TEST
/* For testing `malloc()`/`realloc()` failures */
static int fm_fail_id = 0;
static int fm_fail_at = 0;
INTERNAL void zint_test_fm_set_fail(const int id, const int at) {
fm_fail_id = id;
fm_fail_at = at;
}
#define FM_FAIL(id, ret) fm_fail_at > 0 && fm_fail_id == (id) && --fm_fail_at == 0 ? (ret) :
#define FM_FAIL_ERRNO(id, eno, ret) fm_fail_at > 0 && fm_fail_id == (id) && --fm_fail_at == 0 \
? (errno = (eno), (ret)) :
#define FM_FAIL_SETERR(id, eno) fm_fail_at > 0 && fm_fail_id == (id) && --fm_fail_at == 0 ? fm_seterr(fmp, eno) :
#define fm_malloc(sz) (FM_FAIL(FM_FAIL_ID_MALLOC, NULL) malloc(sz))
#define fm_realloc(ptr, sz) (FM_FAIL(FM_FAIL_ID_REALLOC, NULL) realloc(ptr, sz))
#else
#define FM_FAIL(id, ret)
#define FM_FAIL_ERRNO(id, eno, ret)
#define FM_FAIL_SETERR(id, eno)
#define fm_malloc(sz) malloc(sz)
#define fm_realloc(ptr, sz) realloc(ptr, sz)
#endif
/* Helper to set `err` only if not already set, returning 0 always for convenience */
static int fm_seterr(struct filemem *restrict const fmp, const int err) {
if (fmp->err == 0) {
@@ -103,9 +130,8 @@ INTERNAL int zint_fm_open(struct filemem *restrict const fmp, struct zint_symbol
#ifdef Z_NO_VSNPRINTF
fmp->fp_null = NULL;
#endif
if (fmp->flags & BARCODE_MEMORY_FILE) {
if (!(fmp->mem = (unsigned char *) malloc(FM_PAGE_SIZE))) {
if (!(fmp->mem = (unsigned char *) (FM_FAIL(FM_FAIL_ID_OPEN, NULL) fm_malloc(FM_PAGE_SIZE)))) {
return fm_seterr(fmp, ENOMEM);
}
#ifdef ZINT_SANITIZEM /* Suppress clang -fsanitize=memory false positive */
@@ -128,7 +154,7 @@ INTERNAL int zint_fm_open(struct filemem *restrict const fmp, struct zint_symbol
fmp->fp = stdout;
return 1;
}
if (!(fmp->fp = zint_out_fopen(symbol->outfile, mode))) {
if (!(fmp->fp = (FM_FAIL_ERRNO(FM_FAIL_ID_OPEN, EACCES, NULL) zint_out_fopen(symbol->outfile, mode)))) {
return fm_seterr(fmp, errno);
}
return 1;
@@ -159,7 +185,7 @@ static int fm_mem_expand(struct filemem *restrict const fmp, const size_t size)
return fm_seterr(fmp, EOVERFLOW);
}
/* Protect against very large files & (Linux) OOM killer - cf `raster_malloc()` in "raster.c" */
if (new_size > 0x40000000 /*1GB*/ || !(new_mem = (unsigned char *) realloc(fmp->mem, new_size))) {
if (new_size > 0x40000000 /*1GB*/ || !(new_mem = (unsigned char *) fm_realloc(fmp->mem, new_size))) {
fm_clear_mem(fmp);
return fm_seterr(fmp, new_size > 0x40000000 ? EINVAL : ENOMEM);
}
@@ -178,12 +204,13 @@ INTERNAL int zint_fm_write(const void *restrict ptr, const size_t size, const si
if (fmp->err) {
return 0;
}
if (size == 0 || nitems == 0) {
return 1;
}
if (fmp->flags & BARCODE_MEMORY_FILE) {
const size_t tot_size = size * nitems;
if (tot_size / size != nitems) {
if ((FM_FAIL(FM_FAIL_ID_WRITE, 0) tot_size / size) != nitems) {
return fm_seterr(fmp, EOVERFLOW);
}
if (!fm_mem_expand(fmp, tot_size)) {
@@ -193,7 +220,7 @@ INTERNAL int zint_fm_write(const void *restrict ptr, const size_t size, const si
fm_setpos(fmp, fmp->mempos + tot_size);
return 1;
}
if (fwrite(ptr, size, nitems, fmp->fp) != nitems) {
if ((FM_FAIL_ERRNO(FM_FAIL_ID_WRITE, EIO, 0) fwrite(ptr, size, nitems, fmp->fp)) != nitems) {
return fm_seterr(fmp, errno);
}
return 1;
@@ -206,14 +233,14 @@ INTERNAL int zint_fm_putc(const int ch, struct filemem *restrict const fmp) {
return 0;
}
if (fmp->flags & BARCODE_MEMORY_FILE) {
if (!fm_mem_expand(fmp, 1)) {
if (!(FM_FAIL_SETERR(FM_FAIL_ID_PUTC, EIO) fm_mem_expand(fmp, 1))) {
return 0;
}
fmp->mem[fmp->mempos] = (unsigned char) ch;
fm_setpos(fmp, fmp->mempos + 1);
return 1;
}
if (fputc(ch, fmp->fp) == EOF) {
if ((FM_FAIL_ERRNO(FM_FAIL_ID_PUTC, EIO, EOF) fputc(ch, fmp->fp)) == EOF) {
return fm_seterr(fmp, errno);
}
return 1;
@@ -227,14 +254,14 @@ INTERNAL int zint_fm_puts(const char *str, struct filemem *restrict const fmp) {
}
if (fmp->flags & BARCODE_MEMORY_FILE) {
const size_t len = strlen(str);
if (!fm_mem_expand(fmp, len)) {
if (!(FM_FAIL_SETERR(FM_FAIL_ID_PUTS, EIO) fm_mem_expand(fmp, len))) {
return 0;
}
memcpy(fmp->mem + fmp->mempos, str, len);
fm_setpos(fmp, fmp->mempos + len);
return 1;
}
if (fputs(str, fmp->fp) == EOF) {
if ((FM_FAIL_ERRNO(FM_FAIL_ID_PUTS, EIO, EOF) fputs(str, fmp->fp)) == EOF) {
return fm_seterr(fmp, errno);
}
return 1;
@@ -301,12 +328,12 @@ INTERNAL int zint_fm_printf(struct filemem *restrict const fmp, const char *fmt,
}
if (fmp->flags & BARCODE_MEMORY_FILE) {
va_start(ap, fmt);
ret = fm_vprintf(fmp, fmt, ap);
ret = (FM_FAIL_SETERR(FM_FAIL_ID_PRINTF, EIO) fm_vprintf(fmp, fmt, ap));
va_end(ap);
return ret;
}
va_start(ap, fmt);
ret = vfprintf(fmp->fp, fmt, ap) >= 0;
ret = (FM_FAIL_ERRNO(FM_FAIL_ID_PRINTF, EIO, -1) vfprintf(fmp->fp, fmt, ap)) >= 0;
va_end(ap);
return ret ? 1 : fm_seterr(fmp, errno);
}
@@ -323,8 +350,8 @@ INTERNAL int zint_fm_putsf(const char *prefix, const int dp, const float arg, st
return 0;
}
if (prefix && *prefix) {
if (!zint_fm_puts(prefix, fmp)) {
return 0;
if (!(FM_FAIL_ERRNO(FM_FAIL_ID_PUTSF, EIO, 0) zint_fm_puts(prefix, fmp))) {
return fm_seterr(fmp, errno);
}
}
@@ -345,7 +372,10 @@ INTERNAL int zint_fm_putsf(const char *prefix, const int dp, const float arg, st
}
}
return zint_fm_puts(buf, fmp);
if (!(FM_FAIL_ERRNO(FM_FAIL_ID_PUTSF, EIO, 0) zint_fm_puts(buf, fmp))) {
return fm_seterr(fmp, errno);
}
return 1;
}
/* `fclose()` if file, set `symbol->memfile` & `symbol->memfile_size` if memory, returning 1 on success, 0 on
@@ -358,7 +388,7 @@ INTERNAL int zint_fm_close(struct filemem *restrict const fmp, struct zint_symbo
return fm_seterr(fmp, EINVAL);
}
symbol->memfile_size = (int) fmp->mempos;
if ((size_t) symbol->memfile_size != fmp->mempos) {
if ((size_t) (FM_FAIL(FM_FAIL_ID_CLOSE, 0) symbol->memfile_size) != fmp->mempos) {
fm_clear_mem(fmp);
symbol->memfile_size = 0;
return fm_seterr(fmp, EINVAL);
@@ -375,12 +405,12 @@ INTERNAL int zint_fm_close(struct filemem *restrict const fmp, struct zint_symbo
return fm_seterr(fmp, EINVAL);
}
if (fmp->flags & BARCODE_STDOUT) {
if (fflush(fmp->fp) != 0) {
if ((FM_FAIL_ERRNO(FM_FAIL_ID_CLOSE, EIO, EOF) fflush(fmp->fp)) != 0) {
fmp->fp = NULL;
return fm_seterr(fmp, errno);
}
} else {
if (fclose(fmp->fp) != 0) {
if ((FM_FAIL_ERRNO(FM_FAIL_ID_CLOSE, EIO, EOF) fclose(fmp->fp)) != 0) {
fmp->fp = NULL;
return fm_seterr(fmp, errno);
}
@@ -398,7 +428,8 @@ INTERNAL int zint_fm_seek(struct filemem *restrict const fmp, const long offset,
if (fmp->flags & BARCODE_MEMORY_FILE) {
const size_t start = whence == SEEK_SET ? 0 : whence == SEEK_CUR ? fmp->mempos : fmp->memend;
const size_t new_pos = start + offset;
if ((offset > 0 && new_pos <= start) || (offset < 0 && new_pos >= start)) { /* Check for over/underflow */
/* Check for over/underflow */
if ((FM_FAIL(FM_FAIL_ID_SEEK, 1) (offset > 0 && new_pos <= start) || (offset < 0 && new_pos >= start))) {
return fm_seterr(fmp, EINVAL);
}
if (!fm_mem_expand(fmp, new_pos)) {
@@ -407,7 +438,7 @@ INTERNAL int zint_fm_seek(struct filemem *restrict const fmp, const long offset,
fm_setpos(fmp, new_pos);
return 1;
}
if (fseek(fmp->fp, offset, whence) != 0) {
if ((FM_FAIL_ERRNO(FM_FAIL_ID_SEEK, EOVERFLOW, EOF) fseek(fmp->fp, offset, whence)) != 0) {
return fm_seterr(fmp, errno);
}
return 1;
@@ -421,13 +452,13 @@ INTERNAL long zint_fm_tell(struct filemem *restrict const fmp) {
return -1;
}
if (fmp->flags & BARCODE_MEMORY_FILE) {
if (!fmp->mem) {
if (!(FM_FAIL(FM_FAIL_ID_TELL, NULL) fmp->mem)) {
(void) fm_seterr(fmp, ENOMEM);
return -1;
}
return (long) fmp->mempos;
}
ret = ftell(fmp->fp);
ret = (FM_FAIL_ERRNO(FM_FAIL_ID_TELL, EOVERFLOW, -1) ftell(fmp->fp));
/* On many Linux distros `ftell()` returns LONG_MAX not -1 on error */
if (ret < 0 || ret == LONG_MAX) {
(void) fm_seterr(fmp, errno);
@@ -453,12 +484,12 @@ INTERNAL int zint_fm_flush(struct filemem *restrict const fmp) {
return 0;
}
if (fmp->flags & BARCODE_MEMORY_FILE) {
if (!fmp->mem) {
if (!(FM_FAIL(FM_FAIL_ID_FLUSH, 0) fmp->mem)) {
return fm_seterr(fmp, EINVAL);
}
return 1;
}
if (fflush(fmp->fp) == EOF) {
if ((FM_FAIL_ERRNO(FM_FAIL_ID_FLUSH, EIO, EOF) fflush(fmp->fp)) == EOF) {
return fm_seterr(fmp, errno);
}
return 1;