Changeset 925
- Timestamp:
- 06/13/07 00:46:44 (1 year ago)
- Files:
-
- 1.8.2/trunk/CHANGES.182 (modified) (1 diff)
- 1.8.2/trunk/Patchlevel (modified) (1 diff)
- 1.8.2/trunk/game/txt/hlp/pennfunc.hlp (modified) (1 diff)
- 1.8.2/trunk/game/txt/hlp/pennv182.hlp (modified) (2 diffs)
- 1.8.2/trunk/game/txt/hlp/pennvOLD.hlp (modified) (1 diff)
- 1.8.2/trunk/hdrs/attrib.h (modified) (1 diff)
- 1.8.2/trunk/hdrs/externs.h (modified) (2 diffs)
- 1.8.2/trunk/hdrs/pcre.h (modified) (1 diff)
- 1.8.2/trunk/hdrs/version.h (modified) (1 diff)
- 1.8.2/trunk/src/Makefile.SH (modified) (1 diff)
- 1.8.2/trunk/src/access.c (modified) (2 diffs)
- 1.8.2/trunk/src/attrib.c (modified) (10 diffs)
- 1.8.2/trunk/src/bsd.c (modified) (4 diffs)
- 1.8.2/trunk/src/notify.c (modified) (5 diffs)
- 1.8.2/trunk/src/strutil.c (modified) (1 diff)
- 1.8.2/trunk/src/wild.c (modified) (17 diffs)
- 1.8.2/trunk/src/wiz.c (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
1.8.2/trunk/CHANGES.182
r853 r925 14 14 15 15 ========================================================================== 16 17 Version 1.8.2 patchlevel 5 June 13, 2007 18 19 Minor changes: 20 * Removed the gmalloc malloc option. [SW] 21 * Assorted gcc warning fixes. [SW] 22 23 Fixes: 24 * Cleaned up some unsafe signal handler functions. [SW] 16 25 17 26 Version 1.8.2 patchlevel 4 May 16, 2007 1.8.2/trunk/Patchlevel
r853 r925 1 1 Do not edit this file. It is maintained by the official PennMUSH patches. 2 This is PennMUSH 1.8.2p 42 This is PennMUSH 1.8.2p5 1.8.2/trunk/game/txt/hlp/pennfunc.hlp
r853 r925 1878 1878 1879 1879 Returns a space-separated list of the attribute names on the object 1880 that you are permitted to examine. To see the complete list, 1881 you must either be a Wizard or Royalty, own the object, have the1882 See_All power, or have the object set VISUAL in order to use this1883 function on the object.1880 that you are permitted to examine. To see the complete list, you 1881 must either be a Wizard or Royalty, own the object, have the See_All 1882 power, or have the object set VISUAL and pass its examine lock in 1883 order to use this function on the object. 1884 1884 1885 1885 If a wildcarded attribute pattern is provided, only attribute names 1.8.2/trunk/game/txt/hlp/pennv182.hlp
r853 r925 1 & 1.8.2p 41 & 1.8.2p5 2 2 & changes 3 3 This is a list of changes in this patchlevel which are probably of … … 12 12 be read in 'help patchlevels'. 13 13 14 Version 1.8.2 patchlevel 5 June 13, 2007 15 16 Minor changes: 17 * Removed the gmalloc malloc option. [SW] 18 * Assorted gcc warning fixes. [SW] 19 20 Fixes: 21 * Cleaned up some unsafe signal handler functions. [SW] 22 23 & 1.8.2p4 14 24 Version 1.8.2 patchlevel 4 May 16, 2007 15 25 1.8.2/trunk/game/txt/hlp/pennvOLD.hlp
r853 r925 4418 4418 type 'help <version>p<patchlevel>'. For example, 'help 1.7.2p3' 4419 4419 4420 1.8.2: 0, 1, 2, 3, 4 4420 1.8.2: 0, 1, 2, 3, 4, 5 4421 4421 1.8.1: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 4422 4422 1.8.0: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 1.8.2/trunk/hdrs/attrib.h
r853 r925 127 127 #define AF_PUBLIC 0x2000000 /**< Override SAFER_UFUN */ 128 128 #define AF_ANON 0x4000000 /**< INTERNAL: Attribute doesn't really 129 exist in the database */129 exist in the database */ 130 130 #define AF_NONAME 0x8000000 /**< No name in did_it */ 131 131 #define AF_NOSPACE 0x10000000 /**< No space in did_it */ 1.8.2/trunk/hdrs/externs.h
r527 r925 481 481 char **bp); 482 482 483 char *mush_strncpy(char *restrict, const char *, size_t); 484 483 485 extern char *replace_string 484 486 (const char *RESTRICT old, const char *RESTRICT newbit, … … 570 572 extern int quick_wild_new(const char *RESTRICT tstr, 571 573 const char *RESTRICT dstr, int cs); 572 extern int regexp_match_case(const char *RESTRICT s, const char *RESTRICT d, 573 int cs); 574 extern int regexp_match_case_r(const char *RESTRICT s, 575 const char *RESTRICT d, int cs, char **, int, 576 char *, int); 574 577 extern int quick_regexp_match(const char *RESTRICT s, 575 578 const char *RESTRICT d, int cs); 576 extern int wild_match_case (const char *RESTRICT s, const char *RESTRICT d,577 int cs);579 extern int wild_match_case_r(const char *RESTRICT s, const char *RESTRICT d, 580 int cs, char **, int, char *, int); 578 581 extern int quick_wild(const char *RESTRICT tsr, const char *RESTRICT dstr); 579 582 extern int atr_wild(const char *RESTRICT tstr, const char *RESTRICT dstr); 580 /** Default (case-sensitive) regex match */581 #define regexp_match(s,d) regexp_match_case(s,d,1)582 /** Default (case-insensitive) wildcard match */583 #define wild_match(s,d) wild_match_case(s,d,0)584 583 /** Default (case-insensitive) local wildcard match */ 585 584 #define local_wild_match(s,d) local_wild_match_case(s, d, 0) 1.8.2/trunk/hdrs/pcre.h
r523 r925 184 184 int *, const unsigned char *); 185 185 extern int pcre_copy_substring(const char *, int *, int, int, char *, int); 186 int pcre_get_substring(const char *, int *, int, int, const char **); 186 187 extern int pcre_exec(const pcre *, const pcre_extra *, 187 188 const char *, int, int, int, int *, int); 1.8.2/trunk/hdrs/version.h
r853 r925 1 1 #define VERSION "1.8.2" 2 #define PATCHLEVEL " 4"3 #define PATCHDATE "[0 4/16/2007]"4 #define NUMVERSION 100800200 42 #define PATCHLEVEL "5" 3 #define PATCHDATE "[06/13/2007]" 4 #define NUMVERSION 1008002005 1.8.2/trunk/src/Makefile.SH
r853 r925 207 207 echo '!NO!SUBS!' >> Makefile.SH 208 208 209 # Requires GNU indent! 209 # Requires GNU indent 1.2 or better! 210 210 211 indent: 211 212 (set +e; for file in *.dst *.c ../hdrs/*.h ; do echo $$file; \ 212 /usr/bin/expand $$file > tmpfile; mv -f tmpfile $$file; \ 213 /usr/bin/indent -npro -kr -ci2 -ss -psl -ip4 -i2 -cs -l80 -lc75 \ 213 /usr/bin/indent -npro -kr -ci2 -ss -psl -ip4 -i2 -cs -l80 -lc75 -nut \ 214 214 -T atr_err -T ATRALIAS -T DESC -T CNode -T CONF -T BQUE -T FUN \ 215 215 -T NVAL -T i_rec -T f_rec -T USERFN_ENTRY -T PRIV -T FLAG \ 1.8.2/trunk/src/access.c
r511 r925 331 331 if (!(ap->can & ACS_SITELOCK) 332 332 && ((ap->can & ACS_REGEXP) 333 ? ( regexp_match_case(ap->host, hname, 0)334 || (p && regexp_match_case(ap->host, p, 0))333 ? (quick_regexp_match(ap->host, hname, 0) 334 || (p && quick_regexp_match(ap->host, p, 0)) 335 335 #ifdef FORCE_IPV4 336 || regexp_match_case(ip4_to_ip6(ap->host), hname, 0)337 || (p && regexp_match_case(ip4_to_ip6(ap->host), p, 0))336 || quick_regexp_match(ip4_to_ip6(ap->host), hname, 0) 337 || (p && quick_regexp_match(ip4_to_ip6(ap->host), p, 0)) 338 338 #endif 339 339 ) … … 401 401 if (!(ap->can & ACS_SITELOCK) 402 402 && ((ap->can & ACS_REGEXP) 403 ? ( regexp_match_case(ap->host, hname, 0)404 || (p && regexp_match_case(ap->host, p, 0))403 ? (quick_regexp_match(ap->host, hname, 0) 404 || (p && quick_regexp_match(ap->host, p, 0)) 405 405 #ifdef FORCE_IPV4 406 || regexp_match_case(ip4_to_ip6(ap->host), hname, 0)407 || (p && regexp_match_case(ip4_to_ip6(ap->host), p, 0))406 || quick_regexp_match(ip4_to_ip6(ap->host), hname, 0) 407 || (p && quick_regexp_match(ip4_to_ip6(ap->host), p, 0)) 408 408 #endif 409 409 ) 1.8.2/trunk/src/attrib.c
r853 r925 402 402 do { \ 403 403 ATTR *std = atr_match(AL_NAME((atr))); \ 404 if (std && !(flags) && !strcmp(AL_NAME(std), AL_NAME((atr)))) { \404 if (std && !(flags) && !strcmp(AL_NAME(std), AL_NAME((atr)))) { \ 405 405 AL_FLAGS(atr) = AL_FLAGS(std); \ 406 406 } else { \ … … 569 569 } 570 570 } else { 571 if (!AL_FLAGS(root) & AF_ROOT) /* Upgrading old database */572 AL_FLAGS(root) |= AF_ROOT; 571 if (!AL_FLAGS(root) & AF_ROOT) /* Upgrading old database */ 572 AL_FLAGS(root) |= AF_ROOT; 573 573 } 574 574 } … … 661 661 if (!EMPTY_ATTRS) { 662 662 unsigned char *t = compress(" "); 663 if (!t) 663 if (!t) 664 664 mush_panic(T("Unable to allocate memory in atr_add()!")); 665 665 root->data = chunk_create(t, u_strlen(t), 0); … … 1296 1296 int skipcount; 1297 1297 int lock_checked = 0; 1298 char match_space[BUFFER_LEN * 2]; 1299 int match_space_len = BUFFER_LEN * 2; 1298 1300 1299 1301 /* check for lots of easy ways out */ … … 1369 1371 match_found = 0; 1370 1372 if (AF_Regexp(ptr)) { 1371 if (regexp_match_case(tbuf2 + 1, str, AF_Case(ptr))) { 1373 if (regexp_match_case_r(tbuf2 + 1, str, AF_Case(ptr), 1374 global_eval_context.wnxt, 10, 1375 match_space, match_space_len)) { 1372 1376 match_found = 1; 1373 1377 match++; … … 1377 1381 match_found = 1; 1378 1382 match++; 1379 wild_match_case(tbuf2 + 1, str, AF_Case(ptr)); 1383 if (!just_match) 1384 wild_match_case_r(tbuf2 + 1, str, AF_Case(ptr), 1385 global_eval_context.wnxt, 10, 1386 match_space, match_space_len); 1380 1387 } 1381 1388 } … … 1486 1493 match_found = 0; 1487 1494 if (AF_Regexp(ptr)) { 1488 if (regexp_match_case(tbuf2 + 1, str, AF_Case(ptr))) { 1495 if (regexp_match_case_r(tbuf2 + 1, str, AF_Case(ptr), 1496 global_eval_context.wnxt, 10, 1497 match_space, match_space_len)) { 1489 1498 match_found = 1; 1490 1499 match++; … … 1494 1503 match_found = 1; 1495 1504 match++; 1496 wild_match_case(tbuf2 + 1, str, AF_Case(ptr)); 1505 if (!just_match) 1506 wild_match_case_r(tbuf2 + 1, str, AF_Case(ptr), 1507 global_eval_context.wnxt, 10, 1508 match_space, match_space_len); 1497 1509 } 1498 1510 } … … 1559 1571 char tbuf2[BUFFER_LEN]; 1560 1572 char *s; 1573 char match_space[BUFFER_LEN * 2]; 1574 int match_space_len = BUFFER_LEN * 2; 1561 1575 1562 1576 /* check for lots of easy ways out */ … … 1592 1606 1593 1607 if (AF_Regexp(ptr) ? 1594 regexp_match_case(tbuf2 + 1, str, AF_Case(ptr)) : 1595 wild_match_case(tbuf2 + 1, str, AF_Case(ptr))) { 1608 regexp_match_case_r(tbuf2 + 1, str, AF_Case(ptr), 1609 global_eval_context.wnxt, 10, match_space, 1610 match_space_len) : wild_match_case_r(tbuf2 + 1, str, 1611 AF_Case(ptr), 1612 global_eval_context. 1613 wnxt, 10, 1614 match_space, 1615 match_space_len)) 1616 { 1596 1617 if (!eval_lock(player, thing, Command_Lock) 1597 1618 || !eval_lock(player, thing, Use_Lock)) 1.8.2/trunk/src/bsd.c
r853 r925 372 372 void WIN32_CDECL signal_dump(int sig); 373 373 void reaper(int sig); 374 #ifndef WIN32 375 sig_atomic_t dump_error = 0; 376 WAIT_TYPE dump_status = 0; 377 #endif 374 378 extern Pid_t forked_dump_pid; /**< Process id of forking dump process */ 375 379 static void dump_users(DESC *call_by, char *match, int doing); … … 385 389 static void reap_info_slave(void); 386 390 void kill_info_slave(void); 391 sig_atomic_t slave_error = 0; 387 392 #endif 388 393 void reopen_logs(void); … … 838 843 839 844 process_commands(); 845 846 /* Check signal handler flags */ 847 848 #ifndef WIN32 849 if (dump_error) { 850 if (WIFSIGNALED(dump_status)) { 851 do_rawlog(LT_ERR, T("ERROR! forking dump exited with signal %d"), 852 WTERMSIG(dump_status)); 853 flag_broadcast("ROYALTY WIZARD", 0, 854 T("GAME: ERROR! Forking database save failed!")); 855 } else if (WIFEXITED(dump_status) && WEXITSTATUS(dump_status) == 0) { 856 time(&globals.last_dump_time); 857 if (DUMP_NOFORK_COMPLETE && *DUMP_NOFORK_COMPLETE) 858 flag_broadcast(0, 0, "%s", DUMP_NOFORK_COMPLETE); 859 } 860 dump_error = 0; 861 dump_status = 0; 862 } 863 #ifdef INFO_SLAVE 864 if (slave_error) { 865 do_rawlog(LT_ERR, T("info_slave on pid %d exited unexpectedly!"), 866 slave_error); 867 slave_error = 0; 868 } 869 #endif 870 #endif /* !WIN32 */ 840 871 841 872 if (signal_shutdown_flag) { … … 3036 3067 #ifdef INFO_SLAVE 3037 3068 if (info_slave_pid > -1 && pid == info_slave_pid) { 3038 do_rawlog(LT_ERR, T("info_slave on pid %d exited!"), pid);3039 3069 info_slave_state = 0; 3040 3070 info_slave_pid = -1; 3071 slave_error = pid; 3041 3072 } else 3042 3073 #endif 3043 3074 if (forked_dump_pid > -1 && pid == forked_dump_pid) { 3044 3075 /* Most failures are handled by the forked mush already */ 3045 if (WIFSIGNALED(my_stat)) { 3046 do_rawlog(LT_ERR, T("ERROR! forking dump exited with signal %d"), 3047 WTERMSIG(my_stat)); 3048 flag_broadcast("ROYALTY WIZARD", 0, 3049 T("GAME: ERROR! Forking database save failed!")); 3050 } else if (WIFEXITED(my_stat) && WEXITSTATUS(my_stat) == 0) { 3051 time(&globals.last_dump_time); 3052 if (DUMP_NOFORK_COMPLETE && *DUMP_NOFORK_COMPLETE) 3053 flag_broadcast(0, 0, "%s", DUMP_NOFORK_COMPLETE); 3054 3055 } 3076 dump_error = forked_dump_pid; 3077 dump_status = my_stat; 3056 3078 forked_dump_pid = -1; 3057 3079 } 1.8.2/trunk/src/notify.c
r527 r925 331 331 bp = tbuf; 332 332 safe_str((char *) messages[type].message, tbuf, &bp); 333 safe_chr( IAC, tbuf, &bp);334 safe_chr( GOAHEAD, tbuf, &bp);333 safe_chr((char) IAC, tbuf, &bp); 334 safe_chr((char) GOAHEAD, tbuf, &bp); 335 335 *bp = '\0'; 336 336 return (unsigned char *) tbuf; … … 371 371 bp = tbuf; 372 372 safe_str((char *) messages[type].message, tbuf, &bp); 373 safe_chr( IAC, tbuf, &bp);374 safe_chr( GOAHEAD, tbuf, &bp);373 safe_chr((char) IAC, tbuf, &bp); 374 safe_chr((char) GOAHEAD, tbuf, &bp); 375 375 *bp = '\0'; 376 376 return (unsigned char *) tbuf; … … 421 421 bp = tbuf; 422 422 safe_str((char *) messages[type].message, tbuf, &bp); 423 safe_chr( IAC, tbuf, &bp);424 safe_chr( GOAHEAD, tbuf, &bp);423 safe_chr((char) IAC, tbuf, &bp); 424 safe_chr((char) GOAHEAD, tbuf, &bp); 425 425 *bp = '\0'; 426 426 return (unsigned char *) tbuf; … … 533 533 bp = tbuf; 534 534 safe_str((char *) messages[type].message, tbuf, &bp); 535 safe_chr( IAC, tbuf, &bp);536 safe_chr( GOAHEAD, tbuf, &bp);535 safe_chr((char) IAC, tbuf, &bp); 536 safe_chr((char) GOAHEAD, tbuf, &bp); 537 537 *bp = '\0'; 538 538 return (unsigned char *) tbuf; … … 915 915 a = atr_get_noparent(target, "LISTEN"); 916 916 if (a) { 917 char match_space[BUFFER_LEN * 2]; 918 int match_space_len = BUFFER_LEN * 2; 917 919 if (!tbuf1) 918 920 tbuf1 = (char *) mush_malloc(BUFFER_LEN, "string"); 919 921 strcpy(tbuf1, atr_value(a)); 920 922 if (AF_Regexp(a) 921 ? regexp_match_case(tbuf1, 923 ? regexp_match_case_r(tbuf1, 924 (char *) notify_makestring(msgbuf, messages, 925 NA_ASCII, 0), 926 AF_Case(a), global_eval_context.wnxt, 10, 927 match_space, match_space_len) 928 : wild_match_case_r(tbuf1, 922 929 (char *) notify_makestring(msgbuf, messages, 923 930 NA_ASCII, 0), 924 AF_Case(a)) 925 : wild_match_case(tbuf1, 926 (char *) notify_makestring(msgbuf, messages, 927 NA_ASCII, 0), 928 AF_Case(a))) { 931 AF_Case(a), global_eval_context.wnxt, 10, 932 match_space, match_space_len)) { 929 933 if (eval_lock(speaker, target, Listen_Lock)) 930 934 if (PLAYER_AHEAR || (!IsPlayer(target))) { 1.8.2/trunk/src/strutil.c
r511 r925 1245 1245 *s_len = len + 1; 1246 1246 return buff; 1247 } 1248 1249 /** Safe version of strncpy() that always nul-terminates the 1250 * destination string. The only reason it's not called 1251 * safe_strncpy() is to avoid confusion with the unrelated 1252 * safe_*() pennstr functions. 1253 * \param dst the destination string to copy to 1254 * \param src the source string to copy from 1255 * \param len the maximum number of bytes to copy 1256 * return dst 1257 */ 1258 char * 1259 mush_strncpy(char *RESTRICT dst, const char *RESTRICT src, size_t len) 1260 { 1261 size_t n = 0; 1262 char *start = dst; 1263 1264 if (!src || !dst || len == 0) 1265 return dst; 1266 1267 len--; 1268 1269 while (*src && n < len) { 1270 *dst++ = *src++; 1271 n++; 1272 } 1273 1274 *dst = '\0'; 1275 return start; 1247 1276 } 1248 1277 1.8.2/trunk/src/wild.c
r651 r925 31 31 #include "case.h" 32 32 #include "externs.h" 33 #include "ansi.h" 33 34 #include "mymalloc.h" 34 35 #include "parse.h" … … 47 48 const unsigned char *tables = NULL; /** Pointer to character tables */ 48 49 49 static char wspace[3 * BUFFER_LEN + NUMARGS]; /* argument return buffer */50 /* big to match tprintf */51 52 50 static int wild1 53 51 (const char *RESTRICT tstr, const char *RESTRICT dstr, int arg, 54 char **RESTRICT wbuf, int cs); 55 static int wild(const char *RESTRICT s, const char *RESTRICT d, int p, int cs); 52 char **wbuf, int *len, int cs, char **ary, int max); 53 static int wild(const char *RESTRICT s, const char *RESTRICT d, int p, int cs, 54 char **ary, int max, char *buffer, int len); 56 55 static int check_literals(const char *RESTRICT tstr, const char *RESTRICT dstr, 57 56 int cs); … … 272 271 static int 273 272 wild1(const char *RESTRICT tstr, const char *RESTRICT dstr, int arg, 274 char ** RESTRICT wbuf, int cs)273 char **wbuf, int *len, int cs, char **ary, int max) 275 274 { 276 275 const char *datapos; … … 286 285 return 0; 287 286 288 global_eval_context.wnxt[arg++] = *wbuf; 289 *(*wbuf)++ = *dstr; 290 *(*wbuf)++ = '\0'; 287 if (*len >= 2) { 288 ary[arg++] = *wbuf; 289 *(*wbuf)++ = *dstr; 290 *(*wbuf)++ = '\0'; 291 *len -= 2; 292 } 291 293 292 294 /* Jump to the fast routine if we can. */ 293 295 294 if (arg >= NUMARGS)296 if (arg >= (int) max || *len < 2) 295 297 return quick_wild_new(tstr + 1, dstr + 1, cs); 296 298 break; … … 316 318 /* If at end of pattern, slurp the rest, and leave. */ 317 319 if (!tstr[1]) { 318 global_eval_context.wnxt[arg] = *wbuf; 319 strcpy(*wbuf, dstr); 320 *wbuf += strlen(dstr) + 2; 320 int tlen; 321 tlen = strlen(dstr); 322 if (tlen < *len) { 323 ary[arg] = *wbuf; 324 strcpy(*wbuf, dstr); 325 *wbuf += tlen + 2; 326 *len -= tlen + 1; 327 } 321 328 return 1; 322 329 } … … 331 338 * before a fixed string. 332 339 */ 333 global_eval_context.wnxt[argpos++] = *wbuf; 334 *(*wbuf)++ = '\0'; 340 if (*len >= 1) { 341 ary[argpos++] = *wbuf; 342 *(*wbuf)++ = '\0'; 343 *len -= 1; 344 } 335 345 336 346 /* Jump to the fast routine if we can. */ 337 if (argpos >= NUMARGS)347 if (argpos >= (int) max || *len < 2) 338 348 return quick_wild_new(tstr, dstr, cs); 339 349 340 350 /* Fill in any intervening '?'s */ 341 351 while (argpos < arg) { 342 global_eval_context.wnxt[argpos++] = *wbuf; 343 *(*wbuf)++ = *datapos++; 344 *(*wbuf)++ = '\0'; 352 if (*len >= 2) { 353 ary[argpos++] = *wbuf; 354 *(*wbuf)++ = *datapos++; 355 *(*wbuf)++ = '\0'; 356 *len -= 2; 357 } 345 358 346 359 /* Jump to the fast routine if we can. */ 347 if (argpos >= NUMARGS)360 if (argpos >= (int) max || *len < 1) 348 361 return quick_wild_new(tstr, dstr, cs); 349 362 } … … 378 391 while (1) { 379 392 if (EQUAL(cs, *dstr, *tstr) && 380 ((arg < NUMARGS) ? wild1(tstr, dstr, arg, wbuf, cs)393 ((arg < (int) max) ? wild1(tstr, dstr, arg, wbuf, len, cs, ary, max) 381 394 : quick_wild_new(tstr, dstr, cs))) 382 395 break; … … 390 403 * First do the '*'... 391 404 */ 392 global_eval_context.wnxt[argpos++] = *wbuf; 393 strncpy(*wbuf, datapos, (dstr - datapos) - numextra); 394 *wbuf += (dstr - datapos) - numextra; 395 *(*wbuf)++ = '\0'; 396 datapos = dstr - numextra; 405 { 406 int datalen; 407 datalen = (dstr - datapos) - numextra; 408 if (datalen + 1 <= *len) { 409 ary[argpos++] = *wbuf; 410 strncpy(*wbuf, datapos, datalen); 411 *wbuf += datalen; 412 *(*wbuf)++ = '\0'; 413 *len -= datalen + 1; 414 datapos = dstr - numextra; 415 } 416 } 397 417 398 418 /* Fill in any trailing '?'s that are left. */ 399 419 while (numextra) { 400 if (argpos >= NUMARGS)420 if (argpos >= (int) max || *len < 2) 401 421 return 1; 402 global_eval_context.wnxt[argpos++] = *wbuf; 403 *(*wbuf)++ = *datapos++; 404 *(*wbuf)++ = '\0'; 405 numextra--; 422 if (*len >= 2) { 423 ary[argpos++] = *wbuf; 424 *(*wbuf)++ = *datapos++; 425 *(*wbuf)++ = '\0'; 426 *len -= 2; 427 numextra--; 428 } 406 429 } 407 430 … … 420 443 */ 421 444 static int 422 wild(const char *RESTRICT s, const char *RESTRICT d, int p, int cs )423 { 424 char *buffer = wspace; 425 426 /* Do fast match. */445 wild(const char *RESTRICT s, const char *RESTRICT d, int p, int cs, 446 char **ary, int max, char *buffer, int len) 447 { 448 /* Do fast match to see if pattern matches. If yes, do it again, 449 remembering this time.. */ 427 450 while ((*s != '*') && (*s != '?')) { 428 451 if (*s == '\\') … … 441 464 442 465 /* Do the match. */ 443 return wild1(s, d, p, &buffer, cs); 444 } 445 446 /** Wildcard match, possibly case-sensitive, and remember the wild data. 466 return wild1(s, d, p, &buffer, &len, cs, ary, max); 467 } 468 469 /** Wildcard match, possibly case-sensitive, and remember the wild data 470 * in matches, storing them in data. 447 471 * 448 472 * This routine will cause crashes if fed NULLs instead of strings. … … 451 475 * \param d string to check. 452 476 * \param cs if 1, case-sensitive; if 0, case-insensitive. 477 * \param ary An array to store the grabs in 478 * \param max Number of elements ary can hold 479 * \param data Buffer used to hold the matches. The elements of ary 480 * are set to pointers into this buffer. 481 * \param len The number of bytes in data. Twice the length of d should 482 * be enough. 453 483 * \retval 1 d matches s. 454 484 * \retval 0 d doesn't match s. 455 485 */ 456 486 int 457 wild_match_case (const char *RESTRICT s, const char *RESTRICT d, int cs)458 { 459 int j; 460 /* Clear %0-%9 and r(0) - r(9) */461 for (j = 0; j < NUMARGS; j++) 462 global_eval_context.wnxt[j] = (char *) NULL;463 for (j = 0; j < NUMQ; j++)464 global_eval_context.rnxt[j] = (char *) NULL; 465 return wild(s, d, 0, cs );487 wild_match_case_r(const char *RESTRICT s, const char *RESTRICT d, int cs, 488 char **matches, int nmatches, char *data, int len) 489 { 490 int n; 491 492 for (n = 0; n < nmatches; n++) 493 matches[n] = NULL; 494 495 return wild(s, d, 0, cs, matches, nmatches, data, len); 466 496 } 467 497 … … 472 502 * \param s regexp to match against. 473 503 * \param d string to check. 474 * \param cs if 1, case-sensitive; if 0, case-insensitive. 475 * \retval 1 d matches s. 476 * \retval 0 d doesn't match s. 504 * \param cs if 1, case-sensitive; if 0, case-insensitive 505 * \param matches array to store matched subexpressions in 506 * \param nmatches the size of the matches array 507 * \param data buffer space to copy matches into. The elements of 508 * array point into here 509 * \param len The size of data 510 * \retval 1 d matches s 511 * \retval 0 d doesn't match s 477 512 */ 478 513 int 479 regexp_match_case (const char *RESTRICT s, const char *RESTRICT d, int cs)480 { 481 int j; 514 regexp_match_case_r(const char *RESTRICT s, const char *RESTRICT val, int cs, 515 char **matches, int nmatches, char *data, int len) 516 { 482 517 pcre *re; 483 518 int i; 484 static char wtmp[NUMARGS][BUFFER_LEN];485 519 const char *errptr; 520 const char *d; 521 size_t delenn; 486 522 int erroffset; 487 523 int offsets[99]; 488 524 int subpatterns; 525 526 for (i = 0; i < nmatches; i++) 527 matches[i] = NULL; 489 528 490 529 if ((re = pcre_compile(s, (cs ? 0 : PCRE_CASELESS), &errptr, &erroffset, … … 498 537 } 499 538 add_check("pcre"); 539 d = remove_markup(val, &delenn); 500 540 /* 501 541 * Now we try to match the pattern. The relevant fields will 502 542 * automatically be filled in by this. 503 543 */ 504 if ((subpatterns = pcre_exec(re, NULL, d, strlen(d), 0, 0, offsets, 99))544 if ((subpatterns = pcre_exec(re, NULL, d, delenn - 1, 0, 0, offsets, 99)) 505 545 < 0) { 506 546 mush_free(re, "pcre"); … … 520 560 */ 521 561 522 /* Clear %0-%9 and r(0) - r(9) */ 523 for (j = 0; j < NUMARGS; j++) { 524 wtmp[j][0] = '\0'; 525 global_eval_context.wnxt[j] = (char *) NULL; 526 } 527 for (j = 0; j < NUMQ; j++) 528 global_eval_context.rnxt[j] = (char *) NULL; 529 530 for (i = 0; (i < 10) && (i < NUMARGS); i++) { 531 pcre_copy_substring(d, offsets, subpatterns, i, wtmp[i], BUFFER_LEN); 532 global_eval_context.wnxt[i] = wtmp[i]; 562 for (i = 0; i < nmatches && i < subpatterns && len > 1; i++) { 563 int sublen; 564 const char *submatch; 565 566 pcre_get_substring(d, offsets, subpatterns, (int) i, &submatch); 567 sublen = strlen(submatch); 568 569 if (sublen >= len) 570 break; 571 572 strcpy(data, submatch); 573 matches[i] = data; 574 data += sublen + 1; 575 len -= sublen + 1; 533 576 } 534 577 … … 552 595 { 553 596 pcre *re; 597 const char *sptr; 598 size_t slen; 554 599 const char *errptr; 555 600 int erroffset; … … 573 618 } 574 619 add_check("pcre"); 620 sptr = remove_markup(d, &slen); 575 621 /* 576 622 * Now we try to match the pattern. The relevant fields will 577 623 * automatically be filled in by this. 578 624 */ 579 r = pcre_exec(re, NULL, d, strlen(d), 0, 0, offsets, 99);625 r = pcre_exec(re, NULL, sptr, slen - 1, 0, 0, offsets, 99); 580 626 581 627 mush_free(re, "pcre"); … … 643 689 const char delims[] = "?*"; 644 690 char *sp, *dp; 645 strncpy(dbuf1, dstr, BUFFER_LEN - 1); 646 dbuf1[BUFFER_LEN - 1] = '\0'; 647 strcpy(tbuf1, strip_backslashes(tstr)); 691 mush_strncpy(dbuf1, dstr, BUFFER_LEN); 692 mush_strncpy(tbuf1, strip_backslashes(tstr), BUFFER_LEN); 648 693 if (!cs) { 649 694 upcasestr(tbuf1); 1.8.2/trunk/src/wiz.c
r853 r925 1837 1837 if (!class || !*class || !restriction) 1838 1838 continue; 1839 if (isdigit((unsigned char) *class) || 1840 ((*class == '#') && *(class + 1)1841 && isdigit((unsigned char)*(class + 1)))) {1839 if (isdigit((unsigned char) *class) || ((*class == '#') && *(class + 1) 1840 && isdigit((unsigned char) 1841 *(class + 1)))) { 1842 1842 size_t offset = 0; 1843 1843 if (*class == '#')
