2
0

InteropTests.MemberAccess.cs 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. using System;
  2. using Jint.Native;
  3. using Jint.Runtime.Interop;
  4. using Jint.Tests.Runtime.Domain;
  5. using Xunit;
  6. namespace Jint.Tests.Runtime
  7. {
  8. public partial class InteropTests
  9. {
  10. [Fact]
  11. public void ShouldHideSpecificMembers()
  12. {
  13. var engine = new Engine(options => options.SetMemberAccessor((e, target, member) =>
  14. {
  15. if (target is HiddenMembers)
  16. {
  17. if (member == nameof(HiddenMembers.Member2) || member == nameof(HiddenMembers.Method2))
  18. {
  19. return JsValue.Undefined;
  20. }
  21. }
  22. return null;
  23. }));
  24. engine.SetValue("m", new HiddenMembers());
  25. Assert.Equal("Member1", engine.Evaluate("m.Member1").ToString());
  26. Assert.Equal("undefined", engine.Evaluate("m.Member2").ToString());
  27. Assert.Equal("Method1", engine.Evaluate("m.Method1()").ToString());
  28. // check the method itself, not its invokation as it would mean invoking "undefined"
  29. Assert.Equal("undefined", engine.Evaluate("m.Method2").ToString());
  30. }
  31. [Fact]
  32. public void ShouldOverrideMembers()
  33. {
  34. var engine = new Engine(options => options.SetMemberAccessor((e, target, member) =>
  35. {
  36. if (target is HiddenMembers && member == nameof(HiddenMembers.Member1))
  37. {
  38. return "Orange";
  39. }
  40. return null;
  41. }));
  42. engine.SetValue("m", new HiddenMembers());
  43. Assert.Equal("Orange", engine.Evaluate("m.Member1").ToString());
  44. }
  45. [Fact]
  46. public void ShouldBeAbleToFilterMembers()
  47. {
  48. var engine = new Engine(options => options
  49. .SetTypeResolver(new TypeResolver
  50. {
  51. MemberFilter = member => !Attribute.IsDefined(member, typeof(ObsoleteAttribute))
  52. })
  53. );
  54. engine.SetValue("m", new HiddenMembers());
  55. Assert.True(engine.Evaluate("m.Field1").IsUndefined());
  56. Assert.True(engine.Evaluate("m.Member1").IsUndefined());
  57. Assert.True(engine.Evaluate("m.Method1").IsUndefined());
  58. Assert.True(engine.Evaluate("m.Field2").IsString());
  59. Assert.True(engine.Evaluate("m.Member2").IsString());
  60. Assert.True(engine.Evaluate("m.Method2()").IsString());
  61. // we forbid GetType by default
  62. Assert.True(engine.Evaluate("m.GetType").IsUndefined());
  63. }
  64. [Fact]
  65. public void ShouldBeAbleToExposeGetType()
  66. {
  67. var engine = new Engine(options =>
  68. {
  69. options.Interop.AllowGetType = true;
  70. options.Interop.AllowSystemReflection = true;
  71. });
  72. engine.SetValue("m", new HiddenMembers());
  73. Assert.True(engine.Evaluate("m.GetType").IsCallable());
  74. // reflection could bypass some safeguards
  75. Assert.Equal("Method1", engine.Evaluate("m.GetType().GetMethod('Method1').Invoke(m, [])").AsString());
  76. }
  77. [Fact]
  78. public void ShouldProtectFromReflectionServiceUsage()
  79. {
  80. var engine = new Engine();
  81. engine.SetValue("m", new HiddenMembers());
  82. // we can get a type reference if it's exposed via property, bypassing GetType
  83. var type = engine.Evaluate("m.Type");
  84. Assert.IsType<ObjectWrapper>(type);
  85. var ex = Assert.Throws<InvalidOperationException>(() => engine.Evaluate("m.Type.Module.GetType().Module.GetType('System.DateTime')"));
  86. Assert.Equal("Cannot access System.Reflection namespace, check Engine's interop options", ex.Message);
  87. }
  88. [Fact]
  89. public void TypeReferenceShouldUseTypeResolverConfiguration()
  90. {
  91. var engine = new Engine(options =>
  92. {
  93. options.SetTypeResolver(new TypeResolver
  94. {
  95. MemberFilter = member => !Attribute.IsDefined(member, typeof(ObsoleteAttribute))
  96. });
  97. });
  98. engine.SetValue("EchoService", TypeReference.CreateTypeReference(engine, typeof(EchoService)));
  99. Assert.Equal("anyone there", engine.Evaluate("EchoService.Echo('anyone there')").AsString());
  100. Assert.Equal("anyone there", engine.Evaluate("EchoService.echo('anyone there')").AsString());
  101. Assert.True(engine.Evaluate("EchoService.ECHO").IsUndefined());
  102. Assert.True(engine.Evaluate("EchoService.Hidden").IsUndefined());
  103. }
  104. private static class EchoService
  105. {
  106. public static string Echo(string message) => message;
  107. [Obsolete]
  108. public static string Hidden(string message) => message;
  109. }
  110. }
  111. }