[前][次][番号順一覧][スレッド一覧]

ruby-changes:53915

From: duerst <ko1@a...>
Date: Mon, 3 Dec 2018 06:41:55 +0900 (JST)
Subject: [ruby-changes:53915] duerst:r66135 (trunk): make sure all nodes are freed on error in node_extended_grapheme_cluster()

duerst	2018-12-03 06:41:50 +0900 (Mon, 03 Dec 2018)

  New Revision: 66135

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=66135

  Log:
    make sure all nodes are freed on error in node_extended_grapheme_cluster()
    
    regparse.c: In function node_extended_grapheme_cluster(), introduce function-global
    array node_array and use it for sequence and alternate construction. This is done
    so that in case of error, all nodes that have already been constructed can be
    correctly freed. (issue #15343)

  Modified files:
    trunk/regparse.c
Index: regparse.c
===================================================================
--- regparse.c	(revision 66134)
+++ regparse.c	(revision 66135)
@@ -5787,6 +5787,8 @@ create_sequence_node(Node **np, Node **n https://github.com/ruby/ruby/blob/trunk/regparse.c#L5787
       onig_node_free(tmp);
       return ONIGERR_MEMORY;
     }
+    else
+      node_array[i] = NULL_NODE;
     tmp = *np;
   }
   return 0;
@@ -5810,12 +5812,15 @@ create_alternate_node(Node **np, Node ** https://github.com/ruby/ruby/blob/trunk/regparse.c#L5812
       onig_node_free(tmp);
       return ONIGERR_MEMORY;
     }
+    else
+      node_array[i] = NULL_NODE;
     tmp = *np;
   }
   return 0;
 }
 
 #define R_ERR(call) r=(call);if(r!=0)goto err
+#define NODE_ARRAY_SIZE 9
 
 static int
 node_extended_grapheme_cluster(Node** np, ScanEnv* env)
