示例#1
0
        public void SafeXhtml_cleanses_Audio_src_attribute()
        {
            XDoc doc = XDocFactory.From("<doc><audio src=\"javascript://\" poster=\"javascript://\" autoplay=\"\" loop=\"\" controls=\"\"></audio></doc>", MimeType.TEXT_XML);

            DekiScriptLibrary.ValidateXHtml(doc, true, true);
            Assert.AreEqual("<doc><audio autoplay=\"\" loop=\"\" controls=\"\"></audio></doc>", doc.ToString());
        }
示例#2
0
        public void UnSafeXhtml_cleanses_Audio_element()
        {
            XDoc doc = XDocFactory.From("<doc><audio src=\"\" poster=\"\" onloadstart=\"\" onprogress=\"\" unsafe=\"\"></audio></doc>", MimeType.TEXT_XML);

            DekiScriptLibrary.ValidateXHtml(doc, false, true);
            Assert.AreEqual("<doc><audio src=\"\" onloadstart=\"\" onprogress=\"\"></audio></doc>", doc.ToString());
        }
示例#3
0
        public void SafeXhtml_cleanses_Video_element()
        {
            XDoc doc = XDocFactory.From("<doc><video src=\"\" poster=\"\" autoplay=\"\" loop=\"\" controls=\"\" width=\"\" height=\"\" onloadstart=\"\" onprogress=\"\"></video></doc>", MimeType.TEXT_XML);

            DekiScriptLibrary.ValidateXHtml(doc, true, true);
            Assert.AreEqual("<doc><video src=\"\" poster=\"\" autoplay=\"\" loop=\"\" controls=\"\" width=\"\" height=\"\"></video></doc>", doc.ToString());
        }
示例#4
0
        public void UnSafeXhtml_cleanses_Video_with_sources()
        {
            XDoc doc = XDocFactory.From("<doc><video poster=\"\" onloadstart=\"\" onprogress=\"\"><source src=\"\" unsafe=\"\"/></video></doc>", MimeType.TEXT_XML);

            DekiScriptLibrary.ValidateXHtml(doc, false, true);
            Assert.AreEqual("<doc><video poster=\"\" onloadstart=\"\" onprogress=\"\"><source src=\"\" /></video></doc>", doc.ToString());
        }
        public XDoc WebXml(
            [DekiExtParam("XML source text or source uri")] string source,
            [DekiExtParam("xpath to value (default: none)", true)] string xpath,
            [DekiExtParam("namespaces (default: none)300+", true)] Hashtable namespaces,
            [DekiExtParam("caching duration in seconds (range: 300+; default: 300)", true)] double?ttl,
            [DekiExtParam("return nil if source could not be loaded (default: text with error message)", true)] bool?nilIfMissing
            )
        {
            string text = WebText(source, xpath, namespaces, true, ttl, nilIfMissing);

            if (text == null)
            {
                return(null);
            }
            XDoc result = XDocFactory.From(text, MimeType.XML);

            if (result.IsEmpty)
            {
                // try again assuming the input is HTML
                if (text.TrimStart().StartsWith("<"))
                {
                    result = XDocFactory.From(text, MimeType.HTML);
                }
                else
                {
                    // wrap response into a valid HTML document
                    result = new XDoc("html").Elem("body", text);
                }
            }
            if (result.HasName("html"))
            {
                result = DekiScriptLibrary.CleanseHtmlDocument(result);
            }
            return(result);
        }
        public DekiScriptOutputBuffer.Range Visit(DekiScriptTryCatchFinally expr, DekiScriptExpressionEvaluationState state)
        {
            int marker = state.Buffer.Marker;

            try {
                expr.Try.VisitWith(this, state);
            } catch (DekiScriptFatalException) {
                throw;
            } catch (DekiScriptControlFlowException) {
                throw;
            } catch (Exception e) {
                state.Buffer.Reset(marker);

                // translate exception to an error object
                DekiScriptMap error = DekiScriptLibrary.MakeErrorObject(e, state.Env);

                // capture error object in a nested environment
                try {
                    state.Env.Vars.Add(expr.Variable, error);
                    expr.Catch.VisitWith(this, state);
                } finally {
                    state.Env.Vars.Add(expr.Variable, DekiScriptNil.Value);
                }
            } finally {
                expr.Finally.VisitWith(this, state);
            }
            return(state.Buffer.Since(marker));
        }
