Skip to content

Commit

Permalink
(breaking) Prevent access of static CLR members on object instances (s…
Browse files Browse the repository at this point in the history
  • Loading branch information
TeamDoodz committed Oct 13, 2024
1 parent df7589b commit 8798f18
Show file tree
Hide file tree
Showing 9 changed files with 37 additions and 0 deletions.
4 changes: 4 additions & 0 deletions Jint/Runtime/Interop/ObjectWrapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,10 @@ private PropertyDescriptor GetOwnProperty(JsValue property, bool mustBeReadable,
{
accessor = _engine.Options.Interop.TypeResolver.GetAccessor(_engine, Target.GetType(), member, mustBeReadable, mustBeWritable);
}
if (accessor.IsStatic)
{
return PropertyDescriptor.Undefined;
}
var descriptor = accessor.CreatePropertyDescriptor(_engine, Target, member, enumerable: !isDictionary);
if (!isDictionary
&& !ReferenceEquals(descriptor, PropertyDescriptor.Undefined)
Expand Down
2 changes: 2 additions & 0 deletions Jint/Runtime/Interop/Reflection/ConstantValueAccessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ public ConstantValueAccessor(JsValue? value) : base(null!, null!)

protected override JsValue? ConstantValue { get; }

public override bool IsStatic => true;

protected override object? DoGetValue(object? target, string memberName)
{
return ConstantValue;
Expand Down
2 changes: 2 additions & 0 deletions Jint/Runtime/Interop/Reflection/DynamicObjectAccessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ public DynamicObjectAccessor() : base(memberType: null)

public override bool Writable => true;

public override bool IsStatic => false;

protected override object? DoGetValue(object? target, string memberName)
{
Debug.Assert(target is not null);
Expand Down
2 changes: 2 additions & 0 deletions Jint/Runtime/Interop/Reflection/FieldAccessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ public FieldAccessor(FieldInfo fieldInfo, PropertyInfo? indexer = null)

public override bool Writable => (_fieldInfo.Attributes & FieldAttributes.InitOnly) == (FieldAttributes) 0;

public override bool IsStatic => _fieldInfo.IsStatic;

protected override object? DoGetValue(object? target, string memberName)
{
return _fieldInfo.GetValue(target);
Expand Down
2 changes: 2 additions & 0 deletions Jint/Runtime/Interop/Reflection/IndexerAccessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,8 @@ internal static bool TryFindIndexer(

public override bool Writable => Indexer.CanWrite;

public override bool IsStatic => (_getter ?? _setter)!.IsStatic;

protected override object? DoGetValue(object? target, string memberName)
{
if (_getter is null)
Expand Down
5 changes: 5 additions & 0 deletions Jint/Runtime/Interop/Reflection/MethodAccessor.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Linq;
using Jint.Runtime.Descriptors;

namespace Jint.Runtime.Interop.Reflection;
Expand All @@ -6,15 +7,19 @@ internal sealed class MethodAccessor : ReflectionAccessor
{
private readonly Type _targetType;
private readonly MethodDescriptor[] _methods;
private readonly bool _isStatic;

public MethodAccessor(Type targetType, MethodDescriptor[] methods) : base(null!)
{
_targetType = targetType;
_methods = methods;
_isStatic = _methods.Any(x => x.Method.IsStatic);
}

public override bool Writable => false;

public override bool IsStatic => _isStatic;

protected override object? DoGetValue(object? target, string memberName) => null;

protected override void DoSetValue(object? target, string memberName, object? value)
Expand Down
2 changes: 2 additions & 0 deletions Jint/Runtime/Interop/Reflection/NestedTypeAccessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ public NestedTypeAccessor(TypeReference typeReference) : base(typeof(Type))

public override bool Writable => false;

public override bool IsStatic => true;

protected override object? DoGetValue(object? target, string memberName) => null;

protected override void DoSetValue(object? target, string memberName, object? value) { }
Expand Down
4 changes: 4 additions & 0 deletions Jint/Runtime/Interop/Reflection/PropertyAccessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,23 @@ namespace Jint.Runtime.Interop.Reflection;
internal sealed class PropertyAccessor : ReflectionAccessor
{
private readonly PropertyInfo _propertyInfo;
private readonly bool _isStatic;

public PropertyAccessor(
PropertyInfo propertyInfo,
PropertyInfo? indexerToTry = null)
: base(propertyInfo.PropertyType, indexerToTry)
{
_propertyInfo = propertyInfo;
_isStatic = (_propertyInfo.GetGetMethod() ?? _propertyInfo.GetSetMethod())!.IsStatic;
}

public override bool Readable => _propertyInfo.CanRead;

public override bool Writable => _propertyInfo.CanWrite;

public override bool IsStatic => _isStatic;

protected override object? DoGetValue(object? target, string memberName)
{
return _propertyInfo.GetValue(target, index: null);
Expand Down
14 changes: 14 additions & 0 deletions Jint/Runtime/Interop/Reflection/ReflectionAccessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,20 @@ protected ReflectionAccessor(

public abstract bool Writable { get; }

public abstract bool IsStatic { get; }

protected abstract object? DoGetValue(object? target, string memberName);

protected abstract void DoSetValue(object? target, string memberName, object? value);

public object? GetValue(Engine engine, object? target, string memberName)
{
if (target == null && !IsStatic)
{
ExceptionHelper.ThrowInvalidOperationException("Cannot access a non-static member with a null target.");
return null;
}

var constantValue = ConstantValue;
if (constantValue is not null)
{
Expand Down Expand Up @@ -87,6 +95,12 @@ protected ReflectionAccessor(

public void SetValue(Engine engine, object? target, string memberName, JsValue value)
{
if (target == null && !IsStatic)
{
ExceptionHelper.ThrowInvalidOperationException("Cannot access a non-static member with a null target.");
return;
}

object? converted;
if (_memberType == typeof(JsValue))
{
Expand Down

0 comments on commit 8798f18

Please sign in to comment.