Skip to content

Commit

Permalink
revive pr
Browse files Browse the repository at this point in the history
  • Loading branch information
Jarred-Sumner committed Jan 9, 2025
1 parent 38c9de8 commit 6edb3f4
Show file tree
Hide file tree
Showing 34 changed files with 40,346 additions and 4,799 deletions.
12 changes: 5 additions & 7 deletions src/bun.js/bindings/webcore/DecodeEscapeSequences.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,18 +102,17 @@ struct URLEscapeSequence {
// a valid escape sequence, but there may be characters between the sequences.
Vector<uint8_t, 512> buffer;
buffer.grow(run.length()); // Unescaping hex sequences only makes the length smaller.
uint8_t* p = buffer.data();
size_t bufferIndex = 0;
while (!run.isEmpty()) {
if (run[0] == '%') {
*p++ = (toASCIIHexValue(run[1]) << 4) | toASCIIHexValue(run[2]);
buffer[bufferIndex++] = (toASCIIHexValue(run[1]) << 4) | toASCIIHexValue(run[2]);
run = run.substring(SequenceSize);
} else {
*p++ = run[0];
buffer[bufferIndex++] = run[0];
run = run.substring(1);
}
}
ASSERT(buffer.size() >= static_cast<size_t>(p - buffer.data())); // Prove buffer not overrun.
buffer.shrink(p - buffer.data());
buffer.shrink(bufferIndex);
return buffer;
}

Expand Down Expand Up @@ -175,7 +174,7 @@ inline Vector<uint8_t> decodeURLEscapeSequencesAsData(StringView string)

if (encodedRunPosition == notFound)
return result;

// Bytes go through as-is.
auto decodedEscapeSequence = URLEscapeSequence::decodeRun(string.substring(encodedRunPosition, encodedRunEnd - encodedRunPosition));
ASSERT(!decodedEscapeSequence.isEmpty());
Expand All @@ -186,4 +185,3 @@ inline Vector<uint8_t> decodeURLEscapeSequencesAsData(StringView string)
}

} // namespace PAL

40,204 changes: 35,686 additions & 4,518 deletions src/bun.js/bindings/webcore/EncodingTables.cpp

Large diffs are not rendered by default.

17 changes: 9 additions & 8 deletions src/bun.js/bindings/webcore/EncodingTables.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ template<typename CollectionType, typename KeyType> static auto findFirstInSorte
template<typename CollectionType, typename KeyType> static auto findInSortedPairs(const CollectionType& sortedPairsCollection, const KeyType&) -> std::pair<decltype(std::begin(sortedPairsCollection)), decltype(std::begin(sortedPairsCollection))>;

#if !ASSERT_ENABLED
inline void checkEncodingTableInvariants() { }
inline void checkEncodingTableInvariants() {}
#endif

struct CompareFirst {
Expand Down Expand Up @@ -94,22 +94,22 @@ template<typename T> SecondAdapter<T> makeSecondAdapter(const T& value)

template<typename CollectionType> void sortByFirst(CollectionType& collection)
{
std::sort(std::begin(collection), std::end(collection), CompareFirst { });
std::sort(std::begin(collection), std::end(collection), CompareFirst {});
}

template<typename CollectionType> void stableSortByFirst(CollectionType& collection)
{
std::stable_sort(std::begin(collection), std::end(collection), CompareFirst { });
std::stable_sort(std::begin(collection), std::end(collection), CompareFirst {});
}

template<typename CollectionType> bool isSortedByFirst(const CollectionType& collection)
{
return std::is_sorted(std::begin(collection), std::end(collection), CompareFirst { });
return std::is_sorted(std::begin(collection), std::end(collection), CompareFirst {});
}

template<typename CollectionType> bool sortedFirstsAreUnique(const CollectionType& collection)
{
return std::adjacent_find(std::begin(collection), std::end(collection), EqualFirst { }) == std::end(collection);
return std::adjacent_find(std::begin(collection), std::end(collection), EqualFirst {}) == std::end(collection);
}

template<typename CollectionType, typename KeyType> static auto findFirstInSortedPairs(const CollectionType& collection, const KeyType& key) -> std::optional<decltype(std::begin(collection)->second)>
Expand All @@ -118,18 +118,19 @@ template<typename CollectionType, typename KeyType> static auto findFirstInSorte
if (key != decltype(std::begin(collection)->first)(key))
return std::nullopt;
}
auto iterator = std::lower_bound(std::begin(collection), std::end(collection), makeFirstAdapter(key), CompareFirst { });
auto iterator = std::lower_bound(std::begin(collection), std::end(collection), makeFirstAdapter(key), CompareFirst {});
if (iterator == std::end(collection) || key < iterator->first)
return std::nullopt;
return iterator->second;
}