示例#7
0
        public XDoc External(
            [DekiExtParam("link")] string link
            )
        {
            // store the original link value
            string originalLink = link;

            // remove spaces from the link
            link = link.Trim();

            // extract the title if there is one (indicated by the first space)
            string title      = String.Empty;
            int    titleIndex = link.IndexOf(' ');

            if (0 < titleIndex)
            {
                title = link.Substring(titleIndex + 1, link.Length - titleIndex - 1);
                link  = link.Substring(0, titleIndex);
            }

            // if the url is valid return it as a link - otherwise return the original text
            XDoc result = new XDoc("html").Start("body");
            XUri uri    = null;

            if (XUri.TryParse(link, out uri))
            {
                result.Start("a").Attr("href", link).AddNodes(DekiScriptLibrary.WebHtml(title, null, null, null)["body"]).End();
            }
            else
            {
                result.AddNodes(DekiScriptLibrary.WebHtml("[" + originalLink + "]", null, null, null)["body"]);
            }
            result.End();
            return(result);
        }
示例#8
0
        public void CultureDateTime_with_utc_flagless_signature_assumes_utc_if_no_tz_specified()
        {
            double offset;
            var    time = DekiScriptLibrary.CultureDateTimeParse("12:00pm", CultureInfo.InvariantCulture, out offset);

            Assert.AreEqual(DateTimeKind.Utc, time.Kind);
            Assert.AreEqual(12, time.Hour);
            Assert.AreEqual(0d, offset);
        }
示例#9
0
 public XDoc QueryLink(
     [DekiExtParam("query expression to link to")] string query,
     [DekiExtParam("link contents; can be text, an image, or another document (default: link uri)", true)] object text,
     [DekiExtParam("link hover title (default: link title)", true)] string title,
     [DekiExtParam("link target (default: nil)", true)] string target
     )
 {
     return(DekiScriptLibrary.WebLink(_server.At("issues").With("q", query).ToString(), text, title, target));
 }
示例#10
0
 public XDoc IssueLink(
     [DekiExtParam("YouTrack ID to link to (default: all issues)")] string id,
     [DekiExtParam("link contents; can be text, an image, or another document (default: link uri)", true)] object text,
     [DekiExtParam("link hover title (default: link title)", true)] string title,
     [DekiExtParam("link target (default: nil)", true)] string target
     )
 {
     return(DekiScriptLibrary.WebLink(_server.At("issue", id).ToString(), text, title, target));
 }
示例#11
0
        public void CultureDateTime_adjusts_kind_and_time_to_utc_if_tz_specified_and_utc_flag_is_false()
        {
            double offset;
            var    time = DekiScriptLibrary.CultureDateTimeParse("12:00pm -03:00", CultureInfo.InvariantCulture, false, out offset);

            Assert.AreEqual(DateTimeKind.Utc, time.Kind);
            Assert.AreEqual(15, time.Hour);
            Assert.AreEqual(-3d, offset);
        }
示例#12
0
        public void CultureDateTime_does_not_adjust_kind_if_no_tz_specified_and_utc_flag_is_false()
        {
            double offset;
            var    time = DekiScriptLibrary.CultureDateTimeParse("12:00pm", CultureInfo.InvariantCulture, false, out offset);

            Assert.AreEqual(DateTimeKind.Unspecified, time.Kind);
            Assert.AreEqual(12, time.Hour);
            Assert.AreEqual(0, offset);
        }
示例#13
0
        public void CultureDateTime_with_utc_flagless_signature_adjust_time_to_utc()
        {
            double offset;
            var    time = DekiScriptLibrary.CultureDateTimeParse("12:00pm -03:00", CultureInfo.InvariantCulture, out offset);

            Assert.AreEqual(DateTimeKind.Utc, time.Kind);
            Assert.AreEqual(15, time.Hour);
            Assert.AreEqual(-3d, offset);
        }
示例#14
0
        public DekiScriptDom Visit(DekiScriptDomJson expr, DekiScriptOptimizerState state)
        {
            DekiScriptExpression value = expr.Value.VisitWith(DekiScriptExpressionOptimizer.Instance, state);

            if (value is DekiScriptLiteral)
            {
                return(new DekiScriptDomText(expr.Location, DekiScriptLibrary.JsonEmit(((DekiScriptLiteral)value).NativeValue)));
            }
            return(new DekiScriptDomJson(expr.Location, value));
        }
