From 6b68d38131120c6cb9a2dc5bfd1f1a772ed78836 Mon Sep 17 00:00:00 2001 From: Kalle Olavi Niemitalo Date: Tue, 26 Dec 2006 14:27:50 +0200 Subject: [PATCH 1/5] set_hline: Define local variables as const where possible. I hope this makes the source easier to understand. --- src/document/html/renderer.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/document/html/renderer.c b/src/document/html/renderer.c index e4c8199d9..f870f6f10 100644 --- a/src/document/html/renderer.c +++ b/src/document/html/renderer.c @@ -386,14 +386,14 @@ static inline int set_hline(struct html_context *html_context, unsigned char *chars, int charslen, enum link_state link_state) { - struct part *part = html_context->part; - struct screen_char *schar = get_format_screen_char(html_context, - link_state); + struct part *const part = html_context->part; + struct screen_char *const schar = get_format_screen_char(html_context, + link_state); int x = part->cx; - int y = part->cy; - int x2 = x; + const int y = part->cy; + const int x2 = x; int len = charslen; - int utf8 = html_context->options->utf8; + const int utf8 = html_context->options->utf8; assert(part); if_assert_failed return len; From 819653836af885d256dbda795a29df8651297eee Mon Sep 17 00:00:00 2001 From: Kalle Olavi Niemitalo Date: Tue, 26 Dec 2006 14:37:08 +0200 Subject: [PATCH 2/5] Bug 912: Callers of realloc_line treat only values < 0 as errors. This will let me change realloc_line to return the original length. --- src/document/html/renderer.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/document/html/renderer.c b/src/document/html/renderer.c index f870f6f10..8dcae8dc4 100644 --- a/src/document/html/renderer.c +++ b/src/document/html/renderer.c @@ -244,7 +244,7 @@ clear_hchars(struct html_context *html_context, int x, int y, int width) assert(part && part->document && width > 0); if_assert_failed return; - if (realloc_line(html_context, part->document, Y(y), X(x) + width - 1)) + if (realloc_line(html_context, part->document, Y(y), X(x) + width - 1) < 0) return; assert(part->document->data); @@ -277,7 +277,7 @@ get_frame_char(struct html_context *html_context, struct part *part, assert(part && part->document && x >= 0 && y >= 0); if_assert_failed return NULL; - if (realloc_line(html_context, part->document, Y(y), X(x))) + if (realloc_line(html_context, part->document, Y(y), X(x)) < 0) return NULL; assert(part->document->data); @@ -325,7 +325,7 @@ draw_frame_vchars(struct part *part, int x, int y, int height, /* The template char is the first vertical char to be drawn. So * copy it to the rest. */ for (height -= 1, y += 1; height; height--, y++) { - if (realloc_line(html_context, part->document, Y(y), X(x))) + if (realloc_line(html_context, part->document, Y(y), X(x)) < 0) return; copy_screen_chars(&POS(x, y), template, 1); @@ -417,7 +417,7 @@ set_hline(struct html_context *html_context, unsigned char *chars, int charslen, * the first byte of input can result in a double-cell * character, so we must reserve one extra element. */ if (realloc_line(html_context, part->document, - Y(y), X(x) + charslen)) + Y(y), X(x) + charslen) < 0) return 0; if (utf8) { unsigned char *end = chars + charslen; @@ -564,7 +564,7 @@ set_hline(struct html_context *html_context, unsigned char *chars, int charslen, if (part->document) { if (realloc_line(html_context, part->document, - Y(y), X(x) + charslen - 1)) + Y(y), X(x) + charslen - 1) < 0) return; for (; charslen > 0; charslen--, x++, chars++) { @@ -713,7 +713,7 @@ copy_chars(struct html_context *html_context, int x, int y, int width, struct sc assert(width > 0 && part && part->document && part->document->data); if_assert_failed return; - if (realloc_line(html_context, part->document, Y(y), X(x) + width - 1)) + if (realloc_line(html_context, part->document, Y(y), X(x) + width - 1) < 0) return; copy_screen_chars(&POS(x, y), d, width); From 26cce9aab372477738360370d5ce399a9225b44c Mon Sep 17 00:00:00 2001 From: Kalle Olavi Niemitalo Date: Tue, 26 Dec 2006 14:38:58 +0200 Subject: [PATCH 3/5] Bug 912, realloc_line: Return the original line->length if successful. This will let the caller restore the length if it notices it has allocated too much space. --- src/document/html/renderer.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/document/html/renderer.c b/src/document/html/renderer.c index 8dcae8dc4..949d82b41 100644 --- a/src/document/html/renderer.c +++ b/src/document/html/renderer.c @@ -154,14 +154,16 @@ realloc_line(struct html_context *html_context, struct document *document, { struct screen_char *pos, *end; struct line *line; + int orig_length; if (!realloc_lines(document, y)) return -1; line = &document->data[y]; - - if (length < line->length) - return 0; + orig_length = line->length; + + if (length < orig_length) + return orig_length; if (!ALIGN_LINE(&line->chars, line->length, length + 1)) return -1; @@ -181,7 +183,7 @@ realloc_line(struct html_context *html_context, struct document *document, line->length = length + 1; - return 0; + return orig_length; } void From cd10da6f311100ee112e45bfffd5656ab99ae8e0 Mon Sep 17 00:00:00 2001 From: Kalle Olavi Niemitalo Date: Tue, 26 Dec 2006 14:51:42 +0200 Subject: [PATCH 4/5] Bug 912, set_hline: Don't let LINE(y).length remain larger than needed. --- src/document/html/renderer.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/document/html/renderer.c b/src/document/html/renderer.c index 949d82b41..a6cc26045 100644 --- a/src/document/html/renderer.c +++ b/src/document/html/renderer.c @@ -396,6 +396,7 @@ set_hline(struct html_context *html_context, unsigned char *chars, int charslen, const int x2 = x; int len = charslen; const int utf8 = html_context->options->utf8; + int orig_length; assert(part); if_assert_failed return len; @@ -418,8 +419,9 @@ set_hline(struct html_context *html_context, unsigned char *chars, int charslen, * incomplete character in part->document->buf, then * the first byte of input can result in a double-cell * character, so we must reserve one extra element. */ - if (realloc_line(html_context, part->document, - Y(y), X(x) + charslen) < 0) + orig_length = realloc_line(html_context, part->document, + Y(y), X(x) + charslen); + if (orig_length < 0) /* error */ return 0; if (utf8) { unsigned char *end = chars + charslen; @@ -442,6 +444,7 @@ set_hline(struct html_context *html_context, unsigned char *chars, int charslen, goto good_char; } else { /* Still not full char */ + LINE(y).length = orig_length; return 0; } } @@ -513,6 +516,13 @@ good_char: * before each @copy_screen_chars call above, but * those are in an inner loop that should be fast. */ assert(X(x) <= LINE(y).length); + /* Some part of the code is apparently using LINE(y).length + * for line-wrapping decisions. It may currently be too + * large because it was allocated above based on @charslen + * which is the number of bytes, not the number of cells. + * Change the length to the correct size, but dont let it + * get smaller than it was on entry to this function. */ + LINE(y).length = int_max(orig_length, X(x)); len = x - x2; } else { if (utf8) { From a287f547fdb9be6db5e252f1a84a22feee304275 Mon Sep 17 00:00:00 2001 From: Kalle Olavi Niemitalo Date: Tue, 26 Dec 2006 14:59:16 +0200 Subject: [PATCH 5/5] set_hline: Add a FIXME comment about invalid UTF-8. --- src/document/html/renderer.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/document/html/renderer.c b/src/document/html/renderer.c index a6cc26045..61ec3b92b 100644 --- a/src/document/html/renderer.c +++ b/src/document/html/renderer.c @@ -440,6 +440,16 @@ set_hline(struct html_context *html_context, unsigned char *chars, int charslen, part->document->buf[i] = '\0'; data = utf8_to_unicode(&buf_ptr, buf_ptr + i); if (data != UCS_NO_CHAR) { + /* FIXME: If there was invalid + * UTF-8 in the buffer, + * @utf8_to_unicode may have left + * some bytes unused. Those + * bytes should be pulled back + * into @chars, rather than + * discarded. This is not + * trivial to implement because + * each byte may have arrived in + * a separate call. */ part->document->buf_length = 0; goto good_char; } else {