aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Eggert2020-05-18 17:17:46 -0700
committerPaul Eggert2020-05-18 17:24:35 -0700
commitc5eafccc9d2a32ef422060e50533b36292bdcc01 (patch)
tree895fdec0566fea0f1b94ac54dc2051f65eae925c
parent06fe322c8d7123edea0759a7aa12051f4e676376 (diff)
downloademacs-c5eafccc9d2a32ef422060e50533b36292bdcc01.tar.gz
emacs-c5eafccc9d2a32ef422060e50533b36292bdcc01.zip
Reject attempts to clear pure strings
* src/fns.c (Ffillarray, Fclear_string): Add CHECK_IMPURE here, to be consistent with Faset etc. (Ffillarray): Prefer memset when the fill is a single byte.
-rw-r--r--src/fns.c51
1 files changed, 32 insertions, 19 deletions
diff --git a/src/fns.c b/src/fns.c
index 301bd59ab90..b2f84b202de 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -2508,26 +2508,36 @@ ARRAY is a vector, string, char-table, or bool-vector. */)
2508 } 2508 }
2509 else if (STRINGP (array)) 2509 else if (STRINGP (array))
2510 { 2510 {
2511 register unsigned char *p = SDATA (array); 2511 unsigned char *p = SDATA (array);
2512 int charval;
2513 CHECK_CHARACTER (item); 2512 CHECK_CHARACTER (item);
2514 charval = XFIXNAT (item); 2513 int charval = XFIXNAT (item);
2515 size = SCHARS (array); 2514 size = SCHARS (array);
2516 if (STRING_MULTIBYTE (array)) 2515 if (size != 0)
2517 { 2516 {
2517 CHECK_IMPURE (array, XSTRING (array));
2518 unsigned char str[MAX_MULTIBYTE_LENGTH]; 2518 unsigned char str[MAX_MULTIBYTE_LENGTH];
2519 int len = CHAR_STRING (charval, str); 2519 int len;
2520 ptrdiff_t size_byte = SBYTES (array); 2520 if (STRING_MULTIBYTE (array))
2521 ptrdiff_t product; 2521 len = CHAR_STRING (charval, str);
2522 else
2523 {
2524 str[0] = charval;
2525 len = 1;
2526 }
2522 2527
2523 if (INT_MULTIPLY_WRAPV (size, len, &product) || product != size_byte) 2528 ptrdiff_t size_byte = SBYTES (array);
2524 error ("Attempt to change byte length of a string"); 2529 if (len == 1 && size == size_byte)
2525 for (idx = 0; idx < size_byte; idx++) 2530 memset (p, str[0], size);
2526 *p++ = str[idx % len]; 2531 else
2532 {
2533 ptrdiff_t product;
2534 if (INT_MULTIPLY_WRAPV (size, len, &product)
2535 || product != size_byte)
2536 error ("Attempt to change byte length of a string");
2537 for (idx = 0; idx < size_byte; idx++)
2538 *p++ = str[idx % len];
2539 }
2527 } 2540 }
2528 else
2529 for (idx = 0; idx < size; idx++)
2530 p[idx] = charval;
2531 } 2541 }
2532 else if (BOOL_VECTOR_P (array)) 2542 else if (BOOL_VECTOR_P (array))
2533 return bool_vector_fill (array, item); 2543 return bool_vector_fill (array, item);
@@ -2542,12 +2552,15 @@ DEFUN ("clear-string", Fclear_string, Sclear_string,
2542This makes STRING unibyte and may change its length. */) 2552This makes STRING unibyte and may change its length. */)
2543 (Lisp_Object string) 2553 (Lisp_Object string)
2544{ 2554{
2545 ptrdiff_t len;
2546 CHECK_STRING (string); 2555 CHECK_STRING (string);
2547 len = SBYTES (string); 2556 ptrdiff_t len = SBYTES (string);
2548 memset (SDATA (string), 0, len); 2557 if (len != 0 || STRING_MULTIBYTE (string))
2549 STRING_SET_CHARS (string, len); 2558 {
2550 STRING_SET_UNIBYTE (string); 2559 CHECK_IMPURE (string, XSTRING (string));
2560 memset (SDATA (string), 0, len);
2561 STRING_SET_CHARS (string, len);
2562 STRING_SET_UNIBYTE (string);
2563 }
2551 return Qnil; 2564 return Qnil;
2552} 2565}
2553 2566