Ejemplo n.º 1
0
 //--- Constructors ---
 public DekiScriptComparer(DekiScriptRuntime runtime, DekiScriptExpression compare) {
     if(compare == null) {
         throw new ArgumentNullException("compare");
     }
     _runtime = runtime;
     _compare = compare;
     _values = new DekiScriptMap();
     _env = runtime.CreateEnv();
     _env.Vars.Add(DekiScriptRuntime.DEFAULT_ID, _values);
 }
Ejemplo n.º 2
0
 //--- Constructors ---
 public DekiScriptCaseBlock(DekiScriptExpression[] conditions, DekiScriptExpression body, bool isBlock) {
     if(conditions == null) {
         throw new ArgumentNullException("conditions");
     }
     if(body == null) {
         throw new ArgumentNullException("body");
     }
     this.Conditions = conditions;
     this.Body = body;
     IsBlock = isBlock;
 }
 public DekiScriptExpressionInvocationTarget(DreamAccess access, DekiScriptParameter[] parameters, DekiScriptExpression expr, DekiScriptEnv env) {
     if(parameters == null) {
         throw new ArgumentNullException("parameters");
     }
     if(expr == null) {
         throw new ArgumentNullException("expr");
     }
     this.Access = access;
     this.Parameters = parameters;
     this.Expression = expr;
     _env = env;
 }
 public void Test(DekiScriptExpression expr, string resultValue, Type expectedType, bool safe) {
     var env = Runtime.CreateEnv();
     env.Vars.Add(DekiScriptEnv.SAFEMODE, DekiScriptExpression.Constant(safe));
     DekiScriptExpression result = Runtime.Evaluate(expr, safe ? DekiScriptEvalMode.EvaluateSafeMode : DekiScriptEvalMode.Evaluate, env);
     Assert.IsAssignableFrom(expectedType, result);
     string value;
     if(result is DekiScriptString) {
         value = ((DekiScriptString)result).Value;
     } else if(result is DekiScriptXml) {
         value = ((DekiScriptXml)result).Value.ToString();
     } else {
         value = result.ToString();
     }
     Assert.AreEqual(resultValue, value);
 }
Ejemplo n.º 5
0
        public static object ListReduce(
            [DekiScriptParam("list value")] ArrayList list,
            [DekiScriptParam("expression to compute combined value (use '$value' and '$item' to refer to the current value and item, respectively)")] string expression,
            [DekiScriptParam("starting value (default: nil)", true)] object value,
            DekiScriptRuntime runtime
            )
        {
            DekiScriptExpression expr = DekiScriptParser.Parse(new Location("list.reduce(expression)"), expression);

            foreach (object entry in list)
            {
                DekiScriptEnv env    = runtime.CreateEnv();
                DekiScriptMap values = new DekiScriptMap();
                values.Add("value", DekiScriptLiteral.FromNativeValue(value));
                values.Add("item", DekiScriptLiteral.FromNativeValue(entry));
                env.Vars.Add(DekiScriptRuntime.DEFAULT_ID, values);
                value = runtime.Evaluate(expr, DekiScriptEvalMode.EvaluateSafeMode, env).NativeValue;
            }
            return(value);
        }
Ejemplo n.º 6
0
        public static Hashtable MapApply(
            [DekiScriptParam("map value")] Hashtable map,
            [DekiScriptParam("expression to apply (use '$' to refer to the item)")] string expression,
            DekiScriptRuntime runtime
            )
        {
            DekiScriptExpression expr   = DekiScriptParser.Parse(new Location("map.apply(expression)"), expression);
            Hashtable            result = new Hashtable(StringComparer.OrdinalIgnoreCase);

            foreach (DictionaryEntry entry in map)
            {
                DekiScriptMap keyvalue = new DekiScriptMap();
                keyvalue.Add("key", DekiScriptLiteral.FromNativeValue(entry.Key));
                keyvalue.Add("value", DekiScriptLiteral.FromNativeValue(Eval(entry.Value, runtime)));
                DekiScriptEnv env = runtime.CreateEnv();
                env.Vars.Add(DekiScriptRuntime.DEFAULT_ID, keyvalue);
                result.Add(entry.Key, runtime.Evaluate(expr, DekiScriptEvalMode.EvaluateSafeMode, env));
            }
            return(result);
        }
Ejemplo n.º 7
0
        public static int ListCount(
            [DekiScriptParam("list value")] ArrayList list,
            [DekiScriptParam("condition to execute for each item (use '$' to refer to the item)")] string condition,
            DekiScriptRuntime runtime
            )
        {
            DekiScriptExpression expr = DekiScriptParser.Parse(new Location("list.count(condition)"), condition);
            int count = 0;

            foreach (object entry in list)
            {
                DekiScriptEnv env = runtime.CreateEnv();
                env.Vars.Add(DekiScriptRuntime.DEFAULT_ID, DekiScriptLiteral.FromNativeValue(entry));
                DekiScriptLiteral test = runtime.Evaluate(expr, DekiScriptEvalMode.EvaluateSafeMode, env);
                if (!test.IsNilFalseZero)
                {
                    ++count;
                }
            }
            return(count);
        }
Ejemplo n.º 8
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);
        }
        public DekiScriptOutputBuffer.Range Visit(DekiScriptUnary expr, DekiScriptExpressionEvaluationState state)
        {
            switch (expr.OpCode)
            {
            case DekiScriptUnary.Op.Negate:
                return(state.Push(DekiScriptExpression.Constant(-state.Pop(expr.Value.VisitWith(this, state)).AsNumber())));

            case DekiScriptUnary.Op.LogicalNot:
                return(state.Push(DekiScriptExpression.Constant(state.Pop(expr.Value.VisitWith(this, state)).IsNilFalseZero)));

            case DekiScriptUnary.Op.TypeOf:
                return(state.Push(DekiScriptExpression.Constant(state.Pop(expr.Value.VisitWith(this, state)).ScriptTypeName)));

            case DekiScriptUnary.Op.Length: {
                DekiScriptLiteral value = state.Pop(expr.Value.VisitWith(this, state));
                switch (value.ScriptType)
                {
                case DekiScriptType.NIL:
                    return(state.Push(DekiScriptExpression.Constant(0)));

                case DekiScriptType.LIST:
                    return(state.Push(DekiScriptExpression.Constant(((DekiScriptList)value).Value.Count)));

                case DekiScriptType.STR:
                    return(state.Push(DekiScriptExpression.Constant(((DekiScriptString)value).Value.Length)));

                case DekiScriptType.MAP:
                    return(state.Push(DekiScriptExpression.Constant(((DekiScriptMap)value).Value.Count)));

                case DekiScriptType.XML:
                    return(state.Push(DekiScriptExpression.Constant(((DekiScriptXml)value).Value.ListLength)));

                default:
                    return(DekiScriptOutputBuffer.Range.Empty);
                }
            }
            }
            throw new InvalidOperationException("invalid op code:" + expr.OpCode);
        }
Ejemplo n.º 10
0
        public DekiScriptLiteral GetMagicId(string id)
        {
            DekiScriptLiteral result = DekiScriptNil.Value;

            // check if magic IDs map already exists; if not, create one
            if (_magicIds == null)
            {
                _magicIds = new DekiScriptMap();
            }
            else
            {
                result = _magicIds[id];
            }

            // check if a magic ID was found; if not, create one
            if (result.IsNil)
            {
                result = DekiScriptExpression.Constant(id + "_" + StringUtil.CreateAlphaNumericKey(8));
                _magicIds.Add(id, result);
            }
            return(result);
        }
Ejemplo n.º 11
0
        public void Dom_evaluation_with_static_content()
        {
            XDoc doc = new XDoc("html").UsePrefix("eval", "http://mindtouch.com/2007/dekiscript")
                       .Start("body")
                       .Start("div").Attr("block", "var x = string.toupper('foo')")
                       .Elem("eval:expr", "x .. 3; string.nbsp")
                       .End()
                       .End();

            // parse node
            DekiScriptExpression node = DekiScriptParser.Parse(doc);

            Assert.AreEqual("<html><body>(discard (var x = string.toupper(\"foo\")); <div>(x .. 3; string.nbsp)</div>) !! web.showerror(__error)</body></html> !! web.showerror(__error)", node.ToString());

            // TODO (steveb): disabled the partial evaluation test for now

            // partial evaluation
            //node = node.Optimize(DekiScriptEvalMode.Evaluate, DekiScriptEnv.Create());
            //Assert.AreEqual("<html><body><div>\"FOO3�\"; </div></body></html>", node.ToString());

            // full evaluation
            //XDoc value = node.Evaluate(DekiScriptEvalMode.Evaluate, DekiScriptEnv.Create()).AsEmbeddableXml(false);
            //Assert.AreEqual("<html><body><div>FOO3&nbsp;</div></body></html>", value.ToXHtml());
        }
