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

OISF / suricata / 22618661228

02 Mar 2026 09:33PM UTC coverage: 42.258% (-34.4%) from 76.611%
22618661228

push

github

victorjulien
github-actions: bump actions/download-artifact from 7.0.0 to 8.0.0

Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 7.0.0 to 8.0.0.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](https://github.com/actions/download-artifact/compare/37930b1c2...70fc10c6e)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-version: 8.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

91511 of 216553 relevant lines covered (42.26%)

3416852.41 hits per line

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

61.37
/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*$"
7✔
39

40
/* Default path for the reference.conf file */
41
#define SC_RCONF_DEFAULT_FILE_PATH CONFIG_DIR "/reference.config"
6✔
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
{
7✔
54
    int en;
7✔
55
    PCRE2_SIZE eo;
7✔
56
    int opts = 0;
7✔
57

58
    de_ctx->reference_conf_regex =
7✔
59
            pcre2_compile((PCRE2_SPTR8)SC_RCONF_REGEX, PCRE2_ZERO_TERMINATED, opts, &en, &eo, NULL);
7✔
60
    if (de_ctx->reference_conf_regex == NULL) {
7✔
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 =
7✔
69
            pcre2_match_data_create_from_pattern(de_ctx->reference_conf_regex, NULL);
7✔
70
}
7✔
71

72
void SCReferenceConfDeinit(DetectEngineCtx *de_ctx)
73
{
7✔
74
    if (de_ctx->reference_conf_regex != NULL) {
7✔
75
        pcre2_code_free(de_ctx->reference_conf_regex);
7✔
76
        de_ctx->reference_conf_regex = NULL;
7✔
77
    }
7✔
78
    if (de_ctx->reference_conf_regex_match != NULL) {
7✔
79
        pcre2_match_data_free(de_ctx->reference_conf_regex_match);
7✔
80
        de_ctx->reference_conf_regex_match = NULL;
7✔
81
    }
7✔
82
}
7✔
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
{
7✔
102
    /* init the hash table to be used by the reference config references */
103
    de_ctx->reference_conf_ht = HashTableInit(128, SCRConfReferenceHashFunc,
7✔
104
                                              SCRConfReferenceHashCompareFunc,
7✔
105
                                              SCRConfReferenceHashFree);
7✔
106
    if (de_ctx->reference_conf_ht == NULL) {
7✔
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) {
7✔
117
        const char *filename = SCRConfGetConfFilename(de_ctx);
7✔
118
        if ((fd = fopen(filename, "r")) == NULL) {
7✔
119
#ifdef UNITTESTS
120
            if (RunmodeIsUnittests()) {
121
                return NULL; // silently fail
122
            }
123
#endif
124
            SCLogError("Error opening file: \"%s\": %s", filename, strerror(errno));
7✔
125
            return NULL;
7✔
126
        }
7✔
127
    }
7✔
128

129
    return fd;
×
130
}
7✔
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
{
7✔
144
    const char *path = NULL;
7✔
145

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

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

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

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

184
    de_ctx->reference_conf_ht = NULL;
7✔
185
}
7✔
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
{
38,336✔
194
    char *new_str = NULL;
38,336✔
195
    char *temp_str = NULL;
38,336✔
196

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

201
    temp_str = new_str;
38,336✔
202
    while (*temp_str != '\0') {
157,140✔
203
        *temp_str = u8_tolower((unsigned char)*temp_str);
118,804✔
204
        temp_str++;
118,804✔
205
    }
118,804✔
206

207
    return new_str;
38,336✔
208
}
38,336✔
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
{
9✔
222
    char system[REFERENCE_SYSTEM_NAME_MAX];
9✔
223
    char url[REFERENCE_CONTENT_NAME_MAX];
9✔
224

225
    SCRConfReference *ref_new = NULL;
9✔
226
    SCRConfReference *ref_lookup = NULL;
9✔
227

228
    int ret = 0;
9✔
229

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

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

247
    /* retrieve the reference url */
248
    copylen = sizeof(url);
9✔
249
    ret = pcre2_substring_copy_bynumber(
9✔
250
            de_ctx->reference_conf_regex_match, 2, (PCRE2_UCHAR8 *)url, &copylen);
9✔
251
    if (ret < 0) {
9✔
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);
9✔
258
    if (ref_new == NULL)
9✔
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);
9✔
264
    if (ref_lookup == NULL) {
9✔
265
        if (HashTableAdd(de_ctx->reference_conf_ht, ref_new, 0) < 0) {
9✔
266
            SCLogDebug("HashTable Add failed");
×
267
        }
×
268
    } else {
9✔
269
        SCLogDebug("Duplicate reference found inside reference.config");
×
270
        SCRConfDeAllocSCRConfReference(ref_new);
×
271
    }
×
272

273
    return 0;
9✔
274

275
 error:
×
276
    return -1;
×
277
}
9✔
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
{
×
293
    while (*line != '\0') {
×
294
        /* we have a comment */
295
        if (*line == '#')
×
296
            return 1;
×
297

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

302
        line++;
×
303
    }
×
304

305
    /* we have a blank line */
306
    return 1;
×
307
}
×
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
{
×
317
    char line[1024];
×
318
    int runmode = SCRunmodeGet();
×
319
    bool is_conf_test_mode = runmode == RUNMODE_CONF_TEST;
×
320
    while (fgets(line, sizeof(line), fd) != NULL) {
×
321
        if (SCRConfIsLineBlankOrComment(line))
×
322
            continue;
×
323

324
        if (SCRConfAddReference(de_ctx, line) != 0) {
×
325
            if (is_conf_test_mode) {
×
326
                return false;
×
327
            }
×
328
        }
×
329
    }
×
330

331
#ifdef UNITTESTS
332
    if (de_ctx != NULL && strlen(de_ctx->config_prefix) > 0)
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);
335
    else
336
        SCLogInfo("Added \"%d\" reference types from the reference.config file",
337
                de_ctx->reference_conf_ht->count);
338
#endif /* UNITTESTS */
339
    return true;
×
340
}
×
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
{
38,336✔
354
    SCRConfReference *ref = NULL;
38,336✔
355

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

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

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

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

376
    return ref;
38,336✔
377
}
38,336✔
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
{
38,336✔
386
    if (ref != NULL) {
38,336✔
387
        if (ref->system != NULL)
38,336✔
388
            SCFree(ref->system);
38,336✔
389

390
        if (ref->url != NULL)
38,336✔
391
            SCFree(ref->url);
9✔
392

393
        SCFree(ref);
38,336✔
394
    }
38,336✔
395
}
38,336✔
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
{
38,345✔
409
    SCRConfReference *ref = (SCRConfReference *)data;
38,345✔
410
    uint32_t hash = 0;
38,345✔
411
    size_t i = 0;
38,345✔
412

413
    size_t len = strlen(ref->system);
38,345✔
414

415
    for (i = 0; i < len; i++)
157,196✔
416
        hash += u8_tolower((unsigned char)ref->system[i]);
118,851✔
417

418
    hash = hash % ht->array_size;
38,345✔
419

420
    return hash;
38,345✔
421
}
38,345✔
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
{
38,318✔
439
    SCRConfReference *ref1 = (SCRConfReference *)data1;
38,318✔
440
    SCRConfReference *ref2 = (SCRConfReference *)data2;
38,318✔
441

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

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

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

453
    return 0;
×
454
}
38,318✔
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
{
9✔
464
    SCRConfDeAllocSCRConfReference(data);
9✔
465
}
9✔
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
{
7✔
482
    fd = SCRConfInitContextAndLocalResources(de_ctx, fd);
7✔
483
    if (fd == NULL) {
7✔
484
#ifdef UNITTESTS
485
        if (RunmodeIsUnittests()) {
486
            return -1;
487
        }
488
#endif
489
        SCLogError("please check the \"reference-config-file\" "
7✔
490
                   "option in your suricata.yaml file");
7✔
491
        return -1;
7✔
492
    }
7✔
493

494
    bool rc = SCRConfParseFile(de_ctx, fd);
7✔
495
    SCRConfDeInitLocalResources(fd);
×
496

497
    return rc ? 0 : -1;
×
498
}
7✔
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,327✔
514
    SCRConfReference *ref_conf = SCRConfAllocSCRConfReference(rconf_name, NULL);
