Browse Source

Implemented escape function on global object. (#382)

Fixes #380
girishjjain 8 years ago
parent
commit
541909a11d
2 changed files with 50 additions and 0 deletions
  1. 20 0
      Jint.Tests/Runtime/EngineTests.cs
  2. 30 0
      Jint/Native/Global/GlobalObject.cs

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

@@ -1901,5 +1901,25 @@ namespace Jint.Tests.Runtime
 
             Assert.True(val.AsString() == "53.6841659");
         }
+		
+        [Theory]
+        [InlineData("", "escape('')")]
+        [InlineData("%u0100%u0101%u0102", "escape('\u0100\u0101\u0102')")]
+        [InlineData("%uFFFD%uFFFE%uFFFF", "escape('\ufffd\ufffe\uffff')")]
+        [InlineData("%uD834%uDF06", "escape('\ud834\udf06')")]
+        [InlineData("%00%01%02%03", "escape('\x00\x01\x02\x03')")]
+        [InlineData("%2C", "escape(',')")]
+        [InlineData("%3A%3B%3C%3D%3E%3F", "escape(':;<=>?')")]
+        [InlineData("%60", "escape('`')")]
+        [InlineData("%7B%7C%7D%7E%7F%80", "escape('{|}~\x7f\x80')")]
+        [InlineData("%FD%FE%FF", "escape('\xfd\xfe\xff')")]
+        [InlineData("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789@*_+-./", "escape('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789@*_+-./')")]
+        public void ShouldEvaluateEscape(object expected, string source)
+        {
+            var engine = new Engine();
+            var result = engine.Execute(source).GetCompletionValue().ToObject();
+
+            Assert.Equal(expected, result);
+        }
     }
 }

+ 30 - 0
Jint/Native/Global/GlobalObject.cs

@@ -59,6 +59,7 @@ namespace Jint.Native.Global
             FastAddProperty("decodeURIComponent", new ClrFunctionInstance(Engine, DecodeUriComponent, 1), true, false, true);
             FastAddProperty("encodeURI", new ClrFunctionInstance(Engine, EncodeUri, 1), true, false, true);
             FastAddProperty("encodeURIComponent", new ClrFunctionInstance(Engine, EncodeUriComponent, 1), true, false, true);
+            FastAddProperty("escape", new ClrFunctionInstance(Engine, Escape, 1), true, false, true);
         }
 
         /// <summary>
@@ -598,5 +599,34 @@ namespace Jint.Native.Global
             return R.ToString();
         }
 
+        /// <summary>
+        /// http://www.ecma-international.org/ecma-262/5.1/#sec-B.2.2
+        /// </summary>
+        public JsValue Escape(JsValue thisObject, JsValue[] arguments)
+        {
+            const string whiteList = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789@*_ + -./";
+            var uriString = TypeConverter.ToString(arguments.At(0));
+
+            var strLen = uriString.Length;
+            var r = new StringBuilder(strLen);
+            for (var k = 0; k < strLen; k++)
+            {
+                var c = uriString[k];
+                if (whiteList.IndexOf(c) != -1)
+                {
+                    r.Append(c);
+                }
+                else if (c < 256)
+                {
+                    r.Append(string.Format("%{0}", ((int)c).ToString("X2")));
+                }
+                else
+                {
+                    r.Append(string.Format("%u{0}", ((int)c).ToString("X4")));
+                }
+            }
+
+            return r.ToString();
+        }		
     }
 }