[Groonga-commit] groonga/groonga at 81a9161 [master] Fix invalid strtod() usage

Back to archive index
Kouhei Sutou null+****@clear*****
Wed Oct 17 15:41:40 JST 2018


Kouhei Sutou	2018-10-17 15:41:40 +0900 (Wed, 17 Oct 2018)

  Revision: 81a9161d3efa77a738ddaa9124816df68d822f7a
  https://github.com/groonga/groonga/commit/81a9161d3efa77a738ddaa9124816df68d822f7a

  Message:
    Fix invalid strtod() usage
    
    strtod() requires nul-terminated.
    
    If we don't ensure nul-terminated, wrong conversion error may be
    reported and invalid address may be accessed.

  Modified files:
    lib/expr.c
    lib/str.c

  Modified: lib/expr.c (+9 -2)
===================================================================
--- lib/expr.c    2018-10-17 01:36:07 +0900 (a65c12d14)
+++ lib/expr.c    2018-10-17 15:41:40 +0900 (0a6846b5a)
@@ -6448,13 +6448,20 @@ parse_script(grn_ctx *ctx, efs_info *q)
         if (q->str_end != rest &&
             (*rest == '.' || *rest == 'e' || *rest == 'E' ||
              (*rest >= '0' && *rest <= '9'))) {
+          grn_obj buffer;
           char *rest_float;
-          double d = strtod(q->cur, &rest_float);
+          double d;
           grn_obj floatbuf;
+          GRN_TEXT_INIT(&buffer, 0);
+          GRN_TEXT_SET(ctx, &buffer, q->cur, q->str_end - q->cur);
+          GRN_TEXT_PUTC(ctx, &buffer, '\0');
+          errno = 0;
+          d = strtod(GRN_TEXT_VALUE(&buffer), &rest_float);
+          rest = q->cur + (rest_float - GRN_TEXT_VALUE(&buffer));
+          GRN_OBJ_FIN(ctx, &buffer);
           GRN_FLOAT_INIT(&floatbuf, 0);
           GRN_FLOAT_SET(ctx, &floatbuf, d);
           grn_expr_append_const(ctx, q->e, &floatbuf, GRN_OP_PUSH, 1);
-          rest = rest_float;
         } else {
           const char *rest64 = rest;
           grn_atoui(q->cur, q->str_end, &rest);

  Modified: lib/str.c (+14 -6)
===================================================================
--- lib/str.c    2018-10-17 01:36:07 +0900 (b40489df6)
+++ lib/str.c    2018-10-17 15:41:40 +0900 (a0081ba79)
@@ -1743,6 +1743,8 @@ grn_rc
 grn_aton(grn_ctx *ctx, const char *p, const char *end, const char **rest,
          grn_obj *res)
 {
+  grn_rc rc = GRN_SUCCESS;
+
   if (*p == '+') {
     p++;
   }
@@ -1778,27 +1780,33 @@ grn_aton(grn_ctx *ctx, const char *p, const char *end, const char **rest,
         if (end != *rest) {
           if (rest_char == '.' || rest_char == 'e' || rest_char == 'E' ||
               (rest_char >= '0' && rest_char <= '9')) {
+            grn_obj buffer;
             char *rest_float;
             double d;
             errno = 0;
-            d = strtod(p, &rest_float);
-            if (!errno && rest_float == end) {
+            GRN_TEXT_INIT(&buffer, 0);
+            GRN_TEXT_SET(ctx, &buffer, p, end - p);
+            GRN_TEXT_PUTC(ctx, &buffer, '\0');
+            d = strtod(GRN_TEXT_VALUE(&buffer), &rest_float);
+            if (errno == 0 && rest_float + 1 == GRN_BULK_CURR(&buffer)) {
               grn_obj_reinit(ctx, res, GRN_DB_FLOAT, 0);
               GRN_FLOAT_SET(ctx, res, d);
-              *rest = rest_float;
+              *rest = end;
             } else {
-              return GRN_INVALID_ARGUMENT;
+              rc = GRN_INVALID_ARGUMENT;
             }
+            GRN_OBJ_FIN(ctx, &buffer);
           }
         }
       }
     }
     break;
   default :
-    return GRN_INVALID_ARGUMENT;
+    rc = GRN_INVALID_ARGUMENT;
+    break;
   }
 
-  return GRN_SUCCESS;
+  return rc;
 }
 
 int
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.osdn.me/mailman/archives/groonga-commit/attachments/20181017/2521107d/attachment-0001.html>


More information about the Groonga-commit mailing list
Back to archive index