]> git.eshelyaron.com Git - emacs.git/commitdiff
Support null characters in interactive specs
authorEli Zaretskii <eliz@gnu.org>
Tue, 23 Jan 2018 15:48:08 +0000 (17:48 +0200)
committerEli Zaretskii <eliz@gnu.org>
Tue, 23 Jan 2018 15:48:08 +0000 (17:48 +0200)
* src/callint.c (Fcall_interactively): Support 'interactive'
specifications with embedded null characters.  (Bug#30005)

src/callint.c

index 2253cdf3b44bf8d24e7bff4cc7894875116d9273..3d2ed0016cc18cc8fc51e03fee73f12d17dad3d6 100644 (file)
@@ -288,7 +288,8 @@ invoke it.  If KEYS is omitted or nil, the return value of
   ptrdiff_t next_event;
 
   Lisp_Object prefix_arg;
-  char *string;
+  char *string, *string_end;
+  ptrdiff_t string_len;
   const char *tem;
 
   /* If varies[i] > 0, the i'th argument shouldn't just have its value
@@ -396,6 +397,8 @@ invoke it.  If KEYS is omitted or nil, the return value of
   /* SPECS is set to a string; use it as an interactive prompt.
      Copy it so that STRING will be valid even if a GC relocates SPECS.  */
   SAFE_ALLOCA_STRING (string, specs);
+  string_len = SBYTES (specs);
+  string_end = string + string_len;
 
   /* Here if function specifies a string to control parsing the defaults.  */
 
@@ -418,7 +421,7 @@ invoke it.  If KEYS is omitted or nil, the return value of
              if (!NILP (record_flag))
                {
                  char *p = string;
-                 while (*p)
+                 while (p < string_end)
                    {
                      if (! (*p == 'r' || *p == 'p' || *p == 'P'
                             || *p == '\n'))
@@ -469,7 +472,7 @@ invoke it.  If KEYS is omitted or nil, the return value of
      `funcall-interactively') plus the number of arguments the interactive spec
      would have us give to the function.  */
   tem = string;
-  for (nargs = 2; *tem; )
+  for (nargs = 2; tem < string_end; )
     {
       /* 'r' specifications ("point and mark as 2 numeric args")
         produce *two* arguments.  */
@@ -477,7 +480,7 @@ invoke it.  If KEYS is omitted or nil, the return value of
        nargs += 2;
       else
        nargs++;
-      tem = strchr (tem, '\n');
+      tem = memchr (tem, '\n', string_len - (tem - string));
       if (tem)
        ++tem;
       else
@@ -503,9 +506,12 @@ invoke it.  If KEYS is omitted or nil, the return value of
     specbind (Qenable_recursive_minibuffers, Qt);
 
   tem = string;
-  for (i = 2; *tem; i++)
+  for (i = 2; tem < string_end; i++)
     {
-      visargs[1] = make_string (tem + 1, strcspn (tem + 1, "\n"));
+      char *pnl = memchr (tem + 1, '\n', string_len - (tem + 1 - string));
+      ptrdiff_t sz = pnl ? pnl - (tem + 1) : string_end - (tem + 1);
+
+      visargs[1] = make_string (tem + 1, sz);
       callint_message = Fformat_message (i - 1, visargs + 1);
 
       switch (*tem)
@@ -781,7 +787,7 @@ invoke it.  If KEYS is omitted or nil, the return value of
          {
            /* How many bytes are left unprocessed in the specs string?
               (Note that this excludes the trailing null byte.)  */
-           ptrdiff_t bytes_left = SBYTES (specs) - (tem - string);
+           ptrdiff_t bytes_left = string_len - (tem - string);
            unsigned letter;
 
            /* If we have enough bytes left to treat the sequence as a
@@ -803,9 +809,9 @@ invoke it.  If KEYS is omitted or nil, the return value of
       if (NILP (visargs[i]) && STRINGP (args[i]))
        visargs[i] = args[i];
 
-      tem = strchr (tem, '\n');
+      tem = memchr (tem, '\n', string_len - (tem - string));
       if (tem) tem++;
-      else tem = "";
+      else tem = string_end;
     }
   unbind_to (speccount, Qnil);