diff --git a/AK/Base64.cpp b/AK/Base64.cpp index 0093481a67..f60340e1ad 100644 --- a/AK/Base64.cpp +++ b/AK/Base64.cpp @@ -100,7 +100,7 @@ ErrorOr decode_base64(StringView input) return ByteBuffer::copy(output); } -DeprecatedString encode_base64(ReadonlyBytes input) +ErrorOr encode_base64(ReadonlyBytes input) { StringBuilder output(calculate_base64_encoded_length(input)); @@ -131,13 +131,13 @@ DeprecatedString encode_base64(ReadonlyBytes input) char const out2 = is_16bit ? '=' : alphabet[index2]; char const out3 = is_8bit ? '=' : alphabet[index3]; - output.append(out0); - output.append(out1); - output.append(out2); - output.append(out3); + TRY(output.try_append(out0)); + TRY(output.try_append(out1)); + TRY(output.try_append(out2)); + TRY(output.try_append(out3)); } - return output.to_deprecated_string(); + return output.to_string(); } } diff --git a/AK/Base64.h b/AK/Base64.h index 5635352d00..3bbdf5359b 100644 --- a/AK/Base64.h +++ b/AK/Base64.h @@ -7,8 +7,8 @@ #pragma once #include -#include #include +#include #include namespace AK { @@ -19,7 +19,7 @@ namespace AK { [[nodiscard]] ErrorOr decode_base64(StringView); -[[nodiscard]] DeprecatedString encode_base64(ReadonlyBytes); +[[nodiscard]] ErrorOr encode_base64(ReadonlyBytes); } #if USING_AK_GLOBALLY diff --git a/Tests/AK/TestBase64.cpp b/Tests/AK/TestBase64.cpp index 32048b7e61..f6f79b1737 100644 --- a/Tests/AK/TestBase64.cpp +++ b/Tests/AK/TestBase64.cpp @@ -42,8 +42,8 @@ TEST_CASE(test_decode_invalid) TEST_CASE(test_encode) { auto encode_equal = [&](StringView input, StringView expected) { - auto encoded = encode_base64(input.bytes()); - EXPECT(encoded == DeprecatedString(expected)); + auto encoded = MUST(encode_base64(input.bytes())); + EXPECT(encoded == expected); EXPECT_EQ(expected.length(), calculate_base64_encoded_length(input.bytes())); }; diff --git a/Userland/Applications/PixelPaint/Image.cpp b/Userland/Applications/PixelPaint/Image.cpp index e26cf8cdab..ac7e472280 100644 --- a/Userland/Applications/PixelPaint/Image.cpp +++ b/Userland/Applications/PixelPaint/Image.cpp @@ -137,9 +137,9 @@ ErrorOr Image::serialize_as_json(JsonObjectSerializer& json TRY(json_layer.add("opacity_percent"sv, layer.opacity_percent())); TRY(json_layer.add("visible"sv, layer.is_visible())); TRY(json_layer.add("selected"sv, layer.is_selected())); - TRY(json_layer.add("bitmap"sv, encode_base64(TRY(Gfx::PNGWriter::encode(layer.content_bitmap()))))); + TRY(json_layer.add("bitmap"sv, TRY(encode_base64(TRY(Gfx::PNGWriter::encode(layer.content_bitmap())))))); if (layer.is_masked()) - TRY(json_layer.add("mask"sv, encode_base64(TRY(Gfx::PNGWriter::encode(*layer.mask_bitmap()))))); + TRY(json_layer.add("mask"sv, TRY(encode_base64(TRY(Gfx::PNGWriter::encode(*layer.mask_bitmap())))))); TRY(json_layer.finish()); } diff --git a/Userland/Libraries/LibCore/Account.cpp b/Userland/Libraries/LibCore/Account.cpp index 03808e089c..17746d2cac 100644 --- a/Userland/Libraries/LibCore/Account.cpp +++ b/Userland/Libraries/LibCore/Account.cpp @@ -34,7 +34,10 @@ static DeprecatedString get_salt() StringBuilder builder; builder.append("$5$"sv); - builder.append(encode_base64(ReadonlyBytes(random_data, sizeof(random_data)))); + + // FIXME: change to TRY() and make method fallible + auto salt_string = MUST(encode_base64({ random_data, sizeof(random_data) })); + builder.append(salt_string); return builder.build(); } diff --git a/Userland/Libraries/LibCrypt/crypt.cpp b/Userland/Libraries/LibCrypt/crypt.cpp index 258f2909f1..fcb378353e 100644 --- a/Userland/Libraries/LibCrypt/crypt.cpp +++ b/Userland/Libraries/LibCrypt/crypt.cpp @@ -52,8 +52,13 @@ char* crypt_r(char const* key, char const* salt, struct crypt_data* data) sha.update(reinterpret_cast(salt_value), salt_len); auto digest = sha.digest(); - auto string = encode_base64(ReadonlyBytes(digest.immutable_data(), digest.data_length())); + auto string_or_error = encode_base64({ digest.immutable_data(), digest.data_length() }); + if (string_or_error.is_error()) { + errno = ENOMEM; + return nullptr; + } + auto string = string_or_error.value().bytes_as_string_view(); fits = string.copy_characters_to_buffer(data->result + header_len + 1, sizeof(data->result) - header_len - 1); if (!fits) { errno = EINVAL; diff --git a/Userland/Libraries/LibHTTP/HttpRequest.cpp b/Userland/Libraries/LibHTTP/HttpRequest.cpp index ab6538e3bc..9ac9255e9f 100644 --- a/Userland/Libraries/LibHTTP/HttpRequest.cpp +++ b/Userland/Libraries/LibHTTP/HttpRequest.cpp @@ -242,7 +242,9 @@ Optional HttpRequest::get_http_basic_authentication_header( builder.append(url.username()); builder.append(':'); builder.append(url.password()); - auto token = encode_base64(builder.to_deprecated_string().bytes()); + + // FIXME: change to TRY() and make method fallible + auto token = MUST(encode_base64(MUST(builder.to_string()).bytes())); builder.clear(); builder.append("Basic "sv); builder.append(token); diff --git a/Userland/Libraries/LibWeb/Fetch/Fetching/Fetching.cpp b/Userland/Libraries/LibWeb/Fetch/Fetching/Fetching.cpp index 4845715f5f..ec0846ecb8 100644 --- a/Userland/Libraries/LibWeb/Fetch/Fetching/Fetching.cpp +++ b/Userland/Libraries/LibWeb/Fetch/Fetching/Fetching.cpp @@ -1305,7 +1305,8 @@ WebIDL::ExceptionOr> http_network_or_cache_fet // true, set authorizationValue to httpRequest’s current URL, converted to an `Authorization` value. else if (http_request->current_url().includes_credentials() && is_authentication_fetch == IsAuthenticationFetch::Yes) { auto const& url = http_request->current_url(); - authorization_value = encode_base64(DeprecatedString::formatted("{}:{}", url.username(), url.password()).bytes()); + auto payload = DeprecatedString::formatted("{}:{}", url.username(), url.password()); + authorization_value = TRY_OR_RETURN_OOM(realm, encode_base64(payload.bytes())).to_deprecated_string(); } // 4. If authorizationValue is non-null, then append (`Authorization`, authorizationValue) to diff --git a/Userland/Libraries/LibWeb/HTML/HTMLCanvasElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLCanvasElement.cpp index faad688c1c..3c4eb53e67 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLCanvasElement.cpp +++ b/Userland/Libraries/LibWeb/HTML/HTMLCanvasElement.cpp @@ -181,7 +181,12 @@ DeprecatedString HTMLCanvasElement::to_data_url(DeprecatedString const& type, [[ dbgln("Gfx::PNGWriter failed to encode the HTMLCanvasElement: {}", encoded_bitmap_or_error.error()); return {}; } - return AK::URL::create_with_data(type, encode_base64(encoded_bitmap_or_error.value()), true).to_deprecated_string(); + auto base64_encoded_or_error = encode_base64(encoded_bitmap_or_error.value()); + if (base64_encoded_or_error.is_error()) { + // FIXME: propagate error + return {}; + } + return AK::URL::create_with_data(type, base64_encoded_or_error.release_value().to_deprecated_string(), true).to_deprecated_string(); } void HTMLCanvasElement::present() diff --git a/Userland/Libraries/LibWeb/HTML/Window.cpp b/Userland/Libraries/LibWeb/HTML/Window.cpp index 5b4147b3d4..52f1707947 100644 --- a/Userland/Libraries/LibWeb/HTML/Window.cpp +++ b/Userland/Libraries/LibWeb/HTML/Window.cpp @@ -1423,8 +1423,8 @@ JS_DEFINE_NATIVE_FUNCTION(Window::btoa) byte_string.append(code_point); } - auto encoded = encode_base64(byte_string.span()); - return JS::PrimitiveString::create(vm, move(encoded)); + auto encoded = MUST(encode_base64(byte_string.span())); + return JS::PrimitiveString::create(vm, encoded.to_deprecated_string()); } // https://html.spec.whatwg.org/multipage/interaction.html#dom-window-focus diff --git a/Userland/Libraries/LibWeb/HTML/WorkerGlobalScope.cpp b/Userland/Libraries/LibWeb/HTML/WorkerGlobalScope.cpp index bad102430e..09bf7004c3 100644 --- a/Userland/Libraries/LibWeb/HTML/WorkerGlobalScope.cpp +++ b/Userland/Libraries/LibWeb/HTML/WorkerGlobalScope.cpp @@ -137,7 +137,7 @@ WebIDL::ExceptionOr WorkerGlobalScope::btoa(DeprecatedString c // Otherwise, the user agent must convert data to a byte sequence whose nth byte is the eight-bit representation of the nth code point of data, // and then must apply forgiving-base64 encode to that byte sequence and return the result. - return encode_base64(byte_string.span()); + return TRY_OR_RETURN_OOM(realm(), encode_base64(byte_string.span())).to_deprecated_string(); } // https://html.spec.whatwg.org/multipage/webappapis.html#dom-atob diff --git a/Userland/Libraries/LibWebSocket/WebSocket.cpp b/Userland/Libraries/LibWebSocket/WebSocket.cpp index 78147eb608..f3072c7aa7 100644 --- a/Userland/Libraries/LibWebSocket/WebSocket.cpp +++ b/Userland/Libraries/LibWebSocket/WebSocket.cpp @@ -180,7 +180,8 @@ void WebSocket::send_client_handshake() // 7. 16-byte nonce encoded as Base64 u8 nonce_data[16]; fill_with_random(nonce_data, 16); - m_websocket_key = encode_base64(ReadonlyBytes(nonce_data, 16)); + // FIXME: change to TRY() and make method fallible + m_websocket_key = MUST(encode_base64({ nonce_data, 16 })).to_deprecated_string(); builder.appendff("Sec-WebSocket-Key: {}\r\n", m_websocket_key); // 8. Origin (optional field) @@ -322,7 +323,8 @@ void WebSocket::read_server_handshake() hash.initialize(Crypto::Hash::HashKind::SHA1); hash.update(expected_content); auto expected_sha1 = hash.digest(); - auto expected_sha1_string = encode_base64(ReadonlyBytes(expected_sha1.immutable_data(), expected_sha1.data_length())); + // FIXME: change to TRY() and make method fallible + auto expected_sha1_string = MUST(encode_base64({ expected_sha1.immutable_data(), expected_sha1.data_length() })); if (!parts[1].trim_whitespace().equals_ignoring_case(expected_sha1_string)) { dbgln("WebSocket: Server HTTP Handshake Header |Sec-Websocket-Accept| should be '{}', got '{}'. Failing connection.", expected_sha1_string, parts[1]); fatal_error(WebSocket::Error::ConnectionUpgradeFailed); diff --git a/Userland/Services/WebServer/Client.cpp b/Userland/Services/WebServer/Client.cpp index 2571f88684..84728f3c2c 100644 --- a/Userland/Services/WebServer/Client.cpp +++ b/Userland/Services/WebServer/Client.cpp @@ -238,7 +238,8 @@ static DeprecatedString folder_image_data() static DeprecatedString cache; if (cache.is_empty()) { auto file = Core::MappedFile::map("/res/icons/16x16/filetype-folder.png"sv).release_value_but_fixme_should_propagate_errors(); - cache = encode_base64(file->bytes()); + // FIXME: change to TRY() and make method fallible + cache = MUST(encode_base64(file->bytes())).to_deprecated_string(); } return cache; } @@ -248,7 +249,8 @@ static DeprecatedString file_image_data() static DeprecatedString cache; if (cache.is_empty()) { auto file = Core::MappedFile::map("/res/icons/16x16/filetype-unknown.png"sv).release_value_but_fixme_should_propagate_errors(); - cache = encode_base64(file->bytes()); + // FIXME: change to TRY() and make method fallible + cache = MUST(encode_base64(file->bytes())).to_deprecated_string(); } return cache; } diff --git a/Userland/Utilities/useradd.cpp b/Userland/Utilities/useradd.cpp index 146d2c598f..f84e4c19ea 100644 --- a/Userland/Utilities/useradd.cpp +++ b/Userland/Utilities/useradd.cpp @@ -134,18 +134,18 @@ ErrorOr serenity_main(Main::Arguments arguments) } } - auto get_salt = []() { + auto get_salt = []() -> ErrorOr { char random_data[12]; fill_with_random(random_data, sizeof(random_data)); StringBuilder builder; builder.append("$5$"sv); - builder.append(encode_base64(ReadonlyBytes(random_data, sizeof(random_data)))); + builder.append(TRY(encode_base64({ random_data, sizeof(random_data) }))); return builder.build(); }; - char* hash = crypt(password.characters(), get_salt().characters()); + char* hash = crypt(password.characters(), TRY(get_salt()).characters()); struct passwd p; p.pw_name = const_cast(username.characters());