Mercurial > hg > octave-nkf > gnulib-hg
comparison lib/regcomp.c @ 17419:020c917cba9d
regex: fix dfa race in multithreaded uses
Problem reported by Ludovic Courtès in
<http://lists.gnu.org/archive/html/bug-gnulib/2013-05/msg00058.html>.
* lib/regex_internal.h (lock_define, lock_init, lock_fini):
New macros. All uses of __libc_lock_define, __libc_lock_init
changed to use the first two of these.
(__libc_lock_lock, __libc_lock_unlock): New macros, for
non-glibc platforms.
(struct re_dfa_t): Define the lock unconditionally.
* lib/regexec.c (regexec, re_search_stub): Remove some now-incorrect
'#ifdef _LIBC"s.
* modules/regex (Depends-on): Add pthread, if we use the
included regex.
* lib/regcomp.c: Do actions that are not needed for glibc,
but may be needed elsewhere.
(regfree, re_compile_internal): Destroy the lock.
(re_compile_internal): Check for lock-initialization failure.
author | Paul Eggert <eggert@cs.ucla.edu> |
---|---|
date | Sun, 19 May 2013 14:26:05 -0700 |
parents | cd38818bce4e |
children | 6105f1dfb98e |
comparison
equal
deleted
inserted
replaced
17418:b876bfd31d0f | 17419:020c917cba9d |
---|---|
661 regfree (preg) | 661 regfree (preg) |
662 regex_t *preg; | 662 regex_t *preg; |
663 { | 663 { |
664 re_dfa_t *dfa = preg->buffer; | 664 re_dfa_t *dfa = preg->buffer; |
665 if (BE (dfa != NULL, 1)) | 665 if (BE (dfa != NULL, 1)) |
666 free_dfa_content (dfa); | 666 { |
667 lock_fini (dfa->lock); | |
668 free_dfa_content (dfa); | |
669 } | |
667 preg->buffer = NULL; | 670 preg->buffer = NULL; |
668 preg->allocated = 0; | 671 preg->allocated = 0; |
669 | 672 |
670 re_free (preg->fastmap); | 673 re_free (preg->fastmap); |
671 preg->fastmap = NULL; | 674 preg->fastmap = NULL; |
782 preg->buffer = dfa; | 785 preg->buffer = dfa; |
783 } | 786 } |
784 preg->used = sizeof (re_dfa_t); | 787 preg->used = sizeof (re_dfa_t); |
785 | 788 |
786 err = init_dfa (dfa, length); | 789 err = init_dfa (dfa, length); |
790 if (BE (err == REG_NOERROR && lock_init (dfa->lock) != 0, 0)) | |
791 err = REG_ESPACE; | |
787 if (BE (err != REG_NOERROR, 0)) | 792 if (BE (err != REG_NOERROR, 0)) |
788 { | 793 { |
789 free_dfa_content (dfa); | 794 free_dfa_content (dfa); |
790 preg->buffer = NULL; | 795 preg->buffer = NULL; |
791 preg->allocated = 0; | 796 preg->allocated = 0; |
795 /* Note: length+1 will not overflow since it is checked in init_dfa. */ | 800 /* Note: length+1 will not overflow since it is checked in init_dfa. */ |
796 dfa->re_str = re_malloc (char, length + 1); | 801 dfa->re_str = re_malloc (char, length + 1); |
797 strncpy (dfa->re_str, pattern, length + 1); | 802 strncpy (dfa->re_str, pattern, length + 1); |
798 #endif | 803 #endif |
799 | 804 |
800 __libc_lock_init (dfa->lock); | |
801 | |
802 err = re_string_construct (®exp, pattern, length, preg->translate, | 805 err = re_string_construct (®exp, pattern, length, preg->translate, |
803 (syntax & RE_ICASE) != 0, dfa); | 806 (syntax & RE_ICASE) != 0, dfa); |
804 if (BE (err != REG_NOERROR, 0)) | 807 if (BE (err != REG_NOERROR, 0)) |
805 { | 808 { |
806 re_compile_internal_free_return: | 809 re_compile_internal_free_return: |
807 free_workarea_compile (preg); | 810 free_workarea_compile (preg); |
808 re_string_destruct (®exp); | 811 re_string_destruct (®exp); |
812 lock_fini (dfa->lock); | |
809 free_dfa_content (dfa); | 813 free_dfa_content (dfa); |
810 preg->buffer = NULL; | 814 preg->buffer = NULL; |
811 preg->allocated = 0; | 815 preg->allocated = 0; |
812 return err; | 816 return err; |
813 } | 817 } |
836 free_workarea_compile (preg); | 840 free_workarea_compile (preg); |
837 re_string_destruct (®exp); | 841 re_string_destruct (®exp); |
838 | 842 |
839 if (BE (err != REG_NOERROR, 0)) | 843 if (BE (err != REG_NOERROR, 0)) |
840 { | 844 { |
845 lock_fini (dfa->lock); | |
841 free_dfa_content (dfa); | 846 free_dfa_content (dfa); |
842 preg->buffer = NULL; | 847 preg->buffer = NULL; |
843 preg->allocated = 0; | 848 preg->allocated = 0; |
844 } | 849 } |
845 | 850 |