Fix uninitialized error in my_atof3()
authorKarl Williamson <khw@cpan.org>
Sun, 15 Jul 2018 18:27:20 +0000 (12:27 -0600)
committerKarl Williamson <khw@cpan.org>
Sun, 15 Jul 2018 18:32:18 +0000 (12:32 -0600)
This function, newly introduced in 5.29, by
6928bedc792ff80f0cb915460a7eacae25fa9bdd, is buggy due to my misreading
the man page for strtoflt128().  There was no man page on my system, and
the one on-line is very terse, and could be interpreted as doing what I
wanted, which is to have the second parameter on input point to the end
position in the input string beyond which the function is not to look.
But in fact the function is expecting a NUL-terminated string.

This commit creates such a string by copying the original when it isn't
NUL-terminated, before calling strtoflt128().

numeric.c

index 34eb8b3..46d8cd8 100644 (file)
--- a/numeric.c
+++ b/numeric.c
@@ -1439,10 +1439,30 @@ Perl_my_atof3(pTHX_ const char* orig, NV* value, STRLEN len)
 #ifdef USE_QUADMATH
     {
         char* endp;
+        char* copy = NULL;
+
         if ((endp = S_my_atof_infnan(aTHX_ s, negative, send, value)))
             return endp;
-        endp = send;
+
+        /* If the length is passed in, the input string isn't NUL-terminated,
+         * and in it turns out the function below assumes it is; therefore we
+         * create a copy and NUL-terminate that */
+        if (len) {
+            Newx(copy, len + 1, char);
+            Copy(orig, copy, len, char);
+            copy[len] = '\0';
+            s = copy + (s - orig);
+        }
+
         result[2] = strtoflt128(s, &endp);
+
+        /* If we created a copy, 'endp' is in terms of that.  Convert back to
+         * the original */
+        if (copy) {
+            endp = (endp - copy) + (char *) orig;
+            Safefree(copy);
+        }
+
         if (s != endp) {
             *value = negative ? -result[2] : result[2];
             return endp;