Skip to content

Commit c7e9749

Browse files
committed
Fix method calling crash due to invalid serialization.
1 parent 45b5869 commit c7e9749

2 files changed

Lines changed: 52 additions & 108 deletions

File tree

RemoteInput/Plugin/JVM/RemoteVM.cxx

Lines changed: 49 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -152,60 +152,42 @@ enum class RemoteVMCommand: std::uint32_t
152152
GET_OBJECT_REF_TYPE
153153
};
154154

155+
// Overloads for Stream to support jvalue
156+
155157
Stream& operator << (Stream& stream, const jvalue &value) noexcept
156158
{
157159
stream.write(&value, sizeof(jvalue));
158160
return stream;
159161
}
160162

161-
template<class T>
162-
struct is_string
163-
{
164-
static bool const value = false;
165-
};
166-
167-
template<typename T>
168-
struct is_string<std::basic_string<T>>
169-
{
170-
static bool const value = true;
171-
};
172-
173-
template<typename T>
174-
typename std::enable_if<!is_string<std::decay_t<T>>::value && !is_vector<std::decay_t<T>>::value, std::decay_t<T>>::type Remote_VM_Read(ImageData* image_data) noexcept
175-
{
176-
return image_data->data_stream().read<std::decay_t<T>>();
177-
}
178-
179-
template<typename T>
180-
typename std::enable_if<is_string<std::decay_t<T>>::value, std::decay_t<T>>::type Remote_VM_Read(ImageData* image_data) noexcept
163+
Stream& operator >> (Stream& stream, jvalue &value) noexcept
181164
{
182-
return image_data->data_stream().read<std::decay_t<T>>();
165+
stream.read(&value, sizeof(jvalue));
166+
return stream;
183167
}
184168

185-
template<typename T>
186-
typename std::enable_if<is_vector<std::decay_t<T>>::value, std::decay_t<T>>::type Remote_VM_Read(ImageData* image_data) noexcept
187-
{
188-
std::decay_t<T> result;
189-
image_data->data_stream().read(&result, sizeof(result));
190-
return result;
191-
}
169+
// Helpers for reading
192170

193-
template<typename T>
194-
void Remote_VM_Write(ImageData* image_data, const T& result) noexcept
171+
template<typename... Args>
172+
auto Remote_VM_Read(ImageData* image_data)
195173
{
196-
image_data->data_stream().write(result);
174+
if constexpr (sizeof...(Args) == 1)
175+
{
176+
return image_data->data_stream().read<std::tuple_element_t<0, std::tuple<std::decay_t<Args>...>>>();
177+
}
178+
else
179+
{
180+
return std::tuple<std::decay_t<Args>...>{image_data->data_stream().read<std::decay_t<Args>>()...};
181+
}
197182
}
198183

199-
template<typename T>
200-
void Remote_VM_Write(ImageData* image_data, const std::basic_string<T> &result) noexcept
201-
{
202-
image_data->data_stream().write(result);
203-
}
184+
// Helpers for writing
204185

205-
template<typename T>
206-
void Remote_VM_Write(ImageData* image_data, const std::vector<T> &result) noexcept
186+
template<typename... Args>
187+
void Remote_VM_Write(Stream& stream, RemoteVMCommand command, Args&&... args)
207188
{
208-
image_data->data_stream().write(result);
189+
stream << command;
190+
(stream.write(std::forward<Args>(args)), ...);
209191
}
210192

211193
template<typename T>
@@ -221,76 +203,37 @@ T RemoteVM::local_to_global(T object) const noexcept
221203
}
222204

