Everywhere: Make ByteBuffer::{create_*,copy}() OOM-safe

This commit is contained in:
Ali Mohammad Pur 2021-09-06 03:29:52 +04:30 committed by Andreas Kling
parent 3a9f00c59b
commit 97e97bccab
Notes: sideshowbarker 2024-07-18 04:39:40 +09:00
105 changed files with 629 additions and 290 deletions

View file

@ -87,7 +87,8 @@ ByteBuffer decode_base64(const StringView& input)
output.append(out2);
}
return ByteBuffer::copy(output.data(), output.size());
// FIXME: Handle OOM failure.
return ByteBuffer::copy(output).release_value();
}
String encode_base64(ReadonlyBytes input)

View file

@ -62,31 +62,35 @@ public:
return *this;
}
[[nodiscard]] static ByteBuffer create_uninitialized(size_t size)
[[nodiscard]] static Optional<ByteBuffer> create_uninitialized(size_t size)
{
auto buffer = ByteBuffer();
auto ok = buffer.try_resize(size);
VERIFY(ok);
return buffer;
if (!buffer.try_resize(size))
return {};
return { move(buffer) };
}
[[nodiscard]] static ByteBuffer create_zeroed(size_t size)
[[nodiscard]] static Optional<ByteBuffer> create_zeroed(size_t size)
{
auto buffer = create_uninitialized(size);
auto buffer_result = create_uninitialized(size);
if (!buffer_result.has_value())
return {};
auto& buffer = buffer_result.value();
buffer.zero_fill();
VERIFY(size == 0 || (buffer[0] == 0 && buffer[size - 1] == 0));
return buffer;
return buffer_result;
}
[[nodiscard]] static ByteBuffer copy(void const* data, size_t size)
[[nodiscard]] static Optional<ByteBuffer> copy(void const* data, size_t size)
{
auto buffer = create_uninitialized(size);
if (size != 0)
__builtin_memcpy(buffer.data(), data, size);
if (buffer.has_value() && size != 0)
__builtin_memcpy(buffer->data(), data, size);
return buffer;
}
[[nodiscard]] static ByteBuffer copy(ReadonlyBytes bytes)
[[nodiscard]] static Optional<ByteBuffer> copy(ReadonlyBytes bytes)
{
return copy(bytes.data(), bytes.size());
}
@ -133,12 +137,13 @@ public:
[[nodiscard]] void* end_pointer() { return data() + m_size; }
[[nodiscard]] void const* end_pointer() const { return data() + m_size; }
// FIXME: Make this function handle failures too.
[[nodiscard]] ByteBuffer slice(size_t offset, size_t size) const
{
// I cannot hand you a slice I don't have
VERIFY(offset + size <= this->size());
return copy(offset_pointer(offset), size);
return copy(offset_pointer(offset), size).release_value();
}
void clear()
@ -237,8 +242,10 @@ private:
if (!other.m_inline) {
m_outline_buffer = other.m_outline_buffer;
m_outline_capacity = other.m_outline_capacity;
} else
} else {
VERIFY(other.m_size <= inline_capacity);
__builtin_memcpy(m_inline_buffer, other.m_inline_buffer, other.m_size);
}
other.m_size = 0;
other.m_inline = true;
}

View file

@ -20,7 +20,11 @@ Optional<ByteBuffer> decode_hex(const StringView& input)
if ((input.length() % 2) != 0)
return {};
auto output = ByteBuffer::create_zeroed(input.length() / 2);
auto output_result = ByteBuffer::create_zeroed(input.length() / 2);
if (!output_result.has_value())
return {};
auto& output = output_result.value();
for (size_t i = 0; i < input.length() / 2; ++i) {
const auto c1 = decode_hex_digit(input[i * 2]);
@ -34,7 +38,7 @@ Optional<ByteBuffer> decode_hex(const StringView& input)
output[i] = (c1 << 4) + c2;
}
return output;
return output_result;
}
String encode_hex(const ReadonlyBytes input)

View file

