diff --git a/CHANGES b/CHANGES index 3fa8c4e51e..76126938ea 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,9 @@ +8.0.0-dev.40 | 2025-05-05 13:40:20 -0700 + + * Add baseline for find_first test, update comments, and reorder function imports (yexiaochuan) + + * Add find_first string function (yexiaochuan) + 8.0.0-dev.37 | 2025-05-05 11:11:57 -0700 * Add commands to the static methods for the Redis implementation (Tim Wojtulewicz, Corelight) diff --git a/VERSION b/VERSION index ba28ba7e56..2c094fa9cd 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.0.0-dev.37 +8.0.0-dev.40 diff --git a/src/script_opt/FuncInfo.cc b/src/script_opt/FuncInfo.cc index be25a66a8f..92f382db8f 100644 --- a/src/script_opt/FuncInfo.cc +++ b/src/script_opt/FuncInfo.cc @@ -263,6 +263,7 @@ static std::unordered_map func_attrs = { {"find_all", ATTR_FOLDABLE}, {"find_all_ordered", ATTR_FOLDABLE}, {"find_entropy", ATTR_FOLDABLE}, + {"find_first", ATTR_FOLDABLE}, {"find_in_zeekpath", ATTR_IDEMPOTENT}, // can error {"find_last", ATTR_FOLDABLE}, {"find_str", ATTR_FOLDABLE}, diff --git a/src/strings.bif b/src/strings.bif index 118bc82bb0..b212ec782b 100644 --- a/src/strings.bif +++ b/src/strings.bif @@ -531,7 +531,7 @@ function strcmp%(s1: string, s2: string%): int ## Returns: The location of *little* in *big*, or 0 if *little* is not found in ## *big*. ## -## .. zeek:see:: find_all find_last +## .. zeek:see:: find_all find_first find_last function strstr%(big: string, little: string%): count %{ return zeek::val_mgr->Count( @@ -1015,7 +1015,7 @@ static bool exceeds_max_string_length(int str_len, int max_size, zeek::detail::F ## ## Returns: The set of strings in *str* that match *re*, or the empty set. ## -## .. zeek:see: find_all_ordered find_last strstr +## .. zeek:see: find_all_ordered find_first find_last strstr function find_all%(str: string, re: pattern, max_str_size: int &default=-1%) : string_set %{ auto a = zeek::make_intrusive(zeek::id::string_set); @@ -1055,7 +1055,7 @@ function find_all%(str: string, re: pattern, max_str_size: int &default=-1%) : s ## ## Returns: All strings in *str* that match *re*, or an empty vector. ## -## .. zeek:see: find_all find_last strstr +## .. zeek:see: find_all find_first find_last strstr function find_all_ordered%(str: string, re: pattern, max_str_size: int &default=-1%) : string_vec %{ auto a = zeek::make_intrusive(zeek::id::string_vec); @@ -1091,7 +1091,7 @@ function find_all_ordered%(str: string, re: pattern, max_str_size: int &default= ## ## Returns: The last string in *str* that matches *re*, or the empty string. ## -## .. zeek:see: find_all find_all_ordered strstr +## .. zeek:see: find_all find_all_ordered strstr find_first function find_last%(str: string, re: pattern%) : string %{ const u_char* s = str->Bytes(); @@ -1107,6 +1107,30 @@ function find_last%(str: string, re: pattern%) : string return zeek::val_mgr->EmptyString(); %} +## Finds the first occurrence of a pattern in a string. +## +## str: The string to inspect. +## +## re: The pattern to look for in *str*. +## +## Returns: The first string in *str* that matches *re*, or the empty string. +## +## .. zeek:see:: find_all find_all_ordered find_last strstr +function find_first%(str: string, re: pattern%) : string + %{ + const u_char* s = str->Bytes(); + const u_char* e = s + str->Len(); + + for ( const u_char* t = s; t < e; ++t ) + { + int n = re->MatchPrefix(t, e - t); + if ( n >= 0 ) + return zeek::make_intrusive(n, (const char*) t); + } + + return zeek::val_mgr->EmptyString(); + %} + ## Returns a hex dump for given input data. The hex dump renders 16 bytes per ## line, with hex on the left and ASCII (where printable) ## on the right. diff --git a/testing/btest/Baseline/bifs.find_first/out b/testing/btest/Baseline/bifs.find_first/out new file mode 100644 index 0000000000..15ceaa5904 --- /dev/null +++ b/testing/btest/Baseline/bifs.find_first/out @@ -0,0 +1,4 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +hi +------------------- +0 diff --git a/testing/btest/Baseline/opt.ZAM-bif-tracking/output b/testing/btest/Baseline/opt.ZAM-bif-tracking/output index c20efb9801..67cc8f4838 100644 --- a/testing/btest/Baseline/opt.ZAM-bif-tracking/output +++ b/testing/btest/Baseline/opt.ZAM-bif-tracking/output @@ -1,2 +1,2 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. -558 seen BiFs, 0 unseen BiFs (), 0 new BiFs () +559 seen BiFs, 0 unseen BiFs (), 0 new BiFs () diff --git a/testing/btest/bifs/find_first.zeek b/testing/btest/bifs/find_first.zeek new file mode 100644 index 0000000000..048de762d9 --- /dev/null +++ b/testing/btest/bifs/find_first.zeek @@ -0,0 +1,16 @@ +# @TEST-EXEC: zeek -b %INPUT >out +# @TEST-EXEC: btest-diff out + +event zeek_init() + { + local a = "this is a test"; + local pat = /hi|es/; + local pat2 = /aa|bb/; + + local b = find_first(a, pat); + local b2 = find_first(a, pat2); + + print b; + print "-------------------"; + print |b2|; + } diff --git a/testing/btest/opt/ZAM-bif-tracking.zeek b/testing/btest/opt/ZAM-bif-tracking.zeek index 8ad644ac5a..80dcbdbd1e 100644 --- a/testing/btest/opt/ZAM-bif-tracking.zeek +++ b/testing/btest/opt/ZAM-bif-tracking.zeek @@ -295,6 +295,7 @@ global known_BiFs = set( "find_all", "find_all_ordered", "find_entropy", + "find_first", "find_in_zeekpath", "find_last", "find_str",