示例#1
0
        public SecurityExpressionVisitor(QbservableServiceOptions serviceOptions)
        {
            this.options = serviceOptions.ExpressionOptions;
            this.context = serviceOptions.EvaluationContext;

            if (options.HasFlag(ExpressionOptions.AllowTypeTests) &&
                options.HasFlag(ExpressionOptions.AllowExplicitConversions))
            {
                context.EnsureHasKnownOperator("Cast");
                context.EnsureHasKnownOperator("OfType");
            }

            if (options.HasFlag(ExpressionOptions.AllowCatchBlocks))
            {
                context.EnsureHasKnownOperator("Catch");
                context.EnsureHasKnownOperator("OnErrorResumeNext");
                context.EnsureHasKnownOperator("Retry");
            }
        }
示例#2
0
        public static ExpressionNode Parse(string buffer, int startOffset, int endOffset, ExpressionOptions options, int baseOffset)
        {
            List <ExpressionNode> splitList = null;
            var nodes = new List <ExpressionNode> ();

            int lastNodeEnd = startOffset;

            for (int offset = startOffset; offset <= endOffset; offset++)
            {
                char c = buffer [offset];

                //consume entities simply so the semicolon doesn't mess with list parsing
                //we don't need the value and the base XML editor will handle errors
                if (c == '&')
                {
                    offset++;
                    //FIXME: use proper entity name logic. this will do for now.
                    var name = ReadName(buffer, ref offset, endOffset);
                    if (offset > endOffset)
                    {
                        break;
                    }
                    if (buffer[offset] == ';')
                    {
                        continue;
                    }
                    c = buffer [offset];
                }

                if ((options.HasFlag(ExpressionOptions.Lists) && c == ';') || (c == ',' && options.HasFlag(ExpressionOptions.CommaLists)))
                {
                    CaptureLiteral(offset, nodes.Count == 0);
                    if (splitList == null)
                    {
                        splitList = new List <ExpressionNode> ();
                    }
                    FlushNodesToSplitList(offset);
                    lastNodeEnd = offset + 1;
                    continue;
                }

                int possibleLiteralEndOffset = offset;

                ExpressionNode node;
                switch (c)
                {
                case '@':
                    if (!TryConsumeParen())
                    {
                        continue;
                    }
                    if (options.HasFlag(ExpressionOptions.Items))
                    {
                        node = ParseItem(buffer, ref offset, endOffset, baseOffset);
                    }
                    else
                    {
                        node = new ExpressionError(baseOffset + offset, ExpressionErrorKind.ItemsDisallowed);
                    }
                    break;

                case '$':
                    if (!TryConsumeParen())
                    {
                        continue;
                    }
                    node = ParseProperty(buffer, ref offset, endOffset, baseOffset);
                    break;

                case '%':
                    if (!TryConsumeParen())
                    {
                        continue;
                    }
                    if (options.HasFlag(ExpressionOptions.Metadata))
                    {
                        node = ParseMetadata(buffer, ref offset, endOffset, baseOffset);
                    }
                    else
                    {
                        node = new ExpressionError(baseOffset + offset, ExpressionErrorKind.MetadataDisallowed);
                    }
                    break;

                default:
                    continue;
                }

                CaptureLiteral(possibleLiteralEndOffset, false);
                lastNodeEnd = offset + 1;

                nodes.Add(node);
                if (node is ExpressionError)
                {
                    //short circuit out without capturing the rest as text, since it's not useful
                    return(CreateResult(offset));
                }

                bool TryConsumeParen()
                {
                    if (offset < endOffset && buffer[offset + 1] == '(')
                    {
                        offset++;
                        offset++;
                        return(true);
                    }
                    return(false);
                }
            }

            CaptureLiteral(endOffset + 1, nodes.Count == 0);
            return(CreateResult(endOffset));

            void CaptureLiteral(int toOffset, bool isPure)
            {
                if (toOffset > lastNodeEnd)
                {
                    string s = buffer.Substring(lastNodeEnd, toOffset - lastNodeEnd);
                    nodes.Add(new ExpressionText(baseOffset + lastNodeEnd, s, isPure));
                }
            }

            void FlushNodesToSplitList(int offset)
            {
                if (nodes.Count == 0)
                {
                    splitList.Add(new ExpressionError(baseOffset + offset, ExpressionErrorKind.EmptyListEntry));
                }
                else if (nodes.Count == 1)
                {
                    splitList.Add(nodes [0]);
                    nodes.Clear();
                }
                else
                {
                    var start = nodes [0].Offset;
                    var l     = nodes [nodes.Count - 1].End - start;
                    splitList.Add(new Expression(start, l, nodes.ToArray()));
                    nodes.Clear();
                }
            }

            ExpressionNode CreateResult(int offset)
            {
                if (splitList != null)
                {
                    FlushNodesToSplitList(offset);
                }
                if (splitList != null)
                {
                    return(new ExpressionList(baseOffset + startOffset, endOffset - startOffset + 1, splitList.ToArray()));
                }
                if (nodes.Count == 0)
                {
                    return(new ExpressionText(baseOffset + startOffset, "", true));
                }
                if (nodes.Count == 1)
                {
                    return(nodes [0]);
                }
                return(new Expression(baseOffset + startOffset, endOffset - startOffset + 1, nodes.ToArray()));
            }
        }
示例#3
0
        protected override Expression VisitBinary(BinaryExpression node)
        {
            if (!options.HasFlag(ExpressionOptions.AllowAssignments))
            {
                switch (node.NodeType)
                {
                case ExpressionType.AddAssign:
                case ExpressionType.AddAssignChecked:
                case ExpressionType.AndAssign:
                case ExpressionType.Assign:
                case ExpressionType.DivideAssign:
                case ExpressionType.ExclusiveOrAssign:
                case ExpressionType.LeftShiftAssign:
                case ExpressionType.ModuloAssign:
                case ExpressionType.MultiplyAssign:
                case ExpressionType.MultiplyAssignChecked:
                case ExpressionType.OrAssign:
                case ExpressionType.PostDecrementAssign:
                case ExpressionType.PostIncrementAssign:
                case ExpressionType.PowerAssign:
                case ExpressionType.PreDecrementAssign:
                case ExpressionType.PreIncrementAssign:
                case ExpressionType.RightShiftAssign:
                case ExpressionType.SubtractAssign:
                case ExpressionType.SubtractAssignChecked:
                    throw new ExpressionSecurityException("Assignments are not permitted.");
                }
            }

            return(base.VisitBinary(node));
        }