38,327✔
515
    if (ref_conf == NULL)
38,327✔
516
        return NULL;
×
517
    SCRConfReference *lookup_ref_conf = HashTableLookup(de_ctx->reference_conf_ht,
38,327✔
518
                                                        ref_conf, 0);
38,327✔
519

520
    SCRConfDeAllocSCRConfReference(ref_conf);
38,327✔
521
    return lookup_ref_conf;
38,327✔
522
}
38,327✔
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
{
535
    const char *buffer =
536
        "config reference: one http://www.one.com\n"
537
        "config reference: two http://www.two.com\n"
538
        "config reference: three http://www.three.com\n"
539
        "config reference: one http://www.one.com\n"
540
        "config reference: three http://www.three.com\n";
541

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

546
    return fd;
547
}
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
{
555
    const char *buffer =
556
        "config reference: one http://www.one.com\n"
557
        "config_ reference: two http://www.two.com\n"
558
        "config reference_: three http://www.three.com\n"
559
        "config reference: four\n"
560
        "config reference five http://www.five.com\n";
561

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

566
    return fd;
567
}
568

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

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

585
    return fd;
586
}
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
{
594
    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
595
    int result = 0;
596

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

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

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

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

611
 end:
612
    if (de_ctx != NULL)
613
        DetectEngineCtxFree(de_ctx);
614
    return result;
615
}
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
{
623
    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
624
    int result = 0;
625

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

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

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

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

638

639
 end:
640
    if (de_ctx != NULL)
641
        DetectEngineCtxFree(de_ctx);
642
    return result;
643
}
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
{
651
    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
652
    int result = 0;
653

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

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

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

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

666
 end:
667
    if (de_ctx != NULL)
668
        DetectEngineCtxFree(de_ctx);
669
    return result;
670
}
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
{
678
    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
679
    int result = 1;
680

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

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

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

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

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

698
 end:
699
    if (de_ctx != NULL)
700
        DetectEngineCtxFree(de_ctx);
701
    return result;
702
}
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
{
711
    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
712
    int result = 1;
713

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

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

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

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

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

732
 end:
733
    if (de_ctx != NULL)
734
        DetectEngineCtxFree(de_ctx);
735
    return result;
736
}
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
{
744
    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
745
    int result = 1;
746

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

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

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

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

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

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

771
#endif /* UNITTESTS */
772

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

779
#ifdef UNITTESTS
780
    UtRegisterTest("SCRConfTest01", SCRConfTest01);
781
    UtRegisterTest("SCRConfTest02", SCRConfTest02);
782
    UtRegisterTest("SCRConfTest03", SCRConfTest03);
783
    UtRegisterTest("SCRConfTest04", SCRConfTest04);
784
    UtRegisterTest("SCRConfTest05", SCRConfTest05);
785
    UtRegisterTest("SCRConfTest06", SCRConfTest06);
786
#endif /* UNITTESTS */
787
}
×
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