From efbbc0d20e6457b303adf36222ad12589add3136 Mon Sep 17 00:00:00 2001 From: HARPER Jon Date: Tue, 18 Mar 2025 13:06:02 +0100 Subject: [PATCH 1/4] use generic worfklow for build --- .github/workflows/build.yml | 50 +++++++------------------------------ 1 file changed, 9 insertions(+), 41 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 674661ca..c1d5ed24 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,4 +1,5 @@ name: CI + on: push: branches: @@ -6,44 +7,11 @@ on: pull_request: jobs: - license-headers: - name: Check licenses headers - runs-on: ubuntu-latest - steps: - - name: Checkout sources - uses: actions/checkout@v4 - with: - persist-credentials: false - - uses: actions/setup-node@v4 - with: - node-version: 22 - - name: Check License Header (Check Mode) - uses: apache/skywalking-eyes/header@v0.5.0 - with: - config: .github/config/.licenserc.yaml - - build: - runs-on: ubuntu-latest - steps: - - name: Checkout sources - uses: actions/checkout@v4 - with: - persist-credentials: false - - - uses: actions/setup-node@v4 - with: - node-version: 22 - - - name: Build - run: | - npm ci - npm run licenses-check - npm run lint - npm run test:coverage - npm run build - - - name: SonarCloud Scan - uses: SonarSource/sonarcloud-github-action@v3.0.0 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + build: + uses: powsybl/github-ci/.github/workflows/build-frontend-lib-generic.yml@852670523f7fb3699d16efcbdd6d7500d5730b2f + with: + eventType: commons_ui_updated + licensercPath: .github/config/.licenserc.yaml + secrets: + sonar-token: ${{ secrets.SONAR_TOKEN }} + repo-token: ${{ secrets.REPO_ACCESS_TOKEN }} From 3c310a2b72145bb19c8de9f04afb105534629189 Mon Sep 17 00:00:00 2001 From: HARPER Jon Date: Wed, 26 Mar 2025 11:15:42 +0100 Subject: [PATCH 2/4] test old sonar --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c1d5ed24..aeaed4b1 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -8,7 +8,7 @@ on: jobs: build: - uses: powsybl/github-ci/.github/workflows/build-frontend-lib-generic.yml@852670523f7fb3699d16efcbdd6d7500d5730b2f + uses: powsybl/github-ci/.github/workflows/build-frontend-lib-generic.yml@0f2f06b6f3a89497d4b7e1abe0c74503f3df9fda with: eventType: commons_ui_updated licensercPath: .github/config/.licenserc.yaml From a4df9c701a66c5546cc8e7cf4eac8beb70c5ea00 Mon Sep 17 00:00:00 2001 From: HARPER Jon Date: Wed, 26 Mar 2025 13:58:47 +0100 Subject: [PATCH 3/4] Revert "test old sonar" This reverts commit 3c310a2b72145bb19c8de9f04afb105534629189. --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index aeaed4b1..c1d5ed24 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -8,7 +8,7 @@ on: jobs: build: - uses: powsybl/github-ci/.github/workflows/build-frontend-lib-generic.yml@0f2f06b6f3a89497d4b7e1abe0c74503f3df9fda + uses: powsybl/github-ci/.github/workflows/build-frontend-lib-generic.yml@852670523f7fb3699d16efcbdd6d7500d5730b2f with: eventType: commons_ui_updated licensercPath: .github/config/.licenserc.yaml From 1cdf5e1f40e080d3c8a7a339f43c679c3fa476e4 Mon Sep 17 00:00:00 2001 From: HARPER Jon Date: Wed, 26 Mar 2025 16:02:02 +0100 Subject: [PATCH 4/4] replace O(n^2) regexp with O(N) verbose parsing code --- .../flatParameters/FlatParameters.tsx | 41 ++++++++++++++++++- .../inputs/reactHookForm/numbers/utils.ts | 25 ++++++++++- 2 files changed, 63 insertions(+), 3 deletions(-) diff --git a/src/components/flatParameters/FlatParameters.tsx b/src/components/flatParameters/FlatParameters.tsx index a8e5284f..682ba3f5 100644 --- a/src/components/flatParameters/FlatParameters.tsx +++ b/src/components/flatParameters/FlatParameters.tsx @@ -45,7 +45,44 @@ const styles = { }, }; -const FloatRE = /^-?\d*[.,]?\d*([eE]-?\d*)?$/; +const isFloatNumberPrefix = (val: string) => { + // no possessive qualifier in javascripts native regexp, + // replace /^-?\d*[.,]?\d*([eE]-?\d*)?$/ with code not + // vulnerable to catastrophic backtracking (ON^2) + // TODO find a better way for this code + let idx = 0; + if (idx < val.length && val.charAt(idx) === '-') { + idx += 1; + } + while (idx < val.length && val.charCodeAt(idx) >= 48 && val.charCodeAt(idx) <= 57) { + // [0-9] + idx += 1; + } + if (idx === val.length) { + return true; + } + if (val.charAt(idx) === '.' || val.charAt(idx) === ',') { + idx += 1; + while (idx < val.length && val.charCodeAt(idx) >= 48 && val.charCodeAt(idx) <= 57) { + // [0-9] + idx += 1; + } + } + if (idx === val.length) { + return true; + } + if (val.charAt(idx) === 'e' || val.charAt(idx) === 'E') { + idx += 1; + if (idx < val.length && val.charAt(idx) === '-') { + idx += 1; + } + while (idx < val.length && val.charCodeAt(idx) >= 48 && val.charCodeAt(idx) <= 57) { + // [0-9] + idx += 1; + } + } + return idx === val.length; +}; const IntegerRE = /^-?\d*$/; const ListRE = /^\[(.*)]$/; const sepRE = /[, ]/; @@ -279,7 +316,7 @@ export function FlatParameters({ onFocus={() => onUncommitted(param, true)} onBlur={() => onUncommitted(param, false)} onChange={(e) => { - const m = FloatRE.exec(e.target.value); + const m = isFloatNumberPrefix(e.target.value); if (m) { onFieldChange(outputTransformFloatString(e.target.value), param); } diff --git a/src/components/inputs/reactHookForm/numbers/utils.ts b/src/components/inputs/reactHookForm/numbers/utils.ts index 153b8d02..0fa9f15e 100644 --- a/src/components/inputs/reactHookForm/numbers/utils.ts +++ b/src/components/inputs/reactHookForm/numbers/utils.ts @@ -8,6 +8,29 @@ export const isIntegerNumber = (val: string) => { return /^-?[0-9]*$/.test(val); }; +// checks if it is a prefix export const isFloatNumber = (val: string) => { - return /^-?[0-9]*[.,]?[0-9]*$/.test(val); + // no possessive qualifier in javascripts native regexp, + // replace /^-?[0-9]*[.,]?[0-9]*$/ with code not + // vulnerable to catastrophic backtracking (ON^2) + // TODO find a better way for this code + let idx = 0; + if (idx < val.length && val.charAt(idx) === '-') { + idx += 1; + } + while (idx < val.length && val.charCodeAt(idx) >= 48 && val.charCodeAt(idx) <= 57) { + // [0-9] + idx += 1; + } + if (idx === val.length) { + return true; + } + if (val.charAt(idx) === '.' || val.charAt(idx) === ',') { + idx += 1; + while (idx < val.length && val.charCodeAt(idx) >= 48 && val.charCodeAt(idx) <= 57) { + // [0-9] + idx += 1; + } + } + return idx === val.length; };