template<typename CollectionType, typename KeyType> static auto findInSortedPairs(const CollectionType& collection, const KeyType& key) -> std::pair<decltype(std::begin(collection)), decltype(std::begin(collection))> {
template<typename CollectionType, typename KeyType> static auto findInSortedPairs(const CollectionType& collection, const KeyType& key) -> std::pair<decltype(std::begin(collection)), decltype(std::begin(collection))>
{
if constexpr (std::is_integral_v<KeyType>) {
if (key != decltype(std::begin(collection)->first)(key))
return { std::end(collection), std::end(collection) };
}
return std::equal_range(std::begin(collection), std::end(collection), makeFirstAdapter(key), CompareFirst { });
return std::equal_range(std::begin(collection), std::end(collection), makeFirstAdapter(key), CompareFirst {});
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,286 @@
/*
* Copyright (C) 2013 Google Inc. All rights reserved.
* Copyright (C) 2020 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#pragma once

#include <wtf/StdLibExtras.h>
#include <wtf/text/StringCommon.h>
#include <wtf/text/StringParsingBuffer.h>

namespace WTF {

template<typename CharacterType> inline bool isNotASCIISpace(CharacterType c)
{
return !isUnicodeCompatibleASCIIWhitespace(c);
}

template<typename T> void skip(std::span<T>& data, size_t amountToSkip)
{
data = data.subspan(amountToSkip);
}

template<typename CharacterType, typename DelimiterType> bool skipExactly(const CharacterType*& position, const CharacterType* end, DelimiterType delimiter)
{
if (position < end && *position == delimiter) {
++position;
return true;
}
return false;
}

template<typename CharacterType, typename DelimiterType> bool skipExactly(std::span<const CharacterType>& data, DelimiterType delimiter)
{
if (!data.empty() && data.front() == delimiter) {
skip(data, 1);
return true;
}
return false;
}

template<typename CharacterType, typename DelimiterType> bool skipExactly(StringParsingBuffer<CharacterType>& buffer, DelimiterType delimiter)
{
if (buffer.hasCharactersRemaining() && *buffer == delimiter) {
++buffer;
return true;
}
return false;
}

template<bool characterPredicate(LChar)> bool skipExactly(StringParsingBuffer<LChar>& buffer)
{
if (buffer.hasCharactersRemaining() && characterPredicate(*buffer)) {
++buffer;
return true;
}
return false;
}

template<bool characterPredicate(UChar)> bool skipExactly(StringParsingBuffer<UChar>& buffer)
{
if (buffer.hasCharactersRemaining() && characterPredicate(*buffer)) {
++buffer;
return true;
}
return false;
}

template<bool characterPredicate(LChar)> bool skipExactly(std::span<const LChar>& buffer)
{
if (!buffer.empty() && characterPredicate(buffer[0])) {
skip(buffer, 1);
return true;
}
return false;
}

template<bool characterPredicate(UChar)> bool skipExactly(std::span<const UChar>& buffer)
{
if (!buffer.empty() && characterPredicate(buffer[0])) {
skip(buffer, 1);
return true;
}
return false;
}

template<typename CharacterType, typename DelimiterType> void skipUntil(StringParsingBuffer<CharacterType>& buffer, DelimiterType delimiter)
{
while (buffer.hasCharactersRemaining() && *buffer != delimiter)
++buffer;
}

template<typename CharacterType, typename DelimiterType> void skipUntil(std::span<const CharacterType>& buffer, DelimiterType delimiter)
{
size_t index = 0;
while (index < buffer.size() && buffer[index] != delimiter)
++index;
skip(buffer, index);
}

template<bool characterPredicate(LChar)> void skipUntil(std::span<const LChar>& data)
{
size_t index = 0;
while (index < data.size() && !characterPredicate(data[index]))
++index;
skip(data, index);
}

template<bool characterPredicate(UChar)> void skipUntil(std::span<const UChar>& data)
{
size_t index = 0;
while (index < data.size() && !characterPredicate(data[index]))
++index;
skip(data, index);
}

template<bool characterPredicate(LChar)> void skipUntil(StringParsingBuffer<LChar>& buffer)
{
while (buffer.hasCharactersRemaining() && !characterPredicate(*buffer))
++buffer;
}

template<bool characterPredicate(UChar)> void skipUntil(StringParsingBuffer<UChar>& buffer)
{
while (buffer.hasCharactersRemaining() && !characterPredicate(*buffer))
++buffer;
}

template<typename CharacterType, typename DelimiterType> void skipWhile(StringParsingBuffer<CharacterType>& buffer, DelimiterType delimiter)
{
while (buffer.hasCharactersRemaining() && *buffer == delimiter)
++buffer;
}

template<typename CharacterType, typename DelimiterType> void skipWhile(std::span<const CharacterType>& buffer, DelimiterType delimiter)
{
size_t index = 0;
while (index < buffer.size() && buffer[index] == delimiter)
++index;
skip(buffer, index);
}

template<bool characterPredicate(LChar)> void skipWhile(std::span<const LChar>& data)
{
size_t index = 0;
while (index < data.size() && characterPredicate(data[index]))
++index;
skip(data, index);
}

template<bool characterPredicate(UChar)> void skipWhile(std::span<const UChar>& data)
{
size_t index = 0;
while (index < data.size() && characterPredicate(data[index]))
++index;
skip(data, index);
}

template<bool characterPredicate(LChar)> void skipWhile(StringParsingBuffer<LChar>& buffer)
{
while (buffer.hasCharactersRemaining() && characterPredicate(*buffer))
++buffer;
}

template<bool characterPredicate(UChar)> void skipWhile(StringParsingBuffer<UChar>& buffer)
{
while (buffer.hasCharactersRemaining() && characterPredicate(*buffer))
++buffer;
}

template<typename CharacterType> bool skipExactlyIgnoringASCIICase(StringParsingBuffer<CharacterType>& buffer, ASCIILiteral literal)
{
auto literalLength = literal.length();

if (buffer.lengthRemaining() < literalLength)
return false;
if (!equalLettersIgnoringASCIICaseWithLength(buffer.span(), literal.span8(), literalLength))
return false;
buffer += literalLength;
return true;
}

template<typename CharacterType, std::size_t Extent> bool skipLettersExactlyIgnoringASCIICase(StringParsingBuffer<CharacterType>& buffer, std::span<const CharacterType, Extent> letters)
{
if (buffer.lengthRemaining() < letters.size())
return false;
for (unsigned i = 0; i < letters.size(); ++i) {
ASSERT(isASCIIAlpha(letters[i]));
if (!isASCIIAlphaCaselessEqual(buffer[i], static_cast<char>(letters[i])))
return false;
}
buffer += letters.size();
return true;
}

template<typename CharacterType, std::size_t Extent> bool skipLettersExactlyIgnoringASCIICase(std::span<const CharacterType>& buffer, std::span<const CharacterType, Extent> letters)
{
if (buffer.size() < letters.size())
return false;
if (!equalLettersIgnoringASCIICaseWithLength(buffer, letters, letters.size()))
return false;
skip(buffer, letters.size());
return true;
}

template<typename CharacterType, std::size_t Extent> constexpr bool skipCharactersExactly(StringParsingBuffer<CharacterType>& buffer, std::span<const CharacterType, Extent> string)
{
if (!spanHasPrefix(buffer.span(), string))
return false;
buffer += string.size();
return true;
}

template<typename CharacterType, std::size_t Extent> constexpr bool skipCharactersExactly(std::span<const CharacterType>& buffer, std::span<const CharacterType, Extent> string)
{
if (!spanHasPrefix(buffer, string))
return false;
skip(buffer, string.size());
return true;
}

template<typename T> std::span<T> consumeSpan(std::span<T>& data, size_t amountToConsume)
{
auto consumed = data.first(amountToConsume);
skip(data, amountToConsume);
return consumed;
}

template<typename T> T& consume(std::span<T>& data)
{
T& value = data[0];
skip(data, 1);
return value;
}

template<typename DestinationType, typename SourceType>
match_constness_t<SourceType, DestinationType>& consumeAndCastTo(std::span<SourceType>& data)
requires(sizeof(SourceType) == 1)
{
return spanReinterpretCast<match_constness_t<SourceType, DestinationType>>(consumeSpan(data, sizeof(DestinationType)))[0];
}

// Adapt a UChar-predicate to an LChar-predicate.
template<bool characterPredicate(UChar)>
static inline bool LCharPredicateAdapter(LChar c) { return characterPredicate(c); }

} // namespace WTF

using WTF::consume;
using WTF::consumeAndCastTo;
using WTF::consumeSpan;
using WTF::isNotASCIISpace;
using WTF::LCharPredicateAdapter;
using WTF::skip;
using WTF::skipCharactersExactly;
using WTF::skipExactly;
using WTF::skipExactlyIgnoringASCIICase;
using WTF::skipLettersExactlyIgnoringASCIICase;
using WTF::skipUntil;
using WTF::skipWhile;
Loading

0 comments on commit 6edb3f4

Please sign in to comment.