Properly escape file paths

This commit is contained in:
topjohnwu 2021-02-03 02:34:23 -08:00
parent 56b57bc15f
commit 713e52c816
4 changed files with 43 additions and 15 deletions

View File

@ -114,6 +114,25 @@ public final class ShellUtils {
} catch (IOException ignored) {}
}
/**
* Format string to quoted and escaped string suitable for shell commands.
* @param s the string to be formatted.
* @return the formatted string.
*/
public static String escapedString(String s) {
StringBuilder sb = new StringBuilder();
sb.append('"');
int len = s.length();
for (int i = 0; i < len; ++i) {
char c = s.charAt(i);
if ("$`\"\\".indexOf(c) >= 0)
sb.append('\\');
sb.append(c);
}
sb.append('"');
return sb.toString();
}
/**
* Get the greatest common divisor of 2 integers with binary algorithm.
* @param u an integer.

View File

@ -36,7 +36,7 @@ class ShellBlockIO extends ShellIO {
long bs;
try {
bs = Long.parseLong(ShellUtils.fastCmd(
"blockdev --getsize64 '" + file.getPath() + "'"));
"blockdev --getsize64 " + file.getEscapedPath()));
} catch (NumberFormatException e) {
// Error, no choice but to assume no boundary
bs = Long.MAX_VALUE;

View File

@ -96,12 +96,12 @@ class ShellIO extends SuRandomAccessFile implements DataInputImpl, DataOutputImp
String cmd;
if (fileOff == 0) {
cmd = String.format(Locale.ROOT,
"dd of='%s' bs=%d count=1 %s 2>/dev/null; echo\n",
file.getPath(), len, getConv());
"dd of=%s bs=%d count=1 %s 2>/dev/null; echo\n",
file.getEscapedPath(), len, getConv());
} else {
cmd = String.format(Locale.ROOT,
"dd of='%s' ibs=%d count=1 obs=%d seek=1 %s 2>/dev/null; echo\n",
file.getPath(), len, fileOff, getConv());
"dd of=%s ibs=%d count=1 obs=%d seek=1 %s 2>/dev/null; echo\n",
file.getEscapedPath(), len, fileOff, getConv());
}
Utils.log(TAG, cmd);
in.write(cmd.getBytes(UTF_8));
@ -118,7 +118,7 @@ class ShellIO extends SuRandomAccessFile implements DataInputImpl, DataOutputImp
void streamWrite(byte[] b, int off, int len) throws IOException {
Shell.getShell().execTask((in, out, err) -> {
String cmd = String.format(Locale.ROOT,
"dd bs=%d count=1 >> '%s' 2>/dev/null; echo\n", len, file.getPath());
"dd bs=%d count=1 >> %s 2>/dev/null; echo\n", len, file.getEscapedPath());
Utils.log(TAG, cmd);
in.write(cmd.getBytes(UTF_8));
in.flush();
@ -197,8 +197,8 @@ class ShellIO extends SuRandomAccessFile implements DataInputImpl, DataOutputImp
Shell.getShell().execTask((in, out, err) -> {
int off = _off;
String cmd = String.format(Locale.ROOT,
"dd if='%s' ibs=%d skip=%d count=%d obs=%d 2>/dev/null; echo >&2\n",
file.getPath(), bs, skip, count, len);
"dd if=%s ibs=%d skip=%d count=%d obs=%d 2>/dev/null; echo >&2\n",
file.getEscapedPath(), bs, skip, count, len);
Utils.log(TAG, cmd);
in.write(cmd.getBytes(UTF_8));
in.flush();
@ -278,8 +278,8 @@ class ShellIO extends SuRandomAccessFile implements DataInputImpl, DataOutputImp
}
Shell.getShell().execTask((in, out, err) -> {
String cmd = String.format(Locale.ROOT,
"dd of='%s' bs=%d seek=1 count=0 2>/dev/null; echo\n",
file.getPath(), newLength);
"dd of=%s bs=%d seek=1 count=0 2>/dev/null; echo\n",
file.getEscapedPath(), newLength);
Utils.log(TAG, cmd);
in.write(cmd.getBytes(UTF_8));
in.flush();

View File

@ -54,7 +54,7 @@ import java.util.Locale;
*/
public class SuFile extends File {
private final String quotedPath;
private final String escapedPath;
public static File open(String pathname) {
return Shell.rootAccess() ? new SuFile(pathname) : new File(pathname);
@ -74,7 +74,7 @@ public class SuFile extends File {
SuFile(@NonNull File file) {
super(file.getAbsolutePath());
quotedPath = '"' + getPath() + '"';
escapedPath = ShellUtils.escapedString(getPath());
}
public SuFile(String pathname) {
@ -95,12 +95,21 @@ public class SuFile extends File {
private String cmd(String c) {
// Use replace instead of format for performance
return ShellUtils.fastCmd(c.replace("@@", quotedPath));
return ShellUtils.fastCmd(c.replace("@@", escapedPath));
}
private boolean cmdBool(String c) {
// Use replace instead of format for performance
return ShellUtils.fastCmdResult(c.replace("@@", quotedPath));
return ShellUtils.fastCmdResult(c.replace("@@", escapedPath));
}
/**
* Converts this abstract pathname into a pathname string suitable
* for shell commands.
* @return the formatted string form of this abstract pathname
*/
public String getEscapedPath() {
return escapedPath;
}
@Override
@ -458,7 +467,7 @@ public class SuFile extends File {
public String[] list(FilenameFilter filter) {
if (!isDirectory())
return null;
String cmd = "ls -a " + quotedPath;
String cmd = "ls -a " + escapedPath;
List<String> out = Shell.su(cmd).to(new LinkedList<>(), null).exec().getOut();
for (ListIterator<String> it = out.listIterator(); it.hasNext();) {
String name = it.next();