16
16
#define REPINF 255
17
17
#define MAXSUB REG_MAXSUB
18
18
#define MAXPROG (32 << 10)
19
+ #define MAXREC 1024
19
20
20
21
typedef struct Reclass Reclass ;
21
22
typedef struct Renode Renode ;
@@ -967,98 +968,112 @@ static int strncmpcanon(const char *a, const char *b, int n)
967
968
return 0 ;
968
969
}
969
970
970
- static int match (Reinst * pc , const char * sp , const char * bol , int flags , Resub * out )
971
+ static int match (Reinst * pc , const char * sp , const char * bol , int flags , Resub * out , int depth )
971
972
{
972
973
Resub scratch ;
974
+ int result ;
973
975
int i ;
974
976
Rune c ;
975
977
978
+ /* stack overflow */
979
+ if (depth > MAXREC )
980
+ return -1 ;
981
+
976
982
for (;;) {
977
983
switch (pc -> opcode ) {
978
984
case I_END :
979
- return 1 ;
985
+ return 0 ;
980
986
case I_JUMP :
981
987
pc = pc -> x ;
982
988
break ;
983
989
case I_SPLIT :
984
990
scratch = * out ;
985
- if (match (pc -> x , sp , bol , flags , & scratch )) {
991
+ result = match (pc -> x , sp , bol , flags , & scratch , depth + 1 );
992
+ if (result == -1 )
993
+ return -1 ;
994
+ if (result == 0 ) {
986
995
* out = scratch ;
987
- return 1 ;
996
+ return 0 ;
988
997
}
989
998
pc = pc -> y ;
990
999
break ;
991
1000
992
1001
case I_PLA :
993
- if (!match (pc -> x , sp , bol , flags , out ))
994
- return 0 ;
1002
+ result = match (pc -> x , sp , bol , flags , out , depth + 1 );
1003
+ if (result == -1 )
1004
+ return -1 ;
1005
+ if (result == 1 )
1006
+ return 1 ;
995
1007
pc = pc -> y ;
996
1008
break ;
997
1009
case I_NLA :
998
1010
scratch = * out ;
999
- if (match (pc -> x , sp , bol , flags , & scratch ))
1000
- return 0 ;
1011
+ result = match (pc -> x , sp , bol , flags , & scratch , depth + 1 );
1012
+ if (result == -1 )
1013
+ return -1 ;
1014
+ if (result == 0 )
1015
+ return 1 ;
1001
1016
pc = pc -> y ;
1002
1017
break ;
1003
1018
1004
1019
case I_ANYNL :
1005
1020
sp += chartorune (& c , sp );
1006
1021
if (c == 0 )
1007
- return 0 ;
1022
+ return 1 ;
1008
1023
pc = pc + 1 ;
1009
1024
break ;
1010
1025
case I_ANY :
1011
1026
sp += chartorune (& c , sp );
1012
1027
if (c == 0 )
1013
- return 0 ;
1028
+ return 1 ;
1014
1029
if (isnewline (c ))
1015
- return 0 ;
1030
+ return 1 ;
1016
1031
pc = pc + 1 ;
1017
1032
break ;
1018
1033
case I_CHAR :
1019
1034
sp += chartorune (& c , sp );
1020
1035
if (c == 0 )
1021
- return 0 ;
1036
+ return 1 ;
1022
1037
if (flags & REG_ICASE )
1023
1038
c = canon (c );
1024
1039
if (c != pc -> c )
1025
- return 0 ;
1040
+ return 1 ;
1026
1041
pc = pc + 1 ;
1027
1042
break ;
1028
1043
case I_CCLASS :
1029
1044
sp += chartorune (& c , sp );
1030
1045
if (c == 0 )
1031
- return 0 ;
1046
+ return 1 ;
1032
1047
if (flags & REG_ICASE ) {
1033
1048
if (!incclasscanon (pc -> cc , canon (c )))
1034
- return 0 ;
1049
+ return 1 ;
1035
1050
} else {
1036
1051
if (!incclass (pc -> cc , c ))
1037
- return 0 ;
1052
+ return 1 ;
1038
1053
}
1039
1054
pc = pc + 1 ;
1040
1055
break ;
1041
1056
case I_NCCLASS :
1042
1057
sp += chartorune (& c , sp );
1043
1058
if (c == 0 )
1044
- return 0 ;
1059
+ return 1 ;
1045
1060
if (flags & REG_ICASE ) {
1046
1061
if (incclasscanon (pc -> cc , canon (c )))
1047
- return 0 ;
1062
+ return 1 ;
1048
1063
} else {
1049
1064
if (incclass (pc -> cc , c ))
1050
- return 0 ;
1065
+ return 1 ;
1051
1066
}
1052
1067
pc = pc + 1 ;
1053
1068
break ;
1054
1069
case I_REF :
1055
1070
i = out -> sub [pc -> n ].ep - out -> sub [pc -> n ].sp ;
1056
1071
if (flags & REG_ICASE ) {
1057
1072
if (strncmpcanon (sp , out -> sub [pc -> n ].sp , i ))
1058
- return 0 ;
1073
+ return 1 ;
1059
1074
} else {
1060
1075
if (strncmp (sp , out -> sub [pc -> n ].sp , i ))
1061
- return 0 ;
1076
+ return 1 ;
1062
1077
}
1063
1078
if (i > 0 )
1064
1079
sp += i ;
@@ -1076,7 +1091,7 @@ static int match(Reinst *pc, const char *sp, const char *bol, int flags, Resub *
1076
1091
break ;
1077
1092
}
1078
1093
}
1079
- return 0 ;
1094
+ return 1 ;
1080
1095
case I_EOL :
1081
1096
if (* sp == 0 ) {
1082
1097
pc = pc + 1 ;
@@ -1088,19 +1103,19 @@ static int match(Reinst *pc, const char *sp, const char *bol, int flags, Resub *
1088
1103
break ;
1089
1104
}
1090
1105
}
1091
- return 0 ;
1106
+ return 1 ;
1092
1107
case I_WORD :
1093
1108
i = sp > bol && iswordchar (sp [-1 ]);
1094
1109
i ^= iswordchar (sp [0 ]);
1095
1110
if (!i )
1096
- return 0 ;
1111
+ return 1 ;
1097
1112
pc = pc + 1 ;
1098
1113
break ;
1099
1114
case I_NWORD :
1100
1115
i = sp > bol && iswordchar (sp [-1 ]);
1101
1116
i ^= iswordchar (sp [0 ]);
1102
1117
if (i )
1103
- return 0 ;
1118
+ return 1 ;
1104
1119
pc = pc + 1 ;
1105
1120
break ;
1106
1121
@@ -1113,7 +1128,7 @@ static int match(Reinst *pc, const char *sp, const char *bol, int flags, Resub *
1113
1128
pc = pc + 1 ;
1114
1129
break ;
1115
1130
default :
1116
- return 0 ;
1131
+ return 1 ;
1117
1132
}
1118
1133
}
1119
1134
}
@@ -1130,7 +1145,7 @@ int regexec(Reprog *prog, const char *sp, Resub *sub, int eflags)
1130
1145
for (i = 0 ; i < MAXSUB ; ++ i )
1131
1146
sub -> sub [i ].sp = sub -> sub [i ].ep = NULL ;
1132
1147
1133
- return ! match (prog -> start , sp , sp , prog -> flags | eflags , sub );
1148
+ return match (prog -> start , sp , sp , prog -> flags | eflags , sub , 0 );
1134
1149
}
1135
1150
1136
1151
#ifdef TEST
0 commit comments