Skip to content

Commit

Permalink
Revert back to favoring SearchValues<char> (#1990)
Browse files Browse the repository at this point in the history
  • Loading branch information
lahma authored Oct 27, 2024
1 parent 7ac9805 commit 04466d0
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 29 deletions.
7 changes: 3 additions & 4 deletions Jint/Extensions/Character.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,13 @@ namespace Jint.Extensions;

internal static class Character
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool IsInRange(this char c, ushort min, ushort max) => (uint)(c - min) <= (uint)(max - min);

/// <summary>
/// https://tc39.es/ecma262/#ASCII-word-characters
/// </summary>
public const string AsciiWordCharacters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_";

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool IsAsciiWordCharacter(this char c) => c == '_' || c.IsDecimalDigit() || c.IsInRange('a', 'z') || c.IsInRange('A', 'Z');
public static bool IsInRange(this char c, ushort min, ushort max) => (uint)(c - min) <= (uint)(max - min);

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool IsOctalDigit(this char c) => c.IsInRange('0', '7');
Expand Down
32 changes: 16 additions & 16 deletions Jint/Native/Global/GlobalObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -274,8 +274,8 @@ private static JsValue IsFinite(JsValue thisObject, JsValue[] arguments)

private const string UriReservedString = ";/?:@&=+$,";
private const string UriUnescapedString = "-.!~*'()";
private static readonly SearchValues<char> UriUnescaped = SearchValues.Create(UriUnescapedString);
private static readonly SearchValues<char> UnescapedUriSet = SearchValues.Create(UriReservedString + UriUnescapedString + '#');
private static readonly SearchValues<char> UriUnescaped = SearchValues.Create(Character.AsciiWordCharacters + UriUnescapedString);
private static readonly SearchValues<char> UnescapedUriSet = SearchValues.Create(Character.AsciiWordCharacters + UriReservedString + UriUnescapedString + '#');
private static readonly SearchValues<char> ReservedUriSet = SearchValues.Create(UriReservedString + '#');

[MethodImpl(MethodImplOptions.AggressiveInlining)]
Expand All @@ -300,7 +300,7 @@ private JsValue EncodeUriComponent(JsValue thisObject, JsValue[] arguments)
return Encode(uriString, UriUnescaped);
}