示例#15
0
 internal DekiScriptXml(XDoc value, bool safe)
 {
     if (value == null)
     {
         throw new ArgumentNullException("value");
     }
     if (safe)
     {
         value = DekiScriptLibrary.CleanseHtmlDocument(value);
     }
     this.Value = value;
 }
示例#16
0
        //--- Class Methods ---
        private static string ConvertDate(XDoc date)
        {
            long?epoch = date.AsLong;

            if (!epoch.HasValue)
            {
                return(null);
            }
            var datetime = DateTimeUtil.FromEpoch((uint)(epoch.Value / 1000));

            return(DekiScriptLibrary.CultureDateTime(datetime));
        }
示例#17
0
        public XDoc WebHtml(
            [DekiExtParam("HTML source text or source uri (default: none)", true)] string source,
            [DekiExtParam("xpath to value (default: none)", true)] string xpath,
            [DekiExtParam("namespaces (default: none)", true)] Hashtable namespaces,
            [DekiExtParam("caching duration in seconds (range: 300+; default: 300)", true)] double?ttl,
            [DekiExtParam("return nil if source could not be loaded (default: text with error message)", true)] bool?nilIfMissing
            )
        {
            string text = WebText(source, xpath, namespaces, true, ttl, nilIfMissing);

            if (text == null)
            {
                return(null);
            }

            // convert text to html
            XDoc result = XDoc.Empty;

            using (TextReader reader = new StringReader("<html><body>" + text + "</body></html>")) {
                // NOTE (steveb): we create the sgml reader explicitly since we don't want a DTD to be associated with it; the DTD would force a potentially unwanted HTML structure

                // check if HTML entities DTD has already been loaded
                if (_htmlEntitiesDtd == null)
                {
                    using (StreamReader dtdReader = new StreamReader(Plug.New("resource://mindtouch.deki.script/MindTouch.Deki.Script.HtmlEntities.dtd").Get().AsStream())) {
                        _htmlEntitiesDtd = Sgml.SgmlDtd.Parse(null, "HTML", dtdReader, null, null, XDoc.XmlNameTable);
                    }
                }

                Sgml.SgmlReader sgmlReader = new Sgml.SgmlReader(XDoc.XmlNameTable);
                sgmlReader.Dtd                = _htmlEntitiesDtd;
                sgmlReader.DocType            = "HTML";
                sgmlReader.WhitespaceHandling = WhitespaceHandling.All;
                sgmlReader.CaseFolding        = Sgml.CaseFolding.ToLower;
                sgmlReader.InputStream        = reader;
                try {
                    XmlDocument doc = new XmlDocument(XDoc.XmlNameTable);
                    doc.PreserveWhitespace = true;
                    doc.XmlResolver        = null;
                    doc.Load(sgmlReader);

                    // check if a valid document was created
                    if (doc.DocumentElement != null)
                    {
                        result = new XDoc(doc);
                    }
                } catch (Exception) {
                    // swallow parsing exceptions
                }
            }
            return(DekiScriptLibrary.CleanseHtmlDocument(result));
        }
示例#18
0
        public void Can_execute_function_with_a_defaulted_param()
        {
            string       path   = LoadExtension();
            DreamMessage result =
                Plug.New(_host.LocalMachineUri).At(path, "DefaultedParam").Post(new DekiScriptMap().ToXml());

            Assert.IsTrue(result.IsSuccessful);
            XDoc resultDoc = result.ToDocument();

            Assert.AreEqual("value", resultDoc.Name);
            Assert.AreEqual(
                "args.date: " + DekiScriptLibrary.DateNow().Substring(0, 4),
                resultDoc.Elements.First.AsText.Substring(0, 15));
        }
示例#19
0
        public override XDoc AsEmbeddableXml(bool safe)
        {
            MimeType mime = (Value.Segments.Length > 0) ? MimeType.FromFileExtension(Value.LastSegment ?? string.Empty) : MimeType.BINARY;

            if (StringUtil.EqualsInvariant(mime.MainType, "image"))
            {
                // embed <img> tag
                return(DekiScriptLibrary.WebImage(AsString(), null, null, null));
            }
            else
            {
                // embed <a> tag
                return(DekiScriptLibrary.WebLink(AsString(), null, null, null));
            }
        }
        public Empty Visit(DekiScriptDomJson expr, DekiScriptDomEvaluationState state)
        {
            var context = state.Context;
            var env     = state.Env;
            var parent  = state.Parent;

            try {
                DekiScriptLiteral value  = expr.Value.VisitWith(DekiScriptExpressionEvaluation.Instance, env);
                XmlText           result = context.CreateTextNode(DekiScriptLibrary.JsonEmit(value.NativeValue));
                parent.AppendChild(result);
            } catch (Exception e) {
                EmbedExceptionMessage(expr, env, context, e, parent);
            }
            return(Empty.Value);
        }
