mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 06:38:20 +00:00
Merge remote-tracking branch 'origin/topic/jsiwek/gh-151'
* origin/topic/jsiwek/gh-151: GH-151: fix hash calculation for nested sets
This commit is contained in:
commit
7c892ef7d4
5 changed files with 75 additions and 11 deletions
10
CHANGES
10
CHANGES
|
@ -1,4 +1,14 @@
|
||||||
|
|
||||||
|
2.6-92 | 2019-01-22 08:53:36 -0800
|
||||||
|
|
||||||
|
* GH-151: fix hash calculation for nested sets
|
||||||
|
|
||||||
|
Hash key construction of nested sets depended on the order in
|
||||||
|
which their elements are iterated, which varied even between sets
|
||||||
|
containing equivalent elements. The iteration order is now sorted
|
||||||
|
by each element's hash value (or, on collision, by full key) such
|
||||||
|
that equivalent sets no longer hash differently. (Jon Siwek, Corelight)
|
||||||
|
|
||||||
2.6-89 | 2019-01-18 15:17:34 -0800
|
2.6-89 | 2019-01-18 15:17:34 -0800
|
||||||
|
|
||||||
* Pre-allocate and re-use Vals for bool, int, count, enum and empty string (Jon Siwek, Corelight)
|
* Pre-allocate and re-use Vals for bool, int, count, enum and empty string (Jon Siwek, Corelight)
|
||||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
||||||
2.6-89
|
2.6-92
|
||||||
|
|
|
@ -7,6 +7,9 @@
|
||||||
#include "Reporter.h"
|
#include "Reporter.h"
|
||||||
#include "Func.h"
|
#include "Func.h"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
CompositeHash::CompositeHash(TypeList* composite_type)
|
CompositeHash::CompositeHash(TypeList* composite_type)
|
||||||
{
|
{
|
||||||
type = composite_type;
|
type = composite_type;
|
||||||
|
@ -174,12 +177,44 @@ char* CompositeHash::SingleValHash(int type_check, char* kp0,
|
||||||
{
|
{
|
||||||
int* kp = AlignAndPadType<int>(kp0);
|
int* kp = AlignAndPadType<int>(kp0);
|
||||||
TableVal* tv = v->AsTableVal();
|
TableVal* tv = v->AsTableVal();
|
||||||
ListVal* lv = tv->ConvertToList();
|
|
||||||
*kp = tv->Size();
|
*kp = tv->Size();
|
||||||
kp1 = reinterpret_cast<char*>(kp+1);
|
kp1 = reinterpret_cast<char*>(kp+1);
|
||||||
for ( int i = 0; i < tv->Size(); ++i )
|
|
||||||
|
auto tbl = tv->AsTable();
|
||||||
|
auto it = tbl->InitForIteration();
|
||||||
|
ListVal* lv = new ListVal(TYPE_ANY);
|
||||||
|
|
||||||
|
struct HashKeyComparer {
|
||||||
|
bool operator()(const HashKey* a, const HashKey* b) const
|
||||||
|
{
|
||||||
|
if ( a->Hash() != b->Hash() )
|
||||||
|
return a->Hash() < b->Hash();
|
||||||
|
if ( a->Size() != b->Size() )
|
||||||
|
return a->Size() < b->Size();
|
||||||
|
return strncmp(static_cast<const char*>(a->Key()),
|
||||||
|
static_cast<const char*>(b->Key()),
|
||||||
|
a->Size()) < 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
std::map<HashKey*, int, HashKeyComparer> hashkeys;
|
||||||
|
HashKey* k;
|
||||||
|
auto idx = 0;
|
||||||
|
|
||||||
|
while ( tbl->NextEntry(k, it) )
|
||||||
{
|
{
|
||||||
Val* key = lv->Index(i);
|
hashkeys[k] = idx++;
|
||||||
|
lv->Append(tv->RecoverIndex(k));
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( auto& kv : hashkeys )
|
||||||
|
delete kv.first;
|
||||||
|
|
||||||
|
for ( auto& kv : hashkeys )
|
||||||
|
{
|
||||||
|
auto idx = kv.second;
|
||||||
|
Val* key = lv->Index(idx);
|
||||||
|
|
||||||
if ( ! (kp1 = SingleValHash(type_check, kp1, key->Type(), key,
|
if ( ! (kp1 = SingleValHash(type_check, kp1, key->Type(), key,
|
||||||
false)) )
|
false)) )
|
||||||
{
|
{
|
||||||
|
|
|
@ -10,18 +10,18 @@ a
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
[a=4, tags_v=[0, 1], tags_t={
|
|
||||||
[two] = 2,
|
|
||||||
[one] = 1
|
|
||||||
}, tags_s={
|
|
||||||
b,
|
|
||||||
a
|
|
||||||
}],
|
|
||||||
[a=13, tags_v=[, , 2, 3], tags_t={
|
[a=13, tags_v=[, , 2, 3], tags_t={
|
||||||
[five] = 5,
|
[five] = 5,
|
||||||
[four] = 4
|
[four] = 4
|
||||||
}, tags_s={
|
}, tags_s={
|
||||||
c,
|
c,
|
||||||
d
|
d
|
||||||
|
}],
|
||||||
|
[a=4, tags_v=[0, 1], tags_t={
|
||||||
|
[two] = 2,
|
||||||
|
[one] = 1
|
||||||
|
}, tags_s={
|
||||||
|
b,
|
||||||
|
a
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
|
|
19
testing/btest/language/nested-sets.bro
Normal file
19
testing/btest/language/nested-sets.bro
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
# @TEST-EXEC: for i in `seq 21`; do echo 0 >> random.seed; done
|
||||||
|
# @TEST-EXEC: test `bro -b -G random.seed %INPUT` = "pass"
|
||||||
|
|
||||||
|
type r: record {
|
||||||
|
b: set[count];
|
||||||
|
};
|
||||||
|
|
||||||
|
global foo: set[r];
|
||||||
|
global bar = set(1,3,5);
|
||||||
|
|
||||||
|
add foo[record($b=bar)];
|
||||||
|
|
||||||
|
bar = set(5,3,1);
|
||||||
|
delete foo[record($b=bar)];
|
||||||
|
|
||||||
|
if ( |foo| > 0 )
|
||||||
|
print "fail";
|
||||||
|
else
|
||||||
|
print "pass";
|
Loading…
Add table
Add a link
Reference in a new issue