Skip to content

Commit

Permalink
ODATA-1583 (#106)
Browse files Browse the repository at this point in the history
* ODATA-1583

* ODATA-1540

* Plus in URL needs percent-encoding

* Update odata-abnf-construction-rules.txt

* Update odata-abnf-construction-rules.txt

* Update odata-abnf-construction-rules.txt

* Update odata-abnf-construction-rules.txt

* No percent-encoding in context URLs

* enumLiteral and enumValue

* Update odata-abnf-construction-rules.txt

* Negative test case for key-as-segment

* Another unencoded slash, just to be sure

---------

Co-authored-by: Heiko Theißen <[email protected]>
  • Loading branch information
ralfhandl and HeikoTheissen authored May 22, 2024
1 parent 44738ed commit 7f529f2
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 5 deletions.
28 changes: 23 additions & 5 deletions abnf/odata-abnf-construction-rules.txt
Original file line number Diff line number Diff line change
Expand Up @@ -442,16 +442,34 @@ contextFragment = %s"Collection($ref)"
/ singletonEntity [ navigation *( containmentNavigation ) [ "/" qualifiedEntityTypeName ] ] [ selectList ]
/ qualifiedTypeName [ selectList ]
/ entitySet ( %s"/$deletedEntity" / %s"/$link" / %s"/$deletedLink" )
/ entitySet keyPredicate "/" contextPropertyPath [ selectList ]
/ entitySet contextKeyPredicate "/" contextPropertyPath [ selectList ]
/ entitySet [ selectList ] [ %s"/$entity" / %s"/$delta" ]

entitySet = entitySetName *( containmentNavigation ) [ "/" qualifiedEntityTypeName ]

containmentNavigation = keyPredicate [ "/" qualifiedEntityTypeName ] navigation
containmentNavigation = contextKeyPredicate [ "/" qualifiedEntityTypeName ] navigation
navigation = *( "/" complexProperty [ "/" qualifiedComplexTypeName ] ) "/" navigationProperty

selectList = OPEN [ selectListItem *( COMMA selectListItem ) ] CLOSE
selectListItem = STAR ; all structural properties
contextKeyPredicate = "(" ( contextKeyValue / contextKeyValuePair *( "," contextKeyValuePair ) ) ")"
contextKeyValuePair = ( primitiveKeyProperty / keyPropertyAlias ) EQ contextKeyValue
contextKeyValue = boolean
/ guid
/ dateTimeOffsetValue
/ date
/ timeOfDayValue
/ decimalValue
/ sbyteValue
/ byte
/ int16Value
/ int32Value
/ int64Value
/ stringValue
/ durationValue
/ enumValue
stringValue = %x27 *( %x00-26 / %x27 %x27 / %x28-FF) %x27 ; SQUOTE = %x27

selectList = "(" [ selectListItem *( "," selectListItem ) ] ")"
selectListItem = "*" ; all structural properties
/ allOperationsInSchema
/ [ ( qualifiedEntityTypeName / qualifiedComplexTypeName ) "/" ]
( qualifiedActionName
Expand All @@ -469,7 +487,7 @@ contextPropertyPath = primitiveProperty
/ complexProperty [ [ "/" qualifiedComplexTypeName ] "/" contextPropertyPath ]

qualifiedActionName = namespace "." action
qualifiedFunctionName = namespace "." function [ OPEN parameterNames CLOSE ]
qualifiedFunctionName = namespace "." function [ "(" parameterName *( "," parameterName ) ")" ]

complexAnnotationInFragment = annotationInFragment ; complex-valued annotation
entityAnnotationInFragment = annotationInFragment ; entity-valued annotation
Expand Down
33 changes: 33 additions & 0 deletions abnf/odata-abnf-testcases.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ Constraints:
- ProductsByCustomer
- ProductsOrderedBy
entityColNavigationProperty:
- Details
- DirectReports
- Items
- Orders
Expand Down Expand Up @@ -3363,6 +3364,21 @@ TestCases:
Rule: context
Input: "#Customers(Address/Country)"

- Name: Context URL - no percent-encoding allowed
Rule: context
FailAt: 18
Input: "#Customers(Address%2FStreet)"

- Name: Context URL - no percent-encoding allowed
Rule: context
FailAt: 18
Input: "#Customers(Address%2COrders)"

- Name: Context URL - no percent-encoding allowed
Rule: context
FailAt: 10
Input: "#Customers%28Address,Orders)"

- Name: Context URL - Entity set with $select and type-cast
Rule: context
Input: "#Customers(Address/Model.AddressWithLocation,Orders)"
Expand Down Expand Up @@ -3459,14 +3475,31 @@ TestCases:
Rule: context
Input: "#SingletonEntity/Orders(3)/Items"

- Name: Context URL - Forbidden key-as-segment
Rule: context
FailAt: 8
Input: "#Orders/3/Items"

- Name: Context URL - collection with containment
Rule: context
Input: "#Customers('ALFKI')/Orders"

- Name: Context URL - collection with containment, key value without percent-encoding
Rule: context
Input: "#Customers('ALF/KI')/Orders"

- Name: Context URL - collection with containment, key value without percent-encoding
Rule: context
Input: "#Customers('%')/Orders"

- Name: Context URL - containment
Rule: context
Input: "#Customers('ALFKI')/Orders/$entity"

- Name: Context URL - containment - multi-part key
Rule: context
Input: "#OrderItems(OrderID=1,ItemID='a/b')/Details/$entity"

- Name: Context URL - collection with containment - multi-level
Rule: context
Input: "#Customers('ALFKI')/Orders(1)/Items"
Expand Down

0 comments on commit 7f529f2

Please sign in to comment.