223205
template<typename R, typename... Args>
224-
typename std::enable_if<!is_vector<R>::value, R>::type RemoteVM::SendCommand(RemoteVMCommand command, Args&&... args) const noexcept
206+
R RemoteVM::SendCommand(RemoteVMCommand command, Args&&... args) const noexcept
225207
{
226208
auto result = send_command([&](Stream &stream, ImageData* image_data) {
227209
image_data->set_command(EIOSCommand::REMOTE_VM_INSTRUCTION);
228-
Remote_VM_Write(image_data, command);
229-
(Remote_VM_Write(image_data, args), ...);
230-
231-
/*([](auto& arguments, auto& arg) {
232-
Remote_VM_Write(arguments, arg);
233-
} (arguments, args), ...); //std::forward<void*&>(arguments);*/
210+
Remote_VM_Write(stream, command, std::forward<Args>(args)...);
234211
});
235212

236-
if constexpr(std::is_same<R, void>::value)
237-
{
238-
return;
239-
}
240-
else if (result)
241-
{
242-
ImageData* image_data = (control_center->*get_image_data)();
243-
return Remote_VM_Read<R>(image_data);
244-
}
245-
else if constexpr(std::is_same<R, jboolean>::value)
246-
{
247-
return false;
248-
}
249-
else if constexpr(is_same_of<R, jfloat, jdouble>::value)
250-
{
251-
return 0.0;
252-
}
253-
else if constexpr(is_same_of<R, jchar, jbyte, jshort, jint, jlong, jsize>::value)
254-
{
255-
return -1;
256-
}
257-
else if constexpr (std::is_same<R, jobjectRefType>::value)
213+
if constexpr (!std::is_void_v<R>)
258214
{
259-
ImageData* image_data = (control_center->*get_image_data)();
260-
return Remote_VM_Read<R>(image_data);
261-
}
262-
else
263-
{
264-
return nullptr;
215+
if (result)
216+
{
217+
ImageData* image_data = (control_center->*get_image_data)();
218+
return Remote_VM_Read<R>(image_data);
219+
}
265220
}
221+
return R();
266222
}
267223

268224
template<typename R, typename... Args>
269-
typename std::enable_if<is_vector<R>::value, R>::type RemoteVM::SendCommand(RemoteVMCommand command, Args&&... args) const noexcept
225+
R RemoteVM::ExecuteCommand(ImageData* image_data, R (RemoteVM::*func)(Args...) const noexcept) const noexcept
270226
{
271-
auto result = send_command([&](Stream &stream, ImageData* image_data) {
272-
image_data->set_command(EIOSCommand::REMOTE_VM_INSTRUCTION);
273-
Remote_VM_Write(image_data, command);
274-
(Remote_VM_Write(image_data, args), ...);
275-
276-
/*([](auto& arguments, auto& arg) {
277-
Remote_VM_Write(arguments, arg);
278-
} (arguments, args), ...); //std::forward<void*&>(arguments);*/
279-
});
227+
auto args = Remote_VM_Read<Args...>(image_data);
280228

281-
if (result)
229+
if constexpr (sizeof...(Args) == 1)
282230
{
283-
ImageData* image_data = (control_center->*get_image_data)();
284-
return Remote_VM_Read<R>(image_data);
231+
return std::invoke(func, this, std::move(args));
232+
}
233+
else
234+
{
235+
return std::apply(func, std::tuple_cat(std::make_tuple(this), std::move(args)));
285236
}
286-
return {};
287-
}
288-
289-
template<typename R, typename... Args>
290-
R RemoteVM::ExecuteCommand(ImageData* image_data, R (RemoteVM::*func)(Args...) const noexcept) const noexcept
291-
{
292-
auto args = std::tuple<std::decay_t<Args>...>{Remote_VM_Read<std::decay_t<Args>>(image_data)...};
293-
return std::apply(func, std::tuple_cat(std::forward_as_tuple(this), std::forward<std::tuple<std::decay_t<Args>...>>(args)));
294237
}
295238

296239
RemoteVM::RemoteVM(JNIEnv* env,
@@ -300,17 +243,17 @@ RemoteVM::RemoteVM(JNIEnv* env,
300243
ControlCenter* control_center,
301244
std::function<bool(std::function<void(Stream&, ImageData*)>)>&& send_command,
302245
ImageData* (ControlCenter::*get_image_data)() const) noexcept : env(env), control_center(control_center), send_command(send_command), get_image_data(get_image_data) {}
303-
RemoteVM::~RemoteVM() {}
246+
RemoteVM::~RemoteVM() = default;
304247

305-
RemoteVM::RemoteVM(RemoteVM&& other) : env(other.env), control_center(other.control_center), send_command(other.send_command), get_image_data(other.get_image_data)
248+
RemoteVM::RemoteVM(RemoteVM&& other) noexcept : env(other.env), control_center(other.control_center), send_command(other.send_command), get_image_data(other.get_image_data)
306249
{
307250
other.env = nullptr;
308251
other.control_center = nullptr;
309252
other.send_command = nullptr;
310253
other.get_image_data = nullptr;
311254
}
312255

313-
RemoteVM& RemoteVM::operator = (RemoteVM&& other)
256+
RemoteVM& RemoteVM::operator = (RemoteVM&& other) noexcept
314257
{
315258
env = other.env;
316259
control_center = other.control_center;
@@ -1060,6 +1003,7 @@ jfieldID RemoteVM::GetStaticFieldID(jclass clazz, const std::string &name, const
10601003
{
10611004
return SendCommand<jfieldID>(RemoteVMCommand::GET_STATIC_FIELD_ID, clazz, name, sig);
10621005
}
1006+
10631007
return env->GetStaticFieldID(clazz, name.c_str(), sig.c_str());
10641008
}
10651009

@@ -1263,7 +1207,7 @@ std::wstring RemoteVM::GetStringChars(jstring str) const noexcept
12631207

12641208
env->ReleaseStringChars(str, chars);
12651209
}
1266-
return std::wstring();
1210+
return {};
12671211
}
12681212

