Skip to content

Commit

Permalink
Various string related updates (#2895)
Browse files Browse the repository at this point in the history
  • Loading branch information
jasnell authored Oct 10, 2024
1 parent 2e0fa0e commit 1729660
Show file tree
Hide file tree
Showing 46 changed files with 418 additions and 443 deletions.
4 changes: 2 additions & 2 deletions src/workerd/api/actor-state.c++
Original file line number Diff line number Diff line change
Expand Up @@ -1007,10 +1007,10 @@ jsg::JsValue deserializeV8Value(
// include the key (to help find the data in the database if it hasn't been deleted), the
// length of the value, and the first three bytes of the value (which is just the v8-internal
// version header and the tag that indicates the type of the value, but not its contents).
kj::String actorId = getCurrentActorId().orDefault([]() { return kj::str(); });
kj::String actorId = getCurrentActorId().orDefault([]() { return kj::String(); });
KJ_FAIL_ASSERT("actor storage deserialization failed", "failed to deserialize stored value",
actorId, exception.getHandle(js), key, buf.size(),
buf.slice(0, std::min(static_cast<size_t>(3), buf.size())));
buf.first(std::min(static_cast<size_t>(3), buf.size())));
});
} catch (jsg::JsExceptionThrown&) {
// We can occasionally hit an isolate termination here -- we prefix the error with jsg to avoid
Expand Down
4 changes: 2 additions & 2 deletions src/workerd/api/crypto/aes.c++
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ private:
plainSize = 0;
}

auto actualCipherText = cipherText.slice(0, cipherText.size() - tagLength / 8);
auto actualCipherText = cipherText.first(cipherText.size() - tagLength / 8);
auto tagText = cipherText.slice(actualCipherText.size(), cipherText.size());

auto plainText = kj::heapArray<kj::byte>(actualCipherText.size());
Expand Down Expand Up @@ -513,7 +513,7 @@ protected:
// counter portion of the block back to zero.
auto inputSizePart1 = BN_get_word(numBlocksUntilReset.get()) * AES_BLOCK_SIZE;

process(&cipher, data.slice(0, inputSizePart1), counter, result.asPtr());
process(&cipher, data.first(inputSizePart1), counter, result.asPtr());

