Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/aspnetwebstack.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordavidmatson <dmatson@microsoft.com>2012-10-23 02:05:03 +0400
committerdavidmatson <dmatson@microsoft.com>2012-10-24 03:13:04 +0400
commitcd4a1accc3b3c7e9d418c9217bbe324aa1ae54ea (patch)
tree055c53985540e60b1cd0cb603222b654fb88b770 /src
parentc794e8b418238a29d23d1833c8565c715a6e8767 (diff)
Incorporate code review feedback.
Diffstat (limited to 'src')
-rw-r--r--src/System.Web.Http.OData/OData/Query/Expressions/FilterBinder.cs122
-rw-r--r--src/System.Web.Http.OData/OData/Query/ODataQuerySettings.cs37
-rw-r--r--src/System.Web.Http.OData/Properties/SRResources.Designer.cs2
-rw-r--r--src/System.Web.Http.OData/Properties/SRResources.resx2
-rw-r--r--src/System.Web.Http.OData/QueryableAttribute.cs19
5 files changed, 121 insertions, 61 deletions
diff --git a/src/System.Web.Http.OData/OData/Query/Expressions/FilterBinder.cs b/src/System.Web.Http.OData/OData/Query/Expressions/FilterBinder.cs
index 5329bd30..5a2c19b8 100644
--- a/src/System.Web.Http.OData/OData/Query/Expressions/FilterBinder.cs
+++ b/src/System.Web.Http.OData/OData/Query/Expressions/FilterBinder.cs
@@ -31,7 +31,7 @@ namespace System.Web.Http.OData.Query.Expressions
/// restrict the maximum number of expressions that we generate to prevent DoS attacks.
/// </summary>
private const int MaxBindCount = 100;
- private int _currentBindCount = 0;
+ private int _currentBindCount;
private int _currentLambdaNestingCount;
private static readonly MethodInfo _stringCompareMethodInfo = typeof(string).GetMethod("Compare", new[] { typeof(string), typeof(string), typeof(StringComparison) });
@@ -806,38 +806,44 @@ namespace System.Web.Http.OData.Query.Expressions
{
EnterLambda();
- ParameterExpression allIt = HandleLambdaParameters(allQueryNode.Parameters);
+ Expression returnValue;
- Expression source;
- Contract.Assert(allQueryNode.Source != null);
- source = Bind(allQueryNode.Source);
+ try
+ {
+ ParameterExpression allIt = HandleLambdaParameters(allQueryNode.Parameters);
- Expression body = source;
- Contract.Assert(allQueryNode.Body != null);
+ Expression source;
+ Contract.Assert(allQueryNode.Source != null);
+ source = Bind(allQueryNode.Source);
- body = Bind(allQueryNode.Body);
- body = ApplyNullPropagationForFilterBody(body);
- body = Expression.Lambda(body, allIt);
+ Expression body = source;
+ Contract.Assert(allQueryNode.Body != null);
- Expression all = All(source, body);
- Expression returnValue;
+ body = Bind(allQueryNode.Body);
+ body = ApplyNullPropagationForFilterBody(body);
+ body = Expression.Lambda(body, allIt);
- if (_querySettings.HandleNullPropagation == HandleNullPropagationOption.True && IsNullable(source.Type))
- {
- // IFF(source == null) null; else Any(body);
- all = ToNullable(all);
- returnValue = Expression.Condition(
- test: Expression.Equal(source, _nullConstant),
- ifTrue: Expression.Constant(null, all.Type),
- ifFalse: all);
+ Expression all = All(source, body);
+
+ if (_querySettings.HandleNullPropagation == HandleNullPropagationOption.True && IsNullable(source.Type))
+ {
+ // IFF(source == null) null; else Any(body);
+ all = ToNullable(all);
+ returnValue = Expression.Condition(
+ test: Expression.Equal(source, _nullConstant),
+ ifTrue: Expression.Constant(null, all.Type),
+ ifFalse: all);
+ }
+ else
+ {
+ returnValue = all;
+ }
}
- else
+ finally
{
- returnValue = all;
+ ExitLambda();
}
- ExitLambda();
-
return returnValue;
}
@@ -845,40 +851,46 @@ namespace System.Web.Http.OData.Query.Expressions
{
EnterLambda();
- ParameterExpression anyIt = HandleLambdaParameters(anyQueryNode.Parameters);
-
- Expression source;
- Contract.Assert(anyQueryNode.Source != null);
- source = Bind(anyQueryNode.Source);
+ Expression returnValue;
- Expression body = null;
- // uri parser places an Constant node with value true for empty any() body
- if (anyQueryNode.Body != null && anyQueryNode.Body.Kind != QueryNodeKind.Constant)
+ try
{
- body = Bind(anyQueryNode.Body);
- body = ApplyNullPropagationForFilterBody(body);
- body = Expression.Lambda(body, anyIt);
- }
+ ParameterExpression anyIt = HandleLambdaParameters(anyQueryNode.Parameters);
- Expression any = Any(source, body);
- Expression returnValue;
+ Expression source;
+ Contract.Assert(anyQueryNode.Source != null);
+ source = Bind(anyQueryNode.Source);
- if (_querySettings.HandleNullPropagation == HandleNullPropagationOption.True && IsNullable(source.Type))
- {
- // IFF(source == null) null; else Any(body);
- any = ToNullable(any);
- returnValue = Expression.Condition(
- test: Expression.Equal(source, _nullConstant),
- ifTrue: Expression.Constant(null, any.Type),
- ifFalse: any);
+ Expression body = null;
+ // uri parser places an Constant node with value true for empty any() body
+ if (anyQueryNode.Body != null && anyQueryNode.Body.Kind != QueryNodeKind.Constant)
+ {
+ body = Bind(anyQueryNode.Body);
+ body = ApplyNullPropagationForFilterBody(body);
+ body = Expression.Lambda(body, anyIt);
+ }
+
+ Expression any = Any(source, body);
+
+ if (_querySettings.HandleNullPropagation == HandleNullPropagationOption.True && IsNullable(source.Type))
+ {
+ // IFF(source == null) null; else Any(body);
+ any = ToNullable(any);
+ returnValue = Expression.Condition(
+ test: Expression.Equal(source, _nullConstant),
+ ifTrue: Expression.Constant(null, any.Type),
+ ifFalse: any);
+ }
+ else
+ {
+ returnValue = any;
+ }
}
- else
+ finally
{
- returnValue = any;
+ ExitLambda();
}
- ExitLambda();
-
return returnValue;
}
@@ -922,26 +934,28 @@ namespace System.Web.Http.OData.Query.Expressions
private void IncrementBindCount()
{
- if (++_currentBindCount > MaxBindCount)
+ if (_currentBindCount >= MaxBindCount)
{
throw new ODataException(SRResources.RecursionLimitExceeded);
}
+
+ _currentBindCount++;
}
private void EnterLambda()
{
if (_currentLambdaNestingCount >= _querySettings.LambdaNestingLimit)
{
- throw new ODataException(SRResources.LambdaNestingLimitExceeded);
+ throw new ODataException(Error.Format(SRResources.LambdaNestingLimitExceeded, _querySettings.LambdaNestingLimit));
}
- ++_currentLambdaNestingCount;
+ _currentBindCount++;
}
private void ExitLambda()
{
Contract.Assert(_currentLambdaNestingCount > 0);
- --_currentLambdaNestingCount;
+ _currentLambdaNestingCount--;
}
// If the expression is of non-standard edm primitive type (like uint), convert the expression to its standard edm type.
diff --git a/src/System.Web.Http.OData/OData/Query/ODataQuerySettings.cs b/src/System.Web.Http.OData/OData/Query/ODataQuerySettings.cs
index afb43538..26f299aa 100644
--- a/src/System.Web.Http.OData/OData/Query/ODataQuerySettings.cs
+++ b/src/System.Web.Http.OData/OData/Query/ODataQuerySettings.cs
@@ -8,6 +8,8 @@ namespace System.Web.Http.OData.Query
public class ODataQuerySettings
{
private HandleNullPropagationOption _handleNullPropagationOption = HandleNullPropagationOption.Default;
+ private int _lambdaNestingLimit = 1;
+ private int? _resultLimit;
/// <summary>
/// Instantiates a new instance of the <see cref="ODataQuerySettings"/> class
@@ -16,7 +18,6 @@ namespace System.Web.Http.OData.Query
public ODataQuerySettings()
{
EnsureStableOrdering = true;
- LambdaNestingLimit = 1;
}
/// <summary>
@@ -60,7 +61,22 @@ namespace System.Web.Http.OData.Query
/// <value>
/// The maxiumum depth of the Any or All elements nested inside the query.
/// </value>
- public int LambdaNestingLimit { get; set; }
+ public int LambdaNestingLimit
+ {
+ get
+ {
+ return _lambdaNestingLimit;
+ }
+ set
+ {
+ if (value <= 0)
+ {
+ throw Error.ArgumentMustBeGreaterThanOrEqualTo("value", value, 1);
+ }
+
+ _lambdaNestingLimit = value;
+ }
+ }
/// <summary>
/// Gets or sets the maximum number of query results to return.
@@ -68,6 +84,21 @@ namespace System.Web.Http.OData.Query
/// <value>
/// The maximum number of query results to return, or <c>null</c> if there is no limit.
/// </value>
- public int? ResultLimit { get; set; }
+ public int? ResultLimit
+ {
+ get
+ {
+ return _resultLimit;
+ }
+ set
+ {
+ if (value.HasValue && value <= 0)
+ {
+ throw Error.ArgumentMustBeGreaterThanOrEqualTo("value", value, 1);
+ }
+
+ _resultLimit = value;
+ }
+ }
}
}
diff --git a/src/System.Web.Http.OData/Properties/SRResources.Designer.cs b/src/System.Web.Http.OData/Properties/SRResources.Designer.cs
index ac4718f4..f3b9c3a9 100644
--- a/src/System.Web.Http.OData/Properties/SRResources.Designer.cs
+++ b/src/System.Web.Http.OData/Properties/SRResources.Designer.cs
@@ -556,7 +556,7 @@ namespace System.Web.Http.OData.Properties {
}
/// <summary>
- /// Looks up a localized string similar to The Any/All nesting limit has been exceeded..
+ /// Looks up a localized string similar to The Any/All nesting limit of {0} has been exceeded. LambdaNestingLimit can be configured on ODataQuerySettings or QueryableAttribute..
/// </summary>
internal static string LambdaNestingLimitExceeded {
get {
diff --git a/src/System.Web.Http.OData/Properties/SRResources.resx b/src/System.Web.Http.OData/Properties/SRResources.resx
index 9cc8edf2..9b0e5ca8 100644
--- a/src/System.Web.Http.OData/Properties/SRResources.resx
+++ b/src/System.Web.Http.OData/Properties/SRResources.resx
@@ -439,7 +439,7 @@
<value>Queries can not be applied to a response content of type '{0}'. The response content must be an ObjectContent.</value>
</data>
<data name="LambdaNestingLimitExceeded" xml:space="preserve">
- <value>The Any/All nesting limit has been exceeded.</value>
+ <value>The Any/All nesting limit of {0} has been exceeded. LambdaNestingLimit can be configured on ODataQuerySettings or QueryableAttribute.</value>
</data>
<data name="NoODataFormatterForMetadata" xml:space="preserve">
<value>No OData formatter was found to write the OData metadata. Consider registering an appropriate ODataMediaTypeFormatter on the configuration's formatter collection.</value>
diff --git a/src/System.Web.Http.OData/QueryableAttribute.cs b/src/System.Web.Http.OData/QueryableAttribute.cs
index bf974591..edc8cf13 100644
--- a/src/System.Web.Http.OData/QueryableAttribute.cs
+++ b/src/System.Web.Http.OData/QueryableAttribute.cs
@@ -22,6 +22,7 @@ namespace System.Web.Http
public class QueryableAttribute : ActionFilterAttribute
{
private HandleNullPropagationOption _handleNullPropagationOption = HandleNullPropagationOption.Default;
+ private int _lambdaNestingLimit = 1;
private int? _resultLimit;
/// <summary>
@@ -30,7 +31,6 @@ namespace System.Web.Http
public QueryableAttribute()
{
EnsureStableOrdering = true;
- LambdaNestingLimit = 1;
}
/// <summary>
@@ -74,7 +74,22 @@ namespace System.Web.Http
/// <value>
/// The maxiumum depth of the Any or All elements nested inside the query.
/// </value>
- public int LambdaNestingLimit { get; set; }
+ public int LambdaNestingLimit
+ {
+ get
+ {
+ return _lambdaNestingLimit;
+ }
+ set
+ {
+ if (value <= 0)
+ {
+ throw Error.ArgumentMustBeGreaterThanOrEqualTo("value", value, 1);
+ }
+
+ _lambdaNestingLimit = value;
+ }
+ }
/// <summary>
/// Gets or sets the maximum number of query results to send back to clients.