From 4af8f91470c3157bdb206dd8af8a8238418c9f2b Mon Sep 17 00:00:00 2001 From: michaldev0 <125133223+michaldev0@users.noreply.github.com> Date: Tue, 9 Jun 2026 13:46:05 +0200 Subject: [PATCH 1/3] OLMIS-8118: Validate max value on integer inputs Inputs with java-integer attribute now reject values exceeding Java Integer.MAX_VALUE. --- .../positive-integer.directive.js | 11 +- .../positive-integer.directive.spec.js | 111 ++++++++++++++++++ 2 files changed, 121 insertions(+), 1 deletion(-) create mode 100644 src/openlmis-form/positive-integer.directive.spec.js diff --git a/src/openlmis-form/positive-integer.directive.js b/src/openlmis-form/positive-integer.directive.js index cd206afa..850f0f06 100644 --- a/src/openlmis-form/positive-integer.directive.js +++ b/src/openlmis-form/positive-integer.directive.js @@ -31,8 +31,11 @@ * * ``` */ + var JAVA_INTEGER_MAX = Math.pow(2, 31) - 1; + angular .module('openlmis-form') + .constant('JAVA_INTEGER_MAX', JAVA_INTEGER_MAX) .directive('positiveInteger', positiveInteger); function positiveInteger() { @@ -59,7 +62,13 @@ modelCtrl.$render(); } - return transformedInput ? parseInt(transformedInput) : null; + var parsed = transformedInput ? parseInt(transformedInput) : null; + + if (attrs.hasOwnProperty('javaInteger')) { + modelCtrl.$setValidity('max', !parsed || parsed <= JAVA_INTEGER_MAX); + } + + return parsed; }); } } diff --git a/src/openlmis-form/positive-integer.directive.spec.js b/src/openlmis-form/positive-integer.directive.spec.js new file mode 100644 index 00000000..14c7ffd9 --- /dev/null +++ b/src/openlmis-form/positive-integer.directive.spec.js @@ -0,0 +1,111 @@ +/* + * This program is part of the OpenLMIS logistics management information system platform software. + * Copyright © 2017 VillageReach + * + * This program is free software: you can redistribute it and/or modify it under the terms + * of the GNU Affero General Public License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + *   + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  + * See the GNU Affero General Public License for more details. You should have received a copy of + * the GNU Affero General Public License along with this program. If not, see + * http://www.gnu.org/licenses.  For additional information contact info@OpenLMIS.org.  + */ +describe('openlmisPositiveInteger', function() { + + beforeEach(function() { + module('openlmis-form'); + + inject(function($injector) { + this.$compile = $injector.get('$compile'); + this.$rootScope = $injector.get('$rootScope'); + }); + + this.$scope = this.$rootScope.$new(); + + this.compileElement = function(extraAttrs) { + this.element = this.$compile( + '
' + + '
' + )(this.$scope); + angular.element('body').append(this.element); + this.$rootScope.$apply(); + }; + + this.compileElement(); + }); + + it('should add number class', function() { + expect(this.$scope.form_test.input_test.$$element.hasClass('number')).toBe(true); + }); + + it('should strip non-numeric characters', function() { + this.$scope.form_test.input_test.$setViewValue('12abc3'); + this.$scope.$digest(); + + expect(this.$scope.example).toEqual(123); + }); + + it('should parse value as integer', function() { + this.$scope.form_test.input_test.$setViewValue('42'); + this.$scope.$digest(); + + expect(this.$scope.example).toEqual(42); + }); + + it('should return null for empty input', function() { + this.$scope.form_test.input_test.$setViewValue(''); + this.$scope.$digest(); + + expect(this.$scope.example).toBeNull(); + }); + + describe('without java-integer attribute', function() { + + it('should not validate max', function() { + this.$scope.form_test.input_test.$setViewValue('9999999999'); + this.$scope.$digest(); + + expect(this.$scope.form_test.input_test.$error.max).toBeFalsy(); + }); + }); + + describe('with java-integer attribute', function() { + + beforeEach(function() { + this.compileElement('java-integer'); + }); + + it('should be valid for value within Java Integer range', function() { + this.$scope.form_test.input_test.$setViewValue('2147483647'); + this.$scope.$digest(); + + expect(this.$scope.form_test.input_test.$error.max).toBeFalsy(); + expect(this.$scope.form_test.input_test.$valid).toBe(true); + }); + + it('should be invalid for value exceeding Java Integer max', function() { + this.$scope.form_test.input_test.$setViewValue('2147483648'); + this.$scope.$digest(); + + expect(this.$scope.form_test.input_test.$error.max).toBe(true); + expect(this.$scope.example).toBe(2147483648); + }); + + it('should be valid for empty value', function() { + this.$scope.form_test.input_test.$setViewValue(''); + this.$scope.$digest(); + + expect(this.$scope.form_test.input_test.$error.max).toBeFalsy(); + }); + + it('should be valid for typical small quantity', function() { + this.$scope.form_test.input_test.$setViewValue('100'); + this.$scope.$digest(); + + expect(this.$scope.form_test.input_test.$error.max).toBeFalsy(); + }); + }); +}); \ No newline at end of file From 447418174a1bf8f8c0fd3744fb75cad5d537137d Mon Sep 17 00:00:00 2001 From: michaldev0 <125133223+michaldev0@users.noreply.github.com> Date: Sun, 21 Jun 2026 18:31:29 +0200 Subject: [PATCH 2/3] OLMIS-8118: Validate max safe integer on inputs --- src/openlmis-form/positive-integer.directive.js | 16 ++++++++++++---- .../positive-integer.directive.spec.js | 9 ++++++++- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/openlmis-form/positive-integer.directive.js b/src/openlmis-form/positive-integer.directive.js index 850f0f06..556158c9 100644 --- a/src/openlmis-form/positive-integer.directive.js +++ b/src/openlmis-form/positive-integer.directive.js @@ -23,13 +23,20 @@ * @name openlmis-form.directive:positiveInteger * * @description - * Restricts the ngModel to only allow positive integers. + * Restricts the ngModel to only allow positive integers. Values larger than the maximum safe + * integer in JavaScript are rejected (the 'max' validity is set to false), because parseInt + * would otherwise silently overflow and send a wrong value. When the java-integer attribute is + * present the limit is lowered to the maximum Java Integer value. * * @example * Extend the input element to force it to only accept positive integers as values. * ``` * * ``` + * Add the java-integer attribute to additionally reject values exceeding the Java Integer range. + * ``` + * + * ``` */ var JAVA_INTEGER_MAX = Math.pow(2, 31) - 1; @@ -64,9 +71,10 @@ var parsed = transformedInput ? parseInt(transformedInput) : null; - if (attrs.hasOwnProperty('javaInteger')) { - modelCtrl.$setValidity('max', !parsed || parsed <= JAVA_INTEGER_MAX); - } + var maxValue = attrs.hasOwnProperty('javaInteger') + ? JAVA_INTEGER_MAX + : Number.MAX_SAFE_INTEGER; + modelCtrl.$setValidity('max', !parsed || parsed <= maxValue); return parsed; }); diff --git a/src/openlmis-form/positive-integer.directive.spec.js b/src/openlmis-form/positive-integer.directive.spec.js index 14c7ffd9..b62280cd 100644 --- a/src/openlmis-form/positive-integer.directive.spec.js +++ b/src/openlmis-form/positive-integer.directive.spec.js @@ -64,12 +64,19 @@ describe('openlmisPositiveInteger', function() { describe('without java-integer attribute', function() { - it('should not validate max', function() { + it('should be valid for value within the safe integer range', function() { this.$scope.form_test.input_test.$setViewValue('9999999999'); this.$scope.$digest(); expect(this.$scope.form_test.input_test.$error.max).toBeFalsy(); }); + + it('should be invalid for value exceeding the max safe integer', function() { + this.$scope.form_test.input_test.$setViewValue('99999999999999999'); + this.$scope.$digest(); + + expect(this.$scope.form_test.input_test.$error.max).toBe(true); + }); }); describe('with java-integer attribute', function() { From 1f8d4c7b7f701d5babb366566179189561586131 Mon Sep 17 00:00:00 2001 From: michaldev0 <125133223+michaldev0@users.noreply.github.com> Date: Mon, 22 Jun 2026 13:52:52 +0200 Subject: [PATCH 3/3] OLMIS-8118: Add changelog entry --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 493cb18c..79a96183 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ Upcoming Version (WIP) ================== Improvements: +* [OLMIS-8118](https://openlmis.atlassian.net/browse/OLMIS-8118): Validate max value on positive integer inputs. * [SELV3-748](https://openlmis.atlassian.net/browse/SELV3-748) Resolved cookie issue causing untranslated warning messages * [OLMIS-8192](https://openlmis.atlassian.net/browse/OLMIS-8192): Editable text inputs inside table cells now grow with their content.