• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

jasonish / suricata / 23105300094

15 Mar 2026 06:48AM UTC coverage: 75.784% (-0.7%) from 76.495%
23105300094

push

github

jasonish
github-ci: ubuntu minimal build fixups

- Don't run on the GitHub provided VM, it contains a newer Rust than
  stock Ubuntu does.

252836 of 333628 relevant lines covered (75.78%)

1978514.46 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

89.97
/src/util-reference-config.c
1
/* Copyright (C) 2007-2022 Open Information Security Foundation
2
 *
3
 * You can copy, redistribute or modify this Program under the terms of
4
 * the GNU General Public License version 2 as published by the Free
5
 * Software Foundation.
6
 *
7
 * This program is distributed in the hope that it will be useful,
8
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
 * GNU General Public License for more details.
11
 *
12
 * You should have received a copy of the GNU General Public License
13
 * version 2 along with this program; if not, write to the Free Software
14
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15
 * 02110-1301, USA.
16
 */
17

18
/**
19
 * \file
20
 *
21
 * \author Anoop Saldanha <anoopsaldanha@gmail.com>
22
 */
23

24
#include "suricata-common.h"
25
#include "detect.h"
26
#include "detect-engine.h"
27
#include "util-hash.h"
28

29
#include "util-reference-config.h"
30
#include "conf.h"
31
#include "util-unittest.h"
32
#include "util-debug.h"
33
#include "util-fmemopen.h"
34

35
/* Regex to parse each line from reference.config file.  The first substring
36
 * is for the system name and the second for the url */
37
/*-----------------------------------------------------------system-------------------url----*/
38
#define SC_RCONF_REGEX "^\\s*config\\s+reference\\s*:\\s*([a-zA-Z][a-zA-Z0-9-_]*)\\s+(.+)\\s*$"
3,309✔
39

40
/* Default path for the reference.conf file */
41
#define SC_RCONF_DEFAULT_FILE_PATH CONFIG_DIR "/reference.config"
1,529✔
42

43
/* the hash functions */
44
uint32_t SCRConfReferenceHashFunc(HashTable *ht, void *data, uint16_t datalen);
45
char SCRConfReferenceHashCompareFunc(void *data1, uint16_t datalen1,
46
                                     void *data2, uint16_t datalen2);
47
void SCRConfReferenceHashFree(void *ch);
48

49
/* used to get the reference.config file path */
50
static const char *SCRConfGetConfFilename(const DetectEngineCtx *de_ctx);
51

52
void SCReferenceSCConfInit(DetectEngineCtx *de_ctx)
53
{
3,309✔
54
    int en;
3,309✔
55
    PCRE2_SIZE eo;
3,309✔
56
    int opts = 0;
3,309✔
57

58
    de_ctx->reference_conf_regex =
3,309✔
59
            pcre2_compile((PCRE2_SPTR8)SC_RCONF_REGEX, PCRE2_ZERO_TERMINATED, opts, &en, &eo, NULL);
3,309✔
60
    if (de_ctx->reference_conf_regex == NULL) {
3,309✔
61
        PCRE2_UCHAR errbuffer[256];
×
62
        pcre2_get_error_message(en, errbuffer, sizeof(errbuffer));
×
63
        SCLogWarning("pcre2 compile of \"%s\" failed at "
×
64
                     "offset %d: %s",
×
65
                SC_RCONF_REGEX, (int)eo, errbuffer);
×
66
        return;
×
67
    }
×
68
    de_ctx->reference_conf_regex_match =
3,309✔
69
            pcre2_match_data_create_from_pattern(de_ctx->reference_conf_regex, NULL);
3,309✔
70
}
3,309✔
71

72
void SCReferenceConfDeinit(DetectEngineCtx *de_ctx)
73
{
3,258✔
74
    if (de_ctx->reference_conf_regex != NULL) {
3,258✔
75
        pcre2_code_free(de_ctx->reference_conf_regex);
3,255✔
76
        de_ctx->reference_conf_regex = NULL;
3,255✔
77
    }
3,255✔
78
    if (de_ctx->reference_conf_regex_match != NULL) {
3,258✔
79
        pcre2_match_data_free(de_ctx->reference_conf_regex_match);
3,255✔
80
        de_ctx->reference_conf_regex_match = NULL;
3,255✔
81
    }
3,255✔
82
}
3,258✔
83