Ejemplo n.º 12
0
        public void Test(DekiScriptExpression expr, string resultValue, Type expectedType, bool safe)
        {
            var env = Runtime.CreateEnv();

            env.Vars.Add(DekiScriptEnv.SAFEMODE, DekiScriptExpression.Constant(safe));
            DekiScriptExpression result = Runtime.Evaluate(expr, safe ? DekiScriptEvalMode.EvaluateSafeMode : DekiScriptEvalMode.Evaluate, env);

            Assert.IsAssignableFrom(expectedType, result);
            string value;

            if (result is DekiScriptString)
            {
                value = ((DekiScriptString)result).Value;
            }
            else if (result is DekiScriptXml)
            {
                value = ((DekiScriptXml)result).Value.ToString();
            }
            else
            {
                value = result.ToString();
            }
            Assert.AreEqual(resultValue, value);
        }
Ejemplo n.º 13
0
	void Primary(out DekiScriptExpression expr) {
		DekiScriptExpression inner = null; expr = null; string name = null; Location location = t.Location; 
		if (StartOf(9)) {
			Literal(out expr);
		} else if (la.kind == 22) {
			Get();
			Statements(out expr);
			Expect(23);
			expr = DekiScriptExpression.Block(location, new[] { expr }); 
		} else if (la.kind == 1) {
			Get();
			expr = DekiScriptExpression.Id(location, t.val); 
		} else SynErr(83);
		while (StartOf(10)) {
			if (la.kind == 63) {
				Get();
				location = t.Location; 
				if (StartOf(11)) {
					AnyName(out name);
					expr = DekiScriptExpression.Access(location, expr, DekiScriptExpression.Constant(name)); 
				} else if (la.kind == 22) {
					ArgList(out location, out inner);
					expr = DekiScriptExpression.Curry(location, expr, inner); 
				} else if (la.kind == 9) {
					Map(out location, out inner);
					expr = DekiScriptExpression.Curry(location, expr, inner); 
				} else SynErr(84);
			} else if (la.kind == 64) {
				Get();
				location = t.Location; 
				Expression(out inner);
				Expect(65);
				expr = DekiScriptExpression.Access(location, expr, inner); 
			} else if (la.kind == 22) {
				ArgList(out location, out inner);
				expr = DekiScriptExpression.Call(location, expr, inner); 
			} else {
				Map(out location, out inner);
				expr = DekiScriptExpression.Call(location, expr, inner); 
			}
		}
	}
Ejemplo n.º 14
0
        public void OutputBuffer_image_uri_followed_by_html()
        {
            var expr = DekiScriptExpression.Block(Location.None, new[] { DekiScriptExpression.Constant(new XUri("http://foo/index.png")), DekiScriptExpression.Constant(new XDoc("html").Elem("body", "test")) });

            _dekiScriptTester.Test(
                expr,
                @"<html><body><img src=""http://foo/index.png"" />test</body></html>",
                typeof(DekiScriptXml), false
                );
        }
Ejemplo n.º 15
0
	void AndExpr(out DekiScriptExpression expr) {
		DekiScriptExpression inner = null; Location location = Location.None; 
		EqlExpr(out expr);
		while (la.kind == 40) {
			Get();
			location = t.Location; 
			EqlExpr(out inner);
			expr = DekiScriptExpression.BinaryOp(location, DekiScriptBinary.Op.LogicalAnd, expr, inner); 
		}
	}
Ejemplo n.º 16
0
	void EqlExpr(out DekiScriptExpression expr) {
		DekiScriptExpression inner = null; DekiScriptBinary.Op op = DekiScriptBinary.Op.LeftValue; Location location = Location.None; 
		RelExpr(out expr);
		while (StartOf(5)) {
			if (la.kind == 41) {
				Get();
				op = DekiScriptBinary.Op.NotEqual; 
			} else if (la.kind == 42) {
				Get();
				op = DekiScriptBinary.Op.Equal; 
			} else if (la.kind == 43) {
				Get();
				op = DekiScriptBinary.Op.IdentityNotEqual; 
			} else {
				Get();
				op = DekiScriptBinary.Op.IdentityEqual; 
			}
			location = t.Location; 
			RelExpr(out inner);
			expr = DekiScriptExpression.BinaryOp(location, op, expr, inner); 
		}
	}
Ejemplo n.º 17
0
	void NullCoalescingExpr(out DekiScriptExpression expr) {
		DekiScriptExpression inner = null; Location location = Location.None; 
		OrExpr(out expr);
		while (la.kind == 38) {
			Get();
			location = t.Location; 
			OrExpr(out inner);
			expr = DekiScriptExpression.BinaryOp(location, DekiScriptBinary.Op.NullCoalesce, expr, inner); 
		}
	}
Ejemplo n.º 18
0
 private DekiScriptExpression Html(string container, string tag, string type, DekiScriptExpression expr) {
     DekiScriptExpression style = DekiScriptExpression.XmlElement(Location, null, DekiScriptExpression.Constant(tag), new[] { new DekiScriptXmlElement.Attribute(Location, null, DekiScriptExpression.Constant("type"), DekiScriptExpression.Constant(type)) }, expr);
     DekiScriptExpression head = DekiScriptExpression.XmlElement(Location, null, DekiScriptExpression.Constant(container), null, style);
     DekiScriptExpression html = DekiScriptExpression.XmlElement(Location, null, DekiScriptExpression.Constant("html"), null, head);
     return html;
 }
Ejemplo n.º 19
0
	void Xml(out DekiScriptExpression expr) {
		XmlNode(out expr);
	}
Ejemplo n.º 20
0
        public static void InitializeCustomDekiScriptHeaders(PageBE page)
        {
            var           current = DreamContext.Current;
            DekiScriptMap env     = current.GetState <DekiScriptMap>("pageimplicitenv-" + page.ID);

            // check if we already have an initialized environment
            if (env == null)
            {
                DekiContext  deki     = DekiContext.Current;
                DekiInstance instance = deki.Instance;
                env = new DekiScriptMap();

                // add site fields
                DekiScriptMap siteFields = new DekiScriptMap();
                siteFields.Add("name", DekiScriptExpression.Constant(instance.SiteName));
                siteFields.Add("host", DekiScriptExpression.Constant(deki.UiUri.Uri.Host));
                siteFields.Add("language", DekiScriptExpression.Constant(instance.SiteLanguage));
                siteFields.Add("uri", DekiScriptExpression.Constant(deki.UiUri.Uri.ToString()));
                siteFields.Add("id", DekiScriptExpression.Constant(instance.Id));
                env.Add("site", siteFields);

                // add page fields
                DekiScriptMap pageFields = new DekiScriptMap();
                pageFields.Add("title", DekiScriptExpression.Constant(page.Title.AsUserFriendlyName()));
                pageFields.Add("path", DekiScriptExpression.Constant(page.Title.AsPrefixedDbPath()));
                pageFields.Add("namespace", DekiScriptExpression.Constant(Title.NSToString(page.Title.Namespace)));
                pageFields.Add("id", DekiScriptExpression.Constant(page.ID.ToString()));
                pageFields.Add("uri", DekiScriptExpression.Constant(Utils.AsPublicUiUri(page.Title)));
                pageFields.Add("date", DekiScriptExpression.Constant(page.TimeStamp.ToString("R")));
                pageFields.Add("language", DekiScriptExpression.Constant(string.IsNullOrEmpty(page.Language) ? null : page.Language));
                env.Add("page", pageFields);

                // add user fields
                DekiScriptMap userFields = new DekiScriptMap();
                if (deki.User != null)
                {
                    UserBE user = deki.User;
                    userFields.Add("id", DekiScriptExpression.Constant(user.ID.ToString()));
                    userFields.Add("name", DekiScriptExpression.Constant(user.Name));
                    userFields.Add("uri", DekiScriptExpression.Constant(Utils.AsPublicUiUri(Title.FromDbPath(NS.USER, user.Name, null))));
                    userFields.Add("emailhash", DekiScriptExpression.Constant(StringUtil.ComputeHashString((user.Email ?? string.Empty).Trim().ToLowerInvariant(), Encoding.UTF8)));
                    userFields.Add("anonymous", DekiScriptExpression.Constant(UserBL.IsAnonymous(user).ToString().ToLowerInvariant()));
                    userFields.Add("language", DekiScriptExpression.Constant(string.IsNullOrEmpty(user.Language) ? null : user.Language));
                }
                else
                {
                    userFields.Add("id", DekiScriptExpression.Constant("0"));
                    userFields.Add("name", DekiScriptExpression.Constant(string.Empty));
                    userFields.Add("uri", DekiScriptExpression.Constant(string.Empty));
                    userFields.Add("emailhash", DekiScriptExpression.Constant(string.Empty));
                    userFields.Add("anonymous", DekiScriptExpression.Constant("true"));
                    userFields.Add("language", DekiScriptNil.Value);
                }
                env.Add("user", userFields);

                // store env for later
                current.SetState("pageimplicitenv-" + page.ID, env);
            }

            // set implicit environment
            DreamContext.Current.SetState(env);
        }
 public virtual DekiScriptLiteral Evaluate(DekiScriptExpression expr, DekiScriptEvalMode mode, DekiScriptEnv env) {
     DekiScriptExpressionEvaluationState state = new DekiScriptExpressionEvaluationState(mode, env, this);
     try {
         return state.Pop(expr.VisitWith(DekiScriptExpressionEvaluation.Instance, state));
     } catch(DekiScriptReturnException e) {
         state.Push(e.Value);
         return state.PopAll();
     }
 }
