DefaultModuleLoader.cs 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. #nullable enable
  2. using System;
  3. using System.IO;
  4. using Esprima;
  5. using Esprima.Ast;
  6. namespace Jint.Runtime.Modules;
  7. public class DefaultModuleLoader : IModuleLoader
  8. {
  9. private readonly string _basePath;
  10. public DefaultModuleLoader(string basePath)
  11. {
  12. _basePath = basePath;
  13. }
  14. public virtual ModuleLoaderResult LoadModule(Engine engine, string location, string? referencingLocation)
  15. {
  16. // If no referencing location is provided, ensure location is absolute
  17. var locationUri = referencingLocation == null
  18. ? new Uri(location, UriKind.Absolute)
  19. : new Uri(new Uri(referencingLocation, UriKind.Absolute), location)
  20. ;
  21. // Ensure the resulting resource is under the base path if it is provided
  22. if (!String.IsNullOrEmpty(_basePath) && !locationUri.AbsolutePath.StartsWith(_basePath, StringComparison.Ordinal))
  23. {
  24. ExceptionHelper.ThrowArgumentException("Invalid file location.");
  25. }
  26. return LoadModule(engine, locationUri);
  27. }
  28. protected virtual ModuleLoaderResult LoadModule(Engine engine, Uri location)
  29. {
  30. var code = LoadModuleSourceCode(location);
  31. Module module;
  32. try
  33. {
  34. var parserOptions = new ParserOptions(location.ToString())
  35. {
  36. AdaptRegexp = true,
  37. Tolerant = true
  38. };
  39. module = new JavaScriptParser(code, parserOptions).ParseModule();
  40. }
  41. catch (ParserException ex)
  42. {
  43. ExceptionHelper.ThrowSyntaxError(engine.Realm, $"Error while loading module: error in module '{location}': {ex.Error}");
  44. module = null;
  45. }
  46. return new ModuleLoaderResult(module, location);
  47. }
  48. protected virtual string LoadModuleSourceCode(Uri location)
  49. {
  50. if (!location.IsFile)
  51. {
  52. ExceptionHelper.ThrowArgumentException("Only file loading is supported");
  53. }
  54. return File.ReadAllText(location.AbsolutePath);
  55. }
  56. }