pkgsrc-WIP-changes archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

dillo: Adjust patches based on upstream commit



Module Name:	pkgsrc-wip
Committed By:	Leonardo Taccari <leot%NetBSD.org@localhost>
Pushed By:	leot
Date:		Sun Jan 18 13:48:27 2026 +0100
Changeset:	c72a88396ff93cecc5b0a0954db58ca018801300

Modified Files:
	dillo/distinfo
	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
Added Files:
	dillo/patches/patch-dlib_dlib.h
	dillo/patches/patch-dpi_datauri.c
	dillo/patches/patch-dpi_file.c
	dillo/patches/patch-dpi_ftp.c
	dillo/patches/patch-dw_style.cc
	dillo/patches/patch-lout_misc.cc
	dillo/patches/patch-src_auth.c
	dillo/patches/patch-src_colors.c
	dillo/patches/patch-src_cookies.c
	dillo/patches/patch-src_misc.c
	dillo/patches/patch-src_url.c
	dillo/patches/patch-src_xembed.cc
	dillo/patches/patch-test_dw_dw__anchors__test.cc

Log Message:
dillo: Adjust patches based on upstream commit

Reimport them by cherry-picking Dillo's commit
5e2bc90ea2f80dce3a20ef9c1a282e11d6d67236.

Should be easier to G/C them for the next Dillo release given that they
will all likely ends up as reversed patches then.

To see a diff of this commit:
https://wip.pkgsrc.org/cgi-bin/gitweb.cgi?p=pkgsrc-wip.git;a=commitdiff;h=c72a88396ff93cecc5b0a0954db58ca018801300

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

diffstat:
 dillo/distinfo                                   |  51 ++++++----
 dillo/patches/patch-dlib_dlib.c                  |  28 ++++--
 dillo/patches/patch-dlib_dlib.h                  |  42 ++++++++
 dillo/patches/patch-dpi_bookmarks.c              |  72 ++++++++------
 dillo/patches/patch-dpi_cookies.c                |  48 ++++++---
 dillo/patches/patch-dpi_datauri.c                |  34 +++++++
 dillo/patches/patch-dpi_downloads.cc             |  40 +++++---
 dillo/patches/patch-dpi_dpiutil.c                |  32 ++++--
 dillo/patches/patch-dpi_file.c                   |  25 +++++
 dillo/patches/patch-dpi_ftp.c                    |  25 +++++
 dillo/patches/patch-dpid_dpidc.c                 |  28 ++++--
 dillo/patches/patch-dpip_dpip.c                  |  28 ++++--
 dillo/patches/patch-dw_findtext.hh               |  29 ++++--
 dillo/patches/patch-dw_fltkui.cc                 |  20 ++--
 dillo/patches/patch-dw_style.cc                  |  25 +++++
 dillo/patches/patch-dw_textblock.cc              |  24 +++--
 dillo/patches/patch-lout_misc.cc                 |  25 +++++
 dillo/patches/patch-src_IO_dpi.c                 |  28 ++++--
 dillo/patches/patch-src_IO_http.c                |  28 ++++--
 dillo/patches/patch-src_IO_tls__openssl.c        |  36 +++++--
 dillo/patches/patch-src_auth.c                   |  34 +++++++
 dillo/patches/patch-src_colors.c                 |  31 ++++++
 dillo/patches/patch-src_cookies.c                |  25 +++++
 dillo/patches/patch-src_cssparser.cc             |  65 ++++++++----
 dillo/patches/patch-src_hsts.c                   |  28 ++++--
 dillo/patches/patch-src_html.cc                  | 120 +++++++++++++----------
 dillo/patches/patch-src_keys.cc                  |  32 ++++--
 dillo/patches/patch-src_misc.c                   |  41 ++++++++
 dillo/patches/patch-src_table.cc                 |  18 +++-
 dillo/patches/patch-src_url.c                    |  25 +++++
 dillo/patches/patch-src_xembed.cc                |  25 +++++
 dillo/patches/patch-test_dw_dw__anchors__test.cc |  25 +++++
 dillo/patches/patch-test_unit_cookies.c          |  28 ++++--
 33 files changed, 925 insertions(+), 240 deletions(-)

diffs:
diff --git a/dillo/distinfo b/dillo/distinfo
index 2e8d1174ff..394b64fc3b 100644
--- a/dillo/distinfo
+++ b/dillo/distinfo
@@ -5,22 +5,35 @@ 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) = 5eb9aab04e39f7eed303431ff09d23138e662c37
-SHA1 (patch-dpi_bookmarks.c) = 783cf36f35c8daae47d7c02c3e4a47fb92f9d672
-SHA1 (patch-dpi_cookies.c) = 547cf709ebe7a13914f87c99f1e027d66ea6b5d9
-SHA1 (patch-dpi_downloads.cc) = dd051e9ff9cf2629a1ef4affb8c85260f93891a2
-SHA1 (patch-dpi_dpiutil.c) = b1cf0bb6899304ae41550550a94a66c7d5684d58
-SHA1 (patch-dpid_dpidc.c) = a6fc094820c92bc694e8f765a9d63d700ffd4ace
-SHA1 (patch-dpip_dpip.c) = d07453718dd37eeed322155d99c2481fde73ee37
-SHA1 (patch-dw_findtext.hh) = 0ba3c339e87c6528af57b97044e733477e489b23
-SHA1 (patch-dw_fltkui.cc) = 487d73d3e5fb85f52f9db6a0410455ada2cf0947
-SHA1 (patch-dw_textblock.cc) = 6f600c6fde3301eefd2bd8dac0d2e8b061874611
-SHA1 (patch-src_IO_dpi.c) = d503c9cc8ffac9e1653efc58db74ea961bdb3289
-SHA1 (patch-src_IO_http.c) = f0845383f6a162e0ac863d59fd5fc12085666035
-SHA1 (patch-src_IO_tls__openssl.c) = f89bcbcbeb659ea9adb5f9e7bf7c8eb2bad9b4de
-SHA1 (patch-src_cssparser.cc) = f14601ad41f8191fcdee295f3931aeb8289bc8e1
-SHA1 (patch-src_hsts.c) = 3815c058cdf801f7feac60c93390f7cc59a4f843
-SHA1 (patch-src_html.cc) = 8cc30e37eeb1cf8f86281ca56fccc5ba748c1bab
-SHA1 (patch-src_keys.cc) = bc7c978e6cf9e4a813bff2e6d00a6c00d43a4aaf
-SHA1 (patch-src_table.cc) = 6e29f1b39d64412d095aed5588f335a04069b2f1
-SHA1 (patch-test_unit_cookies.c) = 6ff4a27cc00e5e491de247e31468845a96ca7683
+SHA1 (patch-dlib_dlib.c) = 0a35c4817abcb5d7a230203962050955ce686c8a
+SHA1 (patch-dlib_dlib.h) = 62ba87d250be1fdc188fbac5a421e2014efdb807
+SHA1 (patch-dpi_bookmarks.c) = cf74d17876e59c8e710f0d659f2c228f92313f15
+SHA1 (patch-dpi_cookies.c) = a1919022ca3a4c9902b4c968a9e66ccc66aa1c9f
+SHA1 (patch-dpi_datauri.c) = 5cc8dc48d91ec3481557f38f6a48ef6d1adff3be
+SHA1 (patch-dpi_downloads.cc) = cacd04e64752b54d209c75d252295ca961080ac4
+SHA1 (patch-dpi_dpiutil.c) = 4f0360a2a58f3984ba1ae1edb09c544f72cc9c4e
+SHA1 (patch-dpi_file.c) = 64518eae1956f00b9785611ecec58573b6af7bd5
+SHA1 (patch-dpi_ftp.c) = a268148ec90e1d5441c0b764ecbf2ae5acca6db3
+SHA1 (patch-dpid_dpidc.c) = 5c20bdbb60a7a24b184b566e5ca91a56dbf56c41
+SHA1 (patch-dpip_dpip.c) = e4ba65b0aa04911484db5b7e337966b22a1e4d5c
+SHA1 (patch-dw_findtext.hh) = d3a27f547c0b3a13438172ba74850cd1854eb53b
+SHA1 (patch-dw_fltkui.cc) = 3e5479c554df3a0dfeaedc8baf05d04c85323f54
+SHA1 (patch-dw_style.cc) = b0116e1f31c6608878ba97007060744a7e91e9a4
+SHA1 (patch-dw_textblock.cc) = 3770f6253b073868123a1db543e5f81a3368f76b
+SHA1 (patch-lout_misc.cc) = c16df31edc312b5f87ec2c20c24432a4d0ba1072
+SHA1 (patch-src_IO_dpi.c) = 7b5f4e96ce4378a4d2a88bf36535b171bc38be6d
+SHA1 (patch-src_IO_http.c) = db2a04569bc9e089c22657052e3575810133575e
+SHA1 (patch-src_IO_tls__openssl.c) = da44290d7b7de51e794e81c12a91091feffab96d
+SHA1 (patch-src_auth.c) = e66959bfa05e7fd92204aaf08a585ffa3b53dcaa
+SHA1 (patch-src_colors.c) = d4818f021c70f1c9b8c71df6a515e726d4e4a374
+SHA1 (patch-src_cookies.c) = 9d9d4e63a7a774c010aa418d287f5cc9f5448491
+SHA1 (patch-src_cssparser.cc) = 780fedfba509e9fb2b2ab04debc9c9b182a0a868
+SHA1 (patch-src_hsts.c) = 6853fb438005120734853296c9bf339bb88876da
+SHA1 (patch-src_html.cc) = c8b61e3d90e724bf57b4ed3a94aa1f85a9f4e997
+SHA1 (patch-src_keys.cc) = 08c83bbc9e770711a1baa664a20003e17351f3db
+SHA1 (patch-src_misc.c) = 62ebb46459cea990b66abfa6f41423003d6d8793
+SHA1 (patch-src_table.cc) = 569e75efe38e84de52cdfa3523b17f12d51752c8
+SHA1 (patch-src_url.c) = 9826c9b1ca79e34e9d83b8f7e0e40dc82e4d3b14
+SHA1 (patch-src_xembed.cc) = 0960dc598bc47e8a713e37e9c6c7d9dc9f0a32fd
+SHA1 (patch-test_dw_dw__anchors__test.cc) = 2b14a0392027e382a89d46d0abad17cfde05c4d6
+SHA1 (patch-test_unit_cookies.c) = a0215d1bbc1ab6b3c45beb2d2c9b2041ce309468
diff --git a/dillo/patches/patch-dlib_dlib.c b/dillo/patches/patch-dlib_dlib.c
index 47fb18da25..a352745496 100644
--- a/dillo/patches/patch-dlib_dlib.c
+++ b/dillo/patches/patch-dlib_dlib.c
@@ -1,18 +1,34 @@
 $NetBSD$
 