Ejemplo n.º 22
0
	void Unary(out DekiScriptExpression expr) {
		Stack<Tuplet<Location, DekiScriptUnary.Op>> stack = new Stack<Tuplet<Location, DekiScriptUnary.Op>>(); 
		while (StartOf(8)) {
			if (la.kind == 56) {
				Get();
				stack.Push(new Tuplet<Location, DekiScriptUnary.Op>(t.Location, DekiScriptUnary.Op.Negate)); 
			} else if (la.kind == 55) {
				Get();
				
			} else if (la.kind == 60) {
				Get();
				stack.Push(new Tuplet<Location, DekiScriptUnary.Op>(t.Location, DekiScriptUnary.Op.LogicalNot)); 
			} else if (la.kind == 61) {
				Get();
				stack.Push(new Tuplet<Location, DekiScriptUnary.Op>(t.Location, DekiScriptUnary.Op.TypeOf)); 
			} else {
				Get();
				stack.Push(new Tuplet<Location, DekiScriptUnary.Op>(t.Location, DekiScriptUnary.Op.Length)); 
			}
		}
		Primary(out expr);
		while(stack.Count > 0) { 
		var item = stack.Pop(); 
		expr = DekiScriptExpression.UnaryOp(item.Item1, item.Item2, expr); 
		} 
		
	}
Ejemplo n.º 23
0
	void MulExpr(out DekiScriptExpression expr) {
		DekiScriptExpression inner = null; DekiScriptBinary.Op op = DekiScriptBinary.Op.LeftValue; Location location = Location.None; 
		Unary(out expr);
		while (la.kind == 57 || la.kind == 58 || la.kind == 59) {
			if (la.kind == 57) {
				Get();
				op = DekiScriptBinary.Op.Multiplication; 
			} else if (la.kind == 58) {
				Get();
				op = DekiScriptBinary.Op.Division; 
			} else {
				Get();
				op = DekiScriptBinary.Op.Modulo; 
			}
			location = t.Location; 
			Unary(out inner);
			expr = DekiScriptExpression.BinaryOp(location, op, expr, inner); 
		}
	}
Ejemplo n.º 24
0
	void AddExpr(out DekiScriptExpression expr) {
		DekiScriptExpression inner = null; DekiScriptBinary.Op op = DekiScriptBinary.Op.LeftValue; Location location = Location.None; 
		MulExpr(out expr);
		while (la.kind == 55 || la.kind == 56) {
			if (la.kind == 55) {
				Get();
				op = DekiScriptBinary.Op.Addition; 
			} else {
				Get();
				op = DekiScriptBinary.Op.Subtraction; 
			}
			location = t.Location; 
			MulExpr(out inner);
			expr = DekiScriptExpression.BinaryOp(location, op, expr, inner); 
		}
	}
Ejemplo n.º 25
0
	void ConcatExpr(out DekiScriptExpression expr) {
		DekiScriptExpression inner = null; Location location = Location.None; DekiScriptBinary.Op op = DekiScriptBinary.Op.LeftValue; 
		AddExpr(out expr);
		while (la.kind == 53 || la.kind == 54) {
			if (la.kind == 53) {
				Get();
				op = DekiScriptBinary.Op.Concat; 
			} else {
				Get();
				op = DekiScriptBinary.Op.UriAppend; 
			}
			location = t.Location; 
			AddExpr(out inner);
			expr = DekiScriptExpression.BinaryOp(location, op, expr, inner); 
		}
	}
Ejemplo n.º 26
0
	void RelExpr(out DekiScriptExpression expr) {
		DekiScriptExpression inner = null; 
		DekiScriptBinary.Op op = DekiScriptBinary.Op.LeftValue; 
		Location location = Location.None;
		bool negate = false;
		
		ConcatExpr(out expr);
		while (StartOf(6)) {
			if (StartOf(7)) {
				if (la.kind == 45) {
					Get();
					op = DekiScriptBinary.Op.LessThan; 
				} else if (la.kind == 46) {
					Get();
					op = DekiScriptBinary.Op.GreaterThan; 
				} else if (la.kind == 47) {
					Get();
					op = DekiScriptBinary.Op.LessOrEqual; 
				} else {
					Get();
					op = DekiScriptBinary.Op.GreaterOrEqual; 
				}
				location = t.Location; 
				ConcatExpr(out inner);
				expr = DekiScriptExpression.BinaryOp(location, op, expr, inner); 
			} else if (la.kind == 49) {
				Get();
				location = t.Location; 
				if (la.kind == 50) {
					Get();
					negate = true; 
				}
				if (la.kind == 51) {
					Get();
					expr = DekiScriptExpression.BinaryOp(location, DekiScriptBinary.Op.IsType, expr, DekiScriptExpression.Constant("nil")); 
				} else if (la.kind == 1) {
					Get();
					expr = DekiScriptExpression.BinaryOp(location, DekiScriptBinary.Op.IsType, expr, DekiScriptExpression.Constant(t.val)); 
				} else SynErr(82);
			} else {
				if (la.kind == 50) {
					Get();
					negate = true; 
				}
				Expect(52);
				location = t.Location; 
				ConcatExpr(out inner);
				expr = DekiScriptExpression.BinaryOp(location, DekiScriptBinary.Op.InCollection, expr, inner); 
			}
			if(negate) expr = DekiScriptExpression.UnaryOp(location, DekiScriptUnary.Op.LogicalNot, expr); 
		}
	}
 //--- Constructors ---
 public DekiScriptExpressionInvocationTarget(DreamAccess access, DekiScriptParameter[] parameters, DekiScriptExpression expr) : this(access, parameters, expr, null)
 {
 }
Ejemplo n.º 28
0
	void Literal(out DekiScriptExpression expr) {
		expr = null; Location location = Location.None; 
		switch (la.kind) {
		case 51: case 66: case 67: {
			Nil(out expr);
			break;
		}
		case 68: case 69: {
			Bool(out expr);
			break;
		}
		case 5: case 6: {
			Number(out expr);
			break;
		}
		case 3: case 4: {
			String(out expr);
			break;
		}
		case 7: {
			EntityString(out expr);
			break;
		}
		case 2: {
			MagicId(out expr);
			break;
		}
		case 9: {
			Map(out location, out expr);
			break;
		}
		case 64: {
			List(out expr);
			break;
		}
		case 45: {
			Xml(out expr);
			break;
		}
		default: SynErr(85); break;
		}
	}
