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

Fix extension and class methods being enumerated #959

Merged
merged 1 commit into from
Sep 18, 2021
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
86 changes: 62 additions & 24 deletions Jint.Tests/Runtime/InteropTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ public void EngineShouldStringifyADictionaryOfStringAndObjectCorrectly()
{
var engine = new Engine();

var dictionary = new Dictionary<string,object> {
var dictionary = new Dictionary<string, object> {
{ "foo", 5 },
{ "bar", "A string"},
};
Expand Down Expand Up @@ -705,7 +705,7 @@ public void ShouldCallInstanceMethodWithString()
[Fact]
public void CanUseTrim()
{
var p = new Person { Name = "Mickey Mouse "};
var p = new Person { Name = "Mickey Mouse " };
_engine.SetValue("p", p);

RunTest(@"
Expand Down Expand Up @@ -860,10 +860,10 @@ public void ShouldConvertArrayToArrayInstance()
var parts = result.ToObject();

Assert.True(parts.GetType().IsArray);
Assert.Equal(3, ((object[])parts).Length);
Assert.Equal(2d, ((object[])parts)[0]);
Assert.Equal(4d, ((object[])parts)[1]);
Assert.Equal(6d, ((object[])parts)[2]);
Assert.Equal(3, ((object[]) parts).Length);
Assert.Equal(2d, ((object[]) parts)[0]);
Assert.Equal(4d, ((object[]) parts)[1]);
Assert.Equal(6d, ((object[]) parts)[2]);
}

[Fact]
Expand All @@ -876,10 +876,10 @@ public void ShouldConvertListsToArrayInstance()
var parts = result.ToObject();

Assert.True(parts.GetType().IsArray);
Assert.Equal(3, ((object[])parts).Length);
Assert.Equal(2d, ((object[])parts)[0]);
Assert.Equal(4d, ((object[])parts)[1]);
Assert.Equal(6d, ((object[])parts)[2]);
Assert.Equal(3, ((object[]) parts).Length);
Assert.Equal(2d, ((object[]) parts)[0]);
Assert.Equal(4d, ((object[]) parts)[1]);
Assert.Equal(6d, ((object[]) parts)[2]);
}

[Fact]
Expand All @@ -888,9 +888,9 @@ public void ShouldConvertArrayInstanceToArray()
var parts = _engine.Evaluate("'foo@bar.com'.split('@');").ToObject();

Assert.True(parts.GetType().IsArray);
Assert.Equal(2, ((object[])parts).Length);
Assert.Equal("foo", ((object[])parts)[0]);
Assert.Equal("bar.com", ((object[])parts)[1]);
Assert.Equal(2, ((object[]) parts).Length);
Assert.Equal("foo", ((object[]) parts)[0]);
Assert.Equal("bar.com", ((object[]) parts)[1]);
}

[Fact]
Expand Down Expand Up @@ -964,7 +964,7 @@ public void ShouldConvertObjectInstanceToExpando()
Assert.Equal(1, value.a);
Assert.Equal("foo", value.b);

var dic = (IDictionary<string, object>)result.ToObject();
var dic = (IDictionary<string, object>) result.ToObject();

Assert.Equal(1d, dic["a"]);
Assert.Equal("foo", dic["b"]);
Expand Down Expand Up @@ -1278,12 +1278,12 @@ public void CanSetCustomConverters()
var engine1 = new Engine();
engine1.SetValue("p", new { Test = true });
engine1.Execute("var result = p.Test;");
Assert.True((bool)engine1.GetValue("result").ToObject());
Assert.True((bool) engine1.GetValue("result").ToObject());

var engine2 = new Engine(o => o.AddObjectConverter(new NegateBoolConverter()));
engine2.SetValue("p", new { Test = true });
engine2.Execute("var result = p.Test;");
Assert.False((bool)engine2.GetValue("result").ToObject());
Assert.False((bool) engine2.GetValue("result").ToObject());

}

Expand All @@ -1295,7 +1295,7 @@ public void CanConvertEnumsToString()
engine1.SetValue("p", new { Comparison = StringComparison.CurrentCulture });
engine1.Execute("assert(p.Comparison === 'CurrentCulture');");
engine1.Execute("var result = p.Comparison;");
Assert.Equal("CurrentCulture", (string)engine1.GetValue("result").ToObject());
Assert.Equal("CurrentCulture", (string) engine1.GetValue("result").ToObject());
}

[Fact]
Expand Down Expand Up @@ -1526,7 +1526,7 @@ public void ShouldUseExplicitPropertyGetter()
public void ShouldUseExplicitIndexerPropertyGetter()
{
var company = new Company("ACME");
((ICompany)company)["Foo"] = "Bar";
((ICompany) company)["Foo"] = "Bar";
_engine.SetValue("c", company);

RunTest(@"
Expand All @@ -1549,7 +1549,7 @@ public void ShouldUseExplicitPropertySetter()
public void ShouldUseExplicitIndexerPropertySetter()
{
var company = new Company("ACME");
((ICompany)company)["Foo"] = "Bar";
((ICompany) company)["Foo"] = "Bar";
_engine.SetValue("c", company);

RunTest(@"
Expand Down Expand Up @@ -1646,7 +1646,7 @@ public void ShouldCallMethodWithNull()
public void ShouldReturnUndefinedProperty()
{
_engine.SetValue("uo", new { foo = "bar" });
_engine.SetValue("ud", new Dictionary<string, object> { {"foo", "bar"} });
_engine.SetValue("ud", new Dictionary<string, object> { { "foo", "bar" } });
_engine.SetValue("ul", new List<string> { "foo", "bar" });

RunTest(@"
Expand Down Expand Up @@ -2078,7 +2078,7 @@ public void ArrayFromShouldConvertListToArrayLike()
[Fact]
public void ArrayFromShouldConvertArrayToArrayLike()
{
var list = new []
var list = new[]
{
new Person {Name = "Mike"},
new Person {Name = "Mika"}
Expand All @@ -2103,7 +2103,7 @@ public void ArrayFromShouldConvertArrayToArrayLike()
[Fact]
public void ArrayFromShouldConvertIEnumerable()
{
var enumerable = new []
var enumerable = new[]
{
new Person {Name = "Mike"},
new Person {Name = "Mika"}
Expand Down Expand Up @@ -2148,7 +2148,7 @@ public void ShouldNotResolveToPrimitiveSymbol()
");

Assert.NotNull(c.ToString());
Assert.Equal((uint)0, c.As<ObjectInstance>().Length);
Assert.Equal((uint) 0, c.As<ObjectInstance>().Length);
}

class DictionaryWrapper
Expand Down Expand Up @@ -2524,7 +2524,7 @@ public void ObjectWrapperWrappingDictionaryShouldNotBeArrayLike()
[Fact]
public void ShouldHandleCyclicReferences()
{
var engine=new Engine();
var engine = new Engine();

static void Test(string message, object value) { Console.WriteLine(message); }

Expand Down Expand Up @@ -2583,5 +2583,43 @@ public void CanConfigurePropertyNameMatcher()
Assert.True(e.Evaluate("a.Call1").IsObject());
Assert.True(e.Evaluate("a.CALL1").IsObject());
}

[Fact]
public void ShouldNotEnumerateClassMethods()
{
var engine = new Engine();

var dictionary = new Dictionary<string, object> {
{ "foo", 5 },
{ "bar", "A string"},
};
engine.SetValue("dictionary", dictionary);

var result = engine.Evaluate($"Object.keys(dictionary).join(',')").AsString();
Assert.Equal("foo,bar", result);


engine.Execute("dictionary.ContainsKey('foo')");
result = engine.Evaluate($"Object.keys(dictionary).join(',')").AsString();
Assert.Equal("foo,bar", result);
}

[Fact]
public void ShouldNotEnumerateExtensionMethods()
{
var engine = new Engine(cfg => cfg.AddExtensionMethods(typeof(Enumerable)));

var result = engine.Evaluate("Object.keys({ ...[1,2,3] }).join(',')").AsString();
Assert.Equal("0,1,2", result);

var script = @"
var arr = [1,2,3];
var keys = [];
for(var index in arr) keys.push(index);
keys.join(',');
";
result = engine.Evaluate(script).ToString();
Assert.Equal("0,1,2", result);
}
}
}
2 changes: 1 addition & 1 deletion Jint/Options.cs
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ PropertyDescriptor CreateMethodInstancePropertyDescriptor(ClrFunctionInstance? f
? new MethodInfoFunctionInstance(engine, MethodDescriptor.Build(overloads.ToList()))
: new MethodInfoFunctionInstance(engine, MethodDescriptor.Build(overloads.ToList()), function);

return new PropertyDescriptor(instance, PropertyFlag.NonConfigurable);
return new PropertyDescriptor(instance, PropertyFlag.AllForbidden);
}

JsValue key = overloads.Key;
Expand Down
6 changes: 3 additions & 3 deletions Jint/Runtime/Interop/Reflection/MethodAccessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public MethodAccessor(MethodDescriptor[] methods) : base(null, null)
}

public override bool Writable => false;

protected override object DoGetValue(object target)
{
return null;
Expand All @@ -24,7 +24,7 @@ protected override void DoSetValue(object target, object value)

public override PropertyDescriptor CreatePropertyDescriptor(Engine engine, object target)
{
return new(new MethodInfoFunctionInstance(engine, _methods), PropertyFlag.OnlyEnumerable);
return new(new MethodInfoFunctionInstance(engine, _methods), PropertyFlag.AllForbidden);
}
}
}
}