← Back to team overview

zorba-coders team mailing list archive

[Merge] lp:~paul-lucas/zorba/bug-1085408 into lp:zorba

 

Paul J. Lucas has proposed merging lp:~paul-lucas/zorba/bug-1085408 into lp:zorba.

Commit message:
Fixed signed integer overflow bug.

Requested reviews:
  Paul J. Lucas (paul-lucas)
Related bugs:
  Bug #1085408 in Zorba: "xs:date(): casting large year values"
  https://bugs.launchpad.net/zorba/+bug/1085408

For more details, see:
https://code.launchpad.net/~paul-lucas/zorba/bug-1085408/+merge/159063

Fixed signed integer overflow bug.
-- 
https://code.launchpad.net/~paul-lucas/zorba/bug-1085408/+merge/159063
Your team Zorba Coders is subscribed to branch lp:zorba.
=== modified file 'ChangeLog'
--- ChangeLog	2013-04-11 18:13:48 +0000
+++ ChangeLog	2013-04-16 02:23:28 +0000
@@ -43,6 +43,7 @@
   * Fixed bug #1147518 (fn:round-half-to-even (at least 11 failures))
   * Fixed bug #1114228 (unrecognized options in the XQuery namespace now raise an error)
   * Fixed bug #1124273 (xqdoc crash because of annotation literals)
+  * Fixed bug #1085408 (xs:date(): casting large year values)
   * Fixed bug #867027 (XQST0059 error messages inconsistent)
   * Fixed bug #1095889 (Improve error message for xml-parsing error).
   * Fixed bug #1123163 (fn:format-integer failures)

=== modified file 'src/zorbatypes/datetime/parse.cpp'
--- src/zorbatypes/datetime/parse.cpp	2013-04-05 09:48:19 +0000
+++ src/zorbatypes/datetime/parse.cpp	2013-04-16 02:23:28 +0000
@@ -53,29 +53,37 @@
     long max_digits,
     size_t delta)
 {
-  int tmp_result = 0; // We have to downgrade the precision here from long to int so that some FOTS tests will throw a FOTD0001 date/time overflow. 
-                      // When alternative correct results will be available, this precision downgrading can be removed.
-  long digits = 0;
-
-  if (position + delta >= len)
-    return 1;
-
-  if (str[position+delta] < '0' || str[position+delta] > '9')
-    return 1;
-
-  while ( position + delta < len && ascii::is_digit( str[position+delta] ) )
-  {
-    tmp_result = 10 * tmp_result + str[position + delta] - '0';
-    position++;
-    digits++;
-
-    if (tmp_result < 0) // we've had an overflow
-      return 2;
+  if ( position + delta >= len )
+    return 1;
+
+  //
+  // We have to downgrade the precision here from sizeof(long) to sizeof(int)
+  // so that some FOTS tests will throw a FOTD0001 date/time overflow.  When
+  // alternative correct results are available, this precision downgrading can
+  // be removed.
+  //
+  int tmp_result = 0;
+
+  int digits = 0;
+
+  if ( !ascii::is_digit( str[position+delta] ) )
+    return 1;
+
+  while ( position + delta < len && ascii::is_digit( str[position+delta] ) ) {
+    unsigned const tmp_prev = tmp_result;
+    tmp_result *= 10;
+    // See <http://stackoverflow.com/q/199333/99089>
+    if ( tmp_result / 10 != tmp_prev )
+      return 2;                         // overflow
+    tmp_result += str[position + delta] - '0';
+    if ( tmp_result < tmp_prev )
+      return 2;                         // overflow
+    ++digits;
+    ++position;
   }
 
   if (min_digits >= 0 && digits < min_digits)
     return 1;
-
   if (max_digits >= 0 && digits > max_digits)
     return 1;
 


Follow ups