Ejemplo n.º 29
0
	void ArgList(out Location location, out DekiScriptExpression expr) {
		List<DekiScriptExpression> list = new List<DekiScriptExpression>(); location = Location.None; 
		Expect(22);
		location = t.Location; 
		if (StartOf(2)) {
			Expression(out expr);
			list.Add(expr); 
			while (la.kind == 20) {
				Get();
				Expression(out expr);
				list.Add(expr); 
			}
		}
		Expect(23);
		expr = DekiScriptExpression.List(location, list); 
	}
Ejemplo n.º 30
0
	void Map(out Location location, out DekiScriptExpression expr) {
		List<DekiScriptMapConstructor.FieldConstructor> list = new List<DekiScriptMapConstructor.FieldConstructor>(); 
		DekiScriptMapConstructor.FieldConstructor field = null; 
		DekiScriptGenerator gen = null; 
		location = Location.None;
		
		Expect(9);
		location = t.Location; 
		if (StartOf(12)) {
			Field(out field);
			list.Add(field); 
			while (la.kind == 20) {
				Get();
				Field(out field);
				list.Add(field); 
			}
			if (la.kind == 28) {
				Get();
				GeneratorHead(out gen);
			}
		}
		Expect(10);
		expr = DekiScriptExpression.Map(location, gen, list.ToArray()); 
	}
Ejemplo n.º 31
0
        public void Execute(ExecutionPlan plan)
        {
            var service = DreamTestHelper.CreateService(
                _hostinfo,
                "sid://mindtouch.com/2007/12/dekiscript",
                "dekiscript",
                new XDoc("config").Elem("manifest", _manifestUri)
                );

            foreach (var functionName in _manifest["function/name"])
            {
                var name = functionName.AsText;
                _tester.Runtime.RegisterFunction(name, service.AtLocalHost.At(name));
            }
            try {
                var expr = _tester.Parse(plan.Expr);
                var env  = _tester.Runtime.CreateEnv();
                env.Vars.Add(DekiScriptEnv.SAFEMODE, DekiScriptExpression.Constant(plan.Safe));
                DekiScriptExpression result = _tester.Runtime.Evaluate(expr, plan.Safe ? DekiScriptEvalMode.EvaluateSafeMode : DekiScriptEvalMode.Evaluate, env);
                if (plan.TypedVerification != null)
                {
                    Assert.AreEqual(plan.ExpectedType, result.GetType());
                    plan.TypedVerification(result);
                }
                else if (plan.DocVerification != null)
                {
                    if (!(result is DekiScriptXml))
                    {
                        Assert.Fail(string.Format("return type was '{0}' not DekiScriptXml", result.GetType()));
                    }
                    var doc = ((DekiScriptXml)result).Value;
                    plan.DocVerification(doc);
                }
                else if (plan.StringVerification != null)
                {
                    string value;
                    if (result is DekiScriptString)
                    {
                        value = ((DekiScriptString)result).Value;
                    }
                    else if (result is DekiScriptXml)
                    {
                        value = ((DekiScriptXml)result).Value.ToString();
                    }
                    else
                    {
                        value = result.ToString();
                    }
                    plan.StringVerification(value, result.GetType());
                }
                else
                {
                    Assert.Fail("Execution completed without exception");
                }
            } catch (Exception e) {
                if (plan.ExceptionVerification != null)
                {
                    plan.ExceptionVerification(e);
                }
                else
                {
                    throw;
                }
            } finally {
                service.WithPrivateKey().AtLocalHost.Delete();
            }
        }
Ejemplo n.º 32
0
        private void LoadScript()
        {
            _manifestPath  = null;
            _resourcesPath = null;
            _manifestUri   = null;
            _resourcesUri  = null;
            _manifest      = null;

            // read manifest
            _manifestPath = Config["manifest"].AsText;
            if (string.IsNullOrEmpty(_manifestPath))
            {
                throw new ArgumentNullException("manifest");
            }
            _manifestUri = XUri.TryParse(_manifestPath);
            if (_manifestUri != null)
            {
                _manifestPath = null;
                _manifest     = Plug.New(_manifestUri).Get().ToDocument();
                _resourcesUri = Config["resources"].AsUri ?? _manifestUri.WithoutLastSegment();
            }
            else
            {
                _manifest      = XDocFactory.LoadFrom(_manifestPath, MimeType.XML);
                _resourcesPath = Config["resources"].AsText ?? Path.GetDirectoryName(_manifestPath);
            }
            if (!_manifest.HasName("extension"))
            {
                throw new ArgumentException("invalid extension manifest");
            }

            // initilize runtime
            _runtime = new DekiScriptRuntime();

            // read manifest settings
            _title       = _manifest["title"].AsText;
            _label       = _manifest["label"].AsText;
            _copyright   = _manifest["copyright"].AsText;
            _description = _manifest["description"].AsText;
            _help        = _manifest["uri.help"].AsText;
            _logo        = _manifest["uri.logo"].AsText;
            _namespace   = _manifest["namespace"].AsText;

            // initialize evaluation environment
            _commonEnv = _runtime.CreateEnv();

            // read functions
            _functions = new Dictionary <XUri, DekiScriptInvocationTargetDescriptor>();
            foreach (var function in _manifest["function"])
            {
                var descriptor = ConvertFunction(function);
                if (descriptor != null)
                {
                    var uri = Self.At(descriptor.SystemName);
                    DekiScriptInvocationTargetDescriptor old;
                    if (_functions.TryGetValue(uri, out old))
                    {
                        _log.WarnFormat("duplicate function name {0} in script {1}", descriptor.Name, _manifestUri);
                    }
                    _functions[uri] = descriptor;
                }
            }
            _runtime.RegisterExtensionFunctions(_functions);

            // add extension functions to env
            foreach (var function in _functions)
            {
                _commonEnv.Vars.AddNativeValueAt(function.Value.Name.ToLowerInvariant(), function.Key);
            }

            // add configuration settings
            DreamContext  context      = DreamContext.Current;
            DekiScriptMap scriptConfig = new DekiScriptMap();

            foreach (KeyValuePair <string, string> entry in Config.ToKeyValuePairs())
            {
                XUri local;
                if (XUri.TryParse(entry.Value, out local))
                {
                    local = context.AsPublicUri(local);
                    scriptConfig.AddAt(entry.Key.Split('/'), DekiScriptExpression.Constant(local.ToString()));
                }
                else
                {
                    scriptConfig.AddAt(entry.Key.Split('/'), DekiScriptExpression.Constant(entry.Value));
                }
            }
            _commonEnv.Vars.Add("config", scriptConfig);
        }
 //--- Extension Methods ---
 public static DekiScriptExpression Optimize(this DekiScriptRuntime runtime, DekiScriptExpression expr, DekiScriptEvalMode mode, DekiScriptEnv env) {
     return expr.VisitWith(DekiScriptExpressionOptimizer.Instance, new DekiScriptExpressionEvaluationState(mode, env, runtime));
 }
Ejemplo n.º 34
0
        private DekiScriptDomElement.Attribute Optimize(DekiScriptDomElement.Attribute expr, DekiScriptOptimizerState state)
        {
            DekiScriptExpression value = expr.Value.VisitWith(DekiScriptExpressionOptimizer.Instance, state);

            return(new DekiScriptDomElement.Attribute(expr.Location, expr.Prefix, expr.Name, value));
        }
Ejemplo n.º 35
0
	void Nil(out DekiScriptExpression expr) {
		if (la.kind == 66) {
			Get();
		} else if (la.kind == 51) {
			Get();
		} else if (la.kind == 67) {
			Get();
		} else SynErr(87);
		expr = DekiScriptNil.Value; 
	}
Ejemplo n.º 36
0
	void TernaryExpression(out DekiScriptExpression expr) {
		DekiScriptExpression left = null, right = null; Location location = Location.None; 
		NullCoalescingExpr(out expr);
		if (la.kind == 37) {
			Get();
			location = t.Location; 
			Expression(out left);
			Expect(31);
			Expression(out right);
			expr = DekiScriptExpression.TernaryOp(location, expr, left, right); 
		}
	}