84

85
/**
86
 * \brief Inits the context to be used by the Reference Config parsing API.
87
 *
88
 *        This function initializes the hash table to be used by the Detection
89
 *        Engine Context to hold the data from reference.config file,
90
 *        obtains the file descriptor to parse the reference.config file, and
91
 *        inits the regex used to parse the lines from reference.config file.
92
 *
93
 * \param de_ctx Pointer to the Detection Engine Context.
94
 *
95
 * \note if file open fails, we leave de_ctx->reference_conf_ht initialized
96
 *
97
 * \retval  0 On success.
98
 * \retval -1 On failure.
99
 */
100
static FILE *SCRConfInitContextAndLocalResources(DetectEngineCtx *de_ctx, FILE *fd)
101
{
3,318✔
102
    /* init the hash table to be used by the reference config references */
103
    de_ctx->reference_conf_ht = HashTableInit(128, SCRConfReferenceHashFunc,
3,318✔
104
                                              SCRConfReferenceHashCompareFunc,
3,318✔
105
                                              SCRConfReferenceHashFree);
3,318✔
106
    if (de_ctx->reference_conf_ht == NULL) {
3,318✔
107
        SCLogError("Error initializing the hash "
×
108
                   "table");
×
109
        return NULL;
×
110
    }
×
111

112
    /* if it is not NULL, use the file descriptor.  The hack so that we can
113
     * avoid using a dummy reference file for testing purposes and
114
     * instead use an input stream against a buffer containing the
115
     * reference strings */
116
    if (fd == NULL) {
3,318✔
117
        const char *filename = SCRConfGetConfFilename(de_ctx);
3,309✔
118
        if ((fd = fopen(filename, "r")) == NULL) {
3,309✔
119
#ifdef UNITTESTS
1,514✔
120
            if (RunmodeIsUnittests()) {
1,514✔
121
                return NULL; // silently fail
1,481✔
122
            }
1,481✔
123
#endif
33✔
124
            SCLogError("Error opening file: \"%s\": %s", filename, strerror(errno));
82✔
125
            return NULL;
82✔
126
        }
1,563✔
127
    }
3,309✔
128

129
    return fd;
1,755✔
130
}
3,318✔
131

132

133
/**
134
 * \brief Returns the path for the Reference Config file.  We check if we
135
 *        can retrieve the path from the yaml conf file.  If it is not present,
136
 *        return the default path for the reference.config file which is
137
 *        "./reference.config".
138
 *
139
 * \retval log_filename Pointer to a string containing the path for the
140
 *                      reference.config file.
141
 */
142
static const char *SCRConfGetConfFilename(const DetectEngineCtx *de_ctx)
143
{
3,309✔
144
    const char *path = NULL;
3,309✔
145

146
    if (de_ctx != NULL && strlen(de_ctx->config_prefix) > 0) {
3,309✔
147
        char config_value[256];
12✔
148
        snprintf(config_value, sizeof(config_value),
12✔
149
                 "%s.reference-config-file", de_ctx->config_prefix);
12✔
150

151
        /* try loading prefix setting, fall back to global if that
152
         * fails. */
153
        if (SCConfGet(config_value, &path) != 1) {
12✔
154
            if (SCConfGet("reference-config-file", &path) != 1) {
12✔
155
                return (char *)SC_RCONF_DEFAULT_FILE_PATH;
×
156
            }
×
157
        }
12✔
158
    } else {
3,297✔
159
        if (SCConfGet("reference-config-file", &path) != 1) {
3,297✔
160
            return (char *)SC_RCONF_DEFAULT_FILE_PATH;
1,529✔
161
        }
1,529✔
162
    }
3,297✔
163
    return path;
1,780✔
164
}
3,309✔
165

166
/**
167
 * \brief Releases local resources used by the Reference Config API.
168
 */
169
static void SCRConfDeInitLocalResources(FILE *fd)
170
{
1,755✔
171
    if (fd != NULL) {
1,755✔
172
        fclose(fd);
1,755✔
173
    }
1,755✔
174
}
1,755✔
175

176
/**
177
 * \brief Releases de_ctx resources related to Reference Config API.
178
 */
