@@ -272,33 +272,36 @@ get_wildcard_part(const char *str, int lenstr,
272
272
const char * beginword = str ;
273
273
const char * endword ;
274
274
char * s = buf ;
275
- bool in_wildcard_meta = false;
275
+ bool in_leading_wildcard_meta = false;
276
+ bool in_trailing_wildcard_meta = false;
276
277
bool in_escape = false;
277
278
int clen ;
278
279
279
280
/*
280
- * Find the first word character remembering whether last character was
281
- * wildcard meta-character.
281
+ * Find the first word character, remembering whether preceding character
282
+ * was wildcard meta-character. Note that the in_escape state persists
283
+ * from this loop to the next one, since we may exit at a word character
284
+ * that is in_escape.
282
285
*/
283
286
while (beginword - str < lenstr )
284
287
{
285
288
if (in_escape )
286
289
{
287
- in_escape = false;
288
- in_wildcard_meta = false;
289
290
if (iswordchr (beginword ))
290
291
break ;
292
+ in_escape = false;
293
+ in_leading_wildcard_meta = false;
291
294
}
292
295
else
293
296
{
294
297
if (ISESCAPECHAR (beginword ))
295
298
in_escape = true;
296
299
else if (ISWILDCARDCHAR (beginword ))
297
- in_wildcard_meta = true;
300
+ in_leading_wildcard_meta = true;
298
301
else if (iswordchr (beginword ))
299
302
break ;
300
303
else
301
- in_wildcard_meta = false;
304
+ in_leading_wildcard_meta = false;
302
305
}
303
306
beginword += pg_mblen (beginword );
304
307
}
@@ -310,11 +313,11 @@ get_wildcard_part(const char *str, int lenstr,
310
313
return NULL ;
311
314
312
315
/*
313
- * Add left padding spaces if last character wasn't wildcard
316
+ * Add left padding spaces if preceding character wasn't wildcard
314
317
* meta-character.
315
318
*/
316
319
* charlen = 0 ;
317
- if (!in_wildcard_meta )
320
+ if (!in_leading_wildcard_meta )
318
321
{
319
322
if (LPADDING > 0 )
320
323
{
@@ -333,31 +336,37 @@ get_wildcard_part(const char *str, int lenstr,
333
336
* string boundary. Strip escapes during copy.
334
337
*/
335
338
endword = beginword ;
336
- in_wildcard_meta = false;
337
- in_escape = false;
338
339
while (endword - str < lenstr )
339
340
{
340
341
clen = pg_mblen (endword );
341
342
if (in_escape )
342
343
{
343
- in_escape = false;
344
- in_wildcard_meta = false;
345
344
if (iswordchr (endword ))
346
345
{
347
346
memcpy (s , endword , clen );
348
347
(* charlen )++ ;
349
348
s += clen ;
350
349
}
351
350
else
351
+ {
352
+ /*
353
+ * Back up endword to the escape character when stopping at
354
+ * an escaped char, so that subsequent get_wildcard_part will
355
+ * restart from the escape character. We assume here that
356
+ * escape chars are single-byte.
357
+ */
358
+ endword -- ;
352
359
break ;
360
+ }
361
+ in_escape = false;
353
362
}
354
363
else
355
364
{
356
365
if (ISESCAPECHAR (endword ))
357
366
in_escape = true;
358
367
else if (ISWILDCARDCHAR (endword ))
359
368
{
360
- in_wildcard_meta = true;
369
+ in_trailing_wildcard_meta = true;
361
370
break ;
362
371
}
363
372
else if (iswordchr (endword ))
@@ -367,19 +376,16 @@ get_wildcard_part(const char *str, int lenstr,
367
376
s += clen ;
368
377
}
369
378
else
370
- {
371
- in_wildcard_meta = false;
372
379
break ;
373
- }
374
380
}
375
381
endword += clen ;
376
382
}
377
383
378
384
/*
379
- * Add right padding spaces if last character wasn 't wildcard
385
+ * Add right padding spaces if next character isn 't wildcard
380
386
* meta-character.
381
387
*/
382
- if (!in_wildcard_meta )
388
+ if (!in_trailing_wildcard_meta )
383
389
{
384
390
if (RPADDING > 0 )
385
391
{
0 commit comments