@@ -5829,11 +5834,20 @@ node_extended_grapheme_cluster(Node** np https://github.com/ruby/ruby/blob/trunk/regparse.c#L5834
   BBuf *pbuf1 = NULL;
   int r = 0;
   int num1;
+  int i;
   UChar buf[ONIGENC_CODE_TO_MBC_MAXLEN * 2];
   OnigOptionType option;
+  /* node_array is function-global so that we can free all nodes
+   * in case of error. Unused slots are set to NULL_NODE at all times. */
+  Node *node_array[NODE_ARRAY_SIZE];
 
 #ifdef USE_UNICODE_PROPERTIES
   if (ONIGENC_IS_UNICODE(env->enc)) {
+    Node **seq  = node_array;   /* seq[5] */
+    Node **alts = node_array+5; /* alts[4] */
+
+    for (i=0; i<8; i++)
+      node_array[i] = NULL_NODE;
     /* UTF-8, UTF-16BE/LE, UTF-32BE/LE */
     CClassNode* cc;
     OnigCodePoint sb_out = (ONIGENC_MBC_MINLEN(env->enc) > 1) ? 0x00 : 0x80;
@@ -5914,8 +5928,6 @@ node_extended_grapheme_cluster(Node** np https://github.com/ruby/ruby/blob/trunk/regparse.c#L5928
 
     /* L* LVT T* */
     {
-      Node* seq[4];
-
       R_ERR(quantify_property_node(seq+0, env, "Grapheme_Cluster_Break=L", '*'));
       R_ERR(create_property_node(seq+1, env, "Grapheme_Cluster_Break=LVT"));
       R_ERR(quantify_property_node(seq+2, env, "Grapheme_Cluster_Break=T", '*'));
@@ -5931,8 +5943,6 @@ node_extended_grapheme_cluster(Node** np https://github.com/ruby/ruby/blob/trunk/regparse.c#L5943
 
     /* L* LV V* T* */
     {
-      Node* seq[5];
-
       R_ERR(quantify_property_node(seq+0, env, "Grapheme_Cluster_Break=L", '*'));
       R_ERR(create_property_node(seq+1, env, "Grapheme_Cluster_Break=LV"));
       R_ERR(quantify_property_node(seq+2, env, "Grapheme_Cluster_Break=V", '*'));
@@ -5949,8 +5959,6 @@ node_extended_grapheme_cluster(Node** np https://github.com/ruby/ruby/blob/trunk/regparse.c#L5959
 
     /* L* V+ T* */
     {
-      Node* seq[4];
-
       R_ERR(quantify_property_node(seq+0, env, "Grapheme_Cluster_Break=L", '*'));
       R_ERR(quantify_property_node(seq+1, env, "Grapheme_Cluster_Break=V", '+'));
       R_ERR(quantify_property_node(seq+2, env, "Grapheme_Cluster_Break=T", '*'));
@@ -5971,16 +5979,12 @@ node_extended_grapheme_cluster(Node** np https://github.com/ruby/ruby/blob/trunk/regparse.c#L5979
     /* ZWJ (Glue_After_Zwj | E_Base_GAZ Extend* E_Modifier?) */
 
     {
-      Node* alts[4];
-
       /* Unicode 10.0.0 */
       /* Emoji variation sequence
        * http://unicode.org/Public/emoji/4.0/emoji-zwj-sequences.txt
        */
       /* Emoji U+FE0F */
       {
-        Node* seq[3];
-
         seq[0] = node_new_cclass();
         if (IS_NULL(seq[0])) goto err;
         cc = NCCLASS(seq[0]);
@@ -5999,8 +6003,6 @@ node_extended_grapheme_cluster(Node** np https://github.com/ruby/ruby/blob/trunk/regparse.c#L6003
       /* Unicode 10.0.0 */
       /* Glue_After_Zwj */
       {
-        Node* seq[3];
-
         seq[0] = node_new_cclass();
         if (IS_NULL(seq[0])) goto err;
         cc = NCCLASS(seq[0]);
@@ -6015,7 +6017,6 @@ node_extended_grapheme_cluster(Node** np https://github.com/ruby/ruby/blob/trunk/regparse.c#L6017
 
       /* E_Base_GAZ Extend* E_Modifier? */
       {
-        Node* seq[4];
         R_ERR(create_property_node(seq+0, env, "Grapheme_Cluster_Break=E_Base_GAZ"));
         R_ERR(quantify_property_node(seq+1, env, "Grapheme_Cluster_Break=Extend", '*'));
         R_ERR(quantify_property_node(seq+2, env, "Grapheme_Cluster_Break=E_Modifier", '?'));
@@ -6094,8 +6095,6 @@ node_extended_grapheme_cluster(Node** np https://github.com/ruby/ruby/blob/trunk/regparse.c#L6095
      */
     /* ZWJ (E_Base_GAZ | Glue_After_Zwj) E_Modifier? */
     {
-      Node* seq[4];
-
       r = ONIGENC_CODE_TO_MBC(env->enc, 0x200D, buf); /* ZERO WIDTH JOINER (ZWJ) */
       if (r < 0) goto err;
       seq[0] = node_new_str_raw(buf, buf + r);
@@ -6160,8 +6159,6 @@ node_extended_grapheme_cluster(Node** np https://github.com/ruby/ruby/blob/trunk/regparse.c#L6159
 
     /* Prepend+ ZWJ* */
     {
-      Node* seq[3];
-
       R_ERR(quantify_property_node(seq+0, env, "Grapheme_Cluster_Break=Prepend", '+'));
 
       r = ONIGENC_CODE_TO_MBC(env->enc, 0x200D, buf); /* does this belong to Prepend?? */
@@ -6246,6 +6243,8 @@ node_extended_grapheme_cluster(Node** np https://github.com/ruby/ruby/blob/trunk/regparse.c#L6243
   onig_node_free(alt);
   onig_node_free(alt2);
   bbuf_free(pbuf1);
+  for (i=0; i<NODE_ARRAY_SIZE; i++)
+    onig_node_free(node_array[i]);
   return (r == 0) ? ONIGERR_MEMORY : r;
 }
 #undef R_ERR

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]