179
void SCRConfDeInitContext(DetectEngineCtx *de_ctx)
180
{
3,267✔
181
    if (de_ctx->reference_conf_ht != NULL)
3,267✔
182
        HashTableFree(de_ctx->reference_conf_ht);
3,264✔
183

184
    de_ctx->reference_conf_ht = NULL;
3,267✔
185
}
3,267✔
186

187
/**
188
 * \brief Converts a string to lowercase.
189
 *
190
 * \param str Pointer to the string to be converted.
191
 */
192
static char *SCRConfStringToLowercase(const char *str)
193
{
71,599✔
194
    char *new_str = NULL;
71,599✔
195
    char *temp_str = NULL;
71,599✔
196

197
    if ((new_str = SCStrdup(str)) == NULL) {
71,599✔
198
        return NULL;
×
199
    }
×
200

201
    temp_str = new_str;
71,599✔
202
    while (*temp_str != '\0') {
400,076✔
203
        *temp_str = u8_tolower((unsigned char)*temp_str);
328,477✔
204
        temp_str++;
328,477✔
205
    }
328,477✔
206

207
    return new_str;
71,599✔
208
}
71,599✔
209

210
/**
211
 * \brief Parses a line from the reference config file and adds it to Reference
212
 *        Config hash table DetectEngineCtx->reference_conf_ht.
213
 *
214
 * \param rawstr Pointer to the string to be parsed.
215
 * \param de_ctx Pointer to the Detection Engine Context.
216
 *
217
 * \retval  0 On success.
218
 * \retval -1 On failure.
219
 */
220
int SCRConfAddReference(DetectEngineCtx *de_ctx, const char *line)
221
{
33,187✔
222
    char system[REFERENCE_SYSTEM_NAME_MAX];
33,187✔
223
    char url[REFERENCE_CONTENT_NAME_MAX];
33,187✔
224

225
    SCRConfReference *ref_new = NULL;
33,187✔
226
    SCRConfReference *ref_lookup = NULL;
33,187✔
227

228
    int ret = 0;
33,187✔
229

230
    ret = pcre2_match(de_ctx->reference_conf_regex, (PCRE2_SPTR8)line, strlen(line), 0, 0,
33,187✔
231
            de_ctx->reference_conf_regex_match, NULL);
33,187✔
232
    if (ret < 0) {
33,187✔
233
        SCLogError("Invalid Reference Config in "
18✔
234
                   "reference.config file");
18✔
235
        goto error;
18✔
236
    }
18✔
237

238
    /* retrieve the reference system */
239
    size_t copylen = sizeof(system);
33,169✔
240
    ret = pcre2_substring_copy_bynumber(
33,169✔
241
            de_ctx->reference_conf_regex_match, 1, (PCRE2_UCHAR8 *)system, &copylen);
33,169✔
242
    if (ret < 0) {
33,169✔
243
        SCLogError("pcre2_substring_copy_bynumber() failed");
×
244
        goto error;
×
245
    }
×
246

247
    /* retrieve the reference url */
248
    copylen = sizeof(url);
33,169✔
249
    ret = pcre2_substring_copy_bynumber(
33,169✔
250
            de_ctx->reference_conf_regex_match, 2, (PCRE2_UCHAR8 *)url, &copylen);
33,169✔
251
    if (ret < 0) {
33,169✔
252
        SCLogError("pcre2_substring_copy_bynumber() failed");
×
253
        goto error;
×
254
    }
×
255

256
    /* Create a new instance of the parsed Reference string */
257
    ref_new = SCRConfAllocSCRConfReference(system, url);
33,169✔
258
    if (ref_new == NULL)
33,169✔
259
        goto error;
×
260

261
    /* Check if the Reference is present in the HashTable.  In case it's present
262
     * ignore it, as it's a duplicate.  If not present, add it to the table */
263
    ref_lookup = HashTableLookup(de_ctx->reference_conf_ht, ref_new, 0);
33,169✔
264
    if (ref_lookup == NULL) {
33,169✔
265
        if (HashTableAdd(de_ctx->reference_conf_ht, ref_new, 0) < 0) {
33,159✔
266
            SCLogDebug("HashTable Add failed");
×
267
        }
×
268
    } else {
33,159✔
269
        SCLogDebug("Duplicate reference found inside reference.config");
10✔
270
        SCRConfDeAllocSCRConfReference(ref_new);
10✔
271
    }
10✔
272

273
    return 0;
33,169✔
274

275
 error:
18✔
276
    return -1;
18✔
277
}
33,169✔
278

