Forráskód Böngészése

Merge pull request #68 from honestegg/add-timeout

Add Timeout option to the engine
Sébastien Ros 11 éve
szülő
commit
33e172354c
3 módosított fájl, 33 hozzáadás és 0 törlés
  1. 8 0
      Jint.Tests/Runtime/EngineTests.cs
  2. 13 0
      Jint/Engine.cs
  3. 12 0
      Jint/Options.cs

+ 8 - 0
Jint.Tests/Runtime/EngineTests.cs

@@ -605,6 +605,14 @@ namespace Jint.Tests.Runtime
             );
         }
 
+        [Fact]
+        public void ShouldThrowTimeout()
+        {
+            Assert.Throws<TimeoutException>(
+                () => new Engine(cfg => cfg.TimeoutInterval(new TimeSpan(0,0,0,0,500))).Execute("while(true);")
+            );
+        }
+
         [Fact]
         public void ShouldConvertDoubleToStringWithoutLosingPrecision()
         {

+ 13 - 0
Jint/Engine.cs

@@ -32,6 +32,7 @@ namespace Jint
         private readonly Stack<ExecutionContext> _executionContexts;
         private JsValue _completionValue = JsValue.Undefined;
         private int _statementsCount;
+        private long _timeoutTicks;
         private SyntaxNode _lastSyntaxNode = null;
 
         // cache of types used when resolving CLR type names
@@ -216,6 +217,12 @@ namespace Jint
             _statementsCount = 0;
         }
 
+        public void ResetTimeoutTicks()
+        {
+            var timeoutIntervalTicks = Options.GetTimeoutInterval().Ticks;
+            _timeoutTicks = timeoutIntervalTicks > 0 ? DateTime.UtcNow.Ticks + timeoutIntervalTicks : 0;
+        }
+
         public Engine Execute(string source)
         {
             var parser = new JavaScriptParser();
@@ -231,6 +238,7 @@ namespace Jint
         public Engine Execute(Program program)
         {
             ResetStatementsCount();
+            ResetTimeoutTicks();
             ResetLastStatement();
 
             using (new StrictModeScope(Options.IsStrict() || program.Strict))
@@ -270,6 +278,11 @@ namespace Jint
                 throw new StatementsCountOverflowException();
             }
 
+            if (_timeoutTicks > 0 && _timeoutTicks < DateTime.UtcNow.Ticks)
+            {
+                throw new TimeoutException();
+            }
+
             _lastSyntaxNode = statement;
 
             switch (statement.Type)

+ 12 - 0
Jint/Options.cs

@@ -17,6 +17,7 @@ namespace Jint
         private ITypeConverter _typeConverter = new DefaultTypeConverter();
         private readonly List<IObjectConverter> _objectConverters = new List<IObjectConverter>();
         private int _maxStatements;
+        private TimeSpan _timeoutInterval;
         private CultureInfo _culture = CultureInfo.CurrentCulture;
         private TimeZoneInfo _localTimeZone = TimeZoneInfo.Local;
         private List<Assembly> _lookupAssemblies = new List<Assembly>(); 
@@ -88,6 +89,12 @@ namespace Jint
             return this;
         }
 
+        public Options TimeoutInterval(TimeSpan timeoutInterval)
+        {
+            _timeoutInterval = timeoutInterval;
+            return this;
+        }
+
         public Options Culture(CultureInfo cultureInfo)
         {
             _culture = cultureInfo;
@@ -140,6 +147,11 @@ namespace Jint
             return _maxStatements;
         }
 
+        internal TimeSpan GetTimeoutInterval()
+        {
+            return _timeoutInterval;
+        }
+
         internal CultureInfo GetCulture()
         {
             return _culture;