12691213
jstring RemoteVM::NewStringUTF(const std::string &utf) const noexcept
@@ -1304,7 +1248,7 @@ std::string RemoteVM::GetStringUTFChars(jstring str) const noexcept
13041248

13051249
env->ReleaseStringUTFChars(str, chars);
13061250
}
1307-
return std::string();
1251+
return {};
13081252
}
13091253

13101254
jsize RemoteVM::GetArrayLength(jarray array) const noexcept
@@ -1425,7 +1369,7 @@ void RemoteVM::SetObjectArrayElements(jobjectArray array, jsize index, const std
14251369

14261370
for (std::size_t i = 0; i < elements.size(); ++i)
14271371
{
1428-
env->SetObjectArrayElement(array, i + index, elements[i]);
1372+
env->SetObjectArrayElement(array, static_cast<jsize>(i) + index, elements[i]);
14291373
}
14301374
}
14311375

@@ -1931,7 +1875,7 @@ void RemoteVM::process_command(ImageData* image_data) const noexcept
19311875
jobject loader = Remote_VM_Read<jobject>(image_data);
19321876
jbyte* buf = Remote_VM_Read<jbyte*>(image_data);
19331877
jsize len = Remote_VM_Read<jsize>(image_data);
1934-
jclass result = this->DefineClass(name.c_str(), loader, buf == nullptr ? static_cast<jbyte*>(image_data->data_buffer(
1878+
jclass result = this->DefineClass(name, loader, buf == nullptr ? static_cast<jbyte*>(image_data->data_buffer(
19351879
std::ios::in)) : buf, len);
19361880
image_data->data_stream().write(result);
19371881
}
@@ -2063,6 +2007,9 @@ void RemoteVM::process_command(ImageData* image_data) const noexcept
20632007

20642008
case RemoteVMCommand::CALL_OBJECT_METHOD:
20652009
{
2010+
fprintf(stdout, "CALL_OBJECT_METHOD\n");
2011+
fflush(stdout);
2012+
20662013
jobject result = this->ExecuteCommand(image_data, &RemoteVM::CallObjectMethod);
20672014
image_data->data_stream().write(result);
20682015
}

RemoteInput/Plugin/JVM/RemoteVM.hxx

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,7 @@ private:
3030
T local_to_global(T object) const noexcept;
3131

3232
template<typename R, typename... Args>
33-
typename std::enable_if<!is_vector<R>::value, R>::type SendCommand(RemoteVMCommand command, Args&&... args) const noexcept;
34-
35-
template<typename R, typename... Args>
36-
typename std::enable_if<is_vector<R>::value, R>::type SendCommand(RemoteVMCommand command, Args&&... args) const noexcept;
33+
R SendCommand(RemoteVMCommand command, Args&&... args) const noexcept;
3734

3835
template<typename R, typename... Args>
3936
R ExecuteCommand(ImageData* image_data, R (RemoteVM::*func)(Args...) const noexcept) const noexcept;
@@ -50,10 +47,10 @@ public:
5047
~RemoteVM();
5148

5249
RemoteVM(const RemoteVM& other) = delete;
53-
RemoteVM(RemoteVM&& other);
50+
RemoteVM(RemoteVM&& other) noexcept ;
5451

5552
RemoteVM& operator = (const RemoteVM& other) = delete;
56-
RemoteVM& operator = (RemoteVM&& other);
53+
RemoteVM& operator = (RemoteVM&& other) noexcept;
5754

5855
std::size_t MaxMemoryChunkSize() const noexcept;
5956
void* AllocateMemory(std::size_t size) const noexcept;

0 commit comments

Comments
 (0)