More policy/utils unit tests and documentation.

This commit is contained in:
Jon Siwek 2011-07-19 10:28:26 -05:00
parent c5e98a8116
commit 27ba228fa1
9 changed files with 171 additions and 22 deletions

View file

@ -1,11 +1,13 @@
##! Functions for creating and working with patterns.
## This function only works at or before init time. Given a pattern as a string
## with two tildes (~~) contained in it, it will return a pattern with the
## set[string] elements OR'd together where the double-tilde was given.
## If a literal backslash is include in 'pat', it needs to be given as a double
## backslash due to Bro's string parsing reducing it to a single backslash
## upon rendering.
## Given a pattern as a string with two tildes (~~) contained in it, it will
## return a pattern with string set's elements OR'd together where the
## double-tilde was given (this function only works at or before init time).
## ss: a set of strings to OR together
## pat: the pattern containing a "~~" in it. If a literal backslash is
## included, it needs to be escaped with another backslash due to Bro's
## string parsing reducing it to a single backslash upon rendering.
## Returns: the input pattern with "~~" replaced by OR'd elements of input set
function set_to_regex(ss: set[string], pat: string): pattern
{
local i: count = 0;
@ -31,15 +33,13 @@ type PatternMatchResult: record {
## Matches the given pattern against the given string, returning
## a :bro:type:`PatternMatchResult` record.
## For example:
## match_pattern("foobar", /o*[a-k]/)
## returns:
## [matched=T, str=f, off=1]
## because the *first* match is for zero o's followed by an [a-k],
## while:
## match_pattern("foobar", /o+[a-k]/)
## returns:
## [matched=T, str=oob, off=2]
## For example: ``match_pattern("foobar", /o*[a-k]/)`` returns
## ``[matched=T, str=f, off=1]``, because the *first* match is for
## zero o's followed by an [a-k], but ``match_pattern("foobar", /o+[a-k]/)``
## returns ``[matched=T, str=oob, off=2]``
## s: a string to match against
## p: a pattern to match
## Returns: a record indicating the match status
function match_pattern(s: string, p: pattern): PatternMatchResult
{
local a = split_n(s, p, T, 1);

View file

@ -9,8 +9,11 @@ function is_string_binary(s: string): bool
return byte_len(gsub(s, /[\x00-\x7f]/, "")) * 100 / |s| >= 25;
}
## Takes a :bro:type:`set[string]` and joins each element together with the
## second argument.
## Joins a set of string together, with elements delimited by a constant string.
## ss: a set of strings to join
## j: the string used to join set elements
## Returns: a string composed of the all elements of the set, delimited by the
## joining string.
function join_string_set(ss: set[string], j: string): string
{
local output="";
@ -26,9 +29,11 @@ function join_string_set(ss: set[string], j: string): string
return output;
}
## Given a string, returns an escaped version. This means that
## (1) any occurrences of any character in "chars" are escaped using '\', and
## (2) any '\'s are likewise escaped.
## Given a string, returns an escaped version.
## s: a string to escape
## chars: a string containing all the characters that need to be escaped
## Returns: a string with all occurrences of any character in ``chars`` escaped
## using ``\``, and any literal ``\`` characters likewise escaped.
function string_escape(s: string, chars: string): string
{
s = subst_string(s, "\\", "\\\\");
@ -38,6 +43,9 @@ function string_escape(s: string, chars: string): string
}
## Cut a number of character from the end of the given string.
## s: a string to trim
## tail_len: the number of characters to remove from end of string
## Returns: the string in ``s`` with ``tail_len`` characters removed from end
function cut_tail(s: string, tail_len: count): string
{
if ( tail_len > |s| )

View file

@ -22,8 +22,12 @@ export {
30, 100, 1000, 10000, 100000, 1000000, 10000000,
} &redef;
## This will check if a :bro:type:`TrackCount` variable has crossed the
## thresholds given in the first value.
## This will check if a :bro:type:`TrackCount` variable has crossed any
## thresholds in a given set.
## v: a vector holding counts that represent thresholds
## tracker: the record being used to track event counter and currently
## monitored threshold value
## Returns: T if a threshold has been crossed, else F
global check_threshold: function(v: vector of count, tracker: TrackCount): bool;
## This will use the :bro:id:`default_notice_thresholds` variable to check

View file

@ -0,0 +1,6 @@
/^?((blarg|blah|bleh))$?/
T
/^?(foo(blarg|blah|bleh)bar)$?/
T
[matched=T, str=blah, off=4]
[matched=F, str=, off=0]

View file

@ -0,0 +1,13 @@
'hello' is NOT considered binary
'\xff\xff\xff\0' IS considered binary
'\0\0\xff\0' IS considered binary
'\0\0\0\0' is NOT considered binary
two, one, three
one
hell\o w\orl\d
\\hello world\\
hello world
hello worl
hello

View file

@ -0,0 +1,45 @@
Iteration: 0, threshold check: F
[n=0, index=0]
Iteration: 1, threshold check: F
[n=1, index=0]
Iteration: 2, threshold check: T
[n=2, index=1]
Iteration: 3, threshold check: F
[n=3, index=1]
Iteration: 4, threshold check: T
[n=4, index=2]
Iteration: 5, threshold check: F
[n=5, index=2]
Iteration: 6, threshold check: T
[n=6, index=3]
Iteration: 7, threshold check: F
[n=7, index=3]
Iteration: 8, threshold check: T
[n=8, index=4]
Iteration: 9, threshold check: F
[n=9, index=4]
Iteration: 10, threshold check: T
[n=10, index=5]
====================================
Iteration: 0, threshold check: F
[n=0, index=0]
Iteration: 1, threshold check: F
[n=1, index=0]
Iteration: 2, threshold check: T
[n=2, index=1]
Iteration: 3, threshold check: F
[n=3, index=1]
Iteration: 4, threshold check: T
[n=4, index=2]
Iteration: 5, threshold check: F
[n=5, index=2]
Iteration: 6, threshold check: T
[n=6, index=3]
Iteration: 7, threshold check: F
[n=7, index=3]
Iteration: 8, threshold check: T
[n=8, index=4]
Iteration: 9, threshold check: F
[n=9, index=4]
Iteration: 10, threshold check: T
[n=10, index=5]

View file

@ -0,0 +1,16 @@
# @TEST-EXEC: bro %INPUT >output
# @TEST-EXEC: btest-diff output
@load utils/pattern
global r1 = set_to_regex(set("blah", "bleh", "blarg"), "(~~)");
global r2 = set_to_regex(set("blah", "bleh", "blarg"), "foo(~~)bar");
print r1;
print "blah" == r1;
print r2;
print "fooblargbar" == r2;
print match_pattern("123blah123", r1);
print match_pattern("no match here", r1);

View file

@ -0,0 +1,29 @@
# @TEST-EXEC: bro %INPUT >output
# @TEST-EXEC: btest-diff output
@load utils/strings
function test_binary_string(s: string)
{
if ( is_string_binary(s) )
print fmt("'%s' IS considered binary", s);
else
print fmt("'%s' is NOT considered binary", s);
}
test_binary_string("\x68\x65\x6C\x6C\x6F");
test_binary_string("\xFF\xFF\xFF\x00");
test_binary_string("\x00\x00\xFF\x00");
test_binary_string("\x00\x00\x00\x00");
print join_string_set(set("one", "two", "three"), ", ");
print join_string_set(set("one"), ", ");
print string_escape("hello world", "od");
print string_escape("\\hello world\\", "");
print cut_tail("hello world", 0);
print cut_tail("hello world", 1);
print cut_tail("hello world", 6);
print cut_tail("hello world", 11);
print cut_tail("hello world", 12);

View file

@ -0,0 +1,28 @@
# @TEST-EXEC: bro %INPUT >output
# @TEST-EXEC: btest-diff output
@load utils/thresholds
redef default_notice_thresholds = { 2, 4, 6, 8, 10 };
const my_thresholds: vector of count = { 2, 4, 6, 8, 10 };
const loop_v: vector of count = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
global track_count: TrackCount;
for ( i in loop_v )
{
print fmt("Iteration: %s, threshold check: %s", i,
check_threshold(my_thresholds, track_count));
print track_count;
++track_count$n;
}
track_count$n = 0; track_count$index = 0;
print "====================================";
for ( i in loop_v )
{
print fmt("Iteration: %s, threshold check: %s", i,
default_check_threshold(track_count));
print track_count;
++track_count$n;
}