Skip to content

Commit

Permalink
Fix "Illegal type provided" crash (#2853)
Browse files Browse the repository at this point in the history
## Description

Sometimes RN passes ReadableMap/Array instead of WritableMap/Array when updateProps is called. Currently adding a ReadableMap/Array to a WritableMap/Array is not supported (I opened a PR to allow it since there's no reason it can't be allowed facebook/react-native#32910). In the meantime we have to check if it's not Writable and copy before adding it.

Fixes #2722

## Changes


## Screenshots / GIFs

N/A

## Test code and steps to reproduce

I'm not sure exactly what the minimum repro is, I could 100% repro the crash in an app, but wasn't able to isolate. The app makes heavy usage of a bottom sheet lib that uses reanimated. I was able to repro a few times in the example app with the repro in the linked issue, but not consistently.

In the app where I could repro consistently I verified that it no longer crashes after this change.

## Checklist

- [ ] Included code example that can be used to test this change
- [ ] Updated TS types
- [ ] Added TS types tests
- [ ] Added unit / integration tests
- [ ] Updated documentation
- [ ] Ensured that CI passes
  • Loading branch information
janicduplessis authored Feb 2, 2022
1 parent 99d8263 commit ca620a3
Showing 1 changed file with 48 additions and 2 deletions.
50 changes: 48 additions & 2 deletions android/src/main/java/com/swmansion/reanimated/NodesManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.ReadableType;
import com.facebook.react.bridge.UiThreadUtil;
import com.facebook.react.bridge.WritableArray;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.modules.core.DeviceEventManagerModule;
import com.facebook.react.modules.core.ReactChoreographer;
Expand Down Expand Up @@ -612,6 +614,42 @@ public String obtainProp(int viewTag, String propName) {
return result;
}

private static WritableMap copyReadableMap(ReadableMap map) {
WritableMap copy = Arguments.createMap();
copy.merge(map);
return copy;
}

private static WritableArray copyReadableArray(ReadableArray array) {
WritableArray copy = Arguments.createArray();
for (int i = 0; i < array.size(); i++) {
ReadableType type = array.getType(i);
switch (type) {
case Boolean:
copy.pushBoolean(array.getBoolean(i));
break;
case String:
copy.pushString(array.getString(i));
break;
case Null:
copy.pushNull();
break;
case Number:
copy.pushDouble(array.getDouble(i));
break;
case Map:
copy.pushMap(copyReadableMap(array.getMap(i)));
break;
case Array:
copy.pushArray(copyReadableArray(array.getArray(i)));
break;
default:
throw new IllegalStateException("Unknown type of ReadableArray");
}
}
return copy;
}

private static void addProp(WritableMap propMap, String key, Object value) {
if (value == null) {
propMap.putNull(key);
Expand All @@ -626,9 +664,17 @@ private static void addProp(WritableMap propMap, String key, Object value) {
} else if (value instanceof String) {
propMap.putString(key, (String) value);
} else if (value instanceof ReadableArray) {
propMap.putArray(key, (ReadableArray) value);
if (!(value instanceof WritableArray)) {
propMap.putArray(key, copyReadableArray((ReadableArray) value));
} else {
propMap.putArray(key, (ReadableArray) value);
}
} else if (value instanceof ReadableMap) {
propMap.putMap(key, (ReadableMap) value);
if (!(value instanceof WritableMap)) {
propMap.putMap(key, copyReadableMap((ReadableMap) value));
} else {
propMap.putMap(key, (ReadableMap) value);
}
} else {
throw new IllegalStateException("Unknown type of animated value");
}
Expand Down

0 comments on commit ca620a3

Please sign in to comment.