279
/**
280
 * \brief Checks if a string is a comment or a blank line.
281
 *
282
 *        Comments lines are lines of the following format -
283
 *        "# This is a comment string" or
284
 *        "   # This is a comment string".
285
 *
286
 * \param line String that has to be checked.
287
 *
288
 * \retval 1 On the argument string being a comment or blank line.
289
 * \retval 0 Otherwise.
290
 */
291
static int SCRConfIsLineBlankOrComment(char *line)
292
{
76,781✔
293
    while (*line != '\0') {
90,733✔
294
        /* we have a comment */
295
        if (*line == '#')
76,781✔
296
            return 1;
29,648✔
297

298
        /* this line is neither a comment line, nor a blank line */
299
        if (!isspace((unsigned char)*line))
47,133✔
300
            return 0;
33,181✔
301

302
        line++;
13,952✔
303
    }
13,952✔
304

305
    /* we have a blank line */
306
    return 1;
13,952✔
307
}
76,781✔
308

309
/**
310
 * \brief Parses the Reference Config file and updates the
311
 *        DetectionEngineCtx->reference_conf_ht with the Reference information.
312
 *
313
 * \param de_ctx Pointer to the Detection Engine Context.
314
 */
315
static bool SCRConfParseFile(DetectEngineCtx *de_ctx, FILE *fd)
316
{
1,755✔
317
    char line[1024];
1,755✔
318
    int runmode = SCRunmodeGet();
1,755✔
319
    bool is_conf_test_mode = runmode == RUNMODE_CONF_TEST;
1,755✔
320
    while (fgets(line, sizeof(line), fd) != NULL) {
78,535✔
321
        if (SCRConfIsLineBlankOrComment(line))
76,781✔
322
            continue;
43,600✔
323

324
        if (SCRConfAddReference(de_ctx, line) != 0) {
33,181✔
325
            if (is_conf_test_mode) {
18✔
326
                return false;
1✔
327
            }
1✔
328
        }
18✔
329
    }
33,181✔
330

331
#ifdef UNITTESTS
9✔
332
    if (de_ctx != NULL && strlen(de_ctx->config_prefix) > 0)
9✔
333
        SCLogInfo("tenant id %d: Added \"%d\" reference types from the reference.config file",
334
                de_ctx->tenant_id, de_ctx->reference_conf_ht->count);
9✔
335
    else
9✔
336
        SCLogInfo("Added \"%d\" reference types from the reference.config file",
9✔
337
                de_ctx->reference_conf_ht->count);
9✔
338
#endif /* UNITTESTS */
9✔
339
    return true;
1,754✔
340
}
1,755✔
341

342
/**
343
 * \brief Returns a new SCRConfReference instance.  The reference string
344
 *        is converted into lowercase, before being assigned to the instance.
345
 *
346
 * \param system  Pointer to the system.
347
 * \param url     Pointer to the reference url.
348
 *
349
 * \retval ref Pointer to the new instance of SCRConfReference.
350
 */
351
SCRConfReference *SCRConfAllocSCRConfReference(const char *system,
352
                                               const char *url)
353
{
71,599✔
354
    SCRConfReference *ref = NULL;
71,599✔
355

356
    if (system == NULL) {
71,599✔
357
        SCLogError("Invalid arguments.  system NULL");
×
358
        return NULL;
×
359
    }
×
360

361
    if ((ref = SCCalloc(1, sizeof(SCRConfReference))) == NULL) {
71,599✔
362
        return NULL;
×
363
    }
×
364

365
    if ((ref->system = SCRConfStringToLowercase(system)) == NULL) {
71,599✔
366
        SCFree(ref);
×
367
        return NULL;
×
368
    }
×
369

370
    if (url != NULL && (ref->url = SCStrdup(url)) == NULL) {
71,599✔
371
        SCFree(ref->system);
×
372
        SCFree(ref);
×
373
        return NULL;
×
374
    }
×
375

376
    return ref;
71,599✔
377
}
71,599✔
378

