diff --git a/CHANGES b/CHANGES index 7b9b1a1c40..b97ef5be88 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,8 @@ +3.1.0-dev.357 | 2020-01-06 14:10:54 -0800 + + * GH-412: Enable Patterns as Table index (Dev Bali, Corelight) + 3.1.0-dev.354 | 2020-01-06 14:16:29 -0700 * Fix snprintf compiler warning in hexdump BIF (Jon Siwek, Corelight) diff --git a/VERSION b/VERSION index f2cd0981c7..b97d001f0b 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.1.0-dev.354 +3.1.0-dev.357 diff --git a/src/CompHash.cc b/src/CompHash.cc index 327778c5c5..107eeefde8 100644 --- a/src/CompHash.cc +++ b/src/CompHash.cc @@ -146,6 +146,30 @@ char* CompositeHash::SingleValHash(int type_check, char* kp0, break; } + case TYPE_PATTERN: + { + const char* texts[2] = { + v->AsPattern()->PatternText(), + v->AsPattern()->AnywherePatternText() + }; + + size_t* kp; + for ( int i = 0; i < 2; i++ ) + { + kp = AlignAndPadType(kp0+i); + *kp = strlen(texts[i]) + 1; + } + + kp1 = reinterpret_cast(kp+1); + for ( int i = 0; i < 2; i++ ) + { + memcpy(kp1, texts[i], strlen(texts[i]) + 1); + kp1 += strlen(texts[i]) + 1; + } + + break; + } + case TYPE_RECORD: { char* kp = kp0; @@ -401,6 +425,19 @@ HashKey* CompositeHash::ComputeSingletonHash(const Val* v, int type_check) const if ( v->Type()->Tag() == TYPE_FUNC ) return new HashKey(v->AsFunc()->GetUniqueFuncID()); + if ( v->Type()->Tag() == TYPE_PATTERN ) + { + const char* texts[2] = { + v->AsPattern()->PatternText(), + v->AsPattern()->AnywherePatternText() + }; + int n = strlen(texts[0]) + strlen(texts[1]) + 2; // 2 for null + char* key = new char[n]; + std::memcpy(key, texts[0], strlen(texts[0]) + 1); + std::memcpy(key + strlen(texts[0]) + 1, texts[1], strlen(texts[1]) + 1); + return new HashKey(false, key, n); + } + reporter->InternalError("bad index type in CompositeHash::ComputeSingletonHash"); return 0; @@ -462,6 +499,17 @@ int CompositeHash::SingleTypeKeySize(BroType* bt, const Val* v, break; } + case TYPE_PATTERN: + { + if ( ! v ) + return (optional && ! calc_static_size) ? sz : 0; + + sz = SizeAlign(sz, 2 * sizeof(size_t)); + sz += strlen(v->AsPattern()->PatternText()) + + strlen(v->AsPattern()->AnywherePatternText()) + 2; // 2 for null terminators + break; + } + case TYPE_RECORD: { const RecordVal* rv = v ? v->AsRecordVal() : 0; @@ -831,6 +879,28 @@ const char* CompositeHash::RecoverOneVal(const HashKey* k, const char* kp0, } break; + case TYPE_PATTERN: + { + RE_Matcher* re = nullptr; + if ( is_singleton ) + { + kp1 = kp0; + int divider = strlen(kp0) + 1; + re = new RE_Matcher(kp1, kp1 + divider); + kp1 += k->Size(); + } + else + { + const size_t* const len = AlignType(kp0); + + kp1 = reinterpret_cast(len+2); + re = new RE_Matcher(kp1, kp1 + len[0]); + kp1 += len[0] + len[1]; + } + pval = new PatternVal(re); + } + break; + case TYPE_RECORD: { const char* kp = kp0; diff --git a/src/Type.cc b/src/Type.cc index c3e12f5a29..43f5da6267 100644 --- a/src/Type.cc +++ b/src/Type.cc @@ -391,7 +391,7 @@ TableType::TableType(TypeList* ind, BroType* yield) // Allow functions, since they can be compared // for Func* pointer equality. if ( t == TYPE_INTERNAL_OTHER && tli->Tag() != TYPE_FUNC && - tli->Tag() != TYPE_RECORD ) + tli->Tag() != TYPE_RECORD && tli->Tag() != TYPE_PATTERN ) { tli->Error("bad index type"); SetError(); diff --git a/testing/btest/Baseline/language.table-pattern-index/out b/testing/btest/Baseline/language.table-pattern-index/out new file mode 100644 index 0000000000..823acad741 --- /dev/null +++ b/testing/btest/Baseline/language.table-pattern-index/out @@ -0,0 +1,19 @@ +/^?(one|foo|bar)$?/ +/^?(two|oob)$?/ +/^?(three|oob)$?/ +/^?(four)$?/ +----------------- +/^?(two|oob)$?/ +/^?(four)$?/ +/^?(one|foo|bar)$?/ +/^?(three|oob)$?/ +----------------- +/^?(two|oob)$?/, 1 +/^?(four)$?/, 3 +/^?(one|foo|bar)$?/, 0 +/^?(three|oob)$?/, 2 +----------------- +/^?(two|oob)$?/, 3, 2 +/^?(one|foo|bar)$?/, 2, 0 +/^?(four)$?/, 5, 6 +/^?(three|oob)$?/, 4, 4 diff --git a/testing/btest/language/table-pattern-index.zeek b/testing/btest/language/table-pattern-index.zeek new file mode 100644 index 0000000000..1b33a8e27a --- /dev/null +++ b/testing/btest/language/table-pattern-index.zeek @@ -0,0 +1,43 @@ +# @TEST-EXEC: zeek -b %INPUT >out +# @TEST-EXEC: btest-diff out + +local p1: pattern = /one|foo|bar/; +local p2: pattern = /two|oob/; +local p3: pattern = /three|oob/; +local p4 = /four/; + +local p: set[pattern] = {p1, p2, p3, p4}; + +local t: table[pattern] of count = { + [p1] = 0, + [p2] = 1, + [p3] = 2, + [p4] = 3 +}; + +local t2: table[pattern, count] of count = { + [p1,2] = 0, + [p2,3] = 2, + [p3,4] = 4, + [p4,5] = 6 +}; + +print p1; +print p2; +print p3; +print p4; + +print "-----------------"; + +for ( key in p ) + print key; + +print "-----------------"; + +for ( key, value in t ) + print key, value; + +print "-----------------"; + +for ( [c1, c2], value in t2) + print c1, c2, value; diff --git a/testing/external/commit-hash.zeek-testing b/testing/external/commit-hash.zeek-testing index 48383d67d4..5c53cb6426 100644 --- a/testing/external/commit-hash.zeek-testing +++ b/testing/external/commit-hash.zeek-testing @@ -1 +1 @@ -8be265e13e9ddb2dda704bf1574b1307fc17eea9 +da47ae786562da18910d994b7868530929db6271 diff --git a/testing/external/commit-hash.zeek-testing-private b/testing/external/commit-hash.zeek-testing-private index 0bcb565e2c..4c0cb92860 100644 --- a/testing/external/commit-hash.zeek-testing-private +++ b/testing/external/commit-hash.zeek-testing-private @@ -1 +1 @@ -2f6f3b9211f5f5b04a2ede17835d0a4a523888f1 +931f49917a86a260c69e091c2f66b693e74b33bf