aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDmitry Antipov2014-06-25 14:36:51 +0400
committerDmitry Antipov2014-06-25 14:36:51 +0400
commit5697ca55cb79817a6704c344cc76d866ee2e1699 (patch)
tree3d9cace5c0dd430485eb16697cb6c045553eb3ae /src
parent9a214b9800b7c01d8a473a2564e8f57215990b24 (diff)
downloademacs-5697ca55cb79817a6704c344cc76d866ee2e1699.tar.gz
emacs-5697ca55cb79817a6704c344cc76d866ee2e1699.zip
Do not allow out-of-range character position in Fcompare_strings.
* src/fns.c (validate_subarray): Add prototype. (Fcompare_substring): Use validate_subarray to check ranges. Adjust comment to mention that the semantics was changed. Also see http://lists.gnu.org/archive/html/emacs-devel/2014-06/msg00447.html. * lisp/files.el (dir-locals-find-file, file-relative-name): * lisp/info.el (Info-complete-menu-item): * lisp/minibuffer.el (completion-table-subvert): Prefer string-prefix-p to compare-strings to avoid out-of-range errors. * lisp/subr.el (string-prefix-p): Adjust to match strict range checking in compare-strings. * test/automated/fns-tests.el (fns-tests-compare-string): New test.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog8
-rw-r--r--src/fns.c65
2 files changed, 31 insertions, 42 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 9f676a6518d..fc47fbc8978 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,11 @@
12014-06-25 Dmitry Antipov <dmantipov@yandex.ru>
2
3 Do not allow out-of-range character position in Fcompare_strings.
4 * fns.c (validate_subarray): Add prototype.
5 (Fcompare_substring): Use validate_subarray to check ranges.
6 Adjust comment to mention that the semantics was changed. Also see
7 http://lists.gnu.org/archive/html/emacs-devel/2014-06/msg00447.html.
8
12014-06-24 Paul Eggert <eggert@cs.ucla.edu> 92014-06-24 Paul Eggert <eggert@cs.ucla.edu>
2 10
3 Be more consistent about the 'Qfoo' naming convention. 11 Be more consistent about the 'Qfoo' naming convention.
diff --git a/src/fns.c b/src/fns.c
index 5074ae3b41b..85e9f482fc1 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -50,7 +50,9 @@ static Lisp_Object Qcodeset, Qdays, Qmonths, Qpaper;
50static Lisp_Object Qmd5, Qsha1, Qsha224, Qsha256, Qsha384, Qsha512; 50static Lisp_Object Qmd5, Qsha1, Qsha224, Qsha256, Qsha384, Qsha512;
51 51
52static bool internal_equal (Lisp_Object, Lisp_Object, int, bool, Lisp_Object); 52static bool internal_equal (Lisp_Object, Lisp_Object, int, bool, Lisp_Object);
53 53static void validate_subarray (Lisp_Object, Lisp_Object, Lisp_Object,
54 ptrdiff_t, EMACS_INT *, EMACS_INT *);
55
54DEFUN ("identity", Fidentity, Sidentity, 1, 1, 0, 56DEFUN ("identity", Fidentity, Sidentity, 1, 1, 0,
55 doc: /* Return the argument unchanged. */) 57 doc: /* Return the argument unchanged. */)
56 (Lisp_Object arg) 58 (Lisp_Object arg)
@@ -232,6 +234,7 @@ string STR1, compare the part between START1 (inclusive) and END1
232\(exclusive). If START1 is nil, it defaults to 0, the beginning of 234\(exclusive). If START1 is nil, it defaults to 0, the beginning of
233the string; if END1 is nil, it defaults to the length of the string. 235the string; if END1 is nil, it defaults to the length of the string.
234Likewise, in string STR2, compare the part between START2 and END2. 236Likewise, in string STR2, compare the part between START2 and END2.
237Like in `substring', negative values are counted from the end.
235 238
236The strings are compared by the numeric values of their characters. 239The strings are compared by the numeric values of their characters.
237For instance, STR1 is "less than" STR2 if its first differing 240For instance, STR1 is "less than" STR2 if its first differing
@@ -244,43 +247,25 @@ If string STR1 is less, the value is a negative number N;
244 - 1 - N is the number of characters that match at the beginning. 247 - 1 - N is the number of characters that match at the beginning.
245If string STR1 is greater, the value is a positive number N; 248If string STR1 is greater, the value is a positive number N;
246 N - 1 is the number of characters that match at the beginning. */) 249 N - 1 is the number of characters that match at the beginning. */)
247 (Lisp_Object str1, Lisp_Object start1, Lisp_Object end1, Lisp_Object str2, Lisp_Object start2, Lisp_Object end2, Lisp_Object ignore_case) 250 (Lisp_Object str1, Lisp_Object start1, Lisp_Object end1, Lisp_Object str2,
251 Lisp_Object start2, Lisp_Object end2, Lisp_Object ignore_case)
248{ 252{
249 register ptrdiff_t end1_char, end2_char; 253 EMACS_INT from1, to1, from2, to2;
250 register ptrdiff_t i1, i1_byte, i2, i2_byte; 254 ptrdiff_t i1, i1_byte, i2, i2_byte;
251 255
252 CHECK_STRING (str1); 256 CHECK_STRING (str1);
253 CHECK_STRING (str2); 257 CHECK_STRING (str2);
254 if (NILP (start1)) 258
255 start1 = make_number (0); 259 validate_subarray (str1, start1, end1, SCHARS (str1), &from1, &to1);
256 if (NILP (start2)) 260 validate_subarray (str2, start2, end2, SCHARS (str2), &from2, &to2);
257 start2 = make_number (0); 261
258 CHECK_NATNUM (start1); 262 i1 = from1;
259 CHECK_NATNUM (start2); 263 i2 = from2;
260 if (! NILP (end1))
261 CHECK_NATNUM (end1);
262 if (! NILP (end2))
263 CHECK_NATNUM (end2);
264
265 end1_char = SCHARS (str1);
266 if (! NILP (end1) && end1_char > XINT (end1))
267 end1_char = XINT (end1);
268 if (end1_char < XINT (start1))
269 args_out_of_range (str1, start1);
270
271 end2_char = SCHARS (str2);
272 if (! NILP (end2) && end2_char > XINT (end2))
273 end2_char = XINT (end2);
274 if (end2_char < XINT (start2))
275 args_out_of_range (str2, start2);
276
277 i1 = XINT (start1);
278 i2 = XINT (start2);
279 264
280 i1_byte = string_char_to_byte (str1, i1); 265 i1_byte = string_char_to_byte (str1, i1);
281 i2_byte = string_char_to_byte (str2, i2); 266 i2_byte = string_char_to_byte (str2, i2);
282 267
283 while (i1 < end1_char && i2 < end2_char) 268 while (i1 < to1 && i2 < to2)
284 { 269 {
285 /* When we find a mismatch, we must compare the 270 /* When we find a mismatch, we must compare the
286 characters, not just the bytes. */ 271 characters, not just the bytes. */
@@ -307,12 +292,8 @@ If string STR1 is greater, the value is a positive number N;
307 292
308 if (! NILP (ignore_case)) 293 if (! NILP (ignore_case))
309 { 294 {
310 Lisp_Object tem; 295 c1 = XINT (Fupcase (make_number (c1)));
311 296 c2 = XINT (Fupcase (make_number (c2)));
312 tem = Fupcase (make_number (c1));
313 c1 = XINT (tem);
314 tem = Fupcase (make_number (c2));
315 c2 = XINT (tem);
316 } 297 }
317 298
318 if (c1 == c2) 299 if (c1 == c2)
@@ -322,15 +303,15 @@ If string STR1 is greater, the value is a positive number N;
322 past the character that we are comparing; 303 past the character that we are comparing;
323 hence we don't add or subtract 1 here. */ 304 hence we don't add or subtract 1 here. */
324 if (c1 < c2) 305 if (c1 < c2)
325 return make_number (- i1 + XINT (start1)); 306 return make_number (- i1 + from1);
326 else 307 else
327 return make_number (i1 - XINT (start1)); 308 return make_number (i1 - from1);
328 } 309 }
329 310
330 if (i1 < end1_char) 311 if (i1 < to1)
331 return make_number (i1 - XINT (start1) + 1); 312 return make_number (i1 - from1 + 1);
332 if (i2 < end2_char) 313 if (i2 < to2)
333 return make_number (- i1 + XINT (start1) - 1); 314 return make_number (- i1 + from1 - 1);
334 315
335 return Qt; 316 return Qt;
336} 317}