Ejemplo n.º 37
0
        private DekiScriptInvocationTargetDescriptor ConvertFunction(XDoc function)
        {
            string functionName = function["name"].AsText;

            if (string.IsNullOrEmpty(functionName))
            {
                _log.WarnFormat("function without name in script {0}; skipping function definition", _manifestUri);
                return(null);
            }

            // determine function access level
            DreamAccess access;

            switch (function["access"].AsText ?? "public")
            {
            case "private":
                access = DreamAccess.Private;
                break;

            case "internal":
                access = DreamAccess.Internal;
                break;

            case "public":
                access = DreamAccess.Public;
                break;

            default:
                _log.WarnFormat("unrecognized access level '{0}' for function {1} in script {2}; defaulting to public", function["access"].AsText, functionName, _manifestUri);
                access = DreamAccess.Public;
                break;
            }

            // convert parameters
            List <DekiScriptParameter> parameters = new List <DekiScriptParameter>();

            foreach (XDoc param in function["param"])
            {
                string paramName = param["@name"].AsText;

                // determine if parameter has a default value
                string            paramDefault           = param["@default"].AsText;
                DekiScriptLiteral paramDefaultExpression = DekiScriptNil.Value;
                bool paramOptional = false;
                if (paramDefault != null)
                {
                    paramOptional = true;
                    try {
                        paramDefaultExpression = ScriptRuntime.Evaluate(DekiScriptParser.Parse(Location.Start, paramDefault), DekiScriptEvalMode.Evaluate, ScriptRuntime.CreateEnv());
                    } catch (Exception e) {
                        _log.ErrorExceptionFormat(e, "invalid default value for parameter {0} in function {1} in script {2}; skipping function definition", paramName, functionName, _manifestUri);
                        return(null);
                    }
                }
                else
                {
                    paramOptional = (param["@optional"].AsText == "true");
                }

                // determine parameter type
                string         paramType = param["@type"].AsText ?? "any";
                DekiScriptType paramScriptType;
                if (!SysUtil.TryParseEnum(paramType, out paramScriptType))
                {
                    _log.WarnFormat("unrecognized param type '{0}' for parameter {1} in function {2} in script {3}; defaulting to any", paramType, paramName, functionName, _manifestUri);
                    paramScriptType = DekiScriptType.ANY;
                }

                // add parameter
                parameters.Add(new DekiScriptParameter(paramName, paramScriptType, paramOptional, param.Contents, typeof(object), paramDefaultExpression));
            }
            var parameterArray = parameters.ToArray();

            // determine function body
            XDoc   ret  = function["return"];
            string src  = ret["@src"].AsText;
            string type = ret["@type"].AsText;
            DekiScriptExpression expression;

            if (!string.IsNullOrEmpty(src))
            {
                // 'src' attribute is set, load the script from it
                XDoc script;
                if (_manifestUri != null)
                {
                    // check if uri is relative
                    XUri scriptUri = XUri.TryParse(src) ?? _manifestUri.AtPath(src);
                    script = Plug.New(scriptUri).Get().ToDocument();
                }
                else
                {
                    // check if filename is relative
                    if (!Path.IsPathRooted(src))
                    {
                        src = Path.Combine(_resourcesPath, src);
                    }
                    script = XDocFactory.LoadFrom(src, MimeType.XML);
                }
                expression = DekiScriptParser.Parse(script);
                type       = type ?? "xml";
            }
            else if (!ret["html"].IsEmpty)
            {
                // <return> element contains a <html> node; parse it as a script
                expression = DekiScriptParser.Parse(ret["html"]);
                type       = type ?? "xml";
            }
            else if (!ret.IsEmpty)
            {
                // <return> element contains something else; use the text contents as deki-script expression
                var location = new Location(string.Format("/function[name={0}]/return", functionName));
                expression = DekiScriptParser.Parse(location, function["return"].AsText ?? string.Empty);
                expression = DekiScriptExpression.ReturnScope(location, expression);
                type       = type ?? "any";
            }
            else
            {
                _log.WarnFormat("function {0} has no body in script {1}; skipping function definition", functionName, _manifestUri);
                return(null);
            }

            // determine return type
            DekiScriptType returnScriptType;

            if (!SysUtil.TryParseEnum(type, out returnScriptType))
            {
                _log.WarnFormat("unrecognized return type '{0}' for function {1} in script {2}; defaulting to any", type, functionName, _manifestUri);
                returnScriptType = DekiScriptType.ANY;
            }

            // create function descriptor
            var    target      = new DekiScriptScriptFunctionInvocationTarget(access, parameterArray, expression, _commonEnv, returnScriptType);
            string description = function["description"].AsText;
            string transform   = function["@transform"].AsText;

            return(new DekiScriptInvocationTargetDescriptor(access, false, false, functionName, parameterArray, returnScriptType, description, transform, target));
        }
Ejemplo n.º 38
0
	void Bool(out DekiScriptExpression expr) {
		expr = null; 
		if (la.kind == 68) {
			Get();
			expr = DekiScriptBool.True; 
		} else if (la.kind == 69) {
			Get();
			expr = DekiScriptBool.False; 
		} else SynErr(88);
	}
Ejemplo n.º 39
0
        public DekiScriptDom Visit(DekiScriptDomComment expr, DekiScriptOptimizerState state)
        {
            DekiScriptExpression value = expr.Value.VisitWith(DekiScriptExpressionOptimizer.Instance, state);

            return(new DekiScriptDomComment(expr.Location, value));
        }
Ejemplo n.º 40
0
	void Number(out DekiScriptExpression expr) {
		expr = null; 
		if (la.kind == 5) {
			Get();
			expr = DekiScriptExpression.Constant(SysUtil.ChangeType<double>(t.val)); 
		} else if (la.kind == 6) {
			Get();
			expr = DekiScriptExpression.Constant(long.Parse(t.val.Substring(2), System.Globalization.NumberStyles.AllowHexSpecifier)); 
		} else SynErr(89);
	}
Ejemplo n.º 41
0
 //--- Constructors ---
 internal DekiScriptTernary(DekiScriptExpression test, DekiScriptExpression left, DekiScriptExpression right, bool isIfElse)
 {
     this.Test  = test;
     this.Left  = left;
     this.Right = right;
     IsIfElse   = isIfElse;
 }
Ejemplo n.º 42
0
	void String(out DekiScriptExpression expr) {
		string value = null; bool block; 
		AnyString(out value, out block);
		expr = DekiScriptExpression.Constant(value); 
	}
Ejemplo n.º 43
0
        public void OutputBuffer_web_uri_followed_by_html()
        {
            var expr = DekiScriptExpression.Block(Location.None, new[] { DekiScriptExpression.Constant(new XUri("http://foo/index.html")), DekiScriptExpression.Constant(new XDoc("html").Elem("body", "test")) });

            _dekiScriptTester.Test(
                expr,
                @"<html><body><a rel=""custom nofollow"" href=""http://foo/index.html"">http://foo/index.html</a>test</body></html>",
                typeof(DekiScriptXml), false
                );
        }
Ejemplo n.º 44
0
	void EntityString(out DekiScriptExpression expr) {
		string value = null; 
		Expect(7);
		expr = DekiScriptExpression.Constant(StringUtil.DecodeHtmlEntities(t.val)); 
	}
Ejemplo n.º 45
0
        public void OutputBuffer_web_uri_inside_xml()
        {
            var expr = DekiScriptExpression.XmlElement(Location.None, null, DekiScriptExpression.Constant("doc"), null, DekiScriptExpression.Constant(new XUri("http://foo/index.html")));

            _dekiScriptTester.Test(
                expr,
                @"<doc><a rel=""custom nofollow"" href=""http://foo/index.html"">http://foo/index.html</a></doc>",
                typeof(DekiScriptXml), false
                );
        }
Ejemplo n.º 46
0
	void MagicId(out DekiScriptExpression expr) {
		Location location = t.Location; 
		Expect(2);
		expr = DekiScriptExpression.MagicId(location, t.val.Substring(1)); 
	}
