Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 29 Nov 2016 22:59:46 +0000 (UTC)
From:      Jason Unovitch <junovitch@FreeBSD.org>
To:        ports-committers@freebsd.org, svn-ports-all@freebsd.org, svn-ports-head@freebsd.org
Subject:   svn commit: r427403 - in head/www/libwww: . files
Message-ID:  <201611292259.uATMxk5I096216@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: junovitch
Date: Tue Nov 29 22:59:46 2016
New Revision: 427403
URL: https://svnweb.freebsd.org/changeset/ports/427403

Log:
  www/libwww: address 3 security vulnerabilities; cleanup
  
  - Add three patches from NetBSD pkgsrc for fix CVE's:
    CVE-2005-3183 (files/patch-Library_src_HTBound.c)
    CVE-2009-3560 (files/patch-modules_expat_xmlparse_xmlparse.c)
    CVE-2009-3720 (files/patch-modules_expat_xmltok_xmltok__impl.c)
  - Add License
  - Add USES=ssl
  - Strip .so files (Q/A warnings)
  - Regenerate old patches
  - Pass MAINTAINER to submitter
  
  PR:		214546
  Submitted by:	Danilo G. Baio <dbaio@bsd.com.br>
  Approved by:	marius@nuenneri.ch (maintainer)
  Security:	CVE-2009-3720
  Security:	CVE-2009-3560
  Security:	CVE-2005-3183
  Security:	https://vuxml.FreeBSD.org/freebsd/18449f92-ab39-11e6-8011-005056925db4.html
  MFH:		2016Q4

Added:
  head/www/libwww/files/patch-Library_src_HTBound.c   (contents, props changed)
  head/www/libwww/files/patch-modules_expat_xmlparse_xmlparse.c   (contents, props changed)
  head/www/libwww/files/patch-modules_expat_xmltok_xmltok__impl.c   (contents, props changed)
Modified:
  head/www/libwww/Makefile
  head/www/libwww/files/patch-Library__src__HTMIMImp.c
  head/www/libwww/files/patch-configure
  head/www/libwww/files/patch-libwww-config.in

Modified: head/www/libwww/Makefile
==============================================================================
--- head/www/libwww/Makefile	Tue Nov 29 22:58:53 2016	(r427402)
+++ head/www/libwww/Makefile	Tue Nov 29 22:59:46 2016	(r427403)
@@ -3,24 +3,29 @@
 
 PORTNAME=	libwww
 PORTVERSION=	5.4.0
-PORTREVISION=	5
+PORTREVISION=	6
 CATEGORIES=	www devel
 MASTER_SITES=	http://www.w3.org/Library/Distribution/
 DISTNAME=	w3c-${PORTNAME}-${PORTVERSION}
 
-MAINTAINER=	marius@nuenneri.ch
-COMMENT=	The W3C Reference Library
+MAINTAINER=	dbaio@bsd.com.br
+COMMENT=	W3C Reference Library
+
+LICENSE=	W3C
+LICENSE_NAME=	W3C IPR SOFTWARE NOTICE
+LICENSE_FILE=	${WRKSRC}/LICENSE.html
+LICENSE_PERMS=	dist-mirror dist-sell pkg-mirror pkg-sell auto-accept
 
 GNU_CONFIGURE=	yes
 CONFIGURE_ARGS=	--with-zlib --with-ssl=${OPENSSLBASE}
-USES=		perl5 gmake libtool tar:tgz
+USES=		gmake libtool perl5 ssl tar:tgz
 USE_PERL5=	build
 USE_LDCONFIG=	yes
-USE_OPENSSL=	yes
 
 post-install:
 	${INSTALL_DATA} ${WRKSRC}/modules/expat/xmlparse/xmlparse.h \
 		${STAGEDIR}${PREFIX}/include/w3c-libwww/