379
/**
380
 * \brief Frees a SCRConfReference instance.
381
 *
382
 * \param Pointer to the SCRConfReference instance that has to be freed.
383
 */
384
void SCRConfDeAllocSCRConfReference(SCRConfReference *ref)
385
{
70,573✔
386
    if (ref != NULL) {
70,573✔
387
        if (ref->system != NULL)
70,573✔
388
            SCFree(ref->system);
70,573✔
389

390
        if (ref->url != NULL)
70,573✔
391
            SCFree(ref->url);
32,143✔
392

393
        SCFree(ref);
70,573✔
394
    }
70,573✔
395
}
70,573✔
396

397
/**
398
 * \brief Hashing function to be used to hash the Reference name.  Would be
399
 *        supplied as an argument to the HashTableInit function for
400
 *        DetectEngineCtx->reference_conf_ht.
401
 *
402
 * \param ht      Pointer to the HashTable.
403
 * \param data    Pointer to the data to be hashed.  In this case, the data
404
 *                would be a pointer to a SCRConfReference instance.
405
 * \param datalen Not used by this function.
406
 */
407
uint32_t SCRConfReferenceHashFunc(HashTable *ht, void *data, uint16_t datalen)
408
{
104,758✔
409
    SCRConfReference *ref = (SCRConfReference *)data;
104,758✔
410
    uint32_t hash = 0;
104,758✔
411
    size_t i = 0;
104,758✔
412

413
    size_t len = strlen(ref->system);
104,758✔
414

415
    for (i = 0; i < len; i++)
642,601✔
416
        hash += u8_tolower((unsigned char)ref->system[i]);
537,843✔
417

418
    hash = hash % ht->array_size;
104,758✔
419

420
    return hash;
104,758✔
421
}
104,758✔
422

423
/**
424
 * \brief Used to compare two References that have been stored in the HashTable.
425
 *        This function is supplied as an argument to the HashTableInit function
426
 *        for DetectionEngineCtx->reference_conf_ct.
427
 *
428
 * \param data1 Pointer to the first SCRConfReference to be compared.
429
 * \param len1  Not used by this function.
430
 * \param data2 Pointer to the second SCRConfReference to be compared.
431
 * \param len2  Not used by this function.
432
 *
433
 * \retval 1 On data1 and data2 being equal.
434
 * \retval 0 On data1 and data2 not being equal.
435
 */
436
char SCRConfReferenceHashCompareFunc(void *data1, uint16_t datalen1,
437
                                     void *data2, uint16_t datalen2)
438
{
42,010✔
439
    SCRConfReference *ref1 = (SCRConfReference *)data1;
42,010✔
440
    SCRConfReference *ref2 = (SCRConfReference *)data2;
42,010✔
441

442
    if (ref1 == NULL || ref2 == NULL)
42,010✔
443
        return 0;
×
444

445
    if (ref1->system == NULL || ref2->system == NULL)
42,010✔
446
        return 0;
×
447

448
    if (strcmp(ref1->system, ref2->system) == 0) {
42,010✔
449
        SCLogDebug("Match found inside Reference-Config hash function");
38,424✔
450
        return 1;
38,424✔
451
    }
38,424✔
452

453
    return 0;
3,586✔
454
}
42,010✔
455

456
/**
457
 * \brief Used to free the Reference Config Hash Data that was stored in
458
 *        DetectEngineCtx->reference_conf_ht Hashtable.
459
 *
460
 * \param data Pointer to the data that has to be freed.
461
 */
462
void SCRConfReferenceHashFree(void *data)
463
{
32,133✔
464
    SCRConfDeAllocSCRConfReference(data);
32,133✔
465
}
32,133✔
466

467
/**
468
 * \brief Loads the Reference info from the reference.config file.
469
 *
470
 *        The reference.config file contains references that can be used in
471
 *        Signatures.  Each line of the file should have the following format -
472
 *        config reference: system_name, reference_url.
473
 *
474
 * \param de_ctx Pointer to the Detection Engine Context that should be updated
475
 *               with reference information.
476
 *
477
 * \retval  0 On success.
478
 * \retval -1 On failure.
479
 */
