Acknowledgement
Many thanks to Muntashir Akon and all contributors for continuously maintaining libadb-android—an indispensable bridge for Android developers!
Repository: MuntashirAkon/libadb-android
Summary
The static method io.github.muntashirakon.adb.AdbProtocol.generateOpen under-allocates the ByteBuffer, causing java.nio.BufferOverflowException when the destination string (typically a shell command containing Chinese or other multi-byte characters) exceeds 104 ASCII-equivalent bytes. After the exception the connection becomes unusable.
Stack trace
[异常信息:java.nio.BufferOverflowException: null
at java.nio.HeapByteBuffer.put(HeapByteBuffer.java:164)
at java.nio.ByteBuffer.put(ByteBuffer.java:732)
at io.github.muntashirakon.adb.AdbProtocol.generateOpen(AdbProtocol.java:296)
at io.github.muntashirakon.adb.AdbConnection.open(AdbConnection.java:512)
at io.github.muntashirakon.adb.AbsAdbConnectionManager.openStream(AbsAdbConnectionManager.java:414)
at com.AdbService.AdbToolSingleton.lambda$executeNonInteractive$29$com-AdbService-AdbToolSingleton(AdbToolSingleton.java:464)
at com.AdbService.AdbToolSingleton$$ExternalSyntheticLambda49.run(Unknown Source:8)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:764)
]
Root cause
// inside AdbProtocol.java
ByteBuffer bbuf = ByteBuffer.allocate(destination.length() + 1);
Only len + 1 bytes are reserved, but generateMessage(A_OPEN, ...) prepends a 24-byte header.
Required space = 24 + payload + 1.
Whenever destination.length() >= 104 the write overflows.
Minimal reproduction (verbal)
-
Add the official library and establish a normal ADB connection.
-
Build a shell command whose total length exceeds 104 bytes, e.g. copying an APK whose path contains long Chinese file names.
-
Send the command via AbsAdbConnectionManager.openStream(destination);
when the byte length of destination is ≥ 104, the internal buffer is too small and BufferOverflowException is thrown immediately.
-
Disconnect and reconnect, then issue the same-length command again—the problem always reproduces and all subsequent streams fail.
Suggested fix
Allocate the complete buffer in one shot:
ByteBuffer bbuf = ByteBuffer.allocate(24 + destination.length() + 1);
bbuf.put(StringCompat.getBytes(destination, StandardCharsets.UTF_8));
bbuf.put((byte) 0);
bbuf.flip();
return generateMessage(A_OPEN, localId, 0, bbuf.array());
Environment
- Library version: 3.1.1 and earlier
- Trigger: destination length ≥ 104 bytes (100 % reproducible)
This bug really affects usability.
I hope you can fix it as soon as possible, thank you. ( ╹▽╹ )
Acknowledgement
Many thanks to Muntashir Akon and all contributors for continuously maintaining libadb-android—an indispensable bridge for Android developers!
Repository: MuntashirAkon/libadb-android
Summary
The static method
io.github.muntashirakon.adb.AdbProtocol.generateOpenunder-allocates theByteBuffer, causingjava.nio.BufferOverflowExceptionwhen the destination string (typically a shell command containing Chinese or other multi-byte characters) exceeds 104 ASCII-equivalent bytes. After the exception the connection becomes unusable.Stack trace
[异常信息:java.nio.BufferOverflowException: null
at java.nio.HeapByteBuffer.put(HeapByteBuffer.java:164)
at java.nio.ByteBuffer.put(ByteBuffer.java:732)
at io.github.muntashirakon.adb.AdbProtocol.generateOpen(AdbProtocol.java:296)
at io.github.muntashirakon.adb.AdbConnection.open(AdbConnection.java:512)
at io.github.muntashirakon.adb.AbsAdbConnectionManager.openStream(AbsAdbConnectionManager.java:414)
at com.AdbService.AdbToolSingleton.lambda$executeNonInteractive$29$com-AdbService-AdbToolSingleton(AdbToolSingleton.java:464)
at com.AdbService.AdbToolSingleton$$ExternalSyntheticLambda49.run(Unknown Source:8)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:764)
]
Root cause
Only
len + 1bytes are reserved, butgenerateMessage(A_OPEN, ...)prepends a 24-byte header.Required space = 24 + payload + 1.
Whenever
destination.length() >= 104the write overflows.Minimal reproduction (verbal)
Add the official library and establish a normal ADB connection.
Build a shell command whose total length exceeds 104 bytes, e.g. copying an APK whose path contains long Chinese file names.
Send the command via
AbsAdbConnectionManager.openStream(destination);when the byte length of destination is ≥ 104, the internal buffer is too small and
BufferOverflowExceptionis thrown immediately.Disconnect and reconnect, then issue the same-length command again—the problem always reproduces and all subsequent streams fail.
Suggested fix
Allocate the complete buffer in one shot:
Environment
This bug really affects usability.
I hope you can fix it as soon as possible, thank you. ( ╹▽╹ )