private JsValue Encode(string uriString, SearchValues<char> unescapedUriSet)
private JsValue Encode(string uriString, SearchValues<char> allowedCharacters)
{
var strLen = uriString.Length;
var builder = new ValueStringBuilder(uriString.Length);
Expand All @@ -309,7 +309,7 @@ private JsValue Encode(string uriString, SearchValues<char> unescapedUriSet)
for (var k = 0; k < strLen; k++)
{
var c = uriString[k];
if (c.IsAsciiWordCharacter() || unescapedUriSet.Contains(c))
if (allowedCharacters.Contains(c))
{
builder.Append(c);
}
Expand Down Expand Up @@ -416,7 +416,7 @@ private JsValue Decode(string uriString, SearchValues<char>? reservedSet)
_stringBuilder.Clear();

#if SUPPORTS_SPAN_PARSE
Span<byte> octets = stackalloc byte[4];
Span<byte> octets = stackalloc byte[4];
#else
var octets = new byte[4];
#endif
Expand Down Expand Up @@ -576,36 +576,36 @@ private static bool IsDigit(char c, int radix, out int result)
return tmp < radix;
}

private static readonly SearchValues<char> EscapeAllowList = SearchValues.Create(Character.AsciiWordCharacters + "@*+-./");

/// <summary>
/// https://tc39.es/ecma262/#sec-escape-string
/// </summary>
private JsValue Escape(JsValue thisObject, JsValue[] arguments)
{
var uriString = TypeConverter.ToString(arguments.At(0));

var strLen = uriString.Length;

_stringBuilder.EnsureCapacity(strLen);
_stringBuilder.Clear();
var builder = new ValueStringBuilder(uriString.Length);

for (var k = 0; k < strLen; k++)
foreach (var c in uriString)
{
var c = uriString[k];
if (c.IsAsciiWordCharacter() || c == '@' || c == '*' || c == '+' || c == '-' || c == '.' || c == '/')
if (EscapeAllowList.Contains(c))
{
_stringBuilder.Append(c);
builder.Append(c);
}
else if (c < 256)
{
_stringBuilder.Append('%').AppendFormat(CultureInfo.InvariantCulture, "{0:X2}", (int) c);
builder.Append('%');
builder.AppendHex((byte) c);
}
else
{
_stringBuilder.Append("%u").AppendFormat(CultureInfo.InvariantCulture, "{0:X4}", (int) c);
builder.Append("%u");
builder.Append(((int) c).ToString("X4", CultureInfo.InvariantCulture));
}
}

return _stringBuilder.ToString();
return builder.ToString();
}

/// <summary>
Expand Down
14 changes: 9 additions & 5 deletions Jint/Native/TypedArray/TypedArrayConstructor.Uint8Array.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,12 @@ internal Uint8ArrayConstructor(
protected override void Initialize()
{
const PropertyFlag PropertyFlags = PropertyFlag.Configurable | PropertyFlag.Writable;
var properties = new PropertyDictionary(1, checkExistingKeys: false) { ["BYTES_PER_ELEMENT"] = new(new PropertyDescriptor(JsNumber.PositiveOne, PropertyFlag.AllForbidden)), ["fromBase64"] = new(new ClrFunction(Engine, "fromBase64", FromBase64, 1, PropertyFlag.Configurable), PropertyFlags), ["fromHex"] = new(new ClrFunction(Engine, "fromHex", FromHex, 1, PropertyFlag.Configurable), PropertyFlags), };
var properties = new PropertyDictionary(3, checkExistingKeys: false)
{
["BYTES_PER_ELEMENT"] = new(new PropertyDescriptor(JsNumber.PositiveOne, PropertyFlag.AllForbidden)),
["fromBase64"] = new(new ClrFunction(Engine, "fromBase64", FromBase64, 1, PropertyFlag.Configurable), PropertyFlags),
["fromHex"] = new(new ClrFunction(Engine, "fromHex", FromHex, 1, PropertyFlag.Configurable), PropertyFlags),
};
SetProperties(properties);
}

Expand Down Expand Up @@ -92,6 +97,8 @@ internal static JsString GetAndValidateAlphabetOption(Engine engine, ObjectInsta

internal readonly record struct FromEncodingResult(byte[] Bytes, JavaScriptException? Error, int Read);

private static readonly SearchValues<char> Base64Alphabet = SearchValues.Create("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/");

internal static FromEncodingResult FromBase64(Engine engine, string input, string alphabet, string lastChunkHandling, uint maxLength = uint.MaxValue)
{
if (maxLength == 0)
Expand Down Expand Up @@ -200,10 +207,7 @@ internal static FromEncodingResult FromBase64(Engine engine, string input, strin
}
}

if (!currentChar.IsDecimalDigit()
&& !char.ToLowerInvariant(currentChar).IsInRange('a', 'z')
&& currentChar != '+'
&& currentChar != '/')
if (!Base64Alphabet.Contains(currentChar))
{
return new FromEncodingResult(bytes.ToArray(), ExceptionHelper.CreateSyntaxError(engine.Realm, "Invalid base64 character."), read);
}
Expand Down
8 changes: 4 additions & 4 deletions Jint/Pooling/ValueStringBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -192,11 +192,11 @@ public void Append(char c)
public void AppendHex(byte b)
{
const string Map = "0123456789ABCDEF";
Span<char> data = stackalloc char[]
{
ReadOnlySpan<char> data =
[
Map[b / 16],
Map[b % 16],
};
Map[b % 16]
];
Append(data);
}

Expand Down

0 comments on commit 04466d0

Please sign in to comment.