@openforis/arena-core 2.16.14 → 2.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/auth/authGroups.d.ts +0 -2
- package/dist/auth/authGroups.js +0 -7
- package/dist/auth/authGroups.js.map +1 -1
- package/dist/error/systemErrorKeys.d.ts +2 -0
- package/dist/error/systemErrorKeys.js +2 -0
- package/dist/error/systemErrorKeys.js.map +1 -1
- package/dist/esm/auth/authGroups.js +0 -7
- package/dist/esm/auth/authGroups.js.map +1 -1
- package/dist/esm/error/systemErrorKeys.js +2 -0
- package/dist/esm/error/systemErrorKeys.js.map +1 -1
- package/dist/esm/expression/javascript/node/call.js +15 -0
- package/dist/esm/expression/javascript/node/call.js.map +1 -1
- package/dist/esm/expression/javascript/node/literal.js +7 -1
- package/dist/esm/expression/javascript/node/literal.js.map +1 -1
- package/dist/esm/expression/javascript/regExpSafety.js +82 -0
- package/dist/esm/expression/javascript/regExpSafety.js.map +1 -0
- package/dist/esm/geo/points/distanceToPolygonBoundary.js +2 -0
- package/dist/esm/geo/points/distanceToPolygonBoundary.js.map +1 -1
- package/dist/expression/javascript/node/call.js +15 -0
- package/dist/expression/javascript/node/call.js.map +1 -1
- package/dist/expression/javascript/node/literal.js +7 -1
- package/dist/expression/javascript/node/literal.js.map +1 -1
- package/dist/expression/javascript/regExpSafety.d.ts +12 -0
- package/dist/expression/javascript/regExpSafety.js +86 -0
- package/dist/expression/javascript/regExpSafety.js.map +1 -0
- package/dist/geo/points/distanceToPolygonBoundary.js +2 -0
- package/dist/geo/points/distanceToPolygonBoundary.js.map +1 -1
- package/package.json +1 -1
|
@@ -7,7 +7,6 @@ declare const getSurveyUuid: (authGroup: AuthGroup) => string | undefined;
|
|
|
7
7
|
declare const getRecordSteps: (authGroup?: AuthGroup) => {
|
|
8
8
|
[key: string]: RecordStepPermission;
|
|
9
9
|
} | undefined;
|
|
10
|
-
declare const getRecordEditLevel: (step: string) => (authGroup?: AuthGroup) => RecordStepPermission;
|
|
11
10
|
declare const getDefaultAuthGroups: (surveyUuid: string) => AuthGroup[];
|
|
12
11
|
declare const getPermissions: (group: AuthGroup) => import("./permission").Permission[];
|
|
13
12
|
declare const sortGroups: (groups: AuthGroup[]) => AuthGroup[];
|
|
@@ -17,7 +16,6 @@ export declare const AuthGroups: {
|
|
|
17
16
|
isSurveyManager: typeof isSurveyManager;
|
|
18
17
|
getSurveyUuid: typeof getSurveyUuid;
|
|
19
18
|
getRecordSteps: typeof getRecordSteps;
|
|
20
|
-
getRecordEditLevel: typeof getRecordEditLevel;
|
|
21
19
|
getDefaultAuthGroups: typeof getDefaultAuthGroups;
|
|
22
20
|
getPermissions: typeof getPermissions;
|
|
23
21
|
sortGroups: typeof sortGroups;
|
package/dist/auth/authGroups.js
CHANGED
|
@@ -8,12 +8,6 @@ const isSurveyManager = (authGroup) => (authGroup === null || authGroup === void
|
|
|
8
8
|
const isSurveyGroup = (authGroup) => !isSystemAdmin(authGroup) && !isSurveyManager(authGroup);
|
|
9
9
|
const getSurveyUuid = (authGroup) => authGroup === null || authGroup === void 0 ? void 0 : authGroup.surveyUuid;
|
|
10
10
|
const getRecordSteps = (authGroup) => authGroup === null || authGroup === void 0 ? void 0 : authGroup.recordSteps;
|
|
11
|
-
const getRecordEditLevel = (step) => (authGroup) => {
|
|
12
|
-
const steps = getRecordSteps(authGroup);
|
|
13
|
-
if (!steps)
|
|
14
|
-
throw new Error('No steps');
|
|
15
|
-
return steps[step];
|
|
16
|
-
};
|
|
17
11
|
const getDefaultAuthGroups = (surveyUuid) => (0, authGroup_1.createDefaultAuthGroups)().map((group) => (Object.assign(Object.assign({}, group), { uuid: utils_1.UUIDs.v4(), surveyUuid })));
|
|
18
12
|
const getPermissions = (group) => { var _a; return (_a = authGroup_1.permissionsByGroupName[group.name]) !== null && _a !== void 0 ? _a : []; };
|
|
19
13
|
const sortGroups = (groups) => {
|
|
@@ -31,7 +25,6 @@ exports.AuthGroups = {
|
|
|
31
25
|
isSurveyManager,
|
|
32
26
|
getSurveyUuid,
|
|
33
27
|
getRecordSteps,
|
|
34
|
-
getRecordEditLevel,
|
|
35
28
|
getDefaultAuthGroups,
|
|
36
29
|
getPermissions,
|
|
37
30
|
sortGroups,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authGroups.js","sourceRoot":"","sources":["../../src/auth/authGroups.ts"],"names":[],"mappings":";;;AAAA,oCAAgC;AAChC,2CAMoB;AAGpB,MAAM,aAAa,GAAG,CAAC,SAAoB,EAAW,EAAE,CAAC,CAAA,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,IAAI,MAAK,yBAAa,CAAC,WAAW,CAAA;AAEtG,MAAM,eAAe,GAAG,CAAC,SAAoB,EAAW,EAAE,CAAC,CAAA,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,IAAI,MAAK,yBAAa,CAAC,aAAa,CAAA;AAE1G,MAAM,aAAa,GAAG,CAAC,SAAoB,EAAW,EAAE,CAAC,CAAC,aAAa,CAAC,SAAS,CAAC,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,CAAA;AAEjH,MAAM,aAAa,GAAG,CAAC,SAAoB,EAAsB,EAAE,CAAC,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,UAAU,CAAA;AAEzF,MAAM,cAAc,GAAG,CAAC,SAAqB,EAAuD,EAAE,CACpG,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,WAAW,CAAA;AAExB,MAAM,
|
|
1
|
+
{"version":3,"file":"authGroups.js","sourceRoot":"","sources":["../../src/auth/authGroups.ts"],"names":[],"mappings":";;;AAAA,oCAAgC;AAChC,2CAMoB;AAGpB,MAAM,aAAa,GAAG,CAAC,SAAoB,EAAW,EAAE,CAAC,CAAA,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,IAAI,MAAK,yBAAa,CAAC,WAAW,CAAA;AAEtG,MAAM,eAAe,GAAG,CAAC,SAAoB,EAAW,EAAE,CAAC,CAAA,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,IAAI,MAAK,yBAAa,CAAC,aAAa,CAAA;AAE1G,MAAM,aAAa,GAAG,CAAC,SAAoB,EAAW,EAAE,CAAC,CAAC,aAAa,CAAC,SAAS,CAAC,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,CAAA;AAEjH,MAAM,aAAa,GAAG,CAAC,SAAoB,EAAsB,EAAE,CAAC,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,UAAU,CAAA;AAEzF,MAAM,cAAc,GAAG,CAAC,SAAqB,EAAuD,EAAE,CACpG,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,WAAW,CAAA;AAExB,MAAM,oBAAoB,GAAG,CAAC,UAAkB,EAAe,EAAE,CAC/D,IAAA,mCAAuB,GAAE,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,iCAAM,KAAK,KAAE,IAAI,EAAE,aAAK,CAAC,EAAE,EAAE,EAAE,UAAU,IAAG,CAAC,CAAA;AAExF,MAAM,cAAc,GAAG,CAAC,KAAgB,EAAE,EAAE,wBAAC,kCAAsB,CAAC,KAAK,CAAC,IAAI,CAAC,mCAAI,EAAE,GAAA,CAAA;AAErF,MAAM,UAAU,GAAG,CAAC,MAAmB,EAAE,EAAE;IACzC,MAAM,YAAY,GAAG,CAAC,GAAG,MAAM,CAAC,CAAA;IAChC,YAAY,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE;QACnC,MAAM,UAAU,GAAG,4BAAgB,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;QACxD,MAAM,UAAU,GAAG,4BAAgB,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;QACxD,OAAO,UAAU,GAAG,UAAU,CAAA;IAChC,CAAC,CAAC,CAAA;IACF,OAAO,YAAY,CAAA;AACrB,CAAC,CAAA;AAEY,QAAA,UAAU,GAAG;IACxB,aAAa;IACb,aAAa;IACb,eAAe;IACf,aAAa;IACb,cAAc;IACd,oBAAoB;IACpB,cAAc;IACd,UAAU;CACX,CAAA","sourcesContent":["import { UUIDs } from '../utils'\nimport {\n AuthGroup,\n AuthGroupName,\n createDefaultAuthGroups,\n permissionsByGroupName,\n sortedGroupNames,\n} from './authGroup'\nimport { RecordStepPermission } from './permission'\n\nconst isSystemAdmin = (authGroup: AuthGroup): boolean => authGroup?.name === AuthGroupName.systemAdmin\n\nconst isSurveyManager = (authGroup: AuthGroup): boolean => authGroup?.name === AuthGroupName.surveyManager\n\nconst isSurveyGroup = (authGroup: AuthGroup): boolean => !isSystemAdmin(authGroup) && !isSurveyManager(authGroup)\n\nconst getSurveyUuid = (authGroup: AuthGroup): string | undefined => authGroup?.surveyUuid\n\nconst getRecordSteps = (authGroup?: AuthGroup): { [key: string]: RecordStepPermission } | undefined =>\n authGroup?.recordSteps\n\nconst getDefaultAuthGroups = (surveyUuid: string): AuthGroup[] =>\n createDefaultAuthGroups().map((group) => ({ ...group, uuid: UUIDs.v4(), surveyUuid }))\n\nconst getPermissions = (group: AuthGroup) => permissionsByGroupName[group.name] ?? []\n\nconst sortGroups = (groups: AuthGroup[]) => {\n const sortedGroups = [...groups]\n sortedGroups.sort((group1, group2) => {\n const sortOrder1 = sortedGroupNames.indexOf(group1.name)\n const sortOrder2 = sortedGroupNames.indexOf(group2.name)\n return sortOrder1 - sortOrder2\n })\n return sortedGroups\n}\n\nexport const AuthGroups = {\n isSystemAdmin,\n isSurveyGroup,\n isSurveyManager,\n getSurveyUuid,\n getRecordSteps,\n getDefaultAuthGroups,\n getPermissions,\n sortGroups,\n}\n"]}
|
|
@@ -19,7 +19,9 @@ export declare const SystemErrorKeys: {
|
|
|
19
19
|
readonly multipleNodesFoundForNodeDef: 'expression.multipleNodesFoundForNodeDef';
|
|
20
20
|
readonly nodeNotFoundForNodeDef: 'expression.nodeNotFoundForNodeDef';
|
|
21
21
|
readonly notSupported: 'expression.notSupported';
|
|
22
|
+
readonly regularExpressionInputTooLong: 'expression.regularExpressionInputTooLong';
|
|
22
23
|
readonly unaryOperatorNotSupported: 'expression.unaryOperatorNotSupported';
|
|
24
|
+
readonly unsafeRegularExpression: 'expression.unsafeRegularExpression';
|
|
23
25
|
readonly undefinedFunction: 'expression.undefinedFunction';
|
|
24
26
|
readonly unsupportedFunctionType: 'expression.unsupportedFunctionType';
|
|
25
27
|
};
|
|
@@ -22,7 +22,9 @@ exports.SystemErrorKeys = {
|
|
|
22
22
|
multipleNodesFoundForNodeDef: 'expression.multipleNodesFoundForNodeDef',
|
|
23
23
|
nodeNotFoundForNodeDef: 'expression.nodeNotFoundForNodeDef',
|
|
24
24
|
notSupported: 'expression.notSupported',
|
|
25
|
+
regularExpressionInputTooLong: 'expression.regularExpressionInputTooLong',
|
|
25
26
|
unaryOperatorNotSupported: 'expression.unaryOperatorNotSupported',
|
|
27
|
+
unsafeRegularExpression: 'expression.unsafeRegularExpression',
|
|
26
28
|
undefinedFunction: 'expression.undefinedFunction',
|
|
27
29
|
unsupportedFunctionType: 'expression.unsupportedFunctionType',
|
|
28
30
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"systemErrorKeys.js","sourceRoot":"","sources":["../../src/error/systemErrorKeys.ts"],"names":[],"mappings":";;;AAAA;;GAEG;AACU,QAAA,eAAe,GAAG;IAC7B,UAAU,EAAE;QACV,sBAAsB,EAAE,mCAAmC;QAC3D,2BAA2B,EAAE,wCAAwC;QACrE,0BAA0B,EAAE,uCAAuC;QACnE,2BAA2B,EAAE,wCAAwC;QACrE,kBAAkB,EAAE,+BAA+B;QACnD,iCAAiC,EAAE,8CAA8C;QACjF,iBAAiB,EAAE,8BAA8B;QACjD,wBAAwB,EAAE,qCAAqC;QAC/D,mBAAmB,EAAE,gCAAgC;QACrD,sCAAsC,EAAE,mDAAmD;QAC3F,wBAAwB,EAAE,qCAAqC;QAC/D,mBAAmB,EAAE,gCAAgC;QACrD,yBAAyB,EAAE,sCAAsC;QACjE,4BAA4B,EAAE,yCAAyC;QACvE,sBAAsB,EAAE,mCAAmC;QAC3D,YAAY,EAAE,yBAAyB;QACvC,yBAAyB,EAAE,sCAAsC;QACjE,iBAAiB,EAAE,8BAA8B;QACjD,uBAAuB,EAAE,oCAAoC;KAC9D;IACD,GAAG,EAAE;QACH,cAAc,EAAE,oBAAoB;QACpC,WAAW,EAAE,iBAAiB;QAC9B,eAAe,EAAE,qBAAqB;KACvC;IACD,GAAG,EAAE;QACH,qBAAqB,EAAE,0BAA0B;KAClD;IACD,OAAO,EAAE;QACP,2BAA2B,EAAE,qCAAqC;QAClE,cAAc,EAAE,wBAAwB;KACzC;IACD,MAAM,EAAE;QACN,qBAAqB,EAAE,+CAA+C;QACtE,sBAAsB,EAAE,+BAA+B;QACvD,kBAAkB,EAAE,uCAAuC;QAC3D,YAAY,EAAE,qBAAqB;QACnC,wBAAwB,EAAE,iCAAiC;QAC3D,oCAAoC,EAAE,6CAA6C;QACnF,gCAAgC,EAAE,yCAAyC;KAC5E;IACD,MAAM,EAAE;QACN,aAAa,EAAE,sBAAsB;QACrC,mBAAmB,EAAE,4BAA4B;QACjD,mBAAmB,EAAE,4BAA4B;QACjD,eAAe,EAAE,wBAAwB;KAC1C;CACO,CAAA","sourcesContent":["/**\n * Keys of the errors thrown by arena-core as SystemError (translatable, see SystemError.key).\n */\nexport const SystemErrorKeys = {\n expression: {\n areaOfInterestNotFound: 'expression.areaOfInterestNotFound',\n booleanOperatorNotSupported: 'expression.booleanOperatorNotSupported',\n functionHasTooFewArguments: 'expression.functionHasTooFewArguments',\n functionHasTooManyArguments: 'expression.functionHasTooManyArguments',\n identifierNotFound: 'expression.identifierNotFound',\n invalidAttributeValuePropertyName: 'expression.invalidAttributeValuePropertyName',\n invalidCalleeType: 'expression.invalidCalleeType',\n invalidCategoryExtraProp: 'expression.invalidCategoryExtraProp',\n invalidCategoryName: 'expression.invalidCategoryName',\n invalidTaxonVernacularNameLanguageCode: 'expression.invalidTaxonVernacularNameLanguageCode',\n invalidTaxonomyExtraProp: 'expression.invalidTaxonomyExtraProp',\n invalidTaxonomyName: 'expression.invalidTaxonomyName',\n missingFunctionParameters: 'expression.missingFunctionParameters',\n multipleNodesFoundForNodeDef: 'expression.multipleNodesFoundForNodeDef',\n nodeNotFoundForNodeDef: 'expression.nodeNotFoundForNodeDef',\n notSupported: 'expression.notSupported',\n unaryOperatorNotSupported: 'expression.unaryOperatorNotSupported',\n undefinedFunction: 'expression.undefinedFunction',\n unsupportedFunctionType: 'expression.unsupportedFunctionType',\n },\n geo: {\n pointNotFilled: 'geo.pointNotFilled',\n srsNotFound: 'geo.srsNotFound',\n transformFailed: 'geo.transformFailed',\n },\n job: {\n canceledOrErrorsFound: 'jobCanceledOrErrorsFound',\n },\n nodeDef: {\n hierarchyCircularDependency: 'nodeDef.hierarchyCircularDependency',\n parentNotFound: 'nodeDef.parentNotFound',\n },\n record: {\n dependencyOnRootFound: 'record.nodes.dependents.dependencyOnRootFound',\n enumeratorNodeNotFound: 'record.enumeratorNodeNotFound',\n multipleNodesFound: 'systemError.record.multipleNodesFound',\n nodeNotFound: 'record.nodeNotFound',\n nodesIndexNotInitialized: 'record.nodesIndexNotInitialized',\n updateSelfAndDependentsDefaultValues: 'record.updateSelfAndDependentsDefaultValues',\n updateSelfAndDependentsFileNames: 'record.updateSelfAndDependentsFileNames',\n },\n survey: {\n emptyNodeDefs: 'survey.emptyNodeDefs',\n nodeDefNameNotFound: 'survey.nodeDefNameNotFound',\n nodeDefUuidNotFound: 'survey.nodeDefUuidNotFound',\n rootDefNotFound: 'survey.rootDefNotFound',\n },\n} as const\n"]}
|
|
1
|
+
{"version":3,"file":"systemErrorKeys.js","sourceRoot":"","sources":["../../src/error/systemErrorKeys.ts"],"names":[],"mappings":";;;AAAA;;GAEG;AACU,QAAA,eAAe,GAAG;IAC7B,UAAU,EAAE;QACV,sBAAsB,EAAE,mCAAmC;QAC3D,2BAA2B,EAAE,wCAAwC;QACrE,0BAA0B,EAAE,uCAAuC;QACnE,2BAA2B,EAAE,wCAAwC;QACrE,kBAAkB,EAAE,+BAA+B;QACnD,iCAAiC,EAAE,8CAA8C;QACjF,iBAAiB,EAAE,8BAA8B;QACjD,wBAAwB,EAAE,qCAAqC;QAC/D,mBAAmB,EAAE,gCAAgC;QACrD,sCAAsC,EAAE,mDAAmD;QAC3F,wBAAwB,EAAE,qCAAqC;QAC/D,mBAAmB,EAAE,gCAAgC;QACrD,yBAAyB,EAAE,sCAAsC;QACjE,4BAA4B,EAAE,yCAAyC;QACvE,sBAAsB,EAAE,mCAAmC;QAC3D,YAAY,EAAE,yBAAyB;QACvC,6BAA6B,EAAE,0CAA0C;QACzE,yBAAyB,EAAE,sCAAsC;QACjE,uBAAuB,EAAE,oCAAoC;QAC7D,iBAAiB,EAAE,8BAA8B;QACjD,uBAAuB,EAAE,oCAAoC;KAC9D;IACD,GAAG,EAAE;QACH,cAAc,EAAE,oBAAoB;QACpC,WAAW,EAAE,iBAAiB;QAC9B,eAAe,EAAE,qBAAqB;KACvC;IACD,GAAG,EAAE;QACH,qBAAqB,EAAE,0BAA0B;KAClD;IACD,OAAO,EAAE;QACP,2BAA2B,EAAE,qCAAqC;QAClE,cAAc,EAAE,wBAAwB;KACzC;IACD,MAAM,EAAE;QACN,qBAAqB,EAAE,+CAA+C;QACtE,sBAAsB,EAAE,+BAA+B;QACvD,kBAAkB,EAAE,uCAAuC;QAC3D,YAAY,EAAE,qBAAqB;QACnC,wBAAwB,EAAE,iCAAiC;QAC3D,oCAAoC,EAAE,6CAA6C;QACnF,gCAAgC,EAAE,yCAAyC;KAC5E;IACD,MAAM,EAAE;QACN,aAAa,EAAE,sBAAsB;QACrC,mBAAmB,EAAE,4BAA4B;QACjD,mBAAmB,EAAE,4BAA4B;QACjD,eAAe,EAAE,wBAAwB;KAC1C;CACO,CAAA","sourcesContent":["/**\n * Keys of the errors thrown by arena-core as SystemError (translatable, see SystemError.key).\n */\nexport const SystemErrorKeys = {\n expression: {\n areaOfInterestNotFound: 'expression.areaOfInterestNotFound',\n booleanOperatorNotSupported: 'expression.booleanOperatorNotSupported',\n functionHasTooFewArguments: 'expression.functionHasTooFewArguments',\n functionHasTooManyArguments: 'expression.functionHasTooManyArguments',\n identifierNotFound: 'expression.identifierNotFound',\n invalidAttributeValuePropertyName: 'expression.invalidAttributeValuePropertyName',\n invalidCalleeType: 'expression.invalidCalleeType',\n invalidCategoryExtraProp: 'expression.invalidCategoryExtraProp',\n invalidCategoryName: 'expression.invalidCategoryName',\n invalidTaxonVernacularNameLanguageCode: 'expression.invalidTaxonVernacularNameLanguageCode',\n invalidTaxonomyExtraProp: 'expression.invalidTaxonomyExtraProp',\n invalidTaxonomyName: 'expression.invalidTaxonomyName',\n missingFunctionParameters: 'expression.missingFunctionParameters',\n multipleNodesFoundForNodeDef: 'expression.multipleNodesFoundForNodeDef',\n nodeNotFoundForNodeDef: 'expression.nodeNotFoundForNodeDef',\n notSupported: 'expression.notSupported',\n regularExpressionInputTooLong: 'expression.regularExpressionInputTooLong',\n unaryOperatorNotSupported: 'expression.unaryOperatorNotSupported',\n unsafeRegularExpression: 'expression.unsafeRegularExpression',\n undefinedFunction: 'expression.undefinedFunction',\n unsupportedFunctionType: 'expression.unsupportedFunctionType',\n },\n geo: {\n pointNotFilled: 'geo.pointNotFilled',\n srsNotFound: 'geo.srsNotFound',\n transformFailed: 'geo.transformFailed',\n },\n job: {\n canceledOrErrorsFound: 'jobCanceledOrErrorsFound',\n },\n nodeDef: {\n hierarchyCircularDependency: 'nodeDef.hierarchyCircularDependency',\n parentNotFound: 'nodeDef.parentNotFound',\n },\n record: {\n dependencyOnRootFound: 'record.nodes.dependents.dependencyOnRootFound',\n enumeratorNodeNotFound: 'record.enumeratorNodeNotFound',\n multipleNodesFound: 'systemError.record.multipleNodesFound',\n nodeNotFound: 'record.nodeNotFound',\n nodesIndexNotInitialized: 'record.nodesIndexNotInitialized',\n updateSelfAndDependentsDefaultValues: 'record.updateSelfAndDependentsDefaultValues',\n updateSelfAndDependentsFileNames: 'record.updateSelfAndDependentsFileNames',\n },\n survey: {\n emptyNodeDefs: 'survey.emptyNodeDefs',\n nodeDefNameNotFound: 'survey.nodeDefNameNotFound',\n nodeDefUuidNotFound: 'survey.nodeDefUuidNotFound',\n rootDefNotFound: 'survey.rootDefNotFound',\n },\n} as const\n"]}
|
|
@@ -5,12 +5,6 @@ const isSurveyManager = (authGroup) => (authGroup === null || authGroup === void
|
|
|
5
5
|
const isSurveyGroup = (authGroup) => !isSystemAdmin(authGroup) && !isSurveyManager(authGroup);
|
|
6
6
|
const getSurveyUuid = (authGroup) => authGroup === null || authGroup === void 0 ? void 0 : authGroup.surveyUuid;
|
|
7
7
|
const getRecordSteps = (authGroup) => authGroup === null || authGroup === void 0 ? void 0 : authGroup.recordSteps;
|
|
8
|
-
const getRecordEditLevel = (step) => (authGroup) => {
|
|
9
|
-
const steps = getRecordSteps(authGroup);
|
|
10
|
-
if (!steps)
|
|
11
|
-
throw new Error('No steps');
|
|
12
|
-
return steps[step];
|
|
13
|
-
};
|
|
14
8
|
const getDefaultAuthGroups = (surveyUuid) => createDefaultAuthGroups().map((group) => (Object.assign(Object.assign({}, group), { uuid: UUIDs.v4(), surveyUuid })));
|
|
15
9
|
const getPermissions = (group) => { var _a; return (_a = permissionsByGroupName[group.name]) !== null && _a !== void 0 ? _a : []; };
|
|
16
10
|
const sortGroups = (groups) => {
|
|
@@ -28,7 +22,6 @@ export const AuthGroups = {
|
|
|
28
22
|
isSurveyManager,
|
|
29
23
|
getSurveyUuid,
|
|
30
24
|
getRecordSteps,
|
|
31
|
-
getRecordEditLevel,
|
|
32
25
|
getDefaultAuthGroups,
|
|
33
26
|
getPermissions,
|
|
34
27
|
sortGroups,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authGroups.js","sourceRoot":"","sources":["../../../src/auth/authGroups.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAA;AAChC,OAAO,EAEL,aAAa,EACb,uBAAuB,EACvB,sBAAsB,EACtB,gBAAgB,GACjB,MAAM,aAAa,CAAA;AAGpB,MAAM,aAAa,GAAG,CAAC,SAAoB,EAAW,EAAE,CAAC,CAAA,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,IAAI,MAAK,aAAa,CAAC,WAAW,CAAA;AAEtG,MAAM,eAAe,GAAG,CAAC,SAAoB,EAAW,EAAE,CAAC,CAAA,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,IAAI,MAAK,aAAa,CAAC,aAAa,CAAA;AAE1G,MAAM,aAAa,GAAG,CAAC,SAAoB,EAAW,EAAE,CAAC,CAAC,aAAa,CAAC,SAAS,CAAC,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,CAAA;AAEjH,MAAM,aAAa,GAAG,CAAC,SAAoB,EAAsB,EAAE,CAAC,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,UAAU,CAAA;AAEzF,MAAM,cAAc,GAAG,CAAC,SAAqB,EAAuD,EAAE,CACpG,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,WAAW,CAAA;AAExB,MAAM,
|
|
1
|
+
{"version":3,"file":"authGroups.js","sourceRoot":"","sources":["../../../src/auth/authGroups.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAA;AAChC,OAAO,EAEL,aAAa,EACb,uBAAuB,EACvB,sBAAsB,EACtB,gBAAgB,GACjB,MAAM,aAAa,CAAA;AAGpB,MAAM,aAAa,GAAG,CAAC,SAAoB,EAAW,EAAE,CAAC,CAAA,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,IAAI,MAAK,aAAa,CAAC,WAAW,CAAA;AAEtG,MAAM,eAAe,GAAG,CAAC,SAAoB,EAAW,EAAE,CAAC,CAAA,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,IAAI,MAAK,aAAa,CAAC,aAAa,CAAA;AAE1G,MAAM,aAAa,GAAG,CAAC,SAAoB,EAAW,EAAE,CAAC,CAAC,aAAa,CAAC,SAAS,CAAC,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,CAAA;AAEjH,MAAM,aAAa,GAAG,CAAC,SAAoB,EAAsB,EAAE,CAAC,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,UAAU,CAAA;AAEzF,MAAM,cAAc,GAAG,CAAC,SAAqB,EAAuD,EAAE,CACpG,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,WAAW,CAAA;AAExB,MAAM,oBAAoB,GAAG,CAAC,UAAkB,EAAe,EAAE,CAC/D,uBAAuB,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,iCAAM,KAAK,KAAE,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE,EAAE,UAAU,IAAG,CAAC,CAAA;AAExF,MAAM,cAAc,GAAG,CAAC,KAAgB,EAAE,EAAE,wBAAC,sBAAsB,CAAC,KAAK,CAAC,IAAI,CAAC,mCAAI,EAAE,GAAA,CAAA;AAErF,MAAM,UAAU,GAAG,CAAC,MAAmB,EAAE,EAAE;IACzC,MAAM,YAAY,GAAG,CAAC,GAAG,MAAM,CAAC,CAAA;IAChC,YAAY,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE;QACnC,MAAM,UAAU,GAAG,gBAAgB,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;QACxD,MAAM,UAAU,GAAG,gBAAgB,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;QACxD,OAAO,UAAU,GAAG,UAAU,CAAA;IAChC,CAAC,CAAC,CAAA;IACF,OAAO,YAAY,CAAA;AACrB,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,aAAa;IACb,aAAa;IACb,eAAe;IACf,aAAa;IACb,cAAc;IACd,oBAAoB;IACpB,cAAc;IACd,UAAU;CACX,CAAA","sourcesContent":["import { UUIDs } from '../utils'\nimport {\n AuthGroup,\n AuthGroupName,\n createDefaultAuthGroups,\n permissionsByGroupName,\n sortedGroupNames,\n} from './authGroup'\nimport { RecordStepPermission } from './permission'\n\nconst isSystemAdmin = (authGroup: AuthGroup): boolean => authGroup?.name === AuthGroupName.systemAdmin\n\nconst isSurveyManager = (authGroup: AuthGroup): boolean => authGroup?.name === AuthGroupName.surveyManager\n\nconst isSurveyGroup = (authGroup: AuthGroup): boolean => !isSystemAdmin(authGroup) && !isSurveyManager(authGroup)\n\nconst getSurveyUuid = (authGroup: AuthGroup): string | undefined => authGroup?.surveyUuid\n\nconst getRecordSteps = (authGroup?: AuthGroup): { [key: string]: RecordStepPermission } | undefined =>\n authGroup?.recordSteps\n\nconst getDefaultAuthGroups = (surveyUuid: string): AuthGroup[] =>\n createDefaultAuthGroups().map((group) => ({ ...group, uuid: UUIDs.v4(), surveyUuid }))\n\nconst getPermissions = (group: AuthGroup) => permissionsByGroupName[group.name] ?? []\n\nconst sortGroups = (groups: AuthGroup[]) => {\n const sortedGroups = [...groups]\n sortedGroups.sort((group1, group2) => {\n const sortOrder1 = sortedGroupNames.indexOf(group1.name)\n const sortOrder2 = sortedGroupNames.indexOf(group2.name)\n return sortOrder1 - sortOrder2\n })\n return sortedGroups\n}\n\nexport const AuthGroups = {\n isSystemAdmin,\n isSurveyGroup,\n isSurveyManager,\n getSurveyUuid,\n getRecordSteps,\n getDefaultAuthGroups,\n getPermissions,\n sortGroups,\n}\n"]}
|
|
@@ -19,7 +19,9 @@ export const SystemErrorKeys = {
|
|
|
19
19
|
multipleNodesFoundForNodeDef: 'expression.multipleNodesFoundForNodeDef',
|
|
20
20
|
nodeNotFoundForNodeDef: 'expression.nodeNotFoundForNodeDef',
|
|
21
21
|
notSupported: 'expression.notSupported',
|
|
22
|
+
regularExpressionInputTooLong: 'expression.regularExpressionInputTooLong',
|
|
22
23
|
unaryOperatorNotSupported: 'expression.unaryOperatorNotSupported',
|
|
24
|
+
unsafeRegularExpression: 'expression.unsafeRegularExpression',
|
|
23
25
|
undefinedFunction: 'expression.undefinedFunction',
|
|
24
26
|
unsupportedFunctionType: 'expression.unsupportedFunctionType',
|
|
25
27
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"systemErrorKeys.js","sourceRoot":"","sources":["../../../src/error/systemErrorKeys.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,UAAU,EAAE;QACV,sBAAsB,EAAE,mCAAmC;QAC3D,2BAA2B,EAAE,wCAAwC;QACrE,0BAA0B,EAAE,uCAAuC;QACnE,2BAA2B,EAAE,wCAAwC;QACrE,kBAAkB,EAAE,+BAA+B;QACnD,iCAAiC,EAAE,8CAA8C;QACjF,iBAAiB,EAAE,8BAA8B;QACjD,wBAAwB,EAAE,qCAAqC;QAC/D,mBAAmB,EAAE,gCAAgC;QACrD,sCAAsC,EAAE,mDAAmD;QAC3F,wBAAwB,EAAE,qCAAqC;QAC/D,mBAAmB,EAAE,gCAAgC;QACrD,yBAAyB,EAAE,sCAAsC;QACjE,4BAA4B,EAAE,yCAAyC;QACvE,sBAAsB,EAAE,mCAAmC;QAC3D,YAAY,EAAE,yBAAyB;QACvC,yBAAyB,EAAE,sCAAsC;QACjE,iBAAiB,EAAE,8BAA8B;QACjD,uBAAuB,EAAE,oCAAoC;KAC9D;IACD,GAAG,EAAE;QACH,cAAc,EAAE,oBAAoB;QACpC,WAAW,EAAE,iBAAiB;QAC9B,eAAe,EAAE,qBAAqB;KACvC;IACD,GAAG,EAAE;QACH,qBAAqB,EAAE,0BAA0B;KAClD;IACD,OAAO,EAAE;QACP,2BAA2B,EAAE,qCAAqC;QAClE,cAAc,EAAE,wBAAwB;KACzC;IACD,MAAM,EAAE;QACN,qBAAqB,EAAE,+CAA+C;QACtE,sBAAsB,EAAE,+BAA+B;QACvD,kBAAkB,EAAE,uCAAuC;QAC3D,YAAY,EAAE,qBAAqB;QACnC,wBAAwB,EAAE,iCAAiC;QAC3D,oCAAoC,EAAE,6CAA6C;QACnF,gCAAgC,EAAE,yCAAyC;KAC5E;IACD,MAAM,EAAE;QACN,aAAa,EAAE,sBAAsB;QACrC,mBAAmB,EAAE,4BAA4B;QACjD,mBAAmB,EAAE,4BAA4B;QACjD,eAAe,EAAE,wBAAwB;KAC1C;CACO,CAAA","sourcesContent":["/**\n * Keys of the errors thrown by arena-core as SystemError (translatable, see SystemError.key).\n */\nexport const SystemErrorKeys = {\n expression: {\n areaOfInterestNotFound: 'expression.areaOfInterestNotFound',\n booleanOperatorNotSupported: 'expression.booleanOperatorNotSupported',\n functionHasTooFewArguments: 'expression.functionHasTooFewArguments',\n functionHasTooManyArguments: 'expression.functionHasTooManyArguments',\n identifierNotFound: 'expression.identifierNotFound',\n invalidAttributeValuePropertyName: 'expression.invalidAttributeValuePropertyName',\n invalidCalleeType: 'expression.invalidCalleeType',\n invalidCategoryExtraProp: 'expression.invalidCategoryExtraProp',\n invalidCategoryName: 'expression.invalidCategoryName',\n invalidTaxonVernacularNameLanguageCode: 'expression.invalidTaxonVernacularNameLanguageCode',\n invalidTaxonomyExtraProp: 'expression.invalidTaxonomyExtraProp',\n invalidTaxonomyName: 'expression.invalidTaxonomyName',\n missingFunctionParameters: 'expression.missingFunctionParameters',\n multipleNodesFoundForNodeDef: 'expression.multipleNodesFoundForNodeDef',\n nodeNotFoundForNodeDef: 'expression.nodeNotFoundForNodeDef',\n notSupported: 'expression.notSupported',\n unaryOperatorNotSupported: 'expression.unaryOperatorNotSupported',\n undefinedFunction: 'expression.undefinedFunction',\n unsupportedFunctionType: 'expression.unsupportedFunctionType',\n },\n geo: {\n pointNotFilled: 'geo.pointNotFilled',\n srsNotFound: 'geo.srsNotFound',\n transformFailed: 'geo.transformFailed',\n },\n job: {\n canceledOrErrorsFound: 'jobCanceledOrErrorsFound',\n },\n nodeDef: {\n hierarchyCircularDependency: 'nodeDef.hierarchyCircularDependency',\n parentNotFound: 'nodeDef.parentNotFound',\n },\n record: {\n dependencyOnRootFound: 'record.nodes.dependents.dependencyOnRootFound',\n enumeratorNodeNotFound: 'record.enumeratorNodeNotFound',\n multipleNodesFound: 'systemError.record.multipleNodesFound',\n nodeNotFound: 'record.nodeNotFound',\n nodesIndexNotInitialized: 'record.nodesIndexNotInitialized',\n updateSelfAndDependentsDefaultValues: 'record.updateSelfAndDependentsDefaultValues',\n updateSelfAndDependentsFileNames: 'record.updateSelfAndDependentsFileNames',\n },\n survey: {\n emptyNodeDefs: 'survey.emptyNodeDefs',\n nodeDefNameNotFound: 'survey.nodeDefNameNotFound',\n nodeDefUuidNotFound: 'survey.nodeDefUuidNotFound',\n rootDefNotFound: 'survey.rootDefNotFound',\n },\n} as const\n"]}
|
|
1
|
+
{"version":3,"file":"systemErrorKeys.js","sourceRoot":"","sources":["../../../src/error/systemErrorKeys.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,UAAU,EAAE;QACV,sBAAsB,EAAE,mCAAmC;QAC3D,2BAA2B,EAAE,wCAAwC;QACrE,0BAA0B,EAAE,uCAAuC;QACnE,2BAA2B,EAAE,wCAAwC;QACrE,kBAAkB,EAAE,+BAA+B;QACnD,iCAAiC,EAAE,8CAA8C;QACjF,iBAAiB,EAAE,8BAA8B;QACjD,wBAAwB,EAAE,qCAAqC;QAC/D,mBAAmB,EAAE,gCAAgC;QACrD,sCAAsC,EAAE,mDAAmD;QAC3F,wBAAwB,EAAE,qCAAqC;QAC/D,mBAAmB,EAAE,gCAAgC;QACrD,yBAAyB,EAAE,sCAAsC;QACjE,4BAA4B,EAAE,yCAAyC;QACvE,sBAAsB,EAAE,mCAAmC;QAC3D,YAAY,EAAE,yBAAyB;QACvC,6BAA6B,EAAE,0CAA0C;QACzE,yBAAyB,EAAE,sCAAsC;QACjE,uBAAuB,EAAE,oCAAoC;QAC7D,iBAAiB,EAAE,8BAA8B;QACjD,uBAAuB,EAAE,oCAAoC;KAC9D;IACD,GAAG,EAAE;QACH,cAAc,EAAE,oBAAoB;QACpC,WAAW,EAAE,iBAAiB;QAC9B,eAAe,EAAE,qBAAqB;KACvC;IACD,GAAG,EAAE;QACH,qBAAqB,EAAE,0BAA0B;KAClD;IACD,OAAO,EAAE;QACP,2BAA2B,EAAE,qCAAqC;QAClE,cAAc,EAAE,wBAAwB;KACzC;IACD,MAAM,EAAE;QACN,qBAAqB,EAAE,+CAA+C;QACtE,sBAAsB,EAAE,+BAA+B;QACvD,kBAAkB,EAAE,uCAAuC;QAC3D,YAAY,EAAE,qBAAqB;QACnC,wBAAwB,EAAE,iCAAiC;QAC3D,oCAAoC,EAAE,6CAA6C;QACnF,gCAAgC,EAAE,yCAAyC;KAC5E;IACD,MAAM,EAAE;QACN,aAAa,EAAE,sBAAsB;QACrC,mBAAmB,EAAE,4BAA4B;QACjD,mBAAmB,EAAE,4BAA4B;QACjD,eAAe,EAAE,wBAAwB;KAC1C;CACO,CAAA","sourcesContent":["/**\n * Keys of the errors thrown by arena-core as SystemError (translatable, see SystemError.key).\n */\nexport const SystemErrorKeys = {\n expression: {\n areaOfInterestNotFound: 'expression.areaOfInterestNotFound',\n booleanOperatorNotSupported: 'expression.booleanOperatorNotSupported',\n functionHasTooFewArguments: 'expression.functionHasTooFewArguments',\n functionHasTooManyArguments: 'expression.functionHasTooManyArguments',\n identifierNotFound: 'expression.identifierNotFound',\n invalidAttributeValuePropertyName: 'expression.invalidAttributeValuePropertyName',\n invalidCalleeType: 'expression.invalidCalleeType',\n invalidCategoryExtraProp: 'expression.invalidCategoryExtraProp',\n invalidCategoryName: 'expression.invalidCategoryName',\n invalidTaxonVernacularNameLanguageCode: 'expression.invalidTaxonVernacularNameLanguageCode',\n invalidTaxonomyExtraProp: 'expression.invalidTaxonomyExtraProp',\n invalidTaxonomyName: 'expression.invalidTaxonomyName',\n missingFunctionParameters: 'expression.missingFunctionParameters',\n multipleNodesFoundForNodeDef: 'expression.multipleNodesFoundForNodeDef',\n nodeNotFoundForNodeDef: 'expression.nodeNotFoundForNodeDef',\n notSupported: 'expression.notSupported',\n regularExpressionInputTooLong: 'expression.regularExpressionInputTooLong',\n unaryOperatorNotSupported: 'expression.unaryOperatorNotSupported',\n unsafeRegularExpression: 'expression.unsafeRegularExpression',\n undefinedFunction: 'expression.undefinedFunction',\n unsupportedFunctionType: 'expression.unsupportedFunctionType',\n },\n geo: {\n pointNotFilled: 'geo.pointNotFilled',\n srsNotFound: 'geo.srsNotFound',\n transformFailed: 'geo.transformFailed',\n },\n job: {\n canceledOrErrorsFound: 'jobCanceledOrErrorsFound',\n },\n nodeDef: {\n hierarchyCircularDependency: 'nodeDef.hierarchyCircularDependency',\n parentNotFound: 'nodeDef.parentNotFound',\n },\n record: {\n dependencyOnRootFound: 'record.nodes.dependents.dependencyOnRootFound',\n enumeratorNodeNotFound: 'record.enumeratorNodeNotFound',\n multipleNodesFound: 'systemError.record.multipleNodesFound',\n nodeNotFound: 'record.nodeNotFound',\n nodesIndexNotInitialized: 'record.nodesIndexNotInitialized',\n updateSelfAndDependentsDefaultValues: 'record.updateSelfAndDependentsDefaultValues',\n updateSelfAndDependentsFileNames: 'record.updateSelfAndDependentsFileNames',\n },\n survey: {\n emptyNodeDefs: 'survey.emptyNodeDefs',\n nodeDefNameNotFound: 'survey.nodeDefNameNotFound',\n nodeDefUuidNotFound: 'survey.nodeDefUuidNotFound',\n rootDefNotFound: 'survey.rootDefNotFound',\n },\n} as const\n"]}
|
|
@@ -10,6 +10,20 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
10
10
|
import { SystemError, SystemErrorKeys } from '../../../error';
|
|
11
11
|
import { ExpressionNodeEvaluator, ExpressionNodeType, } from '../../node';
|
|
12
12
|
import { getGlobalObjectProperty } from '../global';
|
|
13
|
+
import { REG_EXP_INPUT_MAX_LENGTH } from '../regExpSafety';
|
|
14
|
+
// e.g. /.../.test(text) or text.match(/.../): the time taken by a regular expression grows with the input length
|
|
15
|
+
const checkRegExpInputLength = (fnObject, args) => {
|
|
16
|
+
const values = [fnObject, ...args];
|
|
17
|
+
if (!values.some((value) => value instanceof RegExp))
|
|
18
|
+
return;
|
|
19
|
+
const inputTooLong = values.find((value) => typeof value === 'string' && value.length > REG_EXP_INPUT_MAX_LENGTH);
|
|
20
|
+
if (inputTooLong !== undefined) {
|
|
21
|
+
throw new SystemError(SystemErrorKeys.expression.regularExpressionInputTooLong, {
|
|
22
|
+
maxLength: REG_EXP_INPUT_MAX_LENGTH,
|
|
23
|
+
length: inputTooLong.length,
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
};
|
|
13
27
|
export class CallEvaluator extends ExpressionNodeEvaluator {
|
|
14
28
|
evaluate(expressionNode) {
|
|
15
29
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -35,6 +49,7 @@ export class CallEvaluator extends ExpressionNodeEvaluator {
|
|
|
35
49
|
const fnObject = yield this.evaluator.evaluateNode(calleeObj, this.context);
|
|
36
50
|
const argsEvaluated = yield Promise.all(exprArgs.map((arg) => this.evaluator.evaluateNode(arg, this.context)));
|
|
37
51
|
const args = argsEvaluated.flat();
|
|
52
|
+
checkRegExpInputLength(fnObject, args);
|
|
38
53
|
return fn.call(fnObject, ...args);
|
|
39
54
|
}
|
|
40
55
|
return null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"call.js","sourceRoot":"","sources":["../../../../../src/expression/javascript/node/call.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAG7D,OAAO,EAEL,uBAAuB,EACvB,kBAAkB,GAGnB,MAAM,YAAY,CAAA;AACnB,OAAO,EAAE,uBAAuB,EAAE,MAAM,WAAW,CAAA;
|
|
1
|
+
{"version":3,"file":"call.js","sourceRoot":"","sources":["../../../../../src/expression/javascript/node/call.ts"],"names":[],"mappings":"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","sourcesContent":["import { SystemError, SystemErrorKeys } from '../../../error'\nimport { ExpressionContext } from '../../context'\nimport { ExpressionFunction } from '../../function'\nimport {\n CallExpression,\n ExpressionNodeEvaluator,\n ExpressionNodeType,\n IdentifierExpression,\n MemberExpression,\n} from '../../node'\nimport { getGlobalObjectProperty } from '../global'\nimport { REG_EXP_INPUT_MAX_LENGTH } from '../regExpSafety'\n\n// e.g. /.../.test(text) or text.match(/.../): the time taken by a regular expression grows with the input length\nconst checkRegExpInputLength = (fnObject: any, args: any[]): void => {\n const values = [fnObject, ...args]\n if (!values.some((value) => value instanceof RegExp)) return\n const inputTooLong = values.find((value) => typeof value === 'string' && value.length > REG_EXP_INPUT_MAX_LENGTH)\n if (inputTooLong !== undefined) {\n throw new SystemError(SystemErrorKeys.expression.regularExpressionInputTooLong, {\n maxLength: REG_EXP_INPUT_MAX_LENGTH,\n length: inputTooLong.length,\n })\n }\n}\n\nexport class CallEvaluator<C extends ExpressionContext> extends ExpressionNodeEvaluator<C, CallExpression> {\n async evaluate(expressionNode: CallExpression): Promise<any> {\n const { callee } = expressionNode\n\n if (callee.type === ExpressionNodeType.Member) {\n return this.evaluateMember(expressionNode, callee)\n } else if (callee.type === ExpressionNodeType.Identifier) {\n return this.evaluateIdentifier(expressionNode, callee)\n }\n\n // No complex expressions may be put in place of a function body.\n // Only a plain identifier is allowed.\n throw new SystemError(SystemErrorKeys.expression.invalidCalleeType, { type: callee.type })\n }\n\n private async evaluateMember(expressionNode: CallExpression, callee: MemberExpression): Promise<any> {\n const { arguments: exprArgs } = expressionNode\n\n // global function (e.g. Math.round(...))\n const fn = await this.evaluator.evaluateNode(callee, this.context)\n if (fn) {\n const { object: calleeObj } = callee\n const fnObject = await this.evaluator.evaluateNode(calleeObj, this.context)\n const argsEvaluated = await Promise.all(exprArgs.map((arg) => this.evaluator.evaluateNode(arg, this.context)))\n const args = argsEvaluated.flat()\n checkRegExpInputLength(fnObject, args)\n return fn.call(fnObject, ...args)\n }\n return null\n }\n\n private async evaluateIdentifier(expressionNode: CallExpression, callee: IdentifierExpression): Promise<any> {\n // Arguments is a reserved word in strict mode\n const { arguments: exprArgs } = expressionNode\n const { object: contextObject } = this.context\n\n const { name: fnName } = callee\n\n const functionInfo = this.evaluator.functions[fnName]\n if (functionInfo) {\n // The function is among the custom functions.\n return this.evaluateCustomIdentifier(expressionNode, fnName)\n }\n // identifier is a global object\n const globalFn = getGlobalObjectProperty(fnName, contextObject)\n if (globalFn !== null) {\n // global functions like String, Number, must be invoked passing node value as argument, not the node itself\n const contextArg = { ...this.context, evaluateToNode: false }\n const args = await Promise.all(exprArgs.map((arg) => this.evaluator.evaluateNode(arg, contextArg)))\n return globalFn(...args)\n }\n\n throw new SystemError(SystemErrorKeys.expression.undefinedFunction, { name: fnName })\n }\n\n private async evaluateCustomIdentifier(expressionNode: CallExpression, fnName: string): Promise<any> {\n // Arguments is a reserved word in strict mode\n const { arguments: exprArgs } = expressionNode\n const numArgs = exprArgs.length\n\n const expressionFunction: ExpressionFunction<C> = this.evaluator.functions[fnName]\n\n const { minArity, maxArity, evaluateArgsToNodes, executor } = expressionFunction\n\n if (numArgs < minArity)\n throw new SystemError(SystemErrorKeys.expression.functionHasTooFewArguments, { fnName, minArity, numArgs })\n if (maxArity !== undefined && maxArity >= 0 && numArgs > maxArity)\n throw new SystemError(SystemErrorKeys.expression.functionHasTooManyArguments, { fnName, maxArity, numArgs })\n\n // evaluate arguments\n const argsContext = { ...this.context, evaluateToNode: evaluateArgsToNodes }\n const args = await Promise.all(exprArgs.map((arg) => this.evaluator.evaluateNode(arg, argsContext)))\n\n // Currently there are no side effects from function evaluation so it's\n // safe to call the function even when we're just parsing the expression\n // to find all identifiers being used.\n return executor(this.context)(...args)\n }\n}\n"]}
|
|
@@ -1,7 +1,13 @@
|
|
|
1
|
+
import { SystemError, SystemErrorKeys } from '../../../error';
|
|
1
2
|
import { ExpressionNodeEvaluator } from '../../node';
|
|
3
|
+
import { hasNestedQuantifiers } from '../regExpSafety';
|
|
2
4
|
export class LiteralEvaluator extends ExpressionNodeEvaluator {
|
|
3
5
|
evaluate(expressionNode) {
|
|
4
|
-
|
|
6
|
+
const { value } = expressionNode;
|
|
7
|
+
if (value instanceof RegExp && hasNestedQuantifiers(value.source)) {
|
|
8
|
+
return Promise.reject(new SystemError(SystemErrorKeys.expression.unsafeRegularExpression, { pattern: value.source }));
|
|
9
|
+
}
|
|
10
|
+
return Promise.resolve(value);
|
|
5
11
|
}
|
|
6
12
|
}
|
|
7
13
|
//# sourceMappingURL=literal.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"literal.js","sourceRoot":"","sources":["../../../../../src/expression/javascript/node/literal.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"literal.js","sourceRoot":"","sources":["../../../../../src/expression/javascript/node/literal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAE7D,OAAO,EAAE,uBAAuB,EAAqB,MAAM,YAAY,CAAA;AACvE,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAA;AAEtD,MAAM,OAAO,gBAA8C,SAAQ,uBAA6C;IAC9G,QAAQ,CAAC,cAAiC;QACxC,MAAM,EAAE,KAAK,EAAE,GAAG,cAAc,CAAA;QAChC,IAAI,KAAK,YAAY,MAAM,IAAI,oBAAoB,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;YAClE,OAAO,OAAO,CAAC,MAAM,CACnB,IAAI,WAAW,CAAC,eAAe,CAAC,UAAU,CAAC,uBAAuB,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAC/F,CAAA;QACH,CAAC;QACD,OAAO,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;IAC/B,CAAC;CACF","sourcesContent":["import { SystemError, SystemErrorKeys } from '../../../error'\nimport { ExpressionContext } from '../../context'\nimport { ExpressionNodeEvaluator, LiteralExpression } from '../../node'\nimport { hasNestedQuantifiers } from '../regExpSafety'\n\nexport class LiteralEvaluator<C extends ExpressionContext> extends ExpressionNodeEvaluator<C, LiteralExpression> {\n evaluate(expressionNode: LiteralExpression): Promise<any> {\n const { value } = expressionNode\n if (value instanceof RegExp && hasNestedQuantifiers(value.source)) {\n return Promise.reject(\n new SystemError(SystemErrorKeys.expression.unsafeRegularExpression, { pattern: value.source })\n )\n }\n return Promise.resolve(value)\n }\n}\n"]}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Protection against regular expressions that can take exponential time (ReDoS): JavaScript cannot interrupt a
|
|
3
|
+
* running regular expression, so a single evaluation could freeze the server or the browser.
|
|
4
|
+
*/
|
|
5
|
+
// maximum length of the strings that regular expressions are applied to in expressions
|
|
6
|
+
export const REG_EXP_INPUT_MAX_LENGTH = 1000;
|
|
7
|
+
// unbounded quantifier at the given position: *, + or {n,} (quantifiers like {n} or {n,m} are bounded)
|
|
8
|
+
const unboundedQuantifierRegExp = /^(\*|\+|\{\d+,\})/;
|
|
9
|
+
const isQuantifierAt = (source, index) => {
|
|
10
|
+
const char = source[index];
|
|
11
|
+
if (char === '*' || char === '+')
|
|
12
|
+
return true;
|
|
13
|
+
// {n,m} or {n,} (exact {n} repetitions don't multiply the ways a string can be matched)
|
|
14
|
+
return char === '{' && /^\{\d+,\d*\}/.test(source.substring(index));
|
|
15
|
+
};
|
|
16
|
+
const skipEscape = (index) => index + 2;
|
|
17
|
+
const skipCharacterClass = (source, index) => {
|
|
18
|
+
let i = index + 1;
|
|
19
|
+
while (i < source.length && source[i] !== ']') {
|
|
20
|
+
i = source[i] === '\\' ? skipEscape(i) : i + 1;
|
|
21
|
+
}
|
|
22
|
+
return i + 1;
|
|
23
|
+
};
|
|
24
|
+
// marks the innermost open group (if any) as containing a quantifier
|
|
25
|
+
const markInnermostGroupQuantified = (groupsStack) => {
|
|
26
|
+
if (groupsStack.length > 0) {
|
|
27
|
+
groupsStack[groupsStack.length - 1] = true;
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Closes the group ending at the specified index (position of the ")").
|
|
32
|
+
* Returns true if the group contains a quantifier and it's repeated by an unbounded quantifier.
|
|
33
|
+
*/
|
|
34
|
+
const closeGroup = (source, index, groupsStack) => {
|
|
35
|
+
var _a;
|
|
36
|
+
const groupContainsQuantifier = (_a = groupsStack.pop()) !== null && _a !== void 0 ? _a : false;
|
|
37
|
+
if (groupContainsQuantifier && unboundedQuantifierRegExp.test(source.substring(index + 1))) {
|
|
38
|
+
return true;
|
|
39
|
+
}
|
|
40
|
+
if (groupContainsQuantifier || isQuantifierAt(source, index + 1)) {
|
|
41
|
+
markInnermostGroupQuantified(groupsStack);
|
|
42
|
+
}
|
|
43
|
+
return false;
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Returns true if the specified regular expression source contains a group repeated by an unbounded quantifier
|
|
47
|
+
* that contains a quantifier itself (star height > 1), e.g. (a+)+, (\w*)* or (x{1,3})+:
|
|
48
|
+
* these patterns can take exponential time on non-matching strings.
|
|
49
|
+
* Overlapping alternations like (a|aa)+ are not detected.
|
|
50
|
+
*/
|
|
51
|
+
export const hasNestedQuantifiers = (source) => {
|
|
52
|
+
// for each open group: true if it contains a quantifier
|
|
53
|
+
const groupsStack = [];
|
|
54
|
+
let i = 0;
|
|
55
|
+
while (i < source.length) {
|
|
56
|
+
switch (source[i]) {
|
|
57
|
+
case '\\':
|
|
58
|
+
i = skipEscape(i);
|
|
59
|
+
break;
|
|
60
|
+
case '[':
|
|
61
|
+
i = skipCharacterClass(source, i);
|
|
62
|
+
break;
|
|
63
|
+
case '(':
|
|
64
|
+
groupsStack.push(false);
|
|
65
|
+
// a "?" right after "(" introduces a group modifier (e.g. "(?:"), it's not a quantifier
|
|
66
|
+
i += source[i + 1] === '?' ? 2 : 1;
|
|
67
|
+
break;
|
|
68
|
+
case ')':
|
|
69
|
+
if (closeGroup(source, i, groupsStack))
|
|
70
|
+
return true;
|
|
71
|
+
i += 1;
|
|
72
|
+
break;
|
|
73
|
+
default:
|
|
74
|
+
if (isQuantifierAt(source, i)) {
|
|
75
|
+
markInnermostGroupQuantified(groupsStack);
|
|
76
|
+
}
|
|
77
|
+
i += 1;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return false;
|
|
81
|
+
};
|
|
82
|
+
//# sourceMappingURL=regExpSafety.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"regExpSafety.js","sourceRoot":"","sources":["../../../../src/expression/javascript/regExpSafety.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Protection against regular expressions that can take exponential time (ReDoS): JavaScript cannot interrupt a\n * running regular expression, so a single evaluation could freeze the server or the browser.\n */\n\n// maximum length of the strings that regular expressions are applied to in expressions\nexport const REG_EXP_INPUT_MAX_LENGTH = 1000\n\n// unbounded quantifier at the given position: *, + or {n,} (quantifiers like {n} or {n,m} are bounded)\nconst unboundedQuantifierRegExp = /^(\\*|\\+|\\{\\d+,\\})/\n\nconst isQuantifierAt = (source: string, index: number): boolean => {\n const char = source[index]\n if (char === '*' || char === '+') return true\n // {n,m} or {n,} (exact {n} repetitions don't multiply the ways a string can be matched)\n return char === '{' && /^\\{\\d+,\\d*\\}/.test(source.substring(index))\n}\n\nconst skipEscape = (index: number): number => index + 2\n\nconst skipCharacterClass = (source: string, index: number): number => {\n let i = index + 1\n while (i < source.length && source[i] !== ']') {\n i = source[i] === '\\\\' ? skipEscape(i) : i + 1\n }\n return i + 1\n}\n\n// marks the innermost open group (if any) as containing a quantifier\nconst markInnermostGroupQuantified = (groupsStack: boolean[]): void => {\n if (groupsStack.length > 0) {\n groupsStack[groupsStack.length - 1] = true\n }\n}\n\n/**\n * Closes the group ending at the specified index (position of the \")\").\n * Returns true if the group contains a quantifier and it's repeated by an unbounded quantifier.\n */\nconst closeGroup = (source: string, index: number, groupsStack: boolean[]): boolean => {\n const groupContainsQuantifier = groupsStack.pop() ?? false\n if (groupContainsQuantifier && unboundedQuantifierRegExp.test(source.substring(index + 1))) {\n return true\n }\n if (groupContainsQuantifier || isQuantifierAt(source, index + 1)) {\n markInnermostGroupQuantified(groupsStack)\n }\n return false\n}\n\n/**\n * Returns true if the specified regular expression source contains a group repeated by an unbounded quantifier\n * that contains a quantifier itself (star height > 1), e.g. (a+)+, (\\w*)* or (x{1,3})+:\n * these patterns can take exponential time on non-matching strings.\n * Overlapping alternations like (a|aa)+ are not detected.\n */\nexport const hasNestedQuantifiers = (source: string): boolean => {\n // for each open group: true if it contains a quantifier\n const groupsStack: boolean[] = []\n let i = 0\n while (i < source.length) {\n switch (source[i]) {\n case '\\\\':\n i = skipEscape(i)\n break\n case '[':\n i = skipCharacterClass(source, i)\n break\n case '(':\n groupsStack.push(false)\n // a \"?\" right after \"(\" introduces a group modifier (e.g. \"(?:\"), it's not a quantifier\n i += source[i + 1] === '?' ? 2 : 1\n break\n case ')':\n if (closeGroup(source, i, groupsStack)) return true\n i += 1\n break\n default:\n if (isQuantifierAt(source, i)) {\n markInnermostGroupQuantified(groupsStack)\n }\n i += 1\n }\n }\n return false\n}\n"]}
|
|
@@ -16,6 +16,8 @@ export const distanceToPolygonBoundary = (point, polygon, srsIndex = DEFAULT_SRS
|
|
|
16
16
|
try {
|
|
17
17
|
// turf expects [longitude, latitude]; planar: polygon edges are straight lines (as in GeoJSON and on the map),
|
|
18
18
|
// consistent with the inside/outside check (geodesic would measure to great-circle edges)
|
|
19
|
+
// shortcut: polygons crossing the antimeridian (longitudes jumping from 180 to -180) are measured wrong,
|
|
20
|
+
// split them in 2 polygons (one for each side) if such areas of interest are needed
|
|
19
21
|
return pointToPolygonDistance([pointLatLong.x, pointLatLong.y], polygon, { units: 'meters', method: 'planar' });
|
|
20
22
|
}
|
|
21
23
|
catch (_a) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"distanceToPolygonBoundary.js","sourceRoot":"","sources":["../../../../src/geo/points/distanceToPolygonBoundary.ts"],"names":[],"mappings":"AAAA,OAAO,sBAAsB,MAAM,iCAAiC,CAAA;AAEpE,OAAO,EAAE,iBAAiB,EAAY,MAAM,WAAW,CAAA;AAGvD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAEvC;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,CACvC,KAAY,EACZ,OAAuB,EACvB,QAAQ,GAAa,iBAAiB,EACvB,EAAE;IACjB,MAAM,YAAY,GAAG,SAAS,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAA;IAC/C,IAAI,CAAC,YAAY;QAAE,OAAO,IAAI,CAAA;IAC9B,IAAI,CAAC;QACH,+GAA+G;QAC/G,0FAA0F;QAC1F,OAAO,sBAAsB,CAAC,CAAC,YAAY,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAA;IACjH,CAAC;eAAO,CAAC;QACP,2BAA2B;QAC3B,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC,CAAA","sourcesContent":["import pointToPolygonDistance from '@turf/point-to-polygon-distance'\n\nimport { DEFAULT_SRS_INDEX, SRSIndex } from '../../srs'\nimport { AreaOfInterest } from '../areaOfInterest'\nimport { Point } from '../point'\nimport { toLatLong } from './toLatLong'\n\n/**\n * Returns the distance (in meters) between a point and the boundary of a polygon: negative inside, positive outside.\n *\n * @param {!Point} point - The point.\n * @param {!AreaOfInterest} polygon - Polygon or multi polygon in WGS84.\n * @param {!SRSIndex} srsIndex - SRSs indexed by SRS code.\n * @returns {number|null} - The signed distance in meters, or null if the point or the polygon are not valid.\n */\nexport const distanceToPolygonBoundary = (\n point: Point,\n polygon: AreaOfInterest,\n srsIndex: SRSIndex = DEFAULT_SRS_INDEX\n): number | null => {\n const pointLatLong = toLatLong(point, srsIndex)\n if (!pointLatLong) return null\n try {\n // turf expects [longitude, latitude]; planar: polygon edges are straight lines (as in GeoJSON and on the map),\n // consistent with the inside/outside check (geodesic would measure to great-circle edges)\n return pointToPolygonDistance([pointLatLong.x, pointLatLong.y], polygon, { units: 'meters', method: 'planar' })\n } catch {\n // invalid polygon geometry\n return null\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"distanceToPolygonBoundary.js","sourceRoot":"","sources":["../../../../src/geo/points/distanceToPolygonBoundary.ts"],"names":[],"mappings":"AAAA,OAAO,sBAAsB,MAAM,iCAAiC,CAAA;AAEpE,OAAO,EAAE,iBAAiB,EAAY,MAAM,WAAW,CAAA;AAGvD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAEvC;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,CACvC,KAAY,EACZ,OAAuB,EACvB,QAAQ,GAAa,iBAAiB,EACvB,EAAE;IACjB,MAAM,YAAY,GAAG,SAAS,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAA;IAC/C,IAAI,CAAC,YAAY;QAAE,OAAO,IAAI,CAAA;IAC9B,IAAI,CAAC;QACH,+GAA+G;QAC/G,0FAA0F;QAC1F,yGAAyG;QACzG,oFAAoF;QACpF,OAAO,sBAAsB,CAAC,CAAC,YAAY,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAA;IACjH,CAAC;eAAO,CAAC;QACP,2BAA2B;QAC3B,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC,CAAA","sourcesContent":["import pointToPolygonDistance from '@turf/point-to-polygon-distance'\n\nimport { DEFAULT_SRS_INDEX, SRSIndex } from '../../srs'\nimport { AreaOfInterest } from '../areaOfInterest'\nimport { Point } from '../point'\nimport { toLatLong } from './toLatLong'\n\n/**\n * Returns the distance (in meters) between a point and the boundary of a polygon: negative inside, positive outside.\n *\n * @param {!Point} point - The point.\n * @param {!AreaOfInterest} polygon - Polygon or multi polygon in WGS84.\n * @param {!SRSIndex} srsIndex - SRSs indexed by SRS code.\n * @returns {number|null} - The signed distance in meters, or null if the point or the polygon are not valid.\n */\nexport const distanceToPolygonBoundary = (\n point: Point,\n polygon: AreaOfInterest,\n srsIndex: SRSIndex = DEFAULT_SRS_INDEX\n): number | null => {\n const pointLatLong = toLatLong(point, srsIndex)\n if (!pointLatLong) return null\n try {\n // turf expects [longitude, latitude]; planar: polygon edges are straight lines (as in GeoJSON and on the map),\n // consistent with the inside/outside check (geodesic would measure to great-circle edges)\n // shortcut: polygons crossing the antimeridian (longitudes jumping from 180 to -180) are measured wrong,\n // split them in 2 polygons (one for each side) if such areas of interest are needed\n return pointToPolygonDistance([pointLatLong.x, pointLatLong.y], polygon, { units: 'meters', method: 'planar' })\n } catch {\n // invalid polygon geometry\n return null\n }\n}\n"]}
|
|
@@ -13,6 +13,20 @@ exports.CallEvaluator = void 0;
|
|
|
13
13
|
const error_1 = require("../../../error");
|
|
14
14
|
const node_1 = require("../../node");
|
|
15
15
|
const global_1 = require("../global");
|
|
16
|
+
const regExpSafety_1 = require("../regExpSafety");
|
|
17
|
+
// e.g. /.../.test(text) or text.match(/.../): the time taken by a regular expression grows with the input length
|
|
18
|
+
const checkRegExpInputLength = (fnObject, args) => {
|
|
19
|
+
const values = [fnObject, ...args];
|
|
20
|
+
if (!values.some((value) => value instanceof RegExp))
|
|
21
|
+
return;
|
|
22
|
+
const inputTooLong = values.find((value) => typeof value === 'string' && value.length > regExpSafety_1.REG_EXP_INPUT_MAX_LENGTH);
|
|
23
|
+
if (inputTooLong !== undefined) {
|
|
24
|
+
throw new error_1.SystemError(error_1.SystemErrorKeys.expression.regularExpressionInputTooLong, {
|
|
25
|
+
maxLength: regExpSafety_1.REG_EXP_INPUT_MAX_LENGTH,
|
|
26
|
+
length: inputTooLong.length,
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
};
|
|
16
30
|
class CallEvaluator extends node_1.ExpressionNodeEvaluator {
|
|
17
31
|
evaluate(expressionNode) {
|
|
18
32
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -38,6 +52,7 @@ class CallEvaluator extends node_1.ExpressionNodeEvaluator {
|
|
|
38
52
|
const fnObject = yield this.evaluator.evaluateNode(calleeObj, this.context);
|
|
39
53
|
const argsEvaluated = yield Promise.all(exprArgs.map((arg) => this.evaluator.evaluateNode(arg, this.context)));
|
|
40
54
|
const args = argsEvaluated.flat();
|
|
55
|
+
checkRegExpInputLength(fnObject, args);
|
|
41
56
|
return fn.call(fnObject, ...args);
|
|
42
57
|
}
|
|
43
58
|
return null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"call.js","sourceRoot":"","sources":["../../../../src/expression/javascript/node/call.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,0CAA6D;AAG7D,qCAMmB;AACnB,sCAAmD;
|
|
1
|
+
{"version":3,"file":"call.js","sourceRoot":"","sources":["../../../../src/expression/javascript/node/call.ts"],"names":[],"mappings":"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","sourcesContent":["import { SystemError, SystemErrorKeys } from '../../../error'\nimport { ExpressionContext } from '../../context'\nimport { ExpressionFunction } from '../../function'\nimport {\n CallExpression,\n ExpressionNodeEvaluator,\n ExpressionNodeType,\n IdentifierExpression,\n MemberExpression,\n} from '../../node'\nimport { getGlobalObjectProperty } from '../global'\nimport { REG_EXP_INPUT_MAX_LENGTH } from '../regExpSafety'\n\n// e.g. /.../.test(text) or text.match(/.../): the time taken by a regular expression grows with the input length\nconst checkRegExpInputLength = (fnObject: any, args: any[]): void => {\n const values = [fnObject, ...args]\n if (!values.some((value) => value instanceof RegExp)) return\n const inputTooLong = values.find((value) => typeof value === 'string' && value.length > REG_EXP_INPUT_MAX_LENGTH)\n if (inputTooLong !== undefined) {\n throw new SystemError(SystemErrorKeys.expression.regularExpressionInputTooLong, {\n maxLength: REG_EXP_INPUT_MAX_LENGTH,\n length: inputTooLong.length,\n })\n }\n}\n\nexport class CallEvaluator<C extends ExpressionContext> extends ExpressionNodeEvaluator<C, CallExpression> {\n async evaluate(expressionNode: CallExpression): Promise<any> {\n const { callee } = expressionNode\n\n if (callee.type === ExpressionNodeType.Member) {\n return this.evaluateMember(expressionNode, callee)\n } else if (callee.type === ExpressionNodeType.Identifier) {\n return this.evaluateIdentifier(expressionNode, callee)\n }\n\n // No complex expressions may be put in place of a function body.\n // Only a plain identifier is allowed.\n throw new SystemError(SystemErrorKeys.expression.invalidCalleeType, { type: callee.type })\n }\n\n private async evaluateMember(expressionNode: CallExpression, callee: MemberExpression): Promise<any> {\n const { arguments: exprArgs } = expressionNode\n\n // global function (e.g. Math.round(...))\n const fn = await this.evaluator.evaluateNode(callee, this.context)\n if (fn) {\n const { object: calleeObj } = callee\n const fnObject = await this.evaluator.evaluateNode(calleeObj, this.context)\n const argsEvaluated = await Promise.all(exprArgs.map((arg) => this.evaluator.evaluateNode(arg, this.context)))\n const args = argsEvaluated.flat()\n checkRegExpInputLength(fnObject, args)\n return fn.call(fnObject, ...args)\n }\n return null\n }\n\n private async evaluateIdentifier(expressionNode: CallExpression, callee: IdentifierExpression): Promise<any> {\n // Arguments is a reserved word in strict mode\n const { arguments: exprArgs } = expressionNode\n const { object: contextObject } = this.context\n\n const { name: fnName } = callee\n\n const functionInfo = this.evaluator.functions[fnName]\n if (functionInfo) {\n // The function is among the custom functions.\n return this.evaluateCustomIdentifier(expressionNode, fnName)\n }\n // identifier is a global object\n const globalFn = getGlobalObjectProperty(fnName, contextObject)\n if (globalFn !== null) {\n // global functions like String, Number, must be invoked passing node value as argument, not the node itself\n const contextArg = { ...this.context, evaluateToNode: false }\n const args = await Promise.all(exprArgs.map((arg) => this.evaluator.evaluateNode(arg, contextArg)))\n return globalFn(...args)\n }\n\n throw new SystemError(SystemErrorKeys.expression.undefinedFunction, { name: fnName })\n }\n\n private async evaluateCustomIdentifier(expressionNode: CallExpression, fnName: string): Promise<any> {\n // Arguments is a reserved word in strict mode\n const { arguments: exprArgs } = expressionNode\n const numArgs = exprArgs.length\n\n const expressionFunction: ExpressionFunction<C> = this.evaluator.functions[fnName]\n\n const { minArity, maxArity, evaluateArgsToNodes, executor } = expressionFunction\n\n if (numArgs < minArity)\n throw new SystemError(SystemErrorKeys.expression.functionHasTooFewArguments, { fnName, minArity, numArgs })\n if (maxArity !== undefined && maxArity >= 0 && numArgs > maxArity)\n throw new SystemError(SystemErrorKeys.expression.functionHasTooManyArguments, { fnName, maxArity, numArgs })\n\n // evaluate arguments\n const argsContext = { ...this.context, evaluateToNode: evaluateArgsToNodes }\n const args = await Promise.all(exprArgs.map((arg) => this.evaluator.evaluateNode(arg, argsContext)))\n\n // Currently there are no side effects from function evaluation so it's\n // safe to call the function even when we're just parsing the expression\n // to find all identifiers being used.\n return executor(this.context)(...args)\n }\n}\n"]}
|
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.LiteralEvaluator = void 0;
|
|
4
|
+
const error_1 = require("../../../error");
|
|
4
5
|
const node_1 = require("../../node");
|
|
6
|
+
const regExpSafety_1 = require("../regExpSafety");
|
|
5
7
|
class LiteralEvaluator extends node_1.ExpressionNodeEvaluator {
|
|
6
8
|
evaluate(expressionNode) {
|
|
7
|
-
|
|
9
|
+
const { value } = expressionNode;
|
|
10
|
+
if (value instanceof RegExp && (0, regExpSafety_1.hasNestedQuantifiers)(value.source)) {
|
|
11
|
+
return Promise.reject(new error_1.SystemError(error_1.SystemErrorKeys.expression.unsafeRegularExpression, { pattern: value.source }));
|
|
12
|
+
}
|
|
13
|
+
return Promise.resolve(value);
|
|
8
14
|
}
|
|
9
15
|
}
|
|
10
16
|
exports.LiteralEvaluator = LiteralEvaluator;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"literal.js","sourceRoot":"","sources":["../../../../src/expression/javascript/node/literal.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"literal.js","sourceRoot":"","sources":["../../../../src/expression/javascript/node/literal.ts"],"names":[],"mappings":";;;AAAA,0CAA6D;AAE7D,qCAAuE;AACvE,kDAAsD;AAEtD,sBAA2D,SAAQ,8BAA6C;IAC9G,QAAQ,CAAC,cAAiC;QACxC,MAAM,EAAE,KAAK,EAAE,GAAG,cAAc,CAAA;QAChC,IAAI,KAAK,YAAY,MAAM,IAAI,IAAA,mCAAoB,EAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;YAClE,OAAO,OAAO,CAAC,MAAM,CACnB,IAAI,mBAAW,CAAC,uBAAe,CAAC,UAAU,CAAC,uBAAuB,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAC/F,CAAA;QACH,CAAC;QACD,OAAO,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;IAC/B,CAAC;CACF","sourcesContent":["import { SystemError, SystemErrorKeys } from '../../../error'\nimport { ExpressionContext } from '../../context'\nimport { ExpressionNodeEvaluator, LiteralExpression } from '../../node'\nimport { hasNestedQuantifiers } from '../regExpSafety'\n\nexport class LiteralEvaluator<C extends ExpressionContext> extends ExpressionNodeEvaluator<C, LiteralExpression> {\n evaluate(expressionNode: LiteralExpression): Promise<any> {\n const { value } = expressionNode\n if (value instanceof RegExp && hasNestedQuantifiers(value.source)) {\n return Promise.reject(\n new SystemError(SystemErrorKeys.expression.unsafeRegularExpression, { pattern: value.source })\n )\n }\n return Promise.resolve(value)\n }\n}\n"]}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Protection against regular expressions that can take exponential time (ReDoS): JavaScript cannot interrupt a
|
|
3
|
+
* running regular expression, so a single evaluation could freeze the server or the browser.
|
|
4
|
+
*/
|
|
5
|
+
export declare const REG_EXP_INPUT_MAX_LENGTH = 1000;
|
|
6
|
+
/**
|
|
7
|
+
* Returns true if the specified regular expression source contains a group repeated by an unbounded quantifier
|
|
8
|
+
* that contains a quantifier itself (star height > 1), e.g. (a+)+, (\w*)* or (x{1,3})+:
|
|
9
|
+
* these patterns can take exponential time on non-matching strings.
|
|
10
|
+
* Overlapping alternations like (a|aa)+ are not detected.
|
|
11
|
+
*/
|
|
12
|
+
export declare const hasNestedQuantifiers: (source: string) => boolean;
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Protection against regular expressions that can take exponential time (ReDoS): JavaScript cannot interrupt a
|
|
4
|
+
* running regular expression, so a single evaluation could freeze the server or the browser.
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.hasNestedQuantifiers = exports.REG_EXP_INPUT_MAX_LENGTH = void 0;
|
|
8
|
+
// maximum length of the strings that regular expressions are applied to in expressions
|
|
9
|
+
exports.REG_EXP_INPUT_MAX_LENGTH = 1000;
|
|
10
|
+
// unbounded quantifier at the given position: *, + or {n,} (quantifiers like {n} or {n,m} are bounded)
|
|
11
|
+
const unboundedQuantifierRegExp = /^(\*|\+|\{\d+,\})/;
|
|
12
|
+
const isQuantifierAt = (source, index) => {
|
|
13
|
+
const char = source[index];
|
|
14
|
+
if (char === '*' || char === '+')
|
|
15
|
+
return true;
|
|
16
|
+
// {n,m} or {n,} (exact {n} repetitions don't multiply the ways a string can be matched)
|
|
17
|
+
return char === '{' && /^\{\d+,\d*\}/.test(source.substring(index));
|
|
18
|
+
};
|
|
19
|
+
const skipEscape = (index) => index + 2;
|
|
20
|
+
const skipCharacterClass = (source, index) => {
|
|
21
|
+
let i = index + 1;
|
|
22
|
+
while (i < source.length && source[i] !== ']') {
|
|
23
|
+
i = source[i] === '\\' ? skipEscape(i) : i + 1;
|
|
24
|
+
}
|
|
25
|
+
return i + 1;
|
|
26
|
+
};
|
|
27
|
+
// marks the innermost open group (if any) as containing a quantifier
|
|
28
|
+
const markInnermostGroupQuantified = (groupsStack) => {
|
|
29
|
+
if (groupsStack.length > 0) {
|
|
30
|
+
groupsStack[groupsStack.length - 1] = true;
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Closes the group ending at the specified index (position of the ")").
|
|
35
|
+
* Returns true if the group contains a quantifier and it's repeated by an unbounded quantifier.
|
|
36
|
+
*/
|
|
37
|
+
const closeGroup = (source, index, groupsStack) => {
|
|
38
|
+
var _a;
|
|
39
|
+
const groupContainsQuantifier = (_a = groupsStack.pop()) !== null && _a !== void 0 ? _a : false;
|
|
40
|
+
if (groupContainsQuantifier && unboundedQuantifierRegExp.test(source.substring(index + 1))) {
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
if (groupContainsQuantifier || isQuantifierAt(source, index + 1)) {
|
|
44
|
+
markInnermostGroupQuantified(groupsStack);
|
|
45
|
+
}
|
|
46
|
+
return false;
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* Returns true if the specified regular expression source contains a group repeated by an unbounded quantifier
|
|
50
|
+
* that contains a quantifier itself (star height > 1), e.g. (a+)+, (\w*)* or (x{1,3})+:
|
|
51
|
+
* these patterns can take exponential time on non-matching strings.
|
|
52
|
+
* Overlapping alternations like (a|aa)+ are not detected.
|
|
53
|
+
*/
|
|
54
|
+
const hasNestedQuantifiers = (source) => {
|
|
55
|
+
// for each open group: true if it contains a quantifier
|
|
56
|
+
const groupsStack = [];
|
|
57
|
+
let i = 0;
|
|
58
|
+
while (i < source.length) {
|
|
59
|
+
switch (source[i]) {
|
|
60
|
+
case '\\':
|
|
61
|
+
i = skipEscape(i);
|
|
62
|
+
break;
|
|
63
|
+
case '[':
|
|
64
|
+
i = skipCharacterClass(source, i);
|
|
65
|
+
break;
|
|
66
|
+
case '(':
|
|
67
|
+
groupsStack.push(false);
|
|
68
|
+
// a "?" right after "(" introduces a group modifier (e.g. "(?:"), it's not a quantifier
|
|
69
|
+
i += source[i + 1] === '?' ? 2 : 1;
|
|
70
|
+
break;
|
|
71
|
+
case ')':
|
|
72
|
+
if (closeGroup(source, i, groupsStack))
|
|
73
|
+
return true;
|
|
74
|
+
i += 1;
|
|
75
|
+
break;
|
|
76
|
+
default:
|
|
77
|
+
if (isQuantifierAt(source, i)) {
|
|
78
|
+
markInnermostGroupQuantified(groupsStack);
|
|
79
|
+
}
|
|
80
|
+
i += 1;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return false;
|
|
84
|
+
};
|
|
85
|
+
exports.hasNestedQuantifiers = hasNestedQuantifiers;
|
|
86
|
+
//# sourceMappingURL=regExpSafety.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"regExpSafety.js","sourceRoot":"","sources":["../../../src/expression/javascript/regExpSafety.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Protection against regular expressions that can take exponential time (ReDoS): JavaScript cannot interrupt a\n * running regular expression, so a single evaluation could freeze the server or the browser.\n */\n\n// maximum length of the strings that regular expressions are applied to in expressions\nexport const REG_EXP_INPUT_MAX_LENGTH = 1000\n\n// unbounded quantifier at the given position: *, + or {n,} (quantifiers like {n} or {n,m} are bounded)\nconst unboundedQuantifierRegExp = /^(\\*|\\+|\\{\\d+,\\})/\n\nconst isQuantifierAt = (source: string, index: number): boolean => {\n const char = source[index]\n if (char === '*' || char === '+') return true\n // {n,m} or {n,} (exact {n} repetitions don't multiply the ways a string can be matched)\n return char === '{' && /^\\{\\d+,\\d*\\}/.test(source.substring(index))\n}\n\nconst skipEscape = (index: number): number => index + 2\n\nconst skipCharacterClass = (source: string, index: number): number => {\n let i = index + 1\n while (i < source.length && source[i] !== ']') {\n i = source[i] === '\\\\' ? skipEscape(i) : i + 1\n }\n return i + 1\n}\n\n// marks the innermost open group (if any) as containing a quantifier\nconst markInnermostGroupQuantified = (groupsStack: boolean[]): void => {\n if (groupsStack.length > 0) {\n groupsStack[groupsStack.length - 1] = true\n }\n}\n\n/**\n * Closes the group ending at the specified index (position of the \")\").\n * Returns true if the group contains a quantifier and it's repeated by an unbounded quantifier.\n */\nconst closeGroup = (source: string, index: number, groupsStack: boolean[]): boolean => {\n const groupContainsQuantifier = groupsStack.pop() ?? false\n if (groupContainsQuantifier && unboundedQuantifierRegExp.test(source.substring(index + 1))) {\n return true\n }\n if (groupContainsQuantifier || isQuantifierAt(source, index + 1)) {\n markInnermostGroupQuantified(groupsStack)\n }\n return false\n}\n\n/**\n * Returns true if the specified regular expression source contains a group repeated by an unbounded quantifier\n * that contains a quantifier itself (star height > 1), e.g. (a+)+, (\\w*)* or (x{1,3})+:\n * these patterns can take exponential time on non-matching strings.\n * Overlapping alternations like (a|aa)+ are not detected.\n */\nexport const hasNestedQuantifiers = (source: string): boolean => {\n // for each open group: true if it contains a quantifier\n const groupsStack: boolean[] = []\n let i = 0\n while (i < source.length) {\n switch (source[i]) {\n case '\\\\':\n i = skipEscape(i)\n break\n case '[':\n i = skipCharacterClass(source, i)\n break\n case '(':\n groupsStack.push(false)\n // a \"?\" right after \"(\" introduces a group modifier (e.g. \"(?:\"), it's not a quantifier\n i += source[i + 1] === '?' ? 2 : 1\n break\n case ')':\n if (closeGroup(source, i, groupsStack)) return true\n i += 1\n break\n default:\n if (isQuantifierAt(source, i)) {\n markInnermostGroupQuantified(groupsStack)\n }\n i += 1\n }\n }\n return false\n}\n"]}
|
|
@@ -22,6 +22,8 @@ const distanceToPolygonBoundary = (point, polygon, srsIndex = srs_1.DEFAULT_SRS_
|
|
|
22
22
|
try {
|
|
23
23
|
// turf expects [longitude, latitude]; planar: polygon edges are straight lines (as in GeoJSON and on the map),
|
|
24
24
|
// consistent with the inside/outside check (geodesic would measure to great-circle edges)
|
|
25
|
+
// shortcut: polygons crossing the antimeridian (longitudes jumping from 180 to -180) are measured wrong,
|
|
26
|
+
// split them in 2 polygons (one for each side) if such areas of interest are needed
|
|
25
27
|
return (0, point_to_polygon_distance_1.default)([pointLatLong.x, pointLatLong.y], polygon, { units: 'meters', method: 'planar' });
|
|
26
28
|
}
|
|
27
29
|
catch (_a) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"distanceToPolygonBoundary.js","sourceRoot":"","sources":["../../../src/geo/points/distanceToPolygonBoundary.ts"],"names":[],"mappings":";;;;;;AAAA,gGAAoE;AAEpE,mCAAuD;AAGvD,2CAAuC;AAEvC;;;;;;;GAOG;AACI,MAAM,yBAAyB,GAAG,CACvC,KAAY,EACZ,OAAuB,EACvB,QAAQ,GAAa,uBAAiB,EACvB,EAAE;IACjB,MAAM,YAAY,GAAG,IAAA,qBAAS,EAAC,KAAK,EAAE,QAAQ,CAAC,CAAA;IAC/C,IAAI,CAAC,YAAY;QAAE,OAAO,IAAI,CAAA;IAC9B,IAAI,CAAC;QACH,+GAA+G;QAC/G,0FAA0F;QAC1F,OAAO,IAAA,mCAAsB,EAAC,CAAC,YAAY,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAA;IACjH,CAAC;eAAO,CAAC;QACP,2BAA2B;QAC3B,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"distanceToPolygonBoundary.js","sourceRoot":"","sources":["../../../src/geo/points/distanceToPolygonBoundary.ts"],"names":[],"mappings":";;;;;;AAAA,gGAAoE;AAEpE,mCAAuD;AAGvD,2CAAuC;AAEvC;;;;;;;GAOG;AACI,MAAM,yBAAyB,GAAG,CACvC,KAAY,EACZ,OAAuB,EACvB,QAAQ,GAAa,uBAAiB,EACvB,EAAE;IACjB,MAAM,YAAY,GAAG,IAAA,qBAAS,EAAC,KAAK,EAAE,QAAQ,CAAC,CAAA;IAC/C,IAAI,CAAC,YAAY;QAAE,OAAO,IAAI,CAAA;IAC9B,IAAI,CAAC;QACH,+GAA+G;QAC/G,0FAA0F;QAC1F,yGAAyG;QACzG,oFAAoF;QACpF,OAAO,IAAA,mCAAsB,EAAC,CAAC,YAAY,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAA;IACjH,CAAC;eAAO,CAAC;QACP,2BAA2B;QAC3B,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC,CAAA;AAjBY,QAAA,yBAAyB,GAAzB,yBAAyB,CAiBrC","sourcesContent":["import pointToPolygonDistance from '@turf/point-to-polygon-distance'\n\nimport { DEFAULT_SRS_INDEX, SRSIndex } from '../../srs'\nimport { AreaOfInterest } from '../areaOfInterest'\nimport { Point } from '../point'\nimport { toLatLong } from './toLatLong'\n\n/**\n * Returns the distance (in meters) between a point and the boundary of a polygon: negative inside, positive outside.\n *\n * @param {!Point} point - The point.\n * @param {!AreaOfInterest} polygon - Polygon or multi polygon in WGS84.\n * @param {!SRSIndex} srsIndex - SRSs indexed by SRS code.\n * @returns {number|null} - The signed distance in meters, or null if the point or the polygon are not valid.\n */\nexport const distanceToPolygonBoundary = (\n point: Point,\n polygon: AreaOfInterest,\n srsIndex: SRSIndex = DEFAULT_SRS_INDEX\n): number | null => {\n const pointLatLong = toLatLong(point, srsIndex)\n if (!pointLatLong) return null\n try {\n // turf expects [longitude, latitude]; planar: polygon edges are straight lines (as in GeoJSON and on the map),\n // consistent with the inside/outside check (geodesic would measure to great-circle edges)\n // shortcut: polygons crossing the antimeridian (longitudes jumping from 180 to -180) are measured wrong,\n // split them in 2 polygons (one for each side) if such areas of interest are needed\n return pointToPolygonDistance([pointLatLong.x, pointLatLong.y], polygon, { units: 'meters', method: 'planar' })\n } catch {\n // invalid polygon geometry\n return null\n }\n}\n"]}
|