new upstream release (3.3.0); modify package compatibility for Stretch
[ossec-hids.git] / src / os_regex / os_regex_execute.c
1 /* Copyright (C) 2009 Trend Micro Inc.
2  * All right reserved.
3  *
4  * This program is a free software; you can redistribute it
5  * and/or modify it under the terms of the GNU General Public
6  * License (version 2) as published by the FSF - Free Software
7  * Foundation
8  */
9
10 #include <stdio.h>
11 #include <string.h>
12 #include <stdlib.h>
13
14 #include "os_regex.h"
15
16 /* Compare an already compiled regular expression with
17  * a not NULL string.
18  * Returns the end of the string on success or NULL on error.
19  * The error code is set on reg->error.
20  */
21 const char *OSRegex_Execute(const char *str, OSRegex *reg)
22 {
23     /* The string can't be NULL */
24     if (str == NULL) {
25         reg->error = OS_REGEX_STR_NULL;
26         return (NULL);
27     }
28     return reg->exec_function(str, reg);
29 }
30
31 const char *OSRegex_Execute_pcre2_match(const char *str, OSRegex *reg)
32 {
33     int rc = 0, nbs = 0, i = 0;
34     PCRE2_SIZE *ov = NULL;
35
36     /* Execute the reg */
37 #ifdef USE_PCRE2_JIT
38     rc = pcre2_jit_match(reg->regex, (PCRE2_SPTR)str, strlen(str), 0, 0, reg->match_data, NULL);
39 #else
40     rc = pcre2_match(reg->regex, (PCRE2_SPTR)str, strlen(str), 0, 0, reg->match_data, NULL);
41 #endif
42
43     /* Check execution result */
44     if (rc <= 0) {
45         return NULL;
46     }
47
48     /* get the offsets informations for the match */
49     ov = pcre2_get_ovector_pointer(reg->match_data);
50
51     if (reg->sub_strings) {
52         /* get the substrings if required */
53         for (i = 1; i < rc; i++) {
54             PCRE2_SIZE sub_string_start = ov[2 * i];
55             PCRE2_SIZE sub_string_end = ov[2 * i + 1];
56             PCRE2_SIZE sub_string_len = sub_string_end - sub_string_start;
57             if (sub_string_end > sub_string_start) {
58                 reg->sub_strings[nbs] = (char *)calloc(sub_string_len + 1, sizeof(char));
59                 strncpy(reg->sub_strings[nbs], &str[sub_string_start], sub_string_len);
60                 nbs++;
61             }
62         }
63         reg->sub_strings[nbs] = NULL;
64     }
65
66     return &str[ov[1]];
67 }
68
69 const char *OSRegex_Execute_strcmp(const char *subject, OSRegex *reg)
70 {
71     if (!strcmp(reg->pattern, subject)) {
72         return &subject[reg->pattern_len];
73     }
74     return NULL;
75 }
76
77 const char *OSRegex_Execute_strncmp(const char *subject, OSRegex *reg)
78 {
79     if (!strncmp(reg->pattern, subject, reg->pattern_len)) {
80         return &subject[reg->pattern_len];
81     }
82     return NULL;
83 }
84
85 const char *OSRegex_Execute_strrcmp(const char *subject, OSRegex *reg)
86 {
87     size_t len = strlen(subject);
88     if (len >= reg->pattern_len && !strcmp(reg->pattern, &subject[len - reg->pattern_len])) {
89         return &subject[len];
90     }
91     return NULL;
92 }
93
94 const char *OSRegex_Execute_strcasecmp(const char *subject, OSRegex *reg)
95 {
96     if (!strcasecmp(reg->pattern, subject)) {
97         return &subject[reg->pattern_len];
98     }
99     return NULL;
100 }
101
102 const char *OSRegex_Execute_strncasecmp(const char *subject, OSRegex *reg)
103 {
104     if (!strncasecmp(reg->pattern, subject, reg->pattern_len)) {
105         return &subject[reg->pattern_len];
106     }
107     return NULL;
108 }
109
110 const char *OSRegex_Execute_strrcasecmp(const char *subject, OSRegex *reg)
111 {
112     size_t len = strlen(subject);
113     if (len >= reg->pattern_len && !strcasecmp(reg->pattern, &subject[len - reg->pattern_len])) {
114         return &subject[len];
115     }
116     return NULL;
117 }