Przeglądaj źródła

Merge pull request #10997 from rmuir/groovy_better

Load fielddata on behalf of scripts.
Robert Muir 10 lat temu
rodzic
commit
5351fbd8a0

+ 12 - 2
src/main/java/org/elasticsearch/search/lookup/LeafDocLookup.java

@@ -19,6 +19,7 @@
 package org.elasticsearch.search.lookup;
 
 import com.google.common.collect.Maps;
+
 import org.elasticsearch.common.Nullable;
 import org.elasticsearch.index.fielddata.IndexFieldDataService;
 import org.elasticsearch.index.fielddata.ScriptDocValues;
@@ -26,6 +27,8 @@ import org.elasticsearch.index.mapper.FieldMapper;
 import org.elasticsearch.index.mapper.MapperService;
 import org.apache.lucene.index.LeafReaderContext;
 
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Map;
@@ -73,11 +76,18 @@ public class LeafDocLookup implements Map {
         String fieldName = key.toString();
         ScriptDocValues scriptValues = localCacheFieldData.get(fieldName);
         if (scriptValues == null) {
-            FieldMapper mapper = mapperService.smartNameFieldMapper(fieldName, types);
+            final FieldMapper mapper = mapperService.smartNameFieldMapper(fieldName, types);
             if (mapper == null) {
                 throw new IllegalArgumentException("No field found for [" + fieldName + "] in mapping with types " + Arrays.toString(types) + "");
             }
-            scriptValues = fieldDataService.getForField(mapper).load(reader).getScriptValues();
+            // load fielddata on behalf of the script: otherwise it would need additional permissions
+            // to deal with pagedbytes/ramusagestimator/etc
+            scriptValues = AccessController.doPrivileged(new PrivilegedAction<ScriptDocValues>() {
+                @Override
+                public ScriptDocValues run() {
+                    return fieldDataService.getForField(mapper).load(reader).getScriptValues();
+                }
+            });
             localCacheFieldData.put(fieldName, scriptValues);
         }
         scriptValues.setNextDocId(docId);

+ 5 - 1
src/test/java/org/elasticsearch/script/GroovySecurityTests.java

@@ -54,10 +54,14 @@ public class GroovySecurityTests extends ElasticsearchIntegrationTest {
         internalCluster().startNodesAsync(nodes, nodeSettings).get();
         client().admin().cluster().prepareHealth().setWaitForNodes(nodes + "").get();
 
-        client().prepareIndex("test", "doc", "1").setSource("foo", 5).setRefresh(true).get();
+        client().prepareIndex("test", "doc", "1").setSource("foo", 5, "bar", "baz").setRefresh(true).get();
 
         // Plain test
         assertSuccess("");
+        // numeric field access
+        assertSuccess("def foo = doc['foo'].value; if (foo == null) { return 5; }");
+        // string field access
+        assertSuccess("def bar = doc['bar'].value; if (foo == null) { return 5; }");
         // List
         assertSuccess("def list = [doc['foo'].value, 3, 4]; def v = list.get(1); list.add(10)");
         // Ranges