80 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			80 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			C++
		
	
	
	
| // Copyright 2021 Code Intelligence GmbH
 | |
| //
 | |
| // Licensed under the Apache License, Version 2.0 (the "License");
 | |
| // you may not use this file except in compliance with the License.
 | |
| // You may obtain a copy of the License at
 | |
| //
 | |
| //      http://www.apache.org/licenses/LICENSE-2.0
 | |
| //
 | |
| // Unless required by applicable law or agreed to in writing, software
 | |
| // distributed under the License is distributed on an "AS IS" BASIS,
 | |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | |
| // See the License for the specific language governing permissions and
 | |
| // limitations under the License.
 | |
| 
 | |
| #include "java_reproducer.h"
 | |
| 
 | |
| #include "fuzzed_data_provider.h"
 | |
| #include "jvm_tooling.h"
 | |
| 
 | |
| namespace {
 | |
| const char kRecordingFuzzedDataProviderClass[] =
 | |
|     "com/code_intelligence/jazzer/runtime/RecordingFuzzedDataProvider";
 | |
| }
 | |
| 
 | |
| namespace jazzer {
 | |
| jobject GetFuzzedDataProviderJavaObject(const JVM &jvm) {
 | |
|   static jobject java_object = nullptr;
 | |
|   if (java_object == nullptr) {
 | |
|     jclass java_class = jvm.FindClass(kFuzzedDataProviderImplClass);
 | |
|     jmethodID java_constructor = jvm.GetMethodID(java_class, "<init>", "()V");
 | |
|     jobject local_ref = jvm.GetEnv().NewObject(java_class, java_constructor);
 | |
|     // We leak a global reference here as it will be used until JVM exit.
 | |
|     java_object = jvm.GetEnv().NewGlobalRef(local_ref);
 | |
|   }
 | |
|   return java_object;
 | |
| }
 | |
| 
 | |
| jobject GetRecordingFuzzedDataProviderJavaObject(const JVM &jvm) {
 | |
|   auto &env = jvm.GetEnv();
 | |
|   jclass java_class = jvm.FindClass(kRecordingFuzzedDataProviderClass);
 | |
|   jmethodID java_make_proxy = jvm.GetStaticMethodID(
 | |
|       java_class, "makeFuzzedDataProviderProxy",
 | |
|       "()Lcom/code_intelligence/jazzer/api/FuzzedDataProvider;", true);
 | |
|   jobject local_ref = env.CallStaticObjectMethod(java_class, java_make_proxy);
 | |
|   if (env.ExceptionCheck()) {
 | |
|     env.ExceptionDescribe();
 | |
|     exit(1);
 | |
|   }
 | |
|   // This global reference is deleted in SerializeRecordingFuzzedDataProvider.
 | |
|   jobject global_ref = env.NewGlobalRef(local_ref);
 | |
|   env.DeleteLocalRef(local_ref);
 | |
|   return global_ref;
 | |
| }
 | |
| 
 | |
| std::string SerializeRecordingFuzzedDataProvider(const JVM &jvm,
 | |
|                                                  jobject recorder) {
 | |
|   auto &env = jvm.GetEnv();
 | |
|   jclass java_class = jvm.FindClass(kRecordingFuzzedDataProviderClass);
 | |
|   jmethodID java_serialize =
 | |
|       jvm.GetStaticMethodID(java_class, "serializeFuzzedDataProviderProxy",
 | |
|                             "(Lcom/code_intelligence/jazzer/api/"
 | |
|                             "FuzzedDataProvider;)Ljava/lang/String;",
 | |
|                             true);
 | |
|   auto serialized_recorder =
 | |
|       (jstring)env.CallStaticObjectMethod(java_class, java_serialize, recorder);
 | |
|   env.DeleteLocalRef(java_class);
 | |
|   env.DeleteGlobalRef(recorder);
 | |
|   if (env.ExceptionCheck()) {
 | |
|     env.ExceptionDescribe();
 | |
|     exit(1);
 | |
|   }
 | |
|   const char *serialized_recorder_cstr =
 | |
|       env.GetStringUTFChars(serialized_recorder, nullptr);
 | |
|   std::string out(serialized_recorder_cstr);
 | |
|   env.ReleaseStringUTFChars(serialized_recorder, serialized_recorder_cstr);
 | |
|   env.DeleteLocalRef(serialized_recorder);
 | |
|   return out;
 | |
| }
 | |
| }  // namespace jazzer
 |