Skip to content

Commit 04466d0

Browse files
authored
Revert back to favoring SearchValues<char> (#1990)
1 parent 7ac9805 commit 04466d0

File tree

4 files changed

+32
-29
lines changed

4 files changed

+32
-29
lines changed

Jint/Extensions/Character.cs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,13 @@ namespace Jint.Extensions;
55

66
internal static class Character
77
{
8-
[MethodImpl(MethodImplOptions.AggressiveInlining)]
9-
public static bool IsInRange(this char c, ushort min, ushort max) => (uint)(c - min) <= (uint)(max - min);
10-
118
/// <summary>
129
/// https://tc39.es/ecma262/#ASCII-word-characters
1310
/// </summary>
11+
public const string AsciiWordCharacters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_";
12+
1413
[MethodImpl(MethodImplOptions.AggressiveInlining)]
15-
public static bool IsAsciiWordCharacter(this char c) => c == '_' || c.IsDecimalDigit() || c.IsInRange('a', 'z') || c.IsInRange('A', 'Z');
14+
public static bool IsInRange(this char c, ushort min, ushort max) => (uint)(c - min) <= (uint)(max - min);
1615

1716
[MethodImpl(MethodImplOptions.AggressiveInlining)]
1817
public static bool IsOctalDigit(this char c) => c.IsInRange('0', '7');

Jint/Native/Global/GlobalObject.cs

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -274,8 +274,8 @@ private static JsValue IsFinite(JsValue thisObject, JsValue[] arguments)
274274

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

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

303-
private JsValue Encode(string uriString, SearchValues<char> unescapedUriSet)
303+
private JsValue Encode(string uriString, SearchValues<char> allowedCharacters)
304304
{
305305
var strLen = uriString.Length;
306306
var builder = new ValueStringBuilder(uriString.Length);
@@ -309,7 +309,7 @@ private JsValue Encode(string uriString, SearchValues<char> unescapedUriSet)
309309
for (var k = 0; k < strLen; k++)
310310
{
311311
var c = uriString[k];
312-
if (c.IsAsciiWordCharacter() || unescapedUriSet.Contains(c))
312+
if (allowedCharacters.Contains(c))
313313
{
314314
builder.Append(c);
315315
}
@@ -416,7 +416,7 @@ private JsValue Decode(string uriString, SearchValues<char>? reservedSet)
416416
_stringBuilder.Clear();
417417

418418
#if SUPPORTS_SPAN_PARSE
419-
Span<byte> octets = stackalloc byte[4];
419+
Span<byte> octets = stackalloc byte[4];
420420
#else
421421
var octets = new byte[4];
422422
#endif
@@ -576,36 +576,36 @@ private static bool IsDigit(char c, int radix, out int result)
576576
return tmp < radix;
577577
}
578578

579+
private static readonly SearchValues<char> EscapeAllowList = SearchValues.Create(Character.AsciiWordCharacters + "@*+-./");
580+
579581
/// <summary>
580582
/// https://tc39.es/ecma262/#sec-escape-string
581583
/// </summary>
582584
private JsValue Escape(JsValue thisObject, JsValue[] arguments)
583585
{
584586
var uriString = TypeConverter.ToString(arguments.At(0));
585587

586-
var strLen = uriString.Length;
587-
588-
_stringBuilder.EnsureCapacity(strLen);
589-
_stringBuilder.Clear();
588+
var builder = new ValueStringBuilder(uriString.Length);
590589

591-
for (var k = 0; k < strLen; k++)
590+
foreach (var c in uriString)
592591
{
593-
var c = uriString[k];
594-
if (c.IsAsciiWordCharacter() || c == '@' || c == '*' || c == '+' || c == '-' || c == '.' || c == '/')
592+
if (EscapeAllowList.Contains(c))
595593
{
596-
_stringBuilder.Append(c);
594+
builder.Append(c);
597595
}
598596
else if (c < 256)
599597
{
600-
_stringBuilder.Append('%').AppendFormat(CultureInfo.InvariantCulture, "{0:X2}", (int) c);
598+
builder.Append('%');
599+
builder.AppendHex((byte) c);
601600
}
602601
else
603602
{
604-
_stringBuilder.Append("%u").AppendFormat(CultureInfo.InvariantCulture, "{0:X4}", (int) c);
603+
builder.Append("%u");
604+
builder.Append(((int) c).ToString("X4", CultureInfo.InvariantCulture));
605605
}
606606
}
607607

608-
return _stringBuilder.ToString();
608+
return builder.ToString();
609609
}
610610

611611
/// <summary>

Jint/Native/TypedArray/TypedArrayConstructor.Uint8Array.cs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,12 @@ internal Uint8ArrayConstructor(
2222
protected override void Initialize()
2323
{
2424
const PropertyFlag PropertyFlags = PropertyFlag.Configurable | PropertyFlag.Writable;
25-
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), };
25+
var properties = new PropertyDictionary(3, checkExistingKeys: false)
26+
{
27+
["BYTES_PER_ELEMENT"] = new(new PropertyDescriptor(JsNumber.PositiveOne, PropertyFlag.AllForbidden)),
28+
["fromBase64"] = new(new ClrFunction(Engine, "fromBase64", FromBase64, 1, PropertyFlag.Configurable), PropertyFlags),
29+
["fromHex"] = new(new ClrFunction(Engine, "fromHex", FromHex, 1, PropertyFlag.Configurable), PropertyFlags),
30+
};
2631
SetProperties(properties);
2732
}
2833

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

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

100+
private static readonly SearchValues<char> Base64Alphabet = SearchValues.Create("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/");
101+
95102
internal static FromEncodingResult FromBase64(Engine engine, string input, string alphabet, string lastChunkHandling, uint maxLength = uint.MaxValue)
96103
{
97104
if (maxLength == 0)
@@ -200,10 +207,7 @@ internal static FromEncodingResult FromBase64(Engine engine, string input, strin
200207
}
201208
}
202209

203-
if (!currentChar.IsDecimalDigit()
204-
&& !char.ToLowerInvariant(currentChar).IsInRange('a', 'z')
205-
&& currentChar != '+'
206-
&& currentChar != '/')
210+
if (!Base64Alphabet.Contains(currentChar))
207211
{
208212
return new FromEncodingResult(bytes.ToArray(), ExceptionHelper.CreateSyntaxError(engine.Realm, "Invalid base64 character."), read);
209213
}

Jint/Pooling/ValueStringBuilder.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -192,11 +192,11 @@ public void Append(char c)
192192
public void AppendHex(byte b)
193193
{
194194
const string Map = "0123456789ABCDEF";
195-
Span<char> data = stackalloc char[]
196-
{
195+
ReadOnlySpan<char> data =
196+
[
197197
Map[b / 16],
198-
Map[b % 16],
199-
};
198+
Map[b % 16]
199+
];
200200
Append(data);
201201
}
202202

0 commit comments

Comments
 (0)