spicy-redis: Make client data only accept bulk strings

This commit is contained in:
Evan Typanski 2024-12-05 15:28:09 -05:00
parent 7f28ec8bc5
commit 292241f420
2 changed files with 21 additions and 5 deletions

View file

@ -67,10 +67,7 @@ public function make_command(command: RESP::ClientData): Command {
public function bulk_command(command: RESP::ClientData): Command {
local v: vector<bytes>;
for (ele in command.multibulk.elements) {
# TODO: Stringify the other data too. Apparently commands *can* have other stuff
# such as SUBSCRIBE, which will magically put an integer after it.
if (ele?.bulk_string)
v.push_back(ele.bulk_string.content);
v.push_back(ele.content);
}
return parse_command(v);
}

View file

@ -27,7 +27,7 @@ public type ClientData = unit {
}
}
if (self.ty == DataType::ARRAY) {
multibulk: Array;
multibulk: BulkStringArray;
} else {
inline: RedisBytes &max-size=1024;
};
@ -40,6 +40,25 @@ public type ClientData = unit {
}
};
type BulkStringArray = unit {
num_elements: RedisBytes &convert=$$.to_int(10) &requires=self.num_elements <= int64(MAX_SIZE);
# Null array is an array with elements unset. This is different from an empty array
elements: BulkStringWithTy[uint64(self.num_elements)];
};
type BulkStringWithTy = unit {
# Need to consume the type here
: uint8 &requires=$$=='$';
length: RedisBytes &convert=$$.to_int(10) &requires=self.length <= int64(MAX_SIZE);
# NullBulkString is a BulkString with content unset
content: bytes &size=uint64(self.length) if(self.length >= 0);
# Consume last CLRF
: skip RedisBytes;
};
public type ServerData = unit {
%synchronize-after = b"\x0d\x0a";
data: Data;