Skip to content

Commit b35c5e8

Browse files
committed
Merge branch 'main' into esql_pragma_load_source
2 parents 263f5ca + 5664f4f commit b35c5e8

File tree

241 files changed

+400
-689
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

241 files changed

+400
-689
lines changed

docs/changelog/122860.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pr: 122860
2+
summary: Improved error message when index field type is invalid
3+
area: Mapping
4+
type: enhancement
5+
issues: []

docs/changelog/123197.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pr: 123197
2+
summary: Fix early termination in `LuceneSourceOperator`
3+
area: ES|QL
4+
type: bug
5+
issues: []

docs/changelog/123272.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pr: 123272
2+
summary: Set Connect Timeout to 5s
3+
area: Machine Learning
4+
type: bug
5+
issues: []

libs/entitlement/src/main/java/org/elasticsearch/entitlement/runtime/policy/entitlements/FilesEntitlement.java

Lines changed: 51 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
import java.util.Objects;
2222
import java.util.stream.Stream;
2323

24+
import static java.lang.Character.isLetter;
25+
2426
/**
2527
* Describes a file entitlement with a path and mode.
2628
*/
@@ -60,6 +62,51 @@ static FileData ofPathSetting(String setting, Mode mode) {
6062
static FileData ofRelativePathSetting(String setting, BaseDir baseDir, Mode mode) {
6163
return new RelativePathSettingFileData(setting, baseDir, mode);
6264
}
65+
66+
/**
67+
* Tests if a path is absolute or relative, taking into consideration both Unix and Windows conventions.
68+
* Note that this leads to a conflict, resolved in favor of Unix rules: `/foo` can be either a Unix absolute path, or a Windows
69+
* relative path with "wrong" directory separator (using non-canonical slash in Windows).
70+
*/
71+
static boolean isAbsolutePath(String path) {
72+
if (path.isEmpty()) {
73+
return false;
74+
}
75+
if (path.charAt(0) == '/') {
76+
// Unix/BSD absolute
77+
return true;
78+
}
79+
80+
return isWindowsAbsolutePath(path);
81+
}
82+
83+
private static boolean isSlash(char c) {
84+
return (c == '\\') || (c == '/');
85+
}
86+
87+
private static boolean isWindowsAbsolutePath(String input) {
88+
// if a prefix is present, we expected (long) UNC or (long) absolute
89+
if (input.startsWith("\\\\?\\")) {
90+
return true;
91+
}
92+
93+
if (input.length() > 1) {
94+
char c0 = input.charAt(0);
95+
char c1 = input.charAt(1);
96+
char c = 0;
97+
int next = 2;
98+
if (isSlash(c0) && isSlash(c1)) {
99+
// Two slashes or more: UNC
100+
return true;
101+
}
102+
if (isLetter(c0) && c1 == ':') {
103+
// A drive: absolute
104+
return true;
105+
}
106+
}
107+
// Otherwise relative
108+
return false;
109+
}
63110
}
64111

