protected LoadServiceResource tryResourceAsIs(String namePlusSuffix) throws RaiseException { LoadServiceResource foundResource = null; try { if (!Ruby.isSecurityRestricted()) { String reportedPath = namePlusSuffix; File actualPath; // we check length == 0 for 'load', which does not use load path if (new File(reportedPath).isAbsolute()) { // it's an absolute path, use it as-is actualPath = new File(RubyFile.expandUserPath(runtime.getCurrentContext(), namePlusSuffix)); } else { // prepend ./ if . is not already there, since we're loading based on CWD if (reportedPath.charAt(0) == '.' && reportedPath.charAt(1) == '/') { reportedPath = reportedPath.replaceFirst("\\./", runtime.getCurrentDirectory()); } actualPath = JRubyFile.create( runtime.getCurrentDirectory(), RubyFile.expandUserPath(runtime.getCurrentContext(), namePlusSuffix)); } debugLogTry("resourceAsIs", actualPath.toString()); if (actualPath.isFile() && actualPath.canRead()) { foundResource = new LoadServiceResource(actualPath, reportedPath); debugLogFound(foundResource); } } } catch (SecurityException secEx) { } return foundResource; }
protected LoadServiceResource tryResourceFromCWD( SearchState state, String baseName, SuffixType suffixType) throws RaiseException { LoadServiceResource foundResource = null; for (String suffix : suffixType.getSuffixes()) { String namePlusSuffix = baseName + suffix; // check current directory; if file exists, retrieve URL and return resource try { JRubyFile file = JRubyFile.create( runtime.getCurrentDirectory(), RubyFile.expandUserPath(runtime.getCurrentContext(), namePlusSuffix)); debugLogTry("resourceFromCWD", file.toString()); if (file.isFile() && file.isAbsolute() && file.canRead()) { boolean absolute = true; String s = namePlusSuffix; if (!namePlusSuffix.startsWith("./")) { s = "./" + s; } foundResource = new LoadServiceResource(file, s, absolute); debugLogFound(foundResource); state.loadName = resolveLoadName(foundResource, namePlusSuffix); break; } } catch (IllegalArgumentException illArgEx) { } catch (SecurityException secEx) { } } return foundResource; }
public void testUnicodeChars() throws Exception { File file = new File("unicodeáéíóú"); if (file.exists()) { if (!file.delete()) { fail("Unable to delete file: " + file); } } try { if (!file.mkdirs()) { fail("Unable to create directory: " + file); } Ruby runtime; RubyInstanceConfig.nativeEnabled = false; runtime = Ruby.newInstance(); JRubyFile rubyFile = RubyFile.file(RubyString.newString(runtime, file.getAbsolutePath())); assertTrue(rubyFile.exists()); assertTrue(file.exists()); assertTrue(file.isDirectory()); try { assertTrue(runtime.getPosix().stat(rubyFile.getAbsolutePath()).isDirectory()); } catch (Exception e) { throw new RuntimeException("Expecting posix layer to work properly", e); } } finally { if (file.exists()) { file.delete(); } } }
public static String expandPath(String fileName, String dir) { /* * TODO(cs): this isn't quite correct - I think we want to collapse .., but we don't want to * resolve symlinks etc. This might be where we want to start borrowing JRuby's * implementation, but it looks quite tied to their data structures. */ return org.jruby.RubyFile.canonicalize(new File(dir, fileName).getAbsolutePath()); }
protected LoadServiceResource tryResourceFromLoadPath(String namePlusSuffix, String loadPathEntry) throws RaiseException { LoadServiceResource foundResource = null; try { if (!Ruby.isSecurityRestricted()) { String reportedPath = loadPathEntry + "/" + namePlusSuffix; JRubyFile actualPath; boolean absolute = false; // we check length == 0 for 'load', which does not use load path if (new File(reportedPath).isAbsolute()) { absolute = true; // it's an absolute path, use it as-is actualPath = JRubyFile.create( loadPathEntry, RubyFile.expandUserPath(runtime.getCurrentContext(), namePlusSuffix)); } else { absolute = false; // prepend ./ if . is not already there, since we're loading based on CWD if (reportedPath.charAt(0) != '.') { reportedPath = "./" + reportedPath; } actualPath = JRubyFile.create( JRubyFile.create(runtime.getCurrentDirectory(), loadPathEntry).getAbsolutePath(), RubyFile.expandUserPath(runtime.getCurrentContext(), namePlusSuffix)); } debugLogTry( "resourceFromLoadPath", "'" + actualPath.toString() + "' " + actualPath.isFile() + " " + actualPath.canRead()); if (actualPath.isFile() && actualPath.canRead()) { foundResource = new LoadServiceResource(actualPath, reportedPath, absolute); debugLogFound(foundResource); } } } catch (SecurityException secEx) { } return foundResource; }
public static String expandPath(RubyContext context, String fileName) { // TODO (nirvdrum 11-Feb-15) This needs to work on Windows without calling into non-Truffle // JRuby. if (context.isRunningOnWindows()) { final org.jruby.RubyString path = context.toJRubyString( StringNodes.createString(context.getCoreLibrary().getStringClass(), fileName)); final org.jruby.RubyString expanded = (org.jruby.RubyString) org.jruby.RubyFile.expand_path19( context.getRuntime().getCurrentContext(), null, new org.jruby.runtime.builtin.IRubyObject[] {path}); return expanded.asJavaString(); } else { return expandPath(fileName, null); } }
protected LoadServiceResource tryResourceFromHome( SearchState state, String baseName, SuffixType suffixType) throws RaiseException { LoadServiceResource foundResource = null; RubyHash env = (RubyHash) runtime.getObject().fastGetConstant("ENV"); RubyString env_home = runtime.newString("HOME"); if (env.has_key_p(env_home).isFalse()) { return null; } String home = env.op_aref(runtime.getCurrentContext(), env_home).toString(); String path = baseName.substring(2); for (String suffix : suffixType.getSuffixes()) { String namePlusSuffix = path + suffix; // check home directory; if file exists, retrieve URL and return resource try { JRubyFile file = JRubyFile.create( home, RubyFile.expandUserPath(runtime.getCurrentContext(), namePlusSuffix)); debugLogTry("resourceFromHome", file.toString()); if (file.isFile() && file.isAbsolute() && file.canRead()) { boolean absolute = true; String s = "~/" + namePlusSuffix; foundResource = new LoadServiceResource(file, s, absolute); debugLogFound(foundResource); state.loadName = resolveLoadName(foundResource, s); break; } } catch (IllegalArgumentException illArgEx) { } catch (SecurityException secEx) { } } return foundResource; }
private static int glob_helper( String cwd, byte[] bytes, int begin, int end, int sub, int flags, GlobFunc func, GlobArgs arg) { int p, m; int status = 0; byte[] newpath = null; File st; p = sub != -1 ? sub : begin; if (!has_magic(bytes, p, end, flags)) { if (DOSISH || (flags & FNM_NOESCAPE) == 0) { newpath = new byte[end]; System.arraycopy(bytes, 0, newpath, 0, end); if (sub != -1) { p = (sub - begin); end = remove_backslashes(newpath, p, end); sub = p; } else { end = remove_backslashes(newpath, 0, end); bytes = newpath; } } if (bytes[begin] == '/' || (DOSISH && begin + 2 < end && bytes[begin + 1] == ':' && isdirsep(bytes[begin + 2]))) { if (new JavaSecuredFile(newStringFromUTF8(bytes, begin, end - begin)).exists()) { status = func.call(bytes, begin, end - begin, arg); } } else if (isJarFilePath(bytes, begin, end)) { int ix = end; for (int i = 0; i < end; i++) { if (bytes[begin + i] == '!') { ix = i; break; } } st = new JavaSecuredFile(newStringFromUTF8(bytes, begin + 5, ix - 5)); try { String jar = newStringFromUTF8(bytes, begin + ix + 1, end - (ix + 1)); JarFile jf = new JarFile(st); if (jar.startsWith("/")) jar = jar.substring(1); ZipEntry entry = RubyFile.getDirOrFileEntry(jf, jar); if (entry != null) { status = func.call(bytes, begin, end, arg); } } catch (Exception e) { } } else if ((end - begin) > 0) { // Length check is a hack. We should not be reeiving "" as a filename ever. if (new JavaSecuredFile(cwd, newStringFromUTF8(bytes, begin, end - begin)).exists()) { status = func.call(bytes, begin, end - begin, arg); } } return status; } ByteList buf = new ByteList(20); List<ByteList> link = new ArrayList<ByteList>(); mainLoop: while (p != -1 && status == 0) { if (bytes[p] == '/') p++; m = strchr(bytes, p, end, (byte) '/'); if (has_magic(bytes, p, m == -1 ? end : m, flags)) { finalize: do { byte[] base = extract_path(bytes, begin, p); byte[] dir = begin == p ? new byte[] {'.'} : base; byte[] magic = extract_elem(bytes, p, end); boolean recursive = false; String jar = null; JarFile jf = null; if (dir[0] == '/' || (DOSISH && 2 < dir.length && dir[1] == ':' && isdirsep(dir[2]))) { st = new JavaSecuredFile(newStringFromUTF8(dir)); } else if (isJarFilePath(dir, 0, dir.length)) { int ix = dir.length; for (int i = 0; i < dir.length; i++) { if (dir[i] == '!') { ix = i; break; } } st = new JavaSecuredFile(newStringFromUTF8(dir, 5, ix - 5)); jar = newStringFromUTF8(dir, ix + 1, dir.length - (ix + 1)); try { jf = new JarFile(st); if (jar.startsWith("/")) jar = jar.substring(1); if (jf.getEntry(jar + "/") != null) jar = jar + "/"; } catch (Exception e) { jar = null; jf = null; } } else { st = new JavaSecuredFile(cwd, newStringFromUTF8(dir)); } if ((jf != null && ("".equals(jar) || (jf.getJarEntry(jar) != null && jf.getJarEntry(jar).isDirectory()))) || st.isDirectory()) { if (m != -1 && Arrays.equals(magic, DOUBLE_STAR)) { int n = base.length; recursive = true; buf.length(0); buf.append(base); buf.append(bytes, (base.length > 0 ? m : m + 1), end - (base.length > 0 ? m : m + 1)); status = glob_helper( cwd, buf.getUnsafeBytes(), buf.getBegin(), buf.getRealSize(), n, flags, func, arg); if (status != 0) { break finalize; } } } else { break mainLoop; } if (jar == null) { String[] dirp = files(st); for (int i = 0; i < dirp.length; i++) { if (recursive) { byte[] bs = getBytesInUTF8(dirp[i]); if (fnmatch(STAR, 0, 1, bs, 0, bs.length, flags) != 0) { continue; } buf.length(0); buf.append(base); buf.append(BASE(base) ? SLASH : EMPTY); buf.append(getBytesInUTF8(dirp[i])); if (buf.getUnsafeBytes()[0] == '/' || (DOSISH && 2 < buf.getRealSize() && buf.getUnsafeBytes()[1] == ':' && isdirsep(buf.getUnsafeBytes()[2]))) { st = new JavaSecuredFile( newStringFromUTF8( buf.getUnsafeBytes(), buf.getBegin(), buf.getRealSize())); } else { st = new JavaSecuredFile( cwd, newStringFromUTF8( buf.getUnsafeBytes(), buf.getBegin(), buf.getRealSize())); } if (st.isDirectory() && !".".equals(dirp[i]) && !"..".equals(dirp[i])) { int t = buf.getRealSize(); buf.append(SLASH); buf.append(DOUBLE_STAR); buf.append(bytes, m, end - m); status = glob_helper( cwd, buf.getUnsafeBytes(), buf.getBegin(), buf.getRealSize(), t, flags, func, arg); if (status != 0) { break; } } continue; } byte[] bs = getBytesInUTF8(dirp[i]); if (fnmatch(magic, 0, magic.length, bs, 0, bs.length, flags) == 0) { buf.length(0); buf.append(base); buf.append(BASE(base) ? SLASH : EMPTY); buf.append(getBytesInUTF8(dirp[i])); if (m == -1) { status = func.call(buf.getUnsafeBytes(), 0, buf.getRealSize(), arg); if (status != 0) { break; } continue; } link.add(buf); buf = new ByteList(20); } } } else { try { List<JarEntry> dirp = new ArrayList<JarEntry>(); for (Enumeration<JarEntry> eje = jf.entries(); eje.hasMoreElements(); ) { JarEntry je = eje.nextElement(); String name = je.getName(); int ix = name.indexOf('/', jar.length()); if (ix == -1 || ix == name.length() - 1) { if ("/".equals(jar) || (name.startsWith(jar) && name.length() > jar.length())) { dirp.add(je); } } } for (JarEntry je : dirp) { byte[] bs = getBytesInUTF8(je.getName()); int len = bs.length; if (je.isDirectory()) { len--; } if (recursive) { if (fnmatch(STAR, 0, 1, bs, 0, len, flags) != 0) { continue; } buf.length(0); buf.append(base, 0, base.length - jar.length()); buf.append(BASE(base) ? SLASH : EMPTY); buf.append(bs, 0, len); if (je.isDirectory()) { int t = buf.getRealSize(); buf.append(SLASH); buf.append(DOUBLE_STAR); buf.append(bytes, m, end - m); status = glob_helper( cwd, buf.getUnsafeBytes(), buf.getBegin(), buf.getRealSize(), t, flags, func, arg); if (status != 0) { break; } } continue; } if (fnmatch(magic, 0, magic.length, bs, 0, len, flags) == 0) { buf.length(0); buf.append(base, 0, base.length - jar.length()); buf.append(BASE(base) ? SLASH : EMPTY); buf.append(bs, 0, len); if (m == -1) { status = func.call(buf.getUnsafeBytes(), 0, buf.getRealSize(), arg); if (status != 0) { break; } continue; } link.add(buf); buf = new ByteList(20); } } } catch (Exception e) { } } } while (false); if (link.size() > 0) { for (ByteList b : link) { if (status == 0) { if (b.getUnsafeBytes()[0] == '/' || (DOSISH && 2 < b.getRealSize() && b.getUnsafeBytes()[1] == ':' && isdirsep(b.getUnsafeBytes()[2]))) { st = new JavaSecuredFile(newStringFromUTF8(b.getUnsafeBytes(), 0, b.getRealSize())); } else { st = new JavaSecuredFile( cwd, newStringFromUTF8(b.getUnsafeBytes(), 0, b.getRealSize())); } if (st.isDirectory()) { int len = b.getRealSize(); buf.length(0); buf.append(b); buf.append(bytes, m, end - m); status = glob_helper( cwd, buf.getUnsafeBytes(), 0, buf.getRealSize(), len, flags, func, arg); } } } break mainLoop; } } p = m; } return status; }