480
int SCRConfLoadReferenceConfigFile(DetectEngineCtx *de_ctx, FILE *fd)
481
{
3,318✔
482
    fd = SCRConfInitContextAndLocalResources(de_ctx, fd);
3,318✔
483
    if (fd == NULL) {
3,318✔
484
#ifdef UNITTESTS
1,514✔
485
        if (RunmodeIsUnittests()) {
1,514✔
486
            return -1;
1,481✔
487
        }
1,481✔
488
#endif
33✔
489
        SCLogError("please check the \"reference-config-file\" "
82✔
490
                   "option in your suricata.yaml file");
82✔
491
        return -1;
82✔
492
    }
1,563✔
493

494
    bool rc = SCRConfParseFile(de_ctx, fd);
3,318✔
495
    SCRConfDeInitLocalResources(fd);
1,755✔
496

497
    return rc ? 0 : -1;
1,755✔
498
}
3,318✔
499

500
/**
501
 * \brief Gets the reference config from the corresponding hash table stored
502
 *        in the Detection Engine Context's reference conf ht, given the
503
 *        reference name.
504
 *
505
 * \param ct_name Pointer to the reference name that has to be looked up.
506
 * \param de_ctx  Pointer to the Detection Engine Context.
507
 *
508
 * \retval lookup_rconf_info Pointer to the SCRConfReference instance from
509
 *                           the hash table on success; NULL on failure.
510
 */
511
SCRConfReference *SCRConfGetReference(const char *rconf_name,
512
                                      DetectEngineCtx *de_ctx)
513
{
38,430✔
514
    SCRConfReference *ref_conf = SCRConfAllocSCRConfReference(rconf_name, NULL);
38,430✔
515
    if (ref_conf == NULL)
38,430✔
516
        return NULL;
×
517
    SCRConfReference *lookup_ref_conf = HashTableLookup(de_ctx->reference_conf_ht,
38,430✔
518
                                                        ref_conf, 0);
38,430✔
519

520
    SCRConfDeAllocSCRConfReference(ref_conf);
38,430✔
521
    return lookup_ref_conf;
38,430✔
522
}
38,430✔
523

524
/*----------------------------------Unittests---------------------------------*/
525

526

527
#ifdef UNITTESTS
528

529
/**
530
 * \brief Creates a dummy reference config, with all valid references, for
531
 *        testing purposes.
532
 */
533
FILE *SCRConfGenerateValidDummyReferenceConfigFD01(void)
534
{
5✔
535
    const char *buffer =
5✔
536
        "config reference: one http://www.one.com\n"
5✔
537
        "config reference: two http://www.two.com\n"
5✔
538
        "config reference: three http://www.three.com\n"
5✔
539
        "config reference: one http://www.one.com\n"
5✔
540
        "config reference: three http://www.three.com\n";
5✔
541

542
    FILE *fd = SCFmemopen((void *)buffer, strlen(buffer), "r");
5✔
543
    if (fd == NULL)
5✔
544
        SCLogDebug("Error with SCFmemopen() called by Reference Config test code");
545

546
    return fd;
5✔
547
}
5✔
548

549
/**
550
 * \brief Creates a dummy reference config, with some valid references and a
551
 *        couple of invalid references, for testing purposes.
552
 */
553
FILE *SCRConfGenerateInvalidDummyReferenceConfigFD02(void)
554
{
2✔
555
    const char *buffer =
2✔
556
        "config reference: one http://www.one.com\n"
2✔
557
        "config_ reference: two http://www.two.com\n"
2✔
558
        "config reference_: three http://www.three.com\n"
2✔
559
        "config reference: four\n"
2✔
560
        "config reference five http://www.five.com\n";
2✔
561

562
    FILE *fd = SCFmemopen((void *)buffer, strlen(buffer), "r");
2✔
563
    if (fd == NULL)
2✔
564
        SCLogDebug("Error with SCFmemopen() called by Reference Config test code");
565

566
    return fd;
2✔
567
}
2✔
568

569
/**
570
 * \brief Creates a dummy reference config, with all invalid references, for
571
 *        testing purposes.
572
 */
