-
Notifications
You must be signed in to change notification settings - Fork 22
/
Copy pathpcre.c
9195 lines (7595 loc) · 276 KB
/
pcre.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/*************************************************
* Perl-Compatible Regular Expressions *
*************************************************/
/*
This is a library of functions to support regular expressions whose syntax
and semantics are as close as possible to those of the Perl 5 language. See
the file Tech.Notes for some information on the internals.
Written by: Philip Hazel <[email protected]>
Copyright (c) 1997-2004 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the University of Cambridge nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
-----------------------------------------------------------------------------
*/
/* Define DEBUG to get debugging output on stdout. */
/* #define DEBUG */
/* Use a macro for debugging printing, 'cause that eliminates the use of #ifdef
inline, and there are *still* stupid compilers about that don't like indented
pre-processor statements. I suppose it's only been 10 years... */
#ifdef DEBUG
#define DPRINTF(p) printf p
#else
#define DPRINTF(p) /*nothing*/
#endif
/* Include the internals header, which itself includes "config.h", the Standard
C headers, and the external pcre header. */
#include "pcre-internal.h"
/* If Unicode Property support is wanted, include a private copy of the
function that does it, and the table that translates names to numbers. */
#ifdef SUPPORT_UCP
#include "ucp.c"
#include "ucptypetable.c"
#endif
/* Maximum number of items on the nested bracket stacks at compile time. This
applies to the nesting of all kinds of parentheses. It does not limit
un-nested, non-capturing parentheses. This number can be made bigger if
necessary - it is used to dimension one int and one unsigned char vector at
compile time. */
#define BRASTACK_SIZE 200
/* Maximum number of ints of offset to save on the stack for recursive calls.
If the offset vector is bigger, malloc is used. This should be a multiple of 3,
because the offset vector is always a multiple of 3 long. */
#define REC_STACK_SAVE_MAX 30
/* The maximum remaining length of subject we are prepared to search for a
req_byte match. */
#define REQ_BYTE_MAX 1000
/* Table of sizes for the fixed-length opcodes. It's defined in a macro so that
the definition is next to the definition of the opcodes in internal.h. */
static const uschar OP_lengths[] = { OP_LENGTHS };
/* Min and max values for the common repeats; for the maxima, 0 => infinity */
static const char rep_min[] = { 0, 0, 1, 1, 0, 0 };
static const char rep_max[] = { 0, 0, 0, 0, 1, 1 };
/* Table for handling escaped characters in the range '0'-'z'. Positive returns
are simple data values; negative values are for special things like \d and so
on. Zero means further processing is needed (for things like \x), or the escape
is invalid. */
#if !EBCDIC /* This is the "normal" table for ASCII systems */
static const short int escapes[] = {
0, 0, 0, 0, 0, 0, 0, 0, /* 0 - 7 */
0, 0, ':', ';', '<', '=', '>', '?', /* 8 - ? */
'@', -ESC_A, -ESC_B, -ESC_C, -ESC_D, -ESC_E, 0, -ESC_G, /* @ - G */
0, 0, 0, 0, 0, 0, 0, 0, /* H - O */
-ESC_P, -ESC_Q, 0, -ESC_S, 0, 0, 0, -ESC_W, /* P - W */
-ESC_X, 0, -ESC_Z, '[', '\\', ']', '^', '_', /* X - _ */
'`', 7, -ESC_b, 0, -ESC_d, ESC_e, ESC_f, 0, /* ` - g */
0, 0, 0, 0, 0, 0, ESC_n, 0, /* h - o */
-ESC_p, 0, ESC_r, -ESC_s, ESC_tee, 0, 0, -ESC_w, /* p - w */
0, 0, -ESC_z /* x - z */
};
#else /* This is the "abnormal" table for EBCDIC systems */
static const short int escapes[] = {
/* 48 */ 0, 0, 0, '.', '<', '(', '+', '|',
/* 50 */ '&', 0, 0, 0, 0, 0, 0, 0,
/* 58 */ 0, 0, '!', '$', '*', ')', ';', '~',
/* 60 */ '-', '/', 0, 0, 0, 0, 0, 0,
/* 68 */ 0, 0, '|', ',', '%', '_', '>', '?',
/* 70 */ 0, 0, 0, 0, 0, 0, 0, 0,
/* 78 */ 0, '`', ':', '#', '@', '\'', '=', '"',
/* 80 */ 0, 7, -ESC_b, 0, -ESC_d, ESC_e, ESC_f, 0,
/* 88 */ 0, 0, 0, '{', 0, 0, 0, 0,
/* 90 */ 0, 0, 0, 'l', 0, ESC_n, 0, -ESC_p,
/* 98 */ 0, ESC_r, 0, '}', 0, 0, 0, 0,
/* A0 */ 0, '~', -ESC_s, ESC_tee, 0, 0, -ESC_w, 0,
/* A8 */ 0,-ESC_z, 0, 0, 0, '[', 0, 0,
/* B0 */ 0, 0, 0, 0, 0, 0, 0, 0,
/* B8 */ 0, 0, 0, 0, 0, ']', '=', '-',
/* C0 */ '{',-ESC_A, -ESC_B, -ESC_C, -ESC_D,-ESC_E, 0, -ESC_G,
/* C8 */ 0, 0, 0, 0, 0, 0, 0, 0,
/* D0 */ '}', 0, 0, 0, 0, 0, 0, -ESC_P,
/* D8 */-ESC_Q, 0, 0, 0, 0, 0, 0, 0,
/* E0 */ '\\', 0, -ESC_S, 0, 0, 0, -ESC_W, -ESC_X,
/* E8 */ 0,-ESC_Z, 0, 0, 0, 0, 0, 0,
/* F0 */ 0, 0, 0, 0, 0, 0, 0, 0,
/* F8 */ 0, 0, 0, 0, 0, 0, 0, 0
};
#endif
/* Tables of names of POSIX character classes and their lengths. The list is
terminated by a zero length entry. The first three must be alpha, upper, lower,
as this is assumed for handling case independence. */
static const char *const posix_names[] = {
"alpha", "lower", "upper",
"alnum", "ascii", "blank", "cntrl", "digit", "graph",
"print", "punct", "space", "word", "xdigit" };
static const uschar posix_name_lengths[] = {
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 6, 0 };
/* Table of class bit maps for each POSIX class; up to three may be combined
to form the class. The table for [:blank:] is dynamically modified to remove
the vertical space characters. */
static const int posix_class_maps[] = {
cbit_lower, cbit_upper, -1, /* alpha */
cbit_lower, -1, -1, /* lower */
cbit_upper, -1, -1, /* upper */
cbit_digit, cbit_lower, cbit_upper, /* alnum */
cbit_print, cbit_cntrl, -1, /* ascii */
cbit_space, -1, -1, /* blank - a GNU extension */
cbit_cntrl, -1, -1, /* cntrl */
cbit_digit, -1, -1, /* digit */
cbit_graph, -1, -1, /* graph */
cbit_print, -1, -1, /* print */
cbit_punct, -1, -1, /* punct */
cbit_space, -1, -1, /* space */
cbit_word, -1, -1, /* word - a Perl extension */
cbit_xdigit,-1, -1 /* xdigit */
};
/* Table to identify digits and hex digits. This is used when compiling
patterns. Note that the tables in chartables are dependent on the locale, and
may mark arbitrary characters as digits - but the PCRE compiling code expects
to handle only 0-9, a-z, and A-Z as digits when compiling. That is why we have
a private table here. It costs 256 bytes, but it is a lot faster than doing
character value tests (at least in some simple cases I timed), and in some
applications one wants PCRE to compile efficiently as well as match
efficiently.
For convenience, we use the same bit definitions as in chartables:
0x04 decimal digit
0x08 hexadecimal digit
Then we can use ctype_digit and ctype_xdigit in the code. */
#if !EBCDIC /* This is the "normal" case, for ASCII systems */
static const unsigned char digitab[] =
{
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0- 7 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 8- 15 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 16- 23 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 24- 31 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* - ' */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* ( - / */
0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c, /* 0 - 7 */
0x0c,0x0c,0x00,0x00,0x00,0x00,0x00,0x00, /* 8 - ? */
0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x00, /* @ - G */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* H - O */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* P - W */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* X - _ */
0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x00, /* ` - g */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* h - o */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p - w */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* x -127 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 128-135 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 136-143 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 144-151 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 152-159 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 160-167 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 168-175 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 176-183 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 184-191 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 192-199 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 200-207 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 208-215 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 216-223 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 224-231 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 232-239 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 240-247 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};/* 248-255 */
#else /* This is the "abnormal" case, for EBCDIC systems */
static const unsigned char digitab[] =
{
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0- 7 0 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 8- 15 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 16- 23 10 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 24- 31 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 32- 39 20 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 40- 47 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 48- 55 30 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 56- 63 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* - 71 40 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 72- | */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* & - 87 50 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 88- ¬ */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* - -103 60 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 104- ? */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 112-119 70 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 120- " */
0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x00, /* 128- g 80 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* h -143 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 144- p 90 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* q -159 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 160- x A0 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* y -175 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* ^ -183 B0 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 184-191 */
0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x00, /* { - G C0 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* H -207 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* } - P D0 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* Q -223 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* \ - X E0 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* Y -239 */
0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c, /* 0 - 7 F0 */
0x0c,0x0c,0x00,0x00,0x00,0x00,0x00,0x00};/* 8 -255 */
static const unsigned char ebcdic_chartab[] = { /* chartable partial dup */
0x80,0x00,0x00,0x00,0x00,0x01,0x00,0x00, /* 0- 7 */
0x00,0x00,0x00,0x00,0x01,0x01,0x00,0x00, /* 8- 15 */
0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00, /* 16- 23 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 24- 31 */
0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00, /* 32- 39 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 40- 47 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 48- 55 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 56- 63 */
0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* - 71 */
0x00,0x00,0x00,0x80,0x00,0x80,0x80,0x80, /* 72- | */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* & - 87 */
0x00,0x00,0x00,0x80,0x80,0x80,0x00,0x00, /* 88- ¬ */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* - -103 */
0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x80, /* 104- ? */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 112-119 */
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 120- " */
0x00,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /* 128- g */
0x12,0x12,0x00,0x00,0x00,0x00,0x00,0x00, /* h -143 */
0x00,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* 144- p */
0x12,0x12,0x00,0x00,0x00,0x00,0x00,0x00, /* q -159 */
0x00,0x00,0x12,0x12,0x12,0x12,0x12,0x12, /* 160- x */
0x12,0x12,0x00,0x00,0x00,0x00,0x00,0x00, /* y -175 */
0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* ^ -183 */
0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00, /* 184-191 */
0x80,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /* { - G */
0x12,0x12,0x00,0x00,0x00,0x00,0x00,0x00, /* H -207 */
0x00,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* } - P */
0x12,0x12,0x00,0x00,0x00,0x00,0x00,0x00, /* Q -223 */
0x00,0x00,0x12,0x12,0x12,0x12,0x12,0x12, /* \ - X */
0x12,0x12,0x00,0x00,0x00,0x00,0x00,0x00, /* Y -239 */
0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c, /* 0 - 7 */
0x1c,0x1c,0x00,0x00,0x00,0x00,0x00,0x00};/* 8 -255 */
#endif
/* Definition to allow mutual recursion */
static BOOL
compile_regex(int, int, int *, uschar **, const uschar **, const char **,
BOOL, int, int *, int *, branch_chain *, compile_data *);
/* Structure for building a chain of data that actually lives on the
stack, for holding the values of the subject pointer at the start of each
subpattern, so as to detect when an empty string has been matched by a
subpattern - to break infinite loops. When NO_RECURSE is set, these blocks
are on the heap, not on the stack. */
typedef struct eptrblock {
struct eptrblock *epb_prev;
const uschar *epb_saved_eptr;
} eptrblock;
/* Flag bits for the match() function */
#define match_condassert 0x01 /* Called to check a condition assertion */
#define match_isgroup 0x02 /* Set if start of bracketed group */
/* Non-error returns from the match() function. Error returns are externally
defined PCRE_ERROR_xxx codes, which are all negative. */
#define MATCH_MATCH 1
#define MATCH_NOMATCH 0
/*************************************************
* Global variables *
*************************************************/
/* PCRE is thread-clean and doesn't use any global variables in the normal
sense. However, it calls memory allocation and free functions via the four
indirections below, and it can optionally do callouts. These values can be
changed by the caller, but are shared between all threads. However, when
compiling for Virtual Pascal, things are done differently (see pcre.in). */
#ifndef VPCOMPAT
#ifdef __cplusplus
extern "C" void *(*pcre_malloc)(size_t) = malloc;
extern "C" void (*pcre_free)(void *) = free;
extern "C" void *(*pcre_stack_malloc)(size_t) = malloc;
extern "C" void (*pcre_stack_free)(void *) = free;
extern "C" int (*pcre_callout)(pcre_callout_block *) = NULL;
#else
void *(*pcre_malloc)(size_t) = malloc;
void (*pcre_free)(void *) = free;
void *(*pcre_stack_malloc)(size_t) = malloc;
void (*pcre_stack_free)(void *) = free;
int (*pcre_callout)(pcre_callout_block *) = NULL;
#endif
#endif
/*************************************************
* Macros and tables for character handling *
*************************************************/
/* When UTF-8 encoding is being used, a character is no longer just a single
byte. The macros for character handling generate simple sequences when used in
byte-mode, and more complicated ones for UTF-8 characters. */
#ifndef SUPPORT_UTF8
#define GETCHAR(c, eptr) c = *eptr;
#define GETCHARINC(c, eptr) c = *eptr++;
#define GETCHARINCTEST(c, eptr) c = *eptr++;
#define GETCHARLEN(c, eptr, len) c = *eptr;
#define BACKCHAR(eptr)
#else /* SUPPORT_UTF8 */
/* Get the next UTF-8 character, not advancing the pointer. This is called when
we know we are in UTF-8 mode. */
#define GETCHAR(c, eptr) \
c = *eptr; \
if ((c & 0xc0) == 0xc0) \
{ \
int gcii; \
int gcaa = utf8_table4[c & 0x3f]; /* Number of additional bytes */ \
int gcss = 6*gcaa; \
c = (c & utf8_table3[gcaa]) << gcss; \
for (gcii = 1; gcii <= gcaa; gcii++) \
{ \
gcss -= 6; \
c |= (eptr[gcii] & 0x3f) << gcss; \
} \
}
/* Get the next UTF-8 character, advancing the pointer. This is called when we
know we are in UTF-8 mode. */
#define GETCHARINC(c, eptr) \
c = *eptr++; \
if ((c & 0xc0) == 0xc0) \
{ \
int gcaa = utf8_table4[c & 0x3f]; /* Number of additional bytes */ \
int gcss = 6*gcaa; \
c = (c & utf8_table3[gcaa]) << gcss; \
while (gcaa-- > 0) \
{ \
gcss -= 6; \
c |= (*eptr++ & 0x3f) << gcss; \
} \
}
/* Get the next character, testing for UTF-8 mode, and advancing the pointer */
#define GETCHARINCTEST(c, eptr) \
c = *eptr++; \
if (md->utf8 && (c & 0xc0) == 0xc0) \
{ \
int gcaa = utf8_table4[c & 0x3f]; /* Number of additional bytes */ \
int gcss = 6*gcaa; \
c = (c & utf8_table3[gcaa]) << gcss; \
while (gcaa-- > 0) \
{ \
gcss -= 6; \
c |= (*eptr++ & 0x3f) << gcss; \
} \
}
/* Get the next UTF-8 character, not advancing the pointer, incrementing length
if there are extra bytes. This is called when we know we are in UTF-8 mode. */
#define GETCHARLEN(c, eptr, len) \
c = *eptr; \
if ((c & 0xc0) == 0xc0) \
{ \
int gcii; \
int gcaa = utf8_table4[c & 0x3f]; /* Number of additional bytes */ \
int gcss = 6*gcaa; \
c = (c & utf8_table3[gcaa]) << gcss; \
for (gcii = 1; gcii <= gcaa; gcii++) \
{ \
gcss -= 6; \
c |= (eptr[gcii] & 0x3f) << gcss; \
} \
len += gcaa; \
}
/* If the pointer is not at the start of a character, move it back until
it is. Called only in UTF-8 mode. */
#define BACKCHAR(eptr) while((*eptr & 0xc0) == 0x80) eptr--;
#endif
/*************************************************
* Default character tables *
*************************************************/
/* A default set of character tables is included in the PCRE binary. Its source
is built by the maketables auxiliary program, which uses the default C ctypes
functions, and put in the file chartables.c. These tables are used by PCRE
whenever the caller of pcre_compile() does not provide an alternate set of
tables. */
#include "pcre-chartables.c"
#ifdef SUPPORT_UTF8
/*************************************************
* Tables for UTF-8 support *
*************************************************/
/* These are the breakpoints for different numbers of bytes in a UTF-8
character. */
static const int utf8_table1[] =
{ 0x7f, 0x7ff, 0xffff, 0x1fffff, 0x3ffffff, 0x7fffffff};
/* These are the indicator bits and the mask for the data bits to set in the
first byte of a character, indexed by the number of additional bytes. */
static const int utf8_table2[] = { 0, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc};
static const int utf8_table3[] = { 0xff, 0x1f, 0x0f, 0x07, 0x03, 0x01};
/* Table of the number of extra characters, indexed by the first character
masked with 0x3f. The highest number for a valid UTF-8 character is in fact
0x3d. */
static const uschar utf8_table4[] = {
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5 };
/*************************************************
* Convert character value to UTF-8 *
*************************************************/
/* This function takes an integer value in the range 0 - 0x7fffffff
and encodes it as a UTF-8 character in 0 to 6 bytes.
Arguments:
cvalue the character value
buffer pointer to buffer for result - at least 6 bytes long
Returns: number of characters placed in the buffer
*/
static int
ord2utf8(int cvalue, uschar *buffer)
{
register int i, j;
for (i = 0; i < sizeof(utf8_table1)/sizeof(int); i++)
if (cvalue <= utf8_table1[i]) break;
buffer += i;
for (j = i; j > 0; j--)
{
*buffer-- = 0x80 | (cvalue & 0x3f);
cvalue >>= 6;
}
*buffer = utf8_table2[i] | cvalue;
return i + 1;
}
#endif
/*************************************************
* Print compiled regex *
*************************************************/
/* The code for doing this is held in a separate file that is also included in
pcretest.c. It defines a function called print_internals(). */
#ifdef DEBUG
#include "printint.c"
#endif
/*************************************************
* Return version string *
*************************************************/
#define STRING(a) # a
#define XSTRING(s) STRING(s)
EXPORT const char *
pcre_version(void)
{
return XSTRING(PCRE_MAJOR) "." XSTRING(PCRE_MINOR) " " XSTRING(PCRE_DATE);
}
/*************************************************
* Flip bytes in an integer *
*************************************************/
/* This function is called when the magic number in a regex doesn't match in
order to flip its bytes to see if we are dealing with a pattern that was
compiled on a host of different endianness. If so, this function is used to
flip other byte values.
Arguments:
value the number to flip
n the number of bytes to flip (assumed to be 2 or 4)
Returns: the flipped value
*/
static long int
byteflip(long int value, int n)
{
if (n == 2) return ((value & 0x00ff) << 8) | ((value & 0xff00) >> 8);
return ((value & 0x000000ff) << 24) |
((value & 0x0000ff00) << 8) |
((value & 0x00ff0000) >> 8) |
((value & 0xff000000) >> 24);
}
/*************************************************
* Test for a byte-flipped compiled regex *
*************************************************/
/* This function is called from pce_exec() and also from pcre_fullinfo(). Its
job is to test whether the regex is byte-flipped - that is, it was compiled on
a system of opposite endianness. The function is called only when the native
MAGIC_NUMBER test fails. If the regex is indeed flipped, we flip all the
relevant values into a different data block, and return it.
Arguments:
re points to the regex
study points to study data, or NULL
internal_re points to a new regex block
internal_study points to a new study block
Returns: the new block if is is indeed a byte-flipped regex
NULL if it is not
*/
static real_pcre *
try_flipped(const real_pcre *re, real_pcre *internal_re,
const pcre_study_data *study, pcre_study_data *internal_study)
{
if (byteflip(re->magic_number, sizeof(re->magic_number)) != MAGIC_NUMBER)
return NULL;
*internal_re = *re; /* To copy other fields */
internal_re->size = byteflip(re->size, sizeof(re->size));
internal_re->options = byteflip(re->options, sizeof(re->options));
internal_re->top_bracket = byteflip(re->top_bracket, sizeof(re->top_bracket));
internal_re->top_backref = byteflip(re->top_backref, sizeof(re->top_backref));
internal_re->first_byte = byteflip(re->first_byte, sizeof(re->first_byte));
internal_re->req_byte = byteflip(re->req_byte, sizeof(re->req_byte));
internal_re->name_table_offset = byteflip(re->name_table_offset,
sizeof(re->name_table_offset));
internal_re->name_entry_size = byteflip(re->name_entry_size,
sizeof(re->name_entry_size));
internal_re->name_count = byteflip(re->name_count, sizeof(re->name_count));
if (study != NULL)
{
*internal_study = *study; /* To copy other fields */
internal_study->size = byteflip(study->size, sizeof(study->size));
internal_study->options = byteflip(study->options, sizeof(study->options));
}
return internal_re;
}
/*************************************************
* (Obsolete) Return info about compiled pattern *
*************************************************/
/* This is the original "info" function. It picks potentially useful data out
of the private structure, but its interface was too rigid. It remains for
backwards compatibility. The public options are passed back in an int - though
the re->options field has been expanded to a long int, all the public options
at the low end of it, and so even on 16-bit systems this will still be OK.
Therefore, I haven't changed the API for pcre_info().
Arguments:
argument_re points to compiled code
optptr where to pass back the options
first_byte where to pass back the first character,
or -1 if multiline and all branches start ^,
or -2 otherwise
Returns: number of capturing subpatterns
or negative values on error
*/
EXPORT int
pcre_info(const pcre *argument_re, int *optptr, int *first_byte)
{
real_pcre internal_re;
const real_pcre *re = (const real_pcre *)argument_re;
if (re == NULL) return PCRE_ERROR_NULL;
if (re->magic_number != MAGIC_NUMBER)
{
re = try_flipped(re, &internal_re, NULL, NULL);
if (re == NULL) return PCRE_ERROR_BADMAGIC;
}
if (optptr != NULL) *optptr = (int)(re->options & PUBLIC_OPTIONS);
if (first_byte != NULL)
*first_byte = ((re->options & PCRE_FIRSTSET) != 0)? re->first_byte :
((re->options & PCRE_STARTLINE) != 0)? -1 : -2;
return re->top_bracket;
}
/*************************************************
* Return info about compiled pattern *
*************************************************/
/* This is a newer "info" function which has an extensible interface so
that additional items can be added compatibly.
Arguments:
argument_re points to compiled code
extra_data points extra data, or NULL
what what information is required
where where to put the information
Returns: 0 if data returned, negative on error
*/
EXPORT int
pcre_fullinfo(const pcre *argument_re, const pcre_extra *extra_data, int what,
void *where)
{
real_pcre internal_re;
pcre_study_data internal_study;
const real_pcre *re = (const real_pcre *)argument_re;
const pcre_study_data *study = NULL;
if (re == NULL || where == NULL) return PCRE_ERROR_NULL;
if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_STUDY_DATA) != 0)
study = (const pcre_study_data *)extra_data->study_data;
if (re->magic_number != MAGIC_NUMBER)
{
re = try_flipped(re, &internal_re, study, &internal_study);
if (re == NULL) return PCRE_ERROR_BADMAGIC;
if (study != NULL) study = &internal_study;
}
switch (what)
{
case PCRE_INFO_OPTIONS:
*((unsigned long int *)where) = re->options & PUBLIC_OPTIONS;
break;
case PCRE_INFO_SIZE:
*((size_t *)where) = re->size;
break;
case PCRE_INFO_STUDYSIZE:
*((size_t *)where) = (study == NULL)? 0 : study->size;
break;
case PCRE_INFO_CAPTURECOUNT:
*((int *)where) = re->top_bracket;
break;
case PCRE_INFO_BACKREFMAX:
*((int *)where) = re->top_backref;
break;
case PCRE_INFO_FIRSTBYTE:
*((int *)where) =
((re->options & PCRE_FIRSTSET) != 0)? re->first_byte :
((re->options & PCRE_STARTLINE) != 0)? -1 : -2;
break;
/* Make sure we pass back the pointer to the bit vector in the external
block, not the internal copy (with flipped integer fields). */
case PCRE_INFO_FIRSTTABLE:
*((const uschar **)where) =
(study != NULL && (study->options & PCRE_STUDY_MAPPED) != 0)?
((const pcre_study_data *)extra_data->study_data)->start_bits : NULL;
break;
case PCRE_INFO_LASTLITERAL:
*((int *)where) =
((re->options & PCRE_REQCHSET) != 0)? re->req_byte : -1;
break;
case PCRE_INFO_NAMEENTRYSIZE:
*((int *)where) = re->name_entry_size;
break;
case PCRE_INFO_NAMECOUNT:
*((int *)where) = re->name_count;
break;
case PCRE_INFO_NAMETABLE:
*((const uschar **)where) = (const uschar *)re + re->name_table_offset;
break;
case PCRE_INFO_DEFAULT_TABLES:
*((const uschar **)where) = (const uschar *)pcre_default_tables;
break;
default: return PCRE_ERROR_BADOPTION;
}
return 0;
}
/*************************************************
* Return info about what features are configured *
*************************************************/
/* This is function which has an extensible interface so that additional items
can be added compatibly.
Arguments:
what what information is required
where where to put the information
Returns: 0 if data returned, negative on error
*/
EXPORT int
pcre_config(int what, void *where)
{
switch (what)
{
case PCRE_CONFIG_UTF8:
#ifdef SUPPORT_UTF8
*((int *)where) = 1;
#else
*((int *)where) = 0;
#endif
break;
case PCRE_CONFIG_UNICODE_PROPERTIES:
#ifdef SUPPORT_UCP
*((int *)where) = 1;
#else
*((int *)where) = 0;
#endif
break;
case PCRE_CONFIG_NEWLINE:
*((int *)where) = NEWLINE;
break;
case PCRE_CONFIG_LINK_SIZE:
*((int *)where) = LINK_SIZE;
break;
case PCRE_CONFIG_POSIX_MALLOC_THRESHOLD:
*((int *)where) = POSIX_MALLOC_THRESHOLD;
break;
case PCRE_CONFIG_MATCH_LIMIT:
*((unsigned int *)where) = MATCH_LIMIT;
break;
case PCRE_CONFIG_STACKRECURSE:
#ifdef NO_RECURSE
*((int *)where) = 0;
#else
*((int *)where) = 1;
#endif
break;
default: return PCRE_ERROR_BADOPTION;
}
return 0;
}
#ifdef DEBUG
/*************************************************
* Debugging function to print chars *
*************************************************/
/* Print a sequence of chars in printable format, stopping at the end of the
subject if the requested.
Arguments:
p points to characters
length number to print
is_subject TRUE if printing from within md->start_subject
md pointer to matching data block, if is_subject is TRUE
Returns: nothing
*/
static void
pchars(const uschar *p, int length, BOOL is_subject, match_data *md)
{
int c;
if (is_subject && length > md->end_subject - p) length = md->end_subject - p;
while (length-- > 0)
if (isprint(c = *(p++))) printf("%c", c); else printf("\\x%02x", c);
}
#endif
/*************************************************
* Handle escapes *
*************************************************/
/* This function is called when a \ has been encountered. It either returns a
positive value for a simple escape such as \n, or a negative value which
encodes one of the more complicated things such as \d. When UTF-8 is enabled,
a positive value greater than 255 may be returned. On entry, ptr is pointing at
the \. On exit, it is on the final character of the escape sequence.
Arguments:
ptrptr points to the pattern position pointer
errorptr points to the pointer to the error message
bracount number of previous extracting brackets
options the options bits
isclass TRUE if inside a character class
Returns: zero or positive => a data character
negative => a special escape sequence
on error, errorptr is set
*/
static int
check_escape(const uschar **ptrptr, const char **errorptr, int bracount,
int options, BOOL isclass)
{
const uschar *ptr = *ptrptr;
int c, i;
/* If backslash is at the end of the pattern, it's an error. */
c = *(++ptr);
if (c == 0) *errorptr = ERR1;
/* Non-alphamerics are literals. For digits or letters, do an initial lookup in
a table. A non-zero result is something that can be returned immediately.
Otherwise further processing may be required. */
#if !EBCDIC /* ASCII coding */
else if (c < '0' || c > 'z') {} /* Not alphameric */
else if ((i = escapes[c - '0']) != 0) c = i;
#else /* EBCDIC coding */
else if (c < 'a' || (ebcdic_chartab[c] & 0x0E) == 0) {} /* Not alphameric */
else if ((i = escapes[c - 0x48]) != 0) c = i;
#endif
/* Escapes that need further processing, or are illegal. */
else
{
const uschar *oldptr;
switch (c)
{
/* A number of Perl escapes are not handled by PCRE. We give an explicit
error. */
case 'l':
case 'L':
case 'N':
case 'u':
case 'U':
*errorptr = ERR37;
break;
/* The handling of escape sequences consisting of a string of digits
starting with one that is not zero is not straightforward. By experiment,
the way Perl works seems to be as follows:
Outside a character class, the digits are read as a decimal number. If the
number is less than 10, or if there are that many previous extracting
left brackets, then it is a back reference. Otherwise, up to three octal
digits are read to form an escaped byte. Thus \123 is likely to be octal
123 (cf \0123, which is octal 012 followed by the literal 3). If the octal
value is greater than 377, the least significant 8 bits are taken. Inside a
character class, \ followed by a digit is always an octal number. */
case '1': case '2': case '3': case '4': case '5':
case '6': case '7': case '8': case '9':
if (!isclass)
{
oldptr = ptr;
c -= '0';
while ((digitab[ptr[1]] & ctype_digit) != 0)
c = c * 10 + *(++ptr) - '0';
if (c < 10 || c <= bracount)
{
c = -(ESC_REF + c);
break;
}
ptr = oldptr; /* Put the pointer back and fall through */
}
/* Handle an octal number following \. If the first digit is 8 or 9, Perl
generates a binary zero byte and treats the digit as a following literal.
Thus we have to pull back the pointer by one. */
if ((c = *ptr) >= '8')
{
ptr--;
c = 0;
break;
}
/* \0 always starts an octal number, but we may drop through to here with a
larger first octal digit. */
case '0':
c -= '0';
while(i++ < 2 && ptr[1] >= '0' && ptr[1] <= '7')
c = c * 8 + *(++ptr) - '0';
c &= 255; /* Take least significant 8 bits */
break;