mirror of
https://github.com/revanced/jadb.git
synced 2024-11-19 02:29:24 +01:00
Merge pull request #112 from phantamanta44/master
Allow multi-byte characters in payload
This commit is contained in:
commit
4546c0583f
@ -19,8 +19,9 @@ public class SyncTransport {
|
||||
public void send(String syncCommand, String name) throws IOException {
|
||||
if (syncCommand.length() != 4) throw new IllegalArgumentException("sync commands must have length 4");
|
||||
output.writeBytes(syncCommand);
|
||||
output.writeInt(Integer.reverseBytes(name.length()));
|
||||
output.writeBytes(name);
|
||||
byte[] data = name.getBytes(StandardCharsets.UTF_8);
|
||||
output.writeInt(Integer.reverseBytes(data.length));
|
||||
output.write(data);
|
||||
}
|
||||
|
||||
public void sendStatus(String statusCode, int length) throws IOException {
|
||||
@ -50,6 +51,21 @@ public class SyncTransport {
|
||||
return new String(buffer, StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
public void sendDirectoryEntry(RemoteFile file) throws IOException {
|
||||
output.writeBytes("DENT");
|
||||
output.writeInt(Integer.reverseBytes(0666 | (file.isDirectory() ? (1 << 14) : 0)));
|
||||
output.writeInt(Integer.reverseBytes(file.getSize()));
|
||||
output.writeInt(Integer.reverseBytes(Long.valueOf(file.getLastModified()).intValue()));
|
||||
byte[] pathChars = file.getPath().getBytes(StandardCharsets.UTF_8);
|
||||
output.writeInt(Integer.reverseBytes(pathChars.length));
|
||||
output.write(pathChars);
|
||||
}
|
||||
|
||||
public void sendDirectoryEntryDone() throws IOException {
|
||||
output.writeBytes("DONE");
|
||||
output.writeBytes("\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"); // equivalent to the length of a "normal" dent
|
||||
}
|
||||
|
||||
public RemoteFileRecord readDirectoryEntry() throws IOException {
|
||||
String id = readString(4);
|
||||
int mode = readInt();
|
||||
|
@ -7,6 +7,7 @@ import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by vidstige on 20/03/14.
|
||||
@ -19,4 +20,6 @@ public interface AdbDeviceResponder {
|
||||
void filePulled(RemoteFile path, ByteArrayOutputStream buffer) throws JadbException, IOException;
|
||||
|
||||
void shell(String command, DataOutputStream stdout, DataInput stdin) throws IOException;
|
||||
|
||||
List<RemoteFile> list(String path) throws IOException;
|
||||
}
|
||||
|
@ -175,6 +175,8 @@ class AdbProtocolHandler implements Runnable {
|
||||
syncSend(output, input, length);
|
||||
} else if ("RECV".equals(id)) {
|
||||
syncRecv(output, input, length);
|
||||
} else if ("LIST".equals(id)) {
|
||||
syncList(output, input, length);
|
||||
} else throw new JadbException("Unknown sync id " + id);
|
||||
} catch (JadbException e) { // sync response with a different type of fail message
|
||||
SyncTransport sync = getSyncTransport(output, input);
|
||||
@ -207,6 +209,15 @@ class AdbProtocolHandler implements Runnable {
|
||||
transport.sendStatus("OKAY", 0); // 0 = ignored
|
||||
}
|
||||
|
||||
private void syncList(DataOutput output, DataInput input, int length) throws IOException, JadbException {
|
||||
String remotePath = readString(input, length);
|
||||
SyncTransport transport = getSyncTransport(output, input);
|
||||
for (RemoteFile file : selected.list(remotePath)) {
|
||||
transport.sendDirectoryEntry(file);
|
||||
}
|
||||
transport.sendDirectoryEntryDone();
|
||||
}
|
||||
|
||||
private String getCommandLength(String command) {
|
||||
return String.format("%04x", command.length());
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ import java.io.IOException;
|
||||
import java.net.ProtocolException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@ -86,6 +87,10 @@ public class FakeAdbServer implements AdbResponder {
|
||||
return findBySerial(serial).expectShell(commands);
|
||||
}
|
||||
|
||||
public DeviceResponder.ListExpectation expectList(String serial, String remotePath) {
|
||||
return findBySerial(serial).expectList(remotePath);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AdbDeviceResponder> getDevices() {
|
||||
return new ArrayList<AdbDeviceResponder>(devices);
|
||||
@ -96,6 +101,7 @@ public class FakeAdbServer implements AdbResponder {
|
||||
private final String type;
|
||||
private List<FileExpectation> fileExpectations = new ArrayList<>();
|
||||
private List<ShellExpectation> shellExpectations = new ArrayList<>();
|
||||
private List<ListExpectation> listExpectations = new ArrayList<>();
|
||||
|
||||
private DeviceResponder(String serial, String type) {
|
||||
this.serial = serial;
|
||||
@ -150,9 +156,21 @@ public class FakeAdbServer implements AdbResponder {
|
||||
throw new ProtocolException("Unexpected shell to device " + serial + ": " + command);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RemoteFile> list(String path) throws IOException {
|
||||
for (ListExpectation le : listExpectations) {
|
||||
if (le.matches(path)) {
|
||||
listExpectations.remove(le);
|
||||
return le.getFiles();
|
||||
}
|
||||
}
|
||||
throw new ProtocolException("Unexpected list of device " + serial + " in dir " + path);
|
||||
}
|
||||
|
||||
public void verifyExpectations() {
|
||||
org.junit.Assert.assertEquals(0, fileExpectations.size());
|
||||
org.junit.Assert.assertEquals(0, shellExpectations.size());
|
||||
org.junit.Assert.assertEquals(0, listExpectations.size());
|
||||
}
|
||||
|
||||
private static class FileExpectation implements ExpectationBuilder {
|
||||
@ -161,7 +179,6 @@ public class FakeAdbServer implements AdbResponder {
|
||||
private String failMessage;
|
||||
|
||||
public FileExpectation(RemoteFile path) {
|
||||
|
||||
this.path = path;
|
||||
content = null;
|
||||
failMessage = null;
|
||||
@ -220,6 +237,62 @@ public class FakeAdbServer implements AdbResponder {
|
||||
}
|
||||
}
|
||||
|
||||
public static class ListExpectation {
|
||||
|
||||
private final String remotePath;
|
||||
private final List<RemoteFile> files = new ArrayList<>();
|
||||
|
||||
public ListExpectation(String remotePath) {
|
||||
this.remotePath = remotePath;
|
||||
}
|
||||
|
||||
public boolean matches(String remotePath) {
|
||||
return remotePath.equals(this.remotePath);
|
||||
}
|
||||
|
||||
public ListExpectation withFile(String path, int size, long modifyTime) {
|
||||
files.add(new MockFileEntry(path, size, modifyTime, false));
|
||||
return this;
|
||||
}
|
||||
|
||||
public ListExpectation withDir(String path, long modifyTime) {
|
||||
files.add(new MockFileEntry(path, -1, modifyTime, true));
|
||||
return this;
|
||||
}
|
||||
|
||||
public List<RemoteFile> getFiles() {
|
||||
return Collections.unmodifiableList(files);
|
||||
}
|
||||
|
||||
private static class MockFileEntry extends RemoteFile {
|
||||
|
||||
private final int size;
|
||||
private final long modifyTime;
|
||||
private final boolean dir;
|
||||
|
||||
MockFileEntry(String path, int size, long modifyTime, boolean dir) {
|
||||
super(path);
|
||||
this.size = size;
|
||||
this.modifyTime = modifyTime;
|
||||
this.dir = dir;
|
||||
}
|
||||
|
||||
public int getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
public long getLastModified() {
|
||||
return modifyTime;
|
||||
}
|
||||
|
||||
public boolean isDirectory() {
|
||||
return dir;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public ExpectationBuilder expectPush(RemoteFile path) {
|
||||
FileExpectation expectation = new FileExpectation(path);
|
||||
fileExpectations.add(expectation);
|
||||
@ -237,5 +310,11 @@ public class FakeAdbServer implements AdbResponder {
|
||||
shellExpectations.add(expectation);
|
||||
return expectation;
|
||||
}
|
||||
|
||||
public ListExpectation expectList(String remotePath) {
|
||||
ListExpectation expectation = new ListExpectation(remotePath);
|
||||
listExpectations.add(expectation);
|
||||
return expectation;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ import java.nio.charset.StandardCharsets;
|
||||
import java.text.DateFormat;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class MockedTestCases {
|
||||
@ -117,8 +118,59 @@ public class MockedTestCases {
|
||||
device.executeShell("echo", "newline2\r\nstring");
|
||||
}
|
||||
|
||||
private long parseDate(String date) throws ParseException {
|
||||
@Test
|
||||
public void testFileList() throws Exception {
|
||||
server.add("serial-123");
|
||||
server.expectList("serial-123", "/sdcard/Documents")
|
||||
.withDir("school", 123456789L)
|
||||
.withDir("finances", 7070707L)
|
||||
.withDir("\u904A\u6232", 528491L)
|
||||
.withFile("user_manual.pdf", 3000, 648649L)
|
||||
.withFile("effective java vol. 7.epub", 0xCAFE, 0xBABEL)
|
||||
.withFile("\uB9AC\uADF8 \uC624\uBE0C \uB808\uC804\uB4DC", 240, 9001L);
|
||||
JadbDevice device = connection.getDevices().get(0);
|
||||
List<RemoteFile> files = device.list("/sdcard/Documents");
|
||||
Assert.assertEquals(6, files.size());
|
||||
assertHasDir("school", 123456789L, files);
|
||||
assertHasDir("finances", 7070707L, files);
|
||||
assertHasDir("\u904A\u6232", 528491L, files);
|
||||
assertHasFile("user_manual.pdf", 3000, 648649L, files);
|
||||
assertHasFile("effective java vol. 7.epub", 0xCAFE, 0xBABEL, files);
|
||||
assertHasFile("\uB9AC\uADF8 \uC624\uBE0C \uB808\uC804\uB4DC", 240, 9001L, files);
|
||||
}
|
||||
|
||||
private static long parseDate(String date) throws ParseException {
|
||||
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
|
||||
return dateFormat.parse(date).getTime();
|
||||
}
|
||||
|
||||
private static void assertHasFile(String expPath, int expSize, long expModifyTime, List<RemoteFile> actualFiles) {
|
||||
for (RemoteFile file : actualFiles) {
|
||||
if (expPath.equals(file.getPath())) {
|
||||
if (file.isDirectory()) {
|
||||
Assert.fail("File " + expPath + " was listed as a dir!");
|
||||
} else if (expSize != file.getSize() || expModifyTime != file.getLastModified()) {
|
||||
Assert.fail("File " + expPath + " exists but has incorrect properties!");
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
Assert.fail("File " + expPath + " could not be found!");
|
||||
}
|
||||
|
||||
private static void assertHasDir(String expPath, long expModifyTime, List<RemoteFile> actualFiles) {
|
||||
for (RemoteFile file : actualFiles) {
|
||||
if (expPath.equals(file.getPath())) {
|
||||
if (!file.isDirectory()) {
|
||||
Assert.fail("Dir " + expPath + " was listed as a file!");
|
||||
} else if (expModifyTime != file.getLastModified()) {
|
||||
Assert.fail("Dir " + expPath + " exists but has incorrect properties!");
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
Assert.fail("Dir " + expPath + " could not be found!");
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user