Skip to content

Commit

Permalink
Check str constraints on dict keys in msgpack
Browse files Browse the repository at this point in the history
Previously the msgpack decoder would miss checking constraints on dict
keys if those keys were short ascii strings. This fixes that and adds a
test.
  • Loading branch information
jcrist committed Nov 1, 2023
1 parent 60d4755 commit 438b80b
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 5 deletions.
8 changes: 3 additions & 5 deletions msgspec/_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -14691,11 +14691,9 @@ mpack_decode_key(DecoderState *self, TypeNode *type, PathNode *path) {
/* Peek at the next op */
op = *self->input_pos;

if (MS_LIKELY(
'\xa0' <= op && op <= '\xbf' &&
type->types & (MS_TYPE_STR | MS_TYPE_ANY)
)
) {
bool is_str = type->types == MS_TYPE_ANY || type->types == MS_TYPE_STR;

if (MS_LIKELY(is_str && '\xa0' <= op && op <= '\xbf')) {
/* A short (<= 31 byte) unicode str */
self->input_pos++; /* consume op */
Py_ssize_t size = op & 0x1f;
Expand Down
17 changes: 17 additions & 0 deletions tests/test_constraints.py
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,23 @@ class Ex(msgspec.Struct):
with pytest.raises(msgspec.ValidationError):
dec.decode(proto.encode(Ex(x)))

@pytest.mark.parametrize(
"meta, good, bad",
[
(Meta(min_length=2), ["xy", "𝄞xy"], ["", "𝄞"]),
(Meta(pattern="as"), ["as", "pass", "𝄞as"], ["", "nope", "𝄞"]),
],
)
def test_str_constraints_on_dict_keys(self, proto, meta, good, bad):
dec = proto.Decoder(Dict[Annotated[str, meta], int])

for x in good:
assert dec.decode(proto.encode({x: 1})) == {x: 1}

for x in bad:
with pytest.raises(msgspec.ValidationError):
dec.decode(proto.encode({x: 1}))


class TestDateTimeConstraints:
@staticmethod
Expand Down

0 comments on commit 438b80b

Please sign in to comment.