示例#21
0
        public override XDoc AsEmbeddableXml(bool safe)
        {
            XDoc result = Value;

            if (!Value.IsEmpty && !Value.HasName("html"))
            {
                result = new XDoc("html").Start("body").Add(Value).End();
                if (safe)
                {
                    foreach (XDoc body in result["body"])
                    {
                        DekiScriptLibrary.ValidateXHtml(body, true, true);
                    }
                }
            }
            return(result);
        }
        public void ThrowIfTimedout()
        {
            if (_sharedState.EvaluationTimer == null)
            {
                return;
            }
            if (_sharedState.EvaluationTimer.Elapsed <= _sharedState.EvaluationTimeout)
            {
                return;
            }
            _sharedState.EvaluationTimer.Stop();
            var e     = new TimeoutException("script execution has timed out");
            var error = DekiScriptLibrary.MakeErrorObject(e, Env);

            _sharedState.EvaluationError = new DekiScriptXml(DekiScriptLibrary.WebShowError((Hashtable)error.NativeValue));
            throw e;
        }
示例#23
0
        private void AddUri(XmlNode context, DekiScriptUri uri)
        {
            if (context == null)
            {
                ConvertStateToHtml(null);
            }

            // NOTE (steveb): URIs have special embedding rules; either embed it as a <img> and <a> document base on the URI file extension on the last segment

            XUri     url  = uri.Value.AsPublicUri();
            MimeType mime = (url.Segments.Length > 0) ? MimeType.FromFileExtension(url.LastSegment ?? string.Empty) : MimeType.BINARY;
            XDoc     item = mime.MainType.EqualsInvariant("image") ?
                            DekiScriptLibrary.WebImage(url.ToString(), null, null, null) :
                            DekiScriptLibrary.WebLink(url.ToString(), null, null, null);

            AddXDoc(context, item);
        }
示例#24
0
        public ArrayList Issues(
            [DekiExtParam("query expression (default: all issues)", true)] string query,
            [DekiExtParam("number of items to skip (default: 0)", true)] int?offset,
            [DekiExtParam("maximum number of items to return (default: 100)", true)] int?limit,
            [DekiExtParam("get only issues updated after specified date.", true)] string since
            )
        {
            Login();
            var request = _server.At("rest", "project", "issues");

            // check if a query was provided
            if (!string.IsNullOrEmpty(query))
            {
                request = request.With("filter", query);
            }

            // check if a limit and offset were provided
            if (offset.HasValue)
            {
                request = request.With("after", offset.Value);
            }
            request = request.With("max", limit ?? 100);

            // check if a date limit was provide
            if (!string.IsNullOrEmpty(since))
            {
                DreamContext context = DreamContext.CurrentOrNull;
                CultureInfo  culture = (context == null) ? CultureInfo.CurrentCulture : context.Culture;
                double       dummy;
                var          date = DekiScriptLibrary.CultureDateTimeParse(since, culture, out dummy);
                request = request.With("updatedAfter", date.ToEpoch());
            }
            var doc = request.Get().ToDocument();

            var result = new ArrayList();

            foreach (var issue in doc["issue"])
            {
                result.Add(ConvertIssue(issue));
            }
            return(result);
        }