-Avoid ctype(3) undefined behaviours.
+Avoid ctype(3) abuses
 
-Shared upstream via:
-<https://lists.mailman3.com/hyperkitty/list/dillo-dev%mailman3.com@localhost/thread/L6QLXSD6UBDK3M5CMXQMRWD6ZB4C65MR/>
+Valid argument of ctype(3) functions must be either EOF or non-negative
+value within the range representable as unsigned char.  Invalid values
+leads to undefined behavior.
 
---- dlib/dlib.c.orig	2026-01-06 16:25:07.189521259 +0000
+Add all missing d*() ctype(3) helper functions and switch to use them.
+
+Noticed by running dillo on NetBSD where dillo crashes due such
+abuses.
+
+See: https://lists.mailman3.com/hyperkitty/list/dillo-dev%mailman3.com@localhost/thread/L6QLXSD6UBDK3M5CMXQMRWD6ZB4C65MR/
+
+--- dlib/dlib.c.orig	2025-01-18 10:51:30.000000000 +0000
 +++ dlib/dlib.c
-@@ -525,7 +525,7 @@ const char *dStr_printable(Dstr *in, int
+@@ -24,7 +24,6 @@
+ #include <string.h>
+ #include <unistd.h>
+ #include <errno.h>
+-#include <ctype.h>
+ #include <time.h>
+ 
+ #include "dlib.h"
+@@ -525,7 +524,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')) {
++      if (dIsprint(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-dlib_dlib.h b/dillo/patches/patch-dlib_dlib.h
new file mode 100644
index 0000000000..440c729095
--- /dev/null
+++ b/dillo/patches/patch-dlib_dlib.h
@@ -0,0 +1,42 @@
+$NetBSD$
+
+Avoid ctype(3) abuses
+
+Valid argument of ctype(3) functions must be either EOF or non-negative
+value within the range representable as unsigned char.  Invalid values
+leads to undefined behavior.
+
+Add all missing d*() ctype(3) helper functions and switch to use them.
+
+Noticed by running dillo on NetBSD where dillo crashes due such
+abuses.
+
+See: https://lists.mailman3.com/hyperkitty/list/dillo-dev%mailman3.com@localhost/thread/L6QLXSD6UBDK3M5CMXQMRWD6ZB4C65MR/
+
+--- dlib/dlib.h.orig	2025-01-18 10:51:30.000000000 +0000
++++ dlib/dlib.h
+@@ -1,6 +1,7 @@
+ #ifndef __DLIB_H__
+ #define __DLIB_H__
+ 
++#include <ctype.h>
+ #include <stdio.h>     /* for FILE*  */
+ #include <stddef.h>    /* for size_t */
+ #include <stdarg.h>    /* for va_list */
+@@ -30,8 +31,15 @@ extern "C" {
+ #define MIN(a, b)  (((a) < (b)) ? (a) : (b))
+ 
+ /* Handle signed char */
+-#define dIsspace(c) isspace((uchar_t)(c))
+ #define dIsalnum(c) isalnum((uchar_t)(c))
++#define dIsalpha(c) isalpha((uchar_t)(c))
++#define dIscntrl(c) iscntrl((uchar_t)(c))
++#define dIsdigit(c) isdigit((uchar_t)(c))
++#define dIsprint(c) isprint((uchar_t)(c))
++#define dIspunct(c) ispunct((uchar_t)(c))
++#define dIsspace(c) isspace((uchar_t)(c))
++#define dIsxdigit(c) isxdigit((uchar_t)(c))
++#define dTolower(c) tolower((uchar_t)(c))
+ 
+ #define D_ASCII_TOUPPER(c) (((c) >= 'a' && (c) <= 'z') ? (c) - 0x20 : (c))
+ #define D_ASCII_TOLOWER(c) (((c) >= 'A' && (c) <= 'Z') ? (c) + 0x20 : (c))
diff --git a/dillo/patches/patch-dpi_bookmarks.c b/dillo/patches/patch-dpi_bookmarks.c
index c19d136cc4..0d53316145 100644
--- a/dillo/patches/patch-dpi_bookmarks.c
+++ b/dillo/patches/patch-dpi_bookmarks.c
@@ -1,115 +1,131 @@
 $NetBSD$
 
-Avoid ctype(3) undefined behaviours.
+Avoid ctype(3) abuses
 
-Shared upstream via:
-<https://lists.mailman3.com/hyperkitty/list/dillo-dev%mailman3.com@localhost/thread/L6QLXSD6UBDK3M5CMXQMRWD6ZB4C65MR/>
+Valid argument of ctype(3) functions must be either EOF or non-negative
+value within the range representable as unsigned char.  Invalid values
+leads to undefined behavior.
 
---- dpi/bookmarks.c.orig	2026-01-06 16:25:07.197502866 +0000
+Add all missing d*() ctype(3) helper functions and switch to use them.
+
+Noticed by running dillo on NetBSD where dillo crashes due such
+abuses.
+
+See: https://lists.mailman3.com/hyperkitty/list/dillo-dev%mailman3.com@localhost/thread/L6QLXSD6UBDK3M5CMXQMRWD6ZB4C65MR/
+
+--- dpi/bookmarks.c.orig	2025-01-18 10:51:30.000000000 +0000
 +++ dpi/bookmarks.c
-@@ -338,8 +338,8 @@ static void Unencode_str(char *e_str)
+@@ -26,7 +26,6 @@
+ #include <string.h>
+ #include <unistd.h>
+ #include <errno.h>
+-#include <ctype.h>
+ #include <sys/socket.h>
+ #include <sys/stat.h>
+ #include <sys/types.h>
+@@ -338,8 +337,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));
++            *p = (dIsdigit(e[1]) ? (e[1] - '0') : (e[1] - 'A' + 10)) * 16 +
++                 (dIsdigit(e[2]) ? (e[2] - '0') : (e[2] - 'A' + 10));
              e += 2;
           }
        } else {
-@@ -807,11 +807,11 @@ static void Bmsrv_count_urls_and_section
+@@ -807,11 +806,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);
++         for (i = 0; dIsdigit(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);
++         for (i = 0; dIsdigit(q[2+i]); ++i);
           *n_sec += (q[2+i] == '=') ? 1 : 0;
        }
     }
-@@ -972,7 +972,7 @@ static int Bmsrv_send_modify_update(Dsh 
+@@ -972,7 +971,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);
++         for (i = 0; dIsdigit(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 
+@@ -992,7 +991,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);
++         for (i = 0; dIsdigit(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
+@@ -1060,7 +1059,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])) {
++      if (dIsdigit(p[2])) {
           key = strtol(p + 2, NULL, 10);
           Bms_sec_del(key);
           ++ns;
-@@ -1070,7 +1070,7 @@ static int Bmsrv_modify_delete(char *url
+@@ -1070,7 +1069,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])) {
++      if (dIsdigit(p[4])) {
           key = strtol(p + 4, NULL, 10);
           Bms_del(key);
           ++nb;
-@@ -1105,7 +1105,7 @@ static int Bmsrv_modify_move(char *url)
+@@ -1105,7 +1104,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])) {
++      if (dIsdigit(p[2])) {
           section = strtol(p + 2, NULL, 10);
           break;
        }
-@@ -1116,7 +1116,7 @@ static int Bmsrv_modify_move(char *url)
+@@ -1116,7 +1115,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])) {
++      if (dIsdigit(p[4])) {
           key = strtol(p + 4, NULL, 10);
           Bms_move(key, section);
           ++n;
-@@ -1145,7 +1145,7 @@ static int Bmsrv_modify_update(char *url
+@@ -1145,7 +1144,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);
++         for (i = 0; dIsdigit(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
+@@ -1164,7 +1163,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);
++         for (i = 0; dIsdigit(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,
+@@ -1229,7 +1228,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);
++         for (i = 0; dIsdigit(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
index f0f1d7fd8a..076921a74d 100644
--- a/dillo/patches/patch-dpi_cookies.c
+++ b/dillo/patches/patch-dpi_cookies.c
@@ -1,66 +1,82 @@
 $NetBSD$
 
-Avoid ctype(3) undefined behaviours.
+Avoid ctype(3) abuses
 
-Shared upstream via:
-<https://lists.mailman3.com/hyperkitty/list/dillo-dev%mailman3.com@localhost/thread/L6QLXSD6UBDK3M5CMXQMRWD6ZB4C65MR/>
+Valid argument of ctype(3) functions must be either EOF or non-negative
+value within the range representable as unsigned char.  Invalid values
+leads to undefined behavior.
 
---- dpi/cookies.c.orig	2026-01-06 16:25:07.192584702 +0000
+Add all missing d*() ctype(3) helper functions and switch to use them.
+
+Noticed by running dillo on NetBSD where dillo crashes due such
+abuses.
+
+See: https://lists.mailman3.com/hyperkitty/list/dillo-dev%mailman3.com@localhost/thread/L6QLXSD6UBDK3M5CMXQMRWD6ZB4C65MR/
+
+--- dpi/cookies.c.orig	2025-01-18 10:51:30.000000000 +0000
 +++ dpi/cookies.c
-@@ -487,14 +487,14 @@ static int Cookies_get_timefield(const c
+@@ -44,7 +44,6 @@ int main(void)
+ #include <stdlib.h>
+ #include <stdio.h>
+ #include <time.h>       /* for time() and time_t */
+-#include <ctype.h>
+ #include <limits.h>
+ #include <netdb.h>
+ #include <signal.h>
+@@ -487,14 +486,14 @@ static int Cookies_get_timefield(const c
     int n;
     const char *s = *str;
  
 -   if (!isdigit(*s))
-+   if (!isdigit((unsigned char)*s))
++   if (!dIsdigit(*s))
        return -1;
  
     n = *(s++) - '0';
 -   if (isdigit(*s)) {
-+   if (isdigit((unsigned char)*s)) {
++   if (dIsdigit(*s)) {
        n *= 10;
        n += *(s++) - '0';
 -      if (isdigit(*s))
-+      if (isdigit((unsigned char)*s))
++      if (dIsdigit(*s))
           return -1;
     }
     *str = s;
-@@ -550,24 +550,24 @@ static bool_t Cookies_get_year(struct tm
+@@ -550,24 +549,24 @@ static bool_t Cookies_get_year(struct tm
     int n;
     const char *s = *str;
  
 -   if (isdigit(*s))
-+   if (isdigit((unsigned char)*s))
++   if (dIsdigit(*s))
        n = *(s++) - '0';
     else
        return FALSE;
 -   if (isdigit(*s)) {
-+   if (isdigit((unsigned char)*s)) {
++   if (dIsdigit(*s)) {
        n *= 10;
        n += *(s++) - '0';
     } else
        return FALSE;
 -   if (isdigit(*s)) {
-+   if (isdigit((unsigned char)*s)) {
++   if (dIsdigit(*s)) {
        n *= 10;
        n += *(s++) - '0';
     }
 -   if (isdigit(*s)) {
-+   if (isdigit((unsigned char)*s)) {
++   if (dIsdigit(*s)) {
        n *= 10;
        n += *(s++) - '0';
     }
 -   if (isdigit(*s)) {
-+   if (isdigit((unsigned char)*s)) {
++   if (dIsdigit(*s)) {
        /* Sorry, users of prehistoric software in the year 10000! */
        return FALSE;
     }
-@@ -936,7 +936,7 @@ static CookieData_t *Cookies_parse(char 
+@@ -936,7 +935,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 == '-') {
++         if (dIsdigit(*value) || *value == '-') {
              long age;
              time_t now = time(NULL);
              struct tm *tm = gmtime(&now);
diff --git a/dillo/patches/patch-dpi_datauri.c b/dillo/patches/patch-dpi_datauri.c
new file mode 100644
index 0000000000..5b8f7e9266
--- /dev/null
+++ b/dillo/patches/patch-dpi_datauri.c
@@ -0,0 +1,34 @@
+$NetBSD$
+
+Avoid ctype(3) abuses
+
+Valid argument of ctype(3) functions must be either EOF or non-negative
+value within the range representable as unsigned char.  Invalid values
+leads to undefined behavior.
+
+Add all missing d*() ctype(3) helper functions and switch to use them.
+
+Noticed by running dillo on NetBSD where dillo crashes due such
+abuses.
+
+See: https://lists.mailman3.com/hyperkitty/list/dillo-dev%mailman3.com@localhost/thread/L6QLXSD6UBDK3M5CMXQMRWD6ZB4C65MR/
+
+--- dpi/datauri.c.orig	2025-01-18 10:51:30.000000000 +0000
++++ dpi/datauri.c
+@@ -15,7 +15,6 @@
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+-#include <ctype.h>
+ #include <errno.h>
+ 
+ #include "../dpip/dpip.h"
+@@ -45,7 +44,7 @@ static void b64strip_illegal_chars(unsig
+    MSG("len=%d{%s}\n", strlen((char*)str), str);
+ 
+    for (p = s; (*p = *s); ++s) {
+-      if (d_isascii(*p) && (isalnum(*p) || strchr("+/=", *p)))
++      if (d_isascii(*p) && (dIsalnum(*p) || strchr("+/=", *p)))
+          ++p;
+    }
+ 
diff --git a/dillo/patches/patch-dpi_downloads.cc b/dillo/patches/patch-dpi_downloads.cc
index 4ab5173c28..ccdbc4d7aa 100644
--- a/dillo/patches/patch-dpi_downloads.cc
+++ b/dillo/patches/patch-dpi_downloads.cc
@@ -1,43 +1,59 @@
 $NetBSD$
 
-Avoid ctype(3) undefined behaviours.
+Avoid ctype(3) abuses
 
-Shared upstream via:
-<https://lists.mailman3.com/hyperkitty/list/dillo-dev%mailman3.com@localhost/thread/L6QLXSD6UBDK3M5CMXQMRWD6ZB4C65MR/>
+Valid argument of ctype(3) functions must be either EOF or non-negative
+value within the range representable as unsigned char.  Invalid values
+leads to undefined behavior.
 
---- dpi/downloads.cc.orig	2026-01-06 16:25:07.202386354 +0000
+Add all missing d*() ctype(3) helper functions and switch to use them.
+
+Noticed by running dillo on NetBSD where dillo crashes due such
+abuses.
+
+See: https://lists.mailman3.com/hyperkitty/list/dillo-dev%mailman3.com@localhost/thread/L6QLXSD6UBDK3M5CMXQMRWD6ZB4C65MR/
+
+--- dpi/downloads.cc.orig	2025-01-18 10:51:30.000000000 +0000
 +++ dpi/downloads.cc
-@@ -513,7 +513,7 @@ void DLItem::log_text_add(const char *bu
+@@ -20,7 +20,6 @@
+ #include <unistd.h>
+ #include <errno.h>
+ #include <fcntl.h>
+-#include <ctype.h>
+ #include <math.h>
+ #include <time.h>
+ #include <signal.h>
+@@ -513,7 +512,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)) {
++         } else if (dIsdigit(*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
+@@ -522,10 +521,10 @@ void DLItem::log_text_add(const char *bu
           }
           break;
        case ST_number:
 -         if (isdigit(*q++ = *p)) {
-+         if (isdigit((unsigned char)(*q++ = *p))) {
++         if (dIsdigit((*q++ = *p))) {
              // keep here
           } else if (*p == 'K') {
 -            for (--q; isdigit(q[-1]); --q) ; 
-+            for (--q; isdigit((unsigned char)q[-1]); --q) ; 
++            for (--q; dIsdigit(q[-1]); --q) ;
              log_state = ST_discard;
           } else {
              log_state = ST_copy;
-@@ -549,9 +549,9 @@ void DLItem::log_text_add(const char *bu
+@@ -549,9 +548,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, ' ')) {
++      if (p && dIsdigit(p[9]) && strchr(p + 9, ' ')) {
           for (p += 9, d = &num[0]; *p != ' '; ++p)
 -            if (isdigit(*p))
-+            if (isdigit((unsigned char)*p))
++            if (dIsdigit(*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
index 1e6076ec2a..9aafd55961 100644
--- a/dillo/patches/patch-dpi_dpiutil.c
+++ b/dillo/patches/patch-dpi_dpiutil.c
@@ -1,23 +1,39 @@
 $NetBSD$
 
-Avoid ctype(3) undefined behaviours.
+Avoid ctype(3) abuses
 
-Shared upstream via:
-<https://lists.mailman3.com/hyperkitty/list/dillo-dev%mailman3.com@localhost/thread/L6QLXSD6UBDK3M5CMXQMRWD6ZB4C65MR/>
+Valid argument of ctype(3) functions must be either EOF or non-negative
+value within the range representable as unsigned char.  Invalid values
+leads to undefined behavior.
 
---- dpi/dpiutil.c.orig	2026-01-06 16:25:07.199992497 +0000
+Add all missing d*() ctype(3) helper functions and switch to use them.
+
+Noticed by running dillo on NetBSD where dillo crashes due such
+abuses.
+
+See: https://lists.mailman3.com/hyperkitty/list/dillo-dev%mailman3.com@localhost/thread/L6QLXSD6UBDK3M5CMXQMRWD6ZB4C65MR/
+
+--- dpi/dpiutil.c.orig	2025-01-18 10:51:30.000000000 +0000
 +++ dpi/dpiutil.c
-@@ -67,10 +67,10 @@ char *Unescape_uri_str(const char *s)
+@@ -14,7 +14,6 @@
+ #include <stdio.h>
+ #include <stdarg.h>
+ #include <string.h>
+-#include <ctype.h>
+ #include <errno.h>
+ #include <sys/socket.h>
+ 
+@@ -67,10 +66,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')
++         if (*p == '%' && dIsxdigit(s[1]) && dIsxdigit(s[2])) {
++            *p = (dIsdigit(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')
++            *p += dIsdigit(s[2]) ? (s[2] - '0')
                                  : D_ASCII_TOUPPER(s[2]) - 'A' + 10;
              s += 2;
           }
diff --git a/dillo/patches/patch-dpi_file.c b/dillo/patches/patch-dpi_file.c
new file mode 100644
index 0000000000..c5ea785de5
--- /dev/null
+++ b/dillo/patches/patch-dpi_file.c
@@ -0,0 +1,25 @@
+$NetBSD$
+
+Avoid ctype(3) abuses
+
+Valid argument of ctype(3) functions must be either EOF or non-negative
+value within the range representable as unsigned char.  Invalid values
+leads to undefined behavior.
+
+Add all missing d*() ctype(3) helper functions and switch to use them.
+
+Noticed by running dillo on NetBSD where dillo crashes due such
+abuses.
+
+See: https://lists.mailman3.com/hyperkitty/list/dillo-dev%mailman3.com@localhost/thread/L6QLXSD6UBDK3M5CMXQMRWD6ZB4C65MR/
+
+--- dpi/file.c.orig	2025-01-18 10:51:30.000000000 +0000
++++ dpi/file.c
+@@ -16,7 +16,6 @@
+  * With new HTML layout.
+  */
+ 
+-#include <ctype.h>           /* for isspace */
+ #include <errno.h>           /* for errno */
+ #include <stdio.h>
+ #include <stdlib.h>
diff --git a/dillo/patches/patch-dpi_ftp.c b/dillo/patches/patch-dpi_ftp.c
new file mode 100644
index 0000000000..a6fdda6e4d
--- /dev/null
+++ b/dillo/patches/patch-dpi_ftp.c
@@ -0,0 +1,25 @@
+$NetBSD$
+
+Avoid ctype(3) abuses
+
+Valid argument of ctype(3) functions must be either EOF or non-negative
+value within the range representable as unsigned char.  Invalid values
+leads to undefined behavior.
+
+Add all missing d*() ctype(3) helper functions and switch to use them.
+
+Noticed by running dillo on NetBSD where dillo crashes due such
+abuses.
+
+See: https://lists.mailman3.com/hyperkitty/list/dillo-dev%mailman3.com@localhost/thread/L6QLXSD6UBDK3M5CMXQMRWD6ZB4C65MR/
+
+--- dpi/ftp.c.orig	2025-01-18 10:51:30.000000000 +0000
++++ dpi/ftp.c
+@@ -39,7 +39,6 @@
+ #include <sys/wait.h>
+ #include <errno.h>
+ #include <sys/time.h>
+-#include <ctype.h>
+ 
+ #include "../dpip/dpip.h"
+ #include "dpiutil.h"
diff --git a/dillo/patches/patch-dpid_dpidc.c b/dillo/patches/patch-dpid_dpidc.c
index e7d1caa4a6..3a0814c18f 100644
--- a/dillo/patches/patch-dpid_dpidc.c
+++ b/dillo/patches/patch-dpid_dpidc.c
@@ -1,18 +1,34 @@
 $NetBSD$
 
-Avoid ctype(3) undefined behaviours.
+Avoid ctype(3) abuses
 
-Shared upstream via:
-<https://lists.mailman3.com/hyperkitty/list/dillo-dev%mailman3.com@localhost/thread/L6QLXSD6UBDK3M5CMXQMRWD6ZB4C65MR/>
+Valid argument of ctype(3) functions must be either EOF or non-negative
+value within the range representable as unsigned char.  Invalid values
+leads to undefined behavior.
 
---- dpid/dpidc.c.orig	2026-01-06 16:25:07.204748644 +0000
+Add all missing d*() ctype(3) helper functions and switch to use them.
+
+Noticed by running dillo on NetBSD where dillo crashes due such
+abuses.
+
+See: https://lists.mailman3.com/hyperkitty/list/dillo-dev%mailman3.com@localhost/thread/L6QLXSD6UBDK3M5CMXQMRWD6ZB4C65MR/
+
+--- dpid/dpidc.c.orig	2025-01-18 10:51:30.000000000 +0000
 +++ dpid/dpidc.c
-@@ -59,7 +59,7 @@ static int Dpi_read_comm_keys(int *port)
+@@ -12,7 +12,6 @@
+ #include <stdlib.h>  /* for exit */
+ #include <string.h>  /* for memset */
+ #include <unistd.h>  /* for read and write */
+-#include <ctype.h>   /* for isxdigit */
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <netinet/in.h>
+@@ -59,7 +58,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)
++      for (i = 0; *tail && dIsxdigit(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
index 490688d1ed..4a897e19a5 100644
--- a/dillo/patches/patch-dpip_dpip.c
+++ b/dillo/patches/patch-dpip_dpip.c
@@ -1,18 +1,34 @@
 $NetBSD$
 
-Avoid ctype(3) undefined behaviours.
+Avoid ctype(3) abuses
 
-Shared upstream via:
-<https://lists.mailman3.com/hyperkitty/list/dillo-dev%mailman3.com@localhost/thread/L6QLXSD6UBDK3M5CMXQMRWD6ZB4C65MR/>
+Valid argument of ctype(3) functions must be either EOF or non-negative
+value within the range representable as unsigned char.  Invalid values
+leads to undefined behavior.
 
---- dpip/dpip.c.orig	2026-01-06 16:25:07.209620860 +0000
+Add all missing d*() ctype(3) helper functions and switch to use them.
+
+Noticed by running dillo on NetBSD where dillo crashes due such
+abuses.
+
+See: https://lists.mailman3.com/hyperkitty/list/dillo-dev%mailman3.com@localhost/thread/L6QLXSD6UBDK3M5CMXQMRWD6ZB4C65MR/
+
+--- dpip/dpip.c.orig	2025-01-18 10:51:30.000000000 +0000
 +++ dpip/dpip.c
-@@ -220,7 +220,7 @@ int a_Dpip_check_auth(const char *auth_t
+@@ -15,7 +15,6 @@
+ #include <stdlib.h>
+ #include <stdarg.h>
+ #include <string.h>
+-#include <ctype.h>
+ #include <unistd.h>   /* for close */
+ #include <fcntl.h>    /* for fcntl */
+ 
+@@ -220,7 +219,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)
++         for (i = 0; *tail && dIsxdigit(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
index fbabd13804..0bfb0ebe9a 100644
--- a/dillo/patches/patch-dw_findtext.hh
+++ b/dillo/patches/patch-dw_findtext.hh
@@ -1,20 +1,37 @@
 $NetBSD$
 
-Avoid ctype(3) undefined behaviours.
+Avoid ctype(3) abuses
 
-Shared upstream via:
-<https://lists.mailman3.com/hyperkitty/list/dillo-dev%mailman3.com@localhost/thread/L6QLXSD6UBDK3M5CMXQMRWD6ZB4C65MR/>
+Valid argument of ctype(3) functions must be either EOF or non-negative
+value within the range representable as unsigned char.  Invalid values
+leads to undefined behavior.
 
---- dw/findtext.hh.orig	2026-01-06 16:25:07.212143829 +0000
+Add all missing d*() ctype(3) helper functions and switch to use them.
+
+Noticed by running dillo on NetBSD where dillo crashes due such
+abuses.
+
+See: https://lists.mailman3.com/hyperkitty/list/dillo-dev%mailman3.com@localhost/thread/L6QLXSD6UBDK3M5CMXQMRWD6ZB4C65MR/
+
+--- dw/findtext.hh.orig	2025-01-18 10:51:30.000000000 +0000
 +++ dw/findtext.hh
+@@ -5,7 +5,7 @@
+ #   error Do not include this file directly, use "core.hh" instead.
+ #endif
+ 
+-#include <ctype.h>
++#include "dlib/dlib.h"
+ 
+ namespace dw {
+ namespace core {
 @@ -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)); }
++   { return caseSens ? c1 == c2 : dTolower (c1) == dTolower (c2) ||
++      (dIsspace (c1) && dIsspace (c2)); }
  
  public:
     FindtextState ();
diff --git a/dillo/patches/patch-dw_fltkui.cc b/dillo/patches/patch-dw_fltkui.cc
index cbfd5e5ba6..f5d9adbba0 100644
--- a/dillo/patches/patch-dw_fltkui.cc
+++ b/dillo/patches/patch-dw_fltkui.cc
@@ -1,18 +1,26 @@
 $NetBSD$
 
-Avoid ctype(3) undefined behaviours.
+Avoid ctype(3) abuses
 
-Shared upstream via:
-<https://lists.mailman3.com/hyperkitty/list/dillo-dev%mailman3.com@localhost/thread/L6QLXSD6UBDK3M5CMXQMRWD6ZB4C65MR/>
+Valid argument of ctype(3) functions must be either EOF or non-negative
+value within the range representable as unsigned char.  Invalid values
+leads to undefined behavior.
 
---- dw/fltkui.cc.orig	2026-01-06 16:25:07.215514321 +0000
+Add all missing d*() ctype(3) helper functions and switch to use them.
+
+Noticed by running dillo on NetBSD where dillo crashes due such
+abuses.
+
+See: https://lists.mailman3.com/hyperkitty/list/dillo-dev%mailman3.com@localhost/thread/L6QLXSD6UBDK3M5CMXQMRWD6ZB4C65MR/
+
+--- dw/fltkui.cc.orig	2025-01-18 10:51:30.000000000 +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
++      } else if (dIsalnum(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]);
@@ -20,7 +28,7 @@ Shared upstream via:
                  ;
               else if (mi->label() && mi->active()) { // menu item?
 -                if (k == tolower(mi->label()[0])) {
-+                if (k == tolower((unsigned char)mi->label()[0])) {
++                if (k == dTolower(mi->label()[0])) {
                     value(mi);
                     return 1; // Let FLTK know we used this key
                  }
diff --git a/dillo/patches/patch-dw_style.cc b/dillo/patches/patch-dw_style.cc
new file mode 100644
index 0000000000..8a22b14779
--- /dev/null
+++ b/dillo/patches/patch-dw_style.cc
@@ -0,0 +1,25 @@
+$NetBSD$
+
+Avoid ctype(3) abuses
+
+Valid argument of ctype(3) functions must be either EOF or non-negative
+value within the range representable as unsigned char.  Invalid values
+leads to undefined behavior.
+
+Add all missing d*() ctype(3) helper functions and switch to use them.
+
+Noticed by running dillo on NetBSD where dillo crashes due such
+abuses.
+
+See: https://lists.mailman3.com/hyperkitty/list/dillo-dev%mailman3.com@localhost/thread/L6QLXSD6UBDK3M5CMXQMRWD6ZB4C65MR/
+
+--- dw/style.cc.orig	2025-01-18 10:51:30.000000000 +0000
++++ dw/style.cc
+@@ -20,7 +20,6 @@
+ #include <stdio.h>
+ #include <string.h>
+ #include <unistd.h>
+-#include <ctype.h>
+ #include <math.h>
+ 
+ #include "dlib/dlib.h"
diff --git a/dillo/patches/patch-dw_textblock.cc b/dillo/patches/patch-dw_textblock.cc
index 6d4667dd98..5a88623fe6 100644
--- a/dillo/patches/patch-dw_textblock.cc
+++ b/dillo/patches/patch-dw_textblock.cc
@@ -1,18 +1,26 @@
 $NetBSD$
 
-Avoid ctype(3) undefined behaviours.
+Avoid ctype(3) abuses
 
-Shared upstream via:
-<https://lists.mailman3.com/hyperkitty/list/dillo-dev%mailman3.com@localhost/thread/L6QLXSD6UBDK3M5CMXQMRWD6ZB4C65MR/>
+Valid argument of ctype(3) functions must be either EOF or non-negative
+value within the range representable as unsigned char.  Invalid values
+leads to undefined behavior.
 
---- dw/textblock.cc.orig	2026-01-06 16:25:07.218295539 +0000
+Add all missing d*() ctype(3) helper functions and switch to use them.
+
+Noticed by running dillo on NetBSD where dillo crashes due such
+abuses.
+
+See: https://lists.mailman3.com/hyperkitty/list/dillo-dev%mailman3.com@localhost/thread/L6QLXSD6UBDK3M5CMXQMRWD6ZB4C65MR/
+
+--- dw/textblock.cc.orig	2025-01-18 10:51:30.000000000 +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]))
++                  if (!dIspunct(text[i]))
                       initial_seen = true;
                 if (initial_seen)
                    break;
@@ -20,7 +28,7 @@ Shared upstream via:
                 int after = 0;
                 text += start;
 -               while (ispunct(text[after]))
-+               while (ispunct((unsigned char)text[after]))
++               while (dIspunct(text[after]))
                    after++;
                 if (text[after])
                    after = layout->nextGlyph(text, after);
@@ -29,7 +37,7 @@ Shared upstream via:
  
                 for (int i = 0; i < start; i++)
 -                  if (!ispunct(text[i]))
-+                  if (!ispunct((unsigned char)text[i]))
++                  if (!dIspunct(text[i]))
                       initial_seen = true;
                 if (initial_seen) {
                    ret = layout->textWidth(style->font, text+start, len);
@@ -38,7 +46,7 @@ Shared upstream via:
  
                    text += start;
 -                  while (ispunct(text[after]))
-+                  while (ispunct((unsigned char)text[after]))
++                  while (dIspunct(text[after]))
                       after++;
                    if (text[after])
                       after = layout->nextGlyph(text, after);
diff --git a/dillo/patches/patch-lout_misc.cc b/dillo/patches/patch-lout_misc.cc
new file mode 100644
index 0000000000..98d3e6f8e0
--- /dev/null
+++ b/dillo/patches/patch-lout_misc.cc
@@ -0,0 +1,25 @@
+$NetBSD$
+
+Avoid ctype(3) abuses
+
+Valid argument of ctype(3) functions must be either EOF or non-negative
+value within the range representable as unsigned char.  Invalid values
+leads to undefined behavior.
+
+Add all missing d*() ctype(3) helper functions and switch to use them.
+
+Noticed by running dillo on NetBSD where dillo crashes due such
+abuses.
+
+See: https://lists.mailman3.com/hyperkitty/list/dillo-dev%mailman3.com@localhost/thread/L6QLXSD6UBDK3M5CMXQMRWD6ZB4C65MR/
+
+--- lout/misc.cc.orig	2025-01-18 10:51:30.000000000 +0000
++++ lout/misc.cc
+@@ -21,7 +21,6 @@
+ 
+ #include "misc.hh"
+ 
+-#include <ctype.h>
+ #include <config.h>
+ 
+ #define PRGNAME PACKAGE "/" VERSION
diff --git a/dillo/patches/patch-src_IO_dpi.c b/dillo/patches/patch-src_IO_dpi.c
index 32e868b8e8..e96de4de12 100644
--- a/dillo/patches/patch-src_IO_dpi.c
+++ b/dillo/patches/patch-src_IO_dpi.c
@@ -1,18 +1,34 @@
 $NetBSD$
 
-Avoid ctype(3) undefined behaviours.
+Avoid ctype(3) abuses
 
-Shared upstream via:
-<https://lists.mailman3.com/hyperkitty/list/dillo-dev%mailman3.com@localhost/thread/L6QLXSD6UBDK3M5CMXQMRWD6ZB4C65MR/>
+Valid argument of ctype(3) functions must be either EOF or non-negative
+value within the range representable as unsigned char.  Invalid values
+leads to undefined behavior.
 
---- src/IO/dpi.c.orig	2026-01-06 16:25:07.223239131 +0000
+Add all missing d*() ctype(3) helper functions and switch to use them.
+
+Noticed by running dillo on NetBSD where dillo crashes due such
+abuses.
+
+See: https://lists.mailman3.com/hyperkitty/list/dillo-dev%mailman3.com@localhost/thread/L6QLXSD6UBDK3M5CMXQMRWD6ZB4C65MR/
+
+--- src/IO/dpi.c.orig	2025-01-18 10:51:30.000000000 +0000
 +++ src/IO/dpi.c
-@@ -404,7 +404,7 @@ static int Dpi_read_comm_keys(int *port)
+@@ -25,7 +25,6 @@
+ #include <stdio.h>
+ #include <errno.h>           /* for errno */
+ #include <fcntl.h>
+-#include <ctype.h>           /* isxdigit */
+ #include <stdint.h>
+ 
+ #include <sys/socket.h>
+@@ -404,7 +403,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)
++      for (i = 0; *tail && dIsxdigit(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
index d3aaa07542..5aa2128ecb 100644
--- a/dillo/patches/patch-src_IO_http.c
+++ b/dillo/patches/patch-src_IO_http.c
@@ -1,18 +1,34 @@
 $NetBSD$
 
-Avoid ctype(3) undefined behaviours.
+Avoid ctype(3) abuses
 
-Shared upstream via:
-<https://lists.mailman3.com/hyperkitty/list/dillo-dev%mailman3.com@localhost/thread/L6QLXSD6UBDK3M5CMXQMRWD6ZB4C65MR/>
+Valid argument of ctype(3) functions must be either EOF or non-negative
+value within the range representable as unsigned char.  Invalid values
+leads to undefined behavior.
 
---- src/IO/http.c.orig	2026-01-06 16:25:07.220765195 +0000
+Add all missing d*() ctype(3) helper functions and switch to use them.
+
+Noticed by running dillo on NetBSD where dillo crashes due such
+abuses.
+
+See: https://lists.mailman3.com/hyperkitty/list/dillo-dev%mailman3.com@localhost/thread/L6QLXSD6UBDK3M5CMXQMRWD6ZB4C65MR/
+
+--- src/IO/http.c.orig	2025-01-18 10:51:30.000000000 +0000
 +++ src/IO/http.c
-@@ -701,7 +701,7 @@ static char *Http_get_connect_str(const 
+@@ -17,7 +17,6 @@
+ 
+ #include <config.h>
+ 
+-#include <ctype.h>              /* isdigit */
+ #include <unistd.h>
+ #include <errno.h>              /* for errno */
+ #include <stdlib.h>
+@@ -701,7 +700,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 (auth_len > 0 && !dIsdigit(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
index bb3ef3cbaa..6ec86139f4 100644
--- a/dillo/patches/patch-src_IO_tls__openssl.c
+++ b/dillo/patches/patch-src_IO_tls__openssl.c
@@ -1,35 +1,51 @@
 $NetBSD$
 
-Avoid ctype(3) undefined behaviours.
+Avoid ctype(3) abuses
 
-Shared upstream via:
-<https://lists.mailman3.com/hyperkitty/list/dillo-dev%mailman3.com@localhost/thread/L6QLXSD6UBDK3M5CMXQMRWD6ZB4C65MR/>
+Valid argument of ctype(3) functions must be either EOF or non-negative
+value within the range representable as unsigned char.  Invalid values
+leads to undefined behavior.
 
---- src/IO/tls_openssl.c.orig	2026-01-06 16:25:07.228170607 +0000
+Add all missing d*() ctype(3) helper functions and switch to use them.
+
+Noticed by running dillo on NetBSD where dillo crashes due such
+abuses.
+
+See: https://lists.mailman3.com/hyperkitty/list/dillo-dev%mailman3.com@localhost/thread/L6QLXSD6UBDK3M5CMXQMRWD6ZB4C65MR/
+
+--- src/IO/tls_openssl.c.orig	2025-01-18 10:51:30.000000000 +0000
 +++ src/IO/tls_openssl.c
-@@ -576,13 +576,13 @@ static bool_t pattern_match (const char 
+@@ -39,7 +39,6 @@
+ #include <sys/stat.h>
+ #include <sys/types.h>
+ 
+-#include <ctype.h>            /* tolower for wget stuff */
+ #include <stdio.h>
+ #include <errno.h>
+ #include "../../dlib/dlib.h"
+@@ -576,13 +575,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++)
++  for (; (c = dTolower (*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 (c = dTolower (*p); c == '*'; c = dTolower (*++p))
            ;
          for (; *n != '\0'; n++)
 -          if (tolower (*n) == c && pattern_match (p, n))
-+          if (tolower ((unsigned char)*n) == c && pattern_match (p, n))
++          if (dTolower (*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 
+@@ -592,7 +591,7 @@ static bool_t pattern_match (const char 
        }
      else
        {
 -        if (c != tolower (*n))
-+        if (c != tolower ((unsigned char)*n))
++        if (c != dTolower (*n))
            return FALSE;
        }
    return *n == '\0';
diff --git a/dillo/patches/patch-src_auth.c b/dillo/patches/patch-src_auth.c
new file mode 100644
index 0000000000..0bafbdfaf7
--- /dev/null
+++ b/dillo/patches/patch-src_auth.c
@@ -0,0 +1,34 @@
+$NetBSD$
+
+Avoid ctype(3) abuses
+
+Valid argument of ctype(3) functions must be either EOF or non-negative
+value within the range representable as unsigned char.  Invalid values
+leads to undefined behavior.
+
+Add all missing d*() ctype(3) helper functions and switch to use them.
+
+Noticed by running dillo on NetBSD where dillo crashes due such
+abuses.
+
+See: https://lists.mailman3.com/hyperkitty/list/dillo-dev%mailman3.com@localhost/thread/L6QLXSD6UBDK3M5CMXQMRWD6ZB4C65MR/
+
+--- src/auth.c.orig	2025-01-18 10:51:30.000000000 +0000
++++ src/auth.c
+@@ -17,7 +17,6 @@
+  */
+ 
+ 
+-#include <ctype.h> /* iscntrl, isascii */
+ #include "auth.h"
+ #include "msg.h"
+ #include "misc.h"
+@@ -105,7 +104,7 @@ static int Auth_path_is_inside(const cha
+ static int Auth_is_token_char(char c)
+ {
+    const char *invalid = "\"()<>@,;:\\[]?=/{} \t";
+-   return (!d_isascii(c) || strchr(invalid, c) || iscntrl((uchar_t)c)) ? 0 : 1;
++   return (!d_isascii(c) || strchr(invalid, c) || dIscntrl(c)) ? 0 : 1;
+ }
+ 
+ /**
diff --git a/dillo/patches/patch-src_colors.c b/dillo/patches/patch-src_colors.c
new file mode 100644
index 0000000000..43a6948e4c
--- /dev/null
+++ b/dillo/patches/patch-src_colors.c
@@ -0,0 +1,31 @@
+$NetBSD$
+
+Avoid ctype(3) abuses
+
+Valid argument of ctype(3) functions must be either EOF or non-negative
+value within the range representable as unsigned char.  Invalid values
+leads to undefined behavior.
+
+Add all missing d*() ctype(3) helper functions and switch to use them.
+
+Noticed by running dillo on NetBSD where dillo crashes due such
+abuses.
+
+See: https://lists.mailman3.com/hyperkitty/list/dillo-dev%mailman3.com@localhost/thread/L6QLXSD6UBDK3M5CMXQMRWD6ZB4C65MR/
+
+--- src/colors.c.orig	2025-01-18 10:51:30.000000000 +0000
++++ src/colors.c
+@@ -11,11 +11,12 @@
+ 
+ #include <string.h>
+ #include <stdlib.h>
+-#include <ctype.h>
+ #include "colors.h"
+ 
+ #include "msg.h"
+ 
++#include "../dlib/dlib.h"
++
+ /*
+  * If EXTENDED_COLOR is defined, the extended set of named colors is supported.
+  * These colors're not standard but they're supported in most browsers.
diff --git a/dillo/patches/patch-src_cookies.c b/dillo/patches/patch-src_cookies.c
new file mode 100644
index 0000000000..ed6620896b
--- /dev/null
+++ b/dillo/patches/patch-src_cookies.c
@@ -0,0 +1,25 @@
+$NetBSD$
+
+Avoid ctype(3) abuses
+
+Valid argument of ctype(3) functions must be either EOF or non-negative
+value within the range representable as unsigned char.  Invalid values
+leads to undefined behavior.
+
+Add all missing d*() ctype(3) helper functions and switch to use them.
+
+Noticed by running dillo on NetBSD where dillo crashes due such
+abuses.
+
+See: https://lists.mailman3.com/hyperkitty/list/dillo-dev%mailman3.com@localhost/thread/L6QLXSD6UBDK3M5CMXQMRWD6ZB4C65MR/
+
+--- src/cookies.c.orig	2025-01-18 10:51:30.000000000 +0000
++++ src/cookies.c
+@@ -36,7 +36,6 @@ void a_Cookies_init(void)
+ #include <unistd.h>
+ #include <stdlib.h>
+ #include <stdio.h>
+-#include <ctype.h>
+ #include <errno.h>
+ 
+ #include "IO/Url.h"
diff --git a/dillo/patches/patch-src_cssparser.cc b/dillo/patches/patch-src_cssparser.cc
index f0f794a4f1..4267df8480 100644
--- a/dillo/patches/patch-src_cssparser.cc
+++ b/dillo/patches/patch-src_cssparser.cc
@@ -1,86 +1,111 @@
 $NetBSD$
 
-Avoid ctype(3) undefined behaviours.
+Avoid ctype(3) abuses
 
-Shared upstream via:
-<https://lists.mailman3.com/hyperkitty/list/dillo-dev%mailman3.com@localhost/thread/L6QLXSD6UBDK3M5CMXQMRWD6ZB4C65MR/>
+Valid argument of ctype(3) functions must be either EOF or non-negative
+value within the range representable as unsigned char.  Invalid values
+leads to undefined behavior.
 
---- src/cssparser.cc.orig	2026-01-06 16:25:07.230739234 +0000
+Add all missing d*() ctype(3) helper functions and switch to use them.
+
+Noticed by running dillo on NetBSD where dillo crashes due such
+abuses.
+
+See: https://lists.mailman3.com/hyperkitty/list/dillo-dev%mailman3.com@localhost/thread/L6QLXSD6UBDK3M5CMXQMRWD6ZB4C65MR/
+
+--- src/cssparser.cc.orig	2025-01-18 10:51:30.000000000 +0000
 +++ src/cssparser.cc
-@@ -530,7 +530,7 @@ void CssParser::nextToken()
+@@ -16,7 +16,6 @@
+  * a dillo1 based CSS prototype written by Sebastian Geerken.
+  */
+ 
+-#include <ctype.h>
+ #include <stdlib.h>
+ #include <stdio.h>
+ 
+@@ -530,7 +529,7 @@ void CssParser::nextToken()
  
     while (true) {
        c = getChar();
 -      if (isspace(c)) {                    // ignore whitespace
-+      if (isspace((unsigned char)c)) {                    // ignore whitespace
++      if (dIsspace(c)) {                    // ignore whitespace
           spaceSeparated = true;
        } else if (skipString(c, "/*")) {    // ignore comments
           do {
-@@ -550,7 +550,7 @@ void CssParser::nextToken()
+@@ -550,7 +549,7 @@ void CssParser::nextToken()
        c = getChar();
     }
  
 -   if (isdigit(c)) {
-+   if (isdigit((unsigned char)c)) {
++   if (dIsdigit(c)) {
        ttype = CSS_TK_DECINT;
        do {
           if (i < maxStrLen - 1) {
-@@ -567,7 +567,7 @@ void CssParser::nextToken()
+@@ -558,7 +557,7 @@ void CssParser::nextToken()
+          }
+          /* else silently truncated */
+          c = getChar();
+-      } while (isdigit(c));
++      } while (dIsdigit(c));
+       if (c != '.')
+          ungetChar();
+ 
+@@ -567,7 +566,7 @@ void CssParser::nextToken()
  
     if (c == '.') {
        c = getChar();
 -      if (isdigit(c)) {
-+      if (isdigit((unsigned char)c)) {
++      if (dIsdigit(c)) {
           ttype = CSS_TK_FLOAT;
           if (i < maxStrLen - 1)
              tval[i++] = '.';
-@@ -576,7 +576,7 @@ void CssParser::nextToken()
+@@ -576,7 +575,7 @@ void CssParser::nextToken()
                 tval[i++] = c;
              /* else silently truncated */
              c = getChar();
 -         } while (isdigit(c));
-+         } while (isdigit((unsigned char)c));
++         } while (dIsdigit(c));
  
           ungetChar();
           tval[i] = 0;
-@@ -604,13 +604,13 @@ void CssParser::nextToken()
+@@ -604,13 +603,13 @@ void CssParser::nextToken()
        c = getChar();
     }
  
 -   if (isalpha(c) || c == '_' || c == '-') {
-+   if (isalpha((unsigned char)c) || c == '_' || c == '-') {
++   if (dIsalpha(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 == '-') {
++      while (dIsalnum(c) || c == '_' || c == '-') {
           if (i < maxStrLen - 1) {
              tval[i] = c;
              i++;
-@@ -633,13 +633,13 @@ void CssParser::nextToken()
+@@ -633,13 +632,13 @@ void CssParser::nextToken()
        while (c != EOF && c != c1) {
           if (c == '\\') {
              d = getChar();
 -            if (isxdigit(d)) {
-+            if (isxdigit((unsigned char)d)) {
++            if (dIsxdigit(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)) {
++               while (j < 4 && dIsxdigit(d)) {
                    hexbuf[j] = d;
                    j++;
                    d = getChar();
-@@ -674,7 +674,7 @@ void CssParser::nextToken()
+@@ -674,7 +673,7 @@ void CssParser::nextToken()
        tval[0] = c;
        i = 1;
        c = getChar();
 -      while (isxdigit(c)) {
-+      while (isxdigit((unsigned char)c)) {
++      while (dIsxdigit(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
index 74606e69b6..c273d91b55 100644
--- a/dillo/patches/patch-src_hsts.c
+++ b/dillo/patches/patch-src_hsts.c
@@ -1,18 +1,34 @@
 $NetBSD$
 
-Avoid ctype(3) undefined behaviours.
+Avoid ctype(3) abuses
 
-Shared upstream via:
-<https://lists.mailman3.com/hyperkitty/list/dillo-dev%mailman3.com@localhost/thread/L6QLXSD6UBDK3M5CMXQMRWD6ZB4C65MR/>
+Valid argument of ctype(3) functions must be either EOF or non-negative
+value within the range representable as unsigned char.  Invalid values
+leads to undefined behavior.
 
---- src/hsts.c.orig	2026-01-06 16:25:07.233270206 +0000
+Add all missing d*() ctype(3) helper functions and switch to use them.
+
+Noticed by running dillo on NetBSD where dillo crashes due such
+abuses.
+
+See: https://lists.mailman3.com/hyperkitty/list/dillo-dev%mailman3.com@localhost/thread/L6QLXSD6UBDK3M5CMXQMRWD6ZB4C65MR/
+
+--- src/hsts.c.orig	2025-01-18 10:51:30.000000000 +0000
 +++ src/hsts.c
-@@ -223,7 +223,7 @@ void a_Hsts_set(const char *header, cons
+@@ -26,7 +26,6 @@
+ #include <time.h>
+ #include <errno.h>
+ #include <limits.h> /* for INT_MAX */
+-#include <ctype.h> /* for isspace */
+ #include <stdlib.h> /* for strtol */
+ 
+ #include "hsts.h"
+@@ -223,7 +222,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)) {
++         if (dIsdigit(*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
index 69b409a37e..6cec2d4a97 100644
--- a/dillo/patches/patch-src_html.cc
+++ b/dillo/patches/patch-src_html.cc
@@ -1,158 +1,174 @@
 $NetBSD$
 
-Avoid ctype(3) undefined behaviours.
+Avoid ctype(3) abuses
 
-Shared upstream via:
-<https://lists.mailman3.com/hyperkitty/list/dillo-dev%mailman3.com@localhost/thread/L6QLXSD6UBDK3M5CMXQMRWD6ZB4C65MR/>
+Valid argument of ctype(3) functions must be either EOF or non-negative
+value within the range representable as unsigned char.  Invalid values
+leads to undefined behavior.
 
---- src/html.cc.orig	2026-01-06 16:25:07.239433534 +0000
+Add all missing d*() ctype(3) helper functions and switch to use them.
+
+Noticed by running dillo on NetBSD where dillo crashes due such
+abuses.
+
+See: https://lists.mailman3.com/hyperkitty/list/dillo-dev%mailman3.com@localhost/thread/L6QLXSD6UBDK3M5CMXQMRWD6ZB4C65MR/
+
+--- src/html.cc.orig	2025-01-18 10:51:30.000000000 +0000
 +++ src/html.cc
-@@ -883,7 +883,7 @@ static const char *Html_parse_numeric_ch
+@@ -17,7 +17,6 @@
+ /*-----------------------------------------------------------------------------
+  * Includes
+  *---------------------------------------------------------------------------*/
+-#include <ctype.h>      /* for isspace */
+ #include <string.h>     /* for memcpy and memmove */
+ #include <stdlib.h>
+ #include <stdio.h>      /* for sprintf */
+@@ -883,7 +882,7 @@ static const char *Html_parse_numeric_ch
     errno = 0;
  
     if (*s == 'x' || *s == 'X') {
 -      if (isxdigit(*++s)) {
-+      if (isxdigit((unsigned char)*++s)) {
++      if (dIsxdigit(*++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
+@@ -892,7 +891,7 @@ static const char *Html_parse_numeric_ch
              codepoint = strtol(s, &s, 16);
           }
        }
 -   } else if (isdigit(*s)) {
-+   } else if (isdigit((unsigned char)*s)) {
++   } else if (dIsdigit(*s)) {
        codepoint = strtol(s, &s, 10);
     }
     if (errno)
-@@ -984,7 +984,7 @@ static const char *Html_parse_named_char
+@@ -984,7 +983,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))) ;
++   while (*++s && (dIsalnum(*s) || strchr(":_.-", *s))) ;
     c = *s;
     *s = '\0';
     if (c != ';') {
-@@ -1051,7 +1051,7 @@ static const char *Html_parse_entity(Dil
+@@ -1051,7 +1050,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)) {
++   } else if (dIsalpha(*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 
+@@ -1249,11 +1248,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])) ;
++         if (dIsspace(Pword[i])) {
++            while (Pword[++i] && dIsspace(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])) ;
++            while (Pword[++i] && !dIsspace(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 
+@@ -1287,8 +1286,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])) ;
++         if (dIsspace(word2[i])) {
++            while (word2[++i] && dIsspace(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 
+@@ -1300,7 +1299,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]) &&
++            } while (word2[i] && !dIsspace(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
+@@ -1324,7 +1323,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] == '/'))
++   if (i < tagsize && (dIsspace(tag[i]) || tag[i] == '>' || tag[i] == '/'))
        return true;
     return false;
  }
-@@ -1441,7 +1441,7 @@ CssLength a_Html_parse_length (DilloHtml
+@@ -1441,7 +1440,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)) {
++      if (*end && !dIsspace (*end)) {
           BUG_MSG("Garbage after length: '%s'.", attr);
           l = CSS_CREATE_LENGTH(0.0, CSS_LENGTH_TYPE_AUTO);
        }
-@@ -1487,10 +1487,10 @@ static int
+@@ -1487,10 +1486,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])))
++         if (!d_isascii(val[i]) || !(dIsalnum(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])))
++      if (val[i] || !(d_isascii(val[0]) && dIsalpha(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
+@@ -1537,8 +1536,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) ;
++      if (dIsspace(*p)) {
++         for (ntag[i++] = ' '; dIsspace(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
+@@ -2376,7 +2375,7 @@ misc::SimpleVector<int> *Html_read_coord
           break;
        coords->increase();
        coords->set(coords->size() - 1, coord);
 -      while (isspace(*newtail))
-+      while (isspace((unsigned char)*newtail))
++      while (dIsspace(*newtail))
           newtail++;
        if (!*newtail)
           break;
-@@ -4178,7 +4178,7 @@ static const char *Html_get_attr2(DilloH
+@@ -4178,7 +4177,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]))
++         if (dIsspace(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
+@@ -4186,7 +4185,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] == '>')) {
++             (tag[i] == '=' || dIsspace(tag[i]) || tag[i] == '>')) {
              Found = 1;
              state = SEEK_TOKEN_START;
              --i;
-@@ -4202,14 +4202,14 @@ static const char *Html_get_attr2(DilloH
+@@ -4202,14 +4201,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])) {
++         } else if (!dIsspace(tag[i])) {
              attr_pos = 0;
              state = (Found) ? FINISHED : MATCH_ATTR_NAME;
              --i;
@@ -160,61 +176,61 @@ Shared upstream via:
           break;
        case SEEK_VALUE_START:
 -         if (!isspace(tag[i])) {
-+         if (!isspace((unsigned char)tag[i])) {
++         if (!dIsspace(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
+@@ -4217,11 +4216,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)
++         if ((delimiter == ' ' && dIsspace(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] == '>')) ||
++         if ((delimiter == ' ' && (dIsspace(tag[i]) || tag[i] == '>')) ||
               tag[i] == delimiter) {
              state = FINISHED;
           } else if (tag[i] == '&' &&
-@@ -4252,10 +4252,10 @@ static const char *Html_get_attr2(DilloH
+@@ -4252,10 +4251,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]))
++      while (dIsspace(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]))
++      while (Buf->len && dIsspace(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
+@@ -4349,14 +4348,14 @@ static int Html_write_raw(DilloHtml *htm
              break;
        }
  
 -      if (isspace(buf[buf_index])) {
-+      if (isspace((unsigned char)buf[buf_index])) {
++      if (dIsspace(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])) ;
++         while (++buf_index < bufsize && dIsspace(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)) ) {
++                 (dIsalpha(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
+@@ -4422,7 +4421,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))
++                !dIsalpha(ch) && !strchr("/!?", ch))
                 continue;
              break;
           }
diff --git a/dillo/patches/patch-src_keys.cc b/dillo/patches/patch-src_keys.cc
index b1e67c06ee..c005ba2bfa 100644
--- a/dillo/patches/patch-src_keys.cc
+++ b/dillo/patches/patch-src_keys.cc
@@ -1,27 +1,43 @@
 $NetBSD$
 
-Avoid ctype(3) undefined behaviours.
+Avoid ctype(3) abuses
 
-Shared upstream via:
-<https://lists.mailman3.com/hyperkitty/list/dillo-dev%mailman3.com@localhost/thread/L6QLXSD6UBDK3M5CMXQMRWD6ZB4C65MR/>
+Valid argument of ctype(3) functions must be either EOF or non-negative
+value within the range representable as unsigned char.  Invalid values
+leads to undefined behavior.
 
---- src/keys.cc.orig	2026-01-06 16:25:07.236435264 +0000
+Add all missing d*() ctype(3) helper functions and switch to use them.
+
+Noticed by running dillo on NetBSD where dillo crashes due such
+abuses.
+
+See: https://lists.mailman3.com/hyperkitty/list/dillo-dev%mailman3.com@localhost/thread/L6QLXSD6UBDK3M5CMXQMRWD6ZB4C65MR/
+
+--- src/keys.cc.orig	2025-01-18 10:51:30.000000000 +0000
 +++ src/keys.cc
-@@ -203,7 +203,7 @@ KeysCommand_t Keys::getKeyCmd()
+@@ -14,7 +14,6 @@
+ #include <stdio.h>
+ #include <stdlib.h>        /* strtol */
+ #include <string.h>
+-#include <ctype.h>
+ 
+ #include "dlib/dlib.h"
+ #include "keys.hh"
+@@ -203,7 +202,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])) {
++   if (dIscntrl(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
+@@ -326,7 +325,7 @@ void Keys::parseKey(char *key, char *com
     }
  
     // Skip space
 -   for (  ; isspace(*key); ++key) ;
-+   for (  ; isspace((unsigned char)*key); ++key) ;
++   for (  ; dIsspace(*key); ++key) ;
     // Get modifiers
     while(*key == '<' && (p = strchr(key, '>'))) {
        ++key;
diff --git a/dillo/patches/patch-src_misc.c b/dillo/patches/patch-src_misc.c
new file mode 100644
index 0000000000..b29277ecbc
--- /dev/null
+++ b/dillo/patches/patch-src_misc.c
@@ -0,0 +1,41 @@
+$NetBSD$
+
+Avoid ctype(3) abuses
+
+Valid argument of ctype(3) functions must be either EOF or non-negative
+value within the range representable as unsigned char.  Invalid values
+leads to undefined behavior.
+
+Add all missing d*() ctype(3) helper functions and switch to use them.
+
+Noticed by running dillo on NetBSD where dillo crashes due such
+abuses.
+
+See: https://lists.mailman3.com/hyperkitty/list/dillo-dev%mailman3.com@localhost/thread/L6QLXSD6UBDK3M5CMXQMRWD6ZB4C65MR/
+
+--- src/misc.c.orig	2025-01-18 10:51:30.000000000 +0000
++++ src/misc.c
+@@ -12,7 +12,6 @@
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+-#include <ctype.h>
+ #include <assert.h>
+ 
+ #include "utf8.hh"
+@@ -222,13 +221,13 @@ void a_Misc_parse_content_type(const cha
+    if (!(str = type))
+       return;
+ 
+-   for (s = str; *s && d_isascii((uchar_t)*s) && !iscntrl((uchar_t)*s) &&
++   for (s = str; *s && d_isascii((uchar_t)*s) && !dIscntrl(*s) &&
+         !strchr(tspecials_space, *s); s++) ;
+    if (major)
+       *major = dStrndup(str, s - str);
+ 
+    if (*s == '/') {
+-      for (str = ++s; *s && d_isascii((uchar_t)*s) && !iscntrl((uchar_t)*s) &&
++      for (str = ++s; *s && d_isascii((uchar_t)*s) && !dIscntrl(*s) &&
+            !strchr(tspecials_space, *s); s++) ;
+       if (minor)
+          *minor = dStrndup(str, s - str);
diff --git a/dillo/patches/patch-src_table.cc b/dillo/patches/patch-src_table.cc
index 8aa18238f5..3347ef5715 100644
--- a/dillo/patches/patch-src_table.cc
+++ b/dillo/patches/patch-src_table.cc
@@ -1,18 +1,26 @@
 $NetBSD$
 
-Avoid ctype(3) undefined behaviours.
+Avoid ctype(3) abuses
 
-Shared upstream via:
-<https://lists.mailman3.com/hyperkitty/list/dillo-dev%mailman3.com@localhost/thread/L6QLXSD6UBDK3M5CMXQMRWD6ZB4C65MR/>
+Valid argument of ctype(3) functions must be either EOF or non-negative
+value within the range representable as unsigned char.  Invalid values
+leads to undefined behavior.
 
---- src/table.cc.orig	2026-01-06 16:25:07.244361847 +0000
+Add all missing d*() ctype(3) helper functions and switch to use them.
+
+Noticed by running dillo on NetBSD where dillo crashes due such
+abuses.
+
+See: https://lists.mailman3.com/hyperkitty/list/dillo-dev%mailman3.com@localhost/thread/L6QLXSD6UBDK3M5CMXQMRWD6ZB4C65MR/
+
+--- src/table.cc.orig	2025-01-18 10:51:30.000000000 +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;
++      border = dIsdigit(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-src_url.c b/dillo/patches/patch-src_url.c
new file mode 100644
index 0000000000..15dba23020
--- /dev/null
+++ b/dillo/patches/patch-src_url.c
@@ -0,0 +1,25 @@
+$NetBSD$
+
+Avoid ctype(3) abuses
+
+Valid argument of ctype(3) functions must be either EOF or non-negative
+value within the range representable as unsigned char.  Invalid values
+leads to undefined behavior.
+
+Add all missing d*() ctype(3) helper functions and switch to use them.
+
+Noticed by running dillo on NetBSD where dillo crashes due such
+abuses.
+
+See: https://lists.mailman3.com/hyperkitty/list/dillo-dev%mailman3.com@localhost/thread/L6QLXSD6UBDK3M5CMXQMRWD6ZB4C65MR/
+
+--- src/url.c.orig	2025-01-18 10:51:30.000000000 +0000
++++ src/url.c
+@@ -44,7 +44,6 @@
+ 
+ #include <stdlib.h>
+ #include <string.h>
+-#include <ctype.h>
+ 
+ #include "url.h"
+ #include "hsts.h"
diff --git a/dillo/patches/patch-src_xembed.cc b/dillo/patches/patch-src_xembed.cc
new file mode 100644
index 0000000000..c6da91fc26
--- /dev/null
+++ b/dillo/patches/patch-src_xembed.cc
@@ -0,0 +1,25 @@
+$NetBSD$
+
+Avoid ctype(3) abuses
+
+Valid argument of ctype(3) functions must be either EOF or non-negative
+value within the range representable as unsigned char.  Invalid values
+leads to undefined behavior.
+
+Add all missing d*() ctype(3) helper functions and switch to use them.
+
+Noticed by running dillo on NetBSD where dillo crashes due such
+abuses.
+
+See: https://lists.mailman3.com/hyperkitty/list/dillo-dev%mailman3.com@localhost/thread/L6QLXSD6UBDK3M5CMXQMRWD6ZB4C65MR/
+
+--- src/xembed.cc.orig	2025-01-18 10:51:30.000000000 +0000
++++ src/xembed.cc
+@@ -10,7 +10,6 @@
+  */
+ 
+ #include <string.h>
+-#include <ctype.h>
+ 
+ #define FL_INTERNALS
+ #include <FL/Fl_Window.H>
diff --git a/dillo/patches/patch-test_dw_dw__anchors__test.cc b/dillo/patches/patch-test_dw_dw__anchors__test.cc
new file mode 100644
index 0000000000..b17a0371f5
--- /dev/null
+++ b/dillo/patches/patch-test_dw_dw__anchors__test.cc
@@ -0,0 +1,25 @@
+$NetBSD$
+
+Avoid ctype(3) abuses
+
+Valid argument of ctype(3) functions must be either EOF or non-negative
+value within the range representable as unsigned char.  Invalid values
+leads to undefined behavior.
+
+Add all missing d*() ctype(3) helper functions and switch to use them.
+
+Noticed by running dillo on NetBSD where dillo crashes due such
+abuses.
+
+See: https://lists.mailman3.com/hyperkitty/list/dillo-dev%mailman3.com@localhost/thread/L6QLXSD6UBDK3M5CMXQMRWD6ZB4C65MR/
+
+--- test/dw/dw_anchors_test.cc.orig	2025-01-18 10:51:30.000000000 +0000
++++ test/dw/dw_anchors_test.cc
+@@ -20,7 +20,6 @@
+ 
+ 
+ 
+-#include <ctype.h>
+ #include <FL/Fl_Window.H>
+ #include <FL/Fl.H>
+ 
diff --git a/dillo/patches/patch-test_unit_cookies.c b/dillo/patches/patch-test_unit_cookies.c
index 8b855b739a..782095ea68 100644
--- a/dillo/patches/patch-test_unit_cookies.c
+++ b/dillo/patches/patch-test_unit_cookies.c
@@ -1,18 +1,34 @@
 $NetBSD$
 
-Avoid ctype(3) undefined behaviours.
+Avoid ctype(3) abuses
 
-Shared upstream via:
-<https://lists.mailman3.com/hyperkitty/list/dillo-dev%mailman3.com@localhost/thread/L6QLXSD6UBDK3M5CMXQMRWD6ZB4C65MR/>
+Valid argument of ctype(3) functions must be either EOF or non-negative
+value within the range representable as unsigned char.  Invalid values
+leads to undefined behavior.
 
---- test/unit/cookies.c.orig	2026-01-06 16:25:07.246777391 +0000
+Add all missing d*() ctype(3) helper functions and switch to use them.
+
+Noticed by running dillo on NetBSD where dillo crashes due such
+abuses.
+
+See: https://lists.mailman3.com/hyperkitty/list/dillo-dev%mailman3.com@localhost/thread/L6QLXSD6UBDK3M5CMXQMRWD6ZB4C65MR/
+
+--- test/unit/cookies.c.orig	2025-01-18 10:51:30.000000000 +0000
 +++ test/unit/cookies.c
-@@ -126,7 +126,7 @@ static int Dpi_read_comm_keys(int *port)
+@@ -26,7 +26,6 @@
+ #include <stdarg.h>  /* va_list */
+ #include <string.h> /* strchr */
+ #include <errno.h>
+-#include <ctype.h>
+ #include <time.h>
+ /* net */
+ #include <sys/types.h>
+@@ -126,7 +125,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)
++      for (i = 0; *tail && dIsxdigit(tail[i+1]); ++i)
           SharedKey[i] = tail[i+1];
        SharedKey[i] = 0;
        ret = 1;


Home | Main Index | Thread Index | Old Index