Ejemplo n.º 47
0
        public static DekiScriptEnv CreateEnvironment(PageBE page)
        {
            DekiScriptEnv commonEnv = DekiContext.Current.Instance.CreateEnvironment();

            // need to strip the config value back out for Deki
            commonEnv.Vars["config"] = new DekiScriptMap();

            // initialize environment
            DekiScriptEnv env      = commonEnv;
            DekiContext   deki     = DekiContext.Current;
            DekiInstance  instance = deki.Instance;

            // add site variables
            env.Vars.AddNativeValueAt("site.name", instance.SiteName);
            env.Vars.AddNativeValueAt("site.hostname", deki.UiUri.Uri.HostPort);
            env.Vars.AddNativeValueAt("site.api", deki.ApiUri.SchemeHostPortPath);
            env.Vars.AddNativeValueAt("site.language", instance.SiteLanguage);
            env.Vars.AddNativeValueAt("site.uri", deki.UiUri.Uri.ToString());
            env.Vars.AddNativeValueAt("site.pagecount", deki.Deki.PropertyAt("$sitepagecount"));
            env.Vars.AddNativeValueAt("site.usercount", deki.Deki.PropertyAt("$siteusercount"));
            env.Vars.AddNativeValueAt("site.homepage", deki.Deki.PropertyAt("$page", DekiContext.Current.Instance.HomePageId, true));
            env.Vars.AddNativeValueAt("site.feed", deki.ApiUri.At("site", "feed").ToString());
            env.Vars.AddNativeValueAt("site.tags", deki.Deki.PropertyAt("$sitetags"));
            env.Vars.AddNativeValueAt("site.users", deki.Deki.PropertyAt("$siteusers"));
            env.Vars.AddNativeValueAt("site.id", DekiScriptExpression.Constant(instance.Id));
            env.Vars.AddNativeValueAt("site.timezone", DekiScriptExpression.Constant(instance.SiteTimezone));

            // add page variables
            env.Vars.Add("page", deki.Deki.PropertyAt("$page", page.ID, true));

            // add user variables
            env.Vars.Add("user", deki.Deki.PropertyAt("$user", (deki.User != null) ? deki.User.ID : 0));

            // add instance functions & properties
            bool hasUnsafeContentPermission = DekiXmlParser.PageAuthorCanExecute();

            foreach (var service in instance.RunningServices.ExtensionServices)
            {
                if (service != null)
                {
                    var extension = service.Extension;
                    if (extension != null)
                    {
                        if (hasUnsafeContentPermission || !extension.IsProtected)
                        {
                            var functions = extension.Functions;
                            if (functions != null)
                            {
                                foreach (var function in functions)
                                {
                                    env.Vars.AddNativeValueAt(function.Name.ToLowerInvariant(), function.Uri);
                                }
                            }
                            else
                            {
                                _log.WarnFormat("CreateEnvironment - null functions (id: {0})", service.ServiceId);
                            }
                        }
                    }
                    else
                    {
                        _log.WarnFormat("CreateEnvironment - null extension (id: {0})", service.ServiceId);
                    }
                }
                else
                {
                    _log.Warn("CreateEnvironment - null service");
                }
            }
            return(env);
        }
Ejemplo n.º 48
0
        private void BuildElement(XmlNode current, ICollection <DekiScriptExpression> list)
        {
            // create new element
            var attributes = BuildAttributes(current);
            var elem       = DekiScriptExpression.XmlElement(Location, current.Prefix, DekiScriptExpression.Constant(current.LocalName), attributes.ToArray(), BuildChildren(current));

            list.Add(elem);
        }
Ejemplo n.º 49
0
        public Hashtable PopularPages(
            [DekiExtParam("max results (default: 10)", true)] int?max,
            [DekiExtParam("poll interval (only for js format, default: 30)", true)] int?interval
            )
        {
            int               maxResults  = max ?? 10;
            int               resultCount = 0;
            DekiScriptMap     env         = DreamContext.Current.GetState <DekiScriptMap>();
            DekiScriptLiteral uriLiteral  = env.GetAt("site.uri");
            XUri              deki        = new XUri(uriLiteral.NativeValue.ToString()).At("@api", "deki");
            Hashtable         map         = new Hashtable(StringComparer.OrdinalIgnoreCase);

            map.Add("interval", _ttl.TotalSeconds);
            ArrayList pages = new ArrayList();

            map.Add("pages", pages);
            int total = 0;
            Dictionary <uint, int> rankLookup = new Dictionary <uint, int>();

            lock (_pageViews) {
                foreach (View view in _pageViews)
                {
                    if (rankLookup.ContainsKey(view.PageId))
                    {
                        rankLookup[view.PageId]++;
                    }
                    else
                    {
                        rankLookup[view.PageId] = 1;
                    }
                    total++;
                }
            }
            List <Tuplet <uint, int> > rank = new List <Tuplet <uint, int> >();

            foreach (KeyValuePair <uint, int> kvp in rankLookup)
            {
                rank.Add(new Tuplet <uint, int>(kvp.Key, kvp.Value));
            }
            rank.Sort(delegate(Tuplet <uint, int> a, Tuplet <uint, int> b) {
                return(b.Item2.CompareTo(a.Item2));
            });
            map.Add("total", total);
            foreach (Tuplet <uint, int> page in rank)
            {
                Hashtable pageMap = new Hashtable(StringComparer.OrdinalIgnoreCase);
                pages.Add(pageMap);

                // BUGBUGBUG (arnec): the AsLocalUri should not be required after bug #5964 is resolved
                pageMap.Add("page", DekiScriptExpression.Constant(deki.At("$page").AsLocalUri(), new[] { DekiScriptExpression.Constant(page.Item1), DekiScriptExpression.Constant(true) }));
                pageMap.Add("views", page.Item2);
                resultCount++;
                if (resultCount >= maxResults)
                {
                    break;
                }
            }
            return(map);
        }
Ejemplo n.º 50
0
        private List <DekiScriptXmlElement.Attribute> BuildAttributes(XmlNode current)
        {
            List <DekiScriptXmlElement.Attribute> result = new List <DekiScriptXmlElement.Attribute>(current.Attributes.Count);

            for (int i = 0; i < current.Attributes.Count; ++i)
            {
                XmlAttribute attribute = current.Attributes[i];
                PushNode(attribute);

                // check if attribute needs to be evaluated
                if (attribute.NamespaceURI == XDekiScript.ScriptNS)
                {
                    // NOTE (steveb): eval:key="value"
                    DekiScriptXmlElement.Attribute attr = new DekiScriptXmlElement.Attribute(Location, null, DekiScriptExpression.Constant(attribute.LocalName), Parse(Location, attribute.Value));
                    result.Add(attr);
                }
                else if (attribute.Value.StartsWithInvariant("{{") && attribute.Value.EndsWithInvariant("}}"))
                {
                    // NOTE (steveb): key="{{value}}"
                    DekiScriptExpression           expr = Parse(Location, StripCode(attribute.Value.Substring(2, attribute.Value.Length - 4)));
                    DekiScriptXmlElement.Attribute attr = new DekiScriptXmlElement.Attribute(Location, attribute.Prefix, DekiScriptExpression.Constant(attribute.LocalName), expr);
                    result.Add(attr);
                }
                else if (!attribute.NamespaceURI.EqualsInvariant("http://www.w3.org/2000/xmlns/") || !attribute.Value.EqualsInvariant("http://mindtouch.com/2007/dekiscript"))
                {
                    // skip "init", "if", "foreach", "block", "where", "function" since they have already been processed
                    if (!attribute.NamespaceURI.EqualsInvariant(string.Empty) || !(
                            attribute.LocalName.EqualsInvariant("init") ||
                            attribute.LocalName.EqualsInvariant("if") ||
                            attribute.LocalName.EqualsInvariant("foreach") ||
                            attribute.LocalName.EqualsInvariant("where") ||
                            attribute.LocalName.EqualsInvariant("block") ||
                            attribute.LocalName.EqualsInvariant("function")
                            ))
                    {
                        // add static attribute
                        DekiScriptXmlElement.Attribute attr = new DekiScriptXmlElement.Attribute(Location, attribute.Prefix, DekiScriptExpression.Constant(attribute.LocalName), DekiScriptExpression.Constant(attribute.Value));
                        result.Add(attr);
                    }
                }
                PopNode();
            }
            return(result);
        }
 public DekiScriptExpressionInvocationTarget(DreamAccess access, DekiScriptParameter[] parameters, DekiScriptExpression expr, DekiScriptEnv env)
 {
     if (parameters == null)
     {
         throw new ArgumentNullException("parameters");
     }
     if (expr == null)
     {
         throw new ArgumentNullException("expr");
     }
     this.Access     = access;
     this.Parameters = parameters;
     this.Expression = expr;
     _env            = env;
 }
