diff options
author | Heyang Zhou <zhy20000919@hotmail.com> | 2024-02-06 00:27:03 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-02-06 00:27:03 +0800 |
commit | e53ced0b8dc458e772ae08fdf152efa889a2250a (patch) | |
tree | 6c180ca2739b6b5194bf7f305cf3dd306b3c9a16 /ext/kv/lib.rs | |
parent | d13094c8215e7e0285e7bf4bcb23ac97a126c198 (diff) |
fix(unstable): validate kv list selector (#22265)
Check that in a `KvListSelector`, `start` and `end` are actually within
the keyspace bounds defined by `prefix`, if both are present.
Diffstat (limited to 'ext/kv/lib.rs')
-rw-r--r-- | ext/kv/lib.rs | 41 |
1 files changed, 30 insertions, 11 deletions
diff --git a/ext/kv/lib.rs b/ext/kv/lib.rs index 1286a7323..3a868d463 100644 --- a/ext/kv/lib.rs +++ b/ext/kv/lib.rs @@ -605,17 +605,36 @@ impl RawSelector { start: None, end: None, }), - (Some(prefix), Some(start), None) => Ok(Self::Prefixed { - prefix, - start: Some(start), - end: None, - }), - (Some(prefix), None, Some(end)) => Ok(Self::Prefixed { - prefix, - start: None, - end: Some(end), - }), - (None, Some(start), Some(end)) => Ok(Self::Range { start, end }), + (Some(prefix), Some(start), None) => { + if !start.starts_with(&prefix) || start.len() == prefix.len() { + return Err(type_error( + "start key is not in the keyspace defined by prefix", + )); + } + Ok(Self::Prefixed { + prefix, + start: Some(start), + end: None, + }) + } + (Some(prefix), None, Some(end)) => { + if !end.starts_with(&prefix) || end.len() == prefix.len() { + return Err(type_error( + "end key is not in the keyspace defined by prefix", + )); + } + Ok(Self::Prefixed { + prefix, + start: None, + end: Some(end), + }) + } + (None, Some(start), Some(end)) => { + if start > end { + return Err(type_error("start key is greater than end key")); + } + Ok(Self::Range { start, end }) + } (None, Some(start), None) => { let end = start.iter().copied().chain(Some(0)).collect(); Ok(Self::Range { start, end }) |