示例#25
0
        public object WebJson(
            [DekiExtParam("source text or source uri (default: none)", true)] string source,
            [DekiExtParam("caching duration in seconds (range: 300+; default: 300)", true)] double?ttl,
            [DekiExtParam("return nil if source could not be loaded (default: text with error message)", true)] bool?nilIfMissing,
            DekiScriptRuntime runtime
            )
        {
            source = source ?? string.Empty;
            XUri uri = XUri.TryParse(source);

            if (uri == null)
            {
                return(DekiScriptLibrary.JsonParse(source, runtime));
            }

            // we need to fetch an online document
            string response = CachedWebGet(uri, ttl, nilIfMissing);

            return(DekiScriptLibrary.JsonParse(response, runtime));
        }
        public DekiScriptOutputBuffer.Range Visit(DekiScriptReturnScope expr, DekiScriptExpressionEvaluationState state)
        {
            int marker = state.Buffer.Marker;

            try {
                if (state.FatalEvaluationError == null)
                {
                    state.ThrowIfTimedout();
                    return(expr.Value.VisitWith(this, state));
                }
                state.Push(state.FatalEvaluationError);
            } catch (DekiScriptReturnException e) {
                state.Push(e.Value);
            } catch (DekiScriptControlFlowException) {
                // nothing to do
            } catch (Exception e) {
                var error = DekiScriptLibrary.MakeErrorObject(e, state.Env);
                state.Runtime.LogExceptionInOutput(error);
                state.Push(new DekiScriptXml(DekiScriptLibrary.WebShowError((Hashtable)error.NativeValue)));
            }
            return(state.Buffer.Since(marker));
        }
示例#27
0
        private static bool TryParseDekiScriptExpression(string ctor, DekiScriptEnv env, DekiScriptRuntime runtime, ref int i, out string value)
        {
            string source = ParseExpression(ctor, null, ParseMode.EXPRESSION, false, env, runtime, null, ref i);

            if ((i >= ctor.Length) || (ctor[i] != '}'))
            {
                value = null;
                return(false);
            }

            // try to parse and execute the dekiscript fragment
            try {
                source = source.Substring(1, source.Length - 2);
                DekiScriptExpression dekiscript = DekiScriptParser.Parse(new Location("jem"), source);
                DekiScriptLiteral    result     = runtime.Evaluate(dekiscript, DekiScriptEvalMode.EvaluateSafeMode, env);
                value = DekiScriptLibrary.JsonEmit(result.NativeValue);
            } catch (Exception e) {
                // execution failed; convert exception into a javascript comment
                value = "alert(\"ERROR in DekiScript expression:\\n---------------------------\\n\\n\" + " + e.GetCoroutineStackTrace().QuoteString() + ")";
            }
            return(true);
        }
示例#28
0
        public static DekiScriptLiteral FromNativeValue(object value)
        {
            if (value is DekiScriptLiteral)
            {
                return((DekiScriptLiteral)value);
            }
            if (value != null)
            {
                switch (AsScriptType(value.GetType()))
                {
                case DekiScriptType.BOOL:
                    return(Constant((bool)value));

                case DekiScriptType.NUM:
                    return(Constant(SysUtil.ChangeType <double>(value)));

                case DekiScriptType.STR:
                    if (value is DateTime)
                    {
                        return(Constant(DekiScriptLibrary.CultureDateTime((DateTime)value)));
                    }
                    return(Constant(value.ToString()));

                case DekiScriptType.MAP:
                    return(new DekiScriptMap((Hashtable)value));

                case DekiScriptType.LIST:
                    return(new DekiScriptList((ArrayList)value));

                case DekiScriptType.XML:
                    return(Constant((XDoc)value));

                case DekiScriptType.URI:
                    return(Constant((XUri)value));
                }
            }
            return(DekiScriptNil.Value);
        }
示例#29
0
 //--- Class Methods ---
 public static string AsSize(float?size)
 {
     return(DekiScriptLibrary.WebSize(size));
 }
示例#30
0
        public XDoc Internal(
            [DekiExtParam("link")] string link,
            [DekiExtParam("language", true)] string language
            )
        {
            // extract the link title
            string displayName      = null;
            int    displayNameIndex = link.IndexOf('|');

            if (0 < displayNameIndex)
            {
                displayName = link.Substring(displayNameIndex + 1, link.Length - displayNameIndex - 1);
                link        = link.Substring(0, displayNameIndex);
            }

            Title title = Title.FromUIUri(null, link, true);

            if (("." == title.Path) && (title.HasAnchor))
            {
                link = "#" + AnchorEncode(title.Anchor);
            }
            else
            {
                link = LocalUrl(language, title.AsPrefixedDbPath(), title.Query);
                if (title.HasAnchor)
                {
                    link += "#" + AnchorEncode(title.Anchor);
                }
            }

            // return the internal link
            XDoc result = new XDoc("html").Start("body").Start("a").Attr("href", link).AddNodes(DekiScriptLibrary.WebHtml(displayName ?? String.Empty, null, null, null)["body"]).End().End();

            return(result);
        }