From b4fa48263bf0d438a273f97e6ba846f81554a3d9 Mon Sep 17 00:00:00 2001 From: airajena Date: Sat, 27 Dec 2025 19:41:11 +0530 Subject: [PATCH] FINERACT-2421: Fix potential NullPointerException in CalendarCommandFromApiJsonDeserializer The extractBooleanNamed method can return null when the JSON value is null or missing. Using primitive boolean causes automatic unboxing which throws NullPointerException. Changes: - CalendarCommandFromApiJsonDeserializer: Use Boolean wrapper instead of primitive boolean for 'repeating' field extraction - CalendarCommandFromApiJsonDeserializer: Use Boolean.TRUE.equals() for null-safe boolean comparison - CalendarCommand: Update field type and constructor parameter from boolean to Boolean to support null values This addresses the FIXME comments on lines 156 and 298 in the original file. --- .../portfolio/calendar/command/CalendarCommand.java | 4 ++-- .../CalendarCommandFromApiJsonDeserializer.java | 12 +++++------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/command/CalendarCommand.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/command/CalendarCommand.java index 005ed9b7d..dea2009a4 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/command/CalendarCommand.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/command/CalendarCommand.java @@ -39,7 +39,7 @@ public class CalendarCommand { @SuppressWarnings("unused") private final Integer typeId; @SuppressWarnings("unused") - private final boolean repeating; + private final Boolean repeating; @SuppressWarnings("unused") private final Integer remindById; @SuppressWarnings("unused") @@ -48,7 +48,7 @@ public class CalendarCommand { private final Integer secondReminder; public CalendarCommand(final String title, final String description, final String location, final LocalDate startDate, - final LocalDate endDate, final LocalDate createdDate, final Integer duration, final Integer typeId, final boolean repeating, + final LocalDate endDate, final LocalDate createdDate, final Integer duration, final Integer typeId, final Boolean repeating, final Integer remindById, final Integer firstReminder, final Integer secondReminder) { this.title = title; this.description = description; diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/serialization/CalendarCommandFromApiJsonDeserializer.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/serialization/CalendarCommandFromApiJsonDeserializer.java index 0a39f1dd2..8f6c2395b 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/serialization/CalendarCommandFromApiJsonDeserializer.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/serialization/CalendarCommandFromApiJsonDeserializer.java @@ -81,7 +81,7 @@ public class CalendarCommandFromApiJsonDeserializer extends AbstractFromApiJsonD element); final Integer typeId = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(CalendarSupportedParameters.TYPE_ID.getValue(), element); - final boolean repeating = this.fromApiJsonHelper.extractBooleanNamed(CalendarSupportedParameters.REPEATING.getValue(), element); + final Boolean repeating = this.fromApiJsonHelper.extractBooleanNamed(CalendarSupportedParameters.REPEATING.getValue(), element); final Integer remindById = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(CalendarSupportedParameters.REMIND_BY_ID.getValue(), element); final Integer firstReminder = this.fromApiJsonHelper @@ -153,11 +153,10 @@ public class CalendarCommandFromApiJsonDeserializer extends AbstractFromApiJsonD .inMinMaxRange(CalendarEntityType.getMinValue(), CalendarEntityType.getMaxValue()); if (this.fromApiJsonHelper.parameterExists(CalendarSupportedParameters.REPEATING.getValue(), element)) { - // FIXME - Throws NullPointerException when boolean value is null - final boolean repeating = this.fromApiJsonHelper.extractBooleanNamed(CalendarSupportedParameters.REPEATING.getValue(), element); + final Boolean repeating = this.fromApiJsonHelper.extractBooleanNamed(CalendarSupportedParameters.REPEATING.getValue(), element); baseDataValidator.reset().parameter(CalendarSupportedParameters.REPEATING.getValue()).value(repeating).notNull(); - if (repeating) { + if (Boolean.TRUE.equals(repeating)) { final Integer frequency = this.fromApiJsonHelper .extractIntegerSansLocaleNamed(CalendarSupportedParameters.FREQUENCY.getValue(), element); baseDataValidator.reset().parameter(CalendarSupportedParameters.FREQUENCY.getValue()).value(frequency).notBlank() @@ -295,11 +294,10 @@ public class CalendarCommandFromApiJsonDeserializer extends AbstractFromApiJsonD .inMinMaxRange(CalendarEntityType.getMinValue(), CalendarEntityType.getMaxValue()); } if (this.fromApiJsonHelper.parameterExists(CalendarSupportedParameters.REPEATING.getValue(), element)) { - // FIXME - Throws NullPointerException when boolean value is null - final boolean repeating = this.fromApiJsonHelper.extractBooleanNamed(CalendarSupportedParameters.REPEATING.getValue(), element); + final Boolean repeating = this.fromApiJsonHelper.extractBooleanNamed(CalendarSupportedParameters.REPEATING.getValue(), element); baseDataValidator.reset().parameter(CalendarSupportedParameters.REPEATING.getValue()).value(repeating).notNull(); - if (repeating) { + if (Boolean.TRUE.equals(repeating)) { final Integer frequency = this.fromApiJsonHelper .extractIntegerSansLocaleNamed(CalendarSupportedParameters.FREQUENCY.getValue(), element); baseDataValidator.reset().parameter(CalendarSupportedParameters.FREQUENCY.getValue()).value(frequency).notBlank()