From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Paul Eggert Newsgroups: gmane.emacs.bugs Subject: bug#8254: race condition in dired.c's scmp function Date: Tue, 15 Mar 2011 14:27:51 -0700 Organization: UCLA Computer Science Department Message-ID: <4D7FD9D7.3070307@cs.ucla.edu> References: <4D7F043A.5070702@cs.ucla.edu> <4D7F15E7.1020407@cs.ucla.edu> <4D7F9ABE.70204@cs.ucla.edu> NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-Trace: dough.gmane.org 1300225514 13497 80.91.229.12 (15 Mar 2011 21:45:14 GMT) X-Complaints-To: usenet@dough.gmane.org NNTP-Posting-Date: Tue, 15 Mar 2011 21:45:14 +0000 (UTC) Cc: Juanma Barranquero , 8254@debbugs.gnu.org To: Stefan Monnier Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Tue Mar 15 22:45:09 2011 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1Pzc39-0007Jo-Lg for geb-bug-gnu-emacs@m.gmane.org; Tue, 15 Mar 2011 22:45:08 +0100 Original-Received: from localhost ([127.0.0.1]:38526 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Pzc39-0000pj-3o for geb-bug-gnu-emacs@m.gmane.org; Tue, 15 Mar 2011 17:45:07 -0400 Original-Received: from [140.186.70.92] (port=47973 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Pzbvg-0003CQ-Ow for bug-gnu-emacs@gnu.org; Tue, 15 Mar 2011 17:37:58 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1PzbvI-0000uZ-0Q for bug-gnu-emacs@gnu.org; Tue, 15 Mar 2011 17:37:01 -0400 Original-Received: from debbugs.gnu.org ([140.186.70.43]:43394) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1PzbvH-0000uV-Uz for bug-gnu-emacs@gnu.org; Tue, 15 Mar 2011 17:36:59 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.69) (envelope-from ) id 1PzbnZ-0003ph-Su; Tue, 15 Mar 2011 17:29:01 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Paul Eggert Original-Sender: debbugs-submit-bounces@debbugs.gnu.org Resent-To: owner@debbugs.gnu.org Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Tue, 15 Mar 2011 21:29:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 8254 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: Original-Received: via spool by 8254-submit@debbugs.gnu.org id=B8254.130022448314661 (code B ref 8254); Tue, 15 Mar 2011 21:29:01 +0000 Original-Received: (at 8254) by debbugs.gnu.org; 15 Mar 2011 21:28:03 +0000 Original-Received: from localhost ([127.0.0.1] helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1Pzbmc-0003oQ-VB for submit@debbugs.gnu.org; Tue, 15 Mar 2011 17:28:03 -0400 Original-Received: from smtp.cs.ucla.edu ([131.179.128.62]) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1PzbmZ-0003nw-9T for 8254@debbugs.gnu.org; Tue, 15 Mar 2011 17:28:01 -0400 Original-Received: from localhost (localhost.localdomain [127.0.0.1]) by smtp.cs.ucla.edu (Postfix) with ESMTP id 52B0839E8109; Tue, 15 Mar 2011 14:27:53 -0700 (PDT) X-Virus-Scanned: amavisd-new at smtp.cs.ucla.edu Original-Received: from smtp.cs.ucla.edu ([127.0.0.1]) by localhost (smtp.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id ER9S6STVbO9X; Tue, 15 Mar 2011 14:27:51 -0700 (PDT) Original-Received: from [131.179.64.200] (Penguin.CS.UCLA.EDU [131.179.64.200]) by smtp.cs.ucla.edu (Postfix) with ESMTPSA id DE97A39E80F2; Tue, 15 Mar 2011 14:27:51 -0700 (PDT) User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.13) Gecko/20101209 Fedora/3.1.7-0.35.b3pre.fc14 Thunderbird/3.1.7 In-Reply-To: X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.11 Precedence: list Resent-Date: Tue, 15 Mar 2011 17:29:01 -0400 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 3) X-Received-From: 140.186.70.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.bugs:45062 Archived-At: On 03/15/2011 12:13 PM, Stefan Monnier wrote: > If we're turning those macros into functions, then I indeed think we > should get rid of the macros. I would also welcome those functions > being real one-liners OK, thanks, then I'll add the following patch to my planned change: === modified file 'src/ChangeLog' --- src/ChangeLog 2011-03-15 18:53:29 +0000 +++ src/ChangeLog 2011-03-15 21:23:54 +0000 @@ -1,5 +1,16 @@ 2011-03-15 Paul Eggert + Use functions, not macros, for up- and down-casing (Bug#8254). + * buffer.h (DOWNCASE_TABLE, UPCASE_TABLE, DOWNCASE, UPPERCASEP): + (NOCASEP, LOWERCASEP, UPCASE, UPCASE1): Remove. All callers changed + to use the following functions instead of these macros. + (downcase): Adjust to lack of DOWNCASE_TABLE. Return int, not + EMACS_INT, since callers assume the returned value fits in int. + (upcase1): Likewise, for UPCASE_TABLE. + (uppercasep, lowercasep, upcase): New static inline functions. + * editfns.c (Fchar_equal): Remove no-longer-needed workaround for + the race-condition problem in the old DOWNCASE. + * regex.c (CHARSET_LOOKUP_RANGE_TABLE_RAW, POP_FAILURE_REG_OR_COUNT): Rename locals to avoid shadowing. (regex_compile, re_match_2_internal): Move locals to avoid shadowing. === modified file 'src/buffer.h' --- src/buffer.h 2011-03-15 07:04:00 +0000 +++ src/buffer.h 2011-03-15 21:14:06 +0000 @@ -1027,46 +1027,30 @@ #define PER_BUFFER_VALUE(BUFFER, OFFSET) \ (*(Lisp_Object *)((OFFSET) + (char *) (BUFFER))) -/* Current buffer's map from characters to lower-case characters. */ - -#define DOWNCASE_TABLE BVAR (current_buffer, downcase_table) - -/* Current buffer's map from characters to upper-case characters. */ - -#define UPCASE_TABLE BVAR (current_buffer, upcase_table) - -/* Downcase a character, or make no change if that cannot be done. */ - -static inline EMACS_INT -downcase (int ch) -{ - Lisp_Object down = CHAR_TABLE_REF (DOWNCASE_TABLE, ch); - return NATNUMP (down) ? XFASTINT (down) : ch; -} -#define DOWNCASE(CH) downcase (CH) - -/* 1 if CH is upper case. */ - -#define UPPERCASEP(CH) (DOWNCASE (CH) != (CH)) - -/* 1 if CH is neither upper nor lower case. */ - -#define NOCASEP(CH) (UPCASE1 (CH) == (CH)) - -/* 1 if CH is lower case. */ - -#define LOWERCASEP(CH) (!UPPERCASEP (CH) && !NOCASEP(CH)) - -/* Upcase a character, or make no change if that cannot be done. */ - -#define UPCASE(CH) (!UPPERCASEP (CH) ? UPCASE1 (CH) : (CH)) - -/* Upcase a character known to be not upper case. */ - -static inline EMACS_INT -upcase1 (int ch) -{ - Lisp_Object up = CHAR_TABLE_REF (UPCASE_TABLE, ch); - return NATNUMP (up) ? XFASTINT (up) : ch; -} -#define UPCASE1(CH) upcase1 (CH) +/* Downcase a character C, or make no change if that cannot be done. */ +static inline int +downcase (int c) +{ + Lisp_Object downcase_table = BVAR (current_buffer, downcase_table); + Lisp_Object down = CHAR_TABLE_REF (downcase_table, c); + return NATNUMP (down) ? XFASTINT (down) : c; +} + +/* 1 if C is upper case. */ +static inline int uppercasep (int c) { return downcase (c) != c; } + +/* Upcase a character C known to be not upper case. */ +static inline int +upcase1 (int c) +{ + Lisp_Object upcase_table = BVAR (current_buffer, upcase_table); + Lisp_Object up = CHAR_TABLE_REF (upcase_table, c); + return NATNUMP (up) ? XFASTINT (up) : c; +} + +/* 1 if C is lower case. */ +static inline int lowercasep (int c) +{ return !uppercasep (c) && upcase1 (c) != c; } + +/* Upcase a character C, or make no change if that cannot be done. */ +static inline int upcase (int c) { return uppercasep (c) ? c : upcase1 (c); } === modified file 'src/casefiddle.c' --- src/casefiddle.c 2011-03-15 17:18:02 +0000 +++ src/casefiddle.c 2011-03-15 21:14:06 +0000 @@ -64,13 +64,13 @@ multibyte = 1; if (! multibyte) MAKE_CHAR_MULTIBYTE (c1); - c = DOWNCASE (c1); + c = downcase (c1); if (inword) XSETFASTINT (obj, c | flags); else if (c == (XFASTINT (obj) & ~flagbits)) { if (! inword) - c = UPCASE1 (c1); + c = upcase1 (c1); if (! multibyte) MAKE_CHAR_UNIBYTE (c); XSETFASTINT (obj, c | flags); @@ -92,10 +92,10 @@ MAKE_CHAR_MULTIBYTE (c); c1 = c; if (inword && flag != CASE_CAPITALIZE_UP) - c = DOWNCASE (c); - else if (!UPPERCASEP (c) + c = downcase (c); + else if (!uppercasep (c) && (!inword || flag != CASE_CAPITALIZE_UP)) - c = UPCASE1 (c1); + c = upcase1 (c1); if ((int) flag >= (int) CASE_CAPITALIZE) inword = (SYNTAX (c) == Sword); if (c != c1) @@ -133,10 +133,10 @@ } c = STRING_CHAR_AND_LENGTH (SDATA (obj) + i_byte, len); if (inword && flag != CASE_CAPITALIZE_UP) - c = DOWNCASE (c); - else if (!UPPERCASEP (c) + c = downcase (c); + else if (!uppercasep (c) && (!inword || flag != CASE_CAPITALIZE_UP)) - c = UPCASE1 (c); + c = upcase1 (c); if ((int) flag >= (int) CASE_CAPITALIZE) inword = (SYNTAX (c) == Sword); o += CHAR_STRING (c, o); @@ -243,10 +243,10 @@ } c2 = c; if (inword && flag != CASE_CAPITALIZE_UP) - c = DOWNCASE (c); - else if (!UPPERCASEP (c) + c = downcase (c); + else if (!uppercasep (c) && (!inword || flag != CASE_CAPITALIZE_UP)) - c = UPCASE1 (c); + c = upcase1 (c); if ((int) flag >= (int) CASE_CAPITALIZE) inword = ((SYNTAX (c) == Sword) && (inword || !syntax_prefix_flag_p (c))); === modified file 'src/dired.c' --- src/dired.c 2011-03-15 18:08:06 +0000 +++ src/dired.c 2011-03-15 21:14:06 +0000 @@ -790,8 +790,8 @@ if (completion_ignore_case) { while (l - && (DOWNCASE ((unsigned char) *s1++) - == DOWNCASE ((unsigned char) *s2++))) + && (downcase ((unsigned char) *s1++) + == downcase ((unsigned char) *s2++))) l--; } else === modified file 'src/editfns.c' --- src/editfns.c 2011-03-13 06:27:18 +0000 +++ src/editfns.c 2011-03-15 21:23:02 +0000 @@ -1374,7 +1374,7 @@ memcpy (r, p, q - p); r[q - p] = 0; strcat (r, SSDATA (login)); - r[q - p] = UPCASE ((unsigned char) r[q - p]); + r[q - p] = upcase ((unsigned char) r[q - p]); strcat (r, q + 1); full = build_string (r); } @@ -4213,7 +4213,7 @@ { int i1, i2; /* Check they're chars, not just integers, otherwise we could get array - bounds violations in DOWNCASE. */ + bounds violations in downcase. */ CHECK_CHARACTER (c1); CHECK_CHARACTER (c2); @@ -4222,9 +4222,6 @@ if (NILP (BVAR (current_buffer, case_fold_search))) return Qnil; - /* Do these in separate statements, - then compare the variables. - because of the way DOWNCASE uses temp variables. */ i1 = XFASTINT (c1); if (NILP (BVAR (current_buffer, enable_multibyte_characters)) && ! ASCII_CHAR_P (i1)) @@ -4237,9 +4234,7 @@ { MAKE_CHAR_MULTIBYTE (i2); } - i1 = DOWNCASE (i1); - i2 = DOWNCASE (i2); - return (i1 == i2 ? Qt : Qnil); + return (downcase (i1) == downcase (i2) ? Qt : Qnil); } /* Transpose the markers in two regions of the current buffer, and === modified file 'src/fileio.c' --- src/fileio.c 2011-03-15 03:17:20 +0000 +++ src/fileio.c 2011-03-15 21:14:06 +0000 @@ -178,7 +178,7 @@ str = SSDATA (errstring); c = STRING_CHAR ((unsigned char *) str); - Faset (errstring, make_number (0), make_number (DOWNCASE (c))); + Faset (errstring, make_number (0), make_number (downcase (c))); } xsignal (Qfile_error, === modified file 'src/keyboard.c' --- src/keyboard.c 2011-03-15 17:13:02 +0000 +++ src/keyboard.c 2011-03-15 21:14:06 +0000 @@ -9836,7 +9836,7 @@ && /* indec.start >= t && fkey.start >= t && */ keytran.start >= t && INTEGERP (key) && ((CHARACTERP (make_number (XINT (key) & ~CHAR_MODIFIER_MASK)) - && UPPERCASEP (XINT (key) & ~CHAR_MODIFIER_MASK)) + && uppercasep (XINT (key) & ~CHAR_MODIFIER_MASK)) || (XINT (key) & shift_modifier))) { Lisp_Object new_key; @@ -9847,7 +9847,7 @@ if (XINT (key) & shift_modifier) XSETINT (new_key, XINT (key) & ~shift_modifier); else - XSETINT (new_key, (DOWNCASE (XINT (key) & ~CHAR_MODIFIER_MASK) + XSETINT (new_key, (downcase (XINT (key) & ~CHAR_MODIFIER_MASK) | (XINT (key) & CHAR_MODIFIER_MASK))); /* We have to do this unconditionally, regardless of whether @@ -9875,13 +9875,13 @@ || (INTEGERP (key) && (KEY_TO_CHAR (key) < XCHAR_TABLE (BVAR (current_buffer, downcase_table))->size) - && UPPERCASEP (KEY_TO_CHAR (key)))) + && uppercasep (KEY_TO_CHAR (key)))) { Lisp_Object new_key = (modifiers & shift_modifier ? apply_modifiers (modifiers & ~shift_modifier, XCAR (breakdown)) - : make_number (DOWNCASE (KEY_TO_CHAR (key)) | modifiers)); + : make_number (downcase (KEY_TO_CHAR (key)) | modifiers)); original_uppercase = key; original_uppercase_position = t - 1; === modified file 'src/process.c' --- src/process.c 2011-03-14 22:49:41 +0000 +++ src/process.c 2011-03-15 21:14:06 +0000 @@ -495,7 +495,7 @@ string = (code_convert_string_norecord (string, Vlocale_coding_system, 0)); c1 = STRING_CHAR (SDATA (string)); - c2 = DOWNCASE (c1); + c2 = downcase (c1); if (c1 != c2) Faset (string, make_number (0), make_number (c2)); } === modified file 'src/regex.c' --- src/regex.c 2011-03-15 18:53:29 +0000 +++ src/regex.c 2011-03-15 21:14:06 +0000 @@ -340,7 +340,7 @@ || ((c) >= 'A' && (c) <= 'Z')) \ : SYNTAX (c) == Sword) -# define ISLOWER(c) (LOWERCASEP (c)) +# define ISLOWER(c) lowercasep (c) # define ISPUNCT(c) (IS_REAL_ASCII (c) \ ? ((c) > ' ' && (c) < 0177 \ @@ -351,7 +351,7 @@ # define ISSPACE(c) (SYNTAX (c) == Swhitespace) -# define ISUPPER(c) (UPPERCASEP (c)) +# define ISUPPER(c) uppercasep (c) # define ISWORD(c) (SYNTAX (c) == Sword) === modified file 'src/search.c' --- src/search.c 2011-03-15 18:13:15 +0000 +++ src/search.c 2011-03-15 21:14:06 +0000 @@ -2469,7 +2469,7 @@ else FETCH_STRING_CHAR_AS_MULTIBYTE_ADVANCE (c, string, pos, pos_byte); - if (LOWERCASEP (c)) + if (lowercasep (c)) { /* Cannot be all caps if any original char is lower case */ @@ -2479,7 +2479,7 @@ else some_multiletter_word = 1; } - else if (UPPERCASEP (c)) + else if (uppercasep (c)) { some_uppercase = 1; if (SYNTAX (prevc) != Sword)