@ -224,7 +224,7 @@ public:
size_t nwritten = 0;
while (bytes.size() - nwritten > 0) {
if ((m_write_offset + nwritten) % chunk_size == 0)
m_chunks.append(ByteBuffer::create_uninitialized(chunk_size));
m_chunks.append(ByteBuffer::create_uninitialized(chunk_size).release_value()); // FIXME: Handle possible OOM situation.
nwritten += bytes.slice(nwritten).copy_trimmed_to(m_chunks.last().bytes().slice((m_write_offset + nwritten) % chunk_size));
}
@ -241,7 +241,8 @@ public:
ByteBuffer copy_into_contiguous_buffer() const
{
auto buffer = ByteBuffer::create_uninitialized(size());
// FIXME: Handle possible OOM situation.
auto buffer = ByteBuffer::create_uninitialized(size()).release_value();
const auto nread = read_without_consuming(buffer);
VERIFY(nread == buffer.size());

View file

@ -176,7 +176,8 @@ ByteBuffer String::to_byte_buffer() const
{
if (!m_impl)
return {};
return ByteBuffer::copy(reinterpret_cast<const u8*>(characters()), length());
// FIXME: Handle OOM failure.
return ByteBuffer::copy(bytes()).release_value();
}
template<typename T>

View file

@ -69,7 +69,8 @@ void StringBuilder::appendvf(char const* fmt, va_list ap)
ByteBuffer StringBuilder::to_byte_buffer() const
{
return ByteBuffer::copy(data(), length());
// FIXME: Handle OOM failure.
return ByteBuffer::copy(data(), length()).release_value();
}
String StringBuilder::to_string() const

View file

@ -213,7 +213,10 @@ KResult Ext2FSInode::write_indirect_block(BlockBasedFileSystem::BlockIndex block
const auto entries_per_block = EXT2_ADDR_PER_BLOCK(&fs().super_block());
VERIFY(blocks_indices.size() <= entries_per_block);
auto block_contents = ByteBuffer::create_uninitialized(fs().block_size());
auto block_contents_result = ByteBuffer::create_uninitialized(fs().block_size());
if (!block_contents_result.has_value())
return ENOMEM;
auto block_contents = block_contents_result.release_value();
OutputMemoryStream stream { block_contents };
auto buffer = UserOrKernelBuffer::for_kernel_buffer(stream.data());
@ -235,7 +238,10 @@ KResult Ext2FSInode::grow_doubly_indirect_block(BlockBasedFileSystem::BlockIndex
VERIFY(blocks_indices.size() > old_blocks_length);
VERIFY(blocks_indices.size() <= entries_per_doubly_indirect_block);
auto block_contents = ByteBuffer::create_uninitialized(fs().block_size());
auto block_contents_result = ByteBuffer::create_uninitialized(fs().block_size());
if (!block_contents_result.has_value())
return ENOMEM;
auto block_contents = block_contents_result.release_value();
auto* block_as_pointers = (unsigned*)block_contents.data();
OutputMemoryStream stream { block_contents };
auto buffer = UserOrKernelBuffer::for_kernel_buffer(stream.data());
@ -275,7 +281,10 @@ KResult Ext2FSInode::shrink_doubly_indirect_block(BlockBasedFileSystem::BlockInd
VERIFY(old_blocks_length >= new_blocks_length);
VERIFY(new_blocks_length <= entries_per_doubly_indirect_block);
auto block_contents = ByteBuffer::create_uninitialized(fs().block_size());
auto block_contents_result = ByteBuffer::create_uninitialized(fs().block_size());
if (!block_contents_result.has_value())
return ENOMEM;
auto block_contents = block_contents_result.release_value();
auto* block_as_pointers = (unsigned*)block_contents.data();
auto buffer = UserOrKernelBuffer::for_kernel_buffer(reinterpret_cast<u8*>(block_as_pointers));
TRY(fs().read_block(block, &buffer, fs().block_size()));
@ -308,7 +317,10 @@ KResult Ext2FSInode::grow_triply_indirect_block(BlockBasedFileSystem::BlockIndex
VERIFY(blocks_indices.size() > old_blocks_length);
VERIFY(blocks_indices.size() <= entries_per_triply_indirect_block);
auto block_contents = ByteBuffer::create_uninitialized(fs().block_size());
auto block_contents_result = ByteBuffer::create_uninitialized(fs().block_size());
if (!block_contents_result.has_value())
return ENOMEM;
auto block_contents = block_contents_result.release_value();
auto* block_as_pointers = (unsigned*)block_contents.data();
OutputMemoryStream stream { block_contents };
auto buffer = UserOrKernelBuffer::for_kernel_buffer(stream.data());
@ -351,7 +363,10 @@ KResult Ext2FSInode::shrink_triply_indirect_block(BlockBasedFileSystem::BlockInd
VERIFY(old_blocks_length >= new_blocks_length);
VERIFY(new_blocks_length <= entries_per_triply_indirect_block);
auto block_contents = ByteBuffer::create_uninitialized(fs().block_size());
auto block_contents_result = ByteBuffer::create_uninitialized(fs().block_size());
if (!block_contents_result.has_value())
return ENOMEM;
auto block_contents = block_contents_result.release_value();
auto* block_as_pointers = (unsigned*)block_contents.data();
auto buffer = UserOrKernelBuffer::for_kernel_buffer(reinterpret_cast<u8*>(block_as_pointers));
TRY(fs().read_block(block, &buffer, fs().block_size()));
@ -583,7 +598,8 @@ Vector<Ext2FS::BlockIndex> Ext2FSInode::compute_block_list_impl_internal(const e
if (!count)
return;
size_t read_size = count * sizeof(u32);
auto array_storage = ByteBuffer::create_uninitialized(read_size);
// FIXME: Handle possible OOM situation.
auto array_storage = ByteBuffer::create_uninitialized(read_size).release_value();
auto* array = (u32*)array_storage.data();
auto buffer = UserOrKernelBuffer::for_kernel_buffer((u8*)array);
if (auto result = fs().read_block(array_block_index, &buffer, read_size, 0); result.is_error()) {
@ -1109,7 +1125,10 @@ KResult Ext2FSInode::write_directory(Vector<Ext2FSDirectoryEntry>& entries)
dbgln_if(EXT2_DEBUG, "Ext2FSInode[{}]::write_directory(): New directory contents to write (size {}):", identifier(), directory_size);
auto directory_data = ByteBuffer::create_uninitialized(directory_size);
auto directory_data_result = ByteBuffer::create_uninitialized(directory_size);
if (!directory_data_result.has_value())
return ENOMEM;
auto directory_data = directory_data_result.release_value();
OutputMemoryStream stream { directory_data };
for (auto& entry : entries) {

View file

@ -251,7 +251,7 @@ UNMAP_AFTER_INIT int NE2000NetworkAdapter::ram_test()
out8(REG_WR_REMOTEBYTECOUNT1, 0x00);
out8(REG_WR_RECEIVECONFIGURATION, BIT_RECEIVECONFIGURATION_MON);
out8(REG_RW_COMMAND, BIT_COMMAND_DMA_ABORT | BIT_COMMAND_START);
auto buffer = ByteBuffer::create_uninitialized(NE2K_RAM_SIZE);
Array<u8, NE2K_RAM_SIZE> buffer;
const u8 patterns[3] = { 0x5a, 0xff, 0x00 };
for (int i = 0; i < 3; ++i) {
@ -412,22 +412,35 @@ void NE2000NetworkAdapter::receive()
dbgln_if(NE2000_DEBUG, "NE2000NetworkAdapter: Packet received {} length={}", (packet_ok ? "intact" : "damaged"), header.length);
if (packet_ok) {
auto packet = NetworkByteBuffer::create_uninitialized(sizeof(received_packet_header) + header.length);
int bytes_left = packet.size();
size_t bytes_in_packet = sizeof(received_packet_header) + header.length;
auto packet_result = NetworkByteBuffer::create_uninitialized(bytes_in_packet);
u8 drop_buffer[NE2K_PAGE_SIZE];
Bytes buffer { drop_buffer, array_size(drop_buffer) };
bool will_drop { false };
if (!packet_result.has_value()) {
dbgln("NE2000NetworkAdapter: Not enough memory for packet with length = {}, dropping.", header.length);
will_drop = true;
} else {
buffer = packet_result->bytes();
}
int current_offset = 0;
int ring_offset = header_address;
while (bytes_left > 0) {
int copy_size = min(bytes_left, NE2K_PAGE_SIZE);
rdma_read(ring_offset, packet.span().slice(current_offset, copy_size));
while (bytes_in_packet > 0) {
int copy_size = min(bytes_in_packet, NE2K_PAGE_SIZE);
rdma_read(ring_offset, buffer.slice(current_offset, copy_size));
if (!will_drop)
current_offset += copy_size;
ring_offset += copy_size;
bytes_left -= copy_size;
bytes_in_packet -= copy_size;
if (ring_offset == NE2K_RAM_RECV_END)
ring_offset = NE2K_RAM_RECV_BEGIN;
}
did_receive(packet.span().slice(sizeof(received_packet_header)));
if (!will_drop)
did_receive(buffer.slice(sizeof(received_packet_header)));
}
if (header.next_packet_page == (NE2K_RAM_RECV_BEGIN >> 8))

View file

@ -33,8 +33,12 @@ void NetworkAdapter::send_packet(ReadonlyBytes packet)
void NetworkAdapter::send(const MACAddress& destination, const ARPPacket& packet)
{
size_t size_in_bytes = sizeof(EthernetFrameHeader) + sizeof(ARPPacket);
auto buffer = NetworkByteBuffer::create_zeroed(size_in_bytes);
auto* eth = (EthernetFrameHeader*)buffer.data();
auto buffer_result = NetworkByteBuffer::create_zeroed(size_in_bytes);
if (!buffer_result.has_value()) {
dbgln("Dropping ARP packet targeted at {} as there is not enough memory to buffer it", packet.target_hardware_address().to_string());
return;
}
auto* eth = (EthernetFrameHeader*)buffer_result->data();
eth->set_source(mac_address());
eth->set_destination(destination);
eth->set_ether_type(EtherType::ARP);

View file

@ -30,8 +30,9 @@ public:
using HashType = HashT;
using DigestType = typename HashT::DigestType;
// FIXME: Do something other than VERIFY()'ing inside Optional in case of OOM.
FortunaPRNG()
: m_counter(ByteBuffer::create_zeroed(BlockType::block_size()))
: m_counter(ByteBuffer::create_zeroed(BlockType::block_size()).release_value())
{
}
@ -95,8 +96,17 @@ private:
}
}
DigestType digest = new_key.digest();
m_key = ByteBuffer::copy(digest.immutable_data(),
digest.data_length());
if (m_key.size() == digest.data_length()) {
// Avoid reallocating, just overwrite the key.
m_key.overwrite(0, digest.immutable_data(), digest.data_length());
} else {
auto buffer_result = ByteBuffer::copy(digest.immutable_data(), digest.data_length());
// If there's no memory left to copy this into, bail out.
if (!buffer_result.has_value())
return;
m_key = buffer_result.release_value();
}
m_reseed_number++;
m_p0_len = 0;

View file

@ -379,8 +379,9 @@ UNMAP_AFTER_INIT void IDEChannel::detect_disks()
}
}
ByteBuffer wbuf = ByteBuffer::create_uninitialized(512);
ByteBuffer bbuf = ByteBuffer::create_uninitialized(512);
// FIXME: Handle possible OOM situation here.
ByteBuffer wbuf = ByteBuffer::create_uninitialized(512).release_value();
ByteBuffer bbuf = ByteBuffer::create_uninitialized(512).release_value();
u8* b = bbuf.data();
u16* w = (u16*)wbuf.data();

View file

@ -58,7 +58,8 @@ Result<NonnullOwnPtr<GUIDPartitionTable>, PartitionTable::Error> GUIDPartitionTa
GUIDPartitionTable::GUIDPartitionTable(const StorageDevice& device)
: MBRPartitionTable(device)
{
m_cached_header = ByteBuffer::create_zeroed(m_device->block_size());
// FIXME: Handle OOM failure here.
m_cached_header = ByteBuffer::create_zeroed(m_device->block_size()).release_value();
VERIFY(partitions_count() == 0);
if (!initialize())
m_valid = false;
@ -87,7 +88,12 @@ bool GUIDPartitionTable::initialize()
return false;
}
auto entries_buffer = ByteBuffer::create_zeroed(m_device->block_size());
auto entries_buffer_result = ByteBuffer::create_zeroed(m_device->block_size());
if (!entries_buffer_result.has_value()) {
dbgln("GUIPartitionTable: not enough memory for entries buffer");
return false;
}
auto entries_buffer = entries_buffer_result.release_value();
auto raw_entries_buffer = UserOrKernelBuffer::for_kernel_buffer(entries_buffer.data());
size_t raw_byte_index = header().partition_array_start_lba * m_device->block_size();
for (size_t entry_index = 0; entry_index < header().entries_count; entry_index++) {

View file

@ -47,7 +47,7 @@ bool MBRPartitionTable::read_boot_record()
MBRPartitionTable::MBRPartitionTable(const StorageDevice& device, u32 start_lba)
: PartitionTable(device)
, m_start_lba(start_lba)
, m_cached_header(ByteBuffer::create_zeroed(m_device->block_size()))
, m_cached_header(ByteBuffer::create_zeroed(m_device->block_size()).release_value()) // FIXME: Do something sensible if this fails because of OOM.
{
if (!read_boot_record() || !initialize())
return;
@ -68,7 +68,7 @@ MBRPartitionTable::MBRPartitionTable(const StorageDevice& device, u32 start_lba)
MBRPartitionTable::MBRPartitionTable(const StorageDevice& device)
: PartitionTable(device)
, m_start_lba(0)
, m_cached_header(ByteBuffer::create_zeroed(m_device->block_size()))
, m_cached_header(ByteBuffer::create_zeroed(m_device->block_size()).release_value()) // FIXME: Do something sensible if this fails because of OOM.
{
if (!read_boot_record() || contains_ebr() || is_protective_mbr() || !initialize())
return;

View file

@ -73,7 +73,10 @@ KResultOr<size_t> StorageDevice::read(FileDescription&, u64 offset, UserOrKernel
off_t pos = whole_blocks * block_size();
if (remaining > 0) {
auto data = ByteBuffer::create_uninitialized(block_size());
auto data_result = ByteBuffer::create_uninitialized(block_size());
if (!data_result.has_value())
return ENOMEM;
auto data = data_result.release_value();
auto data_buffer = UserOrKernelBuffer::for_kernel_buffer(data.data());
auto read_request = make_request<AsyncBlockDeviceRequest>(AsyncBlockDeviceRequest::Read, index + whole_blocks, 1, data_buffer, block_size());
auto result = read_request->wait();
@ -141,7 +144,8 @@ KResultOr<size_t> StorageDevice::write(FileDescription&, u64 offset, const UserO
// partial write, we have to read the block's content first, modify it,
// then write the whole block back to the disk.
if (remaining > 0) {
auto data = ByteBuffer::create_zeroed(block_size());
// FIXME: Do something sensible with this OOM scenario.
auto data = ByteBuffer::create_zeroed(block_size()).release_value();
auto data_buffer = UserOrKernelBuffer::for_kernel_buffer(data.data());
{

View file

@ -10,7 +10,7 @@
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
{
auto flac_data = ByteBuffer::copy(data, size);
auto flac_data = ByteBuffer::copy(data, size).release_value();
auto flac = make<Audio::FlacLoaderPlugin>(flac_data);
if (!flac->sniff())

View file

@ -11,7 +11,7 @@
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
{
auto parser = IMAP::Parser();
parser.parse(ByteBuffer::copy(data, size), true);
parser.parse(ByteBuffer::copy(data, size), false);
parser.parse(ByteBuffer::copy(data, size).release_value(), true);
parser.parse(ByteBuffer::copy(data, size).release_value(), false);
return 0;
}

View file

@ -10,7 +10,6 @@
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
{
auto buffer = ByteBuffer::copy(data, size);
Crypto::Hash::MD5::hash(buffer);
Crypto::Hash::MD5::hash(data, size);
return 0;
}

View file

@ -10,7 +10,6 @@
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
{
ByteBuffer rsa_data = ByteBuffer::copy(data, size);
Crypto::PK::RSA::parse_rsa_key(rsa_data);
Crypto::PK::RSA::parse_rsa_key({ data, size });
return 0;
}

View file

@ -10,7 +10,6 @@
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
{
auto buffer = ByteBuffer::copy(data, size);
Crypto::Hash::SHA1::hash(buffer);
Crypto::Hash::SHA1::hash(data, size);
return 0;
}

View file

@ -10,7 +10,6 @@
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
{
auto buffer = ByteBuffer::copy(data, size);
Crypto::Hash::SHA256::hash(buffer);
Crypto::Hash::SHA256::hash(data, size);
return 0;
}

View file

@ -10,7 +10,6 @@
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
{
auto buffer = ByteBuffer::copy(data, size);
Crypto::Hash::SHA384::hash(buffer);
Crypto::Hash::SHA384::hash(data, size);
return 0;
}

View file

@ -10,7 +10,6 @@
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
{
auto buffer = ByteBuffer::copy(data, size);
Crypto::Hash::SHA512::hash(buffer);
Crypto::Hash::SHA512::hash(data, size);
return 0;
}

View file

@ -10,7 +10,7 @@
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
{
auto wav_data = ByteBuffer::copy(data, size);
auto wav_data = ByteBuffer::copy(data, size).release_value();
auto wav = make<Audio::WavLoaderPlugin>(wav_data);
if (!wav->sniff())

View file

@ -10,8 +10,7 @@
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
{
ByteBuffer zip_data = ByteBuffer::copy(data, size);
auto zip_file = Archive::Zip::try_create(zip_data);
auto zip_file = Archive::Zip::try_create({ data, size });
if (!zip_file.has_value())
return 0;

View file

@ -10,10 +10,10 @@
TEST_CASE(equality_operator)
{
ByteBuffer a = ByteBuffer::copy("Hello, world", 7);
ByteBuffer b = ByteBuffer::copy("Hello, friend", 7);
ByteBuffer a = ByteBuffer::copy("Hello, world", 7).release_value();
ByteBuffer b = ByteBuffer::copy("Hello, friend", 7).release_value();
// `a` and `b` are both "Hello, ".
ByteBuffer c = ByteBuffer::copy("asdf", 4);
ByteBuffer c = ByteBuffer::copy("asdf", 4).release_value();
ByteBuffer d;
EXPECT_EQ(a == a, true);
EXPECT_EQ(a == b, true);

View file

@ -84,7 +84,12 @@ int main(int argc, char** argv)
args_parser.add_positional_argument(target, "Target device/file path", "target");
args_parser.parse(argc, argv);
auto buffer = AK::ByteBuffer::create_zeroed(block_size);
auto buffer_result = AK::ByteBuffer::create_zeroed(block_size);
if (!buffer_result.has_value()) {
warnln("Failed to allocate a buffer of {} bytes", block_size);
return EXIT_FAILURE;
}
auto buffer = buffer_result.release_value();
int fd = open(target, O_CREAT | O_RDWR, 0666);
if (fd < 0) {

View file

@ -53,7 +53,7 @@ static bool test_single(const Testcase& testcase)
}
// Setup
ByteBuffer actual = ByteBuffer::create_uninitialized(SANDBOX_CANARY_SIZE + testcase.dest_n + SANDBOX_CANARY_SIZE);
ByteBuffer actual = ByteBuffer::create_uninitialized(SANDBOX_CANARY_SIZE + testcase.dest_n + SANDBOX_CANARY_SIZE).release_value();
fill_with_random(actual.data(), actual.size());
ByteBuffer expected = actual;
VERIFY(actual.offset_pointer(0) != expected.offset_pointer(0));

View file

@ -55,7 +55,7 @@ static bool test_single(const Testcase& testcase)
}
// Setup
ByteBuffer actual = ByteBuffer::create_uninitialized(SANDBOX_CANARY_SIZE + testcase.dest_n + SANDBOX_CANARY_SIZE);
ByteBuffer actual = ByteBuffer::create_uninitialized(SANDBOX_CANARY_SIZE + testcase.dest_n + SANDBOX_CANARY_SIZE).release_value();
fill_with_random(actual.data(), actual.size());
ByteBuffer expected = actual;
VERIFY(actual.offset_pointer(0) != expected.offset_pointer(0));

View file

@ -113,7 +113,7 @@ TEST_CASE(deflate_decompress_zeroes)
TEST_CASE(deflate_round_trip_store)
{
auto original = ByteBuffer::create_uninitialized(1024);
auto original = ByteBuffer::create_uninitialized(1024).release_value();
fill_with_random(original.data(), 1024);
auto compressed = Compress::DeflateCompressor::compress_all(original, Compress::DeflateCompressor::CompressionLevel::STORE);
EXPECT(compressed.has_value());
@ -124,7 +124,7 @@ TEST_CASE(deflate_round_trip_store)
TEST_CASE(deflate_round_trip_compress)
{
auto original = ByteBuffer::create_zeroed(2048);
auto original = ByteBuffer::create_zeroed(2048).release_value();
fill_with_random(original.data(), 1024); // we pre-filled the second half with 0s to make sure we test back references as well
// Since the different levels just change how much time is spent looking for better matches, just use fast here to reduce test time
auto compressed = Compress::DeflateCompressor::compress_all(original, Compress::DeflateCompressor::CompressionLevel::FAST);
@ -137,7 +137,7 @@ TEST_CASE(deflate_round_trip_compress)
TEST_CASE(deflate_round_trip_compress_large)
{
auto size = Compress::DeflateCompressor::block_size * 2;
auto original = ByteBuffer::create_uninitialized(size); // Compress a buffer larger than the maximum block size to test the sliding window mechanism
auto original = ByteBuffer::create_uninitialized(size).release_value(); // Compress a buffer larger than the maximum block size to test the sliding window mechanism
fill_with_random(original.data(), size);
// Since the different levels just change how much time is spent looking for better matches, just use fast here to reduce test time
auto compressed = Compress::DeflateCompressor::compress_all(original, Compress::DeflateCompressor::CompressionLevel::FAST);

View file

@ -87,7 +87,7 @@ TEST_CASE(gzip_decompress_repeat_around_buffer)
TEST_CASE(gzip_round_trip)
{
auto original = ByteBuffer::create_uninitialized(1024);
auto original = ByteBuffer::create_uninitialized(1024).release_value();
fill_with_random(original.data(), 1024);
auto compressed = Compress::GzipCompressor::compress_all(original);
EXPECT(compressed.has_value());

View file

@ -12,7 +12,7 @@
static ByteBuffer operator""_b(const char* string, size_t length)
{
return ByteBuffer::copy(string, length);
return ByteBuffer::copy(string, length).release_value();
}
TEST_CASE(test_AES_CBC_name)
@ -23,8 +23,8 @@ TEST_CASE(test_AES_CBC_name)
static auto test_aes_cbc_encrypt = [](auto& cipher, auto& result) {
auto in = "This is a test! This is another test!"_b;
auto out = cipher.create_aligned_buffer(in.size());
auto iv = ByteBuffer::create_zeroed(Crypto::Cipher::AESCipher::block_size());
auto out = cipher.create_aligned_buffer(in.size()).release_value();
auto iv = ByteBuffer::create_zeroed(Crypto::Cipher::AESCipher::block_size()).release_value();
auto out_span = out.bytes();
cipher.encrypt(in, out_span, iv);
EXPECT_EQ(out.size(), sizeof(result));
@ -84,9 +84,9 @@ TEST_CASE(test_AES_CBC_encrypt_with_unsigned_256bit_key)
static auto test_aes_cbc_decrypt = [](auto& cipher, auto& result, auto result_len) {
auto true_value = "This is a test! This is another test!";
auto in = ByteBuffer::copy(result, result_len);
auto out = cipher.create_aligned_buffer(in.size());
auto iv = ByteBuffer::create_zeroed(Crypto::Cipher::AESCipher::block_size());
auto in = ByteBuffer::copy(result, result_len).release_value();
auto out = cipher.create_aligned_buffer(in.size()).release_value();
auto iv = ByteBuffer::create_zeroed(Crypto::Cipher::AESCipher::block_size()).release_value();
auto out_span = out.bytes();
cipher.decrypt(in, out_span, iv);
EXPECT_EQ(out_span.size(), strlen(true_value));
@ -142,7 +142,7 @@ TEST_CASE(test_AES_CTR_name)
static auto test_aes_ctr_encrypt = [](auto key, auto ivec, auto in, auto out_expected) {
// nonce is already included in ivec.
Crypto::Cipher::AESCipher::CTRMode cipher(key, 8 * key.size(), Crypto::Cipher::Intent::Encryption);
ByteBuffer out_actual = ByteBuffer::create_zeroed(in.size());
ByteBuffer out_actual = ByteBuffer::create_zeroed(in.size()).release_value();
Bytes out_span = out_actual.bytes();
cipher.encrypt(in, out_span, ivec);
EXPECT_EQ(out_expected.size(), out_actual.size());
@ -309,7 +309,7 @@ TEST_CASE(test_AES_CTR_256bit_encrypt_36bytes_with_high_counter)
static auto test_aes_ctr_decrypt = [](auto key, auto ivec, auto in, auto out_expected) {
// nonce is already included in ivec.
Crypto::Cipher::AESCipher::CTRMode cipher(key, 8 * key.size(), Crypto::Cipher::Intent::Decryption);
ByteBuffer out_actual = ByteBuffer::create_zeroed(in.size());
ByteBuffer out_actual = ByteBuffer::create_zeroed(in.size()).release_value();
auto out_span = out_actual.bytes();
cipher.decrypt(in, out_span, ivec);
EXPECT_EQ(out_expected.size(), out_span.size());
@ -347,7 +347,7 @@ TEST_CASE(test_AES_GCM_128bit_encrypt_empty)
Crypto::Cipher::AESCipher::GCMMode cipher("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"_b, 128, Crypto::Cipher::Intent::Encryption);
u8 result_tag[] { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61, 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a };
Bytes out;
auto tag = ByteBuffer::create_uninitialized(16);
auto tag = ByteBuffer::create_uninitialized(16).release_value();
cipher.encrypt({}, out, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"_b.bytes(), {}, tag);
EXPECT(memcmp(result_tag, tag.data(), tag.size()) == 0);
}
@ -357,8 +357,8 @@ TEST_CASE(test_AES_GCM_128bit_encrypt_zeros)
Crypto::Cipher::AESCipher::GCMMode cipher("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"_b, 128, Crypto::Cipher::Intent::Encryption);
u8 result_tag[] { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd, 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf };
u8 result_ct[] { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92, 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 };
auto tag = ByteBuffer::create_uninitialized(16);
auto out = ByteBuffer::create_uninitialized(16);
auto tag = ByteBuffer::create_uninitialized(16).release_value();
auto out = ByteBuffer::create_uninitialized(16).release_value();
auto out_bytes = out.bytes();
cipher.encrypt("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"_b.bytes(), out_bytes, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"_b.bytes(), {}, tag);
EXPECT(memcmp(result_ct, out.data(), out.size()) == 0);
@ -370,8 +370,8 @@ TEST_CASE(test_AES_GCM_128bit_encrypt_multiple_blocks_with_iv)
Crypto::Cipher::AESCipher::GCMMode cipher("\xfe\xff\xe9\x92\x86\x65\x73\x1c\x6d\x6a\x8f\x94\x67\x30\x83\x08"_b, 128, Crypto::Cipher::Intent::Encryption);
u8 result_tag[] { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6, 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 };
u8 result_ct[] { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c, 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e, 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05, 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97, 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 };
auto tag = ByteBuffer::create_uninitialized(16);
auto out = ByteBuffer::create_uninitialized(64);
auto tag = ByteBuffer::create_uninitialized(16).release_value();
auto out = ByteBuffer::create_uninitialized(64).release_value();
auto out_bytes = out.bytes();
cipher.encrypt(
"\xd9\x31\x32\x25\xf8\x84\x06\xe5\xa5\x59\x09\xc5\xaf\xf5\x26\x9a\x86\xa7\xa9\x53\x15\x34\xf7\xda\x2e\x4c\x30\x3d\x8a\x31\x8a\x72\x1c\x3c\x0c\x95\x95\x68\x09\x53\x2f\xcf\x0e\x24\x49\xa6\xb5\x25\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57\xba\x63\x7b\x39\x1a\xaf\xd2\x55"_b.bytes(),
@ -388,8 +388,8 @@ TEST_CASE(test_AES_GCM_128bit_encrypt_with_aad)
Crypto::Cipher::AESCipher::GCMMode cipher("\xfe\xff\xe9\x92\x86\x65\x73\x1c\x6d\x6a\x8f\x94\x67\x30\x83\x08"_b, 128, Crypto::Cipher::Intent::Encryption);
u8 result_tag[] { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6, 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 };
u8 result_ct[] { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c, 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e, 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05, 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97, 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 };
auto tag = ByteBuffer::create_uninitialized(16);
auto out = ByteBuffer::create_uninitialized(64);
auto tag = ByteBuffer::create_uninitialized(16).release_value();
auto out = ByteBuffer::create_uninitialized(64).release_value();
auto out_bytes = out.bytes();
cipher.encrypt(
"\xd9\x31\x32\x25\xf8\x84\x06\xe5\xa5\x59\x09\xc5\xaf\xf5\x26\x9a\x86\xa7\xa9\x53\x15\x34\xf7\xda\x2e\x4c\x30\x3d\x8a\x31\x8a\x72\x1c\x3c\x0c\x95\x95\x68\x09\x53\x2f\xcf\x0e\x24\x49\xa6\xb5\x25\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57\xba\x63\x7b\x39\x1a\xaf\xd2\x55"_b.bytes(),
@ -417,7 +417,7 @@ TEST_CASE(test_AES_GCM_128bit_decrypt_zeros)
u8 input_tag[] { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd, 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf };
u8 input_ct[] { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92, 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 };
u8 result_pt[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
auto out = ByteBuffer::create_uninitialized(16);
auto out = ByteBuffer::create_uninitialized(16).release_value();
auto out_bytes = out.bytes();
auto consistency = cipher.decrypt({ input_ct, 16 }, out_bytes, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"_b.bytes(), {}, { input_tag, 16 });
EXPECT_EQ(consistency, Crypto::VerificationConsistency::Consistent);
@ -430,7 +430,7 @@ TEST_CASE(test_AES_GCM_128bit_decrypt_multiple_blocks_with_iv)
u8 input_tag[] { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd, 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf };
u8 input_ct[] { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92, 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 };
u8 result_pt[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
auto out = ByteBuffer::create_uninitialized(16);
auto out = ByteBuffer::create_uninitialized(16).release_value();
auto out_bytes = out.bytes();
auto consistency = cipher.decrypt({ input_ct, 16 }, out_bytes, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"_b.bytes(), {}, { input_tag, 16 });
EXPECT_EQ(consistency, Crypto::VerificationConsistency::Consistent);
@ -443,7 +443,7 @@ TEST_CASE(test_AES_GCM_128bit_decrypt_multiple_blocks_with_aad)
u8 input_tag[] { 0x93, 0xae, 0x16, 0x97, 0x49, 0xa3, 0xbf, 0x39, 0x4f, 0x61, 0xb7, 0xc1, 0xb1, 0x2, 0x4f, 0x60 };
u8 input_ct[] { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c, 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e, 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05, 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97, 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 };
u8 result_pt[] { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 };
auto out = ByteBuffer::create_uninitialized(64);
auto out = ByteBuffer::create_uninitialized(64).release_value();
auto out_bytes = out.bytes();
auto consistency = cipher.decrypt(
{ input_ct, 64 },

View file

@ -12,7 +12,7 @@
static ByteBuffer operator""_b(const char* string, size_t length)
{
return ByteBuffer::copy(string, length);
return ByteBuffer::copy(string, length).release_value();
}
TEST_CASE(test_RSA_raw_encrypt)

View file

@ -17,7 +17,7 @@ TEST_CASE(test_decode)
auto decode_equal_byte_buffer = [](const char* input, const char* expected, size_t expected_length) {
auto decoded = IMAP::decode_quoted_printable(StringView(input));
EXPECT(decoded == ByteBuffer::copy(expected, expected_length));
EXPECT(decoded == *ByteBuffer::copy(expected, expected_length));
};
decode_equal("hello world", "hello world");

View file

@ -18,7 +18,7 @@ constexpr const char* DEFAULT_SERVER { "www.google.com" };
static ByteBuffer operator""_b(const char* string, size_t length)
{
return ByteBuffer::copy(string, length);
return ByteBuffer::copy(string, length).release_value();
}
Vector<Certificate> load_certificates();
@ -69,7 +69,7 @@ TEST_CASE(test_TLS_hello_handshake)
RefPtr<TLS::TLSv12> tls = TLS::TLSv12::construct(nullptr);
tls->set_root_certificates(s_root_ca_certificates);
bool sent_request = false;
ByteBuffer contents = ByteBuffer::create_uninitialized(0);
ByteBuffer contents;
tls->on_tls_ready_to_write = [&](TLS::TLSv12& tls) {
if (sent_request)
return;

View file

@ -80,8 +80,7 @@ void GlyphEditorWidget::copy_glyph()
metadata.set("width", String::number(bitmap.width()));
metadata.set("height", String::number(bitmap.height()));
auto data = ByteBuffer::copy(&bits[0], bitmap.width() * bitmap.height());
GUI::Clipboard::the().set_data(data, "glyph/x-fonteditor", metadata);
GUI::Clipboard::the().set_data(ReadonlyBytes(&bits[0], bitmap.width() * bitmap.height()), "glyph/x-fonteditor", metadata);
}
void GlyphEditorWidget::paste_glyph()

View file

@ -75,7 +75,12 @@ HexEditorWidget::HexEditorWidget()
auto file_size = value.to_int();
if (file_size.has_value() && file_size.value() > 0) {
m_document_dirty = false;
m_editor->set_buffer(ByteBuffer::create_zeroed(file_size.value()));
auto buffer_result = ByteBuffer::create_zeroed(file_size.value());
if (!buffer_result.has_value()) {
GUI::MessageBox::show(window(), "Entered file size is too large.", "Error", GUI::MessageBox::Type::Error);
return;
}
m_editor->set_buffer(buffer_result.release_value());
set_path({});
update_title();
} else {

View file

@ -242,8 +242,7 @@ void ViewWidget::load_from_file(const String& path)
// Spawn a new ImageDecoder service process and connect to it.
auto client = ImageDecoderClient::Client::construct();
// FIXME: Find a way to avoid the memory copying here.
auto decoded_image_or_error = client->decode_image(ByteBuffer::copy(mapped_file.bytes()));
auto decoded_image_or_error = client->decode_image(mapped_file.bytes());
if (!decoded_image_or_error.has_value()) {
show_error();
return;

View file

@ -56,7 +56,7 @@ void Image::paint_into(GUI::Painter& painter, Gfx::IntRect const& dest_rect) con
}
}
RefPtr<Gfx::Bitmap> Image::try_decode_bitmap(ByteBuffer const& bitmap_data)
RefPtr<Gfx::Bitmap> Image::try_decode_bitmap(ReadonlyBytes const& bitmap_data)
{
// Spawn a new ImageDecoder service process and connect to it.
auto client = ImageDecoderClient::Client::construct();

View file

@ -50,7 +50,7 @@ public:
static Result<NonnullRefPtr<Image>, String> try_create_from_pixel_paint_json(JsonObject const&);
static RefPtr<Image> try_create_from_bitmap(NonnullRefPtr<Gfx::Bitmap>);
static RefPtr<Gfx::Bitmap> try_decode_bitmap(const ByteBuffer& bitmap_data);
static RefPtr<Gfx::Bitmap> try_decode_bitmap(const ReadonlyBytes& bitmap_data);
// This generates a new Bitmap with the final image (all layers composed according to their attributes.)
RefPtr<Gfx::Bitmap> try_compose_bitmap(Gfx::BitmapFormat format) const;

View file

@ -35,7 +35,7 @@ Result<void, String> ProjectLoader::try_load_from_fd_and_close(int fd, StringVie
auto& mapped_file = *file_or_error.value();
// FIXME: Find a way to avoid the memory copy here.
auto bitmap = Image::try_decode_bitmap(ByteBuffer::copy(mapped_file.bytes()));
auto bitmap = Image::try_decode_bitmap(mapped_file.bytes());
if (!bitmap)
return String { "Unable to decode image"sv };
auto image = Image::try_create_from_bitmap(bitmap.release_nonnull());

View file

@ -35,7 +35,7 @@ CSVExportDialogPage::CSVExportDialogPage(const Sheet& sheet)
m_headers.extend(m_data.take_first());
auto temp_template = String::formatted("{}/spreadsheet-csv-export.{}.XXXXXX", Core::StandardPaths::tempfile_directory(), getpid());
auto temp_path = ByteBuffer::create_uninitialized(temp_template.length() + 1);
auto temp_path = ByteBuffer::create_uninitialized(temp_template.length() + 1).release_value();
auto buf = reinterpret_cast<char*>(temp_path.data());
auto copy_ok = temp_template.copy_characters_to_buffer(buf, temp_path.size());
VERIFY(copy_ok);

View file

@ -85,7 +85,7 @@ BENCHMARK_CASE(fairly_big_data)
{
constexpr auto num_rows = 100000u;
constexpr auto line = "well,hello,friends,1,2,3,4,5,6,7,8,pizza,guacamole\n"sv;
auto buf = ByteBuffer::create_uninitialized((line.length() * num_rows) + 1);
auto buf = ByteBuffer::create_uninitialized((line.length() * num_rows) + 1).release_value();
buf[buf.size() - 1] = '\0';
for (size_t row = 0; row <= num_rows; ++row) {

View file

@ -18,7 +18,7 @@ TEST_CASE(can_write)
{ 7, 8, 9 },
};
auto buffer = ByteBuffer::create_uninitialized(1024);
auto buffer = ByteBuffer::create_uninitialized(1024).release_value();
OutputMemoryStream stream { buffer };
Writer::CSV csv(stream, data);
@ -39,7 +39,7 @@ TEST_CASE(can_write_with_header)
{ 7, 8, 9 },
};
auto buffer = ByteBuffer::create_uninitialized(1024);
auto buffer = ByteBuffer::create_uninitialized(1024).release_value();
OutputMemoryStream stream { buffer };
Writer::CSV csv(stream, data, { "A", "B\"", "C" });
@ -60,7 +60,7 @@ TEST_CASE(can_write_with_different_behaviours)
{ "We\"ll", "Hello,", " Friends" },
};
auto buffer = ByteBuffer::create_uninitialized(1024);
auto buffer = ByteBuffer::create_uninitialized(1024).release_value();
OutputMemoryStream stream { buffer };
Writer::CSV csv(stream, data, { "A", "B\"", "C" }, Writer::WriterBehaviour::QuoteOnlyInFieldStart | Writer::WriterBehaviour::WriteHeaders);

View file

@ -413,7 +413,10 @@ int Emulator::virt$setsockopt(FlatPtr params_addr)
mmu().copy_from_vm(&params, params_addr, sizeof(params));
if (params.option == SO_RCVTIMEO || params.option == SO_TIMESTAMP) {
auto host_value_buffer = ByteBuffer::create_zeroed(params.value_size);
auto host_value_buffer_result = ByteBuffer::create_zeroed(params.value_size);
if (!host_value_buffer_result.has_value())
return -ENOMEM;
auto& host_value_buffer = host_value_buffer_result.value();
mmu().copy_from_vm(host_value_buffer.data(), (FlatPtr)params.value, params.value_size);
int rc = setsockopt(params.sockfd, params.level, params.option, host_value_buffer.data(), host_value_buffer.size());
if (rc < 0)
@ -542,7 +545,10 @@ int Emulator::virt$get_process_name(FlatPtr buffer, int size)
{
if (size < 0)
return -EINVAL;
auto host_buffer = ByteBuffer::create_zeroed((size_t)size);
auto host_buffer_result = ByteBuffer::create_zeroed((size_t)size);
if (!host_buffer_result.has_value())
return -ENOMEM;
auto& host_buffer = host_buffer_result.value();
int rc = syscall(SC_get_process_name, host_buffer.data(), host_buffer.size());
mmu().copy_to_vm(buffer, host_buffer.data(), host_buffer.size());
return rc;
@ -582,13 +588,20 @@ int Emulator::virt$recvmsg(int sockfd, FlatPtr msg_addr, int flags)
Vector<ByteBuffer, 1> buffers;
Vector<iovec, 1> iovs;
for (const auto& iov : mmu_iovs) {
buffers.append(ByteBuffer::create_uninitialized(iov.iov_len));
auto buffer_result = ByteBuffer::create_uninitialized(iov.iov_len);
if (!buffer_result.has_value())
return -ENOMEM;
buffers.append(buffer_result.release_value());
iovs.append({ buffers.last().data(), buffers.last().size() });
}
ByteBuffer control_buffer;
if (mmu_msg.msg_control)
control_buffer = ByteBuffer::create_uninitialized(mmu_msg.msg_controllen);
if (mmu_msg.msg_control) {
auto buffer_result = ByteBuffer::create_uninitialized(mmu_msg.msg_controllen);
if (!buffer_result.has_value())
return -ENOMEM;
control_buffer = buffer_result.release_value();
}
sockaddr_storage addr;
msghdr msg = { &addr, sizeof(addr), iovs.data(), (int)iovs.size(), mmu_msg.msg_control ? control_buffer.data() : nullptr, mmu_msg.msg_controllen, mmu_msg.msg_flags };
@ -625,8 +638,12 @@ int Emulator::virt$sendmsg(int sockfd, FlatPtr msg_addr, int flags)
}
ByteBuffer control_buffer;
if (mmu_msg.msg_control)
control_buffer = ByteBuffer::create_uninitialized(mmu_msg.msg_controllen);
if (mmu_msg.msg_control) {
auto buffer_result = ByteBuffer::create_uninitialized(mmu_msg.msg_controllen);
if (!buffer_result.has_value())
return -ENOMEM;
control_buffer = buffer_result.release_value();
}
sockaddr_storage address;
socklen_t address_length = 0;
@ -733,7 +750,10 @@ int Emulator::virt$getgroups(ssize_t count, FlatPtr groups)
if (!count)
return syscall(SC_getgroups, 0, nullptr);
auto buffer = ByteBuffer::create_uninitialized(count * sizeof(gid_t));
auto buffer_result = ByteBuffer::create_uninitialized(count * sizeof(gid_t));
if (!buffer_result.has_value())
return -ENOMEM;
auto& buffer = buffer_result.value();
int rc = syscall(SC_getgroups, count, buffer.data());
if (rc < 0)
return rc;
@ -858,7 +878,10 @@ u32 Emulator::virt$mmap(u32 params_addr)
String name_str;
if (params.name.characters) {
auto name = ByteBuffer::create_uninitialized(params.name.length);
auto buffer_result = ByteBuffer::create_uninitialized(params.name.length);
if (!buffer_result.has_value())
return -ENOMEM;
auto& name = buffer_result.value();
mmu().copy_from_vm(name.data(), (FlatPtr)params.name.characters, params.name.length);
name_str = { name.data(), name.size() };
}
@ -1002,7 +1025,10 @@ u32 Emulator::virt$read(int fd, FlatPtr buffer, ssize_t size)
{
if (size < 0)
return -EINVAL;
auto local_buffer = ByteBuffer::create_uninitialized(size);
auto buffer_result = ByteBuffer::create_uninitialized(size);
if (!buffer_result.has_value())
return -ENOMEM;
auto& local_buffer = buffer_result.value();
int nread = syscall(SC_read, fd, local_buffer.data(), local_buffer.size());
if (nread < 0) {
if (nread == -EPERM) {
@ -1029,7 +1055,10 @@ void Emulator::virt$exit(int status)
ssize_t Emulator::virt$getrandom(FlatPtr buffer, size_t buffer_size, unsigned int flags)
{
auto host_buffer = ByteBuffer::create_uninitialized(buffer_size);
auto buffer_result = ByteBuffer::create_uninitialized(buffer_size);
if (!buffer_result.has_value())
return -ENOMEM;
auto& host_buffer = buffer_result.value();
int rc = syscall(SC_getrandom, host_buffer.data(), host_buffer.size(), flags);
if (rc < 0)
return rc;
@ -1039,7 +1068,10 @@ ssize_t Emulator::virt$getrandom(FlatPtr buffer, size_t buffer_size, unsigned in
int Emulator::virt$get_dir_entries(int fd, FlatPtr buffer, ssize_t size)
{
auto host_buffer = ByteBuffer::create_uninitialized(size);
auto buffer_result = ByteBuffer::create_uninitialized(size);
if (!buffer_result.has_value())
return -ENOMEM;
auto& host_buffer = buffer_result.value();
int rc = syscall(SC_get_dir_entries, fd, host_buffer.data(), host_buffer.size());
if (rc < 0)
return rc;
@ -1215,7 +1247,10 @@ int Emulator::virt$realpath(FlatPtr params_addr)
mmu().copy_from_vm(&params, params_addr, sizeof(params));
auto path = mmu().copy_buffer_from_vm((FlatPtr)params.path.characters, params.path.length);
auto host_buffer = ByteBuffer::create_zeroed(params.buffer.size);
auto buffer_result = ByteBuffer::create_zeroed(params.buffer.size);
if (!buffer_result.has_value())
return -ENOMEM;
auto& host_buffer = buffer_result.value();
Syscall::SC_realpath_params host_params;
host_params.path = { (const char*)path.data(), path.size() };
@ -1231,7 +1266,10 @@ int Emulator::virt$gethostname(FlatPtr buffer, ssize_t buffer_size)
{
if (buffer_size < 0)
return -EINVAL;
auto host_buffer = ByteBuffer::create_zeroed(buffer_size);
auto buffer_result = ByteBuffer::create_zeroed(buffer_size);
if (!buffer_result.has_value())
return -ENOMEM;
auto& host_buffer = buffer_result.value();
int rc = syscall(SC_gethostname, host_buffer.data(), host_buffer.size());
if (rc < 0)
return rc;
@ -1316,7 +1354,10 @@ int Emulator::virt$setpgid(pid_t pid, pid_t pgid)
int Emulator::virt$ttyname(int fd, FlatPtr buffer, size_t buffer_size)
{
auto host_buffer = ByteBuffer::create_zeroed(buffer_size);
auto buffer_result = ByteBuffer::create_zeroed(buffer_size);
if (!buffer_result.has_value())
return -ENOMEM;
auto& host_buffer = buffer_result.value();
int rc = syscall(SC_ttyname, fd, host_buffer.data(), host_buffer.size());
if (rc < 0)
return rc;
@ -1326,7 +1367,10 @@ int Emulator::virt$ttyname(int fd, FlatPtr buffer, size_t buffer_size)
int Emulator::virt$getcwd(FlatPtr buffer, size_t buffer_size)
{
auto host_buffer = ByteBuffer::create_zeroed(buffer_size);
auto buffer_result = ByteBuffer::create_zeroed(buffer_size);
if (!buffer_result.has_value())
return -ENOMEM;
auto& host_buffer = buffer_result.value();
int rc = syscall(SC_getcwd, host_buffer.data(), host_buffer.size());
if (rc < 0)
return rc;
@ -1436,12 +1480,12 @@ int Emulator::virt$clock_nanosleep(FlatPtr params_addr)
params.requested_sleep = &requested_sleep;
auto remaining_vm_addr = params.remaining_sleep;
auto remaining = ByteBuffer::create_zeroed(sizeof(timespec));
params.remaining_sleep = (timespec*)remaining.data();
timespec remaining { 0, 0 };
params.remaining_sleep = &remaining;
int rc = syscall(SC_clock_nanosleep, &params);
if (remaining_vm_addr)
mmu().copy_to_vm((FlatPtr)remaining_vm_addr, remaining.data(), sizeof(timespec));
mmu().copy_to_vm((FlatPtr)remaining_vm_addr, &remaining, sizeof(timespec));
return rc;
}
@ -1452,7 +1496,10 @@ int Emulator::virt$readlink(FlatPtr params_addr)
mmu().copy_from_vm(&params, params_addr, sizeof(params));
auto path = mmu().copy_buffer_from_vm((FlatPtr)params.path.characters, params.path.length);
auto host_buffer = ByteBuffer::create_zeroed(params.buffer.size);
auto buffer_result = ByteBuffer::create_zeroed(params.buffer.size);
if (!buffer_result.has_value())
return -ENOMEM;
auto& host_buffer = buffer_result.value();
Syscall::SC_readlink_params host_params;
host_params.path = { (const char*)path.data(), path.size() };

View file

@ -321,7 +321,7 @@ void SoftMMU::copy_from_vm(void* destination, const FlatPtr source, size_t size)
ByteBuffer SoftMMU::copy_buffer_from_vm(const FlatPtr source, size_t size)
{
auto buffer = ByteBuffer::create_uninitialized(size);
auto buffer = ByteBuffer::create_uninitialized(size).release_value(); // FIXME: Handle possible OOM situation.
copy_from_vm(buffer.data(), source, size);
return buffer;
}

View file

@ -134,11 +134,11 @@ bool FlacLoaderPlugin::parse_header()
ok = ok && (m_total_samples > 0);
CHECK_OK("Number of samples");
// Parse checksum into a buffer first
ByteBuffer md5_checksum = ByteBuffer::create_uninitialized(128 / 8);
Array<u8, 128 / 8> md5_checksum;
auto md5_bytes_read = streaminfo_data.read(md5_checksum);
ok = ok && (md5_bytes_read == md5_checksum.size());
CHECK_OK("MD5 Checksum");
md5_checksum.bytes().copy_to({ m_md5_checksum, sizeof(m_md5_checksum) });
md5_checksum.span().copy_to({ m_md5_checksum, sizeof(m_md5_checksum) });
// Parse other blocks
// TODO: For a simple first implementation, all other blocks are skipped as allowed by the FLAC specification.
@ -195,7 +195,12 @@ FlacRawMetadataBlock FlacLoaderPlugin::next_meta_block(InputBitStream& bit_input
u32 block_length = bit_input.read_bits_big_endian(24);
m_data_start_location += 3;
CHECK_IO_ERROR();
ByteBuffer block_data = ByteBuffer::create_uninitialized(block_length);
auto block_data_result = ByteBuffer::create_uninitialized(block_length);
if (!block_data_result.has_value()) {
m_error_string = "Out of memory";
return FlacRawMetadataBlock {};
}
auto block_data = block_data_result.release_value();
// Reads exactly the bytes necessary into the Bytes container
bit_input.read(block_data);
m_data_start_location += block_length;
@ -808,9 +813,10 @@ ALWAYS_INLINE i32 decode_unsigned_exp_golomb(u8 k, InputBitStream& bit_input)
u64 read_utf8_char(InputStream& input)
{
u64 character;
ByteBuffer single_byte_buffer = ByteBuffer::create_uninitialized(1);
input.read(single_byte_buffer);
u8 start_byte = single_byte_buffer[0];
u8 buffer = 0;
Bytes buffer_bytes { &buffer, 1 };
input.read(buffer_bytes);
u8 start_byte = buffer_bytes[0];
// Signal byte is zero: ASCII character
if ((start_byte & 0b10000000) == 0) {
return start_byte;
@ -826,8 +832,8 @@ u64 read_utf8_char(InputStream& input)
u8 start_byte_bitmask = AK::exp2(bits_from_start_byte) - 1;
character = start_byte_bitmask & start_byte;
for (u8 i = length - 1; i > 0; --i) {
input.read(single_byte_buffer);
u8 current_byte = single_byte_buffer[0];
input.read(buffer_bytes);
u8 current_byte = buffer_bytes[0];
character = (character << 6) | (current_byte & 0b00111111);
}
return character;

View file

@ -69,7 +69,10 @@ RefPtr<Buffer> WavLoaderPlugin::get_more_samples(size_t max_bytes_to_read_from_i
bytes_to_read, m_num_channels, m_sample_rate,
pcm_bits_per_sample(m_sample_format), sample_format_name(m_sample_format));
ByteBuffer sample_data = ByteBuffer::create_zeroed(bytes_to_read);
auto sample_data_result = ByteBuffer::create_zeroed(bytes_to_read);
if (!sample_data_result.has_value())
return nullptr;
auto sample_data = sample_data_result.release_value();
m_stream->read_or_error(sample_data.bytes());
if (m_stream->handle_any_error()) {
return nullptr;

View file

@ -43,7 +43,12 @@ ByteBuffer IODevice::read(size_t max_size)
return {};
if (!max_size)
return {};
auto buffer = ByteBuffer::create_uninitialized(max_size);
auto buffer_result = ByteBuffer::create_uninitialized(max_size);
if (!buffer_result.has_value()) {
dbgln("IODevice::read: Not enough memory to allocate a buffer of {} bytes", max_size);
return {};
}
auto buffer = buffer_result.release_value();
auto* buffer_ptr = (char*)buffer.data();
size_t remaining_buffer_space = buffer.size();
size_t taken_from_buffered = 0;
@ -166,7 +171,13 @@ ByteBuffer IODevice::read_all()
}
data.append((const u8*)read_buffer, nread);
}
return ByteBuffer::copy(data.data(), data.size());
auto result = ByteBuffer::copy(data);
if (result.has_value())
return result.release_value();
set_error(ENOMEM);
return {};
}
String IODevice::read_line(size_t max_size)
@ -186,7 +197,12 @@ String IODevice::read_line(size_t max_size)
m_buffered_data.clear();
return line;
}
auto line = ByteBuffer::create_uninitialized(max_size + 1);
auto line_result = ByteBuffer::create_uninitialized(max_size + 1);
if (!line_result.has_value()) {
dbgln("IODevice::read_line: Not enough memory to allocate a buffer of {} bytes", max_size + 1);
return {};
}
auto line = line_result.release_value();
size_t line_index = 0;
while (line_index < max_size) {
u8 ch = m_buffered_data[line_index];

View file

@ -63,7 +63,8 @@ bool UDPServer::bind(const IPv4Address& address, u16 port)
ByteBuffer UDPServer::receive(size_t size, sockaddr_in& in)
{
auto buf = ByteBuffer::create_uninitialized(size);
// FIXME: Handle possible OOM situation.
auto buf = ByteBuffer::create_uninitialized(size).release_value();
socklen_t in_len = sizeof(in);
ssize_t rlen = ::recvfrom(m_fd, buf.data(), size, 0, (sockaddr*)&in, &in_len);
if (rlen < 0) {

View file

@ -18,11 +18,14 @@ OwnPtr<Reader> Reader::create(const String& path)
auto file_or_error = MappedFile::map(path);
if (file_or_error.is_error())
return {};
return adopt_own(*new Reader(file_or_error.value()->bytes()));
auto decompressed_data = decompress_coredump(file_or_error.value()->bytes());
if (!decompressed_data.has_value())
return {};
return adopt_own_if_nonnull(new (nothrow) Reader(decompressed_data.release_value()));
}
Reader::Reader(ReadonlyBytes coredump_bytes)
: m_coredump_buffer(decompress_coredump(coredump_bytes))
Reader::Reader(ByteBuffer coredump_data)
: m_coredump_buffer(move(coredump_data))
, m_coredump_image(m_coredump_buffer.bytes())
{
size_t index = 0;
@ -37,14 +40,14 @@ Reader::Reader(ReadonlyBytes coredump_bytes)
VERIFY(m_notes_segment_index != -1);
}
ByteBuffer Reader::decompress_coredump(const ReadonlyBytes& raw_coredump)
Optional<ByteBuffer> Reader::decompress_coredump(const ReadonlyBytes& raw_coredump)
{
if (!Compress::GzipDecompressor::is_likely_compressed(raw_coredump))
return ByteBuffer::copy(raw_coredump); // handle old format coredumps (uncompressed)
auto decompressed_coredump = Compress::GzipDecompressor::decompress_all(raw_coredump);
if (!decompressed_coredump.has_value())
return ByteBuffer::copy(raw_coredump); // if we didn't manage to decompress it, try and parse it as decompressed coredump
return decompressed_coredump.value();
return decompressed_coredump;
}
Reader::~Reader()

View file

@ -51,9 +51,9 @@ public:
HashMap<String, String> metadata() const;
private:
Reader(ReadonlyBytes);
Reader(ByteBuffer);
static ByteBuffer decompress_coredump(const ReadonlyBytes&);
static Optional<ByteBuffer> decompress_coredump(const ReadonlyBytes&);
class NotesEntryIterator {
public:

View file

@ -66,8 +66,14 @@ public:
void encrypt(const ReadonlyBytes& in, Bytes out, const ReadonlyBytes& iv_in, const ReadonlyBytes& aad, Bytes tag)
{
auto iv_buf = ByteBuffer::copy(iv_in.data(), iv_in.size());
auto iv = iv_buf.bytes();
auto iv_buf_result = ByteBuffer::copy(iv_in);
// Not enough memory to figure out :shrug:
if (!iv_buf_result.has_value()) {
dbgln("GCM::encrypt: Not enough memory to allocate {} bytes for IV", iv_in.size());
return;
}
auto iv = iv_buf_result->bytes();
// Increment the IV for block 0
CTR<T>::increment(iv);
@ -90,8 +96,12 @@ public:
VerificationConsistency decrypt(ReadonlyBytes in, Bytes out, ReadonlyBytes iv_in, ReadonlyBytes aad, ReadonlyBytes tag)
{
auto iv_buf = ByteBuffer::copy(iv_in.data(), iv_in.size());
auto iv = iv_buf.bytes();
auto iv_buf_result = ByteBuffer::copy(iv_in);
// Not enough memory to figure out :shrug:
if (!iv_buf_result.has_value())
return VerificationConsistency::Inconsistent;
auto iv = iv_buf_result->bytes();
// Increment the IV for block 0
CTR<T>::increment(iv);

View file

@ -26,7 +26,7 @@ public:
const T& cipher() const { return m_cipher; }
ByteBuffer create_aligned_buffer(size_t input_size) const
Optional<ByteBuffer> create_aligned_buffer(size_t input_size) const
{
size_t remainder = (input_size + T::block_size()) % T::block_size();
if (remainder == 0)

View file

@ -83,18 +83,18 @@ public:
Manager()
{
m_pre_init_buffer = ByteBuffer::create_zeroed(0);
m_pre_init_buffer = ByteBuffer();
}
Manager(const Manager& other) // NOT a copy constructor!
{
m_pre_init_buffer = ByteBuffer::create_zeroed(0); // will not be used
m_pre_init_buffer = ByteBuffer(); // will not be used
initialize(other.m_kind);
}
Manager(HashKind kind)
{
m_pre_init_buffer = ByteBuffer::create_zeroed(0);
m_pre_init_buffer = ByteBuffer();
initialize(kind);
}

View file

@ -165,7 +165,7 @@ UnsignedBigInteger random_number(const UnsignedBigInteger& min, const UnsignedBi
UnsignedBigInteger base;
auto size = range.trimmed_length() * sizeof(u32) + 2;
// "+2" is intentional (see below).
auto buffer = ByteBuffer::create_uninitialized(size);
auto buffer = ByteBuffer::create_uninitialized(size).release_value(); // FIXME: Handle possible OOM situation.
auto* buf = buffer.data();
fill_with_random(buf, size);

View file

@ -147,7 +147,7 @@ public:
void MGF1(ReadonlyBytes seed, size_t length, Bytes out)
{
auto& hash_fn = this->hasher();
ByteBuffer T = ByteBuffer::create_zeroed(0);
ByteBuffer T;
for (size_t counter = 0; counter < length / HashFunction::DigestSize - 1; ++counter) {
hash_fn.update(seed);
hash_fn.update((u8*)&counter, 4);

View file

@ -198,7 +198,12 @@ RSA::KeyPairType RSA::parse_rsa_key(ReadonlyBytes der)
// Now just read it as a PKCS#1 DER.
auto data = data_result.release_value();
// FIXME: This is pretty awkward, maybe just generate a zero'd out ByteBuffer from the parser instead?
auto padded_data = ByteBuffer::create_zeroed(data.size_in_bytes());
auto padded_data_result = ByteBuffer::create_zeroed(data.size_in_bytes());
if (!padded_data_result.has_value()) {
dbgln_if(RSA_PARSE_DEBUG, "RSA PKCS#1 key parse failed: Not enough memory");
return keypair;
}
auto padded_data = padded_data_result.release_value();
padded_data.overwrite(0, data.data(), data.size_in_bytes());
return parse_rsa_key(padded_data.bytes());

View file

@ -169,7 +169,13 @@ static void allocate_tls()
return;
auto page_aligned_size = align_up_to(s_total_tls_size, PAGE_SIZE);
ByteBuffer initial_tls_data = ByteBuffer::create_zeroed(page_aligned_size);
auto initial_tls_data_result = ByteBuffer::create_zeroed(page_aligned_size);
if (!initial_tls_data_result.has_value()) {
dbgln("Failed to allocate initial TLS data");
VERIFY_NOT_REACHED();
}
auto& initial_tls_data = initial_tls_data_result.value();
// Initialize TLS data
for (const auto& entry : s_loaders) {

View file

@ -56,9 +56,12 @@ Clipboard::DataAndType Clipboard::data_and_type() const
if (!response.data().is_valid())
return {};
auto data = ByteBuffer::copy(response.data().data<void>(), response.data().size());
if (!data.has_value())
return {};
auto type = response.mime_type();
auto metadata = response.metadata().entries();
return { data, type, metadata };
return { data.release_value(), type, metadata };
}
RefPtr<Gfx::Bitmap> Clipboard::bitmap() const

View file

@ -946,7 +946,12 @@ static bool uncompress_bmp_rle_data(BMPLoadingContext& context, ByteBuffer& buff
dbgln("Suspiciously large amount of RLE data");
return false;
}
buffer = ByteBuffer::create_zeroed(buffer_size);
auto buffer_result = ByteBuffer::create_zeroed(buffer_size);
if (!buffer_result.has_value()) {
dbgln("Not enough memory for buffer allocation");
return false;
}
buffer = buffer_result.release_value();
// Avoid as many if statements as possible by pulling out
// compression-dependent actions into separate lambdas

View file

@ -45,7 +45,11 @@ private:
static ByteBuffer write_pixel_data(const RefPtr<Bitmap> bitmap, int pixel_row_data_size, int bytes_per_pixel, bool include_alpha_channel)
{
int image_size = pixel_row_data_size * bitmap->height();
auto buffer = ByteBuffer::create_uninitialized(image_size);
auto buffer_result = ByteBuffer::create_uninitialized(image_size);
if (!buffer_result.has_value())
return {};
auto buffer = buffer_result.release_value();
int current_row = 0;
for (int y = bitmap->physical_height() - 1; y >= 0; --y) {
@ -95,7 +99,11 @@ ByteBuffer BMPWriter::dump(const RefPtr<Bitmap> bitmap, DibHeader dib_header)
int pixel_row_data_size = (m_bytes_per_pixel * 8 * bitmap->width() + 31) / 32 * 4;
int image_size = pixel_row_data_size * bitmap->height();
auto buffer = ByteBuffer::create_uninitialized(pixel_data_offset);
auto buffer_result = ByteBuffer::create_uninitialized(pixel_data_offset);
if (!buffer_result.has_value())
return {};
auto buffer = buffer_result.release_value();
auto pixel_data = write_pixel_data(bitmap, pixel_row_data_size, m_bytes_per_pixel, m_include_alpha_channel);
pixel_data = compress_pixel_data(pixel_data, m_compression);

View file

@ -247,7 +247,8 @@ RefPtr<Bitmap> Bitmap::try_create_from_serialized_byte_buffer(ByteBuffer&& buffe
ByteBuffer Bitmap::serialize_to_byte_buffer() const
{
auto buffer = ByteBuffer::create_uninitialized(sizeof(size_t) + 4 * sizeof(unsigned) + sizeof(BitmapFormat) + sizeof(RGBA32) * palette_size(m_format) + size_in_bytes());
// FIXME: Somehow handle possible OOM situation here.
auto buffer = ByteBuffer::create_uninitialized(sizeof(size_t) + 4 * sizeof(unsigned) + sizeof(BitmapFormat) + sizeof(RGBA32) * palette_size(m_format) + size_in_bytes()).release_value();
OutputMemoryStream stream { buffer };
auto write = [&]<typename T>(T value) {

View file

@ -221,7 +221,8 @@ ByteBuffer PNGWriter::encode(Gfx::Bitmap const& bitmap)
writer.add_IHDR_chunk(bitmap.width(), bitmap.height(), 8, 6, 0, 0, 0);
writer.add_IDAT_chunk(bitmap);
writer.add_IEND_chunk();
return ByteBuffer::copy(writer.m_data);
// FIXME: Handle OOM failure.
return ByteBuffer::copy(writer.m_data).release_value();
}
}

View file

@ -47,7 +47,6 @@ public:
void set_method(Method method) { m_method = method; }
ByteBuffer const& body() const { return m_body; }
void set_body(ReadonlyBytes body) { m_body = ByteBuffer::copy(body); }
void set_body(ByteBuffer&& body) { m_body = move(body); }
String method_name() const;

View file

@ -136,17 +136,17 @@ void Job::on_socket_connected()
return;
auto line = read_line(PAGE_SIZE);
if (line.is_null()) {
warnln("Job: Expected HTTP status");
dbgln("Job: Expected HTTP status");
return deferred_invoke([this] { did_fail(Core::NetworkJob::Error::TransmissionFailed); });
}
auto parts = line.split_view(' ');
if (parts.size() < 3) {
warnln("Job: Expected 3-part HTTP status, got '{}'", line);
dbgln("Job: Expected 3-part HTTP status, got '{}'", line);
return deferred_invoke([this] { did_fail(Core::NetworkJob::Error::ProtocolFailed); });
}
auto code = parts[1].to_uint();
if (!code.has_value()) {
warnln("Job: Expected numeric HTTP status");
dbgln("Job: Expected numeric HTTP status");
return deferred_invoke([this] { did_fail(Core::NetworkJob::Error::ProtocolFailed); });
}
m_code = code.value();
@ -164,7 +164,7 @@ void Job::on_socket_connected()
// that is not a valid trailing header.
return finish_up();
}
warnln("Job: Expected HTTP header");
dbgln("Job: Expected HTTP header");
return did_fail(Core::NetworkJob::Error::ProtocolFailed);
}
if (line.is_empty()) {
@ -185,7 +185,7 @@ void Job::on_socket_connected()
// that is not a valid trailing header.
return finish_up();
}
warnln("Job: Expected HTTP header with key/value");
dbgln("Job: Expected HTTP header with key/value");
return deferred_invoke([this] { did_fail(Core::NetworkJob::Error::ProtocolFailed); });
}
auto name = parts[0];
@ -196,7 +196,7 @@ void Job::on_socket_connected()
// that is not a valid trailing header.
return finish_up();
}
warnln("Job: Malformed HTTP header: '{}' ({})", line, line.length());
dbgln("Job: Malformed HTTP header: '{}' ({})", line, line.length());
return deferred_invoke([this] { did_fail(Core::NetworkJob::Error::ProtocolFailed); });
}
auto value = line.substring(name.length() + 2, line.length() - name.length() - 2);
@ -363,7 +363,7 @@ void Job::finish_up()
VERIFY(!m_has_scheduled_finish);
m_state = State::Finished;
if (!m_can_stream_response) {
auto flattened_buffer = ByteBuffer::create_uninitialized(m_received_size);
auto flattened_buffer = ByteBuffer::create_uninitialized(m_received_size).release_value(); // FIXME: Handle possible OOM situation.
u8* flat_ptr = flattened_buffer.data();
for (auto& received_buffer : m_received_buffers) {
memcpy(flat_ptr, received_buffer.data(), received_buffer.size());

View file

@ -231,13 +231,17 @@ protected:
// Sometimes we might receive a partial message. That's okay, just stash away
// the unprocessed bytes and we'll prepend them to the next incoming message
// in the next run of this function.
auto remaining_bytes = ByteBuffer::copy(bytes.data() + index, bytes.size() - index);
auto remaining_bytes_result = ByteBuffer::copy(bytes.span().slice(index));
if (!remaining_bytes_result.has_value()) {
dbgln("{}::drain_messages_from_peer: Failed to allocate buffer", *this);
return false;
}
if (!m_unprocessed_bytes.is_empty()) {
dbgln("{}::drain_messages_from_peer: Already have unprocessed bytes", *this);
shutdown();
return false;
}
m_unprocessed_bytes = remaining_bytes;
m_unprocessed_bytes = remaining_bytes_result.release_value();
}
if (!m_unprocessed_messages.is_empty()) {

View file

@ -110,10 +110,14 @@ bool Decoder::decode(ByteBuffer& value)
return true;
}
if (length == 0) {
value = ByteBuffer::create_uninitialized(0);
value = {};
return true;
}
value = ByteBuffer::create_uninitialized(length);
if (auto buffer_result = ByteBuffer::create_uninitialized(length); buffer_result.has_value())
value = buffer_result.release_value();
else
return false;
m_stream >> value.bytes();
return !m_stream.handle_any_error();
}

View file

@ -20,7 +20,7 @@ void Client::die()
on_death();
}
Optional<DecodedImage> Client::decode_image(const ByteBuffer& encoded_data)
Optional<DecodedImage> Client::decode_image(const ReadonlyBytes& encoded_data)
{
if (encoded_data.is_empty())
return {};

View file

@ -30,7 +30,7 @@ class Client final
C_OBJECT(Client);
public:
Optional<DecodedImage> decode_image(const ByteBuffer&);
Optional<DecodedImage> decode_image(const ReadonlyBytes&);
Function<void()> on_death;

View file

@ -2106,6 +2106,8 @@ Value ArrayExpression::execute(Interpreter& interpreter, GlobalObject& global_ob
InterpreterNodeScope node_scope { interpreter, *this };
auto* array = Array::create(global_object, 0);
array->indexed_properties();
size_t index = 0;
for (auto& element : m_elements) {
auto value = Value();
if (element) {
@ -2115,7 +2117,7 @@ Value ArrayExpression::execute(Interpreter& interpreter, GlobalObject& global_ob
if (is<SpreadExpression>(*element)) {
get_iterator_values(global_object, value, [&](Value iterator_value) {
array->indexed_properties().append(iterator_value);
array->indexed_properties().put(index++, iterator_value, default_attributes);
return IterationDecision::Continue;
});
if (interpreter.exception())
@ -2123,7 +2125,7 @@ Value ArrayExpression::execute(Interpreter& interpreter, GlobalObject& global_ob
continue;
}
}
array->indexed_properties().append(value);
array->indexed_properties().put(index++, value, default_attributes);
}
return array;
}

View file

@ -21,7 +21,7 @@ ArrayBuffer* ArrayBuffer::create(GlobalObject& global_object, ByteBuffer* buffer
ArrayBuffer::ArrayBuffer(size_t byte_size, Object& prototype)
: Object(prototype)
, m_buffer(ByteBuffer::create_zeroed(byte_size))
, m_buffer(ByteBuffer::create_zeroed(byte_size).release_value()) // FIXME: Handle this possible OOM failure.
, m_detach_key(js_undefined())
{
}

View file

@ -125,7 +125,7 @@ template<typename T>
static ByteBuffer numeric_to_raw_bytes(GlobalObject& global_object, Value value, bool is_little_endian)
{
using UnderlyingBufferDataType = Conditional<IsSame<ClampedU8, T>, u8, T>;
ByteBuffer raw_bytes = ByteBuffer::create_uninitialized(sizeof(UnderlyingBufferDataType));
ByteBuffer raw_bytes = ByteBuffer::create_uninitialized(sizeof(UnderlyingBufferDataType)).release_value(); // FIXME: Handle possible OOM situation.
auto flip_if_needed = [&]() {
if (is_little_endian)
return;

View file

@ -185,7 +185,7 @@ Editor::Editor(Configuration configuration)
: m_configuration(move(configuration))
{
m_always_refresh = m_configuration.refresh_behaviour == Configuration::RefreshBehaviour::Eager;
m_pending_chars = ByteBuffer::create_uninitialized(0);
m_pending_chars = {};
get_terminal_size();
m_suggestion_display = make<XtermSuggestionDisplay>(m_num_lines, m_num_columns);
}

View file

@ -44,7 +44,11 @@ Optional<ByteBuffer> Filter::decode_ascii_hex(ReadonlyBytes const& bytes)
// FIXME: Integrate this padding into AK/Hex?
auto output = ByteBuffer::create_zeroed(bytes.size() / 2 + 1);
auto output_result = ByteBuffer::create_zeroed(bytes.size() / 2 + 1);
if (!output_result.has_value())
return output_result;
auto output = output_result.release_value();
for (size_t i = 0; i < bytes.size() / 2; ++i) {
const auto c1 = decode_hex_digit(static_cast<char>(bytes[i * 2]));
@ -61,7 +65,7 @@ Optional<ByteBuffer> Filter::decode_ascii_hex(ReadonlyBytes const& bytes)
// Process last byte with a padded zero
output[output.size() - 1] = decode_hex_digit(static_cast<char>(bytes[bytes.size() - 1])) * 16;
return output;
return { move(output) };
};
Optional<ByteBuffer> Filter::decode_ascii85(ReadonlyBytes const& bytes)

View file

@ -262,7 +262,10 @@ bool Parser::initialize_hint_tables()
auto overflow_size = overflow_hint_stream->bytes().size();
auto total_size = primary_size + overflow_size;
possible_merged_stream_buffer = ByteBuffer::create_uninitialized(total_size);
auto buffer_result = ByteBuffer::create_uninitialized(total_size);
if (!buffer_result.has_value())
return false;
possible_merged_stream_buffer = buffer_result.release_value();
auto ok = possible_merged_stream_buffer.try_append(primary_hint_stream->bytes());
ok = ok && possible_merged_stream_buffer.try_append(overflow_hint_stream->bytes());
if (!ok)

View file

@ -22,7 +22,11 @@ RefPtr<Request> RequestClient::start_request(String const& method, URL const& ur
for (auto& it : request_headers)
header_dictionary.add(it.key, it.value);
auto response = IPCProxy::start_request(method, url, header_dictionary, ByteBuffer::copy(request_body));
auto body_result = ByteBuffer::copy(request_body);
if (!body_result.has_value())
return nullptr;
auto response = IPCProxy::start_request(method, url, header_dictionary, body_result.release_value());
auto request_id = response.request_id();
if (request_id < 0 || !response.response_fd().has_value())
return nullptr;

View file

@ -27,7 +27,9 @@ void WebSocket::send(ByteBuffer binary_or_text_message, bool is_text)
void WebSocket::send(StringView text_message)
{
send(ByteBuffer::copy(text_message.bytes()), true);
auto data_result = ByteBuffer::copy(text_message.bytes());
VERIFY(data_result.has_value());
send(data_result.release_value(), true);
}
void WebSocket::close(u16 code, String reason)

View file

@ -203,7 +203,8 @@ void Heap::update_zero_block()
}
}
auto buffer = ByteBuffer::create_zeroed(BLOCKSIZE);
// FIXME: Handle an OOM failure here.
auto buffer = ByteBuffer::create_zeroed(BLOCKSIZE).release_value();
buffer.overwrite(0, FILE_ID, strlen(FILE_ID));
buffer.overwrite(VERSION_OFFSET, &m_version, sizeof(u32));
buffer.overwrite(SCHEMAS_ROOT_OFFSET, &m_schemas_root, sizeof(u32));

View file

@ -151,7 +151,7 @@ ByteBuffer TLSv12::build_handshake_finished()
u8 out[verify_data_length];
auto outbuffer = Bytes { out, verify_data_length };
auto dummy = ByteBuffer::create_zeroed(0);
ByteBuffer dummy;
auto digest = m_context.handshake_hash.digest();
auto hashbuf = ReadonlyBytes { digest.immutable_data(), m_context.handshake_hash.digest_size() };

View file

@ -192,7 +192,12 @@ void TLSv12::build_rsa_pre_master_secret(PacketBuilder& builder)
*(u16*)random_bytes = AK::convert_between_host_and_network_endian((u16)Version::V12);
}
m_context.premaster_key = ByteBuffer::copy(random_bytes, bytes);
auto premaster_key_result = ByteBuffer::copy(random_bytes, bytes);
if (!premaster_key_result.has_value()) {
dbgln("RSA premaster key generation failed, not enough memory");
return;
}
m_context.premaster_key = premaster_key_result.release_value();
const auto& certificate_option = verify_chain_and_get_matching_certificate(m_context.extensions.SNI); // if the SNI is empty, we'll make a special case and match *a* leaf certificate.
if (!certificate_option.has_value()) {
@ -239,11 +244,21 @@ void TLSv12::build_dhe_rsa_pre_master_secret(PacketBuilder& builder)
auto dh_random = Crypto::NumberTheory::random_number(0, dh_p);
auto dh_Yc = Crypto::NumberTheory::ModularPower(dh_g, dh_random, dh_p);
auto dh_Yc_bytes = ByteBuffer::create_uninitialized(dh_key_size);
auto dh_Yc_bytes_result = ByteBuffer::create_uninitialized(dh_key_size);
if (!dh_Yc_bytes_result.has_value()) {
dbgln("Failed to build DHE_RSA premaster secret: not enough memory");
return;
}
auto dh_Yc_bytes = dh_Yc_bytes_result.release_value();
dh_Yc.export_data(dh_Yc_bytes);
auto premaster_key = Crypto::NumberTheory::ModularPower(dh_Ys, dh_random, dh_p);
m_context.premaster_key = ByteBuffer::create_uninitialized(dh_key_size);
auto premaster_key_result = ByteBuffer::create_uninitialized(dh_key_size);
if (!premaster_key_result.has_value()) {
dbgln("Failed to build DHE_RSA premaster secret: not enough memory");
return;
}
m_context.premaster_key = premaster_key_result.release_value();
premaster_key.export_data(m_context.premaster_key, true);
dh.p.clear();

View file

@ -240,15 +240,30 @@ ssize_t TLSv12::handle_dhe_rsa_server_key_exchange(ReadonlyBytes buffer)
{
auto dh_p_length = AK::convert_between_host_and_network_endian(ByteReader::load16(buffer.offset_pointer(3)));
auto dh_p = buffer.slice(5, dh_p_length);
m_context.server_diffie_hellman_params.p = ByteBuffer::copy(dh_p.data(), dh_p.size());
auto p_result = ByteBuffer::copy(dh_p);
if (!p_result.has_value()) {
dbgln("dhe_rsa_server_key_exchange failed: Not enough memory");
return 0;
}
m_context.server_diffie_hellman_params.p = p_result.release_value();
auto dh_g_length = AK::convert_between_host_and_network_endian(ByteReader::load16(buffer.offset_pointer(5 + dh_p_length)));
auto dh_g = buffer.slice(7 + dh_p_length, dh_g_length);
m_context.server_diffie_hellman_params.g = ByteBuffer::copy(dh_g.data(), dh_g.size());
auto g_result = ByteBuffer::copy(dh_g);
if (!g_result.has_value()) {
dbgln("dhe_rsa_server_key_exchange failed: Not enough memory");
return 0;
}
m_context.server_diffie_hellman_params.g = g_result.release_value();
auto dh_Ys_length = AK::convert_between_host_and_network_endian(ByteReader::load16(buffer.offset_pointer(7 + dh_p_length + dh_g_length)));
auto dh_Ys = buffer.slice(9 + dh_p_length + dh_g_length, dh_Ys_length);
m_context.server_diffie_hellman_params.Ys = ByteBuffer::copy(dh_Ys.data(), dh_Ys.size());
auto Ys_result = ByteBuffer::copy(dh_Ys);
if (!Ys_result.has_value()) {
dbgln("dhe_rsa_server_key_exchange failed: Not enough memory");
return 0;
}
m_context.server_diffie_hellman_params.Ys = Ys_result.release_value();
if constexpr (TLS_DEBUG) {
dbgln("dh_p: {:hex-dump}", dh_p);

View file

@ -97,7 +97,12 @@ void TLSv12::update_packet(ByteBuffer& packet)
if (m_context.crypto.created == 1) {
// `buffer' will continue to be encrypted
auto buffer = ByteBuffer::create_uninitialized(length);
auto buffer_result = ByteBuffer::create_uninitialized(length);
if (!buffer_result.has_value()) {
dbgln("LibTLS: Failed to allocate enough memory");
VERIFY_NOT_REACHED();
}
auto buffer = buffer_result.release_value();
size_t buffer_position = 0;
auto iv_size = iv_length();
@ -112,7 +117,12 @@ void TLSv12::update_packet(ByteBuffer& packet)
[&](Crypto::Cipher::AESCipher::GCMMode& gcm) {
VERIFY(is_aead());
// We need enough space for a header, the data, a tag, and the IV
ct = ByteBuffer::create_uninitialized(length + header_size + iv_size + 16);
auto ct_buffer_result = ByteBuffer::create_uninitialized(length + header_size + iv_size + 16);
if (!ct_buffer_result.has_value()) {
dbgln("LibTLS: Failed to allocate enough memory for the ciphertext");
VERIFY_NOT_REACHED();
}
ct = ct_buffer_result.release_value();
// copy the header over
ct.overwrite(0, packet.data(), header_size - 2);
@ -161,7 +171,12 @@ void TLSv12::update_packet(ByteBuffer& packet)
[&](Crypto::Cipher::AESCipher::CBCMode& cbc) {
VERIFY(!is_aead());
// We need enough space for a header, iv_length bytes of IV and whatever the packet contains
ct = ByteBuffer::create_uninitialized(length + header_size + iv_size);
auto ct_buffer_result = ByteBuffer::create_uninitialized(length + header_size + iv_size);
if (!ct_buffer_result.has_value()) {
dbgln("LibTLS: Failed to allocate enough memory for the ciphertext");
VERIFY_NOT_REACHED();
}
ct = ct_buffer_result.release_value();
// copy the header over
ct.overwrite(0, packet.data(), header_size - 2);
@ -179,7 +194,12 @@ void TLSv12::update_packet(ByteBuffer& packet)
VERIFY(buffer_position == buffer.size());
auto iv = ByteBuffer::create_uninitialized(iv_size);
auto iv_buffer_result = ByteBuffer::create_uninitialized(iv_size);
if (!iv_buffer_result.has_value()) {
dbgln("LibTLS: Failed to allocate memory for IV");
VERIFY_NOT_REACHED();
}
auto iv = iv_buffer_result.release_value();
fill_with_random(iv.data(), iv.size());
// write it into the ciphertext portion of the message
@ -266,14 +286,18 @@ ByteBuffer TLSv12::hmac_message(const ReadonlyBytes& buf, const Optional<Readonl
hmac.update(buf2.value());
}
auto digest = hmac.digest();
auto mac = ByteBuffer::copy(digest.immutable_data(), digest.data_length());
auto mac_result = ByteBuffer::copy(digest.immutable_data(), digest.data_length());
if (!mac_result.has_value()) {
dbgln("Failed to calculate message HMAC: Not enough memory");
return {};
}
if constexpr (TLS_DEBUG) {
dbgln("HMAC of the block for sequence number {}", sequence_number);
print_buffer(mac);
print_buffer(*mac_result);
}
return mac;
return mac_result.release_value();
}
ssize_t TLSv12::handle_message(ReadonlyBytes buffer)
@ -336,7 +360,13 @@ ssize_t TLSv12::handle_message(ReadonlyBytes buffer)
auto packet_length = length - iv_length() - 16;
auto payload = plain;
decrypted = ByteBuffer::create_uninitialized(packet_length);
auto decrypted_result = ByteBuffer::create_uninitialized(packet_length);
if (!decrypted_result.has_value()) {
dbgln("Failed to allocate memory for the packet");
return_value = Error::DecryptionFailed;
return;
}
decrypted = decrypted_result.release_value();
// AEAD AAD (13)
// Seq. no (8)
@ -394,7 +424,13 @@ ssize_t TLSv12::handle_message(ReadonlyBytes buffer)
VERIFY(!is_aead());
auto iv_size = iv_length();
decrypted = cbc.create_aligned_buffer(length - iv_size);
auto decrypted_result = cbc.create_aligned_buffer(length - iv_size);
if (!decrypted_result.has_value()) {
dbgln("Failed to allocate memory for the packet");
return_value = Error::DecryptionFailed;
return;
}
decrypted = decrypted_result.release_value();
auto iv = buffer.slice(header_size, iv_size);
Bytes decrypted_span = decrypted;

View file

@ -15,9 +15,8 @@ namespace TLS {
Optional<ByteBuffer> TLSv12::read()
{
if (m_context.application_buffer.size()) {
auto buf = m_context.application_buffer.slice(0, m_context.application_buffer.size());
m_context.application_buffer.clear();
return buf;
auto buf = move(m_context.application_buffer);
return { move(buf) };
}
return {};
}
@ -47,10 +46,18 @@ String TLSv12::read_line(size_t max_size)
if (offset > max_size)
return {};
auto buffer = ByteBuffer::copy(start, offset);
auto buffer_result = ByteBuffer::copy(start, offset);
if (!buffer_result.has_value()) {
dbgln("TLS: Failed to read line, not enough memory");
dbgln("max_size < offset: {} < {} (size = {})", max_size, offset, m_context.application_buffer.size());
dbgln("-> {:32hex-dump}", ReadonlyBytes { start, offset });
return {};
}
String line { bit_cast<char const*>(start), offset, Chomp };
m_context.application_buffer = m_context.application_buffer.slice(offset + 1, m_context.application_buffer.size() - offset - 1);
return String::copy(buffer, Chomp);
return line;
}
bool TLSv12::write(ReadonlyBytes buffer)

View file

@ -36,7 +36,8 @@ public:
PacketBuilder(MessageType type, Version version, size_t size_hint = 0xfdf)
{
m_packet_data = ByteBuffer::create_uninitialized(size_hint + 16);
// FIXME: Handle possible OOM situation.
m_packet_data = ByteBuffer::create_uninitialized(size_hint + 16).release_value();
m_current_length = 5;
m_packet_data[0] = (u8)type;
ByteReader::store(m_packet_data.offset_pointer(1), AK::convert_between_host_and_network_endian((u16)version));

View file

@ -35,7 +35,7 @@ void TLSv12::consume(ReadonlyBytes record)
dbgln_if(TLS_DEBUG, "Consuming {} bytes", record.size());
if (!m_context.message_buffer.try_append(record.data(), record.size())) {
if (!m_context.message_buffer.try_append(record)) {
dbgln("Not enough space in message buffer, dropping the record");
return;
}
@ -306,7 +306,7 @@ TLSv12::TLSv12(Core::Object* parent, Options options)
{
m_context.options = move(options);
m_context.is_server = false;
m_context.tls_buffer = ByteBuffer::create_uninitialized(0);
m_context.tls_buffer = {};
#ifdef SOCK_NONBLOCK
int fd = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0);
#else

View file

@ -404,18 +404,27 @@ OwnPtr<Block> MatroskaReader::parse_simple_block()
for (int i = 0; i < frame_count; i++) {
auto current_frame_size = frame_sizes.at(i);
block->add_frame(ByteBuffer::copy(m_streamer.data(), current_frame_size));
auto frame_result = ByteBuffer::copy(m_streamer.data(), current_frame_size);
if (!frame_result.has_value())
return {};
block->add_frame(frame_result.release_value());
m_streamer.drop_octets(current_frame_size);
}
} else if (block->lacing() == Block::Lacing::FixedSize) {
auto frame_count = m_streamer.read_octet() + 1;
auto individual_frame_size = total_frame_content_size / frame_count;
for (int i = 0; i < frame_count; i++) {
block->add_frame(ByteBuffer::copy(m_streamer.data(), individual_frame_size));
auto frame_result = ByteBuffer::copy(m_streamer.data(), individual_frame_size);
if (!frame_result.has_value())
return {};
block->add_frame(frame_result.release_value());
m_streamer.drop_octets(individual_frame_size);
}
} else {
block->add_frame(ByteBuffer::copy(m_streamer.data(), total_frame_content_size));
auto frame_result = ByteBuffer::copy(m_streamer.data(), total_frame_content_size);
if (!frame_result.has_value())
return {};
block->add_frame(frame_result.release_value());
m_streamer.drop_octets(total_frame_content_size);
}
return block;

View file

@ -738,7 +738,10 @@ ParseResult<CustomSection> CustomSection::parse(InputStream& stream)
if (name.is_error())
return name.error();
auto data_buffer = ByteBuffer::create_uninitialized(64);
ByteBuffer data_buffer;
if (!data_buffer.try_resize(64))
return ParseError::OutOfMemory;
while (!stream.has_any_error() && !stream.unreliable_eof()) {
char buf[16];
auto size = stream.read({ buf, 16 });
@ -1413,6 +1416,8 @@ String parse_error_to_string(ParseError error)
return "The parser encountered an unimplemented feature";
case ParseError::HugeAllocationRequested:
return "Parsing caused an attempt to allocate a very big chunk of memory, likely malformed data";
case ParseError::OutOfMemory:
return "The parser hit an OOM condition";
case ParseError::ExpectedFloatingImmediate:
return "Expected a floating point immediate";
case ParseError::ExpectedSignedImmediate:

View file

@ -36,6 +36,7 @@ enum class ParseError {
InvalidTag,
InvalidType,
HugeAllocationRequested,
OutOfMemory,
// FIXME: This should not exist!
NotImplemented,
};

View file

@ -68,7 +68,8 @@ static String mime_type_from_content_type(const String& content_type)
void Resource::did_load(Badge<ResourceLoader>, ReadonlyBytes data, const HashMap<String, String, CaseInsensitiveStringTraits>& headers, Optional<u32> status_code)
{
VERIFY(!m_loaded);
m_encoded_data = ByteBuffer::copy(data);
// FIXME: Handle OOM failure.
m_encoded_data = ByteBuffer::copy(data).release_value();
m_response_headers = headers;
m_status_code = move(status_code);
m_loaded = true;

View file

@ -212,7 +212,8 @@ DOM::ExceptionOr<void> XMLHttpRequest::send()
if (!weak_this)
return;
auto& xhr = const_cast<XMLHttpRequest&>(*weak_this);
auto response_data = ByteBuffer::copy(data);
// FIXME: Handle OOM failure.
auto response_data = ByteBuffer::copy(data).release_value();
// FIXME: There's currently no difference between transmitted and length.
u64 transmitted = response_data.size();
u64 length = response_data.size();

View file

@ -15,7 +15,7 @@ class Message {
public:
explicit Message(String const& data)
: m_is_text(true)
, m_data(ByteBuffer::copy(data.bytes()))
, m_data(ByteBuffer::copy(data.bytes()).release_value()) // FIXME: Handle possible OOM situation.
{
}

View file

@ -98,7 +98,7 @@ void WebSocket::close(u16 code, String message)
VERIFY(m_state == WebSocket::InternalState::Open);
VERIFY(m_impl);
auto message_bytes = message.bytes();
auto close_payload = ByteBuffer::create_uninitialized(message_bytes.size() + 2);
auto close_payload = ByteBuffer::create_uninitialized(message_bytes.size() + 2).release_value(); // FIXME: Handle possible OOM situation.
close_payload.overwrite(0, (u8*)&code, 2);
close_payload.overwrite(2, message_bytes.data(), message_bytes.size());
send_frame(WebSocket::OpCode::ConnectionClose, close_payload, true);
@ -428,7 +428,7 @@ void WebSocket::read_frame()
masking_key[3] = masking_key_data[3];
}
auto payload = ByteBuffer::create_uninitialized(payload_length);
auto payload = ByteBuffer::create_uninitialized(payload_length).release_value(); // FIXME: Handle possible OOM situation.
u64 read_length = 0;
while (read_length < payload_length) {
auto payload_part = m_impl->read(payload_length - read_length);
@ -546,11 +546,14 @@ void WebSocket::send_frame(WebSocket::OpCode op_code, ReadonlyBytes payload, boo
fill_with_random(masking_key, 4);
m_impl->send(ReadonlyBytes(masking_key, 4));
// Mask the payload
auto masked_payload = ByteBuffer::create_uninitialized(payload.size());
auto buffer_result = ByteBuffer::create_uninitialized(payload.size());
if (buffer_result.has_value()) {
auto& masked_payload = buffer_result.value();
for (size_t i = 0; i < payload.size(); ++i) {
masked_payload[i] = payload[i] ^ (masking_key[i % 4]);
}
m_impl->send(masked_payload);
}
} else {
m_impl->send(payload);
}

View file

@ -239,7 +239,7 @@ private:
class DHCPv4PacketBuilder {
public:
DHCPv4PacketBuilder()
: m_buffer(ByteBuffer::create_zeroed(sizeof(DHCPv4Packet)))
: m_buffer(ByteBuffer::create_zeroed(sizeof(DHCPv4Packet)).release_value()) // FIXME: Handle possible OOM failure.
{
auto* options = peek().options();
// set the magic DHCP cookie value

View file

@ -69,7 +69,11 @@ OwnPtr<Request> start_request(TBadgedProtocol&& protocol, ClientConnection& clie
request.set_method(HTTP::HttpRequest::Method::GET);
request.set_url(url);
request.set_headers(headers);
request.set_body(body);
auto allocated_body_result = ByteBuffer::copy(body);
if (!allocated_body_result.has_value())
return {};
request.set_body(allocated_body_result.release_value());
auto output_stream = make<OutputFileStream>(pipe_result.value().write_fd);
output_stream->make_unbuffered();

View file

@ -38,8 +38,8 @@ RefPtr<Gfx::Bitmap> ClipboardServerConnection::get_bitmap()
if (!format.has_value() || format.value() == 0)
return nullptr;
auto data = ByteBuffer::copy(clipping.data().data<void>(), clipping.data().size());
auto clipping_bitmap = Gfx::Bitmap::try_create_wrapper((Gfx::BitmapFormat)format.value(), { (int)width.value(), (int)height.value() }, scale.value(), pitch.value(), data.data());
auto data = clipping.data().data<void>();
auto clipping_bitmap = Gfx::Bitmap::try_create_wrapper((Gfx::BitmapFormat)format.value(), { (int)width.value(), (int)height.value() }, scale.value(), pitch.value(), const_cast<void*>(data));
auto bitmap = Gfx::Bitmap::try_create(Gfx::BitmapFormat::BGRA8888, { (int)width.value(), (int)height.value() }, scale.value());
for (int y = 0; y < clipping_bitmap->physical_height(); ++y) {

View file

@ -59,7 +59,7 @@ void SpiceAgent::on_message_received()
{
ChunkHeader header {};
read_n(&header, sizeof(header));
auto buffer = ByteBuffer::create_uninitialized(header.size);
auto buffer = ByteBuffer::create_uninitialized(header.size).release_value(); // FIXME: Handle possible OOM situation.
read_n(buffer.data(), buffer.size());
auto* message = reinterpret_cast<Message*>(buffer.data());
switch (message->type) {
@ -75,15 +75,17 @@ void SpiceAgent::on_message_received()
auto* request_message = reinterpret_cast<ClipboardRequest*>(message->data);
auto clipboard = m_clipboard_connection.get_clipboard_data();
auto& mime = clipboard.mime_type();
ByteBuffer byte_buffer;
ByteBuffer backing_byte_buffer;
ReadonlyBytes bytes;
if (mime == "image/x-serenityos") {
auto bitmap = m_clipboard_connection.get_bitmap();
byte_buffer = Gfx::PNGWriter::encode(*bitmap);
backing_byte_buffer = Gfx::PNGWriter::encode(*bitmap);
bytes = backing_byte_buffer;
} else {
auto clip_data = clipboard.data();
byte_buffer = ByteBuffer::copy(clip_data.data<void>(), clip_data.size());
auto data = clipboard.data();
bytes = { data.data<void>(), data.size() };
}
auto clipboard_buffer = Clipboard::make_buffer((ClipboardType)request_message->type, byte_buffer);
auto clipboard_buffer = Clipboard::make_buffer((ClipboardType)request_message->type, bytes);
send_message(clipboard_buffer);
break;
}
@ -116,7 +118,7 @@ void SpiceAgent::on_message_received()
case (u32)MessageType::Clipboard: {
auto* clipboard_message = reinterpret_cast<Clipboard*>(message->data);
auto type = (ClipboardType)clipboard_message->type;
auto data_buffer = ByteBuffer::create_uninitialized(message->size - sizeof(u32));
auto data_buffer = ByteBuffer::create_uninitialized(message->size - sizeof(u32)).release_value(); // FIXME: Handle possible OOM situation.
const auto total_bytes = message->size - sizeof(Clipboard);
auto bytes_copied = header.size - sizeof(Message) - sizeof(Clipboard);
@ -204,7 +206,7 @@ SpiceAgent::Message* SpiceAgent::initialize_headers(u8* data, size_t additional_
ByteBuffer SpiceAgent::AnnounceCapabilities::make_buffer(bool request, const Vector<Capability>& capabilities)
{
size_t required_size = sizeof(ChunkHeader) + sizeof(Message) + sizeof(AnnounceCapabilities);
auto buffer = ByteBuffer::create_uninitialized(required_size);
auto buffer = ByteBuffer::create_uninitialized(required_size).release_value(); // FIXME: Handle possible OOM situation.
u8* data = buffer.data();
auto* message = initialize_headers(data, sizeof(AnnounceCapabilities), MessageType::AnnounceCapabilities);
@ -226,7 +228,7 @@ ByteBuffer SpiceAgent::ClipboardGrab::make_buffer(const Vector<ClipboardType>& t
VERIFY(types.size() > 0);
size_t variable_data_size = sizeof(u32) * types.size();
size_t required_size = sizeof(ChunkHeader) + sizeof(Message) + variable_data_size;
auto buffer = ByteBuffer::create_uninitialized(required_size);
auto buffer = ByteBuffer::create_uninitialized(required_size).release_value(); // FIXME: Handle possible OOM situation.
u8* data = buffer.data();
auto* message = initialize_headers(data, variable_data_size, MessageType::ClipboardGrab);
@ -244,7 +246,7 @@ ByteBuffer SpiceAgent::Clipboard::make_buffer(ClipboardType type, ReadonlyBytes
{
size_t data_size = sizeof(Clipboard) + contents.size();
size_t required_size = sizeof(ChunkHeader) + sizeof(Message) + data_size;
auto buffer = ByteBuffer::create_uninitialized(required_size);
auto buffer = ByteBuffer::create_uninitialized(required_size).release_value(); // FIXME: Handle possible OOM situation.
u8* data = buffer.data();
auto* message = initialize_headers(data, data_size, MessageType::Clipboard);
@ -262,7 +264,7 @@ ByteBuffer SpiceAgent::ClipboardRequest::make_buffer(ClipboardType type)
{
size_t data_size = sizeof(ClipboardRequest);
size_t required_size = sizeof(ChunkHeader) + sizeof(Message) + data_size;
auto buffer = ByteBuffer::create_uninitialized(required_size);
auto buffer = ByteBuffer::create_uninitialized(required_size).release_value(); // FIXME: Handle possible OOM situation.
u8* data = buffer.data();
auto* message = initialize_headers(data, data_size, MessageType::ClipboardRequest);

View file

@ -150,7 +150,7 @@ void Client::send_command(Command command)
void Client::send_commands(Vector<Command> commands)
{
auto buffer = ByteBuffer::create_uninitialized(commands.size() * 3);
auto buffer = ByteBuffer::create_uninitialized(commands.size() * 3).release_value(); // FIXME: Handle possible OOM situation.
OutputMemoryStream stream { buffer };
for (auto& command : commands)

View file

@ -1589,7 +1589,13 @@ void Execute::for_each_entry(RefPtr<Shell> shell, Function<IterationDecision(Non
return Break;
}
} else {
auto entry = ByteBuffer::create_uninitialized(line_end + ifs.length());
auto entry_result = ByteBuffer::create_uninitialized(line_end + ifs.length());
if (!entry_result.has_value()) {
loop.quit(Break);
notifier->set_enabled(false);
return Break;
}
auto entry = entry_result.release_value();
auto rc = stream.read_or_error(entry);
VERIFY(rc);
@ -1675,7 +1681,12 @@ void Execute::for_each_entry(RefPtr<Shell> shell, Function<IterationDecision(Non
} while (action == Continue);
if (!stream.eof()) {
auto entry = ByteBuffer::create_uninitialized(stream.size());
auto entry_result = ByteBuffer::create_uninitialized(stream.size());
if (!entry_result.has_value()) {
shell->raise_error(Shell::ShellError::OutOfMemory, {}, position());
return;
}
auto entry = entry_result.release_value();
auto rc = stream.read_or_error(entry);
VERIFY(rc);
callback(make_ref_counted<StringValue>(String::copy(entry)));

View file

@ -1999,6 +1999,9 @@ void Shell::possibly_print_error() const
case ShellError::OpenFailure:
warnln("Shell: Open failed for {}", m_error_description);
break;
case ShellError::OutOfMemory:
warnln("Shell: Hit an OOM situation");
break;
case ShellError::InternalControlFlowBreak:
case ShellError::InternalControlFlowContinue:
return;

View file

@ -233,6 +233,7 @@ public:
InvalidGlobError,
InvalidSliceContentsError,
OpenFailure,
OutOfMemory,
};
void raise_error(ShellError kind, String description, Optional<AST::Position> position = {})

Some files were not shown because too many files have changed in this diff Show more