mirror of
https://github.com/servo/servo.git
synced 2025-09-27 23:30:08 +01:00
indexeddb: Use UUIDs instead of sanitization of object store names (#38944)
Sanitization of object store names brought some problems because of replacing special characters and making it impossible to have certain object store names that are allowed by the spec. These changes make sure deterministic UUIDs are used for file paths plus object store names are inserted into SQLite without sanitization. Testing: Covered by existing tests and new unit tests were added. Fixes: #37569 --------- Signed-off-by: Rodion Borovyk <rodion.borovyk@gmail.com>
This commit is contained in:
parent
559b05c1b3
commit
0089e652c5
6 changed files with 119 additions and 111 deletions
|
@ -4,9 +4,7 @@
|
|||
use std::collections::VecDeque;
|
||||
use std::sync::Arc;
|
||||
|
||||
use net::indexeddb::engines::{
|
||||
KvsEngine, KvsOperation, KvsTransaction, SanitizedName, SqliteEngine,
|
||||
};
|
||||
use net::indexeddb::engines::{KvsEngine, KvsOperation, KvsTransaction, SqliteEngine};
|
||||
use net::indexeddb::idb_thread::IndexedDBDescription;
|
||||
use net::resource_thread::CoreResourceThreadPool;
|
||||
use net_traits::indexeddb_thread::{
|
||||
|
@ -73,13 +71,13 @@ fn test_create_store() {
|
|||
thread_pool,
|
||||
)
|
||||
.unwrap();
|
||||
let store_name = SanitizedName::new("test_store".to_string());
|
||||
let result = db.create_store(store_name.clone(), None, true);
|
||||
let store_name = "test_store";
|
||||
let result = db.create_store(store_name, None, true);
|
||||
assert!(result.is_ok());
|
||||
let create_result = result.unwrap();
|
||||
assert_eq!(create_result, CreateObjectResult::Created);
|
||||
// Try to create the same store again
|
||||
let result = db.create_store(store_name.clone(), None, false);
|
||||
let result = db.create_store(store_name, None, false);
|
||||
assert!(result.is_ok());
|
||||
let create_result = result.unwrap();
|
||||
assert_eq!(create_result, CreateObjectResult::AlreadyExists);
|
||||
|
@ -87,6 +85,53 @@ fn test_create_store() {
|
|||
assert!(db.has_key_generator(store_name));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_create_store_empty_name() {
|
||||
let base_dir = tempfile::tempdir().expect("Failed to create temp dir");
|
||||
let thread_pool = get_pool();
|
||||
let db = SqliteEngine::new(
|
||||
base_dir.path(),
|
||||
&IndexedDBDescription {
|
||||
name: "test_db".to_string(),
|
||||
origin: test_origin(),
|
||||
},
|
||||
thread_pool,
|
||||
)
|
||||
.unwrap();
|
||||
let store_name = "";
|
||||
let result = db.create_store(store_name, None, true);
|
||||
assert!(result.is_ok());
|
||||
let create_result = result.unwrap();
|
||||
assert_eq!(create_result, CreateObjectResult::Created);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_injection() {
|
||||
let base_dir = tempfile::tempdir().expect("Failed to create temp dir");
|
||||
let thread_pool = get_pool();
|
||||
let db = SqliteEngine::new(
|
||||
base_dir.path(),
|
||||
&IndexedDBDescription {
|
||||
name: "test_db".to_string(),
|
||||
origin: test_origin(),
|
||||
},
|
||||
thread_pool,
|
||||
)
|
||||
.unwrap();
|
||||
// Create a normal store
|
||||
let store_name1 = "test_store";
|
||||
let result = db.create_store(store_name1, None, true);
|
||||
assert!(result.is_ok());
|
||||
let create_result = result.unwrap();
|
||||
assert_eq!(create_result, CreateObjectResult::Created);
|
||||
// Injection
|
||||
let store_name2 = "' OR 1=1 -- -";
|
||||
let result = db.create_store(store_name2, None, false);
|
||||
assert!(result.is_ok());
|
||||
let create_result = result.unwrap();
|
||||
assert_eq!(create_result, CreateObjectResult::Created);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_key_path() {
|
||||
let base_dir = tempfile::tempdir().expect("Failed to create temp dir");
|
||||
|
@ -100,12 +145,8 @@ fn test_key_path() {
|
|||
thread_pool,
|
||||
)
|
||||
.unwrap();
|
||||
let store_name = SanitizedName::new("test_store".to_string());
|
||||
let result = db.create_store(
|
||||
store_name.clone(),
|
||||
Some(KeyPath::String("test".to_string())),
|
||||
true,
|
||||
);
|
||||
let store_name = "test_store";
|
||||
let result = db.create_store(store_name, Some(KeyPath::String("test".to_string())), true);
|
||||
assert!(result.is_ok());
|
||||
assert_eq!(
|
||||
db.key_path(store_name),
|
||||
|
@ -126,16 +167,16 @@ fn test_delete_store() {
|
|||
thread_pool,
|
||||
)
|
||||
.unwrap();
|
||||
db.create_store(SanitizedName::new("test_store".to_string()), None, false)
|
||||
db.create_store("test_store", None, false)
|
||||
.expect("Failed to create store");
|
||||
// Delete the store
|
||||
db.delete_store(SanitizedName::new("test_store".to_string()))
|
||||
db.delete_store("test_store")
|
||||
.expect("Failed to delete store");
|
||||
// Try to delete the same store again
|
||||
let result = db.delete_store(SanitizedName::new("test_store".into()));
|
||||
let result = db.delete_store("test_store");
|
||||
assert!(result.is_err());
|
||||
// Try to delete a non-existing store
|
||||
let result = db.delete_store(SanitizedName::new("test_store".into()));
|
||||
let result = db.delete_store("test_store");
|
||||
// Should work as per spec
|
||||
assert!(result.is_err());
|
||||
}
|
||||
|
@ -153,8 +194,8 @@ fn test_async_operations() {
|
|||
thread_pool,
|
||||
)
|
||||
.unwrap();
|
||||
let store_name = SanitizedName::new("test_store".to_string());
|
||||
db.create_store(store_name.clone(), None, false)
|
||||
let store_name = "test_store";
|
||||
db.create_store(store_name, None, false)
|
||||
.expect("Failed to create store");
|
||||
let channel = ipc_channel::ipc::channel().unwrap();
|
||||
let channel2 = ipc_channel::ipc::channel().unwrap();
|
||||
|
@ -166,7 +207,7 @@ fn test_async_operations() {
|
|||
mode: IndexedDBTxnMode::Readwrite,
|
||||
requests: VecDeque::from(vec![
|
||||
KvsOperation {
|
||||
store_name: store_name.clone(),
|
||||
store_name: store_name.to_owned(),
|
||||
operation: AsyncOperation::ReadWrite(AsyncReadWriteOperation::PutItem {
|
||||
sender: channel.0,
|
||||
key: IndexedDBKeyType::Number(1.0),
|
||||
|
@ -175,35 +216,35 @@ fn test_async_operations() {
|
|||
}),
|
||||
},
|
||||
KvsOperation {
|
||||
store_name: store_name.clone(),
|
||||
store_name: store_name.to_owned(),
|
||||
operation: AsyncOperation::ReadOnly(AsyncReadOnlyOperation::GetItem {
|
||||
sender: channel2.0,
|
||||
key_range: IndexedDBKeyRange::only(IndexedDBKeyType::Number(1.0)),
|
||||
}),
|
||||
},
|
||||
KvsOperation {
|
||||
store_name: store_name.clone(),
|
||||
store_name: store_name.to_owned(),
|
||||
operation: AsyncOperation::ReadOnly(AsyncReadOnlyOperation::GetItem {
|
||||
sender: channel3.0,
|
||||
key_range: IndexedDBKeyRange::only(IndexedDBKeyType::Number(5.0)),
|
||||
}),
|
||||
},
|
||||
KvsOperation {
|
||||
store_name: store_name.clone(),
|
||||
store_name: store_name.to_owned(),
|
||||
operation: AsyncOperation::ReadOnly(AsyncReadOnlyOperation::Count {
|
||||
sender: channel4.0,
|
||||
key_range: IndexedDBKeyRange::only(IndexedDBKeyType::Number(1.0)),
|
||||
}),
|
||||
},
|
||||
KvsOperation {
|
||||
store_name: store_name.clone(),
|
||||
store_name: store_name.to_owned(),
|
||||
operation: AsyncOperation::ReadWrite(AsyncReadWriteOperation::RemoveItem {
|
||||
sender: channel5.0,
|
||||
key: IndexedDBKeyType::Number(1.0),
|
||||
}),
|
||||
},
|
||||
KvsOperation {
|
||||
store_name: store_name.clone(),
|
||||
store_name: store_name.to_owned(),
|
||||
operation: AsyncOperation::ReadWrite(AsyncReadWriteOperation::Clear(channel6.0)),
|
||||
},
|
||||
]),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue