[OLINGO-659] Duplicated system query options in $expand lead to a http status 400 bad request

This commit is contained in:
Christian Holzer 2015-09-01 16:50:31 +02:00
parent a3541721ef
commit ccf361b8fe
3 changed files with 77 additions and 5 deletions

View File

@ -44,6 +44,7 @@ import org.apache.olingo.commons.api.edm.EdmSingleton;
import org.apache.olingo.commons.api.edm.EdmStructuredType;
import org.apache.olingo.commons.api.edm.EdmType;
import org.apache.olingo.commons.api.edm.FullQualifiedName;
import org.apache.olingo.commons.api.ex.ODataRuntimeException;
import org.apache.olingo.commons.core.edm.primitivetype.EdmPrimitiveTypeFactory;
import org.apache.olingo.server.api.uri.UriInfoKind;
import org.apache.olingo.server.api.uri.UriInfoResource;
@ -1202,13 +1203,25 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> {
} else if (ctx.vM != null) {
LevelsOptionImpl levels = new LevelsOptionImpl().setMax();
levels.setText(ctx.vM.getText());
expandItem.setSystemQueryOption(levels);
try {
expandItem.setSystemQueryOption(levels);
} catch(ODataRuntimeException e) {
// Thrown if duplicated system query options are detected
throw wrap(new UriParserSyntaxException("Double system query option!", e,
UriParserSyntaxException.MessageKeys.DOUBLE_SYSTEM_QUERY_OPTION, e.getMessage()));
}
} else if (ctx.vL != null) {
LevelsOptionImpl levels = new LevelsOptionImpl();
String text = ctx.vL.getText();
levels.setText(text);
levels.setValue(Integer.parseInt(text));
expandItem.setSystemQueryOption(levels);
try {
expandItem.setSystemQueryOption(levels);
} catch(ODataRuntimeException e) {
// Thrown if duplicated system query options are detected
throw wrap(new UriParserSyntaxException("Double system query option!", e,
UriParserSyntaxException.MessageKeys.DOUBLE_SYSTEM_QUERY_OPTION, e.getMessage()));
}
}
} else if (ctx.vEP != null) {
@ -1220,8 +1233,14 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> {
@SuppressWarnings("unchecked")
List<SystemQueryOptionImpl> list = (List<SystemQueryOptionImpl>) ctx.vEPE.accept(this);
for (SystemQueryOptionImpl option : list) {
expandItem.setSystemQueryOption(option);
try {
for (SystemQueryOptionImpl option : list) {
expandItem.setSystemQueryOption(option);
}
} catch(ODataRuntimeException e) {
// Thrown if duplicated system query options are detected
throw wrap(new UriParserSyntaxException("Double system query option!", e,
UriParserSyntaxException.MessageKeys.DOUBLE_SYSTEM_QUERY_OPTION, e.getMessage()));
}
context.contextExpandItemPath = contextExpandItemPathBU;
}

View File

@ -21,6 +21,7 @@ package org.apache.olingo.server.core.uri.queryoption;
import java.util.List;
import org.apache.olingo.commons.api.edm.EdmType;
import org.apache.olingo.commons.api.ex.ODataRuntimeException;
import org.apache.olingo.server.api.uri.UriInfoResource;
import org.apache.olingo.server.api.uri.queryoption.CountOption;
import org.apache.olingo.server.api.uri.queryoption.ExpandItem;
@ -31,6 +32,7 @@ import org.apache.olingo.server.api.uri.queryoption.OrderByOption;
import org.apache.olingo.server.api.uri.queryoption.SearchOption;
import org.apache.olingo.server.api.uri.queryoption.SelectOption;
import org.apache.olingo.server.api.uri.queryoption.SkipOption;
import org.apache.olingo.server.api.uri.queryoption.SystemQueryOption;
import org.apache.olingo.server.api.uri.queryoption.TopOption;
public class ExpandItemImpl implements ExpandItem {
@ -54,27 +56,44 @@ public class ExpandItemImpl implements ExpandItem {
public ExpandItemImpl setSystemQueryOption(final SystemQueryOptionImpl sysItem) {
if (sysItem instanceof ExpandOptionImpl) {
validateDoubleSystemQueryOption(expandOption, sysItem);
expandOption = (ExpandOptionImpl) sysItem;
} else if (sysItem instanceof FilterOptionImpl) {
validateDoubleSystemQueryOption(filterOption, sysItem);
filterOption = (FilterOptionImpl) sysItem;
} else if (sysItem instanceof CountOptionImpl) {
validateDoubleSystemQueryOption(inlineCountOption, sysItem);
inlineCountOption = (CountOptionImpl) sysItem;
} else if (sysItem instanceof OrderByOptionImpl) {
validateDoubleSystemQueryOption(orderByOption, sysItem);
orderByOption = (OrderByOptionImpl) sysItem;
} else if (sysItem instanceof SearchOptionImpl) {
validateDoubleSystemQueryOption(searchOption, sysItem);
searchOption = (SearchOptionImpl) sysItem;
} else if (sysItem instanceof SelectOptionImpl) {
validateDoubleSystemQueryOption(selectOption, sysItem);
selectOption = (SelectOptionImpl) sysItem;
} else if (sysItem instanceof SkipOptionImpl) {
validateDoubleSystemQueryOption(skipOption, sysItem);
skipOption = (SkipOptionImpl) sysItem;
} else if (sysItem instanceof TopOptionImpl) {
validateDoubleSystemQueryOption(topOption, sysItem);
topOption = (TopOptionImpl) sysItem;
} else if (sysItem instanceof LevelsExpandOption) {
if(levelsExpandOption != null) {
throw new ODataRuntimeException("$levels");
}
levelsExpandOption = (LevelsExpandOption) sysItem;
}
return this;
}
private void validateDoubleSystemQueryOption(final SystemQueryOption oldOption, final SystemQueryOption newOption) {
if(oldOption != null) {
throw new ODataRuntimeException(newOption.getName());
}
}
public ExpandItemImpl setSystemQueryOptions(final List<SystemQueryOptionImpl> list) {
for (SystemQueryOptionImpl item : list) {

View File

@ -2537,6 +2537,40 @@ public class TestFullResourcePath {
.isExSemantic(UriParserSemanticException.MessageKeys.EXPRESSION_PROPERTY_NOT_IN_TYPE);
}
@Test
public void runDuplicatedSystemQueryOptionsInExpand() throws UriParserException, UriValidationException {
testUri.runEx("ESKeyNav", "$expand=NavPropertyETKeyNavOne($select=PropertyInt16;$select=PropertyInt16)")
.isExSyntax(UriParserSyntaxException.MessageKeys.DOUBLE_SYSTEM_QUERY_OPTION);
testUri.runEx("ESKeyNav", "$expand=NavPropertyETKeyNavOne($filter=true;$filter=true)")
.isExSyntax(UriParserSyntaxException.MessageKeys.DOUBLE_SYSTEM_QUERY_OPTION);
testUri.runEx("ESKeyNav", "$expand=NavPropertyETKeyNavOne($orderby=PropertyInt16;$orderby=PropertyInt16)")
.isExSyntax(UriParserSyntaxException.MessageKeys.DOUBLE_SYSTEM_QUERY_OPTION);
testUri.runEx("ESKeyNav", "$expand=NavPropertyETKeyNavOne($levels=2;$levels=3)")
.isExSyntax(UriParserSyntaxException.MessageKeys.DOUBLE_SYSTEM_QUERY_OPTION);
testUri.runEx("ESKeyNav", "$expand=NavPropertyETKeyNavOne($expand=*;$expand=*)")
.isExSyntax(UriParserSyntaxException.MessageKeys.DOUBLE_SYSTEM_QUERY_OPTION);
testUri.runEx("ESKeyNav", "$expand=NavPropertyETKeyNavOne($count=true;$count=true)")
.isExSyntax(UriParserSyntaxException.MessageKeys.DOUBLE_SYSTEM_QUERY_OPTION);
testUri.runEx("ESKeyNav", "$expand=NavPropertyETKeyNavOne($top=1;$top=1)")
.isExSyntax(UriParserSyntaxException.MessageKeys.DOUBLE_SYSTEM_QUERY_OPTION);
testUri.runEx("ESKeyNav", "$expand=NavPropertyETKeyNavOne($skip=2;$skip=2)")
.isExSyntax(UriParserSyntaxException.MessageKeys.DOUBLE_SYSTEM_QUERY_OPTION);
}
@Test
@Ignore("$search currently not implemented")
public void runDuplicatedSearchExpand() throws UriParserException, UriValidationException {
testUri.runEx("ESKeyNav", "$expand=NavPropertyETKeyNavOne($search=Test;$search=Test)")
.isExSyntax(UriParserSyntaxException.MessageKeys.DOUBLE_SYSTEM_QUERY_OPTION);
}
@Test
public void runTop() throws Exception {
// top