Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

102 lines
3.0 KiB

  1. #include <regexp.h>
  2. BOOL test_match(int m, LPSTR target, int pattern[]) /* m = length of target */
  3. {
  4. int *match;
  5. int i = -1; /* Will be advanced to 0 */
  6. int j = 0; /* i = index to pattern, j = index to target */
  7. BOOL fResult = FALSE;
  8. match = new int[INTERNET_MAX_URL_LENGTH];
  9. if (match == NULL)
  10. goto Cleanup;
  11. advance:
  12. ++i;
  13. if (j > m)
  14. goto Cleanup;
  15. switch (pattern[i]) {
  16. case PAT_START: if (j != 0) goto Cleanup; match[i] = 0; goto advance;
  17. case PAT_END: if (target[j] == 0) {fResult = TRUE; goto Cleanup;} else goto retreat;
  18. case PAT_STAR: match[i] = j = m; goto advance;
  19. case PAT_QUES: if (j < m) goto match_one; else goto retreat;
  20. case PAT_AUGDOT: if (target[j] == '.') goto match_one;
  21. else if (target[j] == 0) goto match_zero;
  22. else goto retreat;
  23. case PAT_AUGQUES: if (target[j] && target[j] != '.')
  24. goto match_one; else goto match_zero;
  25. case PAT_AUGSTAR: if (target[j] && target[j] != '.')
  26. goto match_one; else goto retreat;
  27. default: if (target[j] == pattern[i])
  28. goto match_one; else goto retreat;
  29. }
  30. match_one: match[i] = ++j; goto advance;
  31. match_zero: match[i] = j; goto advance;
  32. retreat:
  33. --i;
  34. switch (pattern[i]) {
  35. case PAT_START: goto Cleanup;
  36. case PAT_END: goto Cleanup; /* Cannot happen */
  37. case PAT_STAR: if (match[i] == match[i-1]) goto retreat;
  38. j = --match[i]; goto advance;
  39. case PAT_QUES: goto retreat;
  40. case PAT_AUGDOT: goto retreat;
  41. case PAT_AUGQUES: if (match[i] == match[i-1]) goto retreat;
  42. j = --match[i]; goto advance;
  43. case PAT_AUGSTAR: goto retreat;
  44. default: goto retreat;
  45. }
  46. Cleanup:
  47. if (match)
  48. delete [] match;
  49. return fResult;
  50. }
  51. BOOL parse_pattern(LPSTR s, int pattern[])
  52. {
  53. int i = 1;
  54. pattern[0] = PAT_START; /* Can be hard-coded into pattern[] */
  55. for (;;) {
  56. switch (*s) {
  57. case '*': pattern[i] = PAT_STAR; break;
  58. case '?': pattern[i] = PAT_QUES; break;
  59. case '^':
  60. switch (*++s) {
  61. case '.': pattern[i] = PAT_AUGDOT; break;
  62. case '?': pattern[i] = PAT_AUGQUES; break;
  63. case '*': pattern[i] = PAT_AUGSTAR; break;
  64. default: return FALSE;
  65. }
  66. break;
  67. case 0: pattern[i] = PAT_END; return TRUE;
  68. default: pattern[i] = *s; break;
  69. }
  70. if (++i >= INTERNET_MAX_URL_LENGTH) return FALSE;
  71. ++s;
  72. }
  73. }
  74. BOOL match( LPSTR target, LPSTR regexp)
  75. {
  76. int *pattern;
  77. BOOL result;
  78. pattern = new int[INTERNET_MAX_URL_LENGTH];
  79. if (!target || (pattern==NULL))
  80. return FALSE;
  81. if (!parse_pattern(regexp,pattern))
  82. return FALSE;
  83. if (lstrlen(target) >= INTERNET_MAX_URL_LENGTH)
  84. return FALSE;
  85. result = test_match(lstrlen(target),target,pattern);
  86. delete [] pattern;
  87. return result;
  88. }