WebRTC Rusty Base64
Bug: webrtc:416445288 Change-Id: I6eb49d95aa8000812b5299d25198a79a8c069ce7 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/390400 Commit-Queue: Harald Alvestrand <hta@webrtc.org> Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org> Reviewed-by: Harald Alvestrand <hta@webrtc.org> Auto-Submit: Evan Shrubsole <eshr@webrtc.org> Cr-Commit-Position: refs/heads/main@{#44606}
This commit is contained in:
parent
1e9de04049
commit
2f21adc141
1
.gitignore
vendored
1
.gitignore
vendored
@ -73,3 +73,4 @@
|
||||
/xcodebuild
|
||||
/.vscode
|
||||
!webrtc/*
|
||||
rust-project.json
|
||||
|
||||
@ -1795,6 +1795,66 @@ rtc_library("base64") {
|
||||
]
|
||||
}
|
||||
|
||||
if (rtc_rusty_base64) {
|
||||
import("//build/config/rust.gni")
|
||||
import("//build/rust/rust_static_library.gni")
|
||||
|
||||
rtc_source_set("base64_header") {
|
||||
sources = [ "base64.h" ]
|
||||
deps = [
|
||||
"../api:array_view",
|
||||
"//third_party/abseil-cpp/absl/strings:string_view",
|
||||
]
|
||||
}
|
||||
|
||||
rust_static_library("base64_rust_bridge") {
|
||||
allow_unsafe = true # Needed for FFI with cxx crate.
|
||||
crate_root = "base64.rs"
|
||||
sources = [ "base64.rs" ]
|
||||
cxx_bindings = [ "base64.rs" ]
|
||||
deps = [
|
||||
":base64_header",
|
||||
"//third_party/rust/base64/v0_22:lib",
|
||||
]
|
||||
visibility = [ ":rusty_base64" ]
|
||||
}
|
||||
|
||||
rtc_library("rusty_base64") {
|
||||
sources = [ "base64_rust.cc" ]
|
||||
deps = [
|
||||
":base64_header",
|
||||
":base64_rust_bridge",
|
||||
"//build/rust:cxx_cppdeps",
|
||||
"//third_party/abseil-cpp/absl/strings:string_view",
|
||||
]
|
||||
}
|
||||
|
||||
if (rtc_include_tests) {
|
||||
rtc_test("rusty_base64_unittest") {
|
||||
sources = [ "base64_unittest.cc" ]
|
||||
deps = [
|
||||
":base64_header",
|
||||
":rusty_base64",
|
||||
"../test:test_main",
|
||||
"../test:test_support",
|
||||
"//third_party/abseil-cpp/absl/strings:string_view",
|
||||
]
|
||||
}
|
||||
|
||||
if (rtc_enable_google_benchmarks) {
|
||||
rtc_test("rusty_base64_benchmark") {
|
||||
sources = [ "base64_benchmark.cc" ]
|
||||
deps = [
|
||||
":base64_header",
|
||||
":rusty_base64",
|
||||
"../test:benchmark_main",
|
||||
"//third_party/google_benchmark",
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (rtc_include_tests) {
|
||||
if (rtc_enable_google_benchmarks) {
|
||||
rtc_test("base64_benchmark") {
|
||||
|
||||
@ -41,4 +41,7 @@ specific_include_rules = {
|
||||
"base64_benchmark\.cc": [
|
||||
"+benchmark",
|
||||
],
|
||||
"base64_rust\.cc": [
|
||||
"+third_party/rust/chromium_crates_io/vendor/cxx-v1/include/cxx.h",
|
||||
],
|
||||
}
|
||||
|
||||
@ -29,6 +29,10 @@ bool IsStrictBase64(absl::string_view data) {
|
||||
}
|
||||
} // namespace
|
||||
|
||||
std::string Base64Encode(absl::string_view data) {
|
||||
return absl::Base64Escape(data);
|
||||
}
|
||||
|
||||
std::optional<std::string> Base64Decode(absl::string_view data,
|
||||
Base64DecodeOptions options) {
|
||||
// absl::Base64Unescape is forgiving. Return nullopt if the input is not
|
||||
|
||||
@ -15,22 +15,19 @@
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
#include "absl/strings/escaping.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "api/array_view.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
std::string Base64Encode(absl::string_view data);
|
||||
|
||||
inline std::string Base64Encode(ArrayView<const uint8_t> data) {
|
||||
return absl::Base64Escape(absl::string_view(
|
||||
return Base64Encode(absl::string_view(
|
||||
reinterpret_cast<const char*>(data.data()), data.size()));
|
||||
}
|
||||
|
||||
inline std::string Base64Encode(absl::string_view data) {
|
||||
return absl::Base64Escape(data);
|
||||
}
|
||||
|
||||
enum class Base64DecodeOptions {
|
||||
enum class Base64DecodeOptions : uint8_t {
|
||||
kStrict,
|
||||
// Matches https://infra.spec.whatwg.org/#forgiving-base64-decode.
|
||||
kForgiving,
|
||||
|
||||
73
rtc_base/base64.rs
Normal file
73
rtc_base/base64.rs
Normal file
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (c) 2025 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
use base64::alphabet;
|
||||
use base64::engine::general_purpose;
|
||||
use base64::engine::DecodePaddingMode;
|
||||
use base64::Engine;
|
||||
use cxx::CxxString;
|
||||
use std::pin::Pin;
|
||||
|
||||
#[cxx::bridge(namespace = "webrtc")]
|
||||
mod ffi {
|
||||
#[repr(u8)]
|
||||
enum Base64DecodeOptions {
|
||||
kStrict,
|
||||
kForgiving,
|
||||
}
|
||||
|
||||
extern "C++" {
|
||||
include!("rtc_base/base64.h");
|
||||
type Base64DecodeOptions;
|
||||
}
|
||||
|
||||
extern "Rust" {
|
||||
fn rs_base64_encode(data: &[u8]) -> String;
|
||||
fn rs_base64_decode(
|
||||
data: &[u8],
|
||||
options: Base64DecodeOptions,
|
||||
output: Pin<&mut CxxString>,
|
||||
) -> bool;
|
||||
}
|
||||
}
|
||||
|
||||
fn rs_base64_encode(data: &[u8]) -> String {
|
||||
general_purpose::STANDARD.encode(data)
|
||||
}
|
||||
|
||||
const FORGIVING_ENGINE: general_purpose::GeneralPurpose = general_purpose::GeneralPurpose::new(
|
||||
&alphabet::STANDARD,
|
||||
general_purpose::GeneralPurposeConfig::new()
|
||||
.with_decode_padding_mode(DecodePaddingMode::Indifferent),
|
||||
);
|
||||
|
||||
fn rs_base64_decode(
|
||||
data: &[u8],
|
||||
options: ffi::Base64DecodeOptions,
|
||||
output: Pin<&mut CxxString>,
|
||||
) -> bool {
|
||||
let result = match options {
|
||||
ffi::Base64DecodeOptions::kStrict => general_purpose::STANDARD.decode(data),
|
||||
ffi::Base64DecodeOptions::kForgiving => {
|
||||
let data_without_whitespace: Vec<u8> =
|
||||
data.iter().filter(|&c| !c.is_ascii_whitespace()).copied().collect();
|
||||
FORGIVING_ENGINE.decode(data_without_whitespace)
|
||||
}
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
match result {
|
||||
Ok(vec) => {
|
||||
output.push_bytes(vec.as_slice());
|
||||
true
|
||||
}
|
||||
Err(_) => false,
|
||||
}
|
||||
}
|
||||
41
rtc_base/base64_rust.cc
Normal file
41
rtc_base/base64_rust.cc
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) 2025 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include <cstdint>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "rtc_base/base64.h"
|
||||
#include "rtc_base/base64.rs.h"
|
||||
#include "third_party/rust/chromium_crates_io/vendor/cxx-v1/include/cxx.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
std::string Base64Encode(absl::string_view data) {
|
||||
rust::Slice<const uint8_t> input_slice(
|
||||
reinterpret_cast<const uint8_t*>(data.data()), data.size());
|
||||
rust::Vec<uint8_t> output_slice;
|
||||
rust::String str = rs_base64_encode(input_slice);
|
||||
return std::string(str);
|
||||
}
|
||||
|
||||
std::optional<std::string> Base64Decode(absl::string_view data,
|
||||
Base64DecodeOptions options) {
|
||||
rust::Slice<const uint8_t> input_slice(
|
||||
reinterpret_cast<const uint8_t*>(data.data()), data.size());
|
||||
std::string output;
|
||||
if (!rs_base64_decode(input_slice, options, output)) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
@ -334,6 +334,9 @@ declare_args() {
|
||||
|
||||
# Set this to true to disable webrtc metrics.
|
||||
rtc_disable_metrics = false
|
||||
|
||||
# Enables an experimental rust version of base64 for building and testing.
|
||||
rtc_rusty_base64 = true
|
||||
}
|
||||
|
||||
declare_args() {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user