@@ -7,8 +7,8 @@ import { validateAllOf } from "../features/allOf";
77import { validateAnyOf } from "../features/anyOf" ;
88import { validateDependencies } from "../features/dependencies" ;
99import { validateOneOf } from "../features/oneOf" ;
10+ import { getPrecision } from "../utils/getPrecision" ;
1011import deepEqual from "fast-deep-equal" ;
11- const FPP = settings . floatingPointPrecision ;
1212
1313const hasOwnProperty = Object . prototype . hasOwnProperty ;
1414const hasProperty = ( value : Record < string , unknown > , property : string ) =>
@@ -316,20 +316,36 @@ const KeywordValidation: Record<string, JsonValidator> = {
316316 return undefined ;
317317 } ,
318318 multipleOf : ( draft , schema , value : number , pointer ) => {
319- if ( isNaN ( schema . multipleOf ) ) {
319+ if ( isNaN ( schema . multipleOf ) || typeof value !== "number" ) {
320320 return undefined ;
321321 }
322- // https://github.com/cfworker/cfworker/blob/master/packages/json-schema/src/validate.ts#L1061
323- // https://github.com/ExodusMovement/schemasafe/blob/master/src/compile.js#L441
324- if ( ( ( value * FPP ) % ( schema . multipleOf * FPP ) ) / FPP !== 0 ) {
322+
323+ const valuePrecision = getPrecision ( value ) ;
324+ const multiplePrecision = getPrecision ( schema . multipleOf ) ;
325+ if ( valuePrecision > multiplePrecision ) {
326+ // value with higher precision then multipleOf-precision can never be multiple
327+ return draft . errors . multipleOfError ( {
328+ multipleOf : schema . multipleOf ,
329+ value,
330+ pointer,
331+ schema
332+ } ) ;
333+ }
334+
335+ const precision = Math . pow ( 10 , multiplePrecision ) ;
336+ const val = Math . round ( value * precision ) ;
337+ const multiple = Math . round ( schema . multipleOf * precision ) ;
338+ if ( ( val % multiple ) / precision !== 0 ) {
325339 return draft . errors . multipleOfError ( {
326340 multipleOf : schema . multipleOf ,
327341 value,
328342 pointer,
329343 schema
330344 } ) ;
331345 }
332- // also check https://stackoverflow.com/questions/1815367/catch-and-compute-overflow-during-multiplication-of-two-large-integers
346+
347+ // maybe also check overflow
348+ // https://stackoverflow.com/questions/1815367/catch-and-compute-overflow-during-multiplication-of-two-large-integers
333349 return undefined ;
334350 } ,
335351 not : ( draft , schema , value , pointer ) => {
0 commit comments