Skip to content

Commit

Permalink
fix: [IOCOM-645,IABT-1485] Fix an Android crash when dealing with cal…
Browse files Browse the repository at this point in the history
…endar events (#5404)

## Short description
This PR prevents a crash on Android devices when trying to add/remove
calendar events

![7120a04e-58a1-4ebd-b139-3097892f7d50](https://github.com/pagopa/io-app/assets/5150343/165cbd32-ce05-4032-bc08-ff73afcfe739)

## List of changes proposed in this pull request
- The library used to handle calendar events,
`react-native-calendar-events`, has been patched in order to handle
event Ids of type `long` (where the reported crash clearly showed that
it was trying to convert a >4G numeric string into a signed int32

## How to test
Add and remove calendar events on an Android device and check that there
are no problems.
Also check that the patched file matches the same edits [in this
PR](https://github.com/wmcmahan/react-native-calendar-events/pull/359/files).
  • Loading branch information
Vangaorth authored Jan 17, 2024
1 parent 12c22e8 commit a320053
Show file tree
Hide file tree
Showing 2 changed files with 184 additions and 0 deletions.
11 changes: 11 additions & 0 deletions patches/patches.md
Original file line number Diff line number Diff line change
Expand Up @@ -164,3 +164,14 @@ Updated on **13/07/2023**
#### Reason:

- This patch applies security fixes to avoid access on camera and microphone without user permission.

### react-native-calendar-events+2.2.0.patch

Created on **16/01/2023**

#### Reason:

- This patch fixes a crash on Android devices when trying to find/create/remove calendar events.
An Event has an Id property which type may be a long but the library deals only with Java's signed int32.
This was fine as long as each event was originally created and handled using this library only but
initially another library was used, react-native-add-calendar-event, which treated event's Id as long
173 changes: 173 additions & 0 deletions patches/react-native-calendar-events+2.2.0.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
diff --git a/node_modules/react-native-calendar-events/android/src/main/java/com/calendarevents/RNCalendarEvents.java b/node_modules/react-native-calendar-events/android/src/main/java/com/calendarevents/RNCalendarEvents.java
index 782a0da..df20396 100644
--- a/node_modules/react-native-calendar-events/android/src/main/java/com/calendarevents/RNCalendarEvents.java
+++ b/node_modules/react-native-calendar-events/android/src/main/java/com/calendarevents/RNCalendarEvents.java
@@ -162,7 +162,7 @@ public class RNCalendarEvents extends ReactContextBaseJavaModule implements Perm
WritableNativeMap result;
Cursor cursor;
ContentResolver cr = reactContext.getContentResolver();
- Uri uri = ContentUris.withAppendedId(CalendarContract.Calendars.CONTENT_URI, Integer.parseInt(calendarID));
+ Uri uri = ContentUris.withAppendedId(CalendarContract.Calendars.CONTENT_URI, Long.parseLong(calendarID));

String IS_PRIMARY = CalendarContract.Calendars.IS_PRIMARY == null ? "0" : CalendarContract.Calendars.IS_PRIMARY;

@@ -215,7 +215,7 @@ public class RNCalendarEvents extends ReactContextBaseJavaModule implements Perm
return CalendarContract.Calendars.CAL_ACCESS_NONE;
}

- private int addCalendar(ReadableMap details) throws Exception, SecurityException {
+ private long addCalendar(ReadableMap details) throws Exception, SecurityException {

ContentResolver cr = reactContext.getContentResolver();
ContentValues calendarValues = new ContentValues();
@@ -272,7 +272,7 @@ public class RNCalendarEvents extends ReactContextBaseJavaModule implements Perm
Uri calendarsUri = uriBuilder.build();

Uri calendarUri = cr.insert(calendarsUri, calendarValues);
- return Integer.parseInt(calendarUri.getLastPathSegment());
+ return Long.parseLong(calendarUri.getLastPathSegment());
}

private boolean removeCalendar(String calendarID) {
@@ -281,7 +281,7 @@ public class RNCalendarEvents extends ReactContextBaseJavaModule implements Perm
try {
ContentResolver cr = reactContext.getContentResolver();

- Uri uri = ContentUris.withAppendedId(CalendarContract.Calendars.CONTENT_URI, (long) Integer.parseInt(calendarID));
+ Uri uri = ContentUris.withAppendedId(CalendarContract.Calendars.CONTENT_URI, Long.parseLong(calendarID));
rows = cr.delete(uri, null, null);

} catch (Exception e) {
@@ -401,7 +401,7 @@ public class RNCalendarEvents extends ReactContextBaseJavaModule implements Perm
WritableNativeMap result;
Cursor cursor = null;
ContentResolver cr = reactContext.getContentResolver();
- Uri uri = ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, Integer.parseInt(eventID));
+ Uri uri = ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, Long.parseLong(eventID));

String selection = "((" + CalendarContract.Events.DELETED + " != 1))";

@@ -472,7 +472,7 @@ public class RNCalendarEvents extends ReactContextBaseJavaModule implements Perm
return result;
}

- private int addEvent(String title, ReadableMap details, ReadableMap options) throws ParseException {
+ private long addEvent(String title, ReadableMap details, ReadableMap options) throws ParseException {
String dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";
SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
boolean skipTimezone = false;
@@ -623,7 +623,7 @@ public class RNCalendarEvents extends ReactContextBaseJavaModule implements Perm
}

if (details.hasKey("id")) {
- int eventID = Integer.parseInt(details.getString("id"));
+ long eventID = Long.parseLong(details.getString("id"));
WritableMap eventInstance = findEventById(details.getString("id"));

if (eventInstance != null) {
@@ -654,7 +654,7 @@ public class RNCalendarEvents extends ReactContextBaseJavaModule implements Perm
throw e;
}

- Uri exceptionUri = Uri.withAppendedPath(CalendarContract.Events.CONTENT_EXCEPTION_URI, Integer.toString(eventID));
+ Uri exceptionUri = Uri.withAppendedPath(CalendarContract.Events.CONTENT_EXCEPTION_URI, Long.toString(eventID));

if (options.hasKey("sync") && options.getBoolean("sync")) {
syncCalendar(cr, eventInstance.getMap("calendar").getString("id"));
@@ -664,7 +664,7 @@ public class RNCalendarEvents extends ReactContextBaseJavaModule implements Perm
try {
Uri eventUri = cr.insert(exceptionUri, eventValues);
if (eventUri != null) {
- eventID = Integer.parseInt(eventUri.getLastPathSegment());
+ eventID = Long.parseLong(eventUri.getLastPathSegment());
}
} catch (Exception e) {
Log.d(this.getName(), "Event exception error", e);
@@ -673,24 +673,24 @@ public class RNCalendarEvents extends ReactContextBaseJavaModule implements Perm
}

if (details.hasKey("alarms")) {
- createRemindersForEvent(cr, Integer.parseInt(details.getString("id")), details.getArray("alarms"));
+ createRemindersForEvent(cr, Long.parseLong(details.getString("id")), details.getArray("alarms"));
}

if (details.hasKey("attendees")) {
- createAttendeesForEvent(cr, Integer.parseInt(details.getString("id")), details.getArray("attendees"));
+ createAttendeesForEvent(cr, Long.parseLong(details.getString("id")), details.getArray("attendees"));
}

return eventID;

} else {
WritableNativeMap calendar;
- int eventID = -1;
+ long eventID = -1;

if (details.hasKey("calendarId")) {
calendar = findCalendarById(details.getString("calendarId"));

if (calendar != null) {
- eventValues.put(CalendarContract.Events.CALENDAR_ID, Integer.parseInt(calendar.getString("id")));
+ eventValues.put(CalendarContract.Events.CALENDAR_ID, Long.parseLong(calendar.getString("id")));
} else {
eventValues.put(CalendarContract.Events.CALENDAR_ID, 1);
}
@@ -712,7 +712,7 @@ public class RNCalendarEvents extends ReactContextBaseJavaModule implements Perm
if (eventUri != null) {
String rowId = eventUri.getLastPathSegment();
if (rowId != null) {
- eventID = Integer.parseInt(rowId);
+ eventID = Long.parseLong(rowId);

if (details.hasKey("alarms")) {
createRemindersForEvent(cr, eventID, details.getArray("alarms"));
@@ -739,7 +739,7 @@ public class RNCalendarEvents extends ReactContextBaseJavaModule implements Perm
ReadableMap eventCalendar = eventInstance.getMap("calendar");

if (!options.hasKey("exceptionDate")) {
- Uri uri = ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, (long) Integer.parseInt(eventID));
+ Uri uri = ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, Long.parseLong(eventID));

if (options.hasKey("sync") && options.getBoolean("sync")) {
syncCalendar(cr, eventCalendar.getString("id"));
@@ -810,7 +810,7 @@ public class RNCalendarEvents extends ReactContextBaseJavaModule implements Perm
//endregion

//region Attendees
- private void createAttendeesForEvent(ContentResolver resolver, int eventID, ReadableArray attendees) {
+ private void createAttendeesForEvent(ContentResolver resolver, long eventID, ReadableArray attendees) {
Cursor cursor = CalendarContract.Attendees.query(resolver, eventID, new String[] {
CalendarContract.Attendees._ID
});
@@ -842,7 +842,7 @@ public class RNCalendarEvents extends ReactContextBaseJavaModule implements Perm
//endregion

//region Reminders
- private void createRemindersForEvent(ContentResolver resolver, int eventID, ReadableArray reminders) {
+ private void createRemindersForEvent(ContentResolver resolver, long eventID, ReadableArray reminders) {
Cursor cursor = null;

if (resolver != null) {
@@ -1281,7 +1281,7 @@ public class RNCalendarEvents extends ReactContextBaseJavaModule implements Perm
@Override
public void run() {
try {
- Integer calendarID = addCalendar(options);
+ Long calendarID = addCalendar(options);
promise.resolve(calendarID.toString());
} catch (Exception e) {
promise.reject("save calendar error", e.getMessage());
@@ -1322,11 +1322,11 @@ public class RNCalendarEvents extends ReactContextBaseJavaModule implements Perm
Thread thread = new Thread(new Runnable(){
@Override
public void run() {
- int eventId;
+ long eventId;
try {
eventId = addEvent(title, details, options);
if (eventId > -1) {
- promise.resolve(Integer.toString(eventId));
+ promise.resolve(Long.toString(eventId));
} else {
promise.reject("add event error", "Unable to save event");
}

0 comments on commit a320053

Please sign in to comment.