diff --git a/src/analyzer/protocol/redis/resp.spicy b/src/analyzer/protocol/redis/resp.spicy index b5cd6d1e95..f372f0e34d 100644 --- a/src/analyzer/protocol/redis/resp.spicy +++ b/src/analyzer/protocol/redis/resp.spicy @@ -10,15 +10,29 @@ const MAX_SIZE = 1024 * 1024; const MAX_RECURSION_DEPTH = 20; public type ClientMessages = unit { + # The context here refers to whether we saw client data first. It is a one-time switch, + # either we have seen client data or not. + %context = bool; + on %init { + *self.context() = True; + } : ClientData[]; }; public type ServerMessages = unit { + %context = bool; + on %init { + if (!*self.context()) { + throw "Server responses must come after a client request is seen"; + } + } : (ServerData &synchronize)[]; }; public type ClientData = unit { - on %init() { self.start = self.input(); } + on %init() { + self.start = self.input(); + } # Clients can only be an array or inline ty: uint8 &convert=DataType($$) { @@ -49,7 +63,7 @@ type BulkStringArray = unit { type BulkStringWithTy = unit { # Need to consume the type here - : uint8 &requires=$$=='$'; + : uint8 &requires=$$ == '$'; length: RedisBytes &convert=$$.to_int(10) &requires=self.length <= int64(MAX_SIZE); # NullBulkString is a BulkString with content unset @@ -59,7 +73,6 @@ type BulkStringWithTy = unit { : skip RedisBytes; }; - public type ServerData = unit { %synchronize-after = b"\x0d\x0a"; var depth: uint8& = new uint8; diff --git a/testing/btest/Baseline/scripts.base.protocols.redis.start-with-server/output b/testing/btest/Baseline/scripts.base.protocols.redis.start-with-server/output new file mode 100644 index 0000000000..49d861c74c --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.redis.start-with-server/output @@ -0,0 +1 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. diff --git a/testing/btest/Traces/redis/start-with-server.pcap b/testing/btest/Traces/redis/start-with-server.pcap new file mode 100644 index 0000000000..66d0a59f64 Binary files /dev/null and b/testing/btest/Traces/redis/start-with-server.pcap differ diff --git a/testing/btest/scripts/base/protocols/redis/start-with-server.zeek b/testing/btest/scripts/base/protocols/redis/start-with-server.zeek new file mode 100644 index 0000000000..15c9413716 --- /dev/null +++ b/testing/btest/scripts/base/protocols/redis/start-with-server.zeek @@ -0,0 +1,14 @@ +# @TEST-DOC: Test that Redis does not parse if it starts with the server data +# +# @TEST-EXEC: zeek -Cr $TRACES/redis/start-with-server.pcap base/protocols/redis %INPUT >output +# @TEST-EXEC: btest-diff output + +event Redis::command(c: connection, is_orig: bool, command: Redis::Command) + { + print "BAD", command; + } + +event Redis::server_data(c: connection, is_orig: bool, dat: Redis::ServerData) + { + print "BAD", dat; + }