[gnumeric] R1C1: Fix parsing problem.



commit c9f767a6e72758cc325ed672df77005df1bdafda
Author: Morten Welinder <terra gnome org>
Date:   Thu Aug 8 10:51:59 2013 -0400

    R1C1: Fix parsing problem.
    
    Sylk files are R1C1 based.  Crazy relative offset caused trouble.

 ChangeLog        |    5 +++++
 NEWS             |    1 +
 src/parse-util.c |   16 ++++++++++++----
 3 files changed, 18 insertions(+), 4 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 163f662..baa42f3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2013-08-08  Morten Welinder  <terra gnome org>
+
+       * src/parse-util.c (r1c1_get_index): Handle integer overflow.
+       Reduce crazy relative offsets.
+
 2013-08-07  Andreas J. Guelzow <aguelzow pyrshep ca>
 
        * src/sheet-object-widget.c (draw_cairo_text): add arguments and
diff --git a/NEWS b/NEWS
index e64dddb..f9efc21 100644
--- a/NEWS
+++ b/NEWS
@@ -31,6 +31,7 @@ Morten:
        * Fix crashes on corrupted files.  [#704102] [#704004] [#704325]
        [#704562]
        * Fix conditional format problem.  [#704445]
+       * Fix R1C1 parsing issue.  [#705637]
 
 --------------------------------------------------------------------------
 Gnumeric 1.12.4
diff --git a/src/parse-util.c b/src/parse-util.c
index 0237d0c..9c6da94 100644
--- a/src/parse-util.c
+++ b/src/parse-util.c
@@ -520,11 +520,15 @@ r1c1_get_index (char const *str, GnmSheetSize const *ss,
                int *num, unsigned char *relative, gboolean is_col)
 {
        char *end;
+       long l;
+       int max = is_col ? ss->max_cols : ss->max_rows;
+
        if (str[0] == '\0')
                return NULL;
 
        str++;
-       if ((*relative = (*str == '[')))
+       *relative = (*str == '[');
+       if (*relative)
                str++;
        else if (*str == '-' || *str == '+') { /* handle RC-10 as RC followed by -10 */
                *relative = TRUE;
@@ -533,9 +537,11 @@ r1c1_get_index (char const *str, GnmSheetSize const *ss,
        }
 
        errno = 0;
-       *num = strtol (str, &end, 10);
-       if (errno == ERANGE)
+       *num = l = strtol (str, &end, 10);
+       if (errno == ERANGE || l <= G_MININT || l > G_MAXINT) {
+               /* Note: this includes G_MININT to avoid negation overflow.  */
                return NULL;
+       }
        if (str == end) {
                if (*relative)
                        return NULL;
@@ -544,9 +550,11 @@ r1c1_get_index (char const *str, GnmSheetSize const *ss,
        } else if (*relative) {
                if (*end != ']')
                        return NULL;
+               *num = (*num > 0
+                       ? *num % max
+                       : -(-*num % max));
                return end + 1;
        } else {
-               int max = is_col ? ss->max_cols : ss->max_rows;
                if (*num <= 0 || *num > max)
                        return NULL;
                (*num)--;


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