Fossil SCM

Add the glob_multi_match() interface that allows checking against a comma-separated list of GLOB patterns without having to compile the list first.

drh 2024-07-29 12:45 trunk
Commit dc86831179acbe3a4ce9ef6ddb642375eccfa4a8f25819ff6611a8cc85a8402c
2 files changed +59 -1 +4 -13
+59 -1
--- src/glob.c
+++ src/glob.c
@@ -138,10 +138,61 @@
138138
z[i] = 0;
139139
z += i+1;
140140
}
141141
return p;
142142
}
143
+
144
+/*
145
+** Return TRUE if zString matches any of the GLOB patterns in the
146
+** string zPatternList.
147
+**
148
+** This is a like calling glob_create(), glob_match(), and glob_free()
149
+** in sequence, without the overhead of creating the reusable Glob object.
150
+** Use this for one-time matches against a comma-separated GLOB list.
151
+*/
152
+int glob_multi_match(const char *zPatternList, const char *zString){
153
+ int i; /* Loop counters */
154
+ int n = 0; /* Pattern counter */
155
+ const char *z; /* Current GLOB pattern */
156
+ char delimiter; /* '\'' or '\"' or 0 */
157
+ int rc; /* Result of comparison */
158
+ char zPat[100]; /* Copy of just the current pattern */
159
+
160
+ if( zPatternList==0 ) return 0;
161
+ z = zPatternList;
162
+ while( z[0] ){
163
+ while( fossil_isspace(z[0]) || z[0]==',' ){
164
+ z++; /* Skip leading commas, spaces, and newlines */
165
+ }
166
+ if( z[0]==0 ) break;
167
+ if( z[0]=='\'' || z[0]=='"' ){
168
+ delimiter = z[0];
169
+ z++;
170
+ }else{
171
+ delimiter = ',';
172
+ }
173
+ /* Find the next delimiter (or the end of the string). */
174
+ for(i=0; z[i] && z[i]!=delimiter &&
175
+ !(delimiter==',' && fossil_isspace(z[i])); i++){
176
+ /* keep looking for the end of the glob pattern */
177
+ }
178
+ n++;
179
+ if( i>sizeof(zPat)-1 ){
180
+ char *zMPat = fossil_strndup(z, i);
181
+ rc = sqlite3_strglob(zMPat, zString);
182
+ fossil_free(zMPat);
183
+ }else{
184
+ memcpy(zPat, z, i);
185
+ zPat[i] = 0;
186
+ rc = sqlite3_strglob(zPat, zString);
187
+ }
188
+ if( rc==0 ) return n;
189
+ if( z[i]==0 ) break;
190
+ z += i+1;
191
+ }
192
+ return 0;
193
+}
143194
144195
/*
145196
** Return true (non-zero) if zString matches any of the patterns in
146197
** the Glob. The value returned is actually a 1-based index of the pattern
147198
** that matched. Return 0 if none of the patterns match zString.
@@ -210,10 +261,14 @@
210261
** the PATTERN.
211262
**
212263
** If PATTERN begins with "@" the rest of the pattern is understood
213264
** to be a setting name (such as binary-glob, crln-glob, or encoding-glob)
214265
** and the value of that setting is used as the actually glob pattern.
266
+**
267
+** The output consists of two numbers and a STRING. The first number
268
+** is the result of glob_match() and the second is the result of
269
+** glob_multi_match().
215270
*/
216271
void glob_test_cmd(void){
217272
Glob *pGlob;
218273
int i;
219274
char *zPattern;
@@ -229,9 +284,12 @@
229284
pGlob = glob_create(zPattern);
230285
for(i=0; i<pGlob->nPattern; i++){
231286
fossil_print("pattern[%d] = [%s]\n", i, pGlob->azPattern[i]);
232287
}
233288
for(i=3; i<g.argc; i++){
234
- fossil_print("%d %s\n", glob_match(pGlob, g.argv[i]), g.argv[i]);
289
+ fossil_print("%d %d %s\n",
290
+ glob_match(pGlob, g.argv[i]),
291
+ glob_multi_match(zPattern, g.argv[i]),
292
+ g.argv[i]);
235293
}
236294
glob_free(pGlob);
237295
}
238296
--- src/glob.c
+++ src/glob.c
@@ -138,10 +138,61 @@
138 z[i] = 0;
139 z += i+1;
140 }
141 return p;
142 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
143
144 /*
145 ** Return true (non-zero) if zString matches any of the patterns in
146 ** the Glob. The value returned is actually a 1-based index of the pattern
147 ** that matched. Return 0 if none of the patterns match zString.
@@ -210,10 +261,14 @@
210 ** the PATTERN.
211 **
212 ** If PATTERN begins with "@" the rest of the pattern is understood
213 ** to be a setting name (such as binary-glob, crln-glob, or encoding-glob)
214 ** and the value of that setting is used as the actually glob pattern.
 
 
 
 
215 */
216 void glob_test_cmd(void){
217 Glob *pGlob;
218 int i;
219 char *zPattern;
@@ -229,9 +284,12 @@
229 pGlob = glob_create(zPattern);
230 for(i=0; i<pGlob->nPattern; i++){
231 fossil_print("pattern[%d] = [%s]\n", i, pGlob->azPattern[i]);
232 }
233 for(i=3; i<g.argc; i++){
234 fossil_print("%d %s\n", glob_match(pGlob, g.argv[i]), g.argv[i]);
 
 
 
235 }
236 glob_free(pGlob);
237 }
238
--- src/glob.c
+++ src/glob.c
@@ -138,10 +138,61 @@
138 z[i] = 0;
139 z += i+1;
140 }
141 return p;
142 }
143
144 /*
145 ** Return TRUE if zString matches any of the GLOB patterns in the
146 ** string zPatternList.
147 **
148 ** This is a like calling glob_create(), glob_match(), and glob_free()
149 ** in sequence, without the overhead of creating the reusable Glob object.
150 ** Use this for one-time matches against a comma-separated GLOB list.
151 */
152 int glob_multi_match(const char *zPatternList, const char *zString){
153 int i; /* Loop counters */
154 int n = 0; /* Pattern counter */
155 const char *z; /* Current GLOB pattern */
156 char delimiter; /* '\'' or '\"' or 0 */
157 int rc; /* Result of comparison */
158 char zPat[100]; /* Copy of just the current pattern */
159
160 if( zPatternList==0 ) return 0;
161 z = zPatternList;
162 while( z[0] ){
163 while( fossil_isspace(z[0]) || z[0]==',' ){
164 z++; /* Skip leading commas, spaces, and newlines */
165 }
166 if( z[0]==0 ) break;
167 if( z[0]=='\'' || z[0]=='"' ){
168 delimiter = z[0];
169 z++;
170 }else{
171 delimiter = ',';
172 }
173 /* Find the next delimiter (or the end of the string). */
174 for(i=0; z[i] && z[i]!=delimiter &&
175 !(delimiter==',' && fossil_isspace(z[i])); i++){
176 /* keep looking for the end of the glob pattern */
177 }
178 n++;
179 if( i>sizeof(zPat)-1 ){
180 char *zMPat = fossil_strndup(z, i);
181 rc = sqlite3_strglob(zMPat, zString);
182 fossil_free(zMPat);
183 }else{
184 memcpy(zPat, z, i);
185 zPat[i] = 0;
186 rc = sqlite3_strglob(zPat, zString);
187 }
188 if( rc==0 ) return n;
189 if( z[i]==0 ) break;
190 z += i+1;
191 }
192 return 0;
193 }
194
195 /*
196 ** Return true (non-zero) if zString matches any of the patterns in
197 ** the Glob. The value returned is actually a 1-based index of the pattern
198 ** that matched. Return 0 if none of the patterns match zString.
@@ -210,10 +261,14 @@
261 ** the PATTERN.
262 **
263 ** If PATTERN begins with "@" the rest of the pattern is understood
264 ** to be a setting name (such as binary-glob, crln-glob, or encoding-glob)
265 ** and the value of that setting is used as the actually glob pattern.
266 **
267 ** The output consists of two numbers and a STRING. The first number
268 ** is the result of glob_match() and the second is the result of
269 ** glob_multi_match().
270 */
271 void glob_test_cmd(void){
272 Glob *pGlob;
273 int i;
274 char *zPattern;
@@ -229,9 +284,12 @@
284 pGlob = glob_create(zPattern);
285 for(i=0; i<pGlob->nPattern; i++){
286 fossil_print("pattern[%d] = [%s]\n", i, pGlob->azPattern[i]);
287 }
288 for(i=3; i<g.argc; i++){
289 fossil_print("%d %d %s\n",
290 glob_match(pGlob, g.argv[i]),
291 glob_multi_match(zPattern, g.argv[i]),
292 g.argv[i]);
293 }
294 glob_free(pGlob);
295 }
296
+4 -13
--- src/login.c
+++ src/login.c
@@ -1289,21 +1289,18 @@
12891289
** an empty string.
12901290
*/
12911291
void login_restrict_robot_access(void){
12921292
const char *zReferer;
12931293
const char *zGlob;
1294
- Glob *pGlob;
12951294
int isMatch = 1;
12961295
if( g.zLogin!=0 ) return;
12971296
zReferer = P("HTTP_REFERER");
12981297
if( zReferer && zReferer[0]!=0 ) return;
12991298
zGlob = db_get("robot-restrict",0);
13001299
if( zGlob==0 || zGlob[0]==0 ) return;
13011300
if( cgi_qp_count()<1 ) return;
1302
- pGlob = glob_create(zGlob);
1303
- isMatch = glob_match(pGlob, g.zPath);
1304
- glob_free(pGlob);
1301
+ isMatch = glob_multi_match(zGlob, g.zPath);
13051302
if( !isMatch ) return;
13061303
13071304
/* If we reach this point, it means we have a situation where we
13081305
** want to restrict the activity of a robot.
13091306
*/
@@ -1559,17 +1556,15 @@
15591556
** one of the globs in public-pages, then also add in all default-perms
15601557
** permissions.
15611558
*/
15621559
zPublicPages = db_get("public-pages",0);
15631560
if( zPublicPages!=0 ){
1564
- Glob *pGlob = glob_create(zPublicPages);
15651561
const char *zUri = PD("REQUEST_URI","");
15661562
zUri += (int)strlen(g.zTop);
1567
- if( glob_match(pGlob, zUri) ){
1563
+ if( glob_multi_match(zPublicPages, zUri) ){
15681564
login_set_capabilities(db_get("default-perms", "u"), 0);
15691565
}
1570
- glob_free(pGlob);
15711566
}
15721567
return g.zLogin!=0;
15731568
}
15741569
15751570
/*
@@ -1967,23 +1962,19 @@
19671962
** it is a comma-separated list of GLOB patterns for email addresses
19681963
** that are authorized to self-register.
19691964
*/
19701965
int authorized_subscription_email(const char *zEAddr){
19711966
char *zGlob = db_get("auth-sub-email",0);
1972
- Glob *pGlob;
19731967
char *zAddr;
19741968
int rc;
19751969
19761970
if( zGlob==0 || zGlob[0]==0 ) return 1;
19771971
zGlob = fossil_strtolwr(fossil_strdup(zGlob));
1978
- pGlob = glob_create(zGlob);
1972
+ zAddr = fossil_strtolwr(fossil_strdup(zEAddr));
1973
+ rc = glob_multi_match(zGlob, zAddr);
19791974
fossil_free(zGlob);
1980
-
1981
- zAddr = fossil_strtolwr(fossil_strdup(zEAddr));
1982
- rc = glob_match(pGlob, zAddr);
19831975
fossil_free(zAddr);
1984
- glob_free(pGlob);
19851976
return rc!=0;
19861977
}
19871978
19881979
/*
19891980
** WEBPAGE: register
19901981
--- src/login.c
+++ src/login.c
@@ -1289,21 +1289,18 @@
1289 ** an empty string.
1290 */
1291 void login_restrict_robot_access(void){
1292 const char *zReferer;
1293 const char *zGlob;
1294 Glob *pGlob;
1295 int isMatch = 1;
1296 if( g.zLogin!=0 ) return;
1297 zReferer = P("HTTP_REFERER");
1298 if( zReferer && zReferer[0]!=0 ) return;
1299 zGlob = db_get("robot-restrict",0);
1300 if( zGlob==0 || zGlob[0]==0 ) return;
1301 if( cgi_qp_count()<1 ) return;
1302 pGlob = glob_create(zGlob);
1303 isMatch = glob_match(pGlob, g.zPath);
1304 glob_free(pGlob);
1305 if( !isMatch ) return;
1306
1307 /* If we reach this point, it means we have a situation where we
1308 ** want to restrict the activity of a robot.
1309 */
@@ -1559,17 +1556,15 @@
1559 ** one of the globs in public-pages, then also add in all default-perms
1560 ** permissions.
1561 */
1562 zPublicPages = db_get("public-pages",0);
1563 if( zPublicPages!=0 ){
1564 Glob *pGlob = glob_create(zPublicPages);
1565 const char *zUri = PD("REQUEST_URI","");
1566 zUri += (int)strlen(g.zTop);
1567 if( glob_match(pGlob, zUri) ){
1568 login_set_capabilities(db_get("default-perms", "u"), 0);
1569 }
1570 glob_free(pGlob);
1571 }
1572 return g.zLogin!=0;
1573 }
1574
1575 /*
@@ -1967,23 +1962,19 @@
1967 ** it is a comma-separated list of GLOB patterns for email addresses
1968 ** that are authorized to self-register.
1969 */
1970 int authorized_subscription_email(const char *zEAddr){
1971 char *zGlob = db_get("auth-sub-email",0);
1972 Glob *pGlob;
1973 char *zAddr;
1974 int rc;
1975
1976 if( zGlob==0 || zGlob[0]==0 ) return 1;
1977 zGlob = fossil_strtolwr(fossil_strdup(zGlob));
1978 pGlob = glob_create(zGlob);
 
1979 fossil_free(zGlob);
1980
1981 zAddr = fossil_strtolwr(fossil_strdup(zEAddr));
1982 rc = glob_match(pGlob, zAddr);
1983 fossil_free(zAddr);
1984 glob_free(pGlob);
1985 return rc!=0;
1986 }
1987
1988 /*
1989 ** WEBPAGE: register
1990
--- src/login.c
+++ src/login.c
@@ -1289,21 +1289,18 @@
1289 ** an empty string.
1290 */
1291 void login_restrict_robot_access(void){
1292 const char *zReferer;
1293 const char *zGlob;
 
1294 int isMatch = 1;
1295 if( g.zLogin!=0 ) return;
1296 zReferer = P("HTTP_REFERER");
1297 if( zReferer && zReferer[0]!=0 ) return;
1298 zGlob = db_get("robot-restrict",0);
1299 if( zGlob==0 || zGlob[0]==0 ) return;
1300 if( cgi_qp_count()<1 ) return;
1301 isMatch = glob_multi_match(zGlob, g.zPath);
 
 
1302 if( !isMatch ) return;
1303
1304 /* If we reach this point, it means we have a situation where we
1305 ** want to restrict the activity of a robot.
1306 */
@@ -1559,17 +1556,15 @@
1556 ** one of the globs in public-pages, then also add in all default-perms
1557 ** permissions.
1558 */
1559 zPublicPages = db_get("public-pages",0);
1560 if( zPublicPages!=0 ){
 
1561 const char *zUri = PD("REQUEST_URI","");
1562 zUri += (int)strlen(g.zTop);
1563 if( glob_multi_match(zPublicPages, zUri) ){
1564 login_set_capabilities(db_get("default-perms", "u"), 0);
1565 }
 
1566 }
1567 return g.zLogin!=0;
1568 }
1569
1570 /*
@@ -1967,23 +1962,19 @@
1962 ** it is a comma-separated list of GLOB patterns for email addresses
1963 ** that are authorized to self-register.
1964 */
1965 int authorized_subscription_email(const char *zEAddr){
1966 char *zGlob = db_get("auth-sub-email",0);
 
1967 char *zAddr;
1968 int rc;
1969
1970 if( zGlob==0 || zGlob[0]==0 ) return 1;
1971 zGlob = fossil_strtolwr(fossil_strdup(zGlob));
1972 zAddr = fossil_strtolwr(fossil_strdup(zEAddr));
1973 rc = glob_multi_match(zGlob, zAddr);
1974 fossil_free(zGlob);
 
 
 
1975 fossil_free(zAddr);
 
1976 return rc!=0;
1977 }
1978
1979 /*
1980 ** WEBPAGE: register
1981

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button