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

ruby-changes:51207

From: shyouhei <ko1@a...>
Date: Mon, 14 May 2018 12:30:10 +0900 (JST)
Subject: [ruby-changes:51207] shyouhei:r63414 (trunk): RSTRING_PTR is not guaranteed to be char*-aligned

shyouhei	2018-05-14 12:30:03 +0900 (Mon, 14 May 2018)

  New Revision: 63414

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

  Log:
    RSTRING_PTR is not guaranteed to be char*-aligned
    
    This commit eliminates (char **)RSTRING_PTR(...) like usages.

  Modified files:
    trunk/internal.h
    trunk/process.c
Index: process.c
===================================================================
--- process.c	(revision 63413)
+++ process.c	(revision 63414)
@@ -1283,7 +1283,7 @@ proc_exec_cmd(const char *prog, VALUE ar https://github.com/ruby/ruby/blob/trunk/process.c#L1283
     rb_w32_uaspawn(P_OVERLAY, prog, argv);
     return errno;
 #else
-    envp = envp_str ? (char **)RSTRING_PTR(envp_str) : NULL;
+    envp = envp_str ? RB_IMEMO_TMPBUF_PTR(envp_str) : NULL;
     if (envp_str)
         execve(prog, argv, envp); /* async-signal-safe */
     else
@@ -1324,7 +1324,7 @@ proc_exec_sh(const char *str, VALUE envp https://github.com/ruby/ruby/blob/trunk/process.c#L1324
     }
 #else
     if (envp_str)
-        execle("/bin/sh", "sh", "-c", str, (char *)NULL, (char **)RSTRING_PTR(envp_str)); /* async-signal-safe */
+        execle("/bin/sh", "sh", "-c", str, (char *)NULL, RB_IMEMO_TMPBUF_PTR(envp_str)); /* async-signal-safe */
     else
         execl("/bin/sh", "sh", "-c", str, (char *)NULL); /* async-signal-safe (since SUSv4) */
 #endif	/* _WIN32 */
@@ -2264,7 +2264,8 @@ rb_exec_fillarg(VALUE prog, int argc, VA https://github.com/ruby/ruby/blob/trunk/process.c#L2264
             p += strlen(p) + 1;
         }
         rb_str_buf_cat(argv_str, (char *)&null, sizeof(null)); /* terminator for execve.  */
-        eargp->invoke.cmd.argv_str = argv_str;
+        eargp->invoke.cmd.argv_str =
+            rb_imemo_tmpbuf_auto_free_pointer_new_from_an_RString(argv_str);
     }
     RB_GC_GUARD(execarg_obj);
 }
@@ -2464,7 +2465,8 @@ rb_execarg_parent_start1(VALUE execarg_o https://github.com/ruby/ruby/blob/trunk/process.c#L2465
         }
         p = NULL;
         rb_str_buf_cat(envp_str, (char *)&p, sizeof(p));
-        eargp->envp_str = envp_str;
+        eargp->envp_str =
+            rb_imemo_tmpbuf_auto_free_pointer_new_from_an_RString(envp_str);
         eargp->envp_buf = envp_buf;
 
         /*
Index: internal.h
===================================================================
--- internal.h	(revision 63413)
+++ internal.h	(revision 63414)
@@ -964,6 +964,24 @@ VALUE rb_imemo_tmpbuf_auto_free_pointer( https://github.com/ruby/ruby/blob/trunk/internal.h#L964
 VALUE rb_imemo_tmpbuf_auto_free_maybe_mark_buffer(void *buf, size_t cnt);
 rb_imemo_tmpbuf_t *rb_imemo_tmpbuf_parser_heap(void *buf, rb_imemo_tmpbuf_t *old_heap, size_t cnt);
 
+#define RB_IMEMO_TMPBUF_PTR(v) \
+    ((void *)(((const struct rb_imemo_tmpbuf_struct *)(v))->ptr))
+
+static inline VALUE
+rb_imemo_tmpbuf_auto_free_pointer_new_from_an_RString(VALUE str)
+{
+    const void *src;
+    void *dst;
+    size_t len;
+
+    SafeStringValue(str);
+    len = RSTRING_LEN(str);
+    src = RSTRING_PTR(str);
+    dst = ruby_xmalloc(len);
+    memcpy(dst, src, len);
+    return rb_imemo_tmpbuf_auto_free_pointer(dst);
+}
+
 void rb_strterm_mark(VALUE obj);
 
 /*! MEMO
@@ -1679,8 +1697,17 @@ struct rb_execarg { https://github.com/ruby/ruby/blob/trunk/internal.h#L1697
  * The beginning one is for /bin/sh used by exec_with_sh.
  * The last one for terminating NULL used by execve.
  * See rb_exec_fillarg() in process.c. */
-#define ARGVSTR2ARGC(argv_str) (RSTRING_LEN(argv_str) / sizeof(char *) - 2)
-#define ARGVSTR2ARGV(argv_str) ((char **)RSTRING_PTR(argv_str) + 1)
+#define ARGVSTR2ARGV(argv_str) ((char **)RB_IMEMO_TMPBUF_PTR(argv_str) + 1)
+
+static inline size_t
+ARGVSTR2ARGC(VALUE argv_str)
+{
+    size_t i = 0;
+    char *const *p = ARGVSTR2ARGV(argv_str);
+    while (p[i++])
+        ;
+    return i - 1;
+}
 
 rb_pid_t rb_fork_ruby(int *status);
 void rb_last_status_clear(void);

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

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