Describe the bug, including details regarding any error messages, version, and platform.
If Consumer throws exception, TryCopyLastError would copy exception message to C buffer. TryCopyLastError assume the string(byte[]) returned by lastError is '\0' terminated and test the length of the string by strlen which result in invalid memory access. In actually, lastError is a UTF8 encoded buffer(byte[]).
The code of TryCopyLastError:
jobject error_data =
env->GetObjectField(private_data->j_private_data_, kPrivateDataLastErrorField);
...
auto arr = reinterpret_cast<jbyteArray>(error_data);
jbyte* error_bytes = env->GetByteArrayElements(arr, nullptr);
if (!error_bytes) {
private_data->last_error_.clear();
return;
}
char* error_str = reinterpret_cast<char*>(error_bytes);
private_data->last_error_ = std::string(error_str, std::strlen(error_str));
The code below shows how lastError be setted:
private int setLastError(Throwable err) {
// Do not let exceptions propagate up to JNI
try {
StringWriter buf = new StringWriter();
PrintWriter writer = new PrintWriter(buf);
err.printStackTrace(writer);
lastError = buf.toString().getBytes(StandardCharsets.UTF_8);
} catch (Throwable e) {
// Bail out of setting the error message - we'll still return an error code
lastError = null;
}
return 5; // = EIO
}
Describe the bug, including details regarding any error messages, version, and platform.
If
Consumerthrows exception,TryCopyLastErrorwould copy exception message to C buffer.TryCopyLastErrorassume the string(byte[]) returned bylastErroris '\0' terminated and test the length of the string bystrlenwhich result in invalid memory access. In actually,lastErroris a UTF8 encoded buffer(byte[]).The code of
TryCopyLastError:The code below shows how
lastErrorbe setted: