diff options
author | Tatsuya Kinoshita <tats@debian.org> | 2017-01-04 14:14:01 +0000 |
---|---|---|
committer | Tatsuya Kinoshita <tats@debian.org> | 2017-01-04 14:24:43 +0000 |
commit | cd921375d8de0619b79e2997e8969d3d7659316c (patch) | |
tree | f7968c0d99a4eddbe70d12e4aaeab46921ff702a | |
parent | Debian release 0.5.3-33 (diff) | |
download | w3m-cd921375d8de0619b79e2997e8969d3d7659316c.tar.gz w3m-cd921375d8de0619b79e2997e8969d3d7659316c.zip |
Update 020_debian.patch to v0.5.3+git20170102
- Fix multiple flaws with malformed text
(buffer overflow, use after free, infinite loop)
-rw-r--r-- | debian/patches/020_debian.patch | 835 |
1 files changed, 694 insertions, 141 deletions
diff --git a/debian/patches/020_debian.patch b/debian/patches/020_debian.patch index 900ef87..9d17218 100644 --- a/debian/patches/020_debian.patch +++ b/debian/patches/020_debian.patch @@ -60,10 +60,233 @@ index 8f443c1..5fb6581 100755 $input = "w3m-control: GOTO_LINK"; } diff --git a/ChangeLog b/ChangeLog -index 88358ef..90443aa 100644 +index 88358ef..5e77a18 100644 --- a/ChangeLog +++ b/ChangeLog -@@ -1,3 +1,1303 @@ +@@ -1,3 +1,1526 @@ ++2017-01-02 Tatsuya Kinoshita <tats@debian.org> ++ ++ * NEWS: Update NEWS. ++ ++2016-12-24 Tatsuya Kinoshita <tats@debian.org> ++ ++ * libwc/wtf.c: ++ Prevent overflow beyond the end of string in wtf_parse1(). ++ Bug-Debian: https://github.com/tats/w3m/issues/68 ++ ++ * libwc/wtf.c: ++ Revert "Prevent overflow beyond the end of string in wtf_parse1()". ++ This reverts commit 998b6f91d4b02e8bf90b7744dfabc8cccdf9d4f9. ++ Bug-Debian: https://github.com/tats/w3m/issues/86 ++ cf. http://emacs-w3m.namazu.org/ml/msg12505.html ++ ++ * form.c: ++ Preserve one byte for end of string character in form_update_line(). ++ Bug-Debian: https://github.com/tats/w3m/issues/68#issuecomment-266214643 ++ ++ * form.c: ++ Prevent invalid form_update_line() call in formUpdateBuffer(). ++ Bug-Debian: https://github.com/tats/w3m/issues/82 ++ ++2016-12-20 Tatsuya Kinoshita <tats@debian.org> ++ ++ * form.c: ++ Revert "Preserve one byte for end of string character in form_update_line()". ++ This reverts commit a4152aaaea5cb51c9018880a1295e498c38889bf. ++ ++2016-12-18 Tatsuya Kinoshita <tats@debian.org> ++ ++ * file.c: Prevent heap-use-after-free read in HTMLlineproc0(). ++ Bug-Debian: https://github.com/tats/w3m/issues/81 ++ ++ * file.c: Prevent infinite loop in feed_textarea(). ++ Bug-Debian: https://github.com/tats/w3m/issues/85 ++ ++ * form.c: ++ Revert "Prevent overflow beyond the end of string in form_update_line()". ++ This reverts commit 9ccaa1dd0dac6f9b35a649ae9901c225421500f6. ++ ++ * form.c: ++ Revert "Prevent overflow beyond the end of string in form_update_line()". ++ This reverts commit e0efc127ff20cbeb931847af1c9b353056340fbd. ++ ++2016-12-15 Tatsuya Kinoshita <tats@debian.org> ++ ++ * libwc/wtf.c: ++ Prevent overflow beyond the end of string for wtf to wcs macros. ++ Bug-Debian: https://github.com/tats/w3m/issues/77 ++ ++ * libwc/wtf.c: ++ Revert "Prevent overflow beyond the end of string for wtf to wcs macros". ++ This reverts commit b4d27ba5ccffaa38e968c2bf3a8eeb9cd43928ff. ++ ++ * file.c, libwc/wtf.c, libwc/wtf.h: ++ Prevent overflow beyond the end of string in caller of get_mclen(). ++ Bug-Debian: https://github.com/tats/w3m/issues/59 ++ Bug-Debian: https://github.com/tats/w3m/issues/73 ++ Bug-Debian: https://github.com/tats/w3m/issues/74 ++ Bug-Debian: https://github.com/tats/w3m/issues/75 ++ Bug-Debian: https://github.com/tats/w3m/issues/76 ++ Bug-Debian: https://github.com/tats/w3m/issues/78 ++ Bug-Debian: https://github.com/tats/w3m/issues/79 ++ Bug-Debian: https://github.com/tats/w3m/issues/80 ++ Bug-Debian: https://github.com/tats/w3m/issues/83 ++ Bug-Debian: https://github.com/tats/w3m/issues/84 ++ ++ * file.c: ++ Revert "Prevent overflow beyond the end of string in proc_mchar()". ++ This reverts commit 512ed467d12615f5ef40d0d28272e5662d8438ea. ++ ++ * table.c: ++ Revert "Prevent overflow beyond the end of string in visible_length()". ++ This reverts commit a932f78a6d8c105036ffeedf01215c1f6a0e0b71. ++ ++ * table.c: ++ Revert "Prevent overflow beyond the end of string in skip_space()". ++ This reverts commit e757b43bcf8c439c167f62b6d3317ee9518cabbf. ++ ++ * table.c: ++ Revert "Prevent overflow beyond the end of string in visible_length_plain()". ++ This reverts commit f763b8ebf5441cb44d2c0234565fadd5eb1c87a5. ++ ++ * form.c: ++ Revert "Prevent overflow beyond the end of string in textfieldrep()". ++ This reverts commit 77d8d8d6576d8afc0f6b2e09bb88c7ca9dba58bb. ++ ++ * file.c: ++ Revert "Prevent overflow beyond the end of string in proc_mchar()". ++ This reverts commit e79d0ec2a00369a6af24007a1f2bb5e876e2c847. ++ ++2016-12-13 Tatsuya Kinoshita <tats@debian.org> ++ ++ * file.c: Prevent overflow beyond the end of string in proc_mchar(). ++ Bug-Debian: https://github.com/tats/w3m/issues/80 ++ cf. https://github.com/tats/w3m/issues/59 ++ ++ * form.c: Prevent overflow beyond the end of string in textfieldrep(). ++ Bug-Debian: https://github.com/tats/w3m/issues/79 ++ ++ * form.c: ++ Preserve one byte for end of string character in form_update_line(). ++ Bug-Debian: https://github.com/tats/w3m/issues/82 ++ cf. https://github.com/tats/w3m/issues/68#issuecomment-266214643 ++ ++2016-12-10 Tatsuya Kinoshita <tats@debian.org> ++ ++ * libwc/wtf.c: Prevent overflow beyond the end of string in wtf_len(). ++ cf. https://github.com/tats/w3m/issues/57 ++ ++ * etc.c: Prevent negative array index for realColumn in calcPosition(). ++ Bug-Debian: https://github.com/tats/w3m/issues/69 ++ ++ * libwc/wtf.c: ++ Prevent overflow beyond the end of string in wtf_parse1(). ++ Bug-Debian: https://github.com/tats/w3m/issues/68 ++ ++ * Str.c: Prevent heap-buffer-overflow in Strnew_size(). ++ Bug-Debian: https://github.com/tats/w3m/issues/72 ++ ++ * table.c: ++ Prevent overflow beyond the end of string in visible_length_plain(). ++ Bug-Debian: https://github.com/tats/w3m/issues/76 ++ ++ * libwc/wtf.c: ++ Prevent overflow beyond the end of string for wtf to wcs macros. ++ Bug-Debian: https://github.com/tats/w3m/issues/77 ++ ++ * form.c: ++ Prevent overflow beyond the end of string in form_update_line(). ++ Bug-Debian: https://github.com/tats/w3m/issues/78 ++ ++2016-12-08 Tatsuya Kinoshita <tats@debian.org> ++ ++ * form.c: ++ Prevent overflow beyond the end of string in form_update_line(). ++ Bug-Debian: https://github.com/tats/w3m/issues/75 ++ ++ * table.c: Prevent overflow beyond the end of string in skip_space(). ++ Bug-Debian: https://github.com/tats/w3m/issues/74 ++ ++ * table.c: ++ Prevent overflow beyond the end of string in visible_length(). ++ Bug-Debian: https://github.com/tats/w3m/issues/73 ++ ++ * libwc/wtf.c: ++ Prevent overflow beyond the end of string in wtf_strwidth(). ++ Bug-Debian: https://github.com/tats/w3m/issues/57 ++ ++ * libwc/wtf.c: ++ Revert "Prevent overflow beyond the end of string in wtf_strwidth()". ++ This reverts commit d345c0950dfdef065b7377ecad0e4bc1d2601bf8. ++ ++2016-12-07 Tatsuya Kinoshita <tats@debian.org> ++ ++ * file.c: Prevent heap-use-after-free in HTMLlineproc0(). ++ Bug-Debian: https://github.com/tats/w3m/issues/65 ++ ++ * file.c: Prevent negative values for offset and pos in push_link(). ++ Bug-Debian: https://github.com/tats/w3m/issues/64 ++ ++ * file.c: Prevent overflow beyond the end of string in proc_mchar(). ++ Bug-Debian: https://github.com/tats/w3m/issues/59 ++ ++ * libwc/wtf.c: ++ Prevent overflow beyond the end of string in wtf_strwidth(). ++ Bug-Debian: https://github.com/tats/w3m/issues/57 ++ ++2016-12-05 Yixun Lan <dlan@gentoo.org> ++ ++ * html.h: Explictily include <time.h> to avoid build err. ++ While disable ssl, we will got a undefine time_t err. ++ Bug-Gentoo: https://bugs.gentoo.org/show_bug.cgi?id=601498 ++ Origin: https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=8ee43ba4e036db70fff258f3edb2f0335385e93f ++ ++2016-12-05 Tatsuya Kinoshita <tats@debian.org> ++ ++ * table.c: ++ Prevent array index out of bounds for tridvalue in feed_table_tag(). ++ Bug-Debian: https://github.com/tats/w3m/issues/71 ++ ++ * table.c: Prevent negative array index in set_integered_width(). ++ Bug-Debian: https://github.com/tats/w3m/issues/70 ++ ++ * table.c: ++ Prevent array index out of bounds for tabattr in feed_table_tag(). ++ Bug-Debian: https://github.com/tats/w3m/issues/60 ++ ++ * file.c: Prevent negative array index in process_textarea(). ++ Bug-Debian: https://github.com/tats/w3m/issues/58 ++ ++ * file.c: ++ Prevent negative array index for marks in HTMLlineproc2body(). ++ Bug-Debian: https://github.com/tats/w3m/issues/61 ++ ++ * file.c: ++ Prevent negative value of row for pushTable() in HTMLlineproc0(). ++ Bug-Debian: https://github.com/tats/w3m/issues/67 ++ ++ * file.c: Prevent negative array index in getMetaRefreshParam(). ++ Bug-Debian: https://github.com/tats/w3m/issues/63 ++ ++ * anchor.c: ++ Prevent negative array index for marks in shiftAnchorPosition(). ++ Bug-Debian: https://github.com/tats/w3m/issues/62 ++ ++2016-11-27 Kuang-che Wu <kcwu@google.com> ++ ++ * file.c: Fix uninitialized variable in process_img(). fix #44. ++ Bug-Debian: https://github.com/tats/w3m/issues/44 ++ Origin: https://github.com/tats/w3m/pull/50/commits/41a607b06e4475101de59e5c623b9e5f76594a21 ++ ++ * menu.c: Fix menu buffer-overflow. ++ Origin: https://github.com/tats/w3m/pull/49/commits/7e1c05dd90cf42a308e854881ea3813aed000d2e ++ ++2016-11-27 Tatsuya Kinoshita <tats@debian.org> ++ ++ * ChangeLog, NEWS: Add CVE IDs. ++ cf. https://security-tracker.debian.org/tracker/source-package/w3m ++ http://www.openwall.com/lists/oss-security/2016/11/24/1 ++ +2016-11-20 Tatsuya Kinoshita <tats@debian.org> + + * NEWS: Update NEWS. @@ -83,15 +306,15 @@ index 88358ef..90443aa 100644 + + * libwc/ucs.c, libwc/ucs.map: + Prevent global-buffer-overflow in wc_any_to_ucs(). -+ Bug-Debian: https://github.com/tats/w3m/issues/43 ++ Bug-Debian: https://github.com/tats/w3m/issues/43 [CVE-2016-9632] + +2016-11-17 Tatsuya Kinoshita <tats@debian.org> + + * url.c: Prevent global-buffer-overflow in parseURL(). -+ Bug-Debian: https://github.com/tats/w3m/issues/41 ++ Bug-Debian: https://github.com/tats/w3m/issues/41 [CVE-2016-9630] + + * file.c: Prevent deref null pointer in HTMLlineproc0(). -+ Bug-Debian: https://github.com/tats/w3m/issues/42 ++ Bug-Debian: https://github.com/tats/w3m/issues/42 [CVE-2016-9631] + +2016-11-15 Tatsuya Kinoshita <tats@debian.org> + @@ -108,16 +331,16 @@ index 88358ef..90443aa 100644 + This reverts commit f393faf55975a94217df479e1bd06ee4403c6958. + + * anchor.c: Prevent deref null pointer in shiftAnchorPosition(). -+ Bug-Debian: https://github.com/tats/w3m/issues/40 ++ Bug-Debian: https://github.com/tats/w3m/issues/40 [CVE-2016-9629] + +2016-11-14 Tatsuya Kinoshita <tats@debian.org> + + * file.c: Prevent null pointer deref due to bad form id. -+ Bug-Debian: https://github.com/tats/w3m/issues/39 ++ Bug-Debian: https://github.com/tats/w3m/issues/39 [CVE-2016-9628] + + * display.c, file.c, fm.h, symbol.c: + Prevent array index out of bounds for symbol. -+ Bug-Debian: https://github.com/tats/w3m/issues/38 ++ Bug-Debian: https://github.com/tats/w3m/issues/38 [CVE-2016-9627] + +2016-11-13 Tatsuya Kinoshita <tats@debian.org> + @@ -135,12 +358,12 @@ index 88358ef..90443aa 100644 +2016-11-09 Tatsuya Kinoshita <tats@debian.org> + + * table.c: Check indent_level to prevent infinite recursion. -+ Bug-Debian: https://github.com/tats/w3m/issues/37 ++ Bug-Debian: https://github.com/tats/w3m/issues/37 [CVE-2016-9626] + +2016-11-07 Tatsuya Kinoshita <tats@debian.org> + + * file.c: Prevent infinite recursion in HTMLlineproc0. -+ Bug-Debian: https://github.com/tats/w3m/issues/36 ++ Bug-Debian: https://github.com/tats/w3m/issues/36 [CVE-2016-9625] + + * NEWS, w3m-doc/install.html.in: + Update documents for included w3mdict.cgi. @@ -156,16 +379,16 @@ index 88358ef..90443aa 100644 +2016-11-07 Tatsuya Kinoshita <tats@debian.org> + + * form.c: Prevent dereference near-null pointer in formUpdateBuffer. -+ Bug-Debian: https://github.com/tats/w3m/issues/35 ++ Bug-Debian: https://github.com/tats/w3m/issues/35 [CVE-2016-9624] + + * file.c: Prevent crash after allocate string of negative size. -+ Bug-Debian: https://github.com/tats/w3m/issues/33 ++ Bug-Debian: https://github.com/tats/w3m/issues/33 [CVE-2016-9623] + + * file.c: Prevent memory exhausted due to repeat appending "</table>". -+ Bug-Debian: https://github.com/tats/w3m/issues/23 ++ Bug-Debian: https://github.com/tats/w3m/issues/23 [CVE-2016-9633] + + * file.c: Prevent null pointer dereference in HTMLlineproc2body. -+ Bug-Debian: https://github.com/tats/w3m/issues/32 ++ Bug-Debian: https://github.com/tats/w3m/issues/32 [CVE-2016-9622] + +2016-10-31 Tatsuya Kinoshita <tats@debian.org> + @@ -203,7 +426,7 @@ index 88358ef..90443aa 100644 + Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=838952 + + * form.c: Prevent global-buffer-overflow write in formUpdateBuffer. -+ Bug-Debian: https://github.com/tats/w3m/issues/29 [CVE-2016-9429] ++ Bug-Debian: https://github.com/tats/w3m/issues/29 [CVE-2016-9429] [CVE-2016-9621] + + * form.c: Fix null pointer dereference in formUpdateBuffer. + Bug-Debian: https://github.com/tats/w3m/issues/28 [CVE-2016-9443] @@ -1419,15 +1642,25 @@ index 7d692f9..453072d 100644 do \ (cd $$dir && $(MAKE) $(MAKE_ARGS) uninstall); \ diff --git a/NEWS b/NEWS -index 66e309d..b80e8ed 100644 +index 66e309d..d8a99d3 100644 --- a/NEWS +++ b/NEWS -@@ -1,3 +1,55 @@ +@@ -1,3 +1,65 @@ ++Debian's w3m 0.5.3+git20170102 ++ ++* bug fixes ++ - fix multiple flaws with malformed text ++ (buffer overflow, use after free, infinite loop) ++ - fix uninitialized variable when not USE_IMAGE ++ +Debian's w3m 0.5.3+git20161120 + +* bug fixes + - fix multiple flaws with malformed text + (stack overflow, buffer overflow, null deref, out of memory) ++ [CVE-2016-9622], [CVE-2016-9623], [CVE-2016-9624], [CVE-2016-9625], ++ [CVE-2016-9626], [CVE-2016-9627], [CVE-2016-9628], [CVE-2016-9629], ++ [CVE-2016-9630], [CVE-2016-9631], [CVE-2016-9632], [CVE-2016-9633] + - fix stack overflow with nested table and textarea [CVE-2016-9439] + - fix suspend (^Z) behavior + @@ -1452,7 +1685,7 @@ index 66e309d..b80e8ed 100644 + [CVE-2016-9426], [CVE-2016-9428], [CVE-2016-9429], [CVE-2016-9430], + [CVE-2016-9431], [CVE-2016-9432], [CVE-2016-9433], [CVE-2016-9434], + [CVE-2016-9435], [CVE-2016-9436], [CVE-2016-9437], [CVE-2016-9438], -+ [CVE-2016-9440], [CVE-2016-9441], [CVE-2016-9443] ++ [CVE-2016-9440], [CVE-2016-9441], [CVE-2016-9443], [CVE-2016-9621] + - fix potential heap buffer corruption due to Strgrow [CVE-2016-9442] + - disable SSLv2 and SSLv3 by default [CVE-2014-3566] + - set ssl_verify_server to 1 by default @@ -1493,10 +1726,19 @@ index 8778d80..765c996 100644 If you can read Japanese, see doc-jp/*. If you can read both, read both and correct English. :-) diff --git a/Str.c b/Str.c -index e5a0982..d34129f 100644 +index e5a0982..61fe3ca 100644 --- a/Str.c +++ b/Str.c -@@ -56,7 +56,7 @@ Strnew_size(int n) +@@ -48,6 +48,8 @@ Str + Strnew_size(int n) + { + Str x = GC_MALLOC(sizeof(struct _Str)); ++ if (n < 0) ++ n = 0; + x->ptr = GC_MALLOC_ATOMIC(n + 1); + x->ptr[0] = '\0'; + x->area_size = n + 1; +@@ -56,7 +58,7 @@ Strnew_size(int n) } Str @@ -1505,7 +1747,7 @@ index e5a0982..d34129f 100644 { Str x; int n; -@@ -73,7 +73,7 @@ Strnew_charp(char *p) +@@ -73,7 +75,7 @@ Strnew_charp(char *p) } Str @@ -1514,7 +1756,7 @@ index e5a0982..d34129f 100644 { va_list ap; Str r = Strnew(); -@@ -87,7 +87,7 @@ Strnew_m_charp(char *p, ...) +@@ -87,7 +89,7 @@ Strnew_m_charp(char *p, ...) } Str @@ -1523,7 +1765,7 @@ index e5a0982..d34129f 100644 { Str x; -@@ -140,7 +140,7 @@ Strcopy(Str x, Str y) +@@ -140,7 +142,7 @@ Strcopy(Str x, Str y) } void @@ -1532,7 +1774,7 @@ index e5a0982..d34129f 100644 { int len; -@@ -160,7 +160,7 @@ Strcopy_charp(Str x, char *y) +@@ -160,7 +162,7 @@ Strcopy_charp(Str x, char *y) } void @@ -1541,7 +1783,7 @@ index e5a0982..d34129f 100644 { int len = n; -@@ -180,7 +180,7 @@ Strcopy_charp_n(Str x, char *y, int n) +@@ -180,7 +182,7 @@ Strcopy_charp_n(Str x, char *y, int n) } void @@ -1550,7 +1792,7 @@ index e5a0982..d34129f 100644 { int newlen; -@@ -209,7 +209,7 @@ Strcat(Str x, Str y) +@@ -209,7 +211,7 @@ Strcat(Str x, Str y) } void @@ -1559,7 +1801,7 @@ index e5a0982..d34129f 100644 { if (y == NULL) return; -@@ -232,8 +232,8 @@ Strgrow(Str x) +@@ -232,8 +234,8 @@ Strgrow(Str x) { char *old = x->ptr; int newlen; @@ -1570,7 +1812,7 @@ index e5a0982..d34129f 100644 newlen += 2; x->ptr = GC_MALLOC_ATOMIC(newlen); x->area_size = newlen; -@@ -278,8 +278,8 @@ void +@@ -278,8 +280,8 @@ void Strchop(Str s) { STR_LENGTH_CHECK(s); @@ -1581,7 +1823,7 @@ index e5a0982..d34129f 100644 s->length--; } s->ptr[s->length] = '\0'; -@@ -301,7 +301,7 @@ Strinsert_char(Str s, int pos, char c) +@@ -301,7 +303,7 @@ Strinsert_char(Str s, int pos, char c) } void @@ -1590,7 +1832,7 @@ index e5a0982..d34129f 100644 { STR_LENGTH_CHECK(s); while (*p) -@@ -530,11 +530,8 @@ Str +@@ -530,11 +532,8 @@ Str Strfgets(FILE * f) { Str s = Strnew(); @@ -1604,7 +1846,7 @@ index e5a0982..d34129f 100644 Strcat_char(s, c); if (c == '\n') break; -@@ -546,11 +543,8 @@ Str +@@ -546,11 +545,8 @@ Str Strfgetall(FILE * f) { Str s = Strnew(); @@ -1816,7 +2058,7 @@ index 0000000..fa0d391 + +#endif /* W3_ALLOC_H */ diff --git a/anchor.c b/anchor.c -index 27bbd56..10d6c1c 100644 +index 27bbd56..b6d121c 100644 --- a/anchor.c +++ b/anchor.c @@ -11,7 +11,7 @@ putAnchor(AnchorList *al, char *url, char *target, Anchor **anchor_return, @@ -1858,16 +2100,17 @@ index 27bbd56..10d6c1c 100644 '\0', line, pos); } -@@ -549,7 +551,7 @@ shiftAnchorPosition(AnchorList *al, HmarkerList *hl, int line, int pos, +@@ -549,7 +551,8 @@ shiftAnchorPosition(AnchorList *al, HmarkerList *hl, int line, int pos, break; if (a->start.pos > pos) { a->start.pos += shift; - if (hl->marks[a->hseq].line == line) -+ if (hl && hl->marks && hl->marks[a->hseq].line == line) ++ if (hl && hl->marks && ++ a->hseq >= 0 && hl->marks[a->hseq].line == line) hl->marks[a->hseq].pos = a->start.pos; } if (a->end.pos >= pos) -@@ -641,7 +643,6 @@ addMultirowsForm(Buffer *buf, AnchorList *al) +@@ -641,7 +644,6 @@ addMultirowsForm(Buffer *buf, AnchorList *al) { int i, j, k, col, ecol, pos; Anchor a_form, *a; @@ -1875,7 +2118,7 @@ index 27bbd56..10d6c1c 100644 Line *l, *ls; if (al == NULL || al->nanchor == 0) -@@ -668,7 +669,6 @@ addMultirowsForm(Buffer *buf, AnchorList *al) +@@ -668,7 +670,6 @@ addMultirowsForm(Buffer *buf, AnchorList *al) if (!ls) continue; } @@ -1883,7 +2126,7 @@ index 27bbd56..10d6c1c 100644 col = COLPOS(ls, a_form.start.pos); ecol = COLPOS(ls, a_form.end.pos); for (j = 0; l && j < a_form.rows; l = l->next, j++) { -@@ -685,6 +685,8 @@ addMultirowsForm(Buffer *buf, AnchorList *al) +@@ -685,6 +686,8 @@ addMultirowsForm(Buffer *buf, AnchorList *al) a->hseq = a_form.hseq; a->y = a_form.y; a->end.pos = pos + ecol - col; @@ -1892,7 +2135,7 @@ index 27bbd56..10d6c1c 100644 l->lineBuf[pos - 1] = '['; l->lineBuf[a->end.pos] = ']'; for (k = pos; k < a->end.pos; k++) -@@ -756,7 +758,7 @@ link_list_panel(Buffer *buf) +@@ -756,7 +759,7 @@ link_list_panel(Buffer *buf) p = parsedURL2Str(&pu)->ptr; u = html_quote(p); if (DecodeURL) @@ -1901,7 +2144,7 @@ index 27bbd56..10d6c1c 100644 else p = u; } -@@ -787,7 +789,7 @@ link_list_panel(Buffer *buf) +@@ -787,7 +790,7 @@ link_list_panel(Buffer *buf) p = parsedURL2Str(&pu)->ptr; u = html_quote(p); if (DecodeURL) @@ -1910,7 +2153,7 @@ index 27bbd56..10d6c1c 100644 else p = u; t = getAnchorText(buf, al, a); -@@ -809,16 +811,13 @@ link_list_panel(Buffer *buf) +@@ -809,16 +812,13 @@ link_list_panel(Buffer *buf) p = parsedURL2Str(&pu)->ptr; u = html_quote(p); if (DecodeURL) @@ -1929,7 +2172,7 @@ index 27bbd56..10d6c1c 100644 Strcat_m_charp(tmp, "<li><a href=\"", u, "\">", t, "</a><br>", p, "\n", NULL); a = retrieveAnchor(buf->formitem, a->start.line, a->start.pos); -@@ -842,19 +841,13 @@ link_list_panel(Buffer *buf) +@@ -842,19 +842,13 @@ link_list_panel(Buffer *buf) p = parsedURL2Str(&pu)->ptr; u = html_quote(p); if (DecodeURL) @@ -14183,9 +14426,18 @@ index fdd8f64..45dc95e 100644 if (UseAltEntity) return alt_latin1[c - 0xa0]; diff --git a/etc.c b/etc.c -index 8fe1215..dcc6edd 100644 +index 8fe1215..37c4f15 100644 --- a/etc.c +++ b/etc.c +@@ -498,7 +498,7 @@ calcPosition(char *l, Lineprop *pr, int len, int pos, int bpos, int mode) + static char *prevl = NULL; + int i, j; + +- if (l == NULL || len == 0) ++ if (l == NULL || len == 0 || pos < 0) + return bpos; + if (l == prevl && mode == CP_AUTO) { + if (pos <= len) @@ -1365,7 +1365,13 @@ setup_child(int child, int i, int f) if (!child) SETPGRP(); @@ -14201,7 +14453,7 @@ index 8fe1215..dcc6edd 100644 QuietMessage = TRUE; fmInitialized = FALSE; diff --git a/file.c b/file.c -index 567d41e..86af3a9 100644 +index 567d41e..4d15ff1 100644 --- a/file.c +++ b/file.c @@ -26,6 +26,8 @@ @@ -14496,7 +14748,22 @@ index 567d41e..86af3a9 100644 TRAP_OFF; return b; } -@@ -2469,6 +2455,7 @@ set_breakpoint(struct readbuffer *obuf, int tag_length) +@@ -2325,8 +2311,12 @@ push_link(int cmd, int offset, int pos) + struct link_stack *p; + p = New(struct link_stack); + p->cmd = cmd; +- p->offset = offset; +- p->pos = pos; ++ p->offset = (short)offset; ++ if (p->offset < 0) ++ p->offset = 0; ++ p->pos = (short)pos; ++ if (p->pos < 0) ++ p->pos = 0; + p->next = link_stack; + link_stack = p; + } +@@ -2469,6 +2459,7 @@ set_breakpoint(struct readbuffer *obuf, int tag_length) bcopy((void *)&obuf->anchor, (void *)&obuf->bp.anchor, sizeof(obuf->anchor)); obuf->bp.img_alt = obuf->img_alt; @@ -14504,7 +14771,7 @@ index 567d41e..86af3a9 100644 obuf->bp.in_bold = obuf->in_bold; obuf->bp.in_italic = obuf->in_italic; obuf->bp.in_under = obuf->in_under; -@@ -2486,6 +2473,7 @@ back_to_breakpoint(struct readbuffer *obuf) +@@ -2486,6 +2477,7 @@ back_to_breakpoint(struct readbuffer *obuf) bcopy((void *)&obuf->bp.anchor, (void *)&obuf->anchor, sizeof(obuf->anchor)); obuf->img_alt = obuf->bp.img_alt; @@ -14512,7 +14779,7 @@ index 567d41e..86af3a9 100644 obuf->in_bold = obuf->bp.in_bold; obuf->in_italic = obuf->bp.in_italic; obuf->in_under = obuf->bp.in_under; -@@ -2729,7 +2717,7 @@ flushline(struct html_feed_environ *h_env, struct readbuffer *obuf, int indent, +@@ -2729,7 +2721,7 @@ flushline(struct html_feed_environ *h_env, struct readbuffer *obuf, int indent, Str line = obuf->line, pass = NULL; char *hidden_anchor = NULL, *hidden_img = NULL, *hidden_bold = NULL, *hidden_under = NULL, *hidden_italic = NULL, *hidden_strike = NULL, @@ -14521,7 +14788,7 @@ index 567d41e..86af3a9 100644 #ifdef DEBUG if (w3m_debug) { -@@ -2761,6 +2749,12 @@ flushline(struct html_feed_environ *h_env, struct readbuffer *obuf, int indent, +@@ -2761,6 +2753,12 @@ flushline(struct html_feed_environ *h_env, struct readbuffer *obuf, int indent, hidden = hidden_img; } } @@ -14534,7 +14801,7 @@ index 567d41e..86af3a9 100644 if (obuf->in_bold) { if ((hidden_bold = has_hidden_link(obuf, HTML_B)) != NULL) { if (!hidden || hidden_bold < hidden) -@@ -2812,6 +2806,8 @@ flushline(struct html_feed_environ *h_env, struct readbuffer *obuf, int indent, +@@ -2812,6 +2810,8 @@ flushline(struct html_feed_environ *h_env, struct readbuffer *obuf, int indent, Strcat_charp(line, "</a>"); if (obuf->img_alt && !hidden_img) Strcat_charp(line, "</img_alt>"); @@ -14543,7 +14810,7 @@ index 567d41e..86af3a9 100644 if (obuf->in_bold && !hidden_bold) Strcat_charp(line, "</b>"); if (obuf->in_italic && !hidden_italic) -@@ -3022,6 +3018,18 @@ flushline(struct html_feed_environ *h_env, struct readbuffer *obuf, int indent, +@@ -3022,6 +3022,18 @@ flushline(struct html_feed_environ *h_env, struct readbuffer *obuf, int indent, Strcat_charp(tmp, "\">"); push_tag(obuf, tmp->ptr, HTML_IMG_ALT); } @@ -14562,7 +14829,7 @@ index 567d41e..86af3a9 100644 if (!hidden_bold && obuf->in_bold) push_tag(obuf, "<B>", HTML_B); if (!hidden_italic && obuf->in_italic) -@@ -3228,7 +3236,7 @@ process_img(struct parsed_tag *tag, int width) +@@ -3228,7 +3240,7 @@ process_img(struct parsed_tag *tag, int width) if (!parsedtag_get_value(tag, ATTR_SRC, &p)) return tmp; @@ -14571,7 +14838,18 @@ index 567d41e..86af3a9 100644 q = NULL; parsedtag_get_value(tag, ATTR_ALT, &q); if (!pseudoInlines && (q == NULL || (*q == '\0' && ignore_null_img_alt))) -@@ -3322,12 +3330,7 @@ process_img(struct parsed_tag *tag, int width) +@@ -3255,9 +3267,9 @@ process_img(struct parsed_tag *tag, int width) + } + #endif + } ++ i = -1; + #ifdef USE_IMAGE + if (use_image) { +- i = -1; + if (parsedtag_get_value(tag, ATTR_HEIGHT, &i)) { + if (i > 0) { + i = (int)(i * image_scale / 100 + 0.5); +@@ -3322,12 +3334,7 @@ process_img(struct parsed_tag *tag, int width) Image image; ParsedURL u; @@ -14584,7 +14862,7 @@ index 567d41e..86af3a9 100644 image.url = parsedURL2Str(&u)->ptr; if (!uncompressed_file_type(u.file, &image.ext)) image.ext = filename_extension(u.file, TRUE); -@@ -3346,8 +3349,14 @@ process_img(struct parsed_tag *tag, int width) +@@ -3346,8 +3353,14 @@ process_img(struct parsed_tag *tag, int width) if (i < 0) i = pixel_per_line; } @@ -14601,7 +14879,7 @@ index 567d41e..86af3a9 100644 Strcat(tmp, Sprintf("<pre_int><img_alt hseq=\"%d\" src=\"", cur_iseq++)); pre_int = TRUE; -@@ -3378,19 +3387,21 @@ process_img(struct parsed_tag *tag, int width) +@@ -3378,19 +3391,21 @@ process_img(struct parsed_tag *tag, int width) if (i0 >= 0) Strcat(tmp, Sprintf(" height=%d", i0)); switch (align) { @@ -14631,7 +14909,7 @@ index 567d41e..86af3a9 100644 case ALIGN_BOTTOM: top = ni - 1; bottom = 0; -@@ -3408,7 +3419,12 @@ process_img(struct parsed_tag *tag, int width) +@@ -3408,7 +3423,12 @@ process_img(struct parsed_tag *tag, int width) } break; } @@ -14645,7 +14923,16 @@ index 567d41e..86af3a9 100644 if (xoffset) Strcat(tmp, Sprintf(" xoffset=%d", xoffset)); if (yoffset) -@@ -3548,7 +3564,7 @@ process_anchor(struct parsed_tag *tag, char *tagbuf) +@@ -3435,7 +3455,7 @@ process_img(struct parsed_tag *tag, int width) + if (use_image) { + if (n > nw) { + char *r; +- for (r = q, n = 0; r; r += get_mclen(r), n += get_mcwidth(r)) { ++ for (r = q, n = 0; *r; r += get_mclen(r), n += get_mcwidth(r)) { + if (n + get_mcwidth(r) > nw) + break; + } +@@ -3548,7 +3568,7 @@ process_anchor(struct parsed_tag *tag, char *tagbuf) Str process_input(struct parsed_tag *tag) { @@ -14654,7 +14941,7 @@ index 567d41e..86af3a9 100644 char *q, *p, *r, *p2, *s; Str tmp = NULL; char *qq = ""; -@@ -3567,9 +3583,9 @@ process_input(struct parsed_tag *tag) +@@ -3567,9 +3587,9 @@ process_input(struct parsed_tag *tag) parsedtag_get_value(tag, ATTR_VALUE, &q); r = ""; parsedtag_get_value(tag, ATTR_NAME, &r); @@ -14667,7 +14954,7 @@ index 567d41e..86af3a9 100644 parsedtag_get_value(tag, ATTR_MAXLENGTH, &i); p2 = NULL; parsedtag_get_value(tag, ATTR_ALT, &p2); -@@ -3623,9 +3639,10 @@ process_input(struct parsed_tag *tag) +@@ -3623,9 +3643,10 @@ process_input(struct parsed_tag *tag) Strcat(tmp, getLinkNumberStr(0)); Strcat_char(tmp, '('); } @@ -14680,7 +14967,7 @@ index 567d41e..86af3a9 100644 if (x) Strcat_charp(tmp, " checked"); if (y) -@@ -3670,18 +3687,18 @@ process_input(struct parsed_tag *tag) +@@ -3670,18 +3691,18 @@ process_input(struct parsed_tag *tag) case FORM_INPUT_PASSWORD: i = 0; if (q) { @@ -14703,7 +14990,7 @@ index 567d41e..86af3a9 100644 Strcat_char(tmp, ' '); } break; -@@ -3732,6 +3749,75 @@ process_input(struct parsed_tag *tag) +@@ -3732,6 +3753,75 @@ process_input(struct parsed_tag *tag) } Str @@ -14779,7 +15066,27 @@ index 567d41e..86af3a9 100644 process_select(struct parsed_tag *tag) { Str tmp = NULL; -@@ -4084,6 +4170,7 @@ process_form_int(struct parsed_tag *tag, int fid) +@@ -3926,7 +4016,7 @@ process_textarea(struct parsed_tag *tag, int width) + cur_textarea_size = 20; + if (parsedtag_get_value(tag, ATTR_COLS, &p)) { + cur_textarea_size = atoi(p); +- if (p[strlen(p) - 1] == '%') ++ if (strlen(p) > 0 && p[strlen(p) - 1] == '%') + cur_textarea_size = width * cur_textarea_size / 100 - 2; + if (cur_textarea_size <= 0) { + cur_textarea_size = 20; +@@ -4003,7 +4093,9 @@ feed_textarea(char *str) + Strcat_charp(textarea_str[n_textarea], "\r\n"); + str++; + } +- else if (*str != '\r') ++ else if (*str == '\r') ++ str++; ++ else + Strcat_char(textarea_str[n_textarea], *(str++)); + } + } +@@ -4084,6 +4176,7 @@ process_form_int(struct parsed_tag *tag, int fid) parsedtag_get_value(tag, ATTR_METHOD, &p); q = "!CURRENT_URL!"; parsedtag_get_value(tag, ATTR_ACTION, &q); @@ -14787,7 +15094,7 @@ index 567d41e..86af3a9 100644 r = NULL; #ifdef USE_M17N if (parsedtag_get_value(tag, ATTR_ACCEPT_CHARSET, &r)) -@@ -4113,7 +4200,7 @@ process_form_int(struct parsed_tag *tag, int fid) +@@ -4113,7 +4206,7 @@ process_form_int(struct parsed_tag *tag, int fid) forms = New_N(FormList *, forms_size); form_stack = NewAtom_N(int, forms_size); } @@ -14796,7 +15103,7 @@ index 567d41e..86af3a9 100644 forms_size += form_max; forms = New_Reuse(FormList *, forms, forms_size); form_stack = New_Reuse(int, form_stack, forms_size); -@@ -4284,15 +4371,15 @@ getMetaRefreshParam(char *q, Str *refresh_uri) +@@ -4284,15 +4377,16 @@ getMetaRefreshParam(char *q, Str *refresh_uri) while (*q) { if (!strncasecmp(q, "url=", 4)) { q += 4; @@ -14810,12 +15117,13 @@ index 567d41e..86af3a9 100644 - if (s_tmp->ptr[s_tmp->length - 1] == '\"') { /* " - */ -+ if (s_tmp->ptr[s_tmp->length - 1] == '\"' /* " */ -+ || s_tmp->ptr[s_tmp->length - 1] == '\'') { /* ' */ ++ if (s_tmp->length > 0 && ++ (s_tmp->ptr[s_tmp->length - 1] == '\"' || /* " */ ++ s_tmp->ptr[s_tmp->length - 1] == '\'')) { /* ' */ s_tmp->length--; s_tmp->ptr[s_tmp->length] = '\0'; } -@@ -4599,6 +4686,12 @@ HTMLtagproc1(struct parsed_tag *tag, struct html_feed_environ *h_env) +@@ -4599,6 +4693,12 @@ HTMLtagproc1(struct parsed_tag *tag, struct html_feed_environ *h_env) case HTML_DD: CLOSE_A; CLOSE_DT; @@ -14828,7 +15136,7 @@ index 567d41e..86af3a9 100644 if (envs[h_env->envc].env == HTML_DL_COMPACT) { if (obuf->pos > envs[h_env->envc].indent) flushline(h_env, obuf, envs[h_env->envc].indent, 0, -@@ -4833,13 +4926,13 @@ HTMLtagproc1(struct parsed_tag *tag, struct html_feed_environ *h_env) +@@ -4833,13 +4933,13 @@ HTMLtagproc1(struct parsed_tag *tag, struct html_feed_environ *h_env) #ifdef USE_IMAGE i = 0; if (parsedtag_get_value(tag, ATTR_TOP_MARGIN, &i)) { @@ -14846,7 +15154,7 @@ index 567d41e..86af3a9 100644 } #endif return 0; -@@ -4853,15 +4946,43 @@ HTMLtagproc1(struct parsed_tag *tag, struct html_feed_environ *h_env) +@@ -4853,15 +4953,43 @@ HTMLtagproc1(struct parsed_tag *tag, struct html_feed_environ *h_env) case HTML_INPUT_ALT: i = 0; if (parsedtag_get_value(tag, ATTR_TOP_MARGIN, &i)) { @@ -14864,10 +15172,10 @@ index 567d41e..86af3a9 100644 + } + if (parsedtag_get_value(tag, ATTR_HSEQ, &hseq)) { + obuf->input_alt.hseq = hseq; - } ++ } + if (parsedtag_get_value(tag, ATTR_FID, &i)) { + obuf->input_alt.fid = i; -+ } + } + if (parsedtag_get_value(tag, ATTR_TYPE, &p)) { + obuf->input_alt.type = Strnew_charp(p); + } @@ -14894,7 +15202,7 @@ index 567d41e..86af3a9 100644 case HTML_TABLE: close_anchor(h_env, obuf); obuf->table_level++; -@@ -4884,6 +5005,8 @@ HTMLtagproc1(struct parsed_tag *tag, struct html_feed_environ *h_env) +@@ -4884,6 +5012,8 @@ HTMLtagproc1(struct parsed_tag *tag, struct html_feed_environ *h_env) else w = BORDER_THIN; } @@ -14903,7 +15211,7 @@ index 567d41e..86af3a9 100644 if (parsedtag_get_value(tag, ATTR_WIDTH, &i)) { if (obuf->table_level == 0) width = REAL_WIDTH(i, h_env->limit - envs[h_env->envc].indent); -@@ -4892,9 +5015,24 @@ HTMLtagproc1(struct parsed_tag *tag, struct html_feed_environ *h_env) +@@ -4892,9 +5022,24 @@ HTMLtagproc1(struct parsed_tag *tag, struct html_feed_environ *h_env) } if (parsedtag_exists(tag, ATTR_HBORDER)) w = BORDER_NOWIN; @@ -14928,7 +15236,7 @@ index 567d41e..86af3a9 100644 #ifdef ID_EXT parsedtag_get_value(tag, ATTR_ID, &id); #endif /* ID_EXT */ -@@ -4970,6 +5108,16 @@ HTMLtagproc1(struct parsed_tag *tag, struct html_feed_environ *h_env) +@@ -4970,6 +5115,16 @@ HTMLtagproc1(struct parsed_tag *tag, struct html_feed_environ *h_env) case HTML_INPUT: close_anchor(h_env, obuf); tmp = process_input(tag); @@ -14945,7 +15253,7 @@ index 567d41e..86af3a9 100644 if (tmp) HTMLlineproc1(tmp->ptr, h_env); return 1; -@@ -5067,11 +5215,10 @@ HTMLtagproc1(struct parsed_tag *tag, struct html_feed_environ *h_env) +@@ -5067,11 +5222,10 @@ HTMLtagproc1(struct parsed_tag *tag, struct html_feed_environ *h_env) } return 1; case HTML_BASE: @@ -14959,7 +15267,7 @@ index 567d41e..86af3a9 100644 parseURL(p, cur_baseURL, NULL); } #endif -@@ -5329,6 +5476,13 @@ HTMLlineproc2body(Buffer *buf, Str (*feed) (), int llimit) +@@ -5329,6 +5483,13 @@ HTMLlineproc2body(Buffer *buf, Str (*feed) (), int llimit) #ifdef MENU_SELECT Anchor **a_select = NULL; #endif @@ -14973,7 +15281,7 @@ index 567d41e..86af3a9 100644 if (out_size == 0) { out_size = LINELEN; -@@ -5523,16 +5677,17 @@ HTMLlineproc2body(Buffer *buf, Str (*feed) (), int llimit) +@@ -5523,16 +5684,17 @@ HTMLlineproc2body(Buffer *buf, Str (*feed) (), int llimit) hseq = 0; id = NULL; if (parsedtag_get_value(tag, ATTR_NAME, &id)) { @@ -14995,7 +15303,16 @@ index 567d41e..86af3a9 100644 parsedtag_get_value(tag, ATTR_TITLE, &s); parsedtag_get_value(tag, ATTR_ACCESSKEY, &t); parsedtag_get_value(tag, ATTR_HSEQ, &hseq); -@@ -5618,7 +5773,7 @@ HTMLlineproc2body(Buffer *buf, Str (*feed) (), int llimit) +@@ -5571,7 +5733,7 @@ HTMLlineproc2body(Buffer *buf, Str (*feed) (), int llimit) + a_href->end.pos = pos; + if (a_href->start.line == a_href->end.line && + a_href->start.pos == a_href->end.pos) { +- if (buf->hmarklist && ++ if (buf->hmarklist && a_href->hseq >= 0 && + a_href->hseq < buf->hmarklist->nmark) + buf->hmarklist->marks[a_href->hseq].invalid = 1; + a_href->hseq = -1; +@@ -5618,7 +5780,7 @@ HTMLlineproc2body(Buffer *buf, Str (*feed) (), int llimit) ParsedURL u; Image *image; @@ -15004,7 +15321,7 @@ index 567d41e..86af3a9 100644 a_img->image = image = New(Image); image->url = parsedURL2Str(&u)->ptr; if (!uncompressed_file_type(u.file, &image->ext)) -@@ -5639,7 +5794,7 @@ HTMLlineproc2body(Buffer *buf, Str (*feed) (), int llimit) +@@ -5639,7 +5801,7 @@ HTMLlineproc2body(Buffer *buf, Str (*feed) (), int llimit) image->map = q; image->ismap = ismap; image->touch = 0; @@ -15013,7 +15330,7 @@ index 567d41e..86af3a9 100644 IMG_FLAG_SKIP); } else if (iseq < 0) { -@@ -5678,7 +5833,8 @@ HTMLlineproc2body(Buffer *buf, Str (*feed) (), int llimit) +@@ -5678,7 +5840,8 @@ HTMLlineproc2body(Buffer *buf, Str (*feed) (), int llimit) parsedtag_get_value(tag, ATTR_FID, &form_id); parsedtag_get_value(tag, ATTR_TOP_MARGIN, &top); parsedtag_get_value(tag, ATTR_BOTTOM_MARGIN, &bottom); @@ -15023,7 +15340,7 @@ index 567d41e..86af3a9 100644 break; /* outside of <form>..</form> */ form = forms[form_id]; if (hseq > 0) { -@@ -5689,6 +5845,21 @@ HTMLlineproc2body(Buffer *buf, Str (*feed) (), int llimit) +@@ -5689,6 +5852,21 @@ HTMLlineproc2body(Buffer *buf, Str (*feed) (), int llimit) putHmarker(buf->hmarklist, currentLn(buf), hpos, hseq - 1); } @@ -15045,7 +15362,7 @@ index 567d41e..86af3a9 100644 if (!form->target) form->target = buf->baseTarget; if (a_textarea && -@@ -5761,8 +5932,8 @@ HTMLlineproc2body(Buffer *buf, Str (*feed) (), int llimit) +@@ -5761,8 +5939,8 @@ HTMLlineproc2body(Buffer *buf, Str (*feed) (), int llimit) break; if (parsedtag_get_value(tag, ATTR_HREF, &p)) { MapArea *a; @@ -15056,7 +15373,7 @@ index 567d41e..86af3a9 100644 t = NULL; parsedtag_get_value(tag, ATTR_TARGET, &t); q = ""; -@@ -5811,11 +5982,14 @@ HTMLlineproc2body(Buffer *buf, Str (*feed) (), int llimit) +@@ -5811,11 +5989,14 @@ HTMLlineproc2body(Buffer *buf, Str (*feed) (), int llimit) break; case HTML_BASE: if (parsedtag_get_value(tag, ATTR_HREF, &p)) { @@ -15073,7 +15390,7 @@ index 567d41e..86af3a9 100644 } if (parsedtag_get_value(tag, ATTR_TARGET, &p)) buf->baseTarget = -@@ -5830,8 +6004,8 @@ HTMLlineproc2body(Buffer *buf, Str (*feed) (), int llimit) +@@ -5830,8 +6011,8 @@ HTMLlineproc2body(Buffer *buf, Str (*feed) (), int llimit) int refresh_interval = getMetaRefreshParam(q, &tmp); #ifdef USE_ALARM if (tmp) { @@ -15084,7 +15401,7 @@ index 567d41e..86af3a9 100644 buf->event = setAlarmEvent(buf->event, refresh_interval, AL_IMPLICIT_ONCE, -@@ -5844,8 +6018,8 @@ HTMLlineproc2body(Buffer *buf, Str (*feed) (), int llimit) +@@ -5844,8 +6025,8 @@ HTMLlineproc2body(Buffer *buf, Str (*feed) (), int llimit) FUNCNAME_reload, NULL); #else if (tmp && refresh_interval == 0) { @@ -15095,7 +15412,7 @@ index 567d41e..86af3a9 100644 pushEvent(FUNCNAME_gorURL, p); } #endif -@@ -5864,14 +6038,14 @@ HTMLlineproc2body(Buffer *buf, Str (*feed) (), int llimit) +@@ -5864,14 +6045,14 @@ HTMLlineproc2body(Buffer *buf, Str (*feed) (), int llimit) case HTML_TEXTAREA_INT: if (parsedtag_get_value(tag, ATTR_TEXTAREANUMBER, &n_textarea) @@ -15112,7 +15429,7 @@ index 567d41e..86af3a9 100644 FormItemList *item = (FormItemList *)a_textarea[n_textarea]->url; item->init_value = item->value = -@@ -5881,7 +6055,7 @@ HTMLlineproc2body(Buffer *buf, Str (*feed) (), int llimit) +@@ -5881,7 +6062,7 @@ HTMLlineproc2body(Buffer *buf, Str (*feed) (), int llimit) #ifdef MENU_SELECT case HTML_SELECT_INT: if (parsedtag_get_value(tag, ATTR_SELECTNUMBER, &n_select) @@ -15121,7 +15438,7 @@ index 567d41e..86af3a9 100644 select_option[n_select].first = NULL; select_option[n_select].last = NULL; } -@@ -5889,7 +6063,7 @@ HTMLlineproc2body(Buffer *buf, Str (*feed) (), int llimit) +@@ -5889,7 +6070,7 @@ HTMLlineproc2body(Buffer *buf, Str (*feed) (), int llimit) n_select = -1; break; case HTML_N_SELECT_INT: @@ -15130,7 +15447,7 @@ index 567d41e..86af3a9 100644 FormItemList *item = (FormItemList *)a_select[n_select]->url; item->select_option = select_option[n_select].first; -@@ -5929,7 +6103,7 @@ HTMLlineproc2body(Buffer *buf, Str (*feed) (), int llimit) +@@ -5929,7 +6110,7 @@ HTMLlineproc2body(Buffer *buf, Str (*feed) (), int llimit) #ifdef ID_EXT id = NULL; if (parsedtag_get_value(tag, ATTR_ID, &id)) { @@ -15139,7 +15456,7 @@ index 567d41e..86af3a9 100644 registerName(buf, id, currentLn(buf), pos); } if (renderFrameSet && -@@ -5964,7 +6138,8 @@ HTMLlineproc2body(Buffer *buf, Str (*feed) (), int llimit) +@@ -5964,7 +6145,8 @@ HTMLlineproc2body(Buffer *buf, Str (*feed) (), int llimit) fclose(debug); #endif for (form_id = 1; form_id <= form_max; form_id++) @@ -15149,7 +15466,7 @@ index 567d41e..86af3a9 100644 buf->formlist = (form_max >= 0) ? forms[form_max] : NULL; if (n_textarea) addMultirowsForm(buf, buf->formitem); -@@ -5982,7 +6157,8 @@ addLink(Buffer *buf, struct parsed_tag *tag) +@@ -5982,7 +6164,8 @@ addLink(Buffer *buf, struct parsed_tag *tag) parsedtag_get_value(tag, ATTR_HREF, &href); if (href) @@ -15159,7 +15476,7 @@ index 567d41e..86af3a9 100644 parsedtag_get_value(tag, ATTR_TITLE, &title); parsedtag_get_value(tag, ATTR_TYPE, &ctype); parsedtag_get_value(tag, ATTR_REL, &rel); -@@ -6154,10 +6330,10 @@ HTMLlineproc0(char *line, struct html_feed_environ *h_env, int internal) +@@ -6154,10 +6337,10 @@ HTMLlineproc0(char *line, struct html_feed_environ *h_env, int internal) while (*line != '\0') { char *str, *p; int is_tag = FALSE; @@ -15174,7 +15491,16 @@ index 567d41e..86af3a9 100644 if (*line == '<' || obuf->status != R_ST_NORMAL) { /* -@@ -6239,7 +6415,7 @@ HTMLlineproc0(char *line, struct html_feed_environ *h_env, int internal) +@@ -6173,7 +6356,7 @@ HTMLlineproc0(char *line, struct html_feed_environ *h_env, int internal) + } + if (h_env->tagbuf->length == 0) + continue; +- str = h_env->tagbuf->ptr; ++ str = Strdup(h_env->tagbuf)->ptr; + if (*str == '<') { + if (str[1] && REALLY_THE_BEGINNING_OF_A_TAG(str)) + is_tag = TRUE; +@@ -6239,7 +6422,7 @@ HTMLlineproc0(char *line, struct html_feed_environ *h_env, int internal) } proc_normal: @@ -15183,7 +15509,16 @@ index 567d41e..86af3a9 100644 /* * within table: in <table>..</table>, all input tokens * are fed to the table renderer, and then the renderer -@@ -6272,6 +6448,7 @@ HTMLlineproc0(char *line, struct html_feed_environ *h_env, int internal) +@@ -6255,6 +6438,8 @@ HTMLlineproc0(char *line, struct html_feed_environ *h_env, int internal) + if (obuf->table_level >= 0) { + struct table *tbl0 = tables[obuf->table_level]; + str = Sprintf("<table_alt tid=%d>", tbl0->ntable)->ptr; ++ if (tbl0->row < 0) ++ continue; + pushTable(tbl0, tbl); + tbl = tbl0; + tbl_mode = &table_mode[obuf->table_level]; +@@ -6272,6 +6457,7 @@ HTMLlineproc0(char *line, struct html_feed_environ *h_env, int internal) do_blankline(h_env, obuf, indent, 0, h_env->limit); } save_fonteffect(h_env, obuf); @@ -15191,7 +15526,17 @@ index 567d41e..86af3a9 100644 renderTable(tbl, tbl_width, h_env); restore_fonteffect(h_env, obuf); obuf->flag &= ~RB_IGNORE_P; -@@ -6756,6 +6933,12 @@ init_henv(struct html_feed_environ *h_env, struct readbuffer *obuf, +@@ -6429,7 +6615,8 @@ HTMLlineproc0(char *line, struct html_feed_environ *h_env, int internal) + indent = h_env->envs[h_env->envc].indent; + if (obuf->bp.pos - i > indent) { + Str line; +- append_tags(obuf); ++ append_tags(obuf); /* may reallocate the buffer */ ++ bp = obuf->line->ptr + obuf->bp.len; + line = Strnew_charp(bp); + Strshrink(obuf->line, obuf->line->length - obuf->bp.len); + #ifdef FORMAT_NICE +@@ -6756,6 +6943,12 @@ init_henv(struct html_feed_environ *h_env, struct readbuffer *obuf, obuf->nobr_level = 0; bzero((void *)&obuf->anchor, sizeof(obuf->anchor)); obuf->img_alt = 0; @@ -15204,7 +15549,7 @@ index 567d41e..86af3a9 100644 obuf->in_bold = 0; obuf->in_italic = 0; obuf->in_under = 0; -@@ -6791,6 +6974,15 @@ completeHTMLstream(struct html_feed_environ *h_env, struct readbuffer *obuf) +@@ -6791,6 +6984,15 @@ completeHTMLstream(struct html_feed_environ *h_env, struct readbuffer *obuf) push_tag(obuf, "</img_alt>", HTML_N_IMG_ALT); obuf->img_alt = NULL; } @@ -15220,7 +15565,7 @@ index 567d41e..86af3a9 100644 if (obuf->in_bold) { push_tag(obuf, "</b>", HTML_N_B); obuf->in_bold = 0; -@@ -6824,9 +7016,12 @@ completeHTMLstream(struct html_feed_environ *h_env, struct readbuffer *obuf) +@@ -6824,9 +7026,12 @@ completeHTMLstream(struct html_feed_environ *h_env, struct readbuffer *obuf) obuf->table_level = MAX_TABLE - 1; while (obuf->table_level >= 0) { @@ -15233,7 +15578,7 @@ index 567d41e..86af3a9 100644 } } -@@ -6848,6 +7043,8 @@ print_internal_information(struct html_feed_environ *henv) +@@ -6848,6 +7053,8 @@ print_internal_information(struct html_feed_environ *henv) if (form_max >= 0) { FormList *fp; for (i = 0; i <= form_max; i++) { @@ -15242,7 +15587,7 @@ index 567d41e..86af3a9 100644 fp = forms[i]; s = Sprintf("<form_int fid=\"%d\" action=\"%s\" method=\"%s\"", i, html_quote(fp->action->ptr), -@@ -6963,8 +7160,6 @@ loadHTMLstream(URLFile *f, Buffer *newBuf, FILE * src, int internal) +@@ -6963,8 +7170,6 @@ loadHTMLstream(URLFile *f, Buffer *newBuf, FILE * src, int internal) image_flag = IMG_FLAG_AUTO; else image_flag = IMG_FLAG_SKIP; @@ -15251,7 +15596,7 @@ index 567d41e..86af3a9 100644 #endif if (w3m_halfload) { -@@ -6987,6 +7182,9 @@ loadHTMLstream(URLFile *f, Buffer *newBuf, FILE * src, int internal) +@@ -6987,6 +7192,9 @@ loadHTMLstream(URLFile *f, Buffer *newBuf, FILE * src, int internal) htmlenv1.f = stdout; else htmlenv1.buf = newTextLineList(); @@ -15261,7 +15606,7 @@ index 567d41e..86af3a9 100644 if (SETJMP(AbortLoading) != 0) { HTMLlineproc1("<br>Transfer Interrupted!<br>", &htmlenv1); -@@ -7048,18 +7246,23 @@ loadHTMLstream(URLFile *f, Buffer *newBuf, FILE * src, int internal) +@@ -7048,18 +7256,23 @@ loadHTMLstream(URLFile *f, Buffer *newBuf, FILE * src, int internal) } #endif lineBuf2 = convertLine(f, lineBuf2, HTML_MODE, &charset, doc_charset); @@ -15287,7 +15632,7 @@ index 567d41e..86af3a9 100644 if (htmlenv1.title) newBuf->buffername = htmlenv1.title; if (w3m_halfdump) { -@@ -7096,16 +7299,17 @@ loadHTMLString(Str page) +@@ -7096,16 +7309,17 @@ loadHTMLString(Str page) MySignalHandler(*volatile prevtrap) (SIGNAL_ARG) = NULL; Buffer *newBuf; @@ -15307,7 +15652,7 @@ index 567d41e..86af3a9 100644 #ifdef USE_M17N newBuf->document_charset = InnerCharset; #endif -@@ -7115,6 +7319,7 @@ loadHTMLString(Str page) +@@ -7115,6 +7329,7 @@ loadHTMLString(Str page) #endif TRAP_OFF; @@ -15315,7 +15660,7 @@ index 567d41e..86af3a9 100644 newBuf->topLine = newBuf->firstLine; newBuf->lastLine = newBuf->currentLine; newBuf->currentLine = newBuf->firstLine; -@@ -7207,7 +7412,7 @@ loadGopherDir(URLFile *uf, ParsedURL *pu, wc_ces * charset) +@@ -7207,7 +7422,7 @@ loadGopherDir(URLFile *uf, ParsedURL *pu, wc_ces * charset) q = Strnew_m_charp("gopher://", host->ptr, ":", port->ptr, "/", file->ptr, NULL)->ptr; Strcat_m_charp(tmp, "<a href=\"", @@ -15324,7 +15669,7 @@ index 567d41e..86af3a9 100644 "\">", p, html_quote(name->ptr + 1), "</a>\n", NULL); } -@@ -7243,7 +7448,6 @@ loadBuffer(URLFile *uf, Buffer *volatile newBuf) +@@ -7243,7 +7458,6 @@ loadBuffer(URLFile *uf, Buffer *volatile newBuf) if (newBuf == NULL) newBuf = newBuffer(INIT_BUFFER_WIDTH); @@ -15332,7 +15677,7 @@ index 567d41e..86af3a9 100644 if (SETJMP(AbortLoading) != 0) { goto _end; -@@ -7331,6 +7535,7 @@ loadImageBuffer(URLFile *uf, Buffer *newBuf) +@@ -7331,6 +7545,7 @@ loadImageBuffer(URLFile *uf, Buffer *newBuf) URLFile f; MySignalHandler(*volatile prevtrap) (SIGNAL_ARG) = NULL; struct stat st; @@ -15340,7 +15685,7 @@ index 567d41e..86af3a9 100644 loadImage(newBuf, IMG_FLAG_STOP); image.url = uf->url; -@@ -7338,20 +7543,18 @@ loadImageBuffer(URLFile *uf, Buffer *newBuf) +@@ -7338,20 +7553,18 @@ loadImageBuffer(URLFile *uf, Buffer *newBuf) image.width = -1; image.height = -1; image.cache = NULL; @@ -15364,7 +15709,7 @@ index 567d41e..86af3a9 100644 TRAP_OFF; cache->loaded = IMG_FLAG_LOADED; -@@ -7371,6 +7574,7 @@ loadImageBuffer(URLFile *uf, Buffer *newBuf) +@@ -7371,6 +7584,7 @@ loadImageBuffer(URLFile *uf, Buffer *newBuf) init_stream(&f, SCM_LOCAL, newStrStream(tmp)); loadHTMLstream(&f, newBuf, src, TRUE); @@ -15372,7 +15717,7 @@ index 567d41e..86af3a9 100644 if (src) fclose(src); -@@ -7411,7 +7615,7 @@ conv_symbol(Line *l) +@@ -7411,7 +7625,7 @@ conv_symbol(Line *l) symbol = get_symbol(DisplayCharset, &w); #endif } @@ -15381,7 +15726,7 @@ index 567d41e..86af3a9 100644 #ifdef USE_M17N p += len - 1; pr += len - 1; -@@ -7580,8 +7784,11 @@ openGeneralPagerBuffer(InputStream stream) +@@ -7580,8 +7794,11 @@ openGeneralPagerBuffer(InputStream stream) #ifdef USE_M17N content_charset = 0; #endif @@ -15394,7 +15739,7 @@ index 567d41e..86af3a9 100644 readHeader(&uf, t_buf, TRUE, NULL); t = checkContentType(t_buf); if (t == NULL) -@@ -7609,14 +7816,13 @@ openGeneralPagerBuffer(InputStream stream) +@@ -7609,14 +7826,13 @@ openGeneralPagerBuffer(InputStream stream) #ifdef USE_IMAGE else if (activeImage && displayImage && !useExtImageViewer && !(w3m_dump & ~DUMP_FRAME) && !strncasecmp(t, "image/", 6)) { @@ -15411,7 +15756,7 @@ index 567d41e..86af3a9 100644 UFclose(&uf); if (buf == NULL || buf == NO_BUFFER) return buf; -@@ -7629,8 +7835,6 @@ openGeneralPagerBuffer(InputStream stream) +@@ -7629,8 +7845,6 @@ openGeneralPagerBuffer(InputStream stream) } } buf->real_type = t; @@ -15420,7 +15765,7 @@ index 567d41e..86af3a9 100644 return buf; } -@@ -7766,6 +7970,8 @@ save2tmp(URLFile uf, char *tmpf) +@@ -7766,6 +7980,8 @@ save2tmp(URLFile uf, char *tmpf) clen_t linelen = 0, trbyte = 0; MySignalHandler(*volatile prevtrap) (SIGNAL_ARG) = NULL; static JMP_BUF env_bak; @@ -15429,7 +15774,7 @@ index 567d41e..86af3a9 100644 ff = fopen(tmpf, "wb"); if (ff == NULL) { -@@ -7802,30 +8008,29 @@ save2tmp(URLFile uf, char *tmpf) +@@ -7802,30 +8018,29 @@ save2tmp(URLFile uf, char *tmpf) else #endif /* USE_NNTP */ { @@ -15472,7 +15817,7 @@ index 567d41e..86af3a9 100644 { Str tmpf, command; struct mailcap *mcap; -@@ -7834,7 +8039,7 @@ doExternal(URLFile uf, char *path, char *type, Buffer **bufp, +@@ -7834,7 +8049,7 @@ doExternal(URLFile uf, char *path, char *type, Buffer **bufp, char *header, *src = NULL, *ext = uf.ext; if (!(mcap = searchExtViewer(type))) @@ -15481,7 +15826,7 @@ index 567d41e..86af3a9 100644 if (mcap->nametemplate) { tmpf = unquote_mailcap(mcap->nametemplate, NULL, "", NULL, NULL); -@@ -7867,15 +8072,13 @@ doExternal(URLFile uf, char *path, char *type, Buffer **bufp, +@@ -7867,15 +8082,13 @@ doExternal(URLFile uf, char *path, char *type, Buffer **bufp, UFclose(&uf); myExec(command->ptr); } @@ -15499,7 +15844,7 @@ index 567d41e..86af3a9 100644 } } if (mcap->flags & (MAILCAP_HTMLOUTPUT | MAILCAP_COPIOUSOUTPUT)) { -@@ -7918,14 +8121,13 @@ doExternal(URLFile uf, char *path, char *type, Buffer **bufp, +@@ -7918,14 +8131,13 @@ doExternal(URLFile uf, char *path, char *type, Buffer **bufp, buf = NO_BUFFER; } if (buf && buf != NO_BUFFER) { @@ -15518,7 +15863,7 @@ index 567d41e..86af3a9 100644 } static int -@@ -7935,7 +8137,8 @@ _MoveFile(char *path1, char *path2) +@@ -7935,7 +8147,8 @@ _MoveFile(char *path1, char *path2) FILE *f2; int is_pipe; clen_t linelen = 0, trbyte = 0; @@ -15528,7 +15873,7 @@ index 567d41e..86af3a9 100644 f1 = openIS(path1); if (f1 == NULL) -@@ -7953,12 +8156,13 @@ _MoveFile(char *path1, char *path2) +@@ -7953,12 +8166,13 @@ _MoveFile(char *path1, char *path2) return -1; } current_content_length = 0; @@ -15546,7 +15891,7 @@ index 567d41e..86af3a9 100644 ISclose(f1); if (is_pipe) pclose(f2); -@@ -7998,7 +8202,7 @@ _doFileCopy(char *tmpf, char *defstr, int download) +@@ -7998,7 +8212,7 @@ _doFileCopy(char *tmpf, char *defstr, int download) else { if (q) { p = unescape_spaces(Strnew_charp(q))->ptr; @@ -15555,7 +15900,7 @@ index 567d41e..86af3a9 100644 } p = expandPath(p); if (checkOverWrite(p) < 0) -@@ -8317,21 +8521,23 @@ uncompress_stream(URLFile *uf, char **src) +@@ -8317,21 +8531,23 @@ uncompress_stream(URLFile *uf, char **src) } if (pid2 == 0) { /* child2 */ @@ -15584,7 +15929,7 @@ index 567d41e..86af3a9 100644 exit(0); } /* child1 */ -@@ -8378,7 +8584,7 @@ lessopen_stream(char *path) +@@ -8378,7 +8594,7 @@ lessopen_stream(char *path) } c = getc(fp); if (c == EOF) { @@ -15797,7 +16142,7 @@ index 8378939..96d3ab3 100644 global double image_scale init(100); #endif diff --git a/form.c b/form.c -index b7556ca..1aaaf19 100644 +index b7556ca..0605513 100644 --- a/form.c +++ b/form.c @@ -10,8 +10,10 @@ @@ -15835,7 +16180,17 @@ index b7556ca..1aaaf19 100644 } void -@@ -438,6 +442,9 @@ formUpdateBuffer(Anchor *a, Buffer *buf, FormItemList *form) +@@ -316,7 +320,8 @@ form_update_line(Line *line, char **str, int spos, int epos, int width, + pos += width - w; + + len = line->len + pos + spos - epos; +- buf = New_N(char, len); ++ buf = New_N(char, len + 1); ++ buf[len] = '\0'; + prop = New_N(Lineprop, len); + bcopy((void *)line->lineBuf, (void *)buf, spos * sizeof(char)); + bcopy((void *)line->propBuf, (void *)prop, spos * sizeof(Lineprop)); +@@ -438,6 +443,9 @@ formUpdateBuffer(Anchor *a, Buffer *buf, FormItemList *form) switch (form->type) { case FORM_INPUT_CHECKBOX: case FORM_INPUT_RADIO: @@ -15845,7 +16200,7 @@ index b7556ca..1aaaf19 100644 if (form->checked) buf->currentLine->lineBuf[spos] = '*'; else -@@ -455,8 +462,14 @@ formUpdateBuffer(Anchor *a, Buffer *buf, FormItemList *form) +@@ -455,8 +463,14 @@ formUpdateBuffer(Anchor *a, Buffer *buf, FormItemList *form) } else #endif /* MENU_SELECT */ @@ -15860,16 +16215,17 @@ index b7556ca..1aaaf19 100644 if (form->type == FORM_TEXTAREA) { int n = a->y - buf->currentLine->linenumber; if (n > 0) -@@ -477,6 +490,8 @@ formUpdateBuffer(Anchor *a, Buffer *buf, FormItemList *form) +@@ -477,6 +491,9 @@ formUpdateBuffer(Anchor *a, Buffer *buf, FormItemList *form) spos = a->start.pos; epos = a->end.pos; } -+ if (a->start.line != a->end.line || spos > epos || epos >= l->len || spos < 0 || epos < 0) ++ if (a->start.line != a->end.line || spos > epos || epos >= l->len || ++ spos < 0 || epos < 0 || COLPOS(l, epos) < col) + break; pos = form_update_line(l, &p, spos, epos, COLPOS(l, epos) - col, rows > 1, form->type == FORM_INPUT_PASSWORD); -@@ -787,7 +802,7 @@ struct pre_form { +@@ -787,7 +804,7 @@ struct pre_form { static struct pre_form *PreForm = NULL; static struct pre_form * @@ -15878,7 +16234,7 @@ index b7556ca..1aaaf19 100644 { ParsedURL pu; struct pre_form *new; -@@ -796,21 +811,13 @@ add_pre_form(struct pre_form *prev, char *url, char *name, char *action) +@@ -796,21 +813,13 @@ add_pre_form(struct pre_form *prev, char *url, char *name, char *action) new = prev->next = New(struct pre_form); else new = PreForm = New(struct pre_form); @@ -15904,7 +16260,7 @@ index b7556ca..1aaaf19 100644 new->name = (name && *name) ? name : NULL; new->action = (action && *action) ? action : NULL; new->item = NULL; -@@ -834,7 +841,7 @@ add_pre_form_item(struct pre_form *pf, struct pre_form_item *prev, int type, +@@ -834,7 +843,7 @@ add_pre_form_item(struct pre_form *pf, struct pre_form_item *prev, int type, new->name = name; new->value = value; if (checked && *checked && (!strcmp(checked, "0") || @@ -15913,7 +16269,7 @@ index b7556ca..1aaaf19 100644 || !strcasecmp(checked, "no"))) new->checked = 0; else -@@ -875,6 +882,7 @@ loadPreForm(void) +@@ -875,6 +884,7 @@ loadPreForm(void) return; while (1) { char *p, *s, *arg; @@ -15921,7 +16277,7 @@ index b7556ca..1aaaf19 100644 line = Strfgets(fp); if (line->length == 0) -@@ -890,18 +898,20 @@ loadPreForm(void) +@@ -890,18 +900,20 @@ loadPreForm(void) if (*p == '#' || *p == '\0') continue; /* comment or empty line */ s = getWord(&p); @@ -15944,7 +16300,7 @@ index b7556ca..1aaaf19 100644 if (!strcmp(s, "form")) { if (!arg || !*arg) continue; -@@ -913,7 +923,7 @@ loadPreForm(void) +@@ -913,7 +925,7 @@ loadPreForm(void) } if (pf->item) { struct pre_form *prev = pf; @@ -16236,10 +16592,10 @@ index bca227e..d9f08e9 100644 {NULL, NULL, 0, 0}, /* 142 Undefined */ {NULL, NULL, 0, 0}, /* 143 Undefined */ diff --git a/html.h b/html.h -index 7abbd3b..c490655 100644 +index 7abbd3b..2a9a431 100644 --- a/html.h +++ b/html.h -@@ -1,20 +1,18 @@ +@@ -1,20 +1,20 @@ /* $Id: html.h,v 1.31 2010/08/14 01:29:40 htrb Exp $ */ #ifndef _HTML_H #define _HTML_H @@ -16251,7 +16607,8 @@ index 7abbd3b..c490655 100644 #endif /* USE_SSL */ -#include "istream.h" -- ++#include <time.h> + #define StrUFgets(f) StrISgets((f)->stream) #define StrmyUFgets(f) StrmyISgets((f)->stream) #define UFgetc(f) ISgetc((f)->stream) @@ -16262,7 +16619,7 @@ index 7abbd3b..c490655 100644 #define UFfileno(f) ISfileno((f)->stream) struct cmdtable { -@@ -62,11 +60,12 @@ typedef struct _ParsedURL { +@@ -62,11 +62,12 @@ typedef struct _ParsedURL { int is_nocache; } ParsedURL; @@ -16276,7 +16633,7 @@ index 7abbd3b..c490655 100644 char *ext; int compression; int content_encoding; -@@ -214,21 +213,22 @@ typedef struct { +@@ -214,21 +215,22 @@ typedef struct { #define HTML_BIG 122 #define HTML_N_BIG 123 #define HTML_BUTTON 124 @@ -18131,6 +18488,154 @@ index dfac6d9..bed5dff 100644 static wc_wchar_t ucs_cs94_conv(wc_ccs ccs, wc_uint16 c) { +diff --git a/libwc/wtf.c b/libwc/wtf.c +index b8cfdc7..94d95c1 100644 +--- a/libwc/wtf.c ++++ b/libwc/wtf.c +@@ -120,29 +120,36 @@ int + wtf_strwidth(wc_uchar *p) + { + int w = 0; ++ wc_uchar *q = p + strlen(p); + +- while (*p) { ++ while (p < q) { + w += wtf_width(p); + p += WTF_LEN_MAP[*p]; + } + return w; + } + +-/* + size_t + wtf_len1(wc_uchar *p) + { +- return (size_t)WTF_LEN_MAP[*p]; ++ size_t len, len_max = WTF_LEN_MAP[*p]; ++ ++ for (len = 0; *(p + len); len++) ++ if (len == len_max) ++ break; ++ if (len == 0) ++ len = 1; ++ return len; + } +-*/ + + size_t + wtf_len(wc_uchar *p) + { + wc_uchar *q = p; ++ wc_uchar *strz = p + strlen(p); + + q += WTF_LEN_MAP[*q]; +- while (*q && ! WTF_WIDTH_MAP[*q]) ++ while (q < strz && ! WTF_WIDTH_MAP[*q]) + q += WTF_LEN_MAP[*q]; + return q - p; + } +@@ -166,15 +173,17 @@ wtf_type(wc_uchar *p) + ((p)[3] = (((c) >> 7) & 0x7f) | 0x80), \ + ((p)[4] = ( (c) & 0x7f) | 0x80) + #define wtf_to_wcs16(p) \ ++ ((p)[0] == 0 || (p)[1] == 0 || (p)[2] == 0 ? 0 : \ + ((wc_uint32)((p)[0] & 0x03) << 14) \ + | ((wc_uint32)((p)[1] & 0x7f) << 7) \ +- | ((wc_uint32)((p)[2] & 0x7f) ) ++ | ((wc_uint32)((p)[2] & 0x7f) )) + #define wtf_to_wcs32(p) \ ++ ((p)[0] == 0 || (p)[1] == 0 || (p)[2] == 0 || (p)[3] == 0 || (p)[4] == 0 ? 0 : \ + ((wc_uint32)((p)[0] & 0x0f) << 28) \ + | ((wc_uint32)((p)[1] & 0x7f) << 21) \ + | ((wc_uint32)((p)[2] & 0x7f) << 14) \ + | ((wc_uint32)((p)[3] & 0x7f) << 7) \ +- | ((wc_uint32)((p)[4] & 0x7f) ) ++ | ((wc_uint32)((p)[4] & 0x7f) )) + + void + wtf_push(Str os, wc_ccs ccs, wc_uint32 code) +@@ -388,7 +397,7 @@ wtf_parse1(wc_uchar **p) + cc.code = *(q++); + } else if (*q > 0xa0) { + cc.ccs = wtf_gr_ccs; +- if (WC_CCS_IS_WIDE(cc.ccs)) { ++ if (WC_CCS_IS_WIDE(cc.ccs) && *(q+1)) { + cc.code = ((wc_uint32)*q << 8) | *(q+1); + q += 2; + } else +@@ -401,27 +410,47 @@ wtf_parse1(wc_uchar **p) + case WC_CCS_A_CS942: + case WC_CCS_A_PCS: + case WC_CCS_A_UNKNOWN: +- cc.ccs |= *(q++) & 0x7f; +- cc.code = *(q++); ++ if (*q && *(q+1)) { ++ cc.ccs |= *(q++) & 0x7f; ++ cc.code = *(q++); ++ } else { ++ cc.ccs = WC_CCS_US_ASCII; ++ cc.code = (wc_uint32)' '; ++ } + break; + case WC_CCS_A_CS94W: + case WC_CCS_A_CS96W: + case WC_CCS_A_PCSW: +- cc.ccs |= *(q++) & 0x7f; +- cc.code = ((wc_uint32)*q << 8) | *(q+1); +- q += 2; ++ if (*q && *(q+1) && *(q+2)) { ++ cc.ccs |= *(q++) & 0x7f; ++ cc.code = ((wc_uint32)*q << 8) | *(q+1); ++ q += 2; ++ } else { ++ cc.ccs = WC_CCS_US_ASCII; ++ cc.code = (wc_uint32)' '; ++ } + break; + case WC_CCS_A_WCS16: + case WC_CCS_A_WCS16W: +- cc.ccs |= (*q & 0x7c) >> 2; +- cc.code = wtf_to_wcs16(q); +- q += 3; ++ if (*q && *(q+1) && *(q+2)) { ++ cc.ccs |= (*q & 0x7c) >> 2; ++ cc.code = wtf_to_wcs16(q); ++ q += 3; ++ } else { ++ cc.ccs = WC_CCS_US_ASCII; ++ cc.code = (wc_uint32)' '; ++ } + break; + case WC_CCS_A_WCS32: + case WC_CCS_A_WCS32W: +- cc.ccs |= (*q & 0x70) >> 4; +- cc.code = wtf_to_wcs32(q); +- q += 5; ++ if (*q && *(q+1) && *(q+2) && *(q+3) && *(q+4)) { ++ cc.ccs |= (*q & 0x70) >> 4; ++ cc.code = wtf_to_wcs32(q); ++ q += 5; ++ } else { ++ cc.ccs = WC_CCS_US_ASCII; ++ cc.code = (wc_uint32)' '; ++ } + break; + default: + /* case 0: */ +diff --git a/libwc/wtf.h b/libwc/wtf.h +index ad47973..435526f 100644 +--- a/libwc/wtf.h ++++ b/libwc/wtf.h +@@ -59,8 +59,7 @@ extern void wtf_init(wc_ces ces1, wc_ces ces2); + #define wtf_width(p) (WcOption.use_wide ? (int)WTF_WIDTH_MAP[(wc_uchar)*(p)] \ + : ((int)WTF_WIDTH_MAP[(wc_uchar)*(p)] ? 1 : 0)) + extern int wtf_strwidth(wc_uchar *p); +-/* extern size_t wtf_len1(wc_uchar *p); */ +-#define wtf_len1(p) ((int)WTF_LEN_MAP[(wc_uchar)*(p)]) ++extern size_t wtf_len1(wc_uchar *p); + extern size_t wtf_len(wc_uchar *p); + /* extern int wtf_type(wc_uchar *p); */ + #define wtf_type(p) WTF_TYPE_MAP[(wc_uchar)*(p)] diff --git a/linein.c b/linein.c index b7e81b6..d8f9023 100644 --- a/linein.c @@ -20008,7 +20513,7 @@ index 64fd0ad..bc7a5be 100644 #define SWAPI(a,b) { int tmp = a; a = b; b = tmp; } diff --git a/menu.c b/menu.c -index 774b1bd..01acc31 100644 +index 774b1bd..b0c890d 100644 --- a/menu.c +++ b/menu.c @@ -57,6 +57,7 @@ static int mCancel(char c); @@ -20172,6 +20677,15 @@ index 774b1bd..01acc31 100644 Strcat_charp(str, p); break; } +@@ -1696,7 +1741,7 @@ initMenu(void) + FILE *mf; + MenuList *list; + +- w3mMenuList = New_N(MenuList, 3); ++ w3mMenuList = New_N(MenuList, 4); + w3mMenuList[0].id = "Main"; + w3mMenuList[0].menu = &MainMenu; + w3mMenuList[0].item = MainMenuItem; @@ -1845,10 +1890,8 @@ link_menu(Buffer *buf) Strcat_charp(str, " "); if (!l->url) @@ -26690,7 +27204,7 @@ index 50475ae..c047c56 100644 buf[i] = (*p == ' ') ? NBSP_CODE : *p; diff --git a/table.c b/table.c -index e1243ff..572ebd6 100644 +index e1243ff..221db92 100644 --- a/table.c +++ b/table.c @@ -188,7 +188,7 @@ dv2sv(double *dv, short *iv, int size) @@ -26728,6 +27242,24 @@ index e1243ff..572ebd6 100644 int alignment; TextLineListItem *ti; struct table *t = tbl->tables[id].ptr; +@@ -961,7 +960,7 @@ set_integered_width(struct table *t, double *dwidth, short *iwidth) + for (step = 0; step < 2; step++) { + for (i = 0; i <= t->maxcol; i += n) { + int nn; +- char *idx; ++ short *idx; + double nsum; + if (sum < 0.5) + return; +@@ -982,7 +981,7 @@ set_integered_width(struct table *t, double *dwidth, short *iwidth) + (double)rulewidth - mod[ii] > 0.5) + fixed[ii] = 1; + } +- idx = NewAtom_N(char, n); ++ idx = NewAtom_N(short, n); + for (k = 0; k < cell->maxcell; k++) { + int kk, w, width, m; + j = cell->index[k]; @@ -1624,6 +1623,15 @@ get_table_width(struct table *t, short *orgwidth, short *cellwidth, int flag) #define fixed_table_width(t)\ (get_table_width(t,t->fixed_width,t->cell.fixed_width,CHECK_MINIMUM)) @@ -26788,7 +27320,28 @@ index e1243ff..572ebd6 100644 setwidth(tbl, mode); feed_table_inline_tag(tbl, line, mode, -1); clearcontentssize(tbl, mode); -@@ -2600,12 +2620,16 @@ feed_table_tag(struct table *tbl, char *line, struct table_mode *mode, +@@ -2546,8 +2566,10 @@ feed_table_tag(struct table *tbl, char *line, struct table_mode *mode, + } + } + #ifdef ID_EXT +- if (parsedtag_get_value(tag, ATTR_ID, &p)) ++ if (parsedtag_get_value(tag, ATTR_ID, &p)) { ++ check_row(tbl, tbl->row); + tbl->tridvalue[tbl->row] = Strnew_charp(p); ++ } + #endif /* ID_EXT */ + tbl->trattr = align | valign; + break; +@@ -2572,7 +2594,7 @@ feed_table_tag(struct table *tbl, char *line, struct table_mode *mode, + } + tbl->col++; + check_row(tbl, tbl->row); +- while (tbl->tabattr[tbl->row][tbl->col]) { ++ while (tbl->col < MAXCOL && tbl->tabattr[tbl->row][tbl->col]) { + tbl->col++; + } + if (tbl->col > MAXCOL - 1) { +@@ -2600,12 +2622,16 @@ feed_table_tag(struct table *tbl, char *line, struct table_mode *mode, if ((tbl->row + rowspan) >= tbl->max_rowsize) check_row(tbl, tbl->row + rowspan); } @@ -26805,7 +27358,7 @@ index e1243ff..572ebd6 100644 if (parsedtag_get_value(tag, ATTR_ALIGN, &i)) { switch (i) { case ALIGN_LEFT: -@@ -2878,6 +2902,14 @@ feed_table_tag(struct table *tbl, char *line, struct table_mode *mode, +@@ -2878,6 +2904,14 @@ feed_table_tag(struct table *tbl, char *line, struct table_mode *mode, tmp = process_input(tag); feed_table1(tbl, tmp, mode, width); break; @@ -26820,7 +27373,7 @@ index e1243ff..572ebd6 100644 case HTML_SELECT: tmp = process_select(tag); if (tmp) -@@ -3010,7 +3042,6 @@ feed_table_tag(struct table *tbl, char *line, struct table_mode *mode, +@@ -3010,7 +3044,6 @@ feed_table_tag(struct table *tbl, char *line, struct table_mode *mode, break; case HTML_TABLE_ALT: id = -1; |