Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/security/nss/lib/ssl/sslbloom.c
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/*
3
 * A bloom filter.
4
 *
5
 * This Source Code Form is subject to the terms of the Mozilla Public
6
 * License, v. 2.0. If a copy of the MPL was not distributed with this
7
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
8
9
#include "sslbloom.h"
10
#include "prnetdb.h"
11
#include "secport.h"
12
13
static inline unsigned int
14
sslBloom_Size(unsigned int bits)
15
0
{
16
0
    return (bits >= 3) ? (1 << (bits - 3)) : 1;
17
0
}
18
19
SECStatus
20
sslBloom_Init(sslBloomFilter *filter, unsigned int k, unsigned int bits)
21
0
{
22
0
    PORT_Assert(filter);
23
0
    PORT_Assert(bits > 0);
24
0
    PORT_Assert(bits <= sizeof(PRUint32) * 8);
25
0
    PORT_Assert(k > 0);
26
0
27
0
    filter->filter = PORT_ZNewArray(PRUint8, sslBloom_Size(bits));
28
0
    if (!filter->filter) {
29
0
        return SECFailure; /* Error code already set. */
30
0
    }
31
0
32
0
    filter->k = k;
33
0
    filter->bits = bits;
34
0
    return SECSuccess;
35
0
}
36
37
void
38
sslBloom_Zero(sslBloomFilter *filter)
39
0
{
40
0
    PORT_Memset(filter->filter, 0, sslBloom_Size(filter->bits));
41
0
}
42
43
void
44
sslBloom_Fill(sslBloomFilter *filter)
45
0
{
46
0
    PORT_Memset(filter->filter, 0xff, sslBloom_Size(filter->bits));
47
0
}
48
49
static PRBool
50
sslBloom_AddOrCheck(sslBloomFilter *filter, const PRUint8 *hashes, PRBool add)
51
0
{
52
0
    unsigned int iteration;
53
0
    unsigned int bitIndex;
54
0
    PRUint32 tmp = 0;
55
0
    PRUint8 mask;
56
0
    unsigned int bytes = (filter->bits + 7) / 8;
57
0
    unsigned int shift = (bytes * 8) - filter->bits;
58
0
    PRBool found = PR_TRUE;
59
0
60
0
    PORT_Assert(bytes <= sizeof(unsigned int));
61
0
62
0
    for (iteration = 0; iteration < filter->k; ++iteration) {
63
0
        PORT_Memcpy(((PRUint8 *)&tmp) + (sizeof(tmp) - bytes),
64
0
                    hashes, bytes);
65
0
        hashes += bytes;
66
0
        bitIndex = PR_ntohl(tmp) >> shift;
67
0
68
0
        mask = 1 << (bitIndex % 8);
69
0
        found = found && filter->filter[bitIndex / 8] & mask;
70
0
        if (add) {
71
0
            filter->filter[bitIndex / 8] |= mask;
72
0
        }
73
0
    }
74
0
    return found;
75
0
}
76
77
PRBool
78
sslBloom_Add(sslBloomFilter *filter, const PRUint8 *hashes)
79
0
{
80
0
    return sslBloom_AddOrCheck(filter, hashes, PR_TRUE);
81
0
}
82
83
PRBool
84
sslBloom_Check(sslBloomFilter *filter, const PRUint8 *hashes)
85
0
{
86
0
    return sslBloom_AddOrCheck(filter, hashes, PR_FALSE);
87
0
}
88
89
void
90
sslBloom_Destroy(sslBloomFilter *filter)
91
0
{
92
0
    PORT_Free(filter->filter);
93
0
    PORT_Memset(filter, 0, sizeof(*filter));
94
0
}