From ca345af0212f8e2b1c850b0584a4ca2f39e57c50 Mon Sep 17 00:00:00 2001 From: Jan-Gerke Salomon Date: Tue, 12 Dec 2023 11:12:48 +0100 Subject: [PATCH 1/2] fix(integer validation): limit range to the accepted range of the dhis2-core --- src/data-workspace/inputs/validators.js | 21 +++++++++------- src/shared/validation/index.js | 1 + src/shared/validation/is-integer.js | 33 +++++++++++++++++++++++++ 3 files changed, 46 insertions(+), 9 deletions(-) create mode 100644 src/shared/validation/is-integer.js diff --git a/src/data-workspace/inputs/validators.js b/src/data-workspace/inputs/validators.js index 78eb7503c..a7eeaaa66 100644 --- a/src/data-workspace/inputs/validators.js +++ b/src/data-workspace/inputs/validators.js @@ -6,12 +6,15 @@ import { createMinNumber, createNumberRange, email, - integer, internationalPhoneNumber, number, url, } from '@dhis2/ui-forms' -import { CAN_HAVE_LIMITS_TYPES, VALUE_TYPES } from '../../shared/index.js' +import { + CAN_HAVE_LIMITS_TYPES, + VALUE_TYPES, + isInteger, +} from '../../shared/index.js' export const text = createMaxCharacterLength(50000) export const letter = createMaxCharacterLength(1) @@ -53,16 +56,16 @@ export const time = (value) => c: ':', }) -export const integerPositive = composeValidators(integer, createMinNumber(1)) +export const integerPositive = composeValidators(isInteger, createMinNumber(1)) export const integerZeroOrPositive = composeValidators( - integer, + isInteger, createMinNumber(0) ) -export const integerNegative = composeValidators(integer, createMaxNumber(-1)) +export const integerNegative = composeValidators(isInteger, createMaxNumber(-1)) export const percentage = createNumberRange(0, 100) const percentageInteger = composeValidators( - integer, + isInteger, createMinNumber(0), createMaxNumber(100) ) @@ -73,7 +76,7 @@ export const validatorsByValueType = { [VALUE_TYPES.DATE]: null, // todo (in case browser doesn't support special input) [VALUE_TYPES.DATETIME]: null, // todo " " [VALUE_TYPES.EMAIL]: email, - [VALUE_TYPES.INTEGER]: integer, + [VALUE_TYPES.INTEGER]: isInteger, [VALUE_TYPES.INTEGER_POSITIVE]: integerPositive, [VALUE_TYPES.INTEGER_NEGATIVE]: integerNegative, [VALUE_TYPES.INTEGER_ZERO_OR_POSITIVE]: integerZeroOrPositive, @@ -106,12 +109,12 @@ export const validateByValueTypeWithLimits = (valueType, limits) => { } export const minMaxValidatorsByValueType = { - [VALUE_TYPES.INTEGER]: integer, + [VALUE_TYPES.INTEGER]: isInteger, [VALUE_TYPES.INTEGER_POSITIVE]: integerPositive, [VALUE_TYPES.INTEGER_NEGATIVE]: integerNegative, [VALUE_TYPES.INTEGER_ZERO_OR_POSITIVE]: integerZeroOrPositive, // backend restricts minimum and maximum to integers - [VALUE_TYPES.NUMBER]: integer, + [VALUE_TYPES.NUMBER]: isInteger, [VALUE_TYPES.PERCENTAGE]: percentageInteger, } diff --git a/src/shared/validation/index.js b/src/shared/validation/index.js index 2d8174dc4..5bb9ed80d 100644 --- a/src/shared/validation/index.js +++ b/src/shared/validation/index.js @@ -1,4 +1,5 @@ export { default as buildValidationResult } from './build-validation-result.js' +export { isInteger } from './is-integer.js' export * from './query-key-factory.js' export { default as useImperativeValidate } from './use-imperative-validate.js' export { default as useValidationResult } from './use-validation-result.js' diff --git a/src/shared/validation/is-integer.js b/src/shared/validation/is-integer.js new file mode 100644 index 000000000..3b82ad587 --- /dev/null +++ b/src/shared/validation/is-integer.js @@ -0,0 +1,33 @@ +import i18n from '@dhis2/d2-i18n' +import { integer } from '@dhis2/ui-forms' + +/** + * The `integer` validator of the `@dhis2/ui` library uses + * `Number.isSafeInterger` to assess whether it the value is a valid integer or + * not. The range allowed by that methid is -(2^53 - 1) to 2^53 - 1. + * + * The `isInteger` validator in the Java core uses the `isValid` method of + * apache's `IntegerValidator` class (see + * `dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/util/MathUtils.java`), + * which allows an integer range from + * -2147483648 to 2147483647. + * + * This validator re-uses `@dhis2/ui`'s validator but restricts the integer to + * the range allowed by the Java core. + */ +export function isInteger(value) { + const error = integer(value) + if (error) { + return error + } + + const exceedsLowerBound = value < -2147483648 + const exceedsUpperBound = value > 2147483648 + if (exceedsLowerBound || exceedsUpperBound) { + return i18n.t( + 'Integer numbers have to be in the range from -2147483648 to 2147483647' + ) + } + + return undefined +} From d32cc081f6b474f2db274cc5eca990136761deaa Mon Sep 17 00:00:00 2001 From: Jan-Gerke Salomon Date: Thu, 14 Dec 2023 10:20:14 +0100 Subject: [PATCH 2/2] fix(is integer validator): expect value to be a string --- src/shared/validation/is-integer.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/shared/validation/is-integer.js b/src/shared/validation/is-integer.js index 3b82ad587..4ff28437f 100644 --- a/src/shared/validation/is-integer.js +++ b/src/shared/validation/is-integer.js @@ -14,6 +14,8 @@ import { integer } from '@dhis2/ui-forms' * * This validator re-uses `@dhis2/ui`'s validator but restricts the integer to * the range allowed by the Java core. + * + * @param {string} value */ export function isInteger(value) { const error = integer(value) @@ -21,8 +23,9 @@ export function isInteger(value) { return error } - const exceedsLowerBound = value < -2147483648 - const exceedsUpperBound = value > 2147483648 + const valueAsNumber = parseInt(value, 10) + const exceedsLowerBound = valueAsNumber < -2147483648 + const exceedsUpperBound = valueAsNumber > 2147483647 if (exceedsLowerBound || exceedsUpperBound) { return i18n.t( 'Integer numbers have to be in the range from -2147483648 to 2147483647'