pkgsrc-WIP-changes archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
dillo: Avoid ctype(3) abuses
Module Name: pkgsrc-wip
Committed By: Leonardo Taccari <leot%NetBSD.org@localhost>
Pushed By: leot
Date: Tue Jan 6 17:52:57 2026 +0100
Changeset: 56c2d8c5750bae4eed57ca96c814a70ef78d5d29
Modified Files:
dillo/Makefile
dillo/distinfo
Added Files:
dillo/patches/patch-dlib_dlib.c
dillo/patches/patch-dpi_bookmarks.c
dillo/patches/patch-dpi_cookies.c
dillo/patches/patch-dpi_downloads.cc
dillo/patches/patch-dpi_dpiutil.c
dillo/patches/patch-dpid_dpidc.c
dillo/patches/patch-dpip_dpip.c
dillo/patches/patch-dw_findtext.hh
dillo/patches/patch-dw_fltkui.cc
dillo/patches/patch-dw_textblock.cc
dillo/patches/patch-src_IO_dpi.c
dillo/patches/patch-src_IO_http.c
dillo/patches/patch-src_IO_tls__openssl.c
dillo/patches/patch-src_cssparser.cc
dillo/patches/patch-src_hsts.c
dillo/patches/patch-src_html.cc
dillo/patches/patch-src_keys.cc
dillo/patches/patch-src_table.cc
dillo/patches/patch-test_unit_cookies.c
Log Message:
dillo: Avoid ctype(3) abuses
Now dillo seems to being able to loads <https://www.NetBSD.org/>.
Mechanically inspected via a grep and changed all matching abuses
(The only ctype(3) functions left should already take unsigned char-s)
To see a diff of this commit:
https://wip.pkgsrc.org/cgi-bin/gitweb.cgi?p=pkgsrc-wip.git;a=commitdiff;h=56c2d8c5750bae4eed57ca96c814a70ef78d5d29
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
diffstat:
dillo/Makefile | 2 +-
dillo/distinfo | 19 +++
dillo/patches/patch-dlib_dlib.c | 15 +++
dillo/patches/patch-dpi_bookmarks.c | 112 +++++++++++++++
dillo/patches/patch-dpi_cookies.c | 63 +++++++++
dillo/patches/patch-dpi_downloads.cc | 40 ++++++
dillo/patches/patch-dpi_dpiutil.c | 20 +++
dillo/patches/patch-dpid_dpidc.c | 15 +++
dillo/patches/patch-dpip_dpip.c | 15 +++
dillo/patches/patch-dw_findtext.hh | 17 +++
dillo/patches/patch-dw_fltkui.cc | 23 ++++
dillo/patches/patch-dw_textblock.cc | 41 ++++++
dillo/patches/patch-src_IO_dpi.c | 15 +++
dillo/patches/patch-src_IO_http.c | 15 +++
dillo/patches/patch-src_IO_tls__openssl.c | 32 +++++
dillo/patches/patch-src_cssparser.cc | 83 ++++++++++++
dillo/patches/patch-src_hsts.c | 15 +++
dillo/patches/patch-src_html.cc | 217 ++++++++++++++++++++++++++++++
dillo/patches/patch-src_keys.cc | 24 ++++
dillo/patches/patch-src_table.cc | 15 +++
dillo/patches/patch-test_unit_cookies.c | 15 +++
21 files changed, 812 insertions(+), 1 deletion(-)
diffs:
diff --git a/dillo/Makefile b/dillo/Makefile
index 48c54df9d0..63950a7b2a 100644
--- a/dillo/Makefile
+++ b/dillo/Makefile
@@ -1,7 +1,7 @@
# $NetBSD: Makefile,v 1.97 2025/12/01 08:09:06 wiz Exp $
DISTNAME= dillo-3.2.0
-PKGREVISION= 3
+PKGREVISION= 4
CATEGORIES= www
MASTER_SITES= ${MASTER_SITE_GITHUB:=dillo-browser/}
GITHUB_TAG= v${PKGVERSION_NOREV}
diff --git a/dillo/distinfo b/dillo/distinfo
index 68c0a31aec..e0e0e8b86a 100644
--- a/dillo/distinfo
+++ b/dillo/distinfo
@@ -5,3 +5,22 @@ SHA512 (dillo-3.2.0.tar.gz) = ff6aa64c79a5dac3bd5152e7501a20c129924c20df712003fc
Size (dillo-3.2.0.tar.gz) = 1459110 bytes
SHA1 (patch-configure.ac) = 9e3e7297b559dc70a3b1b61416bf1e97eeb23ca0
SHA1 (patch-dillo-install-hyphenation) = 27f3a481da421a691c4c39093f010c01abee2515
+SHA1 (patch-dlib_dlib.c) = 63a2a9670af13cabed6f68c996c8e9497cb333fb
+SHA1 (patch-dpi_bookmarks.c) = d8dbfa28245a7bb7a884a7f18f47385abcee8140
+SHA1 (patch-dpi_cookies.c) = a7142770a7153b0a3a99132d73c5bb11d5de1883
+SHA1 (patch-dpi_downloads.cc) = 824182b56b8fffc9e59432f30d55067b25faac6b
+SHA1 (patch-dpi_dpiutil.c) = 24740dd6565f05eeacad4ef9f1ae450e20802eaf
+SHA1 (patch-dpid_dpidc.c) = 490ab7ec838a4d55d31f8f6bf24b9e80fdab8c22
+SHA1 (patch-dpip_dpip.c) = 29580c3a341d8ad2fca8daa1d968f3d95b4a1ef0
+SHA1 (patch-dw_findtext.hh) = 6004172c7d54cdd52ac1989c248915c3b1d97dec
+SHA1 (patch-dw_fltkui.cc) = 15475a5945aab011ce418618b63c08345436c115
+SHA1 (patch-dw_textblock.cc) = f55c6089eacaefe2097faeae859f8897b0644c1c
+SHA1 (patch-src_IO_dpi.c) = f2ceb7b12e3585a34270b4b26d884cecb654df4e
+SHA1 (patch-src_IO_http.c) = b6740271b12de05f1f24ac506628c1d23e812d9e
+SHA1 (patch-src_IO_tls__openssl.c) = 8369c4db0396b6621793a2e0ff4a20e0a0b2e042
+SHA1 (patch-src_cssparser.cc) = 28a6df949326ef2cc715e5dc0777c5bf931ef808
+SHA1 (patch-src_hsts.c) = 4d149f63968d302c465e1a3475f7ae0c385a2623
+SHA1 (patch-src_html.cc) = c006757fc4590816fc7caac667df80681550424e
+SHA1 (patch-src_keys.cc) = c14d579ae20c54cc13444144f7bb956c9f5f43db
+SHA1 (patch-src_table.cc) = 30304701546ff42d796696102feeabed0b121f0e
+SHA1 (patch-test_unit_cookies.c) = e3e130e9e0c5f718f4768414d642843e4603e02b
diff --git a/dillo/patches/patch-dlib_dlib.c b/dillo/patches/patch-dlib_dlib.c
new file mode 100644
index 0000000000..93a58724ad
--- /dev/null
+++ b/dillo/patches/patch-dlib_dlib.c
@@ -0,0 +1,15 @@
+$NetBSD$
+
+Avoid ctype(3) undefined behaviours.
+
+--- dlib/dlib.c.orig 2026-01-06 16:25:07.189521259 +0000
++++ dlib/dlib.c
+@@ -525,7 +525,7 @@ const char *dStr_printable(Dstr *in, int
+ out = dStr_sized_new(in->len);
+
+ for (i = 0; (i < in->len) && (out->len < maxlen); ++i) {
+- if (isprint(in->str[i]) || (in->str[i] == '\n')) {
++ if (isprint((unsigned char)in->str[i]) || (in->str[i] == '\n')) {
+ dStr_append_c(out, in->str[i]);
+ } else {
+ dStr_append_l(out, "\\x", 2);
diff --git a/dillo/patches/patch-dpi_bookmarks.c b/dillo/patches/patch-dpi_bookmarks.c
new file mode 100644
index 0000000000..2b37b49818
--- /dev/null
+++ b/dillo/patches/patch-dpi_bookmarks.c
@@ -0,0 +1,112 @@
+$NetBSD$
+
+Avoid ctype(3) undefined behaviours.
+
+--- dpi/bookmarks.c.orig 2026-01-06 16:25:07.197502866 +0000
++++ dpi/bookmarks.c
+@@ -338,8 +338,8 @@ static void Unencode_str(char *e_str)
+ *p = '\n';
+ e += 5;
+ } else {
+- *p = (isdigit(e[1]) ? (e[1] - '0') : (e[1] - 'A' + 10)) * 16 +
+- (isdigit(e[2]) ? (e[2] - '0') : (e[2] - 'A' + 10));
++ *p = (isdigit((unsigned char)e[1]) ? (e[1] - '0') : (e[1] - 'A' + 10)) * 16 +
++ (isdigit((unsigned char)e[2]) ? (e[2] - '0') : (e[2] - 'A' + 10));
+ e += 2;
+ }
+ } else {
+@@ -807,11 +807,11 @@ static void Bmsrv_count_urls_and_section
+ *n_sec = *n_url = 0;
+ if ((p = strchr(url, '?'))) {
+ for (q = p; (q = strstr(q, "&url")); ++q) {
+- for (i = 0; isdigit(q[4+i]); ++i);
++ for (i = 0; isdigit((unsigned char)q[4+i]); ++i);
+ *n_url += (q[4+i] == '=') ? 1 : 0;
+ }
+ for (q = p; (q = strstr(q, "&s")); ++q) {
+- for (i = 0; isdigit(q[2+i]); ++i);
++ for (i = 0; isdigit((unsigned char)q[2+i]); ++i);
+ *n_sec += (q[2+i] == '=') ? 1 : 0;
+ }
+ }
+@@ -972,7 +972,7 @@ static int Bmsrv_send_modify_update(Dsh
+ /* send items here */
+ p = strchr(url1, '?');
+ for (q = p; (q = strstr(q, "&s")); ++q) {
+- for (i = 0; isdigit(q[2+i]); ++i);
++ for (i = 0; isdigit((unsigned char)q[2+i]); ++i);
+ if (q[2+i] == '=') {
+ key = strtol(q + 2, NULL, 10);
+ if ((sec_node = Bms_get_sec(key))) {
+@@ -992,7 +992,7 @@ static int Bmsrv_send_modify_update(Dsh
+ /* send items here */
+ p = strchr(url1, '?');
+ for (q = p; (q = strstr(q, "&url")); ++q) {
+- for (i = 0; isdigit(q[4+i]); ++i);
++ for (i = 0; isdigit((unsigned char)q[4+i]); ++i);
+ if (q[4+i] == '=') {
+ key = strtol(q + 4, NULL, 10);
+ bm_node = Bms_get(key);
+@@ -1060,7 +1060,7 @@ static int Bmsrv_modify_delete(char *url
+ /* Remove marked sections */
+ p = strchr(url, '?');
+ for (ns = 0; (p = strstr(p, "&s")); ++p) {
+- if (isdigit(p[2])) {
++ if (isdigit((unsigned char)p[2])) {
+ key = strtol(p + 2, NULL, 10);
+ Bms_sec_del(key);
+ ++ns;
+@@ -1070,7 +1070,7 @@ static int Bmsrv_modify_delete(char *url
+ /* Remove marked urls */
+ p = strchr(url, '?');
+ for (nb = 0; (p = strstr(p, "&url")); ++p) {
+- if (isdigit(p[4])) {
++ if (isdigit((unsigned char)p[4])) {
+ key = strtol(p + 4, NULL, 10);
+ Bms_del(key);
+ ++nb;
+@@ -1105,7 +1105,7 @@ static int Bmsrv_modify_move(char *url)
+
+ /* get target section */
+ for (p = url; (p = strstr(p, "&s")); ++p) {
+- if (isdigit(p[2])) {
++ if (isdigit((unsigned char)p[2])) {
+ section = strtol(p + 2, NULL, 10);
+ break;
+ }
+@@ -1116,7 +1116,7 @@ static int Bmsrv_modify_move(char *url)
+ /* move marked urls */
+ p = strchr(url, '?');
+ for (n = 0; (p = strstr(p, "&url")); ++p) {
+- if (isdigit(p[4])) {
++ if (isdigit((unsigned char)p[4])) {
+ key = strtol(p + 4, NULL, 10);
+ Bms_move(key, section);
+ ++n;
+@@ -1145,7 +1145,7 @@ static int Bmsrv_modify_update(char *url
+ p = strchr(url, '?');
+ for ( ; (p = strstr(p, "s")); ++p) {
+ if (p[-1] == '&' || p[-1] == '?' ) {
+- for (i = 0; isdigit(p[1 + i]); ++i);
++ for (i = 0; isdigit((unsigned char)p[1 + i]); ++i);
+ if (i && p[1 + i] == '=') {
+ /* we have a title/key to change */
+ key = strtol(p + 1, NULL, 10);
+@@ -1164,7 +1164,7 @@ static int Bmsrv_modify_update(char *url
+ p = strchr(url, '?');
+ for ( ; (p = strstr(p, "title")); ++p) {
+ if (p[-1] == '&' || p[-1] == '?' ) {
+- for (i = 0; isdigit(p[5 + i]); ++i);
++ for (i = 0; isdigit((unsigned char)p[5 + i]); ++i);
+ if (i && p[5 + i] == '=') {
+ /* we have a title/key to change */
+ key = strtol(p + 5, NULL, 10);
+@@ -1229,7 +1229,7 @@ static int Bmsrv_modify_add_url(Dsh *sh,
+ if (sh == NULL) {
+ /* look for section */
+ for (q = s_url; (q = strstr(q, "&s")); ++q) {
+- for (i = 0; isdigit(q[2+i]); ++i);
++ for (i = 0; isdigit((unsigned char)q[2+i]); ++i);
+ if (q[2+i] == '=')
+ section = strtol(q + 2, NULL, 10);
+ }
diff --git a/dillo/patches/patch-dpi_cookies.c b/dillo/patches/patch-dpi_cookies.c
new file mode 100644
index 0000000000..dc3b7295e2
--- /dev/null
+++ b/dillo/patches/patch-dpi_cookies.c
@@ -0,0 +1,63 @@
+$NetBSD$
+
+Avoid ctype(3) undefined behaviours.
+
+--- dpi/cookies.c.orig 2026-01-06 16:25:07.192584702 +0000
++++ dpi/cookies.c
+@@ -487,14 +487,14 @@ static int Cookies_get_timefield(const c
+ int n;
+ const char *s = *str;
+
+- if (!isdigit(*s))
++ if (!isdigit((unsigned char)*s))
+ return -1;
+
+ n = *(s++) - '0';
+- if (isdigit(*s)) {
++ if (isdigit((unsigned char)*s)) {
+ n *= 10;
+ n += *(s++) - '0';
+- if (isdigit(*s))
++ if (isdigit((unsigned char)*s))
+ return -1;
+ }
+ *str = s;
+@@ -550,24 +550,24 @@ static bool_t Cookies_get_year(struct tm
+ int n;
+ const char *s = *str;
+
+- if (isdigit(*s))
++ if (isdigit((unsigned char)*s))
+ n = *(s++) - '0';
+ else
+ return FALSE;
+- if (isdigit(*s)) {
++ if (isdigit((unsigned char)*s)) {
+ n *= 10;
+ n += *(s++) - '0';
+ } else
+ return FALSE;
+- if (isdigit(*s)) {
++ if (isdigit((unsigned char)*s)) {
+ n *= 10;
+ n += *(s++) - '0';
+ }
+- if (isdigit(*s)) {
++ if (isdigit((unsigned char)*s)) {
+ n *= 10;
+ n += *(s++) - '0';
+ }
+- if (isdigit(*s)) {
++ if (isdigit((unsigned char)*s)) {
+ /* Sorry, users of prehistoric software in the year 10000! */
+ return FALSE;
+ }
+@@ -936,7 +936,7 @@ static CookieData_t *Cookies_parse(char
+ cookie->domain = value;
+ } else if (dStrAsciiCasecmp(attr, "Max-Age") == 0) {
+ value = Cookies_parse_value(&str);
+- if (isdigit(*value) || *value == '-') {
++ if (isdigit((unsigned char)*value) || *value == '-') {
+ long age;
+ time_t now = time(NULL);
+ struct tm *tm = gmtime(&now);
diff --git a/dillo/patches/patch-dpi_downloads.cc b/dillo/patches/patch-dpi_downloads.cc
new file mode 100644
index 0000000000..aa2b04f9e5
--- /dev/null
+++ b/dillo/patches/patch-dpi_downloads.cc
@@ -0,0 +1,40 @@
+$NetBSD$
+
+Avoid ctype(3) undefined behaviours.
+
+--- dpi/downloads.cc.orig 2026-01-06 16:25:07.202386354 +0000
++++ dpi/downloads.cc
+@@ -513,7 +513,7 @@ void DLItem::log_text_add(const char *bu
+ case ST_newline:
+ if (*p == ' ') {
+ log_state = ST_discard;
+- } else if (isdigit(*p)) {
++ } else if (isdigit((unsigned char)*p)) {
+ *q++ = *p; log_state = ST_number;
+ } else if (*p == '\n') {
+ *q++ = *p;
+@@ -522,10 +522,10 @@ void DLItem::log_text_add(const char *bu
+ }
+ break;
+ case ST_number:
+- if (isdigit(*q++ = *p)) {
++ if (isdigit((unsigned char)(*q++ = *p))) {
+ // keep here
+ } else if (*p == 'K') {
+- for (--q; isdigit(q[-1]); --q) ;
++ for (--q; isdigit((unsigned char)q[-1]); --q) ;
+ log_state = ST_discard;
+ } else {
+ log_state = ST_copy;
+@@ -549,9 +549,9 @@ void DLItem::log_text_add(const char *bu
+ // Now scan for the length of the file
+ if (total_bytesize == -1) {
+ p = strstr(log_text, "\nLength: ");
+- if (p && isdigit(p[9]) && strchr(p + 9, ' ')) {
++ if (p && isdigit((unsigned char)p[9]) && strchr(p + 9, ' ')) {
+ for (p += 9, d = &num[0]; *p != ' '; ++p)
+- if (isdigit(*p))
++ if (isdigit((unsigned char)*p))
+ *d++ = *p;
+ *d = 0;
+ total_bytesize = strtol (num, NULL, 10);
diff --git a/dillo/patches/patch-dpi_dpiutil.c b/dillo/patches/patch-dpi_dpiutil.c
new file mode 100644
index 0000000000..f39fe642fe
--- /dev/null
+++ b/dillo/patches/patch-dpi_dpiutil.c
@@ -0,0 +1,20 @@
+$NetBSD$
+
+Avoid ctype(3) undefined behaviours.
+
+--- dpi/dpiutil.c.orig 2026-01-06 16:25:07.199992497 +0000
++++ dpi/dpiutil.c
+@@ -67,10 +67,10 @@ char *Unescape_uri_str(const char *s)
+
+ if (strchr(s, '%')) {
+ for (p = buf; (*p = *s); ++s, ++p) {
+- if (*p == '%' && isxdigit(s[1]) && isxdigit(s[2])) {
+- *p = (isdigit(s[1]) ? (s[1] - '0')
++ if (*p == '%' && isxdigit((unsigned char)s[1]) && isxdigit((unsigned char)s[2])) {
++ *p = (isdigit((unsigned char)s[1]) ? (s[1] - '0')
+ : D_ASCII_TOUPPER(s[1]) - 'A' + 10) * 16;
+- *p += isdigit(s[2]) ? (s[2] - '0')
++ *p += isdigit((unsigned char)s[2]) ? (s[2] - '0')
+ : D_ASCII_TOUPPER(s[2]) - 'A' + 10;
+ s += 2;
+ }
diff --git a/dillo/patches/patch-dpid_dpidc.c b/dillo/patches/patch-dpid_dpidc.c
new file mode 100644
index 0000000000..d2bbcd9b94
--- /dev/null
+++ b/dillo/patches/patch-dpid_dpidc.c
@@ -0,0 +1,15 @@
+$NetBSD$
+
+Avoid ctype(3) undefined behaviours.
+
+--- dpid/dpidc.c.orig 2026-01-06 16:25:07.204748644 +0000
++++ dpid/dpidc.c
+@@ -59,7 +59,7 @@ static int Dpi_read_comm_keys(int *port)
+ MSG_ERR("[Dpi_read_comm_keys] empty file: %s\n", fname);
+ } else {
+ *port = strtol(rcline, &tail, 10);
+- for (i = 0; *tail && isxdigit(tail[i+1]); ++i)
++ for (i = 0; *tail && isxdigit((unsigned char)tail[i+1]); ++i)
+ SharedKey[i] = tail[i+1];
+ SharedKey[i] = 0;
+ ret = 1;
diff --git a/dillo/patches/patch-dpip_dpip.c b/dillo/patches/patch-dpip_dpip.c
new file mode 100644
index 0000000000..06d8847e18
--- /dev/null
+++ b/dillo/patches/patch-dpip_dpip.c
@@ -0,0 +1,15 @@
+$NetBSD$
+
+Avoid ctype(3) undefined behaviours.
+
+--- dpip/dpip.c.orig 2026-01-06 16:25:07.209620860 +0000
++++ dpip/dpip.c
+@@ -220,7 +220,7 @@ int a_Dpip_check_auth(const char *auth_t
+ } else {
+ port = strtol(rcline, &tail, 10);
+ if (tail && port != 0) {
+- for (i = 0; *tail && isxdigit(tail[i+1]); ++i)
++ for (i = 0; *tail && isxdigit((unsigned char)tail[i+1]); ++i)
+ SharedSecret[i] = tail[i+1];
+ SharedSecret[i] = 0;
+ if (strcmp(msg, SharedSecret) == 0)
diff --git a/dillo/patches/patch-dw_findtext.hh b/dillo/patches/patch-dw_findtext.hh
new file mode 100644
index 0000000000..beeb9b1927
--- /dev/null
+++ b/dillo/patches/patch-dw_findtext.hh
@@ -0,0 +1,17 @@
+$NetBSD$
+
+Avoid ctype(3) undefined behaviours.
+
+--- dw/findtext.hh.orig 2026-01-06 16:25:07.212143829 +0000
++++ dw/findtext.hh
+@@ -66,8 +66,8 @@ private:
+ bool search0 (bool backwards, bool firstTrial);
+
+ inline static bool charsEqual (char c1, char c2, bool caseSens)
+- { return caseSens ? c1 == c2 : tolower (c1) == tolower (c2) ||
+- (isspace (c1) && isspace (c2)); }
++ { return caseSens ? c1 == c2 : tolower ((unsigned char)c1) == tolower ((unsigned char)c2) ||
++ (isspace ((unsigned char)c1) && isspace ((unsigned char)c2)); }
+
+ public:
+ FindtextState ();
diff --git a/dillo/patches/patch-dw_fltkui.cc b/dillo/patches/patch-dw_fltkui.cc
new file mode 100644
index 0000000000..9ebde6a89a
--- /dev/null
+++ b/dillo/patches/patch-dw_fltkui.cc
@@ -0,0 +1,23 @@
+$NetBSD$
+
+Avoid ctype(3) undefined behaviours.
+
+--- dw/fltkui.cc.orig 2026-01-06 16:25:07.215514321 +0000
++++ dw/fltkui.cc
+@@ -365,14 +365,14 @@ int CustChoice::handle(int e)
+ if (k == FL_Enter || k == FL_Down) {
+ return Fl_Choice::handle(FL_PUSH); // activate menu
+
+- } else if (isalnum(k)) { // try key as shortcut to menuitem
++ } else if (isalnum((unsigned char)k)) { // try key as shortcut to menuitem
+ int t = value()+1 >= size() ? 0 : value()+1;
+ while (t != value()) {
+ const Fl_Menu_Item *mi = &(menu()[t]);
+ if (mi->submenu()) // submenu?
+ ;
+ else if (mi->label() && mi->active()) { // menu item?
+- if (k == tolower(mi->label()[0])) {
++ if (k == tolower((unsigned char)mi->label()[0])) {
+ value(mi);
+ return 1; // Let FLTK know we used this key
+ }
diff --git a/dillo/patches/patch-dw_textblock.cc b/dillo/patches/patch-dw_textblock.cc
new file mode 100644
index 0000000000..06bb443faa
--- /dev/null
+++ b/dillo/patches/patch-dw_textblock.cc
@@ -0,0 +1,41 @@
+$NetBSD$
+
+Avoid ctype(3) undefined behaviours.
+
+--- dw/textblock.cc.orig 2026-01-06 16:25:07.218295539 +0000
++++ dw/textblock.cc
+@@ -1238,14 +1238,14 @@ void Textblock::drawText(core::View *vie
+ bool initial_seen = false;
+
+ for (int i = 0; i < start; i++)
+- if (!ispunct(text[i]))
++ if (!ispunct((unsigned char)text[i]))
+ initial_seen = true;
+ if (initial_seen)
+ break;
+
+ int after = 0;
+ text += start;
+- while (ispunct(text[after]))
++ while (ispunct((unsigned char)text[after]))
+ after++;
+ if (text[after])
+ after = layout->nextGlyph(text, after);
+@@ -1931,7 +1931,7 @@ int Textblock::textWidth(const char *tex
+ bool initial_seen = false;
+
+ for (int i = 0; i < start; i++)
+- if (!ispunct(text[i]))
++ if (!ispunct((unsigned char)text[i]))
+ initial_seen = true;
+ if (initial_seen) {
+ ret = layout->textWidth(style->font, text+start, len);
+@@ -1939,7 +1939,7 @@ int Textblock::textWidth(const char *tex
+ int after = 0;
+
+ text += start;
+- while (ispunct(text[after]))
++ while (ispunct((unsigned char)text[after]))
+ after++;
+ if (text[after])
+ after = layout->nextGlyph(text, after);
diff --git a/dillo/patches/patch-src_IO_dpi.c b/dillo/patches/patch-src_IO_dpi.c
new file mode 100644
index 0000000000..ea8f316196
--- /dev/null
+++ b/dillo/patches/patch-src_IO_dpi.c
@@ -0,0 +1,15 @@
+$NetBSD$
+
+Avoid ctype(3) undefined behaviours.
+
+--- src/IO/dpi.c.orig 2026-01-06 16:25:07.223239131 +0000
++++ src/IO/dpi.c
+@@ -404,7 +404,7 @@ static int Dpi_read_comm_keys(int *port)
+ MSG_ERR("[Dpi_read_comm_keys] empty file: %s\n", fname);
+ } else {
+ *port = strtol(rcline, &tail, 10);
+- for (i = 0; *tail && isxdigit(tail[i+1]); ++i)
++ for (i = 0; *tail && isxdigit((unsigned char)tail[i+1]); ++i)
+ SharedKey[i] = tail[i+1];
+ SharedKey[i] = 0;
+ ret = 1;
diff --git a/dillo/patches/patch-src_IO_http.c b/dillo/patches/patch-src_IO_http.c
new file mode 100644
index 0000000000..4048e15481
--- /dev/null
+++ b/dillo/patches/patch-src_IO_http.c
@@ -0,0 +1,15 @@
+$NetBSD$
+
+Avoid ctype(3) undefined behaviours.
+
+--- src/IO/http.c.orig 2026-01-06 16:25:07.220765195 +0000
++++ src/IO/http.c
+@@ -701,7 +701,7 @@ static char *Http_get_connect_str(const
+ dstr = dStr_new("");
+ auth1 = URL_AUTHORITY(url);
+ auth_len = strlen(auth1);
+- if (auth_len > 0 && !isdigit(auth1[auth_len - 1]))
++ if (auth_len > 0 && !isdigit((unsigned char)auth1[auth_len - 1]))
+ /* if no port number, add HTTPS port */
+ auth2 = dStrconcat(auth1, ":443", NULL);
+ else
diff --git a/dillo/patches/patch-src_IO_tls__openssl.c b/dillo/patches/patch-src_IO_tls__openssl.c
new file mode 100644
index 0000000000..21298e0787
--- /dev/null
+++ b/dillo/patches/patch-src_IO_tls__openssl.c
@@ -0,0 +1,32 @@
+$NetBSD$
+
+Avoid ctype(3) undefined behaviours.
+
+--- src/IO/tls_openssl.c.orig 2026-01-06 16:25:07.228170607 +0000
++++ src/IO/tls_openssl.c
+@@ -576,13 +576,13 @@ static bool_t pattern_match (const char
+
+ const char *p = pattern, *n = string;
+ char c;
+- for (; (c = tolower (*p++)) != '\0'; n++)
++ for (; (c = tolower ((unsigned char)*p++)) != '\0'; n++)
+ if (c == '*')
+ {
+- for (c = tolower (*p); c == '*'; c = tolower (*++p))
++ for (c = tolower ((unsigned char)*p); c == '*'; c = tolower ((unsigned char)*++p))
+ ;
+ for (; *n != '\0'; n++)
+- if (tolower (*n) == c && pattern_match (p, n))
++ if (tolower ((unsigned char)*n) == c && pattern_match (p, n))
+ return TRUE;
+ #ifdef ASTERISK_EXCLUDES_DOT
+ else if (*n == '.')
+@@ -592,7 +592,7 @@ static bool_t pattern_match (const char
+ }
+ else
+ {
+- if (c != tolower (*n))
++ if (c != tolower ((unsigned char)*n))
+ return FALSE;
+ }
+ return *n == '\0';
diff --git a/dillo/patches/patch-src_cssparser.cc b/dillo/patches/patch-src_cssparser.cc
new file mode 100644
index 0000000000..2331d8a8fa
--- /dev/null
+++ b/dillo/patches/patch-src_cssparser.cc
@@ -0,0 +1,83 @@
+$NetBSD$
+
+Avoid ctype(3) undefined behaviours.
+
+--- src/cssparser.cc.orig 2026-01-06 16:25:07.230739234 +0000
++++ src/cssparser.cc
+@@ -530,7 +530,7 @@ void CssParser::nextToken()
+
+ while (true) {
+ c = getChar();
+- if (isspace(c)) { // ignore whitespace
++ if (isspace((unsigned char)c)) { // ignore whitespace
+ spaceSeparated = true;
+ } else if (skipString(c, "/*")) { // ignore comments
+ do {
+@@ -550,7 +550,7 @@ void CssParser::nextToken()
+ c = getChar();
+ }
+
+- if (isdigit(c)) {
++ if (isdigit((unsigned char)c)) {
+ ttype = CSS_TK_DECINT;
+ do {
+ if (i < maxStrLen - 1) {
+@@ -567,7 +567,7 @@ void CssParser::nextToken()
+
+ if (c == '.') {
+ c = getChar();
+- if (isdigit(c)) {
++ if (isdigit((unsigned char)c)) {
+ ttype = CSS_TK_FLOAT;
+ if (i < maxStrLen - 1)
+ tval[i++] = '.';
+@@ -576,7 +576,7 @@ void CssParser::nextToken()
+ tval[i++] = c;
+ /* else silently truncated */
+ c = getChar();
+- } while (isdigit(c));
++ } while (isdigit((unsigned char)c));
+
+ ungetChar();
+ tval[i] = 0;
+@@ -604,13 +604,13 @@ void CssParser::nextToken()
+ c = getChar();
+ }
+
+- if (isalpha(c) || c == '_' || c == '-') {
++ if (isalpha((unsigned char)c) || c == '_' || c == '-') {
+ ttype = CSS_TK_SYMBOL;
+
+ tval[0] = c;
+ i = 1;
+ c = getChar();
+- while (isalnum(c) || c == '_' || c == '-') {
++ while (isalnum((unsigned char)c) || c == '_' || c == '-') {
+ if (i < maxStrLen - 1) {
+ tval[i] = c;
+ i++;
+@@ -633,13 +633,13 @@ void CssParser::nextToken()
+ while (c != EOF && c != c1) {
+ if (c == '\\') {
+ d = getChar();
+- if (isxdigit(d)) {
++ if (isxdigit((unsigned char)d)) {
+ /* Read hex Unicode char. (Actually, strings are yet only 8
+ * bit.) */
+ hexbuf[0] = d;
+ j = 1;
+ d = getChar();
+- while (j < 4 && isxdigit(d)) {
++ while (j < 4 && isxdigit((unsigned char)d)) {
+ hexbuf[j] = d;
+ j++;
+ d = getChar();
+@@ -674,7 +674,7 @@ void CssParser::nextToken()
+ tval[0] = c;
+ i = 1;
+ c = getChar();
+- while (isxdigit(c)) {
++ while (isxdigit((unsigned char)c)) {
+ if (i < maxStrLen - 1) {
+ tval[i] = c;
+ i++;
diff --git a/dillo/patches/patch-src_hsts.c b/dillo/patches/patch-src_hsts.c
new file mode 100644
index 0000000000..bcb158c652
--- /dev/null
+++ b/dillo/patches/patch-src_hsts.c
@@ -0,0 +1,15 @@
+$NetBSD$
+
+Avoid ctype(3) undefined behaviours.
+
+--- src/hsts.c.orig 2026-01-06 16:25:07.233270206 +0000
++++ src/hsts.c
+@@ -223,7 +223,7 @@ void a_Hsts_set(const char *header, cons
+ /* Get the value for the attribute and store it */
+ if (dStrAsciiCasecmp(attr, "max-age") == 0) {
+ value = Hsts_parse_value(&header);
+- if (isdigit(*value)) {
++ if (isdigit((unsigned char)*value)) {
+ errno = 0;
+ max_age = strtol(value, NULL, 10);
+ if (errno == ERANGE)
diff --git a/dillo/patches/patch-src_html.cc b/dillo/patches/patch-src_html.cc
new file mode 100644
index 0000000000..440af022ea
--- /dev/null
+++ b/dillo/patches/patch-src_html.cc
@@ -0,0 +1,217 @@
+$NetBSD$
+
+Avoid ctype(3) undefined behaviours.
+
+--- src/html.cc.orig 2026-01-06 16:25:07.239433534 +0000
++++ src/html.cc
+@@ -883,7 +883,7 @@ static const char *Html_parse_numeric_ch
+ errno = 0;
+
+ if (*s == 'x' || *s == 'X') {
+- if (isxdigit(*++s)) {
++ if (isxdigit((unsigned char)*++s)) {
+ /* strtol with base 16 accepts leading "0x" - we don't */
+ if (*s == '0' && s[1] == 'x') {
+ s++;
+@@ -892,7 +892,7 @@ static const char *Html_parse_numeric_ch
+ codepoint = strtol(s, &s, 16);
+ }
+ }
+- } else if (isdigit(*s)) {
++ } else if (isdigit((unsigned char)*s)) {
+ codepoint = strtol(s, &s, 10);
+ }
+ if (errno)
+@@ -984,7 +984,7 @@ static const char *Html_parse_named_char
+ char *s = tok;
+ const char *ret = NULL;
+
+- while (*++s && (isalnum(*s) || strchr(":_.-", *s))) ;
++ while (*++s && (isalnum((unsigned char)*s) || strchr(":_.-", *s))) ;
+ c = *s;
+ *s = '\0';
+ if (c != ';') {
+@@ -1051,7 +1051,7 @@ static const char *Html_parse_entity(Dil
+
+ if (*tok == '#') {
+ ret = Html_parse_numeric_charref(html, tok+1, is_attr, entsize);
+- } else if (isalpha(*tok)) {
++ } else if (isalpha((unsigned char)*tok)) {
+ ret = Html_parse_named_charref(html, tok, is_attr, entsize);
+ } else if (prefs.show_extra_warnings &&
+ (!(html->DocType == DT_HTML && html->DocTypeVersion >= 5.0f))) {
+@@ -1249,11 +1249,11 @@ static void Html_process_word(DilloHtml
+ /* all this overhead is to catch white-space entities */
+ Pword = a_Html_parse_entities(html, word, size);
+ for (start = i = 0; Pword[i]; start = i)
+- if (isspace(Pword[i])) {
+- while (Pword[++i] && isspace(Pword[i])) ;
++ if (isspace((unsigned char)Pword[i])) {
++ while (Pword[++i] && isspace((unsigned char)Pword[i])) ;
+ Html_process_space(html, Pword + start, i - start);
+ } else {
+- while (Pword[++i] && !isspace(Pword[i])) ;
++ while (Pword[++i] && !isspace((unsigned char)Pword[i])) ;
+ HT2TB(html)->addText(Pword + start, i - start, html->wordStyle ());
+ html->pre_column += i - start;
+ html->PreFirstChar = false;
+@@ -1287,8 +1287,8 @@ static void Html_process_word(DilloHtml
+ for (start = i = 0; word2[i]; start = i) {
+ int len;
+
+- if (isspace(word2[i])) {
+- while (word2[++i] && isspace(word2[i])) ;
++ if (isspace((unsigned char)word2[i])) {
++ while (word2[++i] && isspace((unsigned char)word2[i])) ;
+ Html_process_space(html, word2 + start, i - start);
+ } else if (!strncmp(word2+i, utf8_zero_width_space, 3)) {
+ i += 3;
+@@ -1300,7 +1300,7 @@ static void Html_process_word(DilloHtml
+ } else {
+ do {
+ i += len;
+- } while (word2[i] && !isspace(word2[i]) &&
++ } while (word2[i] && !isspace((unsigned char)word2[i]) &&
+ strncmp(word2+i, utf8_zero_width_space, 3) &&
+ (!a_Utf8_ideographic(word2+i, beyond_word2, &len)));
+ HT2TB(html)->addText(word2 + start, i - start, html->wordStyle ());
+@@ -1324,7 +1324,7 @@ static bool Html_match_tag(const char *t
+ return false;
+ }
+ /* The test for '/' is for xml compatibility: "empty/>" will be matched. */
+- if (i < tagsize && (isspace(tag[i]) || tag[i] == '>' || tag[i] == '/'))
++ if (i < tagsize && (isspace((unsigned char)tag[i]) || tag[i] == '>' || tag[i] == '/'))
+ return true;
+ return false;
+ }
+@@ -1441,7 +1441,7 @@ CssLength a_Html_parse_length (DilloHtml
+ l = CSS_CREATE_LENGTH(0.0, CSS_LENGTH_TYPE_AUTO);
+ else {
+ /* allow only whitespaces */
+- if (*end && !isspace (*end)) {
++ if (*end && !isspace ((unsigned char)*end)) {
+ BUG_MSG("Garbage after length: '%s'.", attr);
+ l = CSS_CREATE_LENGTH(0.0, CSS_LENGTH_TYPE_AUTO);
+ }
+@@ -1487,10 +1487,10 @@ static int
+ int i;
+
+ for (i = 0; val[i]; ++i)
+- if (!d_isascii(val[i]) || !(isalnum(val[i]) || strchr(":_.-", val[i])))
++ if (!d_isascii(val[i]) || !(isalnum((unsigned char)val[i]) || strchr(":_.-", val[i])))
+ break;
+
+- if (val[i] || !(d_isascii(val[0]) && isalpha(val[0])))
++ if (val[i] || !(d_isascii(val[0]) && isalpha((unsigned char)val[0])))
+ BUG_MSG("%s attribute value \"%s\" is not of the form "
+ "'[A-Za-z][A-Za-z0-9:_.-]*'.", attrname, val);
+
+@@ -1537,8 +1537,8 @@ static void Html_parse_doctype(DilloHtml
+ /* Tag sanitization: Collapse whitespace between tokens
+ * and replace '\n' and '\r' with ' ' inside quoted strings. */
+ for (i = 0, p = ntag; *p; ++p) {
+- if (isspace(*p)) {
+- for (ntag[i++] = ' '; isspace(p[1]); ++p) ;
++ if (isspace((unsigned char)*p)) {
++ for (ntag[i++] = ' '; isspace((unsigned char)p[1]); ++p) ;
+ } else if ((quote = *p) == '"' || *p == '\'') {
+ for (ntag[i++] = *p++; (ntag[i] = *p) && ntag[i++] != quote; ++p) {
+ if (*p == '\n' || *p == '\r')
+@@ -2376,7 +2376,7 @@ misc::SimpleVector<int> *Html_read_coord
+ break;
+ coords->increase();
+ coords->set(coords->size() - 1, coord);
+- while (isspace(*newtail))
++ while (isspace((unsigned char)*newtail))
+ newtail++;
+ if (!*newtail)
+ break;
+@@ -4178,7 +4178,7 @@ static const char *Html_get_attr2(DilloH
+ for (i = 1; i < tagsize; ++i) {
+ switch (state) {
+ case SEEK_ATTR_START:
+- if (isspace(tag[i]))
++ if (isspace((unsigned char)tag[i]))
+ state = SEEK_TOKEN_START;
+ else if (tag[i] == '=')
+ state = SEEK_VALUE_START;
+@@ -4186,7 +4186,7 @@ static const char *Html_get_attr2(DilloH
+
+ case MATCH_ATTR_NAME:
+ if (!attrname[attr_pos] &&
+- (tag[i] == '=' || isspace(tag[i]) || tag[i] == '>')) {
++ (tag[i] == '=' || isspace((unsigned char)tag[i]) || tag[i] == '>')) {
+ Found = 1;
+ state = SEEK_TOKEN_START;
+ --i;
+@@ -4202,14 +4202,14 @@ static const char *Html_get_attr2(DilloH
+ case SEEK_TOKEN_START:
+ if (tag[i] == '=') {
+ state = SEEK_VALUE_START;
+- } else if (!isspace(tag[i])) {
++ } else if (!isspace((unsigned char)tag[i])) {
+ attr_pos = 0;
+ state = (Found) ? FINISHED : MATCH_ATTR_NAME;
+ --i;
+ }
+ break;
+ case SEEK_VALUE_START:
+- if (!isspace(tag[i])) {
++ if (!isspace((unsigned char)tag[i])) {
+ delimiter = (tag[i] == '"' || tag[i] == '\'') ? tag[i] : ' ';
+ i -= (delimiter == ' ');
+ state = (Found) ? GET_VALUE : SKIP_VALUE;
+@@ -4217,11 +4217,11 @@ static const char *Html_get_attr2(DilloH
+ break;
+
+ case SKIP_VALUE:
+- if ((delimiter == ' ' && isspace(tag[i])) || tag[i] == delimiter)
++ if ((delimiter == ' ' && isspace((unsigned char)tag[i])) || tag[i] == delimiter)
+ state = SEEK_TOKEN_START;
+ break;
+ case GET_VALUE:
+- if ((delimiter == ' ' && (isspace(tag[i]) || tag[i] == '>')) ||
++ if ((delimiter == ' ' && (isspace((unsigned char)tag[i]) || tag[i] == '>')) ||
+ tag[i] == delimiter) {
+ state = FINISHED;
+ } else if (tag[i] == '&' &&
+@@ -4252,10 +4252,10 @@ static const char *Html_get_attr2(DilloH
+ }
+
+ if (tag_parsing_flags & HTML_LeftTrim)
+- while (isspace(Buf->str[0]))
++ while (isspace((unsigned char)Buf->str[0]))
+ dStr_erase(Buf, 0, 1);
+ if (tag_parsing_flags & HTML_RightTrim)
+- while (Buf->len && isspace(Buf->str[Buf->len - 1]))
++ while (Buf->len && isspace((unsigned char)Buf->str[Buf->len - 1]))
+ dStr_truncate(Buf, Buf->len - 1);
+
+ return (Found) ? Buf->str : NULL;
+@@ -4349,14 +4349,14 @@ static int Html_write_raw(DilloHtml *htm
+ break;
+ }
+
+- if (isspace(buf[buf_index])) {
++ if (isspace((unsigned char)buf[buf_index])) {
+ /* whitespace: group all available whitespace */
+- while (++buf_index < bufsize && isspace(buf[buf_index])) ;
++ while (++buf_index < bufsize && isspace((unsigned char)buf[buf_index])) ;
+ Html_process_space(html, buf + token_start, buf_index - token_start);
+ token_start = buf_index;
+
+ } else if (buf[buf_index] == '<' && (ch = buf[buf_index + 1]) &&
+- (isalpha(ch) || strchr("/!?", ch)) ) {
++ (isalpha((unsigned char)ch) || strchr("/!?", ch)) ) {
+ /* Tag */
+ if (buf_index + 3 < bufsize && !strncmp(buf + buf_index, "<!--", 4)) {
+ /* Comment: search for close of comment, skipping over
+@@ -4422,7 +4422,7 @@ static int Html_write_raw(DilloHtml *htm
+ while (++buf_index < bufsize) {
+ buf_index += strcspn(buf + buf_index, " <\n\r\t\f\v");
+ if (buf[buf_index] == '<' && (ch = buf[buf_index + 1]) &&
+- !isalpha(ch) && !strchr("/!?", ch))
++ !isalpha((unsigned char)ch) && !strchr("/!?", ch))
+ continue;
+ break;
+ }
diff --git a/dillo/patches/patch-src_keys.cc b/dillo/patches/patch-src_keys.cc
new file mode 100644
index 0000000000..32997aeec7
--- /dev/null
+++ b/dillo/patches/patch-src_keys.cc
@@ -0,0 +1,24 @@
+$NetBSD$
+
+Avoid ctype(3) undefined behaviours.
+
+--- src/keys.cc.orig 2026-01-06 16:25:07.236435264 +0000
++++ src/keys.cc
+@@ -203,7 +203,7 @@ KeysCommand_t Keys::getKeyCmd()
+ KeyBinding_t keyNode;
+
+ keyNode.modifier = Fl::event_state() & (FL_SHIFT | FL_CTRL |FL_ALT|FL_META);
+- if (iscntrl(Fl::event_text()[0])) {
++ if (iscntrl((unsigned char)Fl::event_text()[0])) {
+ keyNode.key = Fl::event_key();
+ } else {
+ const char *beyond = Fl::event_text() + Fl::event_length();
+@@ -326,7 +326,7 @@ void Keys::parseKey(char *key, char *com
+ }
+
+ // Skip space
+- for ( ; isspace(*key); ++key) ;
++ for ( ; isspace((unsigned char)*key); ++key) ;
+ // Get modifiers
+ while(*key == '<' && (p = strchr(key, '>'))) {
+ ++key;
diff --git a/dillo/patches/patch-src_table.cc b/dillo/patches/patch-src_table.cc
new file mode 100644
index 0000000000..c3c2da7e08
--- /dev/null
+++ b/dillo/patches/patch-src_table.cc
@@ -0,0 +1,15 @@
+$NetBSD$
+
+Avoid ctype(3) undefined behaviours.
+
+--- src/table.cc.orig 2026-01-06 16:25:07.244361847 +0000
++++ src/table.cc
+@@ -51,7 +51,7 @@ void Html_tag_open_table(DilloHtml *html
+ CssLength cssLength;
+
+ if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "border")))
+- border = isdigit(attrbuf[0]) ? strtol (attrbuf, NULL, 10) : 1;
++ border = isdigit((unsigned char)attrbuf[0]) ? strtol (attrbuf, NULL, 10) : 1;
+ if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "cellspacing"))) {
+ cellspacing = strtol (attrbuf, NULL, 10);
+ if (html->DocType == DT_HTML && html->DocTypeVersion >= 5.0f)
diff --git a/dillo/patches/patch-test_unit_cookies.c b/dillo/patches/patch-test_unit_cookies.c
new file mode 100644
index 0000000000..ab5ce19ad3
--- /dev/null
+++ b/dillo/patches/patch-test_unit_cookies.c
@@ -0,0 +1,15 @@
+$NetBSD$
+
+Avoid ctype(3) undefined behaviours.
+
+--- test/unit/cookies.c.orig 2026-01-06 16:25:07.246777391 +0000
++++ test/unit/cookies.c
+@@ -126,7 +126,7 @@ static int Dpi_read_comm_keys(int *port)
+ MSG_ERR("[Dpi_read_comm_keys] empty file: %s\n", fname);
+ } else {
+ *port = strtol(rcline, &tail, 10);
+- for (i = 0; *tail && isxdigit(tail[i+1]); ++i)
++ for (i = 0; *tail && isxdigit((unsigned char)tail[i+1]); ++i)
+ SharedKey[i] = tail[i+1];
+ SharedKey[i] = 0;
+ ret = 1;
Home |
Main Index |
Thread Index |
Old Index