1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* Copyright (c) 1988 AT&T */ 23 /* All Rights Reserved */ 24 25 26 /* 27 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 28 * Use is subject to license terms. 29 */ 30 31 /* 32 * Copyright (c) 2018, Joyent, Inc. 33 */ 34 35 #include <sys/types.h> 36 #include <stdlib.h> 37 #include "utility.h" 38 39 /* this code was taken from regcmp(3C) */ 40 41 #define SSIZE 16 42 #define TGRP 48 43 #define A256 02 44 #define ZERO 01 45 #define NBRA 10 46 #define CIRCFL 32; 47 #define SLOP 5 48 #define FEOF 0 /* This was originally EOF but it clashes with the header */ 49 /* definition so it was changed to FEOF */ 50 51 #define CBRA 60 52 #define GRP 40 53 #define SGRP 56 54 #define PGRP 68 55 #define EGRP 44 56 #define RNGE 03 57 #define CCHR 20 58 #define CDOT 64 59 #define CCL 24 60 #define NCCL 8 61 #define CDOL 28 62 #define FCEOF 52 /* This was originally CEOF but it clashes with the header */ 63 /* definition so it was changed to FCEOF */ 64 #define CKET 12 65 66 #define STAR 01 67 #define PLUS 02 68 #define MINUS 16 69 70 intptr_t *__sp_; 71 intptr_t *__stmax; 72 extern int __i_size; 73 74 /*ARGSUSED2*/ 75 char * 76 libform_regcmp(char *cs1, char *cs2) 77 { 78 char c; 79 char *ep, *sp; 80 int *adx; 81 int i, cflg; 82 char *lastep, *sep, *eptr; 83 int nbra, ngrp; 84 int cclcnt; 85 intptr_t stack[SSIZE]; 86 87 __sp_ = stack; 88 *__sp_ = -1; 89 __stmax = &stack[SSIZE]; 90 91 adx = (int *)&cs1; 92 i = nbra = ngrp = 0; 93 while (*adx) 94 i += __size((char *)(intptr_t)*adx++); 95 adx = (int *)&cs1; 96 sp = (char *)(intptr_t)*adx++; 97 if ((sep = ep = malloc((unsigned)(2 * i + SLOP))) == NULL) 98 return (NULL); 99 if ((c = *sp++) == FEOF) 100 goto cerror; 101 if (c == '^') { 102 c = *sp++; 103 *ep++ = CIRCFL; 104 } 105 if ((c == '*') || (c == '+') || (c == '{')) 106 goto cerror; 107 sp--; 108 for (;;) { 109 if ((c = *sp++) == FEOF) { 110 if (*adx) { 111 sp = (char *)(intptr_t)*adx++; 112 continue; 113 } 114 *ep++ = FCEOF; 115 if (--nbra > NBRA || *__sp_ != -1) 116 goto cerror; 117 __i_size = (int)(ep - sep); 118 return (sep); 119 } 120 if ((c != '*') && (c != '{') && (c != '+')) 121 lastep = ep; 122 switch (c) { 123 124 case '(': 125 if (!__rpush(ep)) goto cerror; 126 *ep++ = CBRA; 127 *ep++ = -1; 128 continue; 129 case ')': 130 if (!(eptr = (char *)__rpop())) goto cerror; 131 if ((c = *sp++) == '$') { 132 if ('0' > (c = *sp++) || c > '9') 133 goto cerror; 134 *ep++ = CKET; 135 *ep++ = *++eptr = nbra++; 136 *ep++ = (c-'0'); 137 continue; 138 } 139 *ep++ = EGRP; 140 *ep++ = ngrp++; 141 sp--; 142 switch (c) { 143 case '+': 144 *eptr = PGRP; 145 break; 146 case '*': 147 *eptr = SGRP; 148 break; 149 case '{': 150 *eptr = TGRP; 151 break; 152 default: 153 *eptr = GRP; 154 continue; 155 } 156 i = (int)(ep - eptr - 2); 157 for (cclcnt = 0; i >= 256; cclcnt++) 158 i -= 256; 159 if (cclcnt > 3) goto cerror; 160 *eptr |= cclcnt; 161 *++eptr = (char)i; 162 continue; 163 164 case '\\': 165 *ep++ = CCHR; 166 if ((c = *sp++) == FEOF) 167 goto cerror; 168 *ep++ = c; 169 continue; 170 171 case '{': 172 *lastep |= RNGE; 173 cflg = 0; 174 nlim: 175 if ((c = *sp++) == '}') goto cerror; 176 i = 0; 177 do { 178 if ('0' <= c && c <= '9') 179 i = (i*10+(c-'0')); 180 else goto cerror; 181 } while (((c = *sp++) != '}') && (c != ',')); 182 if (i > 255) goto cerror; 183 *ep++ = (char)i; 184 if (c == ',') { 185 if (cflg++) goto cerror; 186 if ((c = *sp++) == '}') { 187 *ep++ = -1; 188 continue; 189 } else { 190 sp--; 191 goto nlim; 192 } 193 } 194 if (!cflg) 195 *ep++ = (char)i; 196 else if ((ep[-1]&0377) < (ep[-2]&0377)) 197 goto cerror; 198 continue; 199 200 case '.': 201 *ep++ = CDOT; 202 continue; 203 204 case '+': 205 if (*lastep == CBRA || *lastep == CKET) 206 goto cerror; 207 *lastep |= PLUS; 208 continue; 209 210 case '*': 211 if (*lastep == CBRA || *lastep == CKET) 212 goto cerror; 213 *lastep |= STAR; 214 continue; 215 216 case '$': 217 if ((*sp != FEOF) || (*adx)) 218 goto defchar; 219 *ep++ = CDOL; 220 continue; 221 222 case '[': 223 *ep++ = CCL; 224 *ep++ = 0; 225 cclcnt = 1; 226 if ((c = *sp++) == '^') { 227 c = *sp++; 228 ep[-2] = NCCL; 229 } 230 do { 231 if (c == FEOF) 232 goto cerror; 233 if ((c == '-') && (cclcnt > 1) && 234 (*sp != ']')) { 235 *ep = ep[-1]; 236 ep++; 237 ep[-2] = MINUS; 238 cclcnt++; 239 continue; 240 } 241 *ep++ = c; 242 cclcnt++; 243 } while ((c = *sp++) != ']'); 244 lastep[1] = (char)cclcnt; 245 continue; 246 247 defchar: 248 default: 249 *ep++ = CCHR; 250 *ep++ = c; 251 } 252 } 253 cerror: 254 free(sep); 255 return (0); 256 } 257 258 int 259 __size(char *strg) 260 { 261 int i; 262 263 i = 1; 264 while (*strg++) 265 i++; 266 return (i); 267 } 268 269 intptr_t 270 __rpop(void) 271 { 272 return ((*__sp_ == -1)?0:*__sp_--); 273 } 274 275 int 276 __rpush(char *ptr) 277 { 278 if (__sp_ >= __stmax) 279 return (0); 280 *++__sp_ = (intptr_t)ptr; 281 return (1); 282 } 283