From 7e2a9f58eed5bcc6afe702ba113a339700128383 Mon Sep 17 00:00:00 2001
From: Mayya Sharipova <mayya.sharipova@elastic.co>
Date: Thu, 5 Mar 2020 14:23:39 -0500
Subject: [PATCH] script_score query errors on negative scores (#53133)

7.5 and 7.6 had a regression that allowed for
script_score queries to have negative scores.
We have corrected this regression in #52478.
This is an addition to #52478 that adds
a test and release notes.
---
 docs/reference/release-notes/7.7.asciidoc             |  5 +++++
 .../search/query/ScriptScoreQueryTests.java           | 11 ++++++++++-
 2 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/docs/reference/release-notes/7.7.asciidoc b/docs/reference/release-notes/7.7.asciidoc
index 2e4fce5af8b..cf9e7752209 100644
--- a/docs/reference/release-notes/7.7.asciidoc
+++ b/docs/reference/release-notes/7.7.asciidoc
@@ -11,3 +11,8 @@ Mapping::
 * Dynamic mappings in indices created on 8.0 and later have stricter validation at mapping update time and
   results in a deprecation warning for indices created in Elasticsearch 7.7.0 and later.
   (e.g. incorrect analyzer settings or unknown field types). {pull}51233[#51233]
+
+Search::
+* A regression that allowed negative scores in a script_score query was corrected.
+A behaviour is restored that throws an error if script_score query produces
+a negative score {pull}52478[#52478].
diff --git a/server/src/test/java/org/elasticsearch/search/query/ScriptScoreQueryTests.java b/server/src/test/java/org/elasticsearch/search/query/ScriptScoreQueryTests.java
index 04ee6df44d1..3c7a26fc34c 100644
--- a/server/src/test/java/org/elasticsearch/search/query/ScriptScoreQueryTests.java
+++ b/server/src/test/java/org/elasticsearch/search/query/ScriptScoreQueryTests.java
@@ -53,7 +53,7 @@ import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
 public class ScriptScoreQueryTests extends ESTestCase {
-    
+
     private Directory dir;
     private IndexWriter w;
     private DirectoryReader reader;
@@ -131,6 +131,14 @@ public class ScriptScoreQueryTests extends ESTestCase {
         assertThat(explanation.getValue(), equalTo(2.0f));
     }
 
+    public void testScriptScoreErrorOnNegativeScore() {
+        Script script = new Script("script that returns a negative score");
+        ScoreScript.LeafFactory factory = newFactory(script, false, explanation -> -1000.0);
+        ScriptScoreQuery query = new ScriptScoreQuery(Queries.newMatchAllQuery(), script, factory, null, "index", 0, Version.CURRENT);
+        IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> searcher.search(query, 1));
+        assertTrue(e.getMessage().contains("Must be a non-negative score!"));
+    }
+
     private ScoreScript.LeafFactory newFactory(Script script, boolean needsScore,
                                                Function<ScoreScript.ExplanationHolder, Double> function) {
         SearchLookup lookup = mock(SearchLookup.class);
@@ -153,4 +161,5 @@ public class ScriptScoreQueryTests extends ESTestCase {
             }
         };
     }
+
 }