CompletionFieldMapper: Return error if weight is no integer

In order to make sure that people do not get confused, if they
index a float as weight, it makes more sense to reject it instead of
silently parsing it to an integer and using it.

The CompletionFieldMapper now checks for the type of the number which
is being read and throws and exception if the number is something else
than int or long.

Closes #3977
This commit is contained in:
Alexander Reelsen 2013-10-25 16:38:24 +02:00
parent e79f714b4b
commit f9154de04f
2 changed files with 25 additions and 1 deletions

View File

@ -45,6 +45,8 @@ import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import static org.elasticsearch.common.xcontent.XContentParser.NumberType;
/** /**
* *
*/ */
@ -248,9 +250,13 @@ public class CompletionFieldMapper extends AbstractFieldMapper<String> {
} }
} else if (token == XContentParser.Token.VALUE_NUMBER) { } else if (token == XContentParser.Token.VALUE_NUMBER) {
if (Fields.CONTENT_FIELD_NAME_WEIGHT.equals(currentFieldName)) { if (Fields.CONTENT_FIELD_NAME_WEIGHT.equals(currentFieldName)) {
NumberType numberType = parser.numberType();
if (NumberType.LONG != numberType && NumberType.INT != numberType) {
throw new ElasticSearchIllegalArgumentException("Weight must be an integer, but was [" + parser.numberValue() + "]");
}
weight = parser.longValue(); // always parse a long to make sure we don't get the overflow value weight = parser.longValue(); // always parse a long to make sure we don't get the overflow value
if (weight < 0 || weight > Integer.MAX_VALUE) { if (weight < 0 || weight > Integer.MAX_VALUE) {
throw new ElasticSearchIllegalArgumentException("Weight must be in the interval [0..2147483647] but was " + weight); throw new ElasticSearchIllegalArgumentException("Weight must be in the interval [0..2147483647], but was [" + weight + "]");
} }
} }
} else if (token == XContentParser.Token.START_ARRAY) { } else if (token == XContentParser.Token.START_ARRAY) {

View File

@ -20,6 +20,7 @@ package org.elasticsearch.search.suggest;
import com.carrotsearch.randomizedtesting.generators.RandomStrings; import com.carrotsearch.randomizedtesting.generators.RandomStrings;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import org.elasticsearch.ExceptionsHelper;
import org.elasticsearch.action.admin.cluster.health.ClusterHealthStatus; import org.elasticsearch.action.admin.cluster.health.ClusterHealthStatus;
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingResponse; import org.elasticsearch.action.admin.indices.mapping.put.PutMappingResponse;
import org.elasticsearch.action.admin.indices.optimize.OptimizeResponse; import org.elasticsearch.action.admin.indices.optimize.OptimizeResponse;
@ -120,6 +121,23 @@ public class CompletionSuggestSearchTests extends AbstractIntegrationTest {
assertSuggestions("the", "the", "The the", "The Verve", "The Prodigy"); assertSuggestions("the", "the", "The the", "The Verve", "The Prodigy");
} }
@Test
public void testThatWeightMustBeAnInteger() throws Exception {
createIndexAndMapping();
try {
client().prepareIndex(INDEX, TYPE, "1").setSource(jsonBuilder()
.startObject().startObject(FIELD)
.startArray("input").value("sth").endArray()
.field("weight", 2.5)
.endObject().endObject()
).get();
fail("Indexing with a float weight was successful, but should not be");
} catch (MapperParsingException e) {
assertThat(ExceptionsHelper.detailedMessage(e), containsString("2.5"));
}
}
@Test @Test
public void testThatInputCanBeAStringInsteadOfAnArray() throws Exception { public void testThatInputCanBeAStringInsteadOfAnArray() throws Exception {
createIndexAndMapping(); createIndexAndMapping();