Skip to content

Commit a37f39c

Browse files
authored
Fix custom reference resolver argument (#1938)
1 parent 0ffda10 commit a37f39c

File tree

2 files changed

+79
-6
lines changed

2 files changed

+79
-6
lines changed

Jint.Tests.PublicInterface/RavenApiUsageTests.cs

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,36 @@ public void CanResetCallStack()
201201
var engine = new Engine();
202202
engine.Advanced.ResetCallStack();
203203
}
204+
205+
[Fact]
206+
public void CanUseCustomReferenceResolver()
207+
{
208+
var engine = new Engine(options =>
209+
{
210+
options.ReferenceResolver = new MyReferenceResolver();
211+
});
212+
213+
engine
214+
.Execute("""
215+
function output(doc) {
216+
var rows123 = [{}];
217+
var test = null;
218+
return {
219+
Rows : [{}].map(row=>({row:row, myRows:test.filter(x=>x)
220+
})).map(__rvn4=>({
221+
Custom:__rvn4.myRows[0].Custom,
222+
Custom2:__rvn4.myRows
223+
}))
224+
};
225+
}
226+
""");
227+
228+
var result = engine.Evaluate("output()");
229+
230+
var rows = result.AsObject()["Rows"];
231+
var custom = rows.AsArray()[0].AsObject()["Custom"];
232+
Assert.Equal(JsValue.Null, custom);
233+
}
204234
}
205235

206236
file sealed class CustomString : JsString
@@ -287,3 +317,35 @@ public override string ToString()
287317
return "null";
288318
}
289319
}
320+
321+
file sealed class MyReferenceResolver : IReferenceResolver
322+
{
323+
public bool TryUnresolvableReference(Engine engine, Reference reference, out JsValue value)
324+
{
325+
JsValue referencedName = reference.ReferencedName;
326+
327+
if (referencedName.IsString())
328+
{
329+
value = reference.IsPropertyReference ? JsValue.Undefined : JsValue.Null;
330+
return true;
331+
}
332+
333+
throw new InvalidOperationException();
334+
}
335+
336+
public bool TryPropertyReference(Engine engine, Reference reference, ref JsValue value)
337+
{
338+
return value.IsNull() || value.IsUndefined();
339+
}
340+
341+
public bool TryGetCallable(Engine engine, object callee, out JsValue value)
342+
{
343+
value = new ClrFunction(engine, "function", static (_, _) => JsValue.Undefined);
344+
return true;
345+
}
346+
347+
public bool CheckCoercible(JsValue value)
348+
{
349+
return true;
350+
}
351+
}

Jint/Engine.cs

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
using System.Diagnostics;
2-
using System.Collections.Concurrent;
2+
using System.Collections.Concurrent;
33
using System.Diagnostics.CodeAnalysis;
44
using System.Runtime.CompilerServices;
55
using Jint.Native;
@@ -50,7 +50,10 @@ public sealed partial class Engine : IDisposable
5050
internal readonly Constraint[] _constraints;
5151
internal readonly bool _isDebugMode;
5252
internal readonly bool _isStrict;
53+
54+
private bool _customResolver;
5355
internal readonly IReferenceResolver _referenceResolver;
56+
5457
internal readonly ReferencePool _referencePool;
5558
internal readonly ArgumentsInstancePool _argumentsInstancePool;
5659
internal readonly JsValueArrayPool _jsValueArrayPool;
@@ -135,6 +138,7 @@ private Engine(Options? options, Action<Engine, Options>? configure)
135138

136139
_constraints = Options.Constraints.Constraints.ToArray();
137140
_referenceResolver = Options.ReferenceResolver;
141+
_customResolver = !ReferenceEquals(_referenceResolver, DefaultReferenceResolver.Instance);
138142

139143
_referencePool = new ReferencePool();
140144
_argumentsInstancePool = new ArgumentsInstancePool(this);
@@ -564,18 +568,25 @@ internal JsValue GetValue(Reference reference, bool returnReferenceToPool)
564568

565569
if (baseValue.IsUndefined())
566570
{
567-
if (_referenceResolver.TryUnresolvableReference(this, reference, out var val))
571+
if (_customResolver)
568572
{
569-
return val;
573+
reference.EvaluateAndCachePropertyKey();
574+
if (_referenceResolver.TryUnresolvableReference(this, reference, out var val))
575+
{
576+
return val;
577+
}
570578
}
571579

572580
ExceptionHelper.ThrowReferenceError(Realm, reference);
573581
}
574582

575-
if ((baseValue._type & InternalTypes.ObjectEnvironmentRecord) == InternalTypes.Empty
576-
&& _referenceResolver.TryPropertyReference(this, reference, ref baseValue))
583+
if ((baseValue._type & InternalTypes.ObjectEnvironmentRecord) == InternalTypes.Empty && _customResolver)
577584
{
578-
return baseValue;
585+
reference.EvaluateAndCachePropertyKey();
586+
if (_referenceResolver.TryPropertyReference(this, reference, ref baseValue))
587+
{
588+
return baseValue;
589+
}
579590
}
580591

581592
if (reference.IsPropertyReference)

0 commit comments

Comments
 (0)