Ejemplo n.º 52
0
        private DekiScriptExpression Html(string container, string tag, string type, DekiScriptExpression expr)
        {
            DekiScriptExpression style = DekiScriptExpression.XmlElement(Location, null, DekiScriptExpression.Constant(tag), new[] { new DekiScriptXmlElement.Attribute(Location, null, DekiScriptExpression.Constant("type"), DekiScriptExpression.Constant(type)) }, expr);
            DekiScriptExpression head  = DekiScriptExpression.XmlElement(Location, null, DekiScriptExpression.Constant(container), null, style);
            DekiScriptExpression html  = DekiScriptExpression.XmlElement(Location, null, DekiScriptExpression.Constant("html"), null, head);

            return(html);
        }
 //--- Constructors ---
 public DekiScriptExpressionInvocationTarget(DreamAccess access, DekiScriptParameter[] parameters, DekiScriptExpression expr) : this(access, parameters, expr, null) { }
Ejemplo n.º 54
0
        private void Test(string expression)
        {
            DekiScriptExpression expr = DekiScriptParser.Parse(Location.Start, expression);

            Assert.AreEqual(expression, expr.ToString());
        }
Ejemplo n.º 55
0
 private DekiScriptExpression TryCatch(DekiScriptExpression expr, bool scripted) {
     if(scripted) {
         var handler = DekiScriptExpression.Call(Location, DekiScriptExpression.Access(Location, DekiScriptExpression.Id(Location, "web"), DekiScriptExpression.Constant("showerror")), DekiScriptExpression.List(Location, new[] {DekiScriptExpression.Id(Location, "__error")}));
         return DekiScriptExpression.Block(Location, DekiScriptExpression.TryCatchFinally(Location, expr, handler, DekiScriptNil.Value));
     }
     return expr;
 }
 //--- Extension Methods ---
 public static DekiScriptExpression Optimize(this DekiScriptRuntime runtime, DekiScriptExpression expr, DekiScriptEvalMode mode, DekiScriptEnv env)
 {
     return(expr.VisitWith(DekiScriptExpressionOptimizer.Instance, new DekiScriptExpressionEvaluationState(mode, env, runtime, TimeSpan.MaxValue, int.MaxValue)));
 }
Ejemplo n.º 57
0
        private void AddXDoc(XmlNode contextualbody, XDoc doc)
        {
            // check if this is a no-op
            if (doc.IsEmpty)
            {
                return;
            }

            // create a sub-buffer for processing
            DekiScriptOutputBuffer buffer = new DekiScriptOutputBuffer(int.MaxValue);

            // push all nodes from the XML document into the buffer
            Stack <XmlNode> stack = new Stack <XmlNode>();

            // check if we're dealing with a simple <html><body> ... </body></html> document
            bool addSiblings = false;

            if ((doc.AsXmlNode.NodeType == XmlNodeType.Element) && doc.HasName("html") && doc["head/*"].IsEmpty && doc["tail/*"].IsEmpty && doc["body[@target]"].IsEmpty)
            {
                var body = doc["body"];
                if (body.IsEmpty || (body.AsXmlNode.ChildNodes.Count == 0))
                {
                    // nothing to do
                    return;
                }
                doc         = doc[body.AsXmlNode.FirstChild];
                addSiblings = true;
            }

            // loop over nodes
            XmlNode current = doc.AsXmlNode;

            do
            {
                XmlElement element;
                switch (current.NodeType)
                {
                case XmlNodeType.Element:
                    element = (XmlElement)current;
                    AppendXmlStart(buffer, element);
                    if (element.HasChildNodes)
                    {
                        stack.Push(addSiblings || (stack.Count > 0) ? current.NextSibling : null);
                        current = element.FirstChild;
                        continue;
                    }
                    buffer.PushXmlEnd();
                    break;

                case XmlNodeType.Attribute:
                    buffer.Push(DekiScriptExpression.Constant((string.IsNullOrEmpty(current.Prefix) ? current.Name : current.Prefix + ":" + current.Name) + "=" + current.Value.QuoteString()));
                    break;

                case XmlNodeType.CDATA:
                case XmlNodeType.SignificantWhitespace:
                case XmlNodeType.Text:
                case XmlNodeType.Whitespace:
                    buffer.Push(DekiScriptExpression.Constant(current.Value));
                    break;

                default:

                    // ignore this node
                    break;
                }

                // move onto next item or resume previous one
                current = addSiblings || (stack.Count > 0) ? current.NextSibling : null;
                while ((current == null) && (stack.Count > 0))
                {
                    buffer.PushXmlEnd();
                    current = stack.Pop();
                }
            } while(current != null);

            // parse the sub-buffer
            ParseBuffer(buffer, 0, contextualbody, false);
        }
        //--- Class Methods ---
        public static XmlNode Evaluate(
            XDoc script,
            XmlElement node,
            DekiScriptEvalContext context,
            DekiScriptEnv env,
            DekiScriptRuntime runtime,
            out bool scripted,
            ref bool error
            )
        {
            if ((context.Mode != DekiScriptEvalMode.Verify) && (context.Mode != DekiScriptEvalMode.EvaluateEditOnly) && (context.Mode != DekiScriptEvalMode.EvaluateSaveOnly))
            {
                throw new InvalidOperationException("DekiScript interpreter can only used for save, edit, or verify evaluations.");
            }
            scripted = false;
            XmlNode next = node.NextSibling;

            try {
                // check if element needs to be evaluated
                if (StringUtil.EqualsInvariant(node.NamespaceURI, XDekiScript.ScriptNS))
                {
                    scripted = true;

                    // NOTE (steveb): <eval:xyz> nodes are not processed by the interpreter anymore
                }
                else
                {
                    XDoc current        = script[node];
                    bool hasScriptClass = StringUtil.EqualsInvariant(node.GetAttribute("class"), "script");

                    #region <elem class="script" init="..." if="..." foreach="..." where="..." block="...">
                    // check if element has form <elem class="script" init="..." if="..." foreach="..." where="..." block="...">
                    scripted = node.HasAttribute("init") || node.HasAttribute("if") || node.HasAttribute("foreach") || node.HasAttribute("block");
                    if (context.Mode == DekiScriptEvalMode.Verify)
                    {
                        // check if "block" is present
                        string blockAttr = node.GetAttribute("block");
                        if (!string.IsNullOrEmpty(blockAttr))
                        {
                            // TODO (steveb): validate script expression
                        }

                        // check if "foreach" is present
                        string foreachAttr = node.GetAttribute("foreach");
                        if (!string.IsNullOrEmpty(foreachAttr))
                        {
                            // TODO (steveb): validate script expression
                        }

                        // check if "if" is present
                        string ifAttr = node.GetAttribute("if");
                        if (!string.IsNullOrEmpty(ifAttr))
                        {
                            // TODO (steveb): validate script expression
                        }

                        // check if "init" is present
                        string initAttr = node.GetAttribute("init");
                        if (!string.IsNullOrEmpty(initAttr))
                        {
                            // TODO (steveb): validate script expression
                        }
                    }
                    #endregion

                    // evaluate child nodes
                    EvaluateChildren(script, node, context, env, runtime, out scripted, ref error);

                    #region evaluate attributes
                    for (int i = 0; i < node.Attributes.Count; ++i)
                    {
                        XmlAttribute attribute = node.Attributes[i];

                        // check if attribute needs to be evaluated
                        if (attribute.NamespaceURI == XDekiScript.ScriptNS)
                        {
                            scripted = true;

                            // NOTE (steveb): eval:xyz="abc" attributes are not processed by the interpreter anymore
                        }
                        else if (StringUtil.StartsWithInvariant(attribute.Value, "{{") && StringUtil.EndsWithInvariant(attribute.Value, "}}"))
                        {
                            scripted = true;

                            // NOTE (steveb): key="{{value}}"
                            string code = attribute.Value.Substring(2, attribute.Value.Length - 4).Trim();

                            // check if script content is substituted
                            bool isPermanentReplacement = false;
                            if (StringUtil.StartsWithInvariantIgnoreCase(code, DekiScriptRuntime.ON_SAVE_PATTERN))
                            {
                                isPermanentReplacement = (context.Mode == DekiScriptEvalMode.EvaluateSaveOnly);
                                code = code.Substring(DekiScriptRuntime.ON_SAVE_PATTERN.Length);
                            }
                            else if (StringUtil.StartsWithInvariantIgnoreCase(code, DekiScriptRuntime.ON_SUBST_PATTERN))
                            {
                                isPermanentReplacement = (context.Mode == DekiScriptEvalMode.EvaluateSaveOnly);
                                code = code.Substring(DekiScriptRuntime.ON_SUBST_PATTERN.Length);
                            }
                            else if (StringUtil.StartsWithInvariantIgnoreCase(code, DekiScriptRuntime.ON_EDIT_PATTERN))
                            {
                                isPermanentReplacement = (context.Mode == DekiScriptEvalMode.EvaluateEditOnly);
                                code = code.Substring(DekiScriptRuntime.ON_EDIT_PATTERN.Length);
                            }

                            // parse expression
                            if ((context.Mode == DekiScriptEvalMode.Verify) || isPermanentReplacement)
                            {
                                DekiScriptExpression expression = DekiScriptParser.Parse(ComputeNodeLocation(attribute), code);
                                if (isPermanentReplacement)
                                {
                                    DekiScriptLiteral eval = runtime.Evaluate(expression, DekiScriptEvalMode.EvaluateSafeMode, env);

                                    // determine what the outcome value is
                                    string value = eval.AsString();

                                    // check if we have a value to replace the current attribute with
                                    if ((value != null) && !DekiScriptLibrary.ContainsXSSVulnerability(attribute.LocalName, value))
                                    {
                                        attribute.Value = value;
                                    }
                                    else
                                    {
                                        node.Attributes.RemoveAt(i);
                                        --i;
                                    }
                                }
                            }
                        }
                    }
                    #endregion

                    #region evaluate <span class="script"> or <pre class="script">
                    if (hasScriptClass && (StringUtil.EqualsInvariant(node.LocalName, "pre") || StringUtil.EqualsInvariant(node.LocalName, "span")) && !node.HasAttribute("function"))
                    {
                        // replace the non-breaking space character with space
                        string code = node.InnerText.ReplaceAll("\u00A0", " ", "\u00AD", "").Trim();

                        // check if script content is substituted
                        bool isPermanentReplacement = false;
                        if (StringUtil.StartsWithInvariantIgnoreCase(code, DekiScriptRuntime.ON_SAVE_PATTERN))
                        {
                            isPermanentReplacement = (context.Mode == DekiScriptEvalMode.EvaluateSaveOnly);
                            code = code.Substring(DekiScriptRuntime.ON_SAVE_PATTERN.Length);
                        }
                        else if (StringUtil.StartsWithInvariantIgnoreCase(code, DekiScriptRuntime.ON_SUBST_PATTERN))
                        {
                            isPermanentReplacement = (context.Mode == DekiScriptEvalMode.EvaluateSaveOnly);
                            code = code.Substring(DekiScriptRuntime.ON_SUBST_PATTERN.Length);
                        }
                        else if (StringUtil.StartsWithInvariantIgnoreCase(code, DekiScriptRuntime.ON_EDIT_PATTERN))
                        {
                            isPermanentReplacement = (context.Mode == DekiScriptEvalMode.EvaluateEditOnly);
                            code = code.Substring(DekiScriptRuntime.ON_EDIT_PATTERN.Length);
                        }

                        // parse expression
                        if ((context.Mode == DekiScriptEvalMode.Verify) || isPermanentReplacement)
                        {
                            DekiScriptExpression expression = DekiScriptParser.Parse(ComputeNodeLocation(node), code);
                            if (isPermanentReplacement)
                            {
                                DekiScriptLiteral value = runtime.Evaluate(expression, DekiScriptEvalMode.EvaluateSafeMode, env);
                                context.ReplaceNodeWithValue(node, value);
                            }
                            if (!isPermanentReplacement)
                            {
                                scripted = true;
                            }
                        }
                    }
                    #endregion
                }
            } catch (Exception e) {
                // only embed error in verify mode, not in save/edit modes
                if (context.Mode == DekiScriptEvalMode.Verify)
                {
                    context.InsertExceptionMessageBeforeNode(env, node.ParentNode, node, ComputeNodeLocation(node), e);
                    node.ParentNode.RemoveChild(node);
                }
                error |= true;
            }
            return(next);
        }