573
FILE *SCRConfGenerateInvalidDummyReferenceConfigFD03(void)
574
{
2✔
575
    const char *buffer =
2✔
576
        "config reference one http://www.one.com\n"
2✔
577
        "config_ reference: two http://www.two.com\n"
2✔
578
        "config reference_: three http://www.three.com\n"
2✔
579
        "config reference: four\n";
2✔
580

581
    FILE *fd = SCFmemopen((void *)buffer, strlen(buffer), "r");
2✔
582
    if (fd == NULL)
2✔
583
        SCLogDebug("Error with SCFmemopen() called by Reference Config test code");
584

585
    return fd;
2✔
586
}
2✔
587

588
/**
589
 * \test Check that the reference file is loaded and the detection engine
590
 *       content reference_conf_ht loaded with the reference data.
591
 */
592
static int SCRConfTest01(void)
593
{
1✔
594
    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
1✔
595
    int result = 0;
1✔
596

597
    if (de_ctx == NULL)
1✔
598
        return result;
599

600
    SCRConfDeInitContext(de_ctx);
1✔
601
    FILE *fd = SCRConfGenerateValidDummyReferenceConfigFD01();
1✔
602
    SCRConfLoadReferenceConfigFile(de_ctx, fd);
1✔
603

604
    if (de_ctx->reference_conf_ht == NULL)
1✔
605
        goto end;
606

607
    result = (de_ctx->reference_conf_ht->count == 3);
1✔
608
    if (result == 0)
1✔
609
        printf("FAILED: de_ctx->reference_conf_ht->count %u: ", de_ctx->reference_conf_ht->count);
610

611
 end:
1✔
612
    if (de_ctx != NULL)
1✔
613
        DetectEngineCtxFree(de_ctx);
1✔
614
    return result;
1✔
615
}
1✔
616

617
/**
618
 * \test Check that invalid references present in the reference.config file
619
 *       aren't loaded.
620
 */
621
static int SCRConfTest02(void)
622
{
1✔
623
    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
1✔
624
    int result = 0;
1✔
625

626
    if (de_ctx == NULL)
1✔
627
        return result;
628

629
    SCRConfDeInitContext(de_ctx);
1✔
630
    FILE *fd = SCRConfGenerateInvalidDummyReferenceConfigFD03();
1✔
631
    SCRConfLoadReferenceConfigFile(de_ctx, fd);
1✔
632

633
    if (de_ctx->reference_conf_ht == NULL)
1✔
634
        goto end;
635

636
    result = (de_ctx->reference_conf_ht->count == 0);
1✔
637

638

639
 end:
1✔
640
    if (de_ctx != NULL)
1✔
641
        DetectEngineCtxFree(de_ctx);
1✔
642
    return result;
1✔
643
}
1✔
644

645
/**
646
 * \test Check that only valid references are loaded into the hash table from
647
 *       the reference.config file.
648
 */
649
static int SCRConfTest03(void)
650
{
1✔
651
    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
1✔
652
    int result = 0;
1✔
653

654
    if (de_ctx == NULL)
1✔
655
        return result;
656

657
    SCRConfDeInitContext(de_ctx);
1✔
658
    FILE *fd = SCRConfGenerateInvalidDummyReferenceConfigFD02();
1✔
659
    SCRConfLoadReferenceConfigFile(de_ctx, fd);
1✔
660

661
    if (de_ctx->reference_conf_ht == NULL)
1✔
662
        goto end;
663

664
    result = (de_ctx->reference_conf_ht->count == 1);
1✔
665

666
 end:
1✔
667
    if (de_ctx != NULL)
1✔
668
        DetectEngineCtxFree(de_ctx);
1✔
669
    return result;
1✔
670
}
1✔
671

672
/**
673
 * \test Check if the reference info from the reference.config file have
674
 *       been loaded into the hash table.
675
 */
676
static int SCRConfTest04(void)
677
{
1✔
678
    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
1✔
679
    int result = 1;
1✔
680

681
    if (de_ctx == NULL)
1✔
682
        return 0;
683

684
    SCRConfDeInitContext(de_ctx);
1✔
685
    FILE *fd = SCRConfGenerateValidDummyReferenceConfigFD01();
1✔
686
    SCRConfLoadReferenceConfigFile(de_ctx, fd);
1✔
687

688
    if (de_ctx->reference_conf_ht == NULL)
1✔
689
        goto end;
690

691
    result = (de_ctx->reference_conf_ht->count == 3);
1✔
692

693
    result &= (SCRConfGetReference("one", de_ctx) != NULL);
1✔
694
    result &= (SCRConfGetReference("two", de_ctx) != NULL);
1✔
695
    result &= (SCRConfGetReference("three", de_ctx) != NULL);
1✔
696
    result &= (SCRConfGetReference("four", de_ctx) == NULL);
1✔
697

698
 end:
1✔
699
    if (de_ctx != NULL)
1✔
700
        DetectEngineCtxFree(de_ctx);
1✔
701
    return result;
1✔
702
}
1✔
703

