mirror of
https://github.com/denoland/deno
synced 2024-11-05 18:45:24 +00:00
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.
This commit is contained in:
parent
d13094c821
commit
e53ced0b8d
2 changed files with 81 additions and 11 deletions
|
@ -702,6 +702,24 @@ dbTest("list prefix with start empty", async (db) => {
|
|||
assertEquals(entries.length, 0);
|
||||
});
|
||||
|
||||
dbTest("list prefix with start equal to prefix", async (db) => {
|
||||
await setupData(db);
|
||||
await assertRejects(
|
||||
async () => await collect(db.list({ prefix: ["a"], start: ["a"] })),
|
||||
TypeError,
|
||||
"start key is not in the keyspace defined by prefix",
|
||||
);
|
||||
});
|
||||
|
||||
dbTest("list prefix with start out of bounds", async (db) => {
|
||||
await setupData(db);
|
||||
await assertRejects(
|
||||
async () => await collect(db.list({ prefix: ["b"], start: ["a"] })),
|
||||
TypeError,
|
||||
"start key is not in the keyspace defined by prefix",
|
||||
);
|
||||
});
|
||||
|
||||
dbTest("list prefix with end", async (db) => {
|
||||
const versionstamp = await setupData(db);
|
||||
const entries = await collect(db.list({ prefix: ["a"], end: ["a", "c"] }));
|
||||
|
@ -717,6 +735,24 @@ dbTest("list prefix with end empty", async (db) => {
|
|||
assertEquals(entries.length, 0);
|
||||
});
|
||||
|
||||
dbTest("list prefix with end equal to prefix", async (db) => {
|
||||
await setupData(db);
|
||||
await assertRejects(
|
||||
async () => await collect(db.list({ prefix: ["a"], end: ["a"] })),
|
||||
TypeError,
|
||||
"end key is not in the keyspace defined by prefix",
|
||||
);
|
||||
});
|
||||
|
||||
dbTest("list prefix with end out of bounds", async (db) => {
|
||||
await setupData(db);
|
||||
await assertRejects(
|
||||
async () => await collect(db.list({ prefix: ["a"], end: ["b"] })),
|
||||
TypeError,
|
||||
"end key is not in the keyspace defined by prefix",
|
||||
);
|
||||
});
|
||||
|
||||
dbTest("list prefix with empty prefix", async (db) => {
|
||||
const res = await db.set(["a"], 1);
|
||||
const entries = await collect(db.list({ prefix: [] }));
|
||||
|
@ -1020,6 +1056,21 @@ dbTest("list range with manual cursor reverse", async (db) => {
|
|||
]);
|
||||
});
|
||||
|
||||
dbTest("list range with start greater than end", async (db) => {
|
||||
await setupData(db);
|
||||
await assertRejects(
|
||||
async () => await collect(db.list({ start: ["b"], end: ["a"] })),
|
||||
TypeError,
|
||||
"start key is greater than end key",
|
||||
);
|
||||
});
|
||||
|
||||
dbTest("list range with start equal to end", async (db) => {
|
||||
await setupData(db);
|
||||
const entries = await collect(db.list({ start: ["a"], end: ["a"] }));
|
||||
assertEquals(entries.length, 0);
|
||||
});
|
||||
|
||||
dbTest("list invalid selector", async (db) => {
|
||||
await setupData(db);
|
||||
|
||||
|
|
|
@ -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 })
|
||||
|
|
Loading…
Reference in a new issue