changeset 21686:f07d6f579214

scanf: use appropriate sized types for integer conversions (bug #47741) * oct-stream.cc (octave_base_stream::do_scanf): Use sized types for integer conversions to work in 32-bit environments and be Matlab compatible. * io.tst: Add %!tests.
author Mike Miller <mtmiller@octave.org>
date Wed, 11 May 2016 12:02:22 -0700
parents fc8cc7730514
children 4418e579cca6
files libinterp/corefcn/oct-stream.cc test/io.tst
diffstat 2 files changed, 20 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/corefcn/oct-stream.cc	Wed May 11 10:50:32 2016 -0700
+++ b/libinterp/corefcn/oct-stream.cc	Wed May 11 12:02:22 2016 -0700
@@ -4729,7 +4729,7 @@
                       {
                       case 'h':
                         {
-                          short int tmp;
+                          int16_t tmp;
                           do_scanf_conv (is, *elt, &tmp, mval, data,
                                          data_index, conversion_count,
                                          nr, max_size, discard);
@@ -4738,7 +4738,7 @@
 
                       case 'l':
                         {
-                          long int tmp;
+                          int64_t tmp;
                           do_scanf_conv (is, *elt, &tmp, mval, data,
                                          data_index, conversion_count,
                                          nr, max_size, discard);
@@ -4747,7 +4747,7 @@
 
                       default:
                         {
-                          int tmp;
+                          int32_t tmp;
                           do_scanf_conv (is, *elt, &tmp, mval, data,
                                          data_index, conversion_count,
                                          nr, max_size, discard);
@@ -4763,7 +4763,7 @@
                       {
                       case 'h':
                         {
-                          unsigned short int tmp;
+                          uint16_t tmp;
                           do_scanf_conv (is, *elt, &tmp, mval, data,
                                          data_index, conversion_count,
                                          nr, max_size, discard);
@@ -4772,7 +4772,7 @@
 
                       case 'l':
                         {
-                          unsigned long int tmp;
+                          uint64_t tmp;
                           do_scanf_conv (is, *elt, &tmp, mval, data,
                                          data_index, conversion_count,
                                          nr, max_size, discard);
@@ -4781,7 +4781,7 @@
 
                       default:
                         {
-                          unsigned int tmp;
+                          uint32_t tmp;
                           do_scanf_conv (is, *elt, &tmp, mval, data,
                                          data_index, conversion_count,
                                          nr, max_size, discard);
--- a/test/io.tst	Wed May 11 10:50:32 2016 -0700
+++ b/test/io.tst	Wed May 11 12:02:22 2016 -0700
@@ -284,6 +284,20 @@
 %!assert (sscanf ('0177 08', '%i'), [127; 0; 8])
 %!assert (sscanf ('0177 08', '%d'), [177; 8])
 
+## bug #47741
+%!assert (sscanf ('2147483647', '%d'), 2147483647)
+%!assert (sscanf ('2147483647', '%i'), 2147483647)
+%!assert (sscanf ('4294967295', '%u'), 4294967295)
+%!assert (sscanf ('37777777777', '%o'), 4294967295)
+%!assert (sscanf ('ffffffff', '%x'), 4294967295)
+## FIXME: scanf should return int64/uint64 if all conversions are %l[dioux].
+## Until then only test values that are within precision range of a double.
+%!assert (sscanf ('281474976710655', '%ld'), 281474976710655)
+%!assert (sscanf ('281474976710655', '%li'), 281474976710655)
+%!assert (sscanf ('281474976710655', '%lu'), 281474976710655)
+%!assert (sscanf ('7777777777777777', '%lo'), 281474976710655)
+%!assert (sscanf ('ffffffffffff', '%lx'), 281474976710655)
+
 %!test
 %! [val, count, msg, pos] = sscanf ("3I2", "%f");
 %! assert (val, 3);