// Zero the counter bits of the block. Chromium creates a copy but we own our buffer.
{
Expand Down
2 changes: 1 addition & 1 deletion src/workerd/api/crypto/digest.c++
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ private:

if (format == "jwk") {
// This assert enforces that the slice logic to fill in `.alg` below is safe.
JSG_REQUIRE(keyAlgorithm.hash.name.slice(0, 4) == "SHA-"_kj, DOMNotSupportedError,
JSG_REQUIRE(keyAlgorithm.hash.name.first(4) == "SHA-"_kj, DOMNotSupportedError,
"Unimplemented JWK key export format for key algorithm \"", keyAlgorithm.hash.name,
"\".");

Expand Down
2 changes: 1 addition & 1 deletion src/workerd/api/crypto/ec.c++
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ public:
return nullptr;
}

auto r = signature.slice(0, rsSize);
auto r = signature.first(rsSize);
auto s = signature.slice(rsSize, signature.size());

// Trim leading zeros.
Expand Down
2 changes: 1 addition & 1 deletion src/workerd/api/crypto/impl.c++
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ kj::String errorsToString(
return e;
}
KJ_CASE_ONEOF(e, OpensslUntranslatedError) {
return kj::StringPtr(e.reasonName);
return e.reasonName;
}
}
KJ_UNREACHABLE;
Expand Down
2 changes: 1 addition & 1 deletion src/workerd/api/crypto/keys.c++
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ kj::Array<kj::byte> AsymmetricKeyCryptoKeyImpl::sign(

KJ_ASSERT(signatureSize <= signature.size());
if (signatureSize < signature.size()) {
signature = kj::heapArray<kj::byte>(signature.slice(0, signatureSize));
signature = kj::heapArray<kj::byte>(signature.first(signatureSize));
}

return signatureSslToWebCrypto(kj::mv(signature));
Expand Down
2 changes: 1 addition & 1 deletion src/workerd/api/crypto/rsa.c++
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ kj::Array<kj::byte> Rsa::sign(const kj::ArrayPtr<const kj::byte> data) const {
// We did not fill the entire buffer, let's make sure we zero
// out the rest of it so we don't leak any uninitialized data.
signature.slice(signatureSize).fill(0);
return signature.slice(0, signatureSize).attach(kj::mv(signature));
return signature.first(signatureSize).attach(kj::mv(signature));
}

return kj::mv(signature);
Expand Down
15 changes: 3 additions & 12 deletions src/workerd/api/crypto/spkac.c++
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,13 @@

#include <workerd/io/io-context.h>
#include <workerd/jsg/jsg.h>
#include <workerd/util/strings.h>

#include <openssl/pem.h>
#include <openssl/x509.h>

namespace workerd::api {
namespace {
kj::ArrayPtr<const kj::byte> trim(kj::ArrayPtr<const kj::byte> input) {
size_t length = input.size();
for (auto i = length - 1; i >= 0; --i) {
if (input[i] != ' ' && input[i] != '\n' && input[i] != '\r' && input[i] != '\t') {
break;
}
}
return input.first(length);
}

kj::Array<kj::byte> toArray(BIO* bio) {
BUF_MEM* bptr;
BIO_get_mem_ptr(bio, &bptr);
Expand All @@ -32,8 +23,8 @@ kj::Array<kj::byte> toArray(BIO* bio) {
kj::Maybe<kj::Own<NETSCAPE_SPKI>> tryGetSpki(kj::ArrayPtr<const kj::byte> input) {
static constexpr int32_t kMaxLength = kj::maxValue;
JSG_REQUIRE(input.size() <= kMaxLength, RangeError, "spkac is too large");
input = trim(input);
auto ptr = NETSCAPE_SPKI_b64_decode(input.asChars().begin(), input.size());
auto trimmed = trimTailingWhitespace(input.asChars());
auto ptr = NETSCAPE_SPKI_b64_decode(trimmed.begin(), trimmed.size());
if (!ptr) return kj::none;
return kj::disposeWith<NETSCAPE_SPKI_free>(ptr);
}
Expand Down
30 changes: 4 additions & 26 deletions src/workerd/api/data-url.c++
Original file line number Diff line number Diff line change
Expand Up @@ -25,32 +25,9 @@ kj::Maybe<DataUrl> DataUrl::from(const jsg::Url& url) {
// Per the fetch spec, it doesn't matter if the comma is within a quoted
// string value in the MIME type... which is fun.

static const auto trim = [](auto label) {
size_t start = 0;
auto end = label.size();
while (start < end && isAsciiWhitespace(label[start])) {
start++;
}
while (end > start && isAsciiWhitespace(label[end - 1])) {
end--;
}
return label.slice(start, end).asChars();
};

static const auto strip = [](auto label) {
auto result = kj::heapArray<kj::byte>(label.size());
size_t len = 0;
for (const kj::byte c: label) {
if (!isAsciiWhitespace(c)) {
result[len++] = c;
}
}
return result.first(len).attach(kj::mv(result));
};

static const auto isBase64 = [](kj::ArrayPtr<const char> label) -> bool {
KJ_IF_SOME(pos, label.findLast(';')) {
auto res = trim(label.slice(pos + 1));
auto res = trimLeadingAndTrailingWhitespace(label.slice(pos + 1));
return res.size() == 6 && (res[0] | 0x20) == 'b' && (res[1] | 0x20) == 'a' &&
(res[2] | 0x20) == 's' && (res[3] | 0x20) == 'e' && (res[4] == '6') && (res[5] == '4');
}
Expand All @@ -70,13 +47,14 @@ kj::Maybe<DataUrl> DataUrl::from(const jsg::Url& url) {
auto data = href.slice(pos + 1);

// We need to trim leading and trailing whitespace from the mimetype
unparsed = trim(unparsed);
unparsed = trimLeadingAndTrailingWhitespace(unparsed);

// Determine if the data is base64 encoded
kj::Array<kj::byte> decoded = nullptr;
if (isBase64(unparsed)) {
unparsed = unparsed.first(KJ_ASSERT_NONNULL(unparsed.findLast(';')));
decoded = kj::decodeBase64(strip(jsg::Url::percentDecode(data.asBytes())).asChars());
decoded =
kj::decodeBase64(stripInnerWhitespace(jsg::Url::percentDecode(data.asBytes())).asChars());
} else {
decoded = jsg::Url::percentDecode(data.asBytes());
}
Expand Down
18 changes: 3 additions & 15 deletions src/workerd/api/encoding.c++
Original file line number Diff line number Diff line change
Expand Up @@ -264,22 +264,10 @@ kj::StringPtr getEncodingId(Encoding encoding) {
}

Encoding getEncodingForLabel(kj::StringPtr label) {
kj::String labelInsensitive = toLower(label);
const auto trim = [](kj::StringPtr label) {
size_t start = 0;
auto end = label.size();
while (start < end && isAsciiWhitespace(label[start])) {
start++;
}
while (end > start && isAsciiWhitespace(label[end - 1])) {
end--;
}
return label.slice(start, end).asChars();
};

auto trimmed = trim(labelInsensitive);
auto lower = toLower(label);
auto trimmed = trimLeadingAndTrailingWhitespace(lower);
#define V(label, key) \
if (trimmed == label##_kj) return Encoding::key;
if (trimmed == label##_kjb) return Encoding::key;
EW_ENCODING_LABELS(V)
#undef V
return Encoding::INVALID;
Expand Down
4 changes: 2 additions & 2 deletions src/workerd/api/eventsource.c++
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public:
KJ_IF_SOME(found, findEndOfLine(input)) {
auto prefix = kept.releaseAsArray();
// Feed the line into the processor.
feed(kj::str(prefix, input.slice(0, found.pos)));
feed(kj::str(prefix, input.first(found.pos)));
input = found.remaining;
// If we've reached the end of the input, input will == nullptr here.
} else {
Expand Down Expand Up @@ -168,7 +168,7 @@ private:
};

KJ_IF_SOME(pos, line.findFirst(':')) {
handle(*this, line.slice(0, pos), line.slice(pos + 1));
handle(*this, line.first(pos), line.slice(pos + 1));
} else {
handle(*this, line, ""_kjc);
}
Expand Down
14 changes: 5 additions & 9 deletions src/workerd/api/form-data.c++
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,6 @@ kj::ArrayPtr<const char> splitAtSubString(kj::ArrayPtr<const char>& text, kj::St
return result;
}

bool startsWith(kj::ArrayPtr<const char> bytes, kj::StringPtr prefix) {
return bytes.size() >= prefix.size() && bytes.slice(0, prefix.size()) == prefix;
}

struct FormDataHeaderTable {
kj::HttpHeaderId contentDispositionId;
kj::Own<kj::HttpHeaderTable> table;
Expand Down Expand Up @@ -90,11 +86,11 @@ void parseFormData(kj::Maybe<jsg::Lock&> js,
const auto done = [](kj::ArrayPtr<const char>& body) {
// Consume any (CR)LF characters that trailed the boundary and indicate continuation, or consume
// the terminal "--" characters and indicate termination, or throw an error.
if (startsWith(body, "\n"_kj)) {
if (body.startsWith("\n"_kj)) {
body = body.slice(1, body.size());
} else if (startsWith(body, "\r\n"_kj)) {
} else if (body.startsWith("\r\n"_kj)) {
body = body.slice(2, body.size());
} else if (startsWith(body, "--"_kj)) {
} else if (body.startsWith("--"_kj)) {
// We're done!
return true;
} else {
Expand Down Expand Up @@ -126,7 +122,7 @@ void parseFormData(kj::Maybe<jsg::Lock&> js,
//
// TODO(soon): Read the Content-Type to support files.

auto headersText = kj::str(body.slice(0, match[0].second - body.begin()));
auto headersText = kj::str(body.first(match[0].second - body.begin()));
body = body.slice(match[0].second - body.begin(), body.size());

kj::HttpHeaders headers(*formDataHeaderTable.table);
Expand Down Expand Up @@ -167,7 +163,7 @@ void parseFormData(kj::Maybe<jsg::Lock&> js,

if (message.size() > 0) {
// If we skipped a CR, we must avoid including it in the message data.
message = message.slice(0, message.size() - uint(message.back() == '\r'));
message = message.first(message.size() - uint(message.back() == '\r'));
}

if (filename == kj::none || convertFilesToStrings) {
Expand Down
2 changes: 1 addition & 1 deletion src/workerd/api/global-scope.c++
Original file line number Diff line number Diff line change
Expand Up @@ -675,7 +675,7 @@ jsg::JsString ServiceWorkerGlobalScope::btoa(jsg::Lock& js, jsg::JsValue data) {
auto result = kj::heapArray<kj::byte>(expected_length);
auto written = simdutf::binary_to_base64(
strArray.asChars().begin(), strArray.size(), result.asChars().begin());
return js.str(result.slice(0, written).attach(kj::mv(result)));
return js.str(result.first(written).attach(kj::mv(result)));
}
jsg::JsString ServiceWorkerGlobalScope::atob(jsg::Lock& js, kj::String data) {
auto decoded = kj::decodeBase64(data.asArray());
Expand Down
13 changes: 7 additions & 6 deletions src/workerd/api/http.c++
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <workerd/util/http-util.h>
#include <workerd/util/mimetype.h>
#include <workerd/util/stream-utils.h>
#include <workerd/util/strings.h>
#include <workerd/util/thread-scopes.h>

#include <capnp/compat/http-over-capnp.capnp.h>
Expand Down Expand Up @@ -84,7 +85,7 @@ jsg::ByteString normalizeHeaderValue(jsg::ByteString value) {
slice = slice.slice(1, slice.size());
}
while (slice.size() > 0 && isHttpWhitespace(slice.back())) {
slice = slice.slice(0, slice.size() - 1);
slice = slice.first(slice.size() - 1);
}
if (slice.size() == value.size()) {
return kj::mv(value);
Expand Down Expand Up @@ -268,7 +269,7 @@ jsg::Ref<Headers> Headers::constructor(jsg::Lock& js, jsg::Optional<Initializer>

kj::Maybe<jsg::ByteString> Headers::get(jsg::ByteString name) {
requireValidHeaderName(name);
auto iter = headers.find(toLower(kj::mv(name)));
auto iter = headers.find(jsg::ByteString(toLower(kj::mv(name))));
if (iter == headers.end()) {
return kj::none;
} else {
Expand Down Expand Up @@ -300,7 +301,7 @@ kj::ArrayPtr<jsg::ByteString> Headers::getAll(jsg::ByteString name) {

bool Headers::has(jsg::ByteString name) {
requireValidHeaderName(name);
return headers.find(toLower(kj::mv(name))) != headers.end();
return headers.find(jsg::ByteString(toLower(kj::mv(name)))) != headers.end();
}

void Headers::set(jsg::ByteString name, jsg::ByteString value) {
Expand All @@ -310,7 +311,7 @@ void Headers::set(jsg::ByteString name, jsg::ByteString value) {

void Headers::setUnguarded(jsg::ByteString name, jsg::ByteString value) {
requireValidHeaderName(name);
auto key = toLower(name);
auto key = jsg::ByteString(toLower(name));
value = normalizeHeaderValue(kj::mv(value));
requireValidHeaderValue(value);
auto [iter, emplaced] = headers.try_emplace(key, kj::mv(key), kj::mv(name), kj::mv(value));
Expand All @@ -324,7 +325,7 @@ void Headers::setUnguarded(jsg::ByteString name, jsg::ByteString value) {
void Headers::append(jsg::ByteString name, jsg::ByteString value) {
checkGuard();
requireValidHeaderName(name);
auto key = toLower(name);
auto key = jsg::ByteString(toLower(name));
value = normalizeHeaderValue(kj::mv(value));
requireValidHeaderValue(value);
auto [iter, emplaced] = headers.try_emplace(key, kj::mv(key), kj::mv(name), kj::mv(value));
Expand All @@ -336,7 +337,7 @@ void Headers::append(jsg::ByteString name, jsg::ByteString value) {
void Headers::delete_(jsg::ByteString name) {
checkGuard();
requireValidHeaderName(name);
headers.erase(toLower(kj::mv(name)));
headers.erase(jsg::ByteString(toLower(kj::mv(name))));
}

// There are a couple implementation details of the Headers iterators worth calling out.
Expand Down
2 changes: 1 addition & 1 deletion src/workerd/api/http.h
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ class Body: public jsg::Object {
: ownBytes(kj::refcounted<RefcountedBytes>(string.releaseArray().releaseAsBytes())),
view([this] {
auto bytesIncludingNull = ownBytes.get<kj::Own<RefcountedBytes>>()->bytes.asPtr();
return bytesIncludingNull.slice(0, bytesIncludingNull.size() - 1);
return bytesIncludingNull.first(bytesIncludingNull.size() - 1);
}()) {}
Buffer(jsg::Ref<Blob> blob)
: ownBytes(kj::mv(blob)),
Expand Down
4 changes: 2 additions & 2 deletions src/workerd/api/node/buffer.c++
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ kj::Array<byte> decodeHexTruncated(kj::ArrayPtr<kj::byte> text, bool strict = fa
if (strict) {
JSG_FAIL_REQUIRE(TypeError, "The text is not valid hex");
}
text = text.slice(0, text.size() - 1);
text = text.first(text.size() - 1);
}
auto vec = kj::Vector<kj::byte>(text.size() / 2);

Expand Down Expand Up @@ -159,7 +159,7 @@ kj::Array<kj::byte> decodeStringImpl(
auto len = result.written;
auto dest = kj::heapArray<kj::byte>(nbytes::Base64DecodedSize(buf.begin(), len));
len = nbytes::Base64Decode(dest.asChars().begin(), dest.size(), buf.begin(), buf.size());
return dest.slice(0, len).attach(kj::mv(dest));
return dest.first(len).attach(kj::mv(dest));
}
case Encoding::HEX: {
KJ_STACK_ARRAY(kj::byte, buf, length, 1024, 536870888);
Expand Down
6 changes: 3 additions & 3 deletions src/workerd/api/node/i18n.c++
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ kj::Maybe<kj::Array<kj::byte>> TranscodeDefault(
ucnv_convertEx(to.conv(), from.conv(), &target, target + limit, &source_, source_ + source.size(),
nullptr, nullptr, nullptr, nullptr, true, true, &status);
if (U_SUCCESS(status)) {
return out.slice(0, target - out.asChars().begin()).attach(kj::mv(out));
return out.first(target - out.asChars().begin()).attach(kj::mv(out));
}

return kj::none;
Expand All @@ -82,7 +82,7 @@ kj::Maybe<kj::Array<kj::byte>> TranscodeLatin1ToUTF16(
return kj::none;
}

return destbuf.slice(0, actual_length).asBytes().attach(kj::mv(destbuf));
return destbuf.first(actual_length).asBytes().attach(kj::mv(destbuf));
}

kj::Maybe<kj::Array<kj::byte>> TranscodeFromUTF16(
Expand All @@ -105,7 +105,7 @@ kj::Maybe<kj::Array<kj::byte>> TranscodeFromUTF16(
utf16_input.begin(), utf16_input.size(), &status);

if (U_SUCCESS(status)) {
return destbuf.slice(0, len).asBytes().attach(kj::mv(destbuf));
return destbuf.first(len).asBytes().attach(kj::mv(destbuf));
}

return kj::none;
Expand Down
2 changes: 1 addition & 1 deletion src/workerd/api/node/util.c++
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ kj::String MIMEParams::toString() {
KJ_IF_SOME(inner, mimeType) {
return inner.paramsToString();
}
return kj::str();
return kj::String();
}

jsg::Ref<MIMEParams::EntryIterator> MIMEParams::entries(jsg::Lock&) {
Expand Down
1 change: 1 addition & 0 deletions src/workerd/api/queue.c++
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <workerd/jsg/jsg.h>
#include <workerd/jsg/ser.h>
#include <workerd/util/mimetype.h>
#include <workerd/util/strings.h>

#include <kj/encoding.h>

Expand Down
Loading

0 comments on commit 1729660

Please sign in to comment.