@@ -833,10 +833,12 @@ class Integer {
833833 * @access private
834834 * @param {string } str The textual representation of the Integer
835835 * @param {number= } radix The radix in which the text is written (2-36), defaults to 10
836+ * @param {Object } [opts={}] Configuration options
837+ * @param {boolean } [opts.strictStringValidation=false] Enable strict validation generated Integer.
836838 * @returns {!Integer } The corresponding Integer value
837839 * @expose
838840 */
839- static fromString ( str : string , radix ?: number ) : Integer {
841+ static fromString ( str : string , radix ?: number , { strictStringValidation } : { strictStringValidation ?: boolean } = { } ) : Integer {
840842 if ( str . length === 0 ) {
841843 throw newError ( 'number format error: empty string' )
842844 }
@@ -867,7 +869,13 @@ class Integer {
867869 let result = Integer . ZERO
868870 for ( let i = 0 ; i < str . length ; i += 8 ) {
869871 const size = Math . min ( 8 , str . length - i )
870- const value = parseInt ( str . substring ( i , i + size ) , radix )
872+ const valueString = str . substring ( i , i + size )
873+ const value = parseInt ( valueString , radix )
874+
875+ if ( strictStringValidation === true && ! _isValidNumberFromString ( valueString , value , radix ) ) {
876+ throw newError ( `number format error: "${ valueString } " is NaN in radix ${ radix } : ${ str } ` )
877+ }
878+
871879 if ( size < 8 ) {
872880 const power = Integer . fromNumber ( Math . pow ( radix , size ) )
873881 result = result . multiply ( power ) . add ( Integer . fromNumber ( value ) )
@@ -883,18 +891,20 @@ class Integer {
883891 * Converts the specified value to a Integer.
884892 * @access private
885893 * @param {!Integer|number|string|bigint|!{low: number, high: number} } val Value
894+ * @param {Object } [opts={}] Configuration options
895+ * @param {boolean } [opts.strictStringValidation=false] Enable strict validation generated Integer.
886896 * @returns {!Integer }
887897 * @expose
888898 */
889- static fromValue ( val : Integerable ) : Integer {
899+ static fromValue ( val : Integerable , opts : { strictStringValidation ?: boolean } = { } ) : Integer {
890900 if ( val /* is compatible */ instanceof Integer ) {
891901 return val
892902 }
893903 if ( typeof val === 'number' ) {
894904 return Integer . fromNumber ( val )
895905 }
896906 if ( typeof val === 'string' ) {
897- return Integer . fromString ( val )
907+ return Integer . fromString ( val , undefined , opts )
898908 }
899909 if ( typeof val === 'bigint' ) {
900910 return Integer . fromString ( val . toString ( ) )
@@ -946,6 +956,20 @@ class Integer {
946956 }
947957}
948958
959+ /**
960+ *
961+ * @private
962+ * @param theString
963+ * @param theNumber
964+ * @param radix
965+ * @return {boolean } True if valid
966+ */
967+ function _isValidNumberFromString ( theString : string , theNumber : number , radix : number ) : boolean {
968+ return ! Number . isNaN ( theString ) &&
969+ ! Number . isNaN ( theNumber ) &&
970+ theNumber . toString ( radix ) . toLocaleLowerCase ( ) === theString . toLocaleLowerCase ( )
971+ }
972+
949973type Integerable =
950974 | number
951975 | string
@@ -1011,6 +1035,8 @@ const TWO_PWR_24 = Integer.fromInt(TWO_PWR_24_DBL)
10111035 * Cast value to Integer type.
10121036 * @access public
10131037 * @param {Mixed } value - The value to use.
1038+ * @param {Object } [opts={}] Configuration options
1039+ * @param {boolean } [opts.strictStringValidation=false] Enable strict validation generated Integer.
10141040 * @return {Integer } - An object of type Integer.
10151041 */
10161042const int = Integer . fromValue
0 commit comments