Fix Use After Free With Concurrent Java GC #1279
@@ -32,7 +32,7 @@ public class YogaNative {
|
|||||||
// YGNode related
|
// YGNode related
|
||||||
static native long jni_YGNodeNewJNI();
|
static native long jni_YGNodeNewJNI();
|
||||||
static native long jni_YGNodeNewWithConfigJNI(long configPointer);
|
static native long jni_YGNodeNewWithConfigJNI(long configPointer);
|
||||||
static native void jni_YGNodeFreeJNI(long nativePointer);
|
static native void jni_YGNodeDeallocateJNI(long nativePointer);
|
||||||
static native void jni_YGNodeResetJNI(long nativePointer);
|
static native void jni_YGNodeResetJNI(long nativePointer);
|
||||||
static native void jni_YGNodeInsertChildJNI(long nativePointer, long childPointer, int index);
|
static native void jni_YGNodeInsertChildJNI(long nativePointer, long childPointer, int index);
|
||||||
static native void jni_YGNodeSwapChildJNI(long nativePointer, long childPointer, int index);
|
static native void jni_YGNodeSwapChildJNI(long nativePointer, long childPointer, int index);
|
||||||
|
@@ -29,7 +29,7 @@ public class YogaNodeJNIFinalizer extends YogaNodeJNIBase {
|
|||||||
if (mNativePointer != 0) {
|
if (mNativePointer != 0) {
|
||||||
long nativePointer = mNativePointer;
|
long nativePointer = mNativePointer;
|
||||||
mNativePointer = 0;
|
mNativePointer = 0;
|
||||||
YogaNative.jni_YGNodeFreeJNI(nativePointer);
|
YogaNative.jni_YGNodeDeallocateJNI(nativePointer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -199,7 +199,10 @@ static void jni_YGConfigSetLoggerJNI(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void jni_YGNodeFreeJNI(JNIEnv* env, jobject obj, jlong nativePointer) {
|
static void jni_YGNodeDeallocateJNI(
|
||||||
|
JNIEnv* env,
|
||||||
|
jobject obj,
|
||||||
|
jlong nativePointer) {
|
||||||
if (nativePointer == 0) {
|
if (nativePointer == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -769,7 +772,7 @@ static JNINativeMethod methods[] = {
|
|||||||
(void*) jni_YGConfigSetLoggerJNI},
|
(void*) jni_YGConfigSetLoggerJNI},
|
||||||
{"jni_YGNodeNewJNI", "()J", (void*) jni_YGNodeNewJNI},
|
{"jni_YGNodeNewJNI", "()J", (void*) jni_YGNodeNewJNI},
|
||||||
{"jni_YGNodeNewWithConfigJNI", "(J)J", (void*) jni_YGNodeNewWithConfigJNI},
|
{"jni_YGNodeNewWithConfigJNI", "(J)J", (void*) jni_YGNodeNewWithConfigJNI},
|
||||||
{"jni_YGNodeFreeJNI", "(J)V", (void*) jni_YGNodeFreeJNI},
|
{"jni_YGNodeDeallocateJNI", "(J)V", (void*) jni_YGNodeDeallocateJNI},
|
||||||
{"jni_YGNodeResetJNI", "(J)V", (void*) jni_YGNodeResetJNI},
|
{"jni_YGNodeResetJNI", "(J)V", (void*) jni_YGNodeResetJNI},
|
||||||
{"jni_YGNodeInsertChildJNI", "(JJI)V", (void*) jni_YGNodeInsertChildJNI},
|
{"jni_YGNodeInsertChildJNI", "(JJI)V", (void*) jni_YGNodeInsertChildJNI},
|
||||||
{"jni_YGNodeSwapChildJNI", "(JJI)V", (void*) jni_YGNodeSwapChildJNI},
|
{"jni_YGNodeSwapChildJNI", "(JJI)V", (void*) jni_YGNodeSwapChildJNI},
|
||||||
|
@@ -27,6 +27,10 @@ void YGNodeCalculateLayoutWithContext(
|
|||||||
YGDirection ownerDirection,
|
YGDirection ownerDirection,
|
||||||
void* layoutContext);
|
void* layoutContext);
|
||||||
|
|
||||||
|
// Deallocates a Yoga Node. Unlike YGNodeFree, does not remove the node from
|
||||||
|
// its parent or children.
|
||||||
|
void YGNodeDeallocate(YGNodeRef node);
|
||||||
|
|
||||||
YG_EXTERN_C_END
|
YG_EXTERN_C_END
|
||||||
|
|
||||||
namespace facebook {
|
namespace facebook {
|
||||||
|
@@ -230,6 +230,10 @@ YOGA_EXPORT void YGNodeFree(const YGNodeRef node) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
node->clearChildren();
|
node->clearChildren();
|
||||||
|
YGNodeDeallocate(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
YOGA_EXPORT void YGNodeDeallocate(const YGNodeRef node) {
|
||||||
Event::publish<Event::NodeDeallocation>(node, {node->getConfig()});
|
Event::publish<Event::NodeDeallocation>(node, {node->getConfig()});
|
||||||
delete node;
|
delete node;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user