+	${STRIP_CMD} ${STAGEDIR}${PREFIX}/lib/*.so
 
 .include <bsd.port.pre.mk>
 

Modified: head/www/libwww/files/patch-Library__src__HTMIMImp.c
==============================================================================
--- head/www/libwww/files/patch-Library__src__HTMIMImp.c	Tue Nov 29 22:58:53 2016	(r427402)
+++ head/www/libwww/files/patch-Library__src__HTMIMImp.c	Tue Nov 29 22:59:46 2016	(r427403)
@@ -1,6 +1,6 @@
---- Library/src/HTMIMImp.c.orig	Sun Jun 30 22:51:48 2002
-+++ Library/src/HTMIMImp.c	Sun Jun 30 22:52:01 2002
-@@ -226,7 +226,7 @@
+--- Library/src/HTMIMImp.c.orig	1999-02-22 22:10:11 UTC
++++ Library/src/HTMIMImp.c
+@@ -226,7 +226,7 @@ PRIVATE int HTFindInt(char * haystack, c
      int value = deflt;
      if (start != NULL) {
  	start += strlen(needle);

Added: head/www/libwww/files/patch-Library_src_HTBound.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/www/libwww/files/patch-Library_src_HTBound.c	Tue Nov 29 22:59:46 2016	(r427403)
@@ -0,0 +1,523 @@
+# CVE-2005-3183
+
+--- Library/src/HTBound.c.orig	1999-02-22 22:10:10 UTC
++++ Library/src/HTBound.c
+@@ -11,9 +11,12 @@
+ **
+ ** Authors
+ **	HF	Henrik Frystyk <frystyk@w3.org>
++**      SV      Sam Varshavchik <mrsam@courier-mta.com>
+ **
+ ** History:
+ **	Nov 95	Written from scratch
++**   SV Jun 05  Rewrote HTBoundary_put_block.  Fixed many bugs+segfaults.
++**   SV Jul 05  Fix double-counting of processed bytes.
+ **
+ */
+ 
+@@ -23,104 +26,395 @@
+ #include "WWWCore.h"
+ #include "HTMerge.h"
+ #include "HTReqMan.h"
++#include "HTNetMan.h"
++#include "HTChannl.h"
+ #include "HTBound.h"					 /* Implemented here */
+ 
+-#define PUTBLOCK(b, l)	(*me->target->isa->put_block)(me->target, b, l)
++#define PUTBLOCK(b, l)	(me->target ? (*me->target->isa->put_block)(me->target, b, l):HT_OK)
++
+ #define PUTDEBUG(b, l)	(*me->debug->isa->put_block)(me->debug, b, l)
+ #define FREE_TARGET	(*me->target->isa->_free)(me->target)
+ 
+ struct _HTStream {
+     const HTStreamClass *	isa;
++    HTNet *                      net;
+     HTStream *			target;
+     HTStream *			orig_target;
+     HTFormat			format;
+     HTStream *			debug;		  /* For preamble and epilog */
+     HTRequest *			request;
+-    BOOL			body;		  /* Body or preamble|epilog */
+-    HTEOLState			state;
+-    int				dash;			 /* Number of dashes */
+     char *			boundary;
+-    char *			bpos;
++
++    BOOL                        keptcrlf;
++    int                         (*state)(HTStream *, const char *, int);
++
++    char                        *boundary_ptr;
++
+ };
+ 
++PRIVATE int HTBoundary_flush (HTStream * me);
++
+ /* ------------------------------------------------------------------------- */
+ 
++PRIVATE int start_of_line (HTStream * me, const char * b, int l);
++PRIVATE int seen_dash (HTStream * me, const char * b, int l);
++PRIVATE int seen_doubledash (HTStream * me, const char * b, int l);
++PRIVATE int seen_delimiter_nonterminal(HTStream * me, const char * b, int l);
++PRIVATE int seen_delimiter_nonterminal_CR(HTStream * me, const char * b, int l);
++PRIVATE int seen_delimiter_dash(HTStream * me, const char * b, int l);
++PRIVATE int seen_delimiter_terminal(HTStream * me, const char * b, int l);
++PRIVATE int seen_delimiter_terminal_CR(HTStream * me, const char * b, int l);
++PRIVATE int not_delimiter(HTStream * me, const char * b, int l, int extra);
++PRIVATE int seen_nothing(HTStream * me, const char * b, int l);
++PRIVATE int seen_cr(HTStream * me, const char * b, int l);
++PRIVATE void process_boundary(HTStream *me, int isterminal);
++
++#define UNUSED(l) (l=l)    /* Shut up about unused variables */
++
+ PRIVATE int HTBoundary_put_block (HTStream * me, const char * b, int l)
+ {
+-    const char *start = b;
+-    const char *end = b;
+-    while (l-- > 0) {
+-	if (me->state == EOL_FCR) {
+-	    me->state = (*b == LF) ? EOL_FLF : EOL_BEGIN;
+-	} else if (me->state == EOL_FLF) {
+-	    if (me->dash == 2) {
+-		while (l>0 && *me->bpos && *me->bpos==*b) l--, me->bpos++, b++;
+-		if (!*me->bpos) {
+-		    HTTRACE(STREAM_TRACE, "Boundary.... `%s\' found\n" _ me->boundary);
+-		    me->bpos = me->boundary;
+-		    me->body = YES;
+-		    me->state = EOL_DOT;
+-		} else if (l>0) {
+-		    me->dash = 0;
+-		    me->bpos = me->boundary;
+-		    me->state = EOL_BEGIN;
+-		}
+-	    }
+-	    if (*b == '-') {
+-		me->dash++;
+-	    } else if (*b != CR && *b != LF) {
+-		me->dash = 0;
+-		me->state = EOL_BEGIN;
+-	    }
+-	} else if (me->state == EOL_SLF) {	    /* Look for closing '--' */
+-	    if (me->dash == 4) {
+-		if (end > start) {
+-		    int status = PUTBLOCK(start, end-start);
+-		    if (status != HT_OK) return status;
++	/*
++	** The HTBoundary object gets attached downstream of HTMime.
++	** The HTBoundary object creates another HTMime object downstream of
++	** the HTBoundary object.
++	**
++	** When we push data downstream to the second HTBoundary object, it
++	** updates the bytes read count in the HTNet object.
++	**
++	** When we return to the parent HTMime object, itupdates the
++	** bytes read count in the HTNet object again.  Oops.
++	**
++	** Same thing happens with the consumed byte count.  We can prevent
++	** the consumed byte counts from being updated by temporary setting
++	** the input channel stream pointer to NULL, but for the byte counts
++	** we have to save them and restore them before existing.
++	**
++	** This bug was discovered by chance when a multipart/partial response
++	** was partially received, and as a result of double-counting the
++	** real response got cut off (because HTMime thought that more bytes
++	** were processed than actually were, thus it processed only the
++	** partial count of the remaining bytes in the response).  When the
++	** multipart/partial response was received all at once this bug did
++	** not get triggered.
++	*/
++
++	HTHost *host=HTNet_host(me->net);
++	HTChannel *c=HTHost_channel(host);
++	HTInputStream *i=HTChannel_input(c);
++
++	long saveBytesRead=HTNet_bytesRead(me->net);
++	long saveHeaderBytesRead=HTNet_headerBytesRead(me->net);
++
++	if (i)
++		HTChannel_setInput(c, NULL);
++
++	HTTRACE(STREAM_TRACE, "Boundary: processing %d bytes\n" _ l);
++	/* Main loop consumes all input */
++
++	while (l)
++	{
++		int n= (*me->state)(me, b, l);
++
++		if (n == 0)
++			return HT_ERROR;
++		b += n;
++		l -= n;
++	}
++
++	if (i)
++		HTChannel_setInput(c, i);
++	HTNet_setBytesRead(me->net, saveBytesRead);
++	HTNet_setHeaderBytesRead(me->net, saveHeaderBytesRead);
++
++	return HT_OK;
++}
++
++/*
++** Start of line, keptcrlf=YES if we've kept the preceding CRLF from downstream
++** and we'll pass it along if we decide that this is not a boundary delimiter.
++*/
++
++PRIVATE int start_of_line (HTStream * me, const char * b, int l)
++{
++	if (*b != '-')
++		return not_delimiter(me, b, l, 0);
++
++	HTTRACE(STREAM_TRACE, "Boundary: start of line: input '-'\n");
++
++	me->state= seen_dash;
++
++	return 1;
++}
++
++/*
++** Line: -
++*/
++
++PRIVATE int seen_dash (HTStream * me, const char * b, int l)
++{
++	if (*b != '-')
++		return not_delimiter(me, b, l, 1);
++
++	HTTRACE(STREAM_TRACE, "Boundary: start of line: input '--'\n");
++
++	me->state= seen_doubledash;
++	me->boundary_ptr=me->boundary;
++	return 1;
++}
++
++/*
++** Line: --
++*/
++
++PRIVATE int seen_doubledash (HTStream * me, const char * b, int l)
++{
++	me->state=seen_doubledash;
++
++	if (*me->boundary_ptr)
++	{
++		if (*b != *me->boundary_ptr)
++		{
++			return not_delimiter(me, b, l,
++					     me->boundary_ptr - me->boundary
++					     + 2);
+ 		}
+-		HTTRACE(STREAM_TRACE, "Boundary.... Ending\n");
+-		start = b;
+-		me->dash = 0;
+-		me->state = EOL_BEGIN;
+-	    }
+-	    if (*b == '-') {
+-		me->dash++;
+-	    } else if (*b != CR && *b != LF) {
+-		me->dash = 0;
+-		me->state = EOL_BEGIN;
++		++me->boundary_ptr;
++		return 1;
+ 	    }
+-	    me->body = NO;
+-	} else if (me->state == EOL_DOT) {
+-	    int status;
+-	    if (me->body) {
+-		if (me->target) FREE_TARGET;
++
++	/*
++	** Line: --delimiter
++	*/
++
++	if (*b == '-')
++	{
++		HTTRACE(STREAM_TRACE,
++			"Boundary: start of line: input '--%s-'\n"
++			_ me->boundary);
++
++		me->state=seen_delimiter_dash;
++		return 1;
++	}
++
++	HTTRACE(STREAM_TRACE,
++		"Boundary: Found: '--%s'\n" _ me->boundary);
++	
++	return seen_delimiter_nonterminal(me, b, l);
++}
++
++/*
++** Line: --delimiter
++**
++** Waiting for CRLF.
++*/
++
++
++PRIVATE int seen_delimiter_nonterminal(HTStream * me, const char * b, int l)
++{
++	UNUSED(l);
++
++	me->state=seen_delimiter_nonterminal;
++	if (*b == CR)
++		me->state=seen_delimiter_nonterminal_CR;
++
++	return 1;
++}
++
++/*
++** Line: --delimiter<CR>
++*/
++
++PRIVATE int seen_delimiter_nonterminal_CR(HTStream * me, const char * b, int l)
++{
++	HTTRACE(STREAM_TRACE,
++		"Boundary: Found: '--%s<CR>'\n" _ me->boundary);
++	
++	if (*b != LF)
++		return seen_delimiter_nonterminal(me, b, l);
++
++	HTTRACE(STREAM_TRACE,
++		"Boundary: Found: '--%s<CR><LF>'\n" _ me->boundary);
++	
++	process_boundary(me, NO);
++	return 1;
++}
++
++/*
++** Line: --delimiter-
++*/
++
++PRIVATE int seen_delimiter_dash(HTStream * me, const char * b, int l)
++{
++	if (*b != '-')
++		return seen_delimiter_nonterminal(me, b, l);
++
++	HTTRACE(STREAM_TRACE,
++		"Boundary: start of line: input '--%s--'\n"
++		_ me->boundary);
++	
++	me->state=seen_delimiter_terminal;
++	return 1;
++}
++
++/*
++** Line: --delimiter--
++*/
++
++PRIVATE int seen_delimiter_terminal(HTStream * me, const char * b, int l)
++{
++	UNUSED(l);
++
++	me->state=seen_delimiter_terminal;
++
++	if (*b == CR)
++		me->state=seen_delimiter_terminal_CR;
++	return 1;
++}
++/*
++** Line: --delimiter--<CR>
++*/
++
++PRIVATE int seen_delimiter_terminal_CR(HTStream * me, const char * b, int l)
++{
++	HTTRACE(STREAM_TRACE,
++		"Boundary: Found '--%s--<CR>'\n"
++		_ me->boundary);
++	
++	if (*b != LF)
++		return seen_delimiter_terminal(me, b, l);
++	HTTRACE(STREAM_TRACE,
++		"Boundary: Found '--%s--<CR><LF>'\n"
++		_ me->boundary);
++	
++	process_boundary(me, YES);
++	return 1;
++}
++
++/*
++** Beginning of the line does not contain a delimiter.
++**
++**
++** extra: Count of characters in a partially matched delimiter.  Since it's
++** not a delimiter this is content that needs to go downstream.
++*/
++
++PRIVATE int not_delimiter(HTStream * me, const char * b, int l, int extra)
++{
++	HTTRACE(STREAM_TRACE, "Boundary: not a delimiter line\n");
++	
++	if (me->keptcrlf)
++	{
++		HTTRACE(STREAM_TRACE, "Boundary: Sending previous line's <CR><LF>\n");
++		/*
++		** Did not process CRLF from previous line, because prev CRLF
++		** is considered a part of the delimiter.  See MIME RFC.
++		*/
++
++		me->keptcrlf=NO;
++		if (PUTBLOCK("\r\n", 2) != HT_OK)
++			return 0;
++	}
++
++	/*
++	** Potentially matched some of: --DELIMITER
++	*/
++
++	if (extra)
++	{
++		HTTRACE(STREAM_TRACE, "Boundary: Sending partially-matched %d characters\n" _ extra);
++
++		if (PUTBLOCK("--", extra > 2 ? 2:extra) != HT_OK)
++			return 0;
++
++		if (extra > 2)
++			if (PUTBLOCK(me->boundary, extra-2) != HT_OK)
++				return 0;
++	}
++	return seen_nothing(me, b, l);
++}
++
++/*
++** We're not looking for a delimiter.  Look for the next line of input
++** in the data that could potentially be a delimiter.
++*/
++
++PRIVATE int seen_nothing(HTStream * me, const char * b, int l)
++{
++	int i;
++
++	me->state=seen_nothing;
++
++	for (i=0; i<l; i++)
++	{
++		if (b[i] != CR)
++			continue;
++
++		/*
++		** If we have at least four more characters in unconsumed
++		** input, and they're not \r\n--, we can safely skip over
++		** them.
++		*/
++
++		if (l-i > 4 &&
++		    strncmp(b+i, "\r\n--", 4))
++			continue;
++		break;
++	}
++
++	if (i == 0)
++	{
++		/* Could only be a CR here. */
++
++		me->state=seen_cr;
++		return 1;
++	}
++
++	HTTRACE(STREAM_TRACE, "Boundary: Processed %d (out of %d) bytes\n"
++		_ i _ l);
++
++	if (PUTBLOCK(b, i) != HT_OK)
++		return 0;
++
++	return i;
++}
++
++/*
++** State: seen a CR
++*/
++
++PRIVATE int seen_cr(HTStream * me, const char * b, int l)
++{
++	HTTRACE(STREAM_TRACE, "Boundary: Processed <CR>\n");
++
++	if (*b != LF)
++	{
++		HTTRACE(STREAM_TRACE, "Boundary: ... <LF> didn't follow\n");
++		if (PUTBLOCK("\r", 1) != HT_OK)
++			return 0;
++		return seen_nothing(me, b, l);
++    }
++
++	HTTRACE(STREAM_TRACE, "Boundary: Processed <CR><LF>\n");
++	me->state=start_of_line;
++	me->keptcrlf=YES;
++	return 1;
++}
++
++PRIVATE void process_boundary(HTStream *me, int isterminal)
++{
++	HTBoundary_flush(me);
++	if (me->target) FREE_TARGET;
++	me->target=NULL;
++	me->state=start_of_line;
++	me->keptcrlf=NO;
++
++	if (!isterminal)
+ 		me->target = HTStreamStack(WWW_MIME,me->format,
+ 					   HTMerge(me->orig_target, 2),
+ 					   me->request, YES);
+-		if (end > start) {
+-		    if ((status = PUTBLOCK(start, end-start)) != HT_OK)
+-			return status;
+-		}
+-	    } else {
+-		if (me->debug)
+-		    if ((status = PUTDEBUG(start, end-start)) != HT_OK)
+-			return status;
+-	    }
+-	    start = b;
+-	    if (*b == '-') me->dash++;
+-	    me->state = EOL_SLF;
+-	} else if (*b == CR) {
+-	    me->state = EOL_FCR;
+-	    end = b;
+-	} else if (*b == LF) {
+-	    if (me->state != EOL_FCR) end = b;
+-	    me->state = EOL_FLF;
+-	}
+-	b++;
+-    }
+-    return (start<b && me->body) ? PUTBLOCK(start, b-start) : HT_OK;
+ }
+ 
++
+ PRIVATE int HTBoundary_put_string (HTStream * me, const char * s)
+ {
+     return HTBoundary_put_block(me, s, (int) strlen(s));
+@@ -133,6 +427,8 @@ PRIVATE int HTBoundary_put_character (HT
+ 
+ PRIVATE int HTBoundary_flush (HTStream * me)
+ {
++	if (me->target == NULL)
++		return HT_OK;
+     return (*me->target->isa->flush)(me->target);
+ }
+ 
+@@ -182,18 +478,26 @@ PUBLIC HTStream * HTBoundary   (HTReques
+ 	HTResponse_formatParam(response) :
+ 	HTAnchor_formatParam(anchor);
+     char * boundary = HTAssocList_findObject(type_param, "boundary");
++
++    UNUSED(param);
++    UNUSED(input_format);
++
+     if (boundary) {
+ 	HTStream * me;
+ 	if ((me = (HTStream  *) HT_CALLOC(1, sizeof(HTStream))) == NULL)
+ 	    HT_OUTOFMEM("HTBoundary");
+ 	me->isa = &HTBoundaryClass;
++	me->net = HTRequest_net(request);
+ 	me->request = request;
+ 	me->format = output_format;
+ 	me->orig_target = output_stream;
+ 	me->debug = HTRequest_debugStream(request);
+-	me->state = EOL_FLF;
++
++	me->state = start_of_line;
++	me->keptcrlf=NO;
++
+ 	StrAllocCopy(me->boundary, boundary);		       /* Local copy */
+-	me->bpos = me->boundary;
++
+ 	HTTRACE(STREAM_TRACE, "Boundary.... Stream created with boundary '%s\'\n" _ me->boundary);
+ 	return me;
+     } else {

Modified: head/www/libwww/files/patch-configure
==============================================================================
--- head/www/libwww/files/patch-configure	Tue Nov 29 22:58:53 2016	(r427402)
+++ head/www/libwww/files/patch-configure	Tue Nov 29 22:59:46 2016	(r427403)
@@ -1,6 +1,6 @@
---- configure.orig	Wed Jun 12 11:31:31 2002
-+++ configure	Sat Mar 10 21:51:00 2007
-@@ -7612,8 +7612,11 @@
+--- configure.orig	2002-06-12 09:31:31 UTC
++++ configure
+@@ -7612,8 +7612,11 @@ if test "${with_ssl+set}" = set; then
      if test "x$withval" = "xyes"; then
        withval=$ssllib
        SSLINC=$sslinc

Modified: head/www/libwww/files/patch-libwww-config.in
==============================================================================
--- head/www/libwww/files/patch-libwww-config.in	Tue Nov 29 22:58:53 2016	(r427402)
+++ head/www/libwww/files/patch-libwww-config.in	Tue Nov 29 22:59:46 2016	(r427403)
@@ -1,6 +1,6 @@
---- libwww-config.in.orig       Thu Jul  6 18:48:21 2006
-+++ libwww-config.in    Thu Jul  6 18:49:01 2006
-@@ -48,7 +48,7 @@
+--- libwww-config.in.orig	1999-06-23 18:05:01 UTC
++++ libwww-config.in
+@@ -48,7 +48,7 @@ while test $# -gt 0; do
        echo -I@includedir@ -I@includedir@/@PACKAGE@ @DEFS@
        ;;
      --libs)
@@ -9,4 +9,3 @@
        ;;
      *)
        echo "${usage}" 1>&2
-

Added: head/www/libwww/files/patch-modules_expat_xmlparse_xmlparse.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/www/libwww/files/patch-modules_expat_xmlparse_xmlparse.c	Tue Nov 29 22:59:46 2016	(r427403)
@@ -0,0 +1,14 @@
+# CVE-2009-3560
+
+--- modules/expat/xmlparse/xmlparse.c.orig	2000-08-28 08:52:01 UTC
++++ modules/expat/xmlparse/xmlparse.c
+@@ -2199,6 +2199,9 @@ doProlog(XML_Parser parser,
+ 	return XML_ERROR_UNCLOSED_TOKEN;
+       case XML_TOK_PARTIAL_CHAR:
+ 	return XML_ERROR_PARTIAL_CHAR;
++      case -XML_TOK_PROLOG_S:
++	tok = -tok;
++	break;
+       case XML_TOK_NONE:
+ #ifdef XML_DTD
+ 	if (enc != encoding)

Added: head/www/libwww/files/patch-modules_expat_xmltok_xmltok__impl.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/www/libwww/files/patch-modules_expat_xmltok_xmltok__impl.c	Tue Nov 29 22:59:46 2016	(r427403)
@@ -0,0 +1,13 @@
+# CVE-2009-3720
+
+--- modules/expat/xmltok/xmltok_impl.c.orig	2000-08-28 08:52:01 UTC
++++ modules/expat/xmltok/xmltok_impl.c
+@@ -1753,7 +1753,7 @@ void PREFIX(updatePosition)(const ENCODI
+ 			    const char *end,
+ 			    POSITION *pos)
+ {
+-  while (ptr != end) {
++  while (ptr < end) {
+     switch (BYTE_TYPE(enc, ptr)) {
+ #define LEAD_CASE(n) \
+     case BT_LEAD ## n: \



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201611292259.uATMxk5I096216>