[libgsf] textline: avoid ABR.



commit 26e358563209fba333c257a883b20b572b23bb4e
Author: Morten Welinder <terra gnome org>
Date:   Thu Jun 25 09:03:57 2015 -0400

    textline: avoid ABR.

 ChangeLog                |    6 +++
 NEWS                     |    1 +
 gsf/gsf-input-textline.c |   96 +++++----------------------------------------
 3 files changed, 18 insertions(+), 85 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 4eb88b1..f92d9e9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2015-06-25  Morten Welinder  <terra gnome org>
+
+       * gsf/gsf-input-textline.c (gsf_input_textline_utf8_gets): Go
+       character-by-character.  This is the right thing to do and also
+       prevents stepping past the end.
+
 2015-06-17  Morten Welinder  <terra gnome org>
 
        * gsf/gsf-open-pkg-utils.c (gsf_open_pkg_open_rel): Improve
diff --git a/NEWS b/NEWS
index e4c5779..be88b90 100644
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,7 @@ Morten:
        * Fix OLE2 property parsing problem.  [#748528]
        * Fuzzed file fixes.  [#749120] [#749169] [#749183] [#750809]
        * xlsx: fix problem with absolute relation targets.  [#751120]
+       * Fix text line problem with very long lines.
 
 --------------------------------------------------------------------------
 libgsf 1.14.33
diff --git a/gsf/gsf-input-textline.c b/gsf/gsf-input-textline.c
index 15b4cb6..f9183ba 100644
--- a/gsf/gsf-input-textline.c
+++ b/gsf/gsf-input-textline.c
@@ -152,83 +152,12 @@ GSF_CLASS (GsfInputTextline, gsf_input_textline,
  * Trailing newlines and carriage returns are stripped, and the resultant buffer
  * can be edited.
  *
- * Returns: the string read, or %NULL on eof.
+ * Returns: (transfer none): the string read, or %NULL on eof.
  **/
 unsigned char *
 gsf_input_textline_ascii_gets (GsfInputTextline *textline)
 {
-       guint8 const *ptr ,*end;
-       gsf_off_t remain;
-       unsigned len, count = 0;
-
-       g_return_val_if_fail (textline != NULL, NULL);
-
-       while (1) {
-               if (textline->remainder == NULL ||
-                   textline->remainder_size == 0) {
-                       remain = gsf_input_remaining (textline->source);
-                       len = MIN (remain, textline->max_line_size);
-
-                       textline->remainder = gsf_input_read (textline->source, len, NULL);
-                       if (textline->remainder == NULL)
-                               return NULL;
-                       textline->remainder_size = len;
-               }
-
-               ptr = textline->remainder;
-               end = ptr + textline->remainder_size;
-               for (; ptr < end ; ptr++)
-                       if (*ptr == '\n' || *ptr == '\r')
-                               break;
-
-               /* copy the remains into the buffer, grow it if necessary */
-               len = ptr - textline->remainder;
-               if (count + len >= textline->buf_size) {
-                       textline->buf_size += len;
-                       textline->buf = g_renew (guint8, textline->buf,
-                                                textline->buf_size + 1);
-               }
-
-               g_return_val_if_fail (textline->buf != NULL, NULL);
-
-               memcpy (textline->buf + count, textline->remainder, len);
-               count += len;
-
-               if (ptr < end) {
-                       unsigned char last = ptr [0];
-
-                       /* eat the trailing new line */
-                       ptr++;
-                       if (ptr >= end) {
-                               /* be extra careful, the newline is at the bound */
-                               if (gsf_input_remaining (textline->source) > 0) {
-                                       ptr = gsf_input_read (textline->source, 1, NULL);
-                                       if (ptr == NULL)
-                                               return NULL;
-                                       textline->remainder = ptr;
-                                       textline->remainder_size = 1;
-                                       end = ptr + 1;
-                               } else
-                                       ptr = end = NULL;
-                       }
-                       if (ptr != NULL &&
-                           ((last == '\n' && *ptr == '\r') ||
-                            (last == '\r' && *ptr == '\n')))
-                               ptr++;
-                       break;
-               } else if (gsf_input_remaining (textline->source) <= 0) {
-                       ptr = end = NULL;
-                       break;
-               } else
-                       textline->remainder = NULL;
-
-       }
-
-       textline->remainder = ptr;
-       textline->remainder_size = end - ptr;
-
-       textline->buf [count] = '\0';
-       return textline->buf;
+       return gsf_input_textline_utf8_gets (textline);
 }
 
 /**
@@ -239,13 +168,12 @@ gsf_input_textline_ascii_gets (GsfInputTextline *textline)
  * Trailing newlines and carriage returns are stripped, and the resultant buffer
  * can be edited.
  *
- * Returns: the string read, or %NULL on eof.
+ * Returns: (transfer none): the string read, or %NULL on eof.
  **/
 guint8 *
 gsf_input_textline_utf8_gets (GsfInputTextline *textline)
 {
        guint8 const *ptr ,*end;
-       gsf_off_t remain;
        unsigned len, count = 0;
 
        g_return_val_if_fail (textline != NULL, NULL);
@@ -253,7 +181,7 @@ gsf_input_textline_utf8_gets (GsfInputTextline *textline)
        while (1) {
                if (textline->remainder == NULL ||
                    textline->remainder_size == 0) {
-                       remain = gsf_input_remaining (textline->source);
+                       gsf_off_t remain = gsf_input_remaining (textline->source);
                        len = MIN (remain, textline->max_line_size);
 
                        textline->remainder = gsf_input_read (textline->source, len, NULL);
@@ -264,7 +192,7 @@ gsf_input_textline_utf8_gets (GsfInputTextline *textline)
 
                ptr = textline->remainder;
                end = ptr + textline->remainder_size;
-               for (; ptr < end ; ptr = (guint8 *) g_utf8_next_char (ptr))
+               for (; ptr < end ; ptr++)
                        if (*ptr == '\n' || *ptr == '\r')
                                break;
 
@@ -282,12 +210,12 @@ gsf_input_textline_utf8_gets (GsfInputTextline *textline)
                count += len;
 
                if (ptr < end) {
-                       unsigned char last = ptr [0];
+                       unsigned char last = ptr[0];
 
-                       /* eat the trailing new line */
+                       /* eat the trailing eol marker: \n, \r\n, or \r.  */
                        ptr++;
-                       if (ptr >= end) {
-                               /* be extra careful, the newline is at the bound */
+                       if (ptr >= end && last == '\r') {
+                               /* be extra careful, the CR is at the bound */
                                if (gsf_input_remaining (textline->source) > 0) {
                                        ptr = gsf_input_read (textline->source, 1, NULL);
                                        if (ptr == NULL)
@@ -298,9 +226,7 @@ gsf_input_textline_utf8_gets (GsfInputTextline *textline)
                                } else
                                        ptr = end = NULL;
                        }
-                       if (ptr != NULL &&
-                           ((last == '\n' && *ptr == '\r') ||
-                            (last == '\r' && *ptr == '\n')))
+                       if (ptr != NULL && last == '\r' && *ptr == '\n')
                                ptr++;
                        break;
                } else if (gsf_input_remaining (textline->source) <= 0) {
@@ -314,6 +240,6 @@ gsf_input_textline_utf8_gets (GsfInputTextline *textline)
        textline->remainder = ptr;
        textline->remainder_size = end - ptr;
 
-       textline->buf [count] = '\0';
+       textline->buf[count] = '\0';
        return textline->buf;
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]