annotate lib/regex-quote.c @ 37166:fe129ca366e4

regex-quote: fix buffer access out of bounds http://lists.gnu.org/archive/html/bug-gnulib/2013-09/msg00001.html * lib/regex-quote.c (regex_quote_spec_pcre): Fix typo that resulted in an out-of-bounds read.
author Anton Ovchinnikov <revolver112@gmail.com>
date Wed, 04 Sep 2013 17:09:39 -0700
parents c741bc27922a
children 344018b6e5d7
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
33419
4c735bd27df8 New module 'regex-quote'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1 /* Construct a regular expression from a literal string.
36940
c741bc27922a maint: update all copyright year number ranges
Eric Blake <eblake@redhat.com>
parents: 35892
diff changeset
2 Copyright (C) 1995, 2010-2013 Free Software Foundation, Inc.
33419
4c735bd27df8 New module 'regex-quote'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
3 Written by Bruno Haible <haible@clisp.cons.org>, 2010.
4c735bd27df8 New module 'regex-quote'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
4
4c735bd27df8 New module 'regex-quote'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
5 This program is free software: you can redistribute it and/or modify
4c735bd27df8 New module 'regex-quote'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
6 it under the terms of the GNU General Public License as published by
4c735bd27df8 New module 'regex-quote'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
7 the Free Software Foundation; either version 3 of the License, or
4c735bd27df8 New module 'regex-quote'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
8 (at your option) any later version.
4c735bd27df8 New module 'regex-quote'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
9
4c735bd27df8 New module 'regex-quote'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
10 This program is distributed in the hope that it will be useful,
4c735bd27df8 New module 'regex-quote'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
4c735bd27df8 New module 'regex-quote'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4c735bd27df8 New module 'regex-quote'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
13 GNU General Public License for more details.
4c735bd27df8 New module 'regex-quote'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
14
4c735bd27df8 New module 'regex-quote'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
15 You should have received a copy of the GNU General Public License
4c735bd27df8 New module 'regex-quote'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
16 along with this program. If not, see <http://www.gnu.org/licenses/>. */
4c735bd27df8 New module 'regex-quote'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
17
4c735bd27df8 New module 'regex-quote'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
18 #include <config.h>
4c735bd27df8 New module 'regex-quote'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
19
4c735bd27df8 New module 'regex-quote'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
20 /* Specification. */
4c735bd27df8 New module 'regex-quote'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
21 #include "regex-quote.h"
4c735bd27df8 New module 'regex-quote'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
22
4c735bd27df8 New module 'regex-quote'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
23 #include <string.h>
4c735bd27df8 New module 'regex-quote'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
24
4c735bd27df8 New module 'regex-quote'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
25 #include "mbuiter.h"
4c735bd27df8 New module 'regex-quote'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
26 #include "xalloc.h"
4c735bd27df8 New module 'regex-quote'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
27
4c735bd27df8 New module 'regex-quote'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
28 /* Characters that are special in a BRE. */
4c735bd27df8 New module 'regex-quote'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
29 static const char bre_special[] = "$^.*[]\\";
4c735bd27df8 New module 'regex-quote'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
30
4c735bd27df8 New module 'regex-quote'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
31 /* Characters that are special in an ERE. */
34100
d330ffd59218 regex-quote: Fix creation of POSIX extended regular expressions.
Bruno Haible <bruno@clisp.org>
parents: 33770
diff changeset
32 static const char ere_special[] = "$^.*[]\\+?{}()|";
33419
4c735bd27df8 New module 'regex-quote'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
33
34101
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
34 struct regex_quote_spec
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
35 regex_quote_spec_posix (int cflags, bool anchored)
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
36 {
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
37 struct regex_quote_spec result;
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
38
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
39 strcpy (result.special, cflags != 0 ? ere_special : bre_special);
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
40 result.multibyte = true;
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
41 result.anchored = anchored;
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
42
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
43 return result;
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
44 }
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
45
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
46 /* Syntax bit values, defined in GNU <regex.h>. We don't include it here,
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
47 otherwise this module would need to depend on gnulib module 'regex'. */
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
48 #define RE_BK_PLUS_QM 0x00000002
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
49 #define RE_INTERVALS 0x00000200
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
50 #define RE_LIMITED_OPS 0x00000400
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
51 #define RE_NEWLINE_ALT 0x00000800
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
52 #define RE_NO_BK_BRACES 0x00001000
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
53 #define RE_NO_BK_PARENS 0x00002000
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
54 #define RE_NO_BK_VBAR 0x00008000
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
55
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
56 struct regex_quote_spec
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
57 regex_quote_spec_gnu (unsigned long /*reg_syntax_t*/ syntax, bool anchored)
33419
4c735bd27df8 New module 'regex-quote'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
58 {
34101
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
59 struct regex_quote_spec result;
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
60 char *p;
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
61
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
62 p = result.special;
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
63 memcpy (p, bre_special, sizeof (bre_special) - 1);
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
64 p += sizeof (bre_special) - 1;
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
65 if ((syntax & RE_LIMITED_OPS) == 0 && (syntax & RE_BK_PLUS_QM) == 0)
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
66 {
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
67 *p++ = '+';
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
68 *p++ = '?';
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
69 }
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
70 if ((syntax & RE_INTERVALS) != 0 && (syntax & RE_NO_BK_BRACES) != 0)
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
71 {
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
72 *p++ = '{';
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
73 *p++ = '}';
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
74 }
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
75 if ((syntax & RE_NO_BK_PARENS) != 0)
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
76 {
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
77 *p++ = '(';
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
78 *p++ = ')';
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
79 }
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
80 if ((syntax & RE_LIMITED_OPS) == 0 && (syntax & RE_NO_BK_VBAR) != 0)
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
81 *p++ = '|';
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
82 if ((syntax & RE_NEWLINE_ALT) != 0)
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
83 *p++ = '\n';
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
84 *p = '\0';
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
85
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
86 result.multibyte = true;
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
87 result.anchored = anchored;
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
88
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
89 return result;
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
90 }
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
91
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
92 /* Characters that are special in a PCRE. */
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
93 static const char pcre_special[] = "$^.*[]\\+?{}()|";
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
94
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
95 /* Options bit values, defined in <pcre.h>. We don't include it here, because
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
96 it is not a standard header. */
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
97 #define PCRE_ANCHORED 0x00000010
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
98 #define PCRE_EXTENDED 0x00000008
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
99
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
100 struct regex_quote_spec
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
101 regex_quote_spec_pcre (int options, bool anchored)
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
102 {
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
103 struct regex_quote_spec result;
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
104 char *p;
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
105
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
106 p = result.special;
37166
fe129ca366e4 regex-quote: fix buffer access out of bounds
Anton Ovchinnikov <revolver112@gmail.com>
parents: 36940
diff changeset
107 memcpy (p, pcre_special, sizeof (pcre_special) - 1);
34101
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
108 p += sizeof (pcre_special) - 1;
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
109 if (options & PCRE_EXTENDED)
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
110 {
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
111 *p++ = ' ';
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
112 *p++ = '\t';
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
113 *p++ = '\n';
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
114 *p++ = '\v';
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
115 *p++ = '\f';
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
116 *p++ = '\r';
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
117 *p++ = '#';
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
118 }
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
119 *p = '\0';
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
120
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
121 /* PCRE regular expressions consist of UTF-8 characters of options contains
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
122 PCRE_UTF8 and of single bytes otherwise. */
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
123 result.multibyte = false;
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
124 /* If options contains PCRE_ANCHORED, the anchoring is implicit. */
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
125 result.anchored = (options & PCRE_ANCHORED ? 0 : anchored);
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
126
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
127 return result;
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
128 }
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
129
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
130 size_t
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
131 regex_quote_length (const char *string, const struct regex_quote_spec *spec)
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
132 {
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
133 const char *special = spec->special;
33419
4c735bd27df8 New module 'regex-quote'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
134 size_t length;
4c735bd27df8 New module 'regex-quote'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
135
4c735bd27df8 New module 'regex-quote'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
136 length = 0;
34101
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
137 if (spec->anchored)
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
138 length += 2; /* for '^' at the beginning and '$' at the end */
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
139 if (spec->multibyte)
33419
4c735bd27df8 New module 'regex-quote'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
140 {
34101
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
141 mbui_iterator_t iter;
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
142
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
143 for (mbui_init (iter, string); mbui_avail (iter); mbui_advance (iter))
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
144 {
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
145 /* We know that special contains only ASCII characters. */
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
146 if (mb_len (mbui_cur (iter)) == 1
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
147 && strchr (special, * mbui_cur_ptr (iter)))
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
148 length += 1;
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
149 length += mb_len (mbui_cur (iter));
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
150 }
33419
4c735bd27df8 New module 'regex-quote'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
151 }
34101
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
152 else
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
153 {
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
154 const char *iter;
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
155
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
156 for (iter = string; *iter != '\0'; iter++)
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
157 {
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
158 if (strchr (special, *iter))
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
159 length += 1;
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
160 length += 1;
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
161 }
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
162 }
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
163
33419
4c735bd27df8 New module 'regex-quote'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
164 return length;
4c735bd27df8 New module 'regex-quote'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
165 }
4c735bd27df8 New module 'regex-quote'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
166
4c735bd27df8 New module 'regex-quote'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
167 char *
34101
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
168 regex_quote_copy (char *p, const char *string, const struct regex_quote_spec *spec)
33419
4c735bd27df8 New module 'regex-quote'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
169 {
34101
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
170 const char *special = spec->special;
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
171
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
172 if (spec->anchored)
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
173 *p++ = '^';
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
174 if (spec->multibyte)
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
175 {
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
176 mbui_iterator_t iter;
33419
4c735bd27df8 New module 'regex-quote'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
177
34101
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
178 for (mbui_init (iter, string); mbui_avail (iter); mbui_advance (iter))
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
179 {
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
180 /* We know that special contains only ASCII characters. */
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
181 if (mb_len (mbui_cur (iter)) == 1
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
182 && strchr (special, * mbui_cur_ptr (iter)))
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
183 *p++ = '\\';
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
184 memcpy (p, mbui_cur_ptr (iter), mb_len (mbui_cur (iter)));
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
185 p += mb_len (mbui_cur (iter));
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
186 }
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
187 }
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
188 else
33419
4c735bd27df8 New module 'regex-quote'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
189 {
34101
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
190 const char *iter;
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
191
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
192 for (iter = string; *iter != '\0'; iter++)
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
193 {
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
194 if (strchr (special, *iter))
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
195 *p++ = '\\';
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
196 *p++ = *iter++;
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
197 }
33419
4c735bd27df8 New module 'regex-quote'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
198 }
34101
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
199 if (spec->anchored)
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
200 *p++ = '$';
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
201
33419
4c735bd27df8 New module 'regex-quote'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
202 return p;
4c735bd27df8 New module 'regex-quote'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
203 }
4c735bd27df8 New module 'regex-quote'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
204
4c735bd27df8 New module 'regex-quote'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
205 char *
34101
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
206 regex_quote (const char *string, const struct regex_quote_spec *spec)
33419
4c735bd27df8 New module 'regex-quote'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
207 {
34101
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
208 size_t length = regex_quote_length (string, spec);
33419
4c735bd27df8 New module 'regex-quote'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
209 char *result = XNMALLOC (length + 1, char);
4c735bd27df8 New module 'regex-quote'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
210 char *p;
4c735bd27df8 New module 'regex-quote'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
211
4c735bd27df8 New module 'regex-quote'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
212 p = result;
34101
354aa24c34a4 regex-quote: New API.
Bruno Haible <bruno@clisp.org>
parents: 34100
diff changeset
213 p = regex_quote_copy (p, string, spec);
33419
4c735bd27df8 New module 'regex-quote'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
214 *p = '\0';
4c735bd27df8 New module 'regex-quote'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
215 return result;
4c735bd27df8 New module 'regex-quote'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
216 }