filter_helper_functions.cpp
1 /** 2 * @file filter_helper_functions.cpp 3 * @author Rene Ceska xceska06 (xceska06@stud.fit.vutbr.cz) 4 * @date 2023-11-19 5 */ 6 #include "inc/filter_helper_functions.h" 7 8 bool substrFilterHandler(SubstringFilter *sf, int *err, 9 std::vector<unsigned char> attribute) { 10 std::vector<unsigned char> attributeInital = {}; 11 std::vector<unsigned char> attributeMiddle = {}; 12 std::vector<unsigned char> attributeFinal = {}; 13 14 // extract initial 15 if (!sf->getSubInitial().empty()) { 16 if (attribute.size() >= sf->getSubInitial().size()) { 17 attributeInital = std::vector<unsigned char>( 18 attribute.begin(), attribute.begin() + sf->getSubInitial().size()); 19 attributeMiddle = std::vector<unsigned char>( 20 attribute.begin() + sf->getSubInitial().size(), attribute.end()); 21 } else { 22 return false; 23 } 24 } else { 25 attributeMiddle = 26 std::vector<unsigned char>(attribute.begin(), attribute.end()); 27 } 28 29 // extract final 30 if (!sf->getSubFinal().empty()) { 31 if (attribute.size() >= sf->getSubFinal().size()) { 32 attributeFinal = std::vector<unsigned char>( 33 attribute.end() - sf->getSubFinal().size(), attribute.end()); 34 if (attributeMiddle.size() > sf->getSubFinal().size()) { 35 attributeMiddle = std::vector<unsigned char>( 36 attributeMiddle.begin(), 37 attributeMiddle.end() - sf->getSubFinal().size()); 38 } 39 } else { 40 return false; 41 } 42 } 43 44 // check subInitial 45 if (!sf->getSubInitial().empty() && 46 ToLowerCase(attributeInital) != ToLowerCase(sf->getSubInitial())) { 47 return false; 48 } 49 // check subFinal 50 if (!sf->getSubFinal().empty() && 51 ToLowerCase(attributeFinal) != ToLowerCase(sf->getSubFinal())) { 52 return false; 53 } 54 unsigned long int x = 0; 55 56 // convert to lower case 57 attributeMiddle = ToLowerCase(attributeMiddle); 58 59 for (unsigned long int y = 0; y < sf->getSubAny().size(); y++) { 60 bool match = false; 61 for (; x < attributeMiddle.size(); x++) { 62 63 if (attributeMiddle[x] == std::tolower(sf->getSubAny()[y][0])) { 64 match = true; 65 for (unsigned long int z = 0; z < sf->getSubAny()[y].size(); z++) { 66 if (attributeMiddle[x + z] != std::tolower(sf->getSubAny()[y][z])) { 67 match = false; 68 break; 69 } 70 } 71 if (match) { 72 break; 73 } 74 } 75 } 76 if (!match) { 77 return false; 78 } 79 } 80 return true; 81 } 82 83 bool equalityMatchHandler(EqualityMatchFilter *emf, int *err, 84 std::vector<unsigned char> attribute) { 85 if (ToLowerCase(emf->getAssertionValue()) == ToLowerCase(attribute)) { 86 return true; 87 } 88 return false; 89 } 90 91 bool filterLine(FilterObject *f, int *err, DatabaseObject &databaseEntry) { 92 93 // cn 94 std::vector<unsigned char> cn = {'c', 'n'}; 95 // CommonName 96 std::vector<unsigned char> CommonName = {'c', 'o', 'm', 'm', 'o', 97 'n', 'n', 'a', 'm', 'e'}; 98 // email 99 std::vector<unsigned char> email = {'e', 'm', 'a', 'i', 'l'}; 100 // email 101 std::vector<unsigned char> mail = {'m', 'a', 'i', 'l'}; 102 // uid 103 std::vector<unsigned char> uid = {'u', 'i', 'd'}; 104 // UserID 105 std::vector<unsigned char> UserID = {'u', 's', 'e', 'r', 'i', 'd'}; 106 107 switch (f->getFilterType()) { 108 case equalityMatch: { 109 std::vector<unsigned char> attributeDescription = 110 ToLowerCase(((EqualityMatchFilter *)f)->getAttributeDescription()); 111 if (attributeDescription == cn || attributeDescription == CommonName) { 112 return equalityMatchHandler((EqualityMatchFilter *)f, err, 113 databaseEntry.get_name()); 114 } else if (attributeDescription == email || attributeDescription == mail) { 115 return equalityMatchHandler((EqualityMatchFilter *)f, err, 116 databaseEntry.get_email()); 117 } else if (attributeDescription == uid || attributeDescription == UserID) { 118 return equalityMatchHandler((EqualityMatchFilter *)f, err, 119 databaseEntry.get_uid()); 120 } else { 121 *err = 2; 122 return false; 123 } 124 125 } break; 126 case substrings: { 127 std::vector<unsigned char> attributeDescription = 128 ToLowerCase(((SubstringFilter *)f)->getAttributeDescription()); 129 if (attributeDescription == cn || attributeDescription == CommonName) { 130 return substrFilterHandler((SubstringFilter *)f, err, 131 databaseEntry.get_name()); 132 } else if (attributeDescription == email || attributeDescription == mail) { 133 return substrFilterHandler((SubstringFilter *)f, err, 134 databaseEntry.get_email()); 135 } else if (attributeDescription == uid || attributeDescription == UserID) { 136 return substrFilterHandler((SubstringFilter *)f, err, 137 databaseEntry.get_uid()); 138 } else { 139 *err = 2; 140 return false; 141 } 142 } break; 143 case AND: { 144 AndFilter *af = (AndFilter *)f; 145 for (unsigned long int i = 0; i < af->filters.size(); i++) { 146 if (!filterLine(af->filters[i], err, databaseEntry)) { 147 return false; 148 } 149 } 150 return true; 151 152 } break; 153 case OR: { 154 OrFilter *of = (OrFilter *)f; 155 for (unsigned long int i = 0; i < of->filters.size(); i++) { 156 if (filterLine(of->filters[i], err, databaseEntry)) { 157 return true; 158 } 159 } 160 return false; 161 } break; 162 case NOT: { 163 NotFilter *nf = (NotFilter *)f; 164 bool result = !filterLine((nf->filter), err, databaseEntry); 165 if (*err == 2) 166 return false; 167 return result; 168 } break; 169 default: 170 return false; 171 } 172 return false; 173 } 174 175 std::vector<DatabaseObject> filterHandler(FilterObject *f, int *err, 176 const char *dbLocation, 177 int sizeLimit) { 178 std::vector<DatabaseObject> resultDB; 179 int dbErr = 0; 180 DatabaseController db(dbLocation); 181 int lineCounter = 0; 182 while (true) { 183 184 DatabaseObject obj = db.loadNextRow(&dbErr); 185 186 if (dbErr != 0) 187 break; 188 189 if (filterLine(f, err, obj)) { 190 resultDB.push_back(obj); 191 lineCounter++; 192 } 193 194 if (lineCounter >= sizeLimit && sizeLimit != 0) { 195 *err = 1; 196 break; 197 } 198 } 199 200 return resultDB; 201 } 202 203 FilterObject * 204 convertToFilterObject(std::vector<unsigned char>::iterator BERfilter, 205 std::vector<unsigned char>::iterator end) { 206 207 FilterObject *f; 208 int err; 209 int lenght = 0; 210 int ll = 0; 211 std::vector<unsigned char> attributeDescription; 212 std::vector<unsigned char> assertionValue; 213 214 switch (getFilterType(BERfilter)) { 215 case equalityMatch: 216 217 GoIntoTag(BERfilter, &err, end); 218 if (err != 0) 219 return new FilterObject(); 220 lenght = GetLength(BERfilter + 1, &err, end); 221 222 ll = GetLengthOfLength(BERfilter + 1, &err, end); 223 224 for (int i = 0; i < lenght; i++) { 225 attributeDescription.push_back(BERfilter[1 + ll + i]); 226 } 227 228 SkipTags(BERfilter, 1, &err, end); 229 if (err != 0) 230 return new FilterObject(); 231 232 lenght = GetLength(BERfilter + 1, &err, end); 233 ll = GetLengthOfLength(BERfilter + 1, &err, end); 234 235 for (int i = 0; i < lenght; i++) { 236 assertionValue.push_back(BERfilter[1 + ll + i]); 237 } 238 239 f = new EqualityMatchFilter(attributeDescription, assertionValue); 240 241 break; 242 case substrings: { 243 std::vector<unsigned char> attributeDescription; 244 std::vector<unsigned char> initial; 245 std::vector<std::vector<unsigned char>> any; 246 std::vector<unsigned char> final; 247 GoIntoTag(BERfilter, &err, end); 248 if (err != 0) 249 return new FilterObject(); 250 lenght = GetLength(BERfilter + 1, &err, end); 251 ll = GetLengthOfLength(BERfilter + 1, &err, end); 252 253 for (int i = 0; i < lenght; i++) { 254 attributeDescription.push_back(BERfilter[1 + ll + i]); 255 } 256 257 SkipTags(BERfilter, 1, &err, end); 258 if (err != 0) 259 return new FilterObject(); 260 int lenghtOfSequence = GetLength(BERfilter + 1, &err, end); 261 int lenghtOflenOfSequence = GetLengthOfLength(BERfilter + 1, &err, end); 262 GoIntoTag(BERfilter, &err, end); 263 if (err != 0) 264 return new FilterObject(); 265 266 int currentBitPointer = 0; 267 while (currentBitPointer < lenghtOfSequence + lenghtOflenOfSequence) { 268 switch (BERfilter[0]) { 269 case 0x80: { 270 int dataLenght = GetLength(BERfilter + 1, &err, end); 271 int LenghtLenght = GetLengthOfLength(BERfilter + 1, &err, end); 272 initial = std::vector<unsigned char>(BERfilter + 1 + LenghtLenght, 273 BERfilter + 1 + LenghtLenght + 274 dataLenght); 275 } break; 276 case 0x81: { 277 int dataLenght = GetLength(BERfilter + 1, &err, end); 278 int LenghtLenght = GetLengthOfLength(BERfilter + 1, &err, end); 279 std::vector<unsigned char> tmp = std::vector<unsigned char>( 280 BERfilter + 1 + LenghtLenght, 281 BERfilter + 1 + LenghtLenght + dataLenght); 282 any.push_back(tmp); 283 } break; 284 case 0x82: { 285 int dataLenght = GetLength(BERfilter + 1, &err, end); 286 int LenghtLenght = GetLengthOfLength(BERfilter + 1, &err, end); 287 final = std::vector<unsigned char>(BERfilter + 1 + LenghtLenght, 288 BERfilter + 1 + LenghtLenght + 289 dataLenght); 290 } break; 291 } 292 currentBitPointer += 1 + GetLengthOfLength(BERfilter + 1, &err, end) + 293 GetLength(BERfilter + 1, &err, end); 294 SkipTags(BERfilter, 1, &err, end); 295 } 296 f = new SubstringFilter(attributeDescription, initial, any, final); 297 298 } break; 299 case AND: 300 f = new AndFilter(); 301 302 lenght = GetLength(BERfilter + 1, &err, end); 303 GoIntoTag(BERfilter, &err, end); 304 if (err != 0) 305 return new FilterObject(); 306 for (int i = 0; i < lenght;) { 307 308 if (err != 0) 309 return new FilterObject(); 310 FilterObject *tmpF = convertToFilterObject(BERfilter, end); 311 printf("filter type: %d\n", tmpF->getFilterType()); 312 fflush(stdout); 313 ((AndFilter *)f)->filters.push_back(tmpF); 314 i += 1 + GetLengthOfLength(BERfilter + 1, &err, end) + 315 GetLength(BERfilter + 1, &err, end); 316 SkipTags(BERfilter, 1, &err, end); 317 } 318 319 break; 320 case OR: 321 f = new OrFilter(); 322 lenght = GetLength(BERfilter + 1, &err, end); 323 GoIntoTag(BERfilter, &err, end); 324 if (err != 0) 325 return new FilterObject(); 326 327 for (int i = 0; i < lenght;) { 328 if (err != 0) 329 return new FilterObject(); 330 FilterObject *tmpF = convertToFilterObject(BERfilter, end); 331 ((OrFilter *)f)->filters.push_back(tmpF); 332 i += 1 + GetLengthOfLength(BERfilter + 1, &err, end) + 333 GetLength(BERfilter + 1, &err, end); 334 SkipTags(BERfilter, 1, &err, end); 335 } 336 337 break; 338 case NOT: { 339 f = new NotFilter(); 340 lenght = GetLength(BERfilter + 1, &err, end); 341 GoIntoTag(BERfilter, &err, end); 342 if (err != 0) 343 return new FilterObject(); 344 FilterObject *tmpF = convertToFilterObject(BERfilter, end); 345 ((NotFilter *)f)->filter = tmpF; 346 break; 347 } 348 default: 349 f = new FilterObject(); 350 break; 351 } 352 return f; 353 }