diff options
| author | Paul Eggert | 2014-08-24 22:44:57 -0700 |
|---|---|---|
| committer | Paul Eggert | 2014-08-24 22:44:57 -0700 |
| commit | 90c5c87753fb69dafd664615558fa3fdce3ba5b1 (patch) | |
| tree | d072b51fd01b88140786d85b5fb4927ccce1a1af /src/sysdep.c | |
| parent | d74553559b62cc7b07ed32c35391c1b75eda540f (diff) | |
| download | emacs-90c5c87753fb69dafd664615558fa3fdce3ba5b1.tar.gz emacs-90c5c87753fb69dafd664615558fa3fdce3ba5b1.zip | |
Minor cleanups of str_collate fix.
* fns.c (str_collate): Move decl from here ...
* lisp.h (str_collate): ... to here.
* sysdep.c (str_collate): Prune away some of the forest of ifdefs.
Remove unnecessary casts. Use SAFE_NALLOCA to avoid
potential problems with integer overflow. Don't assume
setlocale succeeds. Remove unnecessary test before restoring
locale via setlocale, and free the copied setlocale string
when done with it.
Fixes: debbugs:18051
Diffstat (limited to 'src/sysdep.c')
| -rw-r--r-- | src/sysdep.c | 55 |
1 files changed, 30 insertions, 25 deletions
diff --git a/src/sysdep.c b/src/sysdep.c index 619361472e4..856d668bb71 100644 --- a/src/sysdep.c +++ b/src/sysdep.c | |||
| @@ -3517,56 +3517,61 @@ system_process_attributes (Lisp_Object pid) | |||
| 3517 | /* Wide character string collation. */ | 3517 | /* Wide character string collation. */ |
| 3518 | 3518 | ||
| 3519 | #ifdef __STDC_ISO_10646__ | 3519 | #ifdef __STDC_ISO_10646__ |
| 3520 | #include <wchar.h> | 3520 | # include <wchar.h> |
| 3521 | 3521 | ||
| 3522 | #if defined (HAVE_USELOCALE) || defined (HAVE_SETLOCALE) | 3522 | # if defined HAVE_USELOCALE || defined HAVE_SETLOCALE |
| 3523 | #include <locale.h> | 3523 | # include <locale.h> |
| 3524 | #endif /* HAVE_USELOCALE || HAVE_SETLOCALE */ | 3524 | # endif |
| 3525 | # ifndef HAVE_SETLOCALE | ||
| 3526 | # define setlocale(category, locale) ((char *) 0) | ||
| 3527 | # endif | ||
| 3525 | 3528 | ||
| 3526 | ptrdiff_t | 3529 | ptrdiff_t |
| 3527 | str_collate (Lisp_Object s1, Lisp_Object s2) | 3530 | str_collate (Lisp_Object s1, Lisp_Object s2) |
| 3528 | { | 3531 | { |
| 3529 | register ptrdiff_t res, len, i, i_byte; | 3532 | ptrdiff_t res, len, i, i_byte; |
| 3530 | wchar_t *p1, *p2; | 3533 | wchar_t *p1, *p2; |
| 3531 | Lisp_Object lc_collate; | 3534 | Lisp_Object lc_collate; |
| 3532 | #ifdef HAVE_USELOCALE | 3535 | # ifdef HAVE_USELOCALE |
| 3533 | locale_t loc = (locale_t) 0, oldloc = (locale_t) 0; | 3536 | locale_t loc = 0, oldloc = 0; |
| 3534 | #elif defined (HAVE_SETLOCALE) | 3537 | # else |
| 3535 | char *oldloc = NULL; | 3538 | char *oldloc = NULL; |
| 3536 | #endif /* HAVE_USELOCALE */ | 3539 | # endif |
| 3537 | 3540 | ||
| 3538 | USE_SAFE_ALLOCA; | 3541 | USE_SAFE_ALLOCA; |
| 3539 | 3542 | ||
| 3540 | /* Convert byte stream to code points. */ | 3543 | /* Convert byte stream to code points. */ |
| 3541 | len = SCHARS (s1); i = i_byte = 0; | 3544 | len = SCHARS (s1); i = i_byte = 0; |
| 3542 | p1 = (wchar_t *) SAFE_ALLOCA ((len+1) * (sizeof *p1)); | 3545 | SAFE_NALLOCA (p1, 1, len + 1); |
| 3543 | while (i < len) | 3546 | while (i < len) |
| 3544 | FETCH_STRING_CHAR_ADVANCE (*(p1+i-1), s1, i, i_byte); | 3547 | FETCH_STRING_CHAR_ADVANCE (*(p1+i-1), s1, i, i_byte); |
| 3545 | *(p1+len) = 0; | 3548 | *(p1+len) = 0; |
| 3546 | 3549 | ||
| 3547 | len = SCHARS (s2); i = i_byte = 0; | 3550 | len = SCHARS (s2); i = i_byte = 0; |
| 3548 | p2 = (wchar_t *) SAFE_ALLOCA ((len+1) * (sizeof *p2)); | 3551 | SAFE_NALLOCA (p2, 1, len + 1); |
| 3549 | while (i < len) | 3552 | while (i < len) |
| 3550 | FETCH_STRING_CHAR_ADVANCE (*(p2+i-1), s2, i, i_byte); | 3553 | FETCH_STRING_CHAR_ADVANCE (*(p2+i-1), s2, i, i_byte); |
| 3551 | *(p2+len) = 0; | 3554 | *(p2+len) = 0; |
| 3552 | 3555 | ||
| 3553 | #if defined (HAVE_USELOCALE) || defined (HAVE_SETLOCALE) | ||
| 3554 | /* Create a new locale object, and set it. */ | 3556 | /* Create a new locale object, and set it. */ |
| 3555 | lc_collate = | 3557 | lc_collate = |
| 3556 | Fgetenv_internal (build_string ("LC_COLLATE"), Vprocess_environment); | 3558 | Fgetenv_internal (build_string ("LC_COLLATE"), Vprocess_environment); |
| 3557 | 3559 | ||
| 3558 | #ifdef HAVE_USELOCALE | ||
| 3559 | if (STRINGP (lc_collate) | ||
| 3560 | && (loc = newlocale (LC_COLLATE_MASK, SSDATA (lc_collate), (locale_t) 0))) | ||
| 3561 | oldloc = uselocale (loc); | ||
| 3562 | #elif defined (HAVE_SETLOCALE) | ||
| 3563 | if (STRINGP (lc_collate)) | 3560 | if (STRINGP (lc_collate)) |
| 3564 | { | 3561 | { |
| 3565 | oldloc = xstrdup (setlocale (LC_COLLATE, NULL)); | 3562 | #ifdef HAVE_USELOCALE |
| 3566 | setlocale (LC_COLLATE, SSDATA (lc_collate)); | 3563 | loc = newlocale (LC_COLLATE_MASK, SSDATA (lc_collate), 0); |
| 3564 | if (loc) | ||
| 3565 | oldloc = uselocale (loc); | ||
| 3566 | #else | ||
| 3567 | oldloc = setlocale (LC_COLLATE, NULL); | ||
| 3568 | if (oldloc) | ||
| 3569 | { | ||
| 3570 | oldloc = xstrdup (oldloc); | ||
| 3571 | setlocale (LC_COLLATE, SSDATA (lc_collate)); | ||
| 3572 | } | ||
| 3573 | #endif | ||
| 3567 | } | 3574 | } |
| 3568 | #endif /* HAVE_USELOCALE */ | ||
| 3569 | #endif /* HAVE_USELOCALE || HAVE_SETLOCALE */ | ||
| 3570 | 3575 | ||
| 3571 | res = wcscoll (p1, p2); | 3576 | res = wcscoll (p1, p2); |
| 3572 | 3577 | ||
| @@ -3576,11 +3581,11 @@ str_collate (Lisp_Object s1, Lisp_Object s2) | |||
| 3576 | freelocale (loc); | 3581 | freelocale (loc); |
| 3577 | if (oldloc) | 3582 | if (oldloc) |
| 3578 | uselocale (oldloc); | 3583 | uselocale (oldloc); |
| 3579 | #elif defined (HAVE_SETLOCALE) | 3584 | #else |
| 3580 | /* Restore the original locale. */ | 3585 | /* Restore the original locale. */ |
| 3581 | if (oldloc) | 3586 | setlocale (LC_COLLATE, oldloc); |
| 3582 | setlocale (LC_COLLATE, oldloc); | 3587 | xfree (oldloc); |
| 3583 | #endif /* HAVE_USELOCALE */ | 3588 | #endif |
| 3584 | 3589 | ||
| 3585 | /* Return result. */ | 3590 | /* Return result. */ |
| 3586 | SAFE_FREE (); | 3591 | SAFE_FREE (); |