Skip to content

Commit 132881a

Browse files
committed
Our own cross-platform implementation of Path.isAbsolute()
1 parent 3f51012 commit 132881a

File tree

2 files changed

+86
-0
lines changed

2 files changed

+86
-0
lines changed

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

Lines changed: 45 additions & 0 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,49 @@ 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+
*/
69+
static boolean isAbsolutePath(String path) {
70+
if (path.isEmpty()) {
71+
return false;
72+
}
73+
if (path.charAt(0) == '/') {
74+
// Unix/BSD absolute
75+
return true;
76+
}
77+
78+
return isWindowsAbsolutePath(path);
79+
}
80+
81+
private static boolean isSlash(char c) {
82+
return (c == '\\') || (c == '/');
83+
}
84+
85+
private static boolean isWindowsAbsolutePath(String input) {
86+
// if a prefix is present, we expected (long) UNC or (long) absolute
87+
if (input.startsWith("\\\\?\\")) {
88+
return true;
89+
}
90+
91+
if (input.length() > 1) {
92+
char c0 = input.charAt(0);
93+
char c1 = input.charAt(1);
94+
char c = 0;
95+
int next = 2;
96+
if (isSlash(c0) && isSlash(c1)) {
97+
// Two slashes or more: UNC
98+
return true;
99+
}
100+
if (isLetter(c0) && c1 == ':') {
101+
// A drive: absolute
102+
return true;
103+
}
104+
}
105+
// Otherwise relative
106+
return false;
107+
}
63108
}
64109

65110
private sealed interface RelativeFileData extends FileData {
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+
import static org.hamcrest.Matchers.is;
14+
15+
import static org.elasticsearch.entitlement.runtime.policy.entitlements.FilesEntitlement.FileData.isAbsolutePath;
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+
}

0 commit comments

Comments
 (0)