Skip to content

Commit 62a40c0

Browse files
committed
libs: Robustness updates for Windows
1 parent 9dc24b2 commit 62a40c0

5 files changed

Lines changed: 111 additions & 16 deletions

File tree

.github/workflows/ci.yml

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,18 @@ jobs:
4343
- name: Test
4444
run: make test
4545

46+
- name: Create CRLF copy of barcode.ps
47+
run: sed 's/$/\r/' build/monolithic/barcode.ps > build/monolithic/barcode_crlf.ps
48+
49+
- name: Store monolithic barcode.ps
50+
uses: actions/upload-artifact@v4
51+
with:
52+
name: monolithic-barcode-ps
53+
path: |
54+
build/monolithic/barcode.ps
55+
build/monolithic/barcode_crlf.ps
56+
retention-days: 1
57+
4658
#
4759
# C library CI
4860
#
@@ -103,6 +115,49 @@ jobs:
103115
make -C libs/c -j "$(nproc)" test CC=gcc
104116
make -C libs/c test-valgrind
105117
118+
ci-windows:
119+
120+
needs: ci
121+
122+
runs-on: windows-latest
123+
124+
steps:
125+
- uses: actions/checkout@v6
126+
with:
127+
persist-credentials: false
128+
129+
- uses: ilammy/msvc-dev-cmd@v1
130+
with:
131+
arch: x64
132+
133+
- name: Load barcode.ps
134+
uses: actions/download-artifact@v4
135+
with:
136+
name: monolithic-barcode-ps
137+
path: build/monolithic
138+
139+
- name: MSVC build
140+
working-directory: libs/c
141+
run: |
142+
cl /W4 /WX /Od /Zi ^
143+
/D_CRT_SECURE_NO_WARNINGS ^
144+
postscriptbarcode.c ^
145+
postscriptbarcode_test.c ^
146+
/Fe:postscriptbarcode_test.exe
147+
shell: cmd
148+
149+
- name: Test with LF barcode.ps
150+
working-directory: libs/c
151+
run: postscriptbarcode_test.exe
152+
shell: cmd
153+
154+
- name: Test with CRLF barcode.ps
155+
working-directory: libs/c
156+
run: |
157+
copy /Y ..\..\build\monolithic\barcode_crlf.ps ..\..\build\monolithic\barcode.ps
158+
postscriptbarcode_test.exe
159+
shell: cmd
160+
106161
ci-scan-build:
107162

108163
runs-on: ubuntu-24.04
@@ -233,6 +288,7 @@ jobs:
233288
- ci
234289
- ci-clang
235290
- ci-gcc
291+
- ci-windows
236292
- ci-valgrind
237293
- ci-scan-build
238294
- ci-bindings

libs/c/Makefile

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ TEST_STATIC = $(NAME)_test_static
6060
PREFIX = /usr/local
6161
LIBDIR = $(PREFIX)/lib
6262

63-
.PHONY: default all clean lib libstatic libshared test test-valgrind fuzzer fuzzer-corpus-seeds clean-fuzzer-corpus install install-static install-shared uninstall
63+
.PHONY: default all clean lib libstatic libshared test test-static test-valgrind fuzzer fuzzer-corpus-seeds clean-fuzzer-corpus install install-static install-shared uninstall
6464

6565
default: lib
6666
all: default test
@@ -95,6 +95,9 @@ test: $(TEST_SHARED) $(TEST_STATIC)
9595
$(SAN_ENV) LD_LIBRARY_PATH=.:$$LD_LIBRARY_PATH ./$(TEST_SHARED)
9696
$(SAN_ENV) ./$(TEST_STATIC)
9797

98+
test-static: $(TEST_STATIC)
99+
$(SAN_ENV) ./$(TEST_STATIC)
100+
98101
# Valgrind: full memory checking with leak detection.
99102
# Mutually exclusive with ASAN/MSAN.
100103
#

libs/c/postscriptbarcode.c

Lines changed: 36 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -168,8 +168,9 @@ static const Resource *get_resource(BWIPP *ctx, const char *name) {
168168
}
169169

170170
/* Read resource body from file on demand; returns NULL on I/O error */
171-
static char *load_code(BWIPP *ctx, const Resource *resource) {
171+
static char *load_code(BWIPP *ctx, const Resource *resource, size_t *out_len) {
172172
char *code;
173+
size_t i, j;
173174

174175
if (resource->code_offset < 0 || !ctx->f)
175176
return NULL;
@@ -188,7 +189,14 @@ static char *load_code(BWIPP *ctx, const Resource *resource) {
188189
return NULL;
189190
}
190191

191-
code[resource->code_len] = '\0';
192+
/* Strip \r from CRLF sequences (file opened in binary mode) */
193+
for (i = 0, j = 0; i < resource->code_len; i++) {
194+
if (code[i] != '\r' || i + 1 >= resource->code_len || code[i + 1] != '\n')
195+
code[j++] = code[i];
196+
}
197+
code[j] = '\0';
198+
*out_len = j;
199+
192200
return code;
193201
}
194202

@@ -373,7 +381,7 @@ BWIPP_API BWIPP *bwipp_load_ex(const bwipp_load_init_opts_t *opts) {
373381
ctx->hexify_width = hexify_width;
374382
tail = &ctx->resourcelist;
375383

376-
f = fopen(filename, "r");
384+
f = fopen(filename, "rb");
377385
if (!f)
378386
goto error;
379387

@@ -386,6 +394,14 @@ BWIPP_API BWIPP *bwipp_load_ex(const bwipp_load_init_opts_t *opts) {
386394
skip = true;
387395
while (fgets(buf, sizeof buf, f)) {
388396
size_t line_len = strlen(buf);
397+
size_t raw_len = line_len;
398+
399+
/* Strip \r from CRLF (binary mode preserves \r) */
400+
if (line_len >= 2 && buf[line_len - 2] == '\r' && buf[line_len - 1] == '\n') {
401+
buf[line_len - 2] = '\n';
402+
buf[line_len - 1] = '\0';
403+
line_len--;
404+
}
389405

390406
/* Reject marker lines truncated by fgets */
391407
if (strncmp(buf, "% --", 4) == 0 &&
@@ -453,6 +469,8 @@ BWIPP_API BWIPP *bwipp_load_ex(const bwipp_load_init_opts_t *opts) {
453469
*code = '\0';
454470
code_len = 0;
455471
code_start = ftell(f);
472+
if (code_start < 0)
473+
goto error;
456474

457475
continue;
458476

@@ -478,6 +496,8 @@ BWIPP_API BWIPP *bwipp_load_ex(const bwipp_load_init_opts_t *opts) {
478496
if (!add_property(resource, key, value))
479497
goto error;
480498
code_start = ftell(f);
499+
if (code_start < 0)
500+
goto error;
481501
continue;
482502
}
483503
}
@@ -501,6 +521,8 @@ BWIPP_API BWIPP *bwipp_load_ex(const bwipp_load_init_opts_t *opts) {
501521
goto error;
502522

503523
code_start = ftell(f);
524+
if (code_start < 0)
525+
goto error;
504526
continue;
505527

506528
} /* REQUIRES */
@@ -531,15 +553,19 @@ BWIPP_API BWIPP *bwipp_load_ex(const bwipp_load_init_opts_t *opts) {
531553
goto error;
532554

533555
if (lazy) {
556+
long end_pos = ftell(f);
557+
if (end_pos < 0)
558+
goto error;
534559
resource->code = NULL;
535560
resource->code_offset = code_start;
561+
resource->code_len = (size_t)(end_pos - (long)raw_len - code_start);
536562
} else {
537563
resource->code = strdup(code);
538564
if (!resource->code)
539565
goto error;
540566
*code = '\0';
567+
resource->code_len = code_len;
541568
}
542-
resource->code_len = code_len;
543569
code_len = 0;
544570

545571
/* Add to ResourceList */
@@ -563,13 +589,9 @@ BWIPP_API BWIPP *bwipp_load_ex(const bwipp_load_init_opts_t *opts) {
563589
} /* END */
564590

565591
/* PS Code */
566-
if (resource) {
567-
if (lazy) {
568-
code_len += line_len;
569-
} else {
570-
if (!safe_append_n(code, &code_len, MAX_CODE, buf, line_len))
571-
goto error;
572-
}
592+
if (resource && !lazy) {
593+
if (!safe_append_n(code, &code_len, MAX_CODE, buf, line_len))
594+
goto error;
573595
}
574596
}
575597

@@ -862,11 +884,12 @@ static bool append_resource_code(BWIPP *ctx, const Resource *res,
862884
if (res->code) {
863885
return safe_append_n(buf, pos, capacity, res->code, res->code_len);
864886
} else {
865-
char *lazy_code = load_code(ctx, res);
887+
size_t len;
888+
char *lazy_code = load_code(ctx, res, &len);
866889
bool ok;
867890
if (!lazy_code)
868891
return false;
869-
ok = safe_append_n(buf, pos, capacity, lazy_code, res->code_len);
892+
ok = safe_append_n(buf, pos, capacity, lazy_code, len);
870893
free(lazy_code);
871894
return ok;
872895
}

libs/c/postscriptbarcode_private.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,11 @@
3636
#include "postscriptbarcode.h"
3737
#include <stddef.h>
3838

39+
#ifdef _MSC_VER
40+
#define strdup _strdup
41+
#define strtok_r strtok_s
42+
#endif
43+
3944
typedef struct Property {
4045
char *key, *value;
4146
} Property;

libs/c/postscriptbarcode_test.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ static BWIPP *load_from(const char *filename) {
6868

6969

7070
static void write_mock_ps(const char *filename, const char *content) {
71-
FILE *f = fopen(filename, "w");
71+
FILE *f = fopen(filename, "wb");
7272
if (!f) {
7373
perror(filename);
7474
abort();
@@ -584,7 +584,7 @@ static void test_load_long_requires_line(void) {
584584
BWIPP *ctx;
585585
FILE *f;
586586

587-
f = fopen(MOCK_PS, "w");
587+
f = fopen(MOCK_PS, "wb");
588588
if (!f) abort();
589589
fputs("%!PS\n", f);
590590
fputs("% Barcode Writer in Pure PostScript - Version 2099-01-01\n", f);
@@ -2447,6 +2447,7 @@ static void test_real_load(void) {
24472447

24482448
TEST_CHECK(bwipp_get_version(ctx) != NULL);
24492449
TEST_CHECK(strlen(bwipp_get_version(ctx)) >= 10);
2450+
TEST_CHECK(strchr(bwipp_get_version(ctx), '\r') == NULL);
24502451

24512452
bwipp_unload(ctx);
24522453
}
@@ -2464,11 +2465,13 @@ static void test_real_emit_required(void) {
24642465
/* Resource with dependencies */
24652466
TEST_CHECK((out = bwipp_emit_required_resources(ctx, "code39ext")) != NULL);
24662467
TEST_CHECK(strlen(out) > 0);
2468+
TEST_CHECK(strchr(out, '\r') == NULL);
24672469
bwipp_free(out);
24682470

24692471
/* Resource without dependencies */
24702472
TEST_CHECK((out = bwipp_emit_required_resources(ctx, "preamble")) != NULL);
24712473
TEST_CHECK(strlen(out) > 0);
2474+
TEST_CHECK(strchr(out, '\r') == NULL);
24722475
bwipp_free(out);
24732476

24742477
/* Missing resource */
@@ -2491,6 +2494,7 @@ static void test_real_emit_all(void) {
24912494

24922495
TEST_CHECK((out = bwipp_emit_all_resources(ctx)) != NULL);
24932496
TEST_CHECK(strlen(out) > 100000);
2497+
TEST_CHECK(strchr(out, '\r') == NULL);
24942498
bwipp_free(out);
24952499

24962500
bwipp_unload(ctx);
@@ -2656,6 +2660,8 @@ static void test_real_lazy_emit_required(void) {
26562660
TEST_ASSERT(lazy_out != NULL);
26572661

26582662
TEST_CHECK(strcmp(eager_out, lazy_out) == 0);
2663+
TEST_CHECK(strchr(eager_out, '\r') == NULL);
2664+
TEST_CHECK(strchr(lazy_out, '\r') == NULL);
26592665

26602666
bwipp_free(eager_out);
26612667
bwipp_free(lazy_out);
@@ -2686,6 +2692,8 @@ static void test_real_lazy_emit_all(void) {
26862692
TEST_ASSERT(lazy_out != NULL);
26872693

26882694
TEST_CHECK(strcmp(eager_out, lazy_out) == 0);
2695+
TEST_CHECK(strchr(eager_out, '\r') == NULL);
2696+
TEST_CHECK(strchr(lazy_out, '\r') == NULL);
26892697

26902698
bwipp_free(eager_out);
26912699
bwipp_free(lazy_out);

0 commit comments

Comments
 (0)