Files
ladybird/Tests/LibDatabase/TestDatabase.cpp
Shannon Booth 201c9bb154 LibDatabase: Allow String values to contain embedded null bytes
LibDatabase previously truncated String values at the first '\0' when
round-tripping through SQLite due to the use of strlen.

This is something which we should support according to WPT:

https://wpt.live/webstorage/storage_setitem.window.html

The above test works fine when run through our test-web harness
as we have the SQL database disabled, so this instead adds a C++
test.
2026-02-14 10:25:33 -05:00

60 lines
2.0 KiB
C++

/*
* Copyright (c) 2026, Shannon Booth <shannon@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibTest/TestCase.h>
#include <Libraries/LibDatabase/Database.h>
TEST_CASE(string_can_contain_null_bytes)
{
auto database = TRY_OR_FAIL(Database::Database::create_memory_backed());
database->execute_statement(TRY_OR_FAIL(database->prepare_statement(R"#(
CREATE TABLE WebStorage (
key TEXT PRIMARY KEY,
value TEXT
);
)#"sv)),
{});
auto get_item_statement = TRY_OR_FAIL(database->prepare_statement("SELECT value FROM WebStorage WHERE key = ?;"sv));
auto set_item_statement = TRY_OR_FAIL(database->prepare_statement("INSERT OR REPLACE INTO WebStorage VALUES (?, ?);"sv));
auto delete_item_statement = TRY_OR_FAIL(database->prepare_statement("DELETE FROM WebStorage WHERE key = ?;"sv));
auto get_item = [&](String const& key) {
Optional<String> result;
database->execute_statement(
get_item_statement,
[&](auto statement_id) {
result = database->result_column<String>(statement_id, 0);
},
key);
return result;
};
auto set_item = [&](String const& key, String const& value) {
database->execute_statement(
set_item_statement,
{},
key,
value);
};
auto remove_item = [&](String const& key) {
database->execute_statement(
delete_item_statement,
{},
key);
};
EXPECT_EQ(get_item("my_key"_string), Optional<String> {});
set_item("my_key"_string, "my_value"_string);
EXPECT_EQ(get_item("my_key"_string), Optional<String> { "my_value"_string });
set_item("my_key"_string, "my_value_with_\0_null"_string);
EXPECT_EQ(get_item("my_key"_string), Optional<String> { "my_value_with_\0_null"_string });
remove_item("my_key"_string);
EXPECT_EQ(get_item("my_key"_string), Optional<String> {});
}