diff --git a/docs/api.md b/docs/api.md index 8d29c318e5..e6a1d62c51 100644 --- a/docs/api.md +++ b/docs/api.md @@ -18925,7 +18925,6 @@ things were successful or not. * [~validateSpecificAttribute(endpointAttribute, attribute, db, zapSessionId)](#module_Validation API_ Validation APIs..validateSpecificAttribute) ⇒ * [~validateSpecificEndpoint(endpoint)](#module_Validation API_ Validation APIs..validateSpecificEndpoint) ⇒ * [~isValidNumberString(value)](#module_Validation API_ Validation APIs..isValidNumberString) ⇒ - * [~isValidSignedNumberString(value)](#module_Validation API_ Validation APIs..isValidSignedNumberString) ⇒ * [~isValidHexString(value)](#module_Validation API_ Validation APIs..isValidHexString) ⇒ * [~isValidDecimalString(value)](#module_Validation API_ Validation APIs..isValidDecimalString) ⇒ * [~isValidFloat(value)](#module_Validation API_ Validation APIs..isValidFloat) ⇒ @@ -18934,6 +18933,7 @@ things were successful or not. * [~extractBigIntegerValue(value)](#module_Validation API_ Validation APIs..extractBigIntegerValue) ⇒ * [~isBigInteger(bits)](#module_Validation API_ Validation APIs..isBigInteger) ⇒ * [~getBoundsInteger(attribute, typeSize, isSigned)](#module_Validation API_ Validation APIs..getBoundsInteger) ⇒ + * [~getTypeRange(typeSize, isSigned, isMin)](#module_Validation API_ Validation APIs..getTypeRange) ⇒ * [~unsignedToSignedInteger(value, typeSize)](#module_Validation API_ Validation APIs..unsignedToSignedInteger) ⇒ * [~getIntegerFromAttribute(attribute, typeSize, isSigned)](#module_Validation API_ Validation APIs..getIntegerFromAttribute) ⇒ * [~getIntegerAttributeSize(db, zapSessionId, attribType)](#module_Validation API_ Validation APIs..getIntegerAttributeSize) ⇒ \* @@ -18976,7 +18976,7 @@ Enforce zigbee specific common cluster initialization. ### Validation API: Validation APIs~validateAttribute(db, endpointTypeId, attributeRef, clusterRef, zapSessionId) ⇒ Main attribute validation function. -Returns a promise of an object which stores a list of validational issues. +Returns a promise of an object which stores a list of validation issues. Such issues as "Invalid type" or "Out of Range". **Kind**: inner method of [Validation API: Validation APIs](#module_Validation API_ Validation APIs) @@ -19057,18 +19057,6 @@ This applies to both actual numbers as well as octet strings. | --- | --- | | value | \* | - - -### Validation API: Validation APIs~isValidSignedNumberString(value) ⇒ -Check if value is a valid signed number in string form. - -**Kind**: inner method of [Validation API: Validation APIs](#module_Validation API_ Validation APIs) -**Returns**: boolean - -| Param | Type | -| --- | --- | -| value | \* | - ### Validation API: Validation APIs~isValidHexString(value) ⇒ @@ -19169,6 +19157,20 @@ Get the integer attribute's bounds. | typeSize | \* | | isSigned | \* | + + +### Validation API: Validation APIs~getTypeRange(typeSize, isSigned, isMin) ⇒ +Gets the range of an integer type. + +**Kind**: inner method of [Validation API: Validation APIs](#module_Validation API_ Validation APIs) +**Returns**: integer + +| Param | Type | +| --- | --- | +| typeSize | \* | +| isSigned | \* | +| isMin | \* | + ### Validation API: Validation APIs~unsignedToSignedInteger(value, typeSize) ⇒ @@ -19300,7 +19302,6 @@ things were successful or not. * [~validateSpecificAttribute(endpointAttribute, attribute, db, zapSessionId)](#module_Validation API_ Validation APIs..validateSpecificAttribute) ⇒ * [~validateSpecificEndpoint(endpoint)](#module_Validation API_ Validation APIs..validateSpecificEndpoint) ⇒ * [~isValidNumberString(value)](#module_Validation API_ Validation APIs..isValidNumberString) ⇒ - * [~isValidSignedNumberString(value)](#module_Validation API_ Validation APIs..isValidSignedNumberString) ⇒ * [~isValidHexString(value)](#module_Validation API_ Validation APIs..isValidHexString) ⇒ * [~isValidDecimalString(value)](#module_Validation API_ Validation APIs..isValidDecimalString) ⇒ * [~isValidFloat(value)](#module_Validation API_ Validation APIs..isValidFloat) ⇒ @@ -19309,6 +19310,7 @@ things were successful or not. * [~extractBigIntegerValue(value)](#module_Validation API_ Validation APIs..extractBigIntegerValue) ⇒ * [~isBigInteger(bits)](#module_Validation API_ Validation APIs..isBigInteger) ⇒ * [~getBoundsInteger(attribute, typeSize, isSigned)](#module_Validation API_ Validation APIs..getBoundsInteger) ⇒ + * [~getTypeRange(typeSize, isSigned, isMin)](#module_Validation API_ Validation APIs..getTypeRange) ⇒ * [~unsignedToSignedInteger(value, typeSize)](#module_Validation API_ Validation APIs..unsignedToSignedInteger) ⇒ * [~getIntegerFromAttribute(attribute, typeSize, isSigned)](#module_Validation API_ Validation APIs..getIntegerFromAttribute) ⇒ * [~getIntegerAttributeSize(db, zapSessionId, attribType)](#module_Validation API_ Validation APIs..getIntegerAttributeSize) ⇒ \* @@ -19351,7 +19353,7 @@ Enforce zigbee specific common cluster initialization. ### Validation API: Validation APIs~validateAttribute(db, endpointTypeId, attributeRef, clusterRef, zapSessionId) ⇒ Main attribute validation function. -Returns a promise of an object which stores a list of validational issues. +Returns a promise of an object which stores a list of validation issues. Such issues as "Invalid type" or "Out of Range". **Kind**: inner method of [Validation API: Validation APIs](#module_Validation API_ Validation APIs) @@ -19432,18 +19434,6 @@ This applies to both actual numbers as well as octet strings. | --- | --- | | value | \* | - - -### Validation API: Validation APIs~isValidSignedNumberString(value) ⇒ -Check if value is a valid signed number in string form. - -**Kind**: inner method of [Validation API: Validation APIs](#module_Validation API_ Validation APIs) -**Returns**: boolean - -| Param | Type | -| --- | --- | -| value | \* | - ### Validation API: Validation APIs~isValidHexString(value) ⇒ @@ -19544,6 +19534,20 @@ Get the integer attribute's bounds. | typeSize | \* | | isSigned | \* | + + +### Validation API: Validation APIs~getTypeRange(typeSize, isSigned, isMin) ⇒ +Gets the range of an integer type. + +**Kind**: inner method of [Validation API: Validation APIs](#module_Validation API_ Validation APIs) +**Returns**: integer + +| Param | Type | +| --- | --- | +| typeSize | \* | +| isSigned | \* | +| isMin | \* | + ### Validation API: Validation APIs~unsignedToSignedInteger(value, typeSize) ⇒ diff --git a/src-electron/validation/validation.js b/src-electron/validation/validation.js index 1530970d53..015501470f 100644 --- a/src-electron/validation/validation.js +++ b/src-electron/validation/validation.js @@ -30,7 +30,7 @@ const queryPackage = require('../db/query-package.js') /** * Main attribute validation function. - * Returns a promise of an object which stores a list of validational issues. + * Returns a promise of an object which stores a list of validation issues. * Such issues as "Invalid type" or "Out of Range". * @param {*} db db reference * @param {*} endpointTypeId endpoint reference @@ -128,20 +128,6 @@ async function validateSpecificAttribute( //Interpreting float values if (!checkAttributeBoundsFloat(attribute, endpointAttribute)) defaultAttributeIssues.push('Out of range') - } else if (await types.isSignedInteger(db, zapSessionId, attribute.type)) { - // we shouldn't check boundaries for an invalid number string - if (!isValidSignedNumberString(endpointAttribute.defaultValue)) { - defaultAttributeIssues.push('Invalid Integer') - } else if ( - !(await checkAttributeBoundsInteger( - attribute, - endpointAttribute, - db, - zapSessionId - )) - ) { - defaultAttributeIssues.push('Out of range') - } } else { // we shouldn't check boundaries for an invalid number string if (!isValidNumberString(endpointAttribute.defaultValue)) { @@ -210,16 +196,6 @@ function isValidNumberString(value) { return /^(0x)?[\dA-F]+$/i.test(value) || Number.isInteger(Number(value)) } -/** - * Check if value is a valid signed number in string form. - * - * @param {*} value - * @returns boolean - */ -function isValidSignedNumberString(value) { - return /^(0x)?[\dA-F]+$/i.test(value) || Number.isInteger(Number(value)) -} - /** * Check if value is a valid hex string. * @@ -315,11 +291,26 @@ async function getBoundsInteger(attribute, typeSize, isSigned) { return { min: attribute.min ? await getIntegerFromAttribute(attribute.min, typeSize, isSigned) - : null, + : getTypeRange(typeSize, isSigned, true), max: attribute.max ? await getIntegerFromAttribute(attribute.max, typeSize, isSigned) - : null + : getTypeRange(typeSize, isSigned, false) + } +} + +/** + * Gets the range of an integer type. + * + * @param {*} typeSize + * @param {*} isSigned + * @param {*} isMin + * @returns integer + */ +function getTypeRange(typeSize, isSigned, isMin) { + if (isMin) { + return isSigned ? -Math.pow(2, typeSize - 1) : 0 } + return isSigned ? Math.pow(2, typeSize - 1) - 1 : Math.pow(2, typeSize) - 1 } /** diff --git a/test/validation.test.js b/test/validation.test.js index 4d9174fc59..3082083da1 100644 --- a/test/validation.test.js +++ b/test/validation.test.js @@ -425,6 +425,83 @@ test( timeout.medium() ) +test('validate Attribute without min/max', async () => { + //Invalid default value + let fakeEndpointAttribute = { defaultValue: '300' } + + let fakeAttribute = { type: 'int8u' } + + let attributeValidation = await validation.validateSpecificAttribute( + fakeEndpointAttribute, + fakeAttribute, + db, + sid + ) + + expect(attributeValidation.defaultValue.length == 1).toBeTruthy() + expect( + attributeValidation.defaultValue[0].includes('Out of range') + ).toBeTruthy() + + //Valid default value + fakeEndpointAttribute.defaultValue = '30' + attributeValidation = await validation.validateSpecificAttribute( + fakeEndpointAttribute, + fakeAttribute, + db, + sid + ) + expect(attributeValidation.defaultValue.length == 0).toBeTruthy() + + //Invalid default value for enum16 + fakeEndpointAttribute.defaultValue = '66000' + fakeAttribute.type = 'enum16' + attributeValidation = await validation.validateSpecificAttribute( + fakeEndpointAttribute, + fakeAttribute, + db, + sid + ) + expect(attributeValidation.defaultValue.length == 1).toBeTruthy() + expect( + attributeValidation.defaultValue[0].includes('Out of range') + ).toBeTruthy() + + //Valid default value for enum16 + fakeEndpointAttribute.defaultValue = '65535' + attributeValidation = await validation.validateSpecificAttribute( + fakeEndpointAttribute, + fakeAttribute, + db, + sid + ) + expect(attributeValidation.defaultValue.length == 0).toBeTruthy() + + //Invalid default value for bitmap8 + fakeEndpointAttribute.defaultValue = '-2' + fakeAttribute.type = 'bitmap8' + attributeValidation = await validation.validateSpecificAttribute( + fakeEndpointAttribute, + fakeAttribute, + db, + sid + ) + expect(attributeValidation.defaultValue.length == 1).toBeTruthy() + expect( + attributeValidation.defaultValue[0].includes('Out of range') + ).toBeTruthy() + + //Valid default value for bitmap8 + fakeEndpointAttribute.defaultValue = '255' + attributeValidation = await validation.validateSpecificAttribute( + fakeEndpointAttribute, + fakeAttribute, + db, + sid + ) + expect(attributeValidation.defaultValue.length == 0).toBeTruthy() +}) + test( 'validate endpoint test', () => {