Ejemplo n.º 59
0
        protected override Yield Start(XDoc config, Result result)
        {
            yield return(Coroutine.Invoke(base.Start, config, new Result()));

            // loop over all resources
            Type   type     = GetType();
            string assembly = type.Assembly.FullName.Split(new char[] { ',' }, 2)[0];

            foreach (DekiExtLibraryFilesAttribute files in Attribute.GetCustomAttributes(type, typeof(DekiExtLibraryFilesAttribute)))
            {
                string prefix = files.Prefix ?? type.Namespace;
                foreach (string filename in files.Filenames)
                {
                    MimeType mime = MimeType.FromFileExtension(filename);
                    _files[filename] = Plug.New(string.Format("resource://{0}/{1}.{2}", assembly, prefix, filename)).With("dream.out.type", mime.FullType);
                }
            }

            // check if a public digital signature key was provided
            string dsaKey = config["deki-signature"].AsText ?? config["dekiwiki-signature"].AsText;

            if (dsaKey != null)
            {
                try {
                    DSACryptoServiceProvider dsa = new DSACryptoServiceProvider();
                    dsa.ImportCspBlob(Convert.FromBase64String(dsaKey));
                    _publicDigitalSignature = dsa;
                } catch {
                    throw new ArgumentException("invalid digital signature provided", "deki-signature");
                }
            }

            // loop over all instance methods
            foreach (MethodInfo method in type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
            {
                // check if it has the DekiExtFunction attriute
                DekiExtFunctionAttribute ext = (DekiExtFunctionAttribute)Attribute.GetCustomAttribute(method, typeof(DekiExtFunctionAttribute));
                if (ext != null)
                {
                    // check if function has an associated script
                    XDekiScript script = null;
                    DekiExtFunctionScriptAttribute scriptAttr = (DekiExtFunctionScriptAttribute)Attribute.GetCustomAttribute(method, typeof(DekiExtFunctionScriptAttribute));
                    if (scriptAttr != null)
                    {
                        DreamMessage scriptresource = Plug.New(string.Format("resource://{0}/{1}.{2}", assembly, scriptAttr.Prefix ?? type.Namespace, scriptAttr.Scriptname)).With("dream.out.type", MimeType.XML.FullType).GetAsync().Wait();
                        if (scriptresource.IsSuccessful)
                        {
                            script = new XDekiScript(scriptresource.ToDocument());
                        }
                        if (script == null)
                        {
                            throw new InvalidOperationException(string.Format("method '{0}' is declard as script, but script could not be loaded", method.Name));
                        }
                    }

                    // add function
                    Add(ext, method, script);
                }
            }

            // add configuration settings
            var context = DreamContext.Current;

            _scriptConfig = new DekiScriptMap();
            foreach (KeyValuePair <string, string> entry in Config.ToKeyValuePairs())
            {
                XUri local;
                if (XUri.TryParse(entry.Value, out local))
                {
                    local = context.AsPublicUri(local);
                    _scriptConfig.AddAt(entry.Key.Split('/'), DekiScriptExpression.Constant(local.ToString()));
                }
                else
                {
                    _scriptConfig.AddAt(entry.Key.Split('/'), DekiScriptExpression.Constant(entry.Value));
                }
            }
            result.Return();
        }
Ejemplo n.º 60
0
	void DefineConstruct(out DekiScriptExpression expr) {
		expr = null; DekiScriptExpression var; Location location = Location.None; 
		AssignLHS(out var);
		if (la.kind == 12) {
			Get();
			location = t.Location; 
			Expression(out expr);
			expr = DekiScriptExpression.VarStatement(location, var, expr); 
		} else if (StartOf(4)) {
			expr = DekiScriptExpression.VarStatement(location, var, DekiScriptNil.Value);
		} else SynErr(79);
	}