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.

103 lines
3.0 KiB

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