diff --git a/src/fns.c b/src/fns.c index 2f64d955760..2fcc282dcb3 100644 --- a/src/fns.c +++ b/src/fns.c @@ -5468,6 +5468,7 @@ Case is always significant and text properties are ignored. */) { ptrdiff_t start_byte = 0, haybytes; char *res, *haystart; + EMACS_INT start = 0; CHECK_STRING (needle); CHECK_STRING (haystack); @@ -5475,12 +5476,17 @@ Case is always significant and text properties are ignored. */) if (!NILP (start_pos)) { CHECK_FIXNUM (start_pos); - EMACS_INT start = XFIXNUM (start_pos); + start = XFIXNUM (start_pos); if (start < 0 || start > SCHARS (haystack)) xsignal1 (Qargs_out_of_range, start_pos); start_byte = string_char_to_byte (haystack, start); } + /* If NEEDLE is longer than (the remaining length of) haystack, then + we can't have a match, and return early. */ + if (SCHARS (needle) > SCHARS (haystack) - start) + return Qnil; + haystart = SSDATA (haystack) + start_byte; haybytes = SBYTES (haystack) - start_byte; diff --git a/test/lisp/subr-tests.el b/test/lisp/subr-tests.el index a3e9c426db5..42dcf382e40 100644 --- a/test/lisp/subr-tests.el +++ b/test/lisp/subr-tests.el @@ -461,6 +461,9 @@ See https://debbugs.gnu.org/cgi/bugreport.cgi?bug=19350." (should (equal (string-replace "azot" "bar" "foozotbar") "foozotbar")) + (should (equal (string-replace "fo" "bar" "lafofofozot") + "labarbarbarzot")) + (should (equal (string-replace "\377" "x" "a\377b") "axb")) (should (equal (string-replace "\377" "x" "a\377ΓΈ")