Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revert back to favoring SearchValues<char> #1990

Merged
merged 1 commit into from
Oct 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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