diff options
| author | Dmitry Antipov | 2014-06-25 14:36:51 +0400 |
|---|---|---|
| committer | Dmitry Antipov | 2014-06-25 14:36:51 +0400 |
| commit | 5697ca55cb79817a6704c344cc76d866ee2e1699 (patch) | |
| tree | 3d9cace5c0dd430485eb16697cb6c045553eb3ae /src | |
| parent | 9a214b9800b7c01d8a473a2564e8f57215990b24 (diff) | |
| download | emacs-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/ChangeLog | 8 | ||||
| -rw-r--r-- | src/fns.c | 65 |
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 @@ | |||
| 1 | 2014-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 | |||
| 1 | 2014-06-24 Paul Eggert <eggert@cs.ucla.edu> | 9 | 2014-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. |
| @@ -50,7 +50,9 @@ static Lisp_Object Qcodeset, Qdays, Qmonths, Qpaper; | |||
| 50 | static Lisp_Object Qmd5, Qsha1, Qsha224, Qsha256, Qsha384, Qsha512; | 50 | static Lisp_Object Qmd5, Qsha1, Qsha224, Qsha256, Qsha384, Qsha512; |
| 51 | 51 | ||
| 52 | static bool internal_equal (Lisp_Object, Lisp_Object, int, bool, Lisp_Object); | 52 | static bool internal_equal (Lisp_Object, Lisp_Object, int, bool, Lisp_Object); |
| 53 | 53 | static void validate_subarray (Lisp_Object, Lisp_Object, Lisp_Object, | |
| 54 | ptrdiff_t, EMACS_INT *, EMACS_INT *); | ||
| 55 | |||
| 54 | DEFUN ("identity", Fidentity, Sidentity, 1, 1, 0, | 56 | DEFUN ("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 |
| 233 | the string; if END1 is nil, it defaults to the length of the string. | 235 | the string; if END1 is nil, it defaults to the length of the string. |
| 234 | Likewise, in string STR2, compare the part between START2 and END2. | 236 | Likewise, in string STR2, compare the part between START2 and END2. |
| 237 | Like in `substring', negative values are counted from the end. | ||
| 235 | 238 | ||
| 236 | The strings are compared by the numeric values of their characters. | 239 | The strings are compared by the numeric values of their characters. |
| 237 | For instance, STR1 is "less than" STR2 if its first differing | 240 | For 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. |
| 245 | If string STR1 is greater, the value is a positive number N; | 248 | If 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 | } |