704
/**
705
 * \test Check if the reference info from the invalid reference.config file
706
 *       have not been loaded into the hash table, and cross verify to check
707
 *       that the hash table contains no reference data.
708
 */
709
static int SCRConfTest05(void)
710
{
1✔
711
    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
1✔
712
    int result = 1;
1✔
713

714
    if (de_ctx == NULL)
1✔
715
        return 0;
716

717
    SCRConfDeInitContext(de_ctx);
1✔
718
    FILE *fd = SCRConfGenerateInvalidDummyReferenceConfigFD03();
1✔
719
    SCRConfLoadReferenceConfigFile(de_ctx, fd);
1✔
720

721
    if (de_ctx->reference_conf_ht == NULL)
1✔
722
        goto end;
723

724
    result = (de_ctx->reference_conf_ht->count == 0);
1✔
725

726
    result &= (SCRConfGetReference("one", de_ctx) == NULL);
1✔
727
    result &= (SCRConfGetReference("two", de_ctx) == NULL);
1✔
728
    result &= (SCRConfGetReference("three", de_ctx) == NULL);
1✔
729
    result &= (SCRConfGetReference("four", de_ctx) == NULL);
1✔
730
    result &= (SCRConfGetReference("five", de_ctx) == NULL);
1✔
731

732
 end:
1✔
733
    if (de_ctx != NULL)
1✔
734
        DetectEngineCtxFree(de_ctx);
1✔
735
    return result;
1✔
736
}
1✔
737

738
/**
739
 * \test Check if the reference info from the reference.config file have
740
 *       been loaded into the hash table.
741
 */
742
static int SCRConfTest06(void)
743
{
1✔
744
    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
1✔
745
    int result = 1;
1✔
746

747
    if (de_ctx == NULL)
1✔
748
        return 0;
749

750
    SCRConfDeInitContext(de_ctx);
1✔
751
    FILE *fd = SCRConfGenerateInvalidDummyReferenceConfigFD02();
1✔
752
    SCRConfLoadReferenceConfigFile(de_ctx, fd);
1✔
753

754
    if (de_ctx->reference_conf_ht == NULL)
1✔
755
        goto end;
756

757
    result = (de_ctx->reference_conf_ht->count == 1);
1✔
758

759
    result &= (SCRConfGetReference("one", de_ctx) != NULL);
1✔
760
    result &= (SCRConfGetReference("two", de_ctx) == NULL);
1✔
761
    result &= (SCRConfGetReference("three", de_ctx) == NULL);
1✔
762
    result &= (SCRConfGetReference("four", de_ctx) == NULL);
1✔
763
    result &= (SCRConfGetReference("five", de_ctx) == NULL);
1✔
764

765
 end:
1✔
766
    if (de_ctx != NULL)
1✔
767
        DetectEngineCtxFree(de_ctx);
1✔
768
    return result;
1✔
769
}
1✔
770

771
#endif /* UNITTESTS */
772

773
/**
774
 * \brief This function registers unit tests for Reference Config API.
775
 */
776
void SCRConfRegisterTests(void)
777
{
1✔
778

779
#ifdef UNITTESTS
1✔
780
    UtRegisterTest("SCRConfTest01", SCRConfTest01);
1✔
781
    UtRegisterTest("SCRConfTest02", SCRConfTest02);
1✔
782
    UtRegisterTest("SCRConfTest03", SCRConfTest03);
1✔
783
    UtRegisterTest("SCRConfTest04", SCRConfTest04);
1✔
784
    UtRegisterTest("SCRConfTest05", SCRConfTest05);
1✔
785
    UtRegisterTest("SCRConfTest06", SCRConfTest06);
1✔
786
#endif /* UNITTESTS */
1✔
787
}
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc