sebastienros / jint

Javascript Interpreter for .NET
BSD 2-Clause "Simplified" License
4.13k stars 561 forks source link

Boolean value in JsonObject cannot be work as expected #1801

Closed hyzx86 closed 8 months ago

hyzx86 commented 8 months ago

Reproduction code

        const string Json = """
        {
            "booleanValue":false,
            "trueValue":true
        }
        """;
       var variables = JsonNode.Parse(Json);

       var engine = new Engine(options =>
       {
           // make JsonArray behave like JS array
           options.Interop.WrapObjectHandler = static (e, target, type) =>
           {
               var wrapped = new ObjectWrapper(e, target);
               if (target is JsonArray)
               {
                   wrapped.Prototype = e.Intrinsics.Array.PrototypeObject;
               }
               return wrapped;
           };

           // we cannot access this[string] with anything else than JsonObject, otherwise itw will throw
           options.Interop.TypeResolver = new TypeResolver
           {
               MemberFilter = static info =>
               {
                   if (info.ReflectedType != typeof(JsonObject) && info.Name == "Item" && info is PropertyInfo p)
                   {
                       var parameters = p.GetIndexParameters();
                       return parameters.Length != 1 || parameters[0].ParameterType != typeof(string);
                   }

                   return true;
               }
           };
       });

       engine.SetValue("variables", variables);

        Assert.False(engine.Evaluate("variables.trueValue==false").AsBoolean());
        var boolObject = engine.Evaluate("variables.trueValue");
        Assert.NotNull(boolObject);// not a boolean value
        Assert.True(engine.Evaluate("variables.trueValue").AsBoolean());
        Assert.True(engine.Evaluate("variables.trueValue==true").AsBoolean());
        Assert.False((bool) variables["booleanValue"]);
        Assert.True(engine.Evaluate("variables.booleanValue==false").AsBoolean());

Originally posted by @hyzx86 in https://github.com/sebastienros/jint/issues/1767#issuecomment-1990342006

lahma commented 8 months ago

A pull request fixing the issue is most welcome.

hyzx86 commented 8 months ago

A pull request fixing the issue is most welcome.

It's no problem at all, but I haven't found a solution to this problem yet. Can you give me a hint?

var boolObject = engine.Evaluate("variables.trueValue"); boolObject.GetType();


{Name = "ObjectWrapper" FullName = "Jint.Runtime.Interop.ObjectWrapper"}
    Assembly: {Jint, Version=3.0.1.0, Culture=neutral, PublicKeyToken=2e92ba9c8d81157f}
    AssemblyQualifiedName: "Jint.Runtime.Interop.ObjectWrapper, Jint, Version=3.0.1.0, Culture=neutral, PublicKeyToken=2e92ba9c8d81157f"
    Attributes: Public | Sealed | BeforeFieldInit
    BaseType: {Name = "ObjectInstance" FullName = "Jint.Native.Object.ObjectInstance"}
    ContainsGenericParameters: false
    CustomAttributes: Count = 2
    DeclaredConstructors: {System.Reflection.ConstructorInfo[1]}
    DeclaredEvents: {System.Reflection.EventInfo[0]}
    DeclaredFields: {System.Reflection.FieldInfo[3]}
    DeclaredMembers: {System.Reflection.MemberInfo[40]}
    DeclaredMethods: {System.Reflection.MethodInfo[25]}
    DeclaredNestedTypes: {System.Reflection.TypeInfo.<get_DeclaredNestedTypes>d__22}
    DeclaredProperties: {System.Reflection.PropertyInfo[5]}
    DeclaringMethod: “((System.RuntimeType)boolObject.GetType()).DeclaringMethod”引发了类型“System.InvalidOperationException”的异常
    DeclaringType: null
    FullName: "Jint.Runtime.Interop.ObjectWrapper"
    GUID: {0dd98266-890a-34ea-bbd8-7aec05be540b}
    GenericParameterAttributes: “((System.RuntimeType)boolObject.GetType()).GenericParameterAttributes”引发了类型“System.InvalidOperationException”的异常
    GenericParameterPosition: “((System.RuntimeType)boolObject.GetType()).GenericParameterPosition”引发了类型“System.InvalidOperationException”的异常
    GenericTypeArguments: {System.Type[0]}
    GenericTypeParameters: {System.Type[0]}
    HasElementType: false
    ImplementedInterfaces: {System.Type[5]}
    IsAbstract: false
    IsAnsiClass: true
    IsArray: false
    IsAutoClass: false
    IsAutoLayout: true
    IsByRef: false
    IsByRefLike: false
    IsCOMObject: false
    IsClass: true
    IsCollectible: false
    IsConstructedGenericType: false
    IsContextful: false
    IsEnum: false
    IsExplicitLayout: false
    IsFunctionPointer: false
    IsGenericMethodParameter: false
    IsGenericParameter: false
    IsGenericType: false
    IsGenericTypeDefinition: false
    IsGenericTypeParameter: false
    IsImport: false
    IsInterface: false
    IsLayoutSequential: false
    IsMarshalByRef: false
    IsNested: false
    IsNestedAssembly: false
    IsNestedFamANDAssem: false
    IsNestedFamORAssem: false
    IsNestedFamily: false
    IsNestedPrivate: false
    IsNestedPublic: false
    IsNotPublic: false
    IsPointer: false
    IsPrimitive: false
    IsPublic: true
    IsSZArray: false
    IsSealed: true
    IsSecurityCritical: true
    IsSecuritySafeCritical: false
    IsSecurityTransparent: false
    IsSerializable: false
    IsSignatureType: false
    IsSpecialName: false
    IsTypeDefinition: true
    IsUnicodeClass: false
    IsUnmanagedFunctionPointer: false
    IsValueType: false
    IsVariableBoundArray: false
    IsVisible: true
    MemberType: TypeInfo
    MetadataToken: 33554588
    Module (System.Reflection.MemberInfo): {Jint.dll}
    Module: {Jint.dll}
    Name: "ObjectWrapper"
    Namespace: "Jint.Runtime.Interop"
    ReflectedType: null
    StructLayoutAttribute: {System.Runtime.InteropServices.StructLayoutAttribute}
    TypeHandle: {System.RuntimeTypeHandle}
    TypeInitializer: null
    UnderlyingSystemType: {Name = "ObjectWrapper" FullName = "Jint.Runtime.Interop.ObjectWrapper"}
lahma commented 8 months ago

The thing is just that, it needs investigation and it would help if you'd do the investigation 🙂

hyzx86 commented 8 months ago

Hi @sebastienros , I applied your code and found that there was another test that failed.

Use if(!jobj.falseValue) could not hit the condition.

            var result1 = scriptingEngine.Evaluate(scriptingScope,
                  @"var jobj = tryAccessJsonObject();
                var steps = [];
                if(!jobj.falseValue) steps.push(1);
                if(jobj.trueValue) steps.push(2);

                // falseValue should be false 
                if(jobj.falseValue == false) steps.push(3);
                if(jobj.trueValue == true) steps.push(4);
                if(!!jobj.trueValue) steps.push(5);
                steps.push(jobj.falseValue);
                steps.push(jobj.falseValue.toString());

             return steps.join(',')
            ");
            Assert.Equal("1,2,3,4,5,false,false", result1);//output 

Test Result :

Assert.Equal() Failure: Values differ
Expected: 1,2,3,4,5,false,false
Actual:   2,3,4,5,false,false
hyzx86 commented 8 months ago

Hi @sebastienros ,I updated the tests and they seem to be working fine 😁

https://github.com/sebastienros/jint/pull/1803

lahma commented 8 months ago

Closing as more a configuration issue.