Skip to content

Commit f4d76f5

Browse files
committedJun 19, 2018
[fix] work-around File.exist when ending with '/'
... MRI always returns false when path is a file (dir works) the work-around here is java.io.File's path normalization resolves GH-4403
1 parent 0411d68 commit f4d76f5

File tree

3 files changed

+38
-19
lines changed

3 files changed

+38
-19
lines changed
 

‎core/src/main/java/org/jruby/util/JRubyFile.java

+12-12
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,13 @@ public class JRubyFile extends JavaSecuredFile {
5252
private static final long serialVersionUID = 435364547567567L;
5353

5454
public static JRubyFile create(String cwd, String pathname) {
55-
return createNoUnicodeConversion(cwd, pathname);
55+
if (pathname == null || pathname.length() == 0 || Ruby.isSecurityRestricted()) {
56+
return JRubyFile.DUMMY;
57+
}
58+
if (pathname.startsWith("file:")) {
59+
pathname = pathname.substring(5);
60+
}
61+
return createNoUnicodeConversion(cwd, pathname, new File(pathname));
5662
}
5763

5864
public static FileResource createResource(ThreadContext context, String pathname) {
@@ -109,23 +115,13 @@ private static FileResource createResource(Ruby runtime, String cwd, String path
109115
}
110116

111117
// If any other special resource types fail, count it as a filesystem backed resource.
112-
return new RegularFileResource(runtime != null ? runtime.getPosix() : null, create(cwd, pathname));
118+
return new RegularFileResource(runtime != null ? runtime.getPosix() : null, create(cwd, pathname), pathname);
113119
}
114120

115121
public static String normalizeSeps(String path) {
116122
return Platform.IS_WINDOWS ? path.replace(File.separatorChar, '/') : path;
117123
}
118124

119-
private static JRubyFile createNoUnicodeConversion(String cwd, String pathname) {
120-
if (pathname == null || pathname.length() == 0 || Ruby.isSecurityRestricted()) {
121-
return JRubyFile.DUMMY;
122-
}
123-
if (pathname.startsWith("file:")) {
124-
pathname = pathname.substring(5);
125-
}
126-
return createNoUnicodeConversion(cwd, pathname, new File(pathname));
127-
}
128-
129125
private static JRubyFile createNoUnicodeConversion(String cwd, String pathname, File path) {
130126
// File and company do not seem to recognize bare \ and / on Windows as absolute. Cheat!
131127
if (path.isAbsolute() || Platform.IS_WINDOWS && (pathname.startsWith("/") || pathname.startsWith("\\"))) {
@@ -184,6 +180,10 @@ public String getPath() {
184180
return normalizeSeps(super.getPath());
185181
}
186182

183+
final String getPathDefault() {
184+
return super.getPath();
185+
}
186+
187187
@Override
188188
public String toString() {
189189
return normalizeSeps(super.toString());

‎core/src/main/java/org/jruby/util/RegularFileResource.java

+17-7
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,20 @@
2929
* Represents a "regular" file, backed by regular file system.
3030
*/
3131
class RegularFileResource implements FileResource {
32+
3233
private final JRubyFile file;
34+
private final String filePath; // original (non-normalized) file-path
3335
private final POSIX posix;
3436

35-
RegularFileResource(POSIX posix, JRubyFile file) {
37+
RegularFileResource(POSIX posix, JRubyFile file, String filePath) {
3638
this.file = file;
39+
this.filePath = filePath;
3740
this.posix = posix;
3841
}
3942

4043
protected RegularFileResource(POSIX posix, String filename) {
4144
this.file = new JRubyFile(filename);
45+
this.filePath = filename;
4246
this.posix = posix;
4347
}
4448

@@ -91,7 +95,17 @@ private BasicFileAttributes readAttributes() throws IOException {
9195

9296
@Override
9397
public boolean exists() {
94-
return file.exists();
98+
if (file.exists()) {
99+
String path = filePath;
100+
if (path.length() > 1 && path.charAt(path.length() - 1) == '/') {
101+
path = file.getPathDefault();
102+
if (path.length() > 0 && path.charAt(path.length() - 1) != '/' && !isDirectory()) {
103+
return false;
104+
}
105+
}
106+
return true;
107+
}
108+
return false;
95109
}
96110

97111
@Override
@@ -123,11 +137,7 @@ public boolean isSymLink() {
123137
BasicFileAttributes attrs = Files.readAttributes(file.toPath(), BasicFileAttributes.class, LinkOption.NOFOLLOW_LINKS);
124138

125139
return attrs != null && attrs.isSymbolicLink();
126-
} catch (SecurityException se) {
127-
return false;
128-
} catch (IOException ie) {
129-
return false;
130-
} catch (UnsupportedOperationException uoe) {
140+
} catch (SecurityException|IOException|UnsupportedOperationException ex) {
131141
return false;
132142
}
133143
}

‎test/jruby/test_file.rb

+9
Original file line numberDiff line numberDiff line change
@@ -1406,4 +1406,13 @@ def test_realpath_with_uri_paths
14061406
assert_equal(result.end_with?(postfix), true, result + " ends with " + postfix)
14071407
end
14081408
end
1409+
1410+
def test_file_exists_ending_with_slash
1411+
assert File.exist?(__FILE__)
1412+
assert_false File.exist?(__FILE__ + '/')
1413+
1414+
assert File.exist?(File.dirname(__FILE__))
1415+
assert File.exist?(File.dirname(__FILE__) + '/')
1416+
end
1417+
14091418
end

0 commit comments

Comments
 (0)
Please sign in to comment.