From add18719c5b45bc07fa86f9af376c205d3b75117 Mon Sep 17 00:00:00 2001 From: Sean Li Date: Wed, 8 Mar 2023 15:13:44 -0800 Subject: [PATCH] Adding query fuzziness validation (#5805) * Adding fuzziness validation Signed-off-by: Sean Li * Updating imports Signed-off-by: Sean Li * Adding fuzziness validation Signed-off-by: Sean Li * Updating imports Signed-off-by: Sean Li * removing comments Signed-off-by: Sean Li * running spotlessApply Signed-off-by: Sean Li * updating CHANGELOG.md Signed-off-by: Sean Li * resolving reviews Signed-off-by: Sean Li * revising comment Signed-off-by: Sean Li * updating CHANGELOG.md Signed-off-by: Sean Li * moving fix to 2.x in CHANGELOG.md Signed-off-by: Sean Li --------- Signed-off-by: Sean Li --- CHANGELOG.md | 1 + .../org/opensearch/common/unit/Fuzziness.java | 14 +++++++++---- .../common/unit/FuzzinessTests.java | 21 +++++++++++++++++++ 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index df3ac6ae0fa1b..f273687634baa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -96,6 +96,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ### Fixed - Added equals/hashcode for named DocValueFormat.DateTime inner class ([#6357](https://github.com/opensearch-project/OpenSearch/pull/6357)) - Fixed bug for searchable snapshot to take 'base_path' of blob into account ([#6558](https://github.com/opensearch-project/OpenSearch/pull/6558)) +- Fix fuzziness validation ([#5805](https://github.com/opensearch-project/OpenSearch/pull/5805)) ### Security diff --git a/server/src/main/java/org/opensearch/common/unit/Fuzziness.java b/server/src/main/java/org/opensearch/common/unit/Fuzziness.java index 41ac57adace4d..1257a06895a9c 100644 --- a/server/src/main/java/org/opensearch/common/unit/Fuzziness.java +++ b/server/src/main/java/org/opensearch/common/unit/Fuzziness.java @@ -189,7 +189,13 @@ public static Fuzziness parse(XContentParser parser) throws IOException { return build(fuzziness); } } catch (NumberFormatException ex) { - return build(fuzziness); + // Validate if the fuzziness value is formatted correctly as a numeric value. + try { + final float minimumSimilarity = Float.parseFloat(fuzziness); + return build(fuzziness); + } catch (NumberFormatException e) { + throw new IllegalArgumentException("Invalid fuzziness value: " + fuzziness); + } } default: @@ -225,7 +231,7 @@ public float asFloat() { if (this.equals(AUTO) || isAutoWithCustomValues()) { return 1f; } - return Float.parseFloat(fuzziness.toString()); + return Float.parseFloat(fuzziness); } private int termLen(String text) { @@ -234,9 +240,9 @@ private int termLen(String text) { public String asString() { if (isAutoWithCustomValues()) { - return fuzziness.toString() + ":" + lowDistance + "," + highDistance; + return fuzziness + ":" + lowDistance + "," + highDistance; } - return fuzziness.toString(); + return fuzziness; } private boolean isAutoWithCustomValues() { diff --git a/server/src/test/java/org/opensearch/common/unit/FuzzinessTests.java b/server/src/test/java/org/opensearch/common/unit/FuzzinessTests.java index 0c3ca94e716e7..1f41fc822a784 100644 --- a/server/src/test/java/org/opensearch/common/unit/FuzzinessTests.java +++ b/server/src/test/java/org/opensearch/common/unit/FuzzinessTests.java @@ -31,6 +31,7 @@ package org.opensearch.common.unit; +import org.opensearch.OpenSearchParseException; import org.opensearch.common.io.stream.BytesStreamOutput; import org.opensearch.common.io.stream.StreamInput; import org.opensearch.core.xcontent.XContentBuilder; @@ -138,6 +139,26 @@ public void testParseFromXContent() throws IOException { } + public void testFuzzinessValidationWithStrings() throws IOException { + String[] invalidStrings = new String[] { "+++", "asdfghjkl", "2k23" }; + XContentBuilder json = jsonBuilder().startObject().field(Fuzziness.X_FIELD_NAME, randomFrom(invalidStrings)).endObject(); + try (XContentParser parser = createParser(json)) { + assertThat(parser.nextToken(), equalTo(XContentParser.Token.START_OBJECT)); + assertThat(parser.nextToken(), equalTo(XContentParser.Token.FIELD_NAME)); + assertThat(parser.nextToken(), equalTo(XContentParser.Token.VALUE_STRING)); + IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> Fuzziness.parse(parser)); + assertTrue(e.getMessage().startsWith("Invalid fuzziness value:")); + } + json = jsonBuilder().startObject().field(Fuzziness.X_FIELD_NAME, "AUTO:").endObject(); + try (XContentParser parser = createParser(json)) { + assertThat(parser.nextToken(), equalTo(XContentParser.Token.START_OBJECT)); + assertThat(parser.nextToken(), equalTo(XContentParser.Token.FIELD_NAME)); + assertThat(parser.nextToken(), equalTo(XContentParser.Token.VALUE_STRING)); + OpenSearchParseException e = expectThrows(OpenSearchParseException.class, () -> Fuzziness.parse(parser)); + assertTrue(e.getMessage().startsWith("failed to find low and high distance values")); + } + } + public void testAuto() { assertThat(Fuzziness.AUTO.asFloat(), equalTo(1f)); }