65112
private sealed interface RelativeFileData extends FileData {
@@ -190,17 +237,15 @@ public static FilesEntitlement build(List<Object> paths) {
190237
throw new PolicyValidationException("files entitlement with a 'relative_path' must specify 'relative_to'");
191238
}
192239

193-
Path relativePath = Path.of(relativePathAsString);
194-
if (relativePath.isAbsolute()) {
240+
if (FileData.isAbsolutePath(relativePathAsString)) {
195241
throw new PolicyValidationException("'relative_path' [" + relativePathAsString + "] must be relative");
196242
}
197-
filesData.add(FileData.ofRelativePath(relativePath, baseDir, mode));
243+
filesData.add(FileData.ofRelativePath(Path.of(relativePathAsString), baseDir, mode));
198244
} else if (pathAsString != null) {
199-
Path path = Path.of(pathAsString);
200-
if (path.isAbsolute() == false) {
245+
if (FileData.isAbsolutePath(pathAsString) == false) {
201246
throw new PolicyValidationException("'path' [" + pathAsString + "] must be absolute");
202247
}
203-
filesData.add(FileData.ofPath(path, mode));
248+
filesData.add(FileData.ofPath(Path.of(pathAsString), mode));
204249
} else if (pathSetting != null) {
205250
filesData.add(FileData.ofPathSetting(pathSetting, mode));
206251
} else if (relativePathSetting != null) {
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the "Elastic License
4+
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
5+
* Public License v 1"; you may not use this file except in compliance with, at
6+
* your election, the "Elastic License 2.0", the "GNU Affero General Public
7+
* License v3.0 only", or the "Server Side Public License, v 1".
8+
*/
9+
10+
package org.elasticsearch.entitlement.runtime.policy.entitlements;
11+
12+
import org.elasticsearch.test.ESTestCase;
13+
14+
import static org.elasticsearch.entitlement.runtime.policy.entitlements.FilesEntitlement.FileData.isAbsolutePath;
15+
import static org.hamcrest.Matchers.is;
16+
17+
public class FileDataTests extends ESTestCase {
18+
19+
public void testPathIsAbsolute() {
20+
var windowsNamedPipe = "\\\\.\\pipe";
21+
var windowsDosAbsolutePath = "C:\\temp";
22+
var unixAbsolutePath = "/tmp/foo";
23+
var unixStyleUncPath = "//C/temp";
24+
var uncPath = "\\\\C\\temp";
25+
var longPath = "\\\\?\\C:\\temp";
26+
27+
var relativePath = "foo";
28+
var headingSlashRelativePath = "\\foo";
29+
30+
assertThat(isAbsolutePath(windowsNamedPipe), is(true));
31+
assertThat(isAbsolutePath(windowsDosAbsolutePath), is(true));
32+
assertThat(isAbsolutePath(unixAbsolutePath), is(true));
33+
assertThat(isAbsolutePath(unixStyleUncPath), is(true));
34+
assertThat(isAbsolutePath(uncPath), is(true));
35+
assertThat(isAbsolutePath(longPath), is(true));
36+
37+
assertThat(isAbsolutePath(relativePath), is(false));
38+
assertThat(isAbsolutePath(headingSlashRelativePath), is(false));
39+
assertThat(isAbsolutePath(""), is(false));
40+
}
41+
}

libs/entitlement/src/test/java/org/elasticsearch/entitlement/runtime/policy/entitlements/FilesEntitlementTests.java

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,36 @@ public void testInvalidRelativeDirectory() {
6060
assertThat(ex.getMessage(), is("invalid relative directory: bar, valid values: [config, data, home]"));
6161
}
6262

63-
public void testFileDataRelativeWithEmptyDirectory() {
63+
public void testFileDataRelativeWithAbsoluteDirectoryFails() {
6464
var fileData = FileData.ofRelativePath(Path.of(""), FilesEntitlement.BaseDir.DATA, READ_WRITE);
6565
var dataDirs = fileData.resolvePaths(TEST_PATH_LOOKUP);
6666
assertThat(dataDirs.toList(), contains(Path.of("/data1/"), Path.of("/data2")));
6767
}
6868

69+
public void testFileDataAbsoluteWithRelativeDirectoryFails() {
70+
var ex = expectThrows(
71+
PolicyValidationException.class,
72+
() -> FilesEntitlement.build(List.of((Map.of("path", "foo", "mode", "read"))))
73+
);
74+
75+
assertThat(ex.getMessage(), is("'path' [foo] must be absolute"));
76+
}
77+
78+
public void testFileDataRelativeWithEmptyDirectory() {
79+
var ex = expectThrows(
80+
PolicyValidationException.class,
81+
() -> FilesEntitlement.build(List.of((Map.of("relative_path", "/foo", "mode", "read", "relative_to", "config"))))
82+
);
83+
84+
var ex2 = expectThrows(
85+
PolicyValidationException.class,
86+
() -> FilesEntitlement.build(List.of((Map.of("relative_path", "C:\\foo", "mode", "read", "relative_to", "config"))))
87+
);
88+
89+
assertThat(ex.getMessage(), is("'relative_path' [/foo] must be relative"));
90+
assertThat(ex2.getMessage(), is("'relative_path' [C:\\foo] must be relative"));
91+
}
92+
6993
public void testPathSettingResolve() {
7094
var entitlement = FilesEntitlement.build(List.of(Map.of("path_setting", "foo.bar", "mode", "read")));
7195
var filesData = entitlement.filesData();

modules/data-streams/src/main/java/org/elasticsearch/datastreams/action/MigrateToDataStreamTransportAction.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
import org.elasticsearch.cluster.ClusterState;
1717
import org.elasticsearch.cluster.block.ClusterBlockException;
1818
import org.elasticsearch.cluster.block.ClusterBlockLevel;
19-
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
2019
import org.elasticsearch.cluster.metadata.MetadataCreateIndexService;
2120
import org.elasticsearch.cluster.metadata.MetadataMigrateToDataStreamService;
2221
import org.elasticsearch.cluster.service.ClusterService;
@@ -37,7 +36,6 @@ public MigrateToDataStreamTransportAction(
3736
ClusterService clusterService,
3837
ThreadPool threadPool,
3938
ActionFilters actionFilters,
40-
IndexNameExpressionResolver indexNameExpressionResolver,
4139
IndicesService indicesService,
4240
MetadataCreateIndexService metadataCreateIndexService
4341
) {

modules/data-streams/src/main/java/org/elasticsearch/datastreams/action/PromoteDataStreamTransportAction.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
import org.elasticsearch.cluster.block.ClusterBlockException;
2222
import org.elasticsearch.cluster.block.ClusterBlockLevel;
2323
import org.elasticsearch.cluster.metadata.DataStream;
24-
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
2524
import org.elasticsearch.cluster.metadata.Metadata;
2625
import org.elasticsearch.cluster.service.ClusterService;
2726
import org.elasticsearch.common.Priority;
@@ -49,7 +48,6 @@ public PromoteDataStreamTransportAction(
4948
ClusterService clusterService,
5049
ThreadPool threadPool,
5150
ActionFilters actionFilters,
52-
IndexNameExpressionResolver indexNameExpressionResolver,
5351
SystemIndices systemIndices
5452
) {
5553
super(

modules/data-streams/src/main/java/org/elasticsearch/datastreams/lifecycle/action/TransportGetDataStreamLifecycleStatsAction.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
import org.elasticsearch.cluster.block.ClusterBlockException;
1616
import org.elasticsearch.cluster.block.ClusterBlockLevel;
1717
import org.elasticsearch.cluster.metadata.DataStream;
18-
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
1918
import org.elasticsearch.cluster.metadata.Metadata;
2019
import org.elasticsearch.cluster.service.ClusterService;
2120
import org.elasticsearch.common.util.concurrent.EsExecutors;
@@ -46,7 +45,6 @@ public TransportGetDataStreamLifecycleStatsAction(
4645
ClusterService clusterService,
4746
ThreadPool threadPool,
4847
ActionFilters actionFilters,
49-
IndexNameExpressionResolver indexNameExpressionResolver,
5048
DataStreamLifecycleService lifecycleService
5149
) {
5250
super(

modules/data-streams/src/test/java/org/elasticsearch/datastreams/lifecycle/action/TransportGetDataStreamLifecycleStatsActionTests.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
import org.elasticsearch.cluster.metadata.DataStream;
1818
import org.elasticsearch.cluster.metadata.DataStreamLifecycle;
1919
import org.elasticsearch.cluster.metadata.IndexMetadata;
20-
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
2120
import org.elasticsearch.cluster.metadata.Metadata;
2221
import org.elasticsearch.cluster.service.ClusterService;
2322
import org.elasticsearch.common.settings.Settings;
@@ -52,7 +51,6 @@ public class TransportGetDataStreamLifecycleStatsActionTests extends ESTestCase
5251
mock(ClusterService.class),
5352
mock(ThreadPool.class),
5453
mock(ActionFilters.class),
55-
mock(IndexNameExpressionResolver.class),
5654
dataStreamLifecycleService
5755
);
5856
private Long lastRunDuration;

0 commit comments

Comments
 (0)