From 412139f1be7415791a0d964f95f319c86eded426 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Tue, 9 Jul 2019 13:10:27 -0700 Subject: [PATCH] Do not alter match data in Fcapitalize etc. MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Without this patch, (capitalize "x") can alter the match data, which is not what users expect. Problem found by running morse-tests-unnato-region in a stripped-down Emacs. Perhaps ‘load’ should also save and restore the match data? That would be a simpler fix, though arguably incompatible. * src/lread.c (save_match_data_load): New function. * src/chartab.c (uniprop_table): * src/doc.c (reread_doc_file): * src/eval.c (Fautoload_do_load): * src/fns.c (Frequire): Use it. --- src/chartab.c | 2 +- src/doc.c | 2 +- src/eval.c | 5 +---- src/fns.c | 5 +++-- src/lisp.h | 2 ++ src/lread.c | 11 +++++++++++ 6 files changed, 19 insertions(+), 8 deletions(-) diff --git a/src/chartab.c b/src/chartab.c index bf8e34b2529..04205ac1032 100644 --- a/src/chartab.c +++ b/src/chartab.c @@ -1288,7 +1288,7 @@ uniprop_table (Lisp_Object prop) if (STRINGP (table)) { AUTO_STRING (intl, "international/"); - result = Fload (concat2 (intl, table), Qt, Qt, Qt, Qt); + result = save_match_data_load (concat2 (intl, table), Qt, Qt, Qt, Qt); if (NILP (result)) return Qnil; table = XCDR (val); diff --git a/src/doc.c b/src/doc.c index 8875360d6e6..8b663f0f249 100644 --- a/src/doc.c +++ b/src/doc.c @@ -302,7 +302,7 @@ reread_doc_file (Lisp_Object file) if (NILP (file)) Fsnarf_documentation (Vdoc_file_name); else - Fload (file, Qt, Qt, Qt, Qnil); + save_match_data_load (file, Qt, Qt, Qt, Qnil); return 1; } diff --git a/src/eval.c b/src/eval.c index 8f569949036..02a6c3555a9 100644 --- a/src/eval.c +++ b/src/eval.c @@ -2049,9 +2049,6 @@ it defines a macro. */) CHECK_SYMBOL (funname); - /* Preserve the match data. */ - record_unwind_save_match_data (); - /* If autoloading gets an error (which includes the error of failing to define the function being called), we use Vautoload_queue to undo function definitions and `provide' calls made by @@ -2067,7 +2064,7 @@ it defines a macro. */) so don't signal an error if autoloading fails. */ Lisp_Object ignore_errors = (EQ (kind, Qt) || EQ (kind, Qmacro)) ? Qnil : macro_only; - Fload (Fcar (Fcdr (fundef)), ignore_errors, Qt, Qnil, Qt); + save_match_data_load (Fcar (Fcdr (fundef)), ignore_errors, Qt, Qnil, Qt); /* Once loading finishes, don't undo it. */ Vautoload_queue = Qt; diff --git a/src/fns.c b/src/fns.c index 77c0b15037f..11f5dddc858 100644 --- a/src/fns.c +++ b/src/fns.c @@ -2984,8 +2984,9 @@ suppressed. */) Vautoload_queue = Qt; /* Load the file. */ - tem = Fload (NILP (filename) ? Fsymbol_name (feature) : filename, - noerror, Qt, Qnil, (NILP (filename) ? Qt : Qnil)); + tem = save_match_data_load + (NILP (filename) ? Fsymbol_name (feature) : filename, + noerror, Qt, Qnil, (NILP (filename) ? Qt : Qnil)); /* If load failed entirely, return nil. */ if (NILP (tem)) diff --git a/src/lisp.h b/src/lisp.h index 8acf63fe227..fa57cad8a60 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -4019,6 +4019,8 @@ LOADHIST_ATTACH (Lisp_Object x) if (initialized) Vcurrent_load_list = Fcons (x, Vcurrent_load_list); } +extern Lisp_Object save_match_data_load (Lisp_Object, Lisp_Object, Lisp_Object, + Lisp_Object, Lisp_Object); extern int openp (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object *, Lisp_Object, bool); enum { S2N_IGNORE_TRAILING = 1 }; diff --git a/src/lread.c b/src/lread.c index e06eafcf6cf..3152fcf867d 100644 --- a/src/lread.c +++ b/src/lread.c @@ -1508,6 +1508,17 @@ Return t if the file exists and loads successfully. */) return Qt; } + +Lisp_Object +save_match_data_load (Lisp_Object file, Lisp_Object noerror, + Lisp_Object nomessage, Lisp_Object nosuffix, + Lisp_Object must_suffix) +{ + ptrdiff_t count = SPECPDL_INDEX (); + record_unwind_save_match_data (); + Lisp_Object result = Fload (file, noerror, nomessage, nosuffix, must_suffix); + return unbind_to (count, result); +} static bool complete_filename_p (Lisp_Object pathname) -- 2.39.5