/[LeafOK_CVS]/lbbs/src/bwf.c
ViewVC logotype

Diff of /lbbs/src/bwf.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

Revision 1.2 by sysadm, Fri Nov 7 04:58:09 2025 UTC Revision 1.9 by sysadm, Sat Jan 3 10:27:14 2026 UTC
# Line 3  Line 3 
3   * bwf   * bwf
4   *   - bad words filter   *   - bad words filter
5   *   *
6   * Copyright (C) 2004-2025  Leaflet <leaflet@leafok.com>   * Copyright (C) 2004-2026  Leaflet <leaflet@leafok.com>
7   */   */
8    
9    #ifdef HAVE_CONFIG_H
10    #include "config.h"
11    #endif
12    
13  #define PCRE2_CODE_UNIT_WIDTH 8  #define PCRE2_CODE_UNIT_WIDTH 8
14    
15  #include "bwf.h"  #include "bwf.h"
# Line 31  int bwf_load(const char *filename) Line 35  int bwf_load(const char *filename)
35          size_t len_line;          size_t len_line;
36          char *p = bwf_pattern_str;          char *p = bwf_pattern_str;
37          int line_id = 0;          int line_id = 0;
         int errorcode;  
         PCRE2_SIZE erroroffset;  
38    
39          if (filename == NULL)          if (filename == NULL)
40          {          {
41                  log_error("NULL pointer error\n");                  log_error("NULL pointer error");
42                  return -1;                  return -1;
43          }          }
44    
45          if ((fp = fopen(filename, "r")) == NULL)          if ((fp = fopen(filename, "r")) == NULL)
46          {          {
47                  log_error("fopen(%s) error: %d\n", filename, errno);                  log_error("fopen(%s) error: %d", filename, errno);
48                  return -2;                  return -2;
49          }          }
50    
# Line 51  int bwf_load(const char *filename) Line 53  int bwf_load(const char *filename)
53                  len_line = strnlen(line, sizeof(line) - 1);                  len_line = strnlen(line, sizeof(line) - 1);
54                  if (!feof(fp) && line[len_line - 1] != '\n')                  if (!feof(fp) && line[len_line - 1] != '\n')
55                  {                  {
56                          log_error("Data line %d (len=%d) is truncated\n", line_id, len_line);                          log_error("Data line %d (len=%d) is truncated", line_id, len_line);
57                          bwf_pattern_str[0] = '\0';                          bwf_pattern_str[0] = '\0';
58                          return -3;                          return -3;
59                  }                  }
60    
61                  if (line[len_line - 1] == '\n')                  while (len_line > 0 && (line[len_line - 1] == '\n' || line[len_line - 1] == '\r'))
62                  {                  {
63                          line[len_line - 1] = '\0';                          line[len_line - 1] = '\0';
64                            len_line--;
65                    }
66    
67                    if (len_line == 0)
68                    {
69                            continue;
70                  }                  }
71    
72                  if (p > bwf_pattern_str)                  if (p > bwf_pattern_str)
# Line 68  int bwf_load(const char *filename) Line 76  int bwf_load(const char *filename)
76    
77                  if (len_line + 2 > sizeof(bwf_pattern_str) - 1 - (size_t)(p - bwf_pattern_str))                  if (len_line + 2 > sizeof(bwf_pattern_str) - 1 - (size_t)(p - bwf_pattern_str))
78                  {                  {
79                          log_error("Data in %s exceed length limit %d\n", filename, sizeof(bwf_pattern_str) - 1);                          log_error("Data in %s exceed length limit %d", filename, sizeof(bwf_pattern_str) - 1);
80                          bwf_pattern_str[0] = '\0';                          bwf_pattern_str[0] = '\0';
81                          return -3;                          return -3;
82                  }                  }
# Line 83  int bwf_load(const char *filename) Line 91  int bwf_load(const char *filename)
91    
92          fclose(fp);          fclose(fp);
93    
94  #ifdef _DEBUG          log_debug("Debug: bwf_pattern_str: %s", bwf_pattern_str);
95          log_error("Debug: bwf_pattern_str: %s\n", bwf_pattern_str);  
96  #endif          return 0;
97    }
98    
99    int bwf_compile(void)
100    {
101            int errorcode;
102            PCRE2_SIZE erroroffset;
103    
104            bwf_cleanup();
105    
         bwf_unload();  
           
106          bwf_code = pcre2_compile((PCRE2_SPTR)bwf_pattern_str, PCRE2_ZERO_TERMINATED, PCRE2_CASELESS, &errorcode, &erroroffset, NULL);          bwf_code = pcre2_compile((PCRE2_SPTR)bwf_pattern_str, PCRE2_ZERO_TERMINATED, PCRE2_CASELESS, &errorcode, &erroroffset, NULL);
107          if (bwf_code == NULL)          if (bwf_code == NULL)
108          {          {
109                  log_error("pcre2_compile() error: %d", errorcode);                  log_error("pcre2_compile() error: %d", errorcode);
110                  return -4;                  return -1;
111          }          }
112    
113          return 0;          return 0;
114  }  }
115    
116  void bwf_unload(void)  void bwf_cleanup(void)
117  {  {
118          if (bwf_code != NULL)          if (bwf_code != NULL)
119          {          {
# Line 111  void bwf_unload(void) Line 125  void bwf_unload(void)
125  int check_badwords(char *str, char c_mask)  int check_badwords(char *str, char c_mask)
126  {  {
127          pcre2_match_data *match_data;          pcre2_match_data *match_data;
128            PCRE2_SIZE startoffset = 0;
129          PCRE2_SIZE *ovector;          PCRE2_SIZE *ovector;
130            uint32_t match_count;
131          int ret;          int ret;
132          int i;          int i;
133            int total_match_count = 0;
134    
135          if (bwf_code == NULL)          if (bwf_code == NULL)
136          {          {
137                  log_error("BWF not loaded\n");                  log_error("BWF not loaded");
138                  return -1;                  return -1;
139          }          }
140    
141          match_data = pcre2_match_data_create_from_pattern(bwf_code, NULL);          match_data = pcre2_match_data_create_from_pattern(bwf_code, NULL);
142    
143          ret = pcre2_match(bwf_code, (PCRE2_SPTR)str, PCRE2_ZERO_TERMINATED, 0, 0, match_data, NULL);          while (1)
         if (ret == PCRE2_ERROR_NOMATCH)  
144          {          {
145                  ret = 0;                  ret = pcre2_match(bwf_code, (PCRE2_SPTR)str, PCRE2_ZERO_TERMINATED, startoffset, 0, match_data, NULL);
146          }                  if (ret == PCRE2_ERROR_NOMATCH)
         else if (ret < 0)  
         {  
                 log_error("pcre2_match() error: %d\n", ret);  
         }  
         else if (ret == 0)  
         {  
                 log_error("Vector of offsets is too small\n");  
         }  
         else // ret >= 1  
         {  
                 ovector = pcre2_get_ovector_pointer(match_data);  
                 i = ret - 1;  
   
                 if (ovector[i * 2] == -1 || ovector[i * 2 + 1] == -1)  
147                  {                  {
148                          log_error("Bug: match pattern #%d with invalid offsets [%d, %d)",                          ret = total_match_count;
149                                            i, ovector[i * 2], ovector[i * 2 + 1]);                          break;
                         ret = -2;  
150                  }                  }
151                  else                  else if (ret < 0)
152                  {                  {
153  #ifdef _DEBUG                          log_error("pcre2_match() error: %d", ret);
154                          log_error("Debug: match pattern #%d at offsets [%d, %d]\n",                  }
155                                            i, ovector[i * 2], ovector[i * 2 + 1] - ovector[i * 2]);                  else if (ret == 0)
156  #endif                  {
157                          memset(str + ovector[i * 2], c_mask, ovector[i * 2 + 1] - ovector[i * 2]);                          log_error("Vector of offsets is too small");
158                    }
159                    else // ret >= 1
160                    {
161                            ovector = pcre2_get_ovector_pointer(match_data);
162                            match_count = pcre2_get_ovector_count(match_data);
163    
164                            i = ret - 1;
165                            if (ovector[i * 2] == -1 || ovector[i * 2 + 1] == -1)
166                            {
167                                    log_error("Bug: match pattern #%d of %d with invalid offsets [%d, %d)",
168                                                      i, match_count, ovector[i * 2], ovector[i * 2 + 1]);
169                                    ret = -2;
170                            }
171                            else
172                            {
173                                    log_debug("Debug: match pattern #%d of %d at offsets [%d, %d]",
174                                                      i, match_count, ovector[i * 2], ovector[i * 2 + 1] - ovector[i * 2]);
175                                    memset(str + ovector[i * 2], c_mask, ovector[i * 2 + 1] - ovector[i * 2]);
176                                    total_match_count++;
177                                    startoffset = ovector[i * 2 + 1];
178                            }
179                  }                  }
180          }          }
181    


Legend:
Removed lines/characters  
Changed lines/characters
  Added lines/characters

webmaster@leafok.com
ViewVC Help
Powered by ViewVC 1.3.0-beta1