Re: [PATCHES] www/w3m bug fixes

2015-01-10 Thread Scarlett
On Fri, Jan 09, 2015 at 08:22:13PM -0500, Brian Callahan wrote:
> 
> On 01/07/15 15:32, Scarlett wrote:
> > Updated diff to bump revision (whoops), and carrying over the change to use
> > overflow-detecting malloc to matrix.c (patch-matrix_c). I forgot about
> > this because my local fork of w3m has been fixed to build without MATRIX.
> 
> I think this is fine. I will note that you need to add RCS ID tags at
> the top of every patch file (make update-patches is kind enough to do
> this for you, for future reference). But besides that one nit w3m looks
> like it works as expected. It's too bad you can't get all this
> upstreamed (or can you?).
> 
> Anyone else want to weigh in/give oks?
> 
> ~Brian

RCS tags added, and thank you.

My full diff against w3m-0.5.3 is much larger, and includes changes
such as the code being completely reformatted, DOS/Windows #ifdefs
removed, modern C changes (const, enums, using size_t instead of
int everywhere), attributes added to GC string library functions,
TLS support rewritten to use the unfinalized libtls API
(an older w3m had a CVE because of a flaw in the SSL code...),
NNTP support removed, Gopher support improved (:3), and a
restructuring of the build system using BSD make instead of autotools.

Backporting every change would take a long time and I doubt upstream
would be interested in a lot of the changes even if it was active.

I wouldn't object to becoming upstream if there is interest, but I
would definitely want to subject the code to more refactoring and
auditing before making a release.

Index: Makefile
===
RCS file: /cvs/ports/www/w3m/Makefile,v
retrieving revision 1.84
diff -u -p -r1.84 Makefile
--- Makefile16 Jul 2014 08:20:01 -  1.84
+++ Makefile10 Jan 2015 16:06:37 -
@@ -3,7 +3,7 @@
 COMMENT=   pager/text-based web browser
 
 DISTNAME=  w3m-0.5.3
-REVISION=  3
+REVISION=  4
 CATEGORIES=www
 HOMEPAGE=  http://w3m.sourceforge.net/
 
@@ -50,6 +50,9 @@ DOCSRC=   ${WRKSRC}/doc-jp
 CONFIGURE_ARGS+=--enable-m17n=ISO-8859-1
 DOCSRC=${WRKSRC}/doc
 .endif
+
+post-patch:
+   @cp ${FILESDIR}/alloc.h ${WRKSRC}
 
 post-install:
${INSTALL_DATA_DIR} ${PREFIX}/share/doc/w3m
Index: files/alloc.h
===
RCS file: files/alloc.h
diff -N files/alloc.h
--- /dev/null   1 Jan 1970 00:00:00 -
+++ files/alloc.h   10 Jan 2015 16:06:37 -
@@ -0,0 +1,40 @@
+$OpenBSD$
+/*
+ * by Scarlett. public domain.
+ * replacements for w3m's allocation macros which add overflow
+ * detection and concentrate the macros in one file
+ */
+#ifndef W3_ALLOC_H
+#define W3_ALLOC_H
+#include 
+#include 
+#include 
+#include 
+
+static inline size_t
+z_mult_no_oflow_(size_t n, size_t size)
+{
+   if (size != 0 && n > SIZE_MAX / size) {
+   fprintf(stderr,
+   "w3m: overflow in malloc, %zu*%zu\n", n, size);
+   exit(1);
+   }
+   return n * size;
+}
+
+#define New(type) \
+   (GC_MALLOC(sizeof(type)))
+
+#define NewAtom(type) \
+   (GC_MALLOC_ATOMIC(sizeof(type)))
+
+#define New_N(type, n) \
+   (GC_MALLOC(z_mult_no_oflow_((n), sizeof(type
+
+#define NewAtom_N(type, n) \
+   (GC_MALLOC_ATOMIC(z_mult_no_oflow_((n), sizeof(type
+
+#define New_Reuse(type, ptr, n) \
+   (GC_REALLOC((ptr), z_mult_no_oflow_((n), sizeof(type
+
+#endif /* W3_ALLOC_H */
Index: patches/patch-Str_c
===
RCS file: patches/patch-Str_c
diff -N patches/patch-Str_c
--- /dev/null   1 Jan 1970 00:00:00 -
+++ patches/patch-Str_c 10 Jan 2015 16:06:37 -
@@ -0,0 +1,129 @@
+$OpenBSD$
+
+Use asprintf() instead of rolling our own printf string length detection.
+
+--- Str.c.orig Mon Jan  5 22:49:07 2015
 Str.c  Mon Jan  5 22:52:59 2015
+@@ -427,103 +427,27 @@
+ Str
+ Sprintf(char *fmt, ...)
+ {
+-int len = 0;
+-int status = SP_NORMAL;
+-int p = 0;
+-char *f;
+-Str s;
+-va_list ap;
++  Str s;
++  char *cb;
++  int ret;
++  size_t n;
++  va_list ap;
+ 
+-va_start(ap, fmt);
+-for (f = fmt; *f; f++) {
+-  redo:
+-  switch (status) {
+-  case SP_NORMAL:
+-  if (*f == '%') {
+-  status = SP_PREC;
+-  p = 0;
+-  }
+-  else
+-  len++;
+-  break;
+-  case SP_PREC:
+-  if (IS_ALPHA(*f)) {
+-  /* conversion char. */
+-  double vd;
+-  int vi;
+-  char *vs;
+-  void *vp;
+-
+-  switch (*f) {
+-  case 'l':
+-  case 'h':
+-  case 'L':
+-  case 'w':
+-  continue;
+-  case 'd':
+-  case 'i':
+-  case 'o':
+-  case 'x':
+-  case 'X':
+-  case '

Re: [PATCHES] www/w3m bug fixes

2015-01-09 Thread Brian Callahan

On 01/07/15 15:32, Scarlett wrote:
> Updated diff to bump revision (whoops), and carrying over the change to use
> overflow-detecting malloc to matrix.c (patch-matrix_c). I forgot about
> this because my local fork of w3m has been fixed to build without MATRIX.

I think this is fine. I will note that you need to add RCS ID tags at
the top of every patch file (make update-patches is kind enough to do
this for you, for future reference). But besides that one nit w3m looks
like it works as expected. It's too bad you can't get all this
upstreamed (or can you?).

Anyone else want to weigh in/give oks?

~Brian

> Index: w3m/Makefile
> ===
> RCS file: /cvs/ports/www/w3m/Makefile,v
> retrieving revision 1.84
> diff -u -p -r1.84 Makefile
> --- w3m/Makefile  16 Jul 2014 08:20:01 -  1.84
> +++ w3m/Makefile  7 Jan 2015 20:21:59 -
> @@ -3,7 +3,7 @@
>  COMMENT= pager/text-based web browser
>  
>  DISTNAME=w3m-0.5.3
> -REVISION=3
> +REVISION=4
>  CATEGORIES=  www
>  HOMEPAGE=http://w3m.sourceforge.net/
>  
> @@ -50,6 +50,9 @@ DOCSRC= ${WRKSRC}/doc-jp
>  CONFIGURE_ARGS+=--enable-m17n=ISO-8859-1
>  DOCSRC=  ${WRKSRC}/doc
>  .endif
> +
> +post-patch:
> + @cp ${FILESDIR}/alloc.h ${WRKSRC}
>  
>  post-install:
>   ${INSTALL_DATA_DIR} ${PREFIX}/share/doc/w3m
> Index: w3m/files/alloc.h
> ===
> RCS file: w3m/files/alloc.h
> diff -N w3m/files/alloc.h
> --- /dev/null 1 Jan 1970 00:00:00 -
> +++ w3m/files/alloc.h 7 Jan 2015 20:21:59 -
> @@ -0,0 +1,39 @@
> +/*
> + * by Scarlett. public domain.
> + * replacements for w3m's allocation macros which add overflow
> + * detection and concentrate the macros in one file
> + */
> +#ifndef W3_ALLOC_H
> +#define W3_ALLOC_H
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +static inline size_t
> +z_mult_no_oflow_(size_t n, size_t size)
> +{
> + if (size != 0 && n > SIZE_MAX / size) {
> + fprintf(stderr,
> + "w3m: overflow in malloc, %zu*%zu\n", n, size);
> + exit(1);
> + }
> + return n * size;
> +}
> +
> +#define New(type) \
> + (GC_MALLOC(sizeof(type)))
> +
> +#define NewAtom(type) \
> + (GC_MALLOC_ATOMIC(sizeof(type)))
> +
> +#define New_N(type, n) \
> + (GC_MALLOC(z_mult_no_oflow_((n), sizeof(type
> +
> +#define NewAtom_N(type, n) \
> + (GC_MALLOC_ATOMIC(z_mult_no_oflow_((n), sizeof(type
> +
> +#define New_Reuse(type, ptr, n) \
> + (GC_REALLOC((ptr), z_mult_no_oflow_((n), sizeof(type
> +
> +#endif /* W3_ALLOC_H */
> Index: w3m/patches/patch-Str_c
> ===
> RCS file: w3m/patches/patch-Str_c
> diff -N w3m/patches/patch-Str_c
> --- /dev/null 1 Jan 1970 00:00:00 -
> +++ w3m/patches/patch-Str_c   7 Jan 2015 20:21:59 -
> @@ -0,0 +1,127 @@
> +Use asprintf() instead of rolling our own printf string length detection.
> +
> +--- Str.c.orig   Mon Jan  5 22:49:07 2015
>  Str.cMon Jan  5 22:52:59 2015
> +@@ -427,103 +427,27 @@
> + Str
> + Sprintf(char *fmt, ...)
> + {
> +-int len = 0;
> +-int status = SP_NORMAL;
> +-int p = 0;
> +-char *f;
> +-Str s;
> +-va_list ap;
> ++Str s;
> ++char *cb;
> ++int ret;
> ++size_t n;
> ++va_list ap;
> + 
> +-va_start(ap, fmt);
> +-for (f = fmt; *f; f++) {
> +-  redo:
> +-switch (status) {
> +-case SP_NORMAL:
> +-if (*f == '%') {
> +-status = SP_PREC;
> +-p = 0;
> +-}
> +-else
> +-len++;
> +-break;
> +-case SP_PREC:
> +-if (IS_ALPHA(*f)) {
> +-/* conversion char. */
> +-double vd;
> +-int vi;
> +-char *vs;
> +-void *vp;
> +-
> +-switch (*f) {
> +-case 'l':
> +-case 'h':
> +-case 'L':
> +-case 'w':
> +-continue;
> +-case 'd':
> +-case 'i':
> +-case 'o':
> +-case 'x':
> +-case 'X':
> +-case 'u':
> +-vi = va_arg(ap, int);
> +-len += (p > 0) ? p : 10;
> +-break;
> +-case 'f':
> +-case 'g':
> +-case 'e':
> +-case 'G':
> +-case 'E':
> +-vd = va_arg(ap, double);
> +-len += (p > 0) ? p : 15;
> +-break;
> +-case 'c':
> +-len += 1;
> +-vi = va_arg(ap, int);
> +-break;
> +-case 's':
> +-vs = va_arg(ap, char *);
> +-vi = strlen(vs);
> +-len += (p > vi) ? p : vi;
> +-break;
> +-case 'p':
> +-vp = va_arg(ap, void *);
> +-len += 10;
> 

Re: [PATCHES] www/w3m bug fixes

2015-01-07 Thread Scarlett
Updated diff to bump revision (whoops), and carrying over the change to use
overflow-detecting malloc to matrix.c (patch-matrix_c). I forgot about
this because my local fork of w3m has been fixed to build without MATRIX.

Index: w3m/Makefile
===
RCS file: /cvs/ports/www/w3m/Makefile,v
retrieving revision 1.84
diff -u -p -r1.84 Makefile
--- w3m/Makefile16 Jul 2014 08:20:01 -  1.84
+++ w3m/Makefile7 Jan 2015 20:21:59 -
@@ -3,7 +3,7 @@
 COMMENT=   pager/text-based web browser
 
 DISTNAME=  w3m-0.5.3
-REVISION=  3
+REVISION=  4
 CATEGORIES=www
 HOMEPAGE=  http://w3m.sourceforge.net/
 
@@ -50,6 +50,9 @@ DOCSRC=   ${WRKSRC}/doc-jp
 CONFIGURE_ARGS+=--enable-m17n=ISO-8859-1
 DOCSRC=${WRKSRC}/doc
 .endif
+
+post-patch:
+   @cp ${FILESDIR}/alloc.h ${WRKSRC}
 
 post-install:
${INSTALL_DATA_DIR} ${PREFIX}/share/doc/w3m
Index: w3m/files/alloc.h
===
RCS file: w3m/files/alloc.h
diff -N w3m/files/alloc.h
--- /dev/null   1 Jan 1970 00:00:00 -
+++ w3m/files/alloc.h   7 Jan 2015 20:21:59 -
@@ -0,0 +1,39 @@
+/*
+ * by Scarlett. public domain.
+ * replacements for w3m's allocation macros which add overflow
+ * detection and concentrate the macros in one file
+ */
+#ifndef W3_ALLOC_H
+#define W3_ALLOC_H
+#include 
+#include 
+#include 
+#include 
+
+static inline size_t
+z_mult_no_oflow_(size_t n, size_t size)
+{
+   if (size != 0 && n > SIZE_MAX / size) {
+   fprintf(stderr,
+   "w3m: overflow in malloc, %zu*%zu\n", n, size);
+   exit(1);
+   }
+   return n * size;
+}
+
+#define New(type) \
+   (GC_MALLOC(sizeof(type)))
+
+#define NewAtom(type) \
+   (GC_MALLOC_ATOMIC(sizeof(type)))
+
+#define New_N(type, n) \
+   (GC_MALLOC(z_mult_no_oflow_((n), sizeof(type
+
+#define NewAtom_N(type, n) \
+   (GC_MALLOC_ATOMIC(z_mult_no_oflow_((n), sizeof(type
+
+#define New_Reuse(type, ptr, n) \
+   (GC_REALLOC((ptr), z_mult_no_oflow_((n), sizeof(type
+
+#endif /* W3_ALLOC_H */
Index: w3m/patches/patch-Str_c
===
RCS file: w3m/patches/patch-Str_c
diff -N w3m/patches/patch-Str_c
--- /dev/null   1 Jan 1970 00:00:00 -
+++ w3m/patches/patch-Str_c 7 Jan 2015 20:21:59 -
@@ -0,0 +1,127 @@
+Use asprintf() instead of rolling our own printf string length detection.
+
+--- Str.c.orig Mon Jan  5 22:49:07 2015
 Str.c  Mon Jan  5 22:52:59 2015
+@@ -427,103 +427,27 @@
+ Str
+ Sprintf(char *fmt, ...)
+ {
+-int len = 0;
+-int status = SP_NORMAL;
+-int p = 0;
+-char *f;
+-Str s;
+-va_list ap;
++  Str s;
++  char *cb;
++  int ret;
++  size_t n;
++  va_list ap;
+ 
+-va_start(ap, fmt);
+-for (f = fmt; *f; f++) {
+-  redo:
+-  switch (status) {
+-  case SP_NORMAL:
+-  if (*f == '%') {
+-  status = SP_PREC;
+-  p = 0;
+-  }
+-  else
+-  len++;
+-  break;
+-  case SP_PREC:
+-  if (IS_ALPHA(*f)) {
+-  /* conversion char. */
+-  double vd;
+-  int vi;
+-  char *vs;
+-  void *vp;
+-
+-  switch (*f) {
+-  case 'l':
+-  case 'h':
+-  case 'L':
+-  case 'w':
+-  continue;
+-  case 'd':
+-  case 'i':
+-  case 'o':
+-  case 'x':
+-  case 'X':
+-  case 'u':
+-  vi = va_arg(ap, int);
+-  len += (p > 0) ? p : 10;
+-  break;
+-  case 'f':
+-  case 'g':
+-  case 'e':
+-  case 'G':
+-  case 'E':
+-  vd = va_arg(ap, double);
+-  len += (p > 0) ? p : 15;
+-  break;
+-  case 'c':
+-  len += 1;
+-  vi = va_arg(ap, int);
+-  break;
+-  case 's':
+-  vs = va_arg(ap, char *);
+-  vi = strlen(vs);
+-  len += (p > vi) ? p : vi;
+-  break;
+-  case 'p':
+-  vp = va_arg(ap, void *);
+-  len += 10;
+-  break;
+-  case 'n':
+-  vp = va_arg(ap, void *);
+-  break;
+-  }
+-  status = SP_NORMAL;
+-  }
+-  else if (IS_DIGIT(*f))
+-  p = p * 10 + *f - '0';
+-  else if (*f == '.')
+-  status = SP_PREC2;
+-  else if (*f == '%') {
+-  status = SP_NORMAL;
+-  len++;
+-  }
+-  break;
+-  case SP_PREC2:
+-  if (IS_ALPHA(*f)) {
+-  status = 

Re: [PATCHES] www/w3m bug fixes

2015-01-06 Thread Scarlett
On Tue, Jan 06, 2015 at 01:42:49AM -0500, Brian Callahan wrote:
> Hi Scarlett --
> 
> I don't have time to do more than eyeball this right now, but I just
> want to make two quick comments:
> 1. Usually we use CVS to send patches. Lets you send a single file
> instead of a whole tarball :-)
> But that aside...
> 2. Could you put all this nice information into the patches themselves?
> Partly for attribution, partly to see quickly what each patch is doing
> and why, and partly because it makes it easier to track future bug fixes
> from those same sources.
> 
> ~Brian
>

Thanks for your quick response, Brian. I've added descriptions to the top
of each patch.


Index: w3m/Makefile
===
RCS file: /cvs/ports/www/w3m/Makefile,v
retrieving revision 1.84
diff -u -p -u -r1.84 Makefile
--- w3m/Makefile16 Jul 2014 08:20:01 -  1.84
+++ w3m/Makefile6 Jan 2015 09:16:56 -
@@ -51,6 +51,9 @@ CONFIGURE_ARGS+=--enable-m17n=ISO-8859-1
 DOCSRC=${WRKSRC}/doc
 .endif
 
+post-patch:
+   @cp ${FILESDIR}/alloc.h ${WRKSRC}
+
 post-install:
${INSTALL_DATA_DIR} ${PREFIX}/share/doc/w3m
cd ${DOCSRC}; \
Index: w3m/files/alloc.h
===
RCS file: w3m/files/alloc.h
diff -N w3m/files/alloc.h
--- /dev/null   1 Jan 1970 00:00:00 -
+++ w3m/files/alloc.h   6 Jan 2015 09:16:56 -
@@ -0,0 +1,39 @@
+/*
+ * by Scarlett. public domain.
+ * replacements for w3m's allocation macros which add overflow
+ * detection and concentrate the macros in one file
+ */
+#ifndef W3_ALLOC_H
+#define W3_ALLOC_H
+#include 
+#include 
+#include 
+#include 
+
+static inline size_t
+z_mult_no_oflow_(size_t n, size_t size)
+{
+   if (size != 0 && n > SIZE_MAX / size) {
+   fprintf(stderr,
+   "w3m: overflow in malloc, %zu*%zu\n", n, size);
+   exit(1);
+   }
+   return n * size;
+}
+
+#define New(type) \
+   (GC_MALLOC(sizeof(type)))
+
+#define NewAtom(type) \
+   (GC_MALLOC_ATOMIC(sizeof(type)))
+
+#define New_N(type, n) \
+   (GC_MALLOC(z_mult_no_oflow_((n), sizeof(type
+
+#define NewAtom_N(type, n) \
+   (GC_MALLOC_ATOMIC(z_mult_no_oflow_((n), sizeof(type
+
+#define New_Reuse(type, ptr, n) \
+   (GC_REALLOC((ptr), z_mult_no_oflow_((n), sizeof(type
+
+#endif /* W3_ALLOC_H */
Index: w3m/patches/patch-Str_c
===
RCS file: w3m/patches/patch-Str_c
diff -N w3m/patches/patch-Str_c
--- /dev/null   1 Jan 1970 00:00:00 -
+++ w3m/patches/patch-Str_c 6 Jan 2015 09:16:56 -
@@ -0,0 +1,127 @@
+Use asprintf() instead of rolling our own printf string length detection.
+
+--- Str.c.orig Mon Jan  5 22:49:07 2015
 Str.c  Mon Jan  5 22:52:59 2015
+@@ -427,103 +427,27 @@
+ Str
+ Sprintf(char *fmt, ...)
+ {
+-int len = 0;
+-int status = SP_NORMAL;
+-int p = 0;
+-char *f;
+-Str s;
+-va_list ap;
++  Str s;
++  char *cb;
++  int ret;
++  size_t n;
++  va_list ap;
+ 
+-va_start(ap, fmt);
+-for (f = fmt; *f; f++) {
+-  redo:
+-  switch (status) {
+-  case SP_NORMAL:
+-  if (*f == '%') {
+-  status = SP_PREC;
+-  p = 0;
+-  }
+-  else
+-  len++;
+-  break;
+-  case SP_PREC:
+-  if (IS_ALPHA(*f)) {
+-  /* conversion char. */
+-  double vd;
+-  int vi;
+-  char *vs;
+-  void *vp;
+-
+-  switch (*f) {
+-  case 'l':
+-  case 'h':
+-  case 'L':
+-  case 'w':
+-  continue;
+-  case 'd':
+-  case 'i':
+-  case 'o':
+-  case 'x':
+-  case 'X':
+-  case 'u':
+-  vi = va_arg(ap, int);
+-  len += (p > 0) ? p : 10;
+-  break;
+-  case 'f':
+-  case 'g':
+-  case 'e':
+-  case 'G':
+-  case 'E':
+-  vd = va_arg(ap, double);
+-  len += (p > 0) ? p : 15;
+-  break;
+-  case 'c':
+-  len += 1;
+-  vi = va_arg(ap, int);
+-  break;
+-  case 's':
+-  vs = va_arg(ap, char *);
+-  vi = strlen(vs);
+-  len += (p > vi) ? p : vi;
+-  break;
+-  case 'p':
+-  vp = va_arg(ap, void *);
+-  len += 10;
+-  break;
+-  case 'n':
+-  vp = va_arg(ap, void *);
+-  break;
+-  }
+-  status = SP_NORMAL;
+-  }
+-  else if (IS_DIGIT(*f))
+-  p = p * 10 + *f - '0';
+-  else if (*f == '.')

Re: [PATCHES] www/w3m bug fixes

2015-01-05 Thread Brian Callahan
Hi Scarlett --

On 01/06/15 01:10, Scarlett wrote:
> This archive contains patches for several problems I have found
> while hacking on www/w3m, as well as several bug fixes taken from
> elsewhere.

I don't have time to do more than eyeball this right now, but I just
want to make two quick comments:
1. Usually we use CVS to send patches. Lets you send a single file
instead of a whole tarball :-)
But that aside...
2. Could you put all this nice information into the patches themselves?
Partly for attribution, partly to see quickly what each patch is doing
and why, and partly because it makes it easier to track future bug fixes
from those same sources.

~Brian

> --
>
> Ported patches
>
> * Use "%s" to printf a string, from Colin Watson at Ubuntu
> http://anonscm.debian.org/cgit/collab-maint/w3m.git/commit/?h=bug/646321
>
> * Fix a null pointer deref when parsing "" in HTML, from olh
> at suse dot de
> https://build.opensuse.org/package/view_file/openSUSE:Factory/w3m/w3m-closedir.patch?expand=1
>
> * Fix a directory descriptor leak, from max at suse dot de
> https://build.opensuse.org/package/view_file/openSUSE:Factory/w3m/w3m-parsetagx-crash.patch?expand=1
>
> * exit(1) when out of memory, since malloc's return value is never checked
> anywhere in the program. inspired by an old patch by dugsong@ which got
> sent to the cvs attic when w3m was updated in the distant past
> http://cvsweb.openbsd.org/cgi-bin/cvsweb/ports/www/w3m/patches/Attic/patch-ac
>
> --
>
> My patches
>
> * Various printf format string fixes:
>
>   * Instead of printing a "Str" structure with %s, print the
> char pointer inside it with %s.
>   * Use %ld to print long, not %d
>   * Use %zu to print size_t, not %d
>   * Use %lld to print time_t, not %ld
>
> * Change hand-rolled and suspicious sprintf implementation in Str.c to
> use asprintf() from libc.
>
> * Move "New()" gc alloc macros to a header file and add overflow checks to
> the "allocate an array" macros.
>
> --
>
> w3m's code is disgusting, and upstream is mostly dead with occasional
> patches ported from debian. However, it is one of the more usable web
> browsers (and the only curses browser with inline images, iirc).
> Fixing its problems is good for its users.
>
> Scarlett



Re: [PATCHES] www/w3m bug fixes

2015-01-05 Thread Scarlett
On Tue, Jan 06, 2015 at 06:10:25AM +, Scarlett wrote:
> This archive contains patches for several problems I have found
> while hacking on www/w3m, as well as several bug fixes taken from
> elsewhere.
> 
> --
> 
> Ported patches
> 
> * Use "%s" to printf a string, from Colin Watson at Ubuntu
> http://anonscm.debian.org/cgit/collab-maint/w3m.git/commit/?h=bug/646321
> 
> * Fix a null pointer deref when parsing "" in HTML, from olh
> at suse dot de
> https://build.opensuse.org/package/view_file/openSUSE:Factory/w3m/w3m-closedir.patch?expand=1
> 
> * Fix a directory descriptor leak, from max at suse dot de
> https://build.opensuse.org/package/view_file/openSUSE:Factory/w3m/w3m-parsetagx-crash.patch?expand=1
> 
> * exit(1) when out of memory, since malloc's return value is never checked
> anywhere in the program. inspired by an old patch by dugsong@ which got
> sent to the cvs attic when w3m was updated in the distant past
> http://cvsweb.openbsd.org/cgi-bin/cvsweb/ports/www/w3m/patches/Attic/patch-ac
> 
> --
> 
> My patches
> 
> * Various printf format string fixes:
> 
>   * Instead of printing a "Str" structure with %s, print the
> char pointer inside it with %s.
>   * Use %ld to print long, not %d
>   * Use %zu to print size_t, not %d
>   * Use %lld to print time_t, not %ld
> 
> * Change hand-rolled and suspicious sprintf implementation in Str.c to
> use asprintf() from libc.
> 
> * Move "New()" gc alloc macros to a header file and add overflow checks to
> the "allocate an array" macros.
> 
> --
> 
> w3m's code is disgusting, and upstream is mostly dead with occasional
> patches ported from debian. However, it is one of the more usable web
> browsers (and the only curses browser with inline images, iirc).
> Fixing its problems is good for its users.
> 
> Scarlett

Whoops, I got the two OpenSUSE links mixed up.

The first link is the patch for the directory leak, the second is the
patch for the null pointer deref.