From 3950b49050e9088ca8c23eec7667a3c2988d256d Mon Sep 17 00:00:00 2001
From: gitlost
Date: Fri, 29 Dec 2023 19:34:44 +0000
Subject: [PATCH] filemem: fix `fwrite()` return check in `fm_write()`; test
`ferror()` also in `fm_err()` if `err` zero and file NetBSD: add instructions
and some workarounds (`getopt_long_only()` in particular) qzint: check
`__GNUC__` version for "-Wstringop-truncation" suppression
---
README.bsd | 18 +++++++++++++++++-
backend/filemem.c | 12 ++++++------
backend/filemem.h | 2 +-
backend/ps.c | 13 +++++++------
backend/tests/test_library.c | 8 +++++++-
backend/tests/test_output.c | 4 ++--
backend_qt/qzint.cpp | 2 +-
docs/manual.html | 4 ++--
docs/manual.pmd | 3 ++-
docs/manual.txt | 3 ++-
frontend/main.c | 21 ++++++++++++++-------
frontend/tests/test_args.c | 3 +++
12 files changed, 64 insertions(+), 29 deletions(-)
diff --git a/README.bsd b/README.bsd
index 79adf273..2654381f 100644
--- a/README.bsd
+++ b/README.bsd
@@ -1,4 +1,4 @@
-% Tested on FreeBSD 13.2-RELEASE (with X11 + GNOME installed) and OpenBSD 7.3 (with X11)
+% Tested on FreeBSD 14.0-RELEASE (with X11 + GNOME installed), OpenBSD 7.4 (with X11) and NetBSD 9.3 (with X11)
1. Prerequisites for building zint
==================================
@@ -15,6 +15,12 @@ or OpenBSD (make and clang should already be installed):
pkg_add git cmake png
exit
+or NetBSD (make and gcc should already be installed):
+
+ su
+ pkgin install git cmake png
+ exit
+
Then clone the latest source
git clone https://git.code.sf.net/p/zint/code zint
@@ -36,6 +42,12 @@ On OpenBSD:
pkg_add qtbase qttools qtsvg
exit
+On NetBSD:
+
+ su
+ pkgin install qt5-qtbase qt5-qttools qt5-qtsvg
+ exit
+
3. Build
========
@@ -54,6 +66,10 @@ except that on OpenBSD you need to use
cmake -DCMAKE_PREFIX_PATH=/usr/local/lib/qt5/cmake ..
+and on NetBSD
+
+ cmake -DCMAKE_PREFIX_PATH=/usr/pkg/qt5 ..
+
instead.
diff --git a/backend/filemem.c b/backend/filemem.c
index c6e2175a..6fad2bf3 100644
--- a/backend/filemem.c
+++ b/backend/filemem.c
@@ -187,7 +187,7 @@ INTERNAL int fm_write(const void *restrict ptr, const size_t size, const size_t
fm_setpos(fmp, fmp->mempos + tot_size);
return 1;
}
- if (fwrite(ptr, size, nitems, fmp->fp) == 0) {
+ if (fwrite(ptr, size, nitems, fmp->fp) != nitems) {
return fm_seterr(fmp, errno);
}
return 1;
@@ -304,11 +304,8 @@ INTERNAL int fm_printf(struct filemem *restrict const fmp, const char *fmt, ...)
}
va_start(ap, fmt);
ret = vfprintf(fmp->fp, fmt, ap) >= 0; /* NOLINT(clang-analyzer-valist.Uninitialized) - see above */
- if (!ret) {
- (void) fm_seterr(fmp, errno);
- }
va_end(ap);
- return ret != 0;
+ return ret ? 1 : fm_seterr(fmp, errno);
}
/* Output float without trailing zeroes to `fmp` with decimal pts `dp` (precision), returning 1 on success, 0 on
@@ -436,9 +433,12 @@ INTERNAL long fm_tell(struct filemem *restrict const fmp) {
return ret;
}
-/* Return `err`, which uses `errno` values */
+/* Return `err`, which uses `errno` values; if file and `err` not set, test `ferror()` also */
INTERNAL int fm_error(struct filemem *restrict const fmp) {
assert(fmp);
+ if (fmp->err == 0 && !(fmp->flags & BARCODE_MEMORY_FILE) && ferror(fmp->fp)) {
+ (void) fm_seterr(fmp, EIO);
+ }
return fmp->err;
}
diff --git a/backend/filemem.h b/backend/filemem.h
index e79e1647..74704ecd 100644
--- a/backend/filemem.h
+++ b/backend/filemem.h
@@ -84,7 +84,7 @@ INTERNAL int fm_seek(struct filemem *restrict const fmp, const long offset, cons
/* `ftell()` returns current file/memory offset if successful, -1 on failure */
INTERNAL long fm_tell(struct filemem *restrict const fmp);
-/* Return `err`, which uses `errno` values */
+/* Return `err`, which uses `errno` values; if file and `err` not set, test `ferror()` also */
INTERNAL int fm_error(struct filemem *restrict const fmp);
/* `fflush()` if file, no-op if memory, returning 1 on success, 0 on failure
diff --git a/backend/ps.c b/backend/ps.c
index 834b18ed..21ffd71c 100644
--- a/backend/ps.c
+++ b/backend/ps.c
@@ -263,17 +263,18 @@ INTERNAL int ps_plot(struct zint_symbol *symbol) {
}
/* Start writing the header */
- fm_puts("%!PS-Adobe-3.0 EPSF-3.0\n", fmp);
+ fm_puts("%!PS-Adobe-3.0 EPSF-3.0\n"
+ "%%Creator: Zint ", fmp);
if (ZINT_VERSION_BUILD) {
- fm_printf(fmp, "%%%%Creator: Zint %d.%d.%d.%d\n",
+ fm_printf(fmp, "%d.%d.%d.%d\n",
ZINT_VERSION_MAJOR, ZINT_VERSION_MINOR, ZINT_VERSION_RELEASE, ZINT_VERSION_BUILD);
} else {
- fm_printf(fmp, "%%%%Creator: Zint %d.%d.%d\n", ZINT_VERSION_MAJOR, ZINT_VERSION_MINOR, ZINT_VERSION_RELEASE);
+ fm_printf(fmp, "%d.%d.%d\n", ZINT_VERSION_MAJOR, ZINT_VERSION_MINOR, ZINT_VERSION_RELEASE);
}
fm_puts("%%Title: Zint Generated Symbol\n"
- "%%Pages: 0\n", fmp);
- fm_printf(fmp, "%%%%BoundingBox: 0 0 %d %d\n",
- (int) ceilf(symbol->vector->width), (int) ceilf(symbol->vector->height));
+ "%%Pages: 0\n"
+ "%%BoundingBox: 0 0 ", fmp);
+ fm_printf(fmp, "%d %d\n", (int) ceilf(symbol->vector->width), (int) ceilf(symbol->vector->height));
fm_puts("%%EndComments\n", fmp);
/* Definitions */
diff --git a/backend/tests/test_library.c b/backend/tests/test_library.c
index 112407d1..83803b76 100644
--- a/backend/tests/test_library.c
+++ b/backend/tests/test_library.c
@@ -34,7 +34,6 @@
#include
#include
#include "testcommon.h"
-#include "../common.h"
static void test_checks(const testCtx *const p_ctx) {
int debug = p_ctx->debug;
@@ -946,14 +945,20 @@ static void test_encode_file_unreadable(const testCtx *const p_ctx) {
/* #181 Nico Gunkel OSS-Fuzz (buffer not freed on fread() error) Note: unable to reproduce fread() error using this method */
static void test_encode_file_directory(const testCtx *const p_ctx) {
+#ifndef __NetBSD__
int ret;
struct zint_symbol *symbol;
char dirname[] = "in_dir";
+#endif
(void)p_ctx;
testStart("test_encode_file_directory");
+#ifdef __NetBSD__
+ /* Reading a directory works on NetBSD, and get `code128()` ZINT_ERROR_TOO_LONG instead */
+ testSkip("Test not implemented on NetBSD");
+#else
symbol = ZBarcode_Create();
assert_nonnull(symbol, "Symbol not created\n");
@@ -970,6 +975,7 @@ static void test_encode_file_directory(const testCtx *const p_ctx) {
ZBarcode_Delete(symbol);
testFinish();
+#endif /* __NetBSD__ */
}
static void test_encode_file(const testCtx *const p_ctx) {
diff --git a/backend/tests/test_output.c b/backend/tests/test_output.c
index 18159337..8e1718ce 100644
--- a/backend/tests/test_output.c
+++ b/backend/tests/test_output.c
@@ -123,7 +123,7 @@ static void test_colour_get_rgb(const testCtx *const p_ctx) {
unsigned char red = 0, green = 0, blue = 0, alpha = 0, rgb_alpha = 0;
int cyan, magenta, yellow, black;
int have_alpha;
- char rgb[9];
+ char rgb[16];
char cmyk[16];
if (testContinue(p_ctx, i)) continue;
@@ -181,7 +181,7 @@ static void test_colour_get_cmyk(const testCtx *const p_ctx) {
for (i = 0; i < data_size; i++) {
int cyan, magenta, yellow, black;
unsigned char red, green, blue, alpha, rgb_alpha;
- char rgb[9];
+ char rgb[16];
if (testContinue(p_ctx, i)) continue;
diff --git a/backend_qt/qzint.cpp b/backend_qt/qzint.cpp
index 6728802d..35b589d9 100644
--- a/backend_qt/qzint.cpp
+++ b/backend_qt/qzint.cpp
@@ -464,7 +464,7 @@ namespace Zint {
memset(m_structapp.id, 0, sizeof(m_structapp.id));
if (!id.isEmpty()) {
QByteArray idArr = id.toLatin1();
-#if defined(__GNUC__) && !defined(__clang__)
+#if defined(__GNUC__) && __GNUC__ >= 8 && !defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wstringop-truncation"
#endif
diff --git a/docs/manual.html b/docs/manual.html
index 8f369c9b..b78a7935 100644
--- a/docs/manual.html
+++ b/docs/manual.html
@@ -946,8 +946,8 @@ package):
class="sourceCode bash">su
pkg_add zint zint-gui
exit
-To build from source see "README.bsd"
in the project
-root directory.
+To build from source (including for NetBSD) see
+"README.bsd"
in the project root directory.
2.3 Microsoft Windows
For Microsoft Windows, Zint is distributed as a binary executable.
Simply download the ZIP file, then right-click on the ZIP file and
diff --git a/docs/manual.pmd b/docs/manual.pmd
index f0c80e21..e8aba36f 100644
--- a/docs/manual.pmd
+++ b/docs/manual.pmd
@@ -193,7 +193,8 @@ pkg_add zint zint-gui
exit
```
-To build from source see `"README.bsd"` in the project root directory.
+To build from source (including for NetBSD) see `"README.bsd"` in the project
+root directory.
## 2.3 Microsoft Windows
diff --git a/docs/manual.txt b/docs/manual.txt
index 2b66257a..3e03200c 100644
--- a/docs/manual.txt
+++ b/docs/manual.txt
@@ -375,7 +375,8 @@ and on OpenBSD (where the GUI is in a separate zint-gui package):
pkg_add zint zint-gui
exit
-To build from source see "README.bsd" in the project root directory.
+To build from source (including for NetBSD) see "README.bsd" in the project root
+directory.
2.3 Microsoft Windows
diff --git a/frontend/main.c b/frontend/main.c
index 92d93eaf..82f64ccf 100644
--- a/frontend/main.c
+++ b/frontend/main.c
@@ -26,20 +26,27 @@
#include
#ifndef _MSC_VER
-#include
-#include
+# include
+# ifdef __NetBSD__ /* `getopt_long_only()` not available */
+# define getopt_long_only getopt_long
+# endif
+# include
#else
-#include "../getopt/getopt.h"
-#include "zint.h"
-#if _MSC_VER != 1200 /* VC6 */
-#pragma warning(disable: 4996) /* function or variable may be unsafe */
-#endif
+# include "../getopt/getopt.h"
+# include "zint.h"
+# if _MSC_VER != 1200 /* VC6 */
+# pragma warning(disable: 4996) /* function or variable may be unsafe */
+# endif
#endif /* _MSC_VER */
+/* Following copied from "backend/library.c" */
+
/* It's assumed that int is at least 32 bits, the following will compile-time fail if not
* https://stackoverflow.com/a/1980056 */
typedef char static_assert_int_at_least_32bits[sizeof(int) * CHAR_BIT < 32 ? -1 : 1];
+/* Following copied from "backend/common.h" */
+
#ifndef ARRAY_SIZE
#define ARRAY_SIZE(x) ((int) (sizeof(x) / sizeof((x)[0])))
#endif
diff --git a/frontend/tests/test_args.c b/frontend/tests/test_args.c
index d9f67c2f..47b85d99 100644
--- a/frontend/tests/test_args.c
+++ b/frontend/tests/test_args.c
@@ -1245,6 +1245,9 @@ static void test_other_opts(const testCtx *const p_ctx) {
for (i = 0; i < data_size; i++) {
if (testContinue(p_ctx, i)) continue;
+#ifdef __NetBSD__
+ if (strcmp(data[i].opt, " -bg=") == 0) continue; /* `getopt_long_only()` not available on NetBSD */
+#endif
strcpy(cmd, "zint");