blob: 6fbdc5a14cbe608335a933fe141710d96541fd44 [file] [log] [blame] [edit]
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "net/base/base64.h"
#include <algorithm>
#include <string>
#include <string_view>
#include <utility>
#include "base/containers/contains.h"
#include "base/strings/string_util.h"
#include "net/base/features.h"
#include "third_party/simdutf/simdutf.h"
namespace net {
bool SimdutfBase64Decode(std::string_view input,
std::string* output,
base::Base64DecodePolicy policy) {
CHECK(base::FeatureList::IsEnabled(features::kSimdutfBase64Support));
if (policy == base::Base64DecodePolicy::kStrict) {
if (input.size() % 4 != 0) {
// The input is not properly padded.
return false;
}
if (std::ranges::any_of(input, [](char c) {
return base::Contains(base::kInfraAsciiWhitespace, c);
})) {
return false;
}
}
std::string decode_buf;
decode_buf.resize(
simdutf::maximal_binary_length_from_base64(input.data(), input.size()));
simdutf::result r =
simdutf::base64_to_binary(input.data(), input.size(), decode_buf.data());
if (r.error != simdutf::error_code::SUCCESS) {
return false;
}
// If this failed it would indicate we wrote OOB. It's possible for this to
// be elided by the compiler, since writing OOB is UB.
CHECK_LE(r.count, decode_buf.size());
// Shrinks the buffer and makes it NUL-terminated.
decode_buf.resize(r.count);
*output = std::move(decode_buf);
return true;
}
} // namespace net