diff --git a/.clang-format b/.clang-format index 4aad29c328a..828ec0ad86d 100644 --- a/.clang-format +++ b/.clang-format @@ -9,11 +9,11 @@ AlignEscapedNewlines: Right AlignOperands: true AlignTrailingComments: true AllowAllParametersOfDeclarationOnNextLine: true -AllowShortBlocksOnASingleLine: false +AllowShortBlocksOnASingleLine: Never AllowShortCaseLabelsOnASingleLine: false AllowShortFunctionsOnASingleLine: Inline AllowShortIfStatementsOnASingleLine: true -AllowShortLoopsOnASingleLine: true +AllowShortLoopsOnASingleLine: false AlwaysBreakAfterDefinitionReturnType: None AlwaysBreakAfterReturnType: None AlwaysBreakBeforeMultilineStrings: false diff --git a/.eslintrc.js b/.eslintrc.js index f86f42e8f2e..9eaa7e3f47b 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -348,6 +348,7 @@ module.exports = { Crypto: 'readable', CryptoKey: 'readable', DecompressionStream: 'readable', + EventSource: 'readable', fetch: 'readable', FormData: 'readable', ReadableStream: 'readable', diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index e1fe4d0add3..3f259a9152e 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -15,7 +15,7 @@ /.github/ISSUE_TEMPLATE/* @nodejs/tsc /CODE_OF_CONDUCT.md @nodejs/tsc /CONTRIBUTING.md @nodejs/tsc -/doc/contributing/*.md @nodejs/tsc +/doc/contributing/**/* @nodejs/tsc /GOVERNANCE.md @nodejs/tsc /SECURITY.md @nodejs/tsc /LICENSE @nodejs/tsc @@ -167,6 +167,7 @@ /doc/api/permissions.md @nodejs/security-wg /lib/internal/process/permission.js @nodejs/security-wg /src/permission/* @nodejs/security-wg +/test/parallel/test-permission-* @nodejs/security-wg # Dependency Update Tools diff --git a/.github/label-pr-config.yml b/.github/label-pr-config.yml index 5a9764b1908..c126adcee0c 100644 --- a/.github/label-pr-config.yml +++ b/.github/label-pr-config.yml @@ -98,6 +98,7 @@ subSystemLabels: /^lib\/test.js$/: test_runner /^lib\/internal\/url\.js$/: whatwg-url /^lib\/internal\/modules\/esm/: esm + /^lib\/internal\/modules/: module /^lib\/internal\/webstreams/: web streams /^lib\/internal\/test_runner/: test_runner diff --git a/.github/workflows/auto-start-ci.yml b/.github/workflows/auto-start-ci.yml index 15b35cea97b..86a360d8c48 100644 --- a/.github/workflows/auto-start-ci.yml +++ b/.github/workflows/auto-start-ci.yml @@ -50,7 +50,7 @@ jobs: persist-credentials: false - name: Install Node.js - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 + uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 with: node-version: ${{ env.NODE_VERSION }} diff --git a/.github/workflows/build-tarball.yml b/.github/workflows/build-tarball.yml index b0d3e52f5e4..05259a97caf 100644 --- a/.github/workflows/build-tarball.yml +++ b/.github/workflows/build-tarball.yml @@ -46,13 +46,13 @@ jobs: with: persist-credentials: false - name: Set up Python ${{ env.PYTHON_VERSION }} - uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5.1.0 + uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0 with: python-version: ${{ env.PYTHON_VERSION }} - name: Set up sccache uses: mozilla-actions/sccache-action@89e9040de88b577a072e3760aaf59f585da083af # v0.0.5 with: - version: v0.8.0 + version: v0.8.1 - name: Environment Information run: npx envinfo - name: Make tarball @@ -64,7 +64,7 @@ jobs: mkdir tarballs mv *.tar.gz tarballs - name: Upload tarball artifact - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 + uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0 with: name: tarballs path: tarballs @@ -76,17 +76,17 @@ jobs: with: persist-credentials: false - name: Set up Python ${{ env.PYTHON_VERSION }} - uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5.1.0 + uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0 with: python-version: ${{ env.PYTHON_VERSION }} - name: Set up sccache uses: mozilla-actions/sccache-action@89e9040de88b577a072e3760aaf59f585da083af # v0.0.5 with: - version: v0.8.0 + version: v0.8.1 - name: Environment Information run: npx envinfo - name: Download tarball - uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 + uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8 with: name: tarballs path: tarballs diff --git a/.github/workflows/build-windows.yml b/.github/workflows/build-windows.yml index 9f33e7f1de1..37e1d789bb3 100644 --- a/.github/workflows/build-windows.yml +++ b/.github/workflows/build-windows.yml @@ -42,7 +42,7 @@ jobs: with: persist-credentials: false - name: Set up Python ${{ env.PYTHON_VERSION }} - uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5.1.0 + uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0 with: python-version: ${{ env.PYTHON_VERSION }} - name: Install deps diff --git a/.github/workflows/commit-lint.yml b/.github/workflows/commit-lint.yml index 67c77677814..23a2d1392b3 100644 --- a/.github/workflows/commit-lint.yml +++ b/.github/workflows/commit-lint.yml @@ -23,7 +23,7 @@ jobs: persist-credentials: false - run: git reset HEAD^2 - name: Install Node.js - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 + uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 with: node-version: ${{ env.NODE_VERSION }} - name: Validate commit message diff --git a/.github/workflows/commit-queue.yml b/.github/workflows/commit-queue.yml index fbf4ec808b4..31d61b84b60 100644 --- a/.github/workflows/commit-queue.yml +++ b/.github/workflows/commit-queue.yml @@ -71,7 +71,7 @@ jobs: # Install dependencies - name: Install Node.js - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 + uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 with: node-version: ${{ env.NODE_VERSION }} - name: Install @node-core/utils diff --git a/.github/workflows/coverage-linux-without-intl.yml b/.github/workflows/coverage-linux-without-intl.yml index 136639a7258..e9ac653acc2 100644 --- a/.github/workflows/coverage-linux-without-intl.yml +++ b/.github/workflows/coverage-linux-without-intl.yml @@ -52,13 +52,13 @@ jobs: with: persist-credentials: false - name: Set up Python ${{ env.PYTHON_VERSION }} - uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5.1.0 + uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0 with: python-version: ${{ env.PYTHON_VERSION }} - name: Set up sccache uses: mozilla-actions/sccache-action@89e9040de88b577a072e3760aaf59f585da083af # v0.0.5 with: - version: v0.8.0 + version: v0.8.1 - name: Environment Information run: npx envinfo - name: Install gcovr diff --git a/.github/workflows/coverage-linux.yml b/.github/workflows/coverage-linux.yml index d1c468fcc53..b7d0ed40284 100644 --- a/.github/workflows/coverage-linux.yml +++ b/.github/workflows/coverage-linux.yml @@ -52,13 +52,13 @@ jobs: with: persist-credentials: false - name: Set up Python ${{ env.PYTHON_VERSION }} - uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5.1.0 + uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0 with: python-version: ${{ env.PYTHON_VERSION }} - name: Set up sccache uses: mozilla-actions/sccache-action@89e9040de88b577a072e3760aaf59f585da083af # v0.0.5 with: - version: v0.8.0 + version: v0.8.1 - name: Environment Information run: npx envinfo - name: Install gcovr diff --git a/.github/workflows/coverage-windows.yml b/.github/workflows/coverage-windows.yml index e6b56ec753e..ae02da59d5f 100644 --- a/.github/workflows/coverage-windows.yml +++ b/.github/workflows/coverage-windows.yml @@ -5,7 +5,7 @@ on: types: [opened, synchronize, reopened, ready_for_review] paths: - lib/**/*.js - - Makefile + - vcbuild.bat - src/**/*.cc - src/**/*.h - test/** @@ -19,7 +19,7 @@ on: - main paths: - lib/**/*.js - - Makefile + - vcbuild.bat - src/**/*.cc - src/**/*.h - test/** @@ -49,7 +49,7 @@ jobs: with: persist-credentials: false - name: Set up Python ${{ env.PYTHON_VERSION }} - uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5.1.0 + uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0 with: python-version: ${{ env.PYTHON_VERSION }} - name: Install deps diff --git a/.github/workflows/daily-wpt-fyi.yml b/.github/workflows/daily-wpt-fyi.yml index 56aa214dca1..d68b27aee57 100644 --- a/.github/workflows/daily-wpt-fyi.yml +++ b/.github/workflows/daily-wpt-fyi.yml @@ -33,7 +33,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Set up Python ${{ env.PYTHON_VERSION }} - uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5.1.0 + uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0 with: python-version: ${{ env.PYTHON_VERSION }} - name: Environment Information @@ -45,7 +45,7 @@ jobs: run: echo "NIGHTLY=$(curl -s https://nodejs.org/download/nightly/index.json | jq -r '[.[] | select(.files[] | contains("linux-x64"))][0].version')" >> $GITHUB_ENV - name: Install Node.js id: setup-node - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 + uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 with: node-version: ${{ env.NIGHTLY || matrix.node-version }} check-latest: true @@ -121,7 +121,7 @@ jobs: run: cp wptreport.json wptreport-${{ steps.setup-node.outputs.node-version }}.json - name: Upload GitHub Actions artifact if: ${{ env.WPT_REPORT != '' }} - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 + uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0 with: path: out/wpt/wptreport-*.json name: WPT Report for ${{ steps.setup-node.outputs.node-version }} diff --git a/.github/workflows/daily.yml b/.github/workflows/daily.yml index 6d1fcd2bf7e..d020a1b98d0 100644 --- a/.github/workflows/daily.yml +++ b/.github/workflows/daily.yml @@ -19,7 +19,7 @@ jobs: with: persist-credentials: false - name: Use Node.js ${{ env.NODE_VERSION }} - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 + uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 with: node-version: ${{ env.NODE_VERSION }} - name: Environment Information diff --git a/.github/workflows/doc.yml b/.github/workflows/doc.yml index 139216b56ed..16844a46def 100644 --- a/.github/workflows/doc.yml +++ b/.github/workflows/doc.yml @@ -28,14 +28,14 @@ jobs: with: persist-credentials: false - name: Use Node.js ${{ env.NODE_VERSION }} - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 + uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 with: node-version: ${{ env.NODE_VERSION }} - name: Environment Information run: npx envinfo - name: Build run: NODE=$(command -v node) make doc-only - - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 + - uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0 with: name: docs path: out/doc diff --git a/.github/workflows/find-inactive-collaborators.yml b/.github/workflows/find-inactive-collaborators.yml index 3886f5622de..a5992fc8ad4 100644 --- a/.github/workflows/find-inactive-collaborators.yml +++ b/.github/workflows/find-inactive-collaborators.yml @@ -25,7 +25,7 @@ jobs: persist-credentials: false - name: Use Node.js ${{ env.NODE_VERSION }} - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 + uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 with: node-version: ${{ env.NODE_VERSION }} diff --git a/.github/workflows/find-inactive-tsc.yml b/.github/workflows/find-inactive-tsc.yml index 7cd8e2faf71..4fe3f5d4cb1 100644 --- a/.github/workflows/find-inactive-tsc.yml +++ b/.github/workflows/find-inactive-tsc.yml @@ -34,7 +34,7 @@ jobs: repository: nodejs/TSC - name: Use Node.js ${{ env.NODE_VERSION }} - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 + uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 with: node-version: ${{ env.NODE_VERSION }} diff --git a/.github/workflows/linters.yml b/.github/workflows/linters.yml index f050dabbb3d..bdda9b1de23 100644 --- a/.github/workflows/linters.yml +++ b/.github/workflows/linters.yml @@ -29,7 +29,7 @@ jobs: with: persist-credentials: false - name: Use Node.js ${{ env.NODE_VERSION }} - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 + uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 with: node-version: ${{ env.NODE_VERSION }} - name: Environment Information @@ -44,7 +44,7 @@ jobs: with: persist-credentials: false - name: Set up Python ${{ env.PYTHON_VERSION }} - uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5.1.0 + uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0 with: python-version: ${{ env.PYTHON_VERSION }} - name: Environment Information @@ -59,7 +59,7 @@ jobs: with: persist-credentials: false - name: Use Node.js ${{ env.NODE_VERSION }} - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 + uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 with: node-version: ${{ env.NODE_VERSION }} - name: Environment Information @@ -84,7 +84,7 @@ jobs: with: persist-credentials: false - name: Set up Python ${{ env.PYTHON_VERSION }} - uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5.1.0 + uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0 with: python-version: ${{ env.PYTHON_VERSION }} - name: Environment Information diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index f8be5980a05..866b3e36cac 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -33,7 +33,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 + uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs @@ -43,7 +43,7 @@ jobs: persist-credentials: false - name: Run analysis - uses: ossf/scorecard-action@dc50aa9510b46c811795eb24b2f1ba02a914e534 # v2.3.3 + uses: ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46 # v2.4.0 with: results_file: results.sarif results_format: sarif @@ -65,7 +65,7 @@ jobs: # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF # format to the repository Actions tab. - name: Upload artifact - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 + uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0 with: name: SARIF file path: results.sarif @@ -73,6 +73,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: Upload to code-scanning - uses: github/codeql-action/upload-sarif@b611370bb5703a7efb587f9d136a52ea24c5c38c # v3.25.11 + uses: github/codeql-action/upload-sarif@4dd16135b69a43b6c8efb853346f8437d92d3c93 # v3.26.6 with: sarif_file: results.sarif diff --git a/.github/workflows/test-asan.yml b/.github/workflows/test-asan.yml index f2767253aa4..64317d335c8 100644 --- a/.github/workflows/test-asan.yml +++ b/.github/workflows/test-asan.yml @@ -51,13 +51,13 @@ jobs: with: persist-credentials: false - name: Set up Python ${{ env.PYTHON_VERSION }} - uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5.1.0 + uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0 with: python-version: ${{ env.PYTHON_VERSION }} - name: Set up sccache uses: mozilla-actions/sccache-action@89e9040de88b577a072e3760aaf59f585da083af # v0.0.5 with: - version: v0.8.0 + version: v0.8.1 - name: Environment Information run: npx envinfo - name: Build diff --git a/.github/workflows/test-internet.yml b/.github/workflows/test-internet.yml index 784e057fcd2..9d8458cbc3b 100644 --- a/.github/workflows/test-internet.yml +++ b/.github/workflows/test-internet.yml @@ -48,7 +48,7 @@ jobs: with: persist-credentials: false - name: Set up Python ${{ env.PYTHON_VERSION }} - uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5.1.0 + uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0 with: python-version: ${{ env.PYTHON_VERSION }} - name: Environment Information diff --git a/.github/workflows/test-linux.yml b/.github/workflows/test-linux.yml index 68df8a8534e..9d1cb796007 100644 --- a/.github/workflows/test-linux.yml +++ b/.github/workflows/test-linux.yml @@ -41,13 +41,13 @@ jobs: with: persist-credentials: false - name: Set up Python ${{ env.PYTHON_VERSION }} - uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5.1.0 + uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0 with: python-version: ${{ env.PYTHON_VERSION }} - name: Set up sccache uses: mozilla-actions/sccache-action@89e9040de88b577a072e3760aaf59f585da083af # v0.0.5 with: - version: v0.8.0 + version: v0.8.1 - name: Environment Information run: npx envinfo - name: Build diff --git a/.github/workflows/test-macos.yml b/.github/workflows/test-macos.yml index 06549a9e3be..ecbd3184a1c 100644 --- a/.github/workflows/test-macos.yml +++ b/.github/workflows/test-macos.yml @@ -48,13 +48,13 @@ jobs: with: persist-credentials: false - name: Set up Python ${{ env.PYTHON_VERSION }} - uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5.1.0 + uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0 with: python-version: ${{ env.PYTHON_VERSION }} - name: Set up sccache uses: mozilla-actions/sccache-action@89e9040de88b577a072e3760aaf59f585da083af # v0.0.5 with: - version: v0.8.0 + version: v0.8.1 - name: Environment Information run: npx envinfo # The `npm ci` for this step fails a lot as part of the Test step. Run it @@ -65,6 +65,20 @@ jobs: # information.) - name: tools/doc/node_modules workaround run: make tools/doc/node_modules + # This is needed due to https://github.com/nodejs/build/issues/3878 + - name: Cleanup + run: | + echo "::group::Free space before cleanup" + df -h + echo "::endgroup::" + echo "::group::Cleaned Files" + + sudo rm -rfv /Users/runner/Library/Android/sdk + + echo "::endgroup::" + echo "::group::Free space after cleanup" + df -h + echo "::endgroup::" - name: Build run: make build-ci -j$(getconf _NPROCESSORS_ONLN) V=1 CONFIG_FLAGS="--error-on-warn" - name: Test diff --git a/.github/workflows/test-ubsan.yml b/.github/workflows/test-ubsan.yml index 3295f1ce59a..f62f0a39072 100644 --- a/.github/workflows/test-ubsan.yml +++ b/.github/workflows/test-ubsan.yml @@ -52,13 +52,13 @@ jobs: run: | echo "UBSAN_OPTIONS=suppressions=$GITHUB_WORKSPACE/suppressions.supp" >> $GITHUB_ENV - name: Set up Python ${{ env.PYTHON_VERSION }} - uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5.1.0 + uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0 with: python-version: ${{ env.PYTHON_VERSION }} - name: Set up sccache uses: mozilla-actions/sccache-action@89e9040de88b577a072e3760aaf59f585da083af # v0.0.5 with: - version: v0.8.0 + version: v0.8.1 - name: Environment Information run: npx envinfo - name: Build diff --git a/.github/workflows/tools.yml b/.github/workflows/tools.yml index d8ceea2bd95..cf87745ebc1 100644 --- a/.github/workflows/tools.yml +++ b/.github/workflows/tools.yml @@ -303,7 +303,7 @@ jobs: persist-credentials: false - name: Set up Python ${{ env.PYTHON_VERSION }} if: matrix.id == 'icu' && (github.event_name == 'schedule' || inputs.id == 'all' || inputs.id == matrix.id) - uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5.1.0 + uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0 with: python-version: ${{ env.PYTHON_VERSION }} - run: ${{ matrix.run }} diff --git a/.github/workflows/update-v8.yml b/.github/workflows/update-v8.yml index b47c78356e2..8aca91c5444 100644 --- a/.github/workflows/update-v8.yml +++ b/.github/workflows/update-v8.yml @@ -30,7 +30,7 @@ jobs: ~/.npm key: ${{ runner.os }}-build-${{ env.cache-name }} - name: Install Node.js - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 + uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 with: node-version: ${{ env.NODE_VERSION }} - name: Install @node-core/utils @@ -45,7 +45,7 @@ jobs: cat temp-output tail -n1 temp-output | grep "NEW_VERSION=" >> "$GITHUB_ENV" || true rm temp-output - - uses: peter-evans/create-pull-request@c5a7806660adbe173f04e3e038b0ccdcd758773c # v6.1.0 + - uses: peter-evans/create-pull-request@8867c4aba1b742c39f8d0ba35429c2dfa4b6cb20 # v7.0.1 # Creates a PR or update the Action's existing PR, or # no-op if the base branch is already up-to-date. with: diff --git a/BUILDING.md b/BUILDING.md index 67ab9625503..3e3bf7c56de 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -19,7 +19,7 @@ file a new issue. * [OpenSSL asm support](#openssl-asm-support) * [Previous versions of this document](#previous-versions-of-this-document) * [Building N|Solid on supported platforms](#building-nsolid-on-supported-platforms) - * [Note about Python](#note-about-python) + * [Prerequisites](#prerequisites) * [Unix and macOS](#unix-and-macos) * [Unix prerequisites](#unix-prerequisites) * [macOS prerequisites](#macos-prerequisites) @@ -33,7 +33,7 @@ file a new issue. * [Speeding up frequent rebuilds when developing](#speeding-up-frequent-rebuilds-when-developing) * [Troubleshooting Unix and macOS builds](#troubleshooting-unix-and-macos-builds) * [Windows](#windows) - * [Prerequisites](#prerequisites) + * [Windows Prerequisites](#windows-prerequisites) * [Option 1: Manual install](#option-1-manual-install) * [Option 2: Automated install with Boxstarter](#option-2-automated-install-with-boxstarter) * [Building N|Solid](#building-nsolid-2) @@ -122,7 +122,7 @@ platforms. This is true regardless of entries in the table below. -[^1]: Older kernel versions may work. However official N|Solid release +[^1]: Older kernel versions may work. However, official N|Solid release binaries are [built on RHEL 8 systems](#official-binary-platforms-and-toolchains) with kernel 4.18. @@ -209,17 +209,17 @@ For use of AVX2, * llvm version 3.3 or higher * nasm version 2.10 or higher in Windows -Please refer to - for details. +Please refer to for details. If compiling without one of the above, use `configure` with the `--openssl-no-asm` flag. Otherwise, `configure` will fail. ## Building N|Solid on supported platforms -### Note about Python +### Prerequisites -The N|Solid project supports Python >= 3 for building and testing. +* Python support: the N|Solid project supports Python >= 3.6 for building and testing. +* Memory: at least 8GB of RAM is typically required when compiling with 4 parallel jobs (e.g: `make -j4`) ### Unix and macOS @@ -563,6 +563,11 @@ rebuild may take a lot more time than previous builds. Additionally, ran `./configure` with non-default options (such as `--debug`), you will need to run it again before invoking `make -j4`. +If you received the error `nodejs g++ fatal error compilation terminated cc1plus` +during compilation, this is likely a memory issue and you should either provide +more RAM or create swap space to accommodate toolchain requirements or reduce +the number of parallel build tasks (`-j`). + ### Windows #### Prerequisites @@ -589,7 +594,9 @@ Optional requirements to build the MSI installer package: Optional requirements for compiling for Windows 10 on ARM (ARM64): -* Visual Studio 15.9.0 or newer +* Visual Studio 17.6.0 or newer + > **Note:** There is [a bug](https://github.com/nodejs/build/issues/3739) in `17.10.x` + > preventing Node.js from compiling. * Visual Studio optional components * Visual C++ compilers and libraries for ARM64 * Visual C++ ATL for ARM64 @@ -637,8 +644,8 @@ architecture supports \[arm, arm64/aarch64, x86, x86\_64]. ## `Intl` (ECMA-402) support -[Intl](https://github.com/nodesource/nsolid/blob/HEAD/doc/api/intl.md) support -is enabled by default. +[Intl](doc/api/intl.md) support is +enabled by default. ### Build with full ICU support (all locales supported by ICU) @@ -703,7 +710,7 @@ that works for both your host and target environments. ### Build with a specific ICU You can find other ICU releases at -[the ICU homepage](http://site.icu-project.org/download). +[the ICU homepage](https://icu.unicode.org/download). Download the file named something like `icu4c-**##.#**-src.tgz` (or `.zip`). @@ -734,7 +741,7 @@ From a tarball URL: #### Windows First unpack latest ICU to `deps/icu` -[icu4c-**##.#**-src.tgz](http://site.icu-project.org/download) (or `.zip`) +[icu4c-**##.#**-src.tgz](https://icu.unicode.org/download) (or `.zip`) as `deps/icu` (You'll have: `deps/icu/source/...`) ```powershell @@ -757,10 +764,10 @@ configure option: ## Building N|Solid with FIPS-compliant OpenSSL N|Solid supports FIPS when statically or dynamically linked with OpenSSL 3 via -[OpenSSL's provider model](https://www.openssl.org/docs/man3.0/man7/crypto.html#OPENSSL-PROVIDERS). +[OpenSSL's provider model](https://docs.openssl.org/3.0/man7/crypto/#OPENSSL-PROVIDERS). It is not necessary to rebuild N|Solid to enable support for FIPS. -See [FIPS mode](./doc/api/crypto.md#fips-mode) for more information on how to +See [FIPS mode](doc/api/crypto.md#fips-mode) for more information on how to enable FIPS support in N|Solid. ## Building N|Solid with external core modules diff --git a/CHANGELOG.md b/CHANGELOG.md index e99ca70d47b..ff92e5dc2bf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,7 +35,8 @@ release. -20.17.0
+20.18.0
+20.17.0
20.16.0
20.15.1
20.15.0
diff --git a/LICENSE b/LICENSE index 51d9d971c68..3f6cacb6785 100644 --- a/LICENSE +++ b/LICENSE @@ -106,16 +106,16 @@ The externally maintained libraries used by Node.js are: - cjs-module-lexer, located at deps/cjs-module-lexer, is licensed as follows: """ - MIT License - ----------- - - Copyright (C) 2018-2020 Guy Bedford - - Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + MIT License + ----------- + + Copyright (C) 2018-2020 Guy Bedford + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ - ittapi, located at deps/v8/third_party/ittapi, is licensed as follows: diff --git a/Makefile b/Makefile index a5fa4973962..a4ecb7865b8 100644 --- a/Makefile +++ b/Makefile @@ -238,8 +238,10 @@ coverage-clean: $(RM) -r node_modules $(RM) -r gcovr $(RM) -r coverage/tmp - $(FIND) out/$(BUILDTYPE)/obj.target \( -name "*.gcda" -o -name "*.gcno" \) \ - -type f -exec $(RM) {} \; + @if [ -d "out/Release/obj.target" ]; then \ + $(FIND) out/$(BUILDTYPE)/obj.target \( -name "*.gcda" -o -name "*.gcno" \) \ + -type f -exec $(RM) {};\ + fi .PHONY: coverage # Build and test with code coverage reporting. HTML coverage reports will be @@ -263,7 +265,9 @@ coverage-build-js: .PHONY: coverage-test coverage-test: coverage-build - $(FIND) out/$(BUILDTYPE)/obj.target -name "*.gcda" -type f -exec $(RM) {} \; + @if [ -d "out/Release/obj.target" ]; then \ + $(FIND) out/$(BUILDTYPE)/obj.target -name "*.gcda" -type f -exec $(RM) {}; \ + fi -NODE_V8_COVERAGE=coverage/tmp \ TEST_CI_ARGS="$(TEST_CI_ARGS) --type=coverage" $(MAKE) $(COVTESTS) $(MAKE) coverage-report-js @@ -1540,8 +1544,8 @@ cpplint: lint-cpp # Try with '--system' if it fails without; the system may have set '--user' lint-py-build: $(info Pip installing ruff on $(shell $(PYTHON) --version)...) - $(PYTHON) -m pip install --upgrade --target tools/pip/site-packages ruff==0.4.5 || \ - $(PYTHON) -m pip install --upgrade --system --target tools/pip/site-packages ruff==0.4.5 + $(PYTHON) -m pip install --upgrade --target tools/pip/site-packages ruff==0.5.2 || \ + $(PYTHON) -m pip install --upgrade --system --target tools/pip/site-packages ruff==0.5.2 .PHONY: lint-py ifneq ("","$(wildcard tools/pip/site-packages/ruff)") diff --git a/benchmark/README.md b/benchmark/README.md index 96bd0318465..2f52a44f251 100644 --- a/benchmark/README.md +++ b/benchmark/README.md @@ -40,6 +40,7 @@ directories. * `_cli.R`: parses the command line arguments passed to `compare.R` * `_http-benchmarkers.js`: selects and runs external tools for benchmarking the `http` subsystem. +* `bar.R`: R script for visualizing the output of benchmarks with bar plots. * `common.js`: see [Common API](#common-api). * `compare.js`: command line tool for comparing performance between different Node.js binaries. diff --git a/benchmark/_cli.js b/benchmark/_cli.js index 33ba2e0963f..583da8f6b20 100644 --- a/benchmark/_cli.js +++ b/benchmark/_cli.js @@ -33,6 +33,7 @@ function CLI(usage, settings) { let mode = 'both'; // Possible states are: [both, option, item] for (const arg of process.argv.slice(2)) { + if (arg === '--help') this.abort(usage); if (arg === '--') { // Only items can follow -- mode = 'item'; diff --git a/benchmark/assert/match.js b/benchmark/assert/match.js new file mode 100644 index 00000000000..fab86a23944 --- /dev/null +++ b/benchmark/assert/match.js @@ -0,0 +1,21 @@ +'use strict'; + +const common = require('../common.js'); +const assert = require('assert'); + +const bench = common.createBenchmark(main, { + n: [25, 2e7], + method: ['match', 'doesNotMatch'], +}); + +function main({ n, method }) { + const fn = assert[method]; + const actual = 'Example of string that will match'; + const expected = method === 'match' ? /will match/ : /will not match/; + + bench.start(); + for (let i = 0; i < n; ++i) { + fn(actual, expected); + } + bench.end(n); +} diff --git a/benchmark/assert/rejects.js b/benchmark/assert/rejects.js new file mode 100644 index 00000000000..43ec500177a --- /dev/null +++ b/benchmark/assert/rejects.js @@ -0,0 +1,27 @@ +'use strict'; + +const common = require('../common.js'); +const assert = require('assert'); + +const bench = common.createBenchmark(main, { + n: [25, 2e5], + method: ['rejects', 'doesNotReject'], +}); + +async function main({ n, method }) { + const fn = assert[method]; + const shouldReject = method === 'rejects'; + + bench.start(); + for (let i = 0; i < n; ++i) { + await fn(async () => { + const err = new Error(`assert.${method}`); + if (shouldReject) { + throw err; + } else { + return err; + } + }); + } + bench.end(n); +} diff --git a/benchmark/assert/strictequal.js b/benchmark/assert/strictequal.js new file mode 100644 index 00000000000..21a77f0472c --- /dev/null +++ b/benchmark/assert/strictequal.js @@ -0,0 +1,43 @@ +'use strict'; + +const common = require('../common.js'); +const assert = require('assert'); + +const bench = common.createBenchmark(main, { + n: [25, 2e5], + type: ['string', 'object', 'number'], + method: ['strictEqual', 'notStrictEqual'], +}); + +function main({ type, n, method }) { + const fn = assert[method]; + let actual, expected; + switch (type) { + case 'string': + actual = expected = 'Hello World'; + if (method === 'notStrictEqual') { + expected += 'bar'; + } + break; + case 'object': + actual = expected = { a: 'Hello', b: 'World' }; + if (method === 'notStrictEqual') { + expected = { a: 'Hello', b: 'World' }; + } + break; + case 'number': + actual = expected = 1e9; + if (method === 'notStrictEqual') { + expected += 1; + } + break; + default: + throw new Error('Unexpected type'); + } + + bench.start(); + for (let i = 0; i < n; ++i) { + fn(actual, expected); + } + bench.end(n); +} diff --git a/benchmark/assert/throws.js b/benchmark/assert/throws.js new file mode 100644 index 00000000000..9c070ac8281 --- /dev/null +++ b/benchmark/assert/throws.js @@ -0,0 +1,27 @@ +'use strict'; + +const common = require('../common.js'); +const assert = require('assert'); + +const bench = common.createBenchmark(main, { + n: [25, 2e5], + method: ['throws', 'doesNotThrow'], +}); + +function main({ n, method }) { + const fn = assert[method]; + const shouldThrow = method === 'throws'; + + bench.start(); + for (let i = 0; i < n; ++i) { + fn(() => { + const err = new Error(`assert.${method}`); + if (shouldThrow) { + throw err; + } else { + return err; + } + }); + } + bench.end(n); +} diff --git a/benchmark/buffers/buffer-atob.js b/benchmark/buffers/buffer-atob.js index 2cc20759e3f..ee986e49e5e 100644 --- a/benchmark/buffers/buffer-atob.js +++ b/benchmark/buffers/buffer-atob.js @@ -16,5 +16,5 @@ function main({ n, size }) { out += atob(input).length; } bench.end(n); - assert(out > 0); + assert.ok(out > 0); } diff --git a/benchmark/buffers/buffer-btoa.js b/benchmark/buffers/buffer-btoa.js index 3867d5890b1..5bfe7cff3db 100644 --- a/benchmark/buffers/buffer-btoa.js +++ b/benchmark/buffers/buffer-btoa.js @@ -16,5 +16,5 @@ function main({ n, size }) { out += btoa(input).length; } bench.end(n); - assert(out > 0); + assert.ok(out > 0); } diff --git a/benchmark/buffers/buffer-isascii.js b/benchmark/buffers/buffer-isascii.js new file mode 100644 index 00000000000..d118049fa5e --- /dev/null +++ b/benchmark/buffers/buffer-isascii.js @@ -0,0 +1,23 @@ +'use strict'; + +const common = require('../common.js'); +const buffer = require('node:buffer'); +const assert = require('node:assert'); + +const bench = common.createBenchmark(main, { + n: [2e7], + length: ['short', 'long'], + input: ['hello world'], +}); + + +function main({ n, input }) { + const normalizedInput = input === 'short' ? input : input.repeat(200); + const encoder = new TextEncoder(); + const buff = encoder.encode(normalizedInput); + bench.start(); + for (let i = 0; i < n; ++i) { + assert.ok(buffer.isAscii(buff)); + } + bench.end(n); +} diff --git a/benchmark/buffers/buffer-isutf8.js b/benchmark/buffers/buffer-isutf8.js new file mode 100644 index 00000000000..dac1e07b30b --- /dev/null +++ b/benchmark/buffers/buffer-isutf8.js @@ -0,0 +1,23 @@ +'use strict'; + +const common = require('../common.js'); +const buffer = require('node:buffer'); +const assert = require('node:assert'); + +const bench = common.createBenchmark(main, { + n: [2e7], + length: ['short', 'long'], + input: ['regular string', '∀x∈ℝ: ⌈x⌉ = −⌊−x⌋'], +}); + + +function main({ n, input, length }) { + const normalizedInput = length === 'short' ? input : input.repeat(300); + const encoder = new TextEncoder(); + const buff = encoder.encode(normalizedInput); + bench.start(); + for (let i = 0; i < n; ++i) { + assert.ok(buffer.isUtf8(buff)); + } + bench.end(n); +} diff --git a/benchmark/buffers/buffer-iterate.js b/benchmark/buffers/buffer-iterate.js index 57a15e42249..c1c4f691750 100644 --- a/benchmark/buffers/buffer-iterate.js +++ b/benchmark/buffers/buffer-iterate.js @@ -31,7 +31,7 @@ function main({ size, type, method, n }) { function benchFor(buffer, n) { for (let k = 0; k < n; k++) { for (let i = 0; i < buffer.length; i++) { - assert(buffer[i] === 0); + assert.strictEqual(buffer[i], 0); } } } @@ -39,7 +39,7 @@ function benchFor(buffer, n) { function benchForOf(buffer, n) { for (let k = 0; k < n; k++) { for (const b of buffer) { - assert(b === 0); + assert.strictEqual(b, 0); } } } @@ -50,7 +50,7 @@ function benchIterator(buffer, n) { let cur = iter.next(); while (!cur.done) { - assert(cur.value === 0); + assert.strictEqual(cur.value, 0); cur = iter.next(); } diff --git a/benchmark/buffers/buffer-transcode.js b/benchmark/buffers/buffer-transcode.js new file mode 100644 index 00000000000..cbb3b2e9b16 --- /dev/null +++ b/benchmark/buffers/buffer-transcode.js @@ -0,0 +1,35 @@ +'use strict'; +const common = require('../common.js'); +const assert = require('node:assert'); +const buffer = require('node:buffer'); + +const hasIntl = !!process.config.variables.v8_enable_i18n_support; +const encodings = ['latin1', 'ascii', 'ucs2', 'utf8']; + +if (!hasIntl) { + console.log('Skipping: `transcode` is only available on platforms that support i18n`'); + process.exit(0); +} + +const bench = common.createBenchmark(main, { + fromEncoding: encodings, + toEncoding: encodings, + length: [1, 10, 1000], + n: [1e5], +}, { + combinationFilter(p) { + return !(p.fromEncoding === 'ucs2' && p.toEncoding === 'utf8'); + }, +}); + +function main({ n, fromEncoding, toEncoding, length }) { + const input = Buffer.from('a'.repeat(length)); + let out = 0; + bench.start(); + for (let i = 0; i < n; i++) { + const dest = buffer.transcode(input, fromEncoding, toEncoding); + out += dest.buffer.byteLength; + } + bench.end(n); + assert.ok(out >= 0); +} diff --git a/benchmark/common.js b/benchmark/common.js index efe21e87157..b4978e8e140 100644 --- a/benchmark/common.js +++ b/benchmark/common.js @@ -22,27 +22,36 @@ class Benchmark { this.name = require.main.filename.slice(__dirname.length + 1); // Execution arguments i.e. flags used to run the jobs - this.flags = process.env.NODE_BENCHMARK_FLAGS ? - process.env.NODE_BENCHMARK_FLAGS.split(/\s+/) : - []; + this.flags = process.env.NODE_BENCHMARK_FLAGS?.split(/\s+/) ?? []; // Parse job-specific configuration from the command line arguments const argv = process.argv.slice(2); const parsed_args = this._parseArgs(argv, configs, options); + this.options = parsed_args.cli; this.extra_options = parsed_args.extra; + this.combinationFilter = typeof options.combinationFilter === 'function' ? options.combinationFilter : allow; + + if (options.byGroups) { + this.queue = []; + const groupNames = process.env.NODE_RUN_BENCHMARK_GROUPS?.split(',') ?? Object.keys(configs); + + for (const groupName of groupNames) { + const config = { ...configs[groupName][0], group: groupName }; + const parsed_args = this._parseArgs(argv, config, options); + + this.options = parsed_args.cli; + this.extra_options = parsed_args.extra; + this.queue = this.queue.concat(this._queue(this.options)); + } + } else { + this.queue = this._queue(this.options); + } + if (options.flags) { this.flags = this.flags.concat(options.flags); } - if (typeof options.combinationFilter === 'function') - this.combinationFilter = options.combinationFilter; - else - this.combinationFilter = allow; - - // The configuration list as a queue of jobs - this.queue = this._queue(this.options); - if (this.queue.length === 0) return; diff --git a/benchmark/cpu.sh b/benchmark/cpu.sh new file mode 100755 index 00000000000..9c9dd7fa4dd --- /dev/null +++ b/benchmark/cpu.sh @@ -0,0 +1,24 @@ +#!/bin/sh + +CPUPATH=/sys/devices/system/cpu + +MAXID=$(cat $CPUPATH/present | awk -F- '{print $NF}') + +set_governor() { + echo "Setting CPU frequency governor to \"$1\"" + i=0 + while [ "$i" -le "$MAXID" ]; do + echo "$1" > "$CPUPATH/cpu$i/cpufreq/scaling_governor" + i=$((i + 1)) + done +} + +case "$1" in + fast | performance) + set_governor "performance" + ;; + *) + echo "Usage: $0 fast" + exit 1 + ;; +esac diff --git a/benchmark/diagnostics_channel/publish.js b/benchmark/diagnostics_channel/publish.js index 3a30012ba69..6d8e40a6b73 100644 --- a/benchmark/diagnostics_channel/publish.js +++ b/benchmark/diagnostics_channel/publish.js @@ -1,29 +1,58 @@ 'use strict'; const common = require('../common.js'); -const dc = require('diagnostics_channel'); +const dc = require('node:diagnostics_channel'); const bench = common.createBenchmark(main, { n: [1e8], + checkSubscribers: [1, 0], + objSize: [10, 1e2, 1e3], subscribers: [0, 1, 10], }); function noop() {} -function main({ n, subscribers }) { +function createObj(size) { + return Array.from({ length: size }, (n) => ({ + foo: 'yarp', + nope: { + bar: '123', + a: [1, 2, 3], + baz: n, + c: {}, + b: [], + }, + })); +} + +function main({ n, subscribers, checkSubscribers, objSize }) { const channel = dc.channel('test'); for (let i = 0; i < subscribers; i++) { channel.subscribe(noop); } - const data = { - foo: 'bar', + const publishWithCheck = () => { + const data = createObj(objSize); + bench.start(); + for (let i = 0; i < n; i++) { + if (channel.hasSubscribers) { + channel.publish(data); + } + } + bench.end(n); }; - bench.start(); - for (let i = 0; i < n; i++) { - if (channel.hasSubscribers) { + const publishWithoutCheck = () => { + const data = createObj(objSize); + bench.start(); + for (let i = 0; i < n; i++) { channel.publish(data); } + bench.end(n); + }; + + if (checkSubscribers) { + publishWithCheck(); + } else { + publishWithoutCheck(); } - bench.end(n); } diff --git a/benchmark/esm/require-esm.js b/benchmark/esm/require-esm.js new file mode 100644 index 00000000000..8734d0d0bc0 --- /dev/null +++ b/benchmark/esm/require-esm.js @@ -0,0 +1,79 @@ +'use strict'; + +const common = require('../common'); +const fs = require('fs'); +const tmpdir = require('../../test/common/tmpdir'); +const path = require('path'); +const assert = require('assert'); + +const bench = common.createBenchmark(main, { + type: ['all', 'access', 'load'], + exports: ['default', 'named'], + n: [1000], +}, { + flags: ['--experimental-require-module', '--no-warnings'], +}); + +function prepare(count, useDefault) { + tmpdir.refresh(); + const dir = tmpdir.resolve('modules'); + fs.mkdirSync(dir, { recursive: true }); + let mainSource = ''; + let useSource = 'exports.access = function() { return 0'; + for (let i = 0; i < count; ++i) { + let modSource = `const value${i} = 1;\n`; + if (useDefault) { + modSource += `export default { value${i} }\n`; + } else { + modSource += `export { value${i} };\n`; + } + const filename = `mod${i}.mjs`; + fs.writeFileSync( + path.resolve(dir, filename), + modSource, + 'utf8', + ); + mainSource += `const mod${i} = require('./modules/${filename}');\n`; + if (useDefault) { + useSource += ` + mod${i}.default.value${i}`; + } else { + useSource += ` + mod${i}.value${i}`; + } + } + useSource += '; };\n'; + const script = tmpdir.resolve('main.js'); + fs.writeFileSync(script, mainSource + useSource, 'utf8'); + return script; +} + +function main({ n, exports, type }) { + const script = prepare(n, exports === 'default'); + switch (type) { + case 'all': { + bench.start(); + const result = require(script).access(); + bench.end(n); + assert.strictEqual(result, n); + break; + } + case 'access': { + const { access } = require(script); + bench.start(); + let result = access(); + for (let i = 0; i < 99; ++i) { + result = access(); + } + bench.end(n * 100); + assert.strictEqual(result, n); + break; + } + case 'load': { + bench.start(); + const { access } = require(script); + bench.end(n); + const result = access(); + assert.strictEqual(result, n); + break; + } + } +} diff --git a/benchmark/fs/bench-accessSync.js b/benchmark/fs/bench-accessSync.js index bf0718634b1..0be0ca799d3 100644 --- a/benchmark/fs/bench-accessSync.js +++ b/benchmark/fs/bench-accessSync.js @@ -10,6 +10,7 @@ fs.writeFileSync(tmpfile, 'this-is-for-a-benchmark', 'utf8'); const bench = common.createBenchmark(main, { type: ['existing', 'non-existing', 'non-flat-existing'], + method: ['access', 'accessSync'], n: [1e5], }); @@ -23,7 +24,17 @@ function runBench(n, path) { } } -function main({ n, type }) { +function runAsyncBench(n, path) { + (function r(cntr, path) { + if (cntr-- <= 0) + return bench.end(n); + fs.access(path, () => { + r(cntr, path); + }); + })(n, path); +} + +function main({ n, type, method }) { let path; switch (type) { @@ -39,10 +50,19 @@ function main({ n, type }) { default: new Error('Invalid type'); } - // warmup - runBench(n, path); - bench.start(); - runBench(n, path); - bench.end(n); + if (method === 'access') { + // Warmup the filesystem - it doesn't need to use the async method + runBench(n, path); + + bench.start(); + runAsyncBench(n, path); + } else { + // warmup + runBench(n, path); + + bench.start(); + runBench(n, path); + bench.end(n); + } } diff --git a/benchmark/fs/bench-chownSync.js b/benchmark/fs/bench-chownSync.js index d07f3b65949..18e2bd35d52 100644 --- a/benchmark/fs/bench-chownSync.js +++ b/benchmark/fs/bench-chownSync.js @@ -45,7 +45,7 @@ function main({ n, type, method }) { } } bench.end(n); - assert(hasError); + assert.ok(hasError); break; } default: diff --git a/benchmark/fs/bench-cpSync.js b/benchmark/fs/bench-cpSync.js index f3ad9c26b35..5ee11689e47 100644 --- a/benchmark/fs/bench-cpSync.js +++ b/benchmark/fs/bench-cpSync.js @@ -12,7 +12,7 @@ const bench = common.createBenchmark(main, { function main({ n }) { tmpdir.refresh(); - const options = { force: true, recursive: true }; + const options = { recursive: true }; const src = path.join(__dirname, '../../test/fixtures/copy'); const dest = tmpdir.resolve(`${process.pid}/subdir/cp-bench-${process.pid}`); bench.start(); diff --git a/benchmark/fs/bench-linkSync.js b/benchmark/fs/bench-linkSync.js index 7c3ef292919..ead39c338fe 100644 --- a/benchmark/fs/bench-linkSync.js +++ b/benchmark/fs/bench-linkSync.js @@ -41,7 +41,7 @@ function main({ n, type }) { } } bench.end(n); - assert(hasError); + assert.ok(hasError); break; } default: diff --git a/benchmark/fs/bench-readlinkSync.js b/benchmark/fs/bench-readlinkSync.js index 15c22273e55..9b3bbceb42e 100644 --- a/benchmark/fs/bench-readlinkSync.js +++ b/benchmark/fs/bench-readlinkSync.js @@ -30,7 +30,7 @@ function main({ n, type }) { returnValue = fs.readlinkSync(tmpdir.resolve(`.readlink-sync-${i}`), { encoding: 'utf8' }); } bench.end(n); - assert(returnValue); + assert.ok(returnValue); break; } @@ -45,7 +45,7 @@ function main({ n, type }) { } } bench.end(n); - assert(hasError); + assert.ok(hasError); break; } default: diff --git a/benchmark/fs/bench-readvSync.js b/benchmark/fs/bench-readvSync.js index c163429b5f6..21f61ba7e9b 100644 --- a/benchmark/fs/bench-readvSync.js +++ b/benchmark/fs/bench-readvSync.js @@ -49,7 +49,7 @@ function main({ n, type }) { } bench.end(n); - assert(hasError); + assert.ok(hasError); break; } default: diff --git a/benchmark/fs/bench-renameSync.js b/benchmark/fs/bench-renameSync.js index 9f9f5e4e84c..2c4c5a39eeb 100644 --- a/benchmark/fs/bench-renameSync.js +++ b/benchmark/fs/bench-renameSync.js @@ -23,7 +23,7 @@ function main({ n, type }) { } } bench.end(n); - assert(hasError); + assert.ok(hasError); break; } case 'valid': { diff --git a/benchmark/fs/bench-symlinkSync.js b/benchmark/fs/bench-symlinkSync.js index 5bf4e0e5077..92ceb3579a4 100644 --- a/benchmark/fs/bench-symlinkSync.js +++ b/benchmark/fs/bench-symlinkSync.js @@ -42,7 +42,7 @@ function main({ n, type }) { } } bench.end(n); - assert(hasError); + assert.ok(hasError); break; } default: diff --git a/benchmark/fs/bench-writevSync.js b/benchmark/fs/bench-writevSync.js index 596359c6750..bdcd0919050 100644 --- a/benchmark/fs/bench-writevSync.js +++ b/benchmark/fs/bench-writevSync.js @@ -30,7 +30,7 @@ function main({ n, type }) { } bench.end(n); - assert(result); + assert.ok(result); fs.closeSync(fd); break; case 'invalid': { @@ -46,7 +46,7 @@ function main({ n, type }) { } bench.end(n); - assert(hasError); + assert.ok(hasError); break; } default: diff --git a/benchmark/fs/read-stream-throughput.js b/benchmark/fs/read-stream-throughput.js index 9d4431d360e..e3705b6c327 100644 --- a/benchmark/fs/read-stream-throughput.js +++ b/benchmark/fs/read-stream-throughput.js @@ -67,7 +67,7 @@ function main(conf) { } function runTest(filesize, highWaterMark, encoding, n) { - assert(fs.statSync(filename).size === filesize * n); + assert.strictEqual(fs.statSync(filename).size, filesize * n); const rs = fs.createReadStream(filename, { highWaterMark, encoding, diff --git a/benchmark/http/headers.js b/benchmark/http/headers.js index e995f380cef..62612d9fda1 100644 --- a/benchmark/http/headers.js +++ b/benchmark/http/headers.js @@ -4,10 +4,22 @@ const common = require('../common.js'); const http = require('http'); const bench = common.createBenchmark(main, { - n: [10, 600], - len: [1, 100], - duration: 5, -}); + fewHeaders: { + n: [10], + len: [1, 5], + duration: 5, + }, + mediumHeaders: { + n: [50], + len: [1, 10], + duration: 5, + }, + manyHeaders: { + n: [600], + len: [1, 100], + duration: 5, + }, +}, { byGroups: true }); function main({ len, n, duration }) { const headers = { @@ -15,10 +27,9 @@ function main({ len, n, duration }) { 'Transfer-Encoding': 'chunked', }; - // TODO(BridgeAR): Change this benchmark to use grouped arguments when - // implemented. https://github.com/nodejs/node/issues/26425 - const Is = [ ...Array(Math.max(n / len, 1)).keys() ]; - const Js = [ ...Array(len).keys() ]; + const Is = [...Array(n / len).keys()]; + const Js = [...Array(len).keys()]; + for (const i of Is) { headers[`foo${i}`] = Js.map(() => `some header value ${i}`); } @@ -27,6 +38,7 @@ function main({ len, n, duration }) { res.writeHead(200, headers); res.end(); }); + server.listen(0, () => { bench.http({ path: '/', diff --git a/benchmark/misc/startup-cli-version.js b/benchmark/misc/startup-cli-version.js index 0c8d4848b46..d2c1bc3db66 100644 --- a/benchmark/misc/startup-cli-version.js +++ b/benchmark/misc/startup-cli-version.js @@ -18,12 +18,12 @@ const availableCli = [ ].filter((cli) => existsSync(path.resolve(__dirname, '../../', cli))); const bench = common.createBenchmark(main, { cli: availableCli, - count: [30], + n: [30], }); function spawnProcess(cli, bench, state) { const cmd = process.execPath || process.argv[0]; - while (state.finished < state.count) { + while (state.finished < state.n) { const child = spawnSync(cmd, [cli, '--version'], { env: { npm_config_loglevel: 'silent', ...process.env }, }); @@ -41,15 +41,15 @@ function spawnProcess(cli, bench, state) { bench.start(); } - if (state.finished === state.count) { - bench.end(state.count); + if (state.finished === state.n) { + bench.end(state.n); } } } -function main({ count, cli }) { +function main({ n, cli }) { cli = path.resolve(__dirname, '../../', cli); const warmup = 3; - const state = { count, finished: -warmup }; + const state = { n, finished: -warmup }; spawnProcess(cli, bench, state); } diff --git a/benchmark/misc/startup-core.js b/benchmark/misc/startup-core.js index 07c0701d128..62ead40742f 100644 --- a/benchmark/misc/startup-core.js +++ b/benchmark/misc/startup-core.js @@ -11,12 +11,12 @@ const bench = common.createBenchmark(main, { 'test/fixtures/semicolon', ], mode: ['process', 'worker'], - count: [30], + n: [30], }); function spawnProcess(script, bench, state) { const cmd = process.execPath || process.argv[0]; - while (state.finished < state.count) { + while (state.finished < state.n) { const child = spawnSync(cmd, [script]); if (child.status !== 0) { console.log('---- STDOUT ----'); @@ -31,8 +31,8 @@ function spawnProcess(script, bench, state) { bench.start(); } - if (state.finished === state.count) { - bench.end(state.count); + if (state.finished === state.n) { + bench.end(state.n); } } } @@ -48,18 +48,18 @@ function spawnWorker(script, bench, state) { // Finished warmup. bench.start(); } - if (state.finished < state.count) { + if (state.finished < state.n) { spawnWorker(script, bench, state); } else { - bench.end(state.count); + bench.end(state.n); } }); } -function main({ count, script, mode }) { +function main({ n, script, mode }) { script = path.resolve(__dirname, '../../', `${script}.js`); const warmup = 3; - const state = { count, finished: -warmup }; + const state = { n, finished: -warmup }; if (mode === 'worker') { Worker = require('worker_threads').Worker; spawnWorker(script, bench, state); diff --git a/benchmark/module/module-loader.js b/benchmark/module/module-loader.js index a885207ff63..0b7700c10aa 100644 --- a/benchmark/module/module-loader.js +++ b/benchmark/module/module-loader.js @@ -16,7 +16,7 @@ const bench = common.createBenchmark(main, { files: [5e2], n: [1, 1e3], cache: ['true', 'false'], -}); +}, { flags: '--no-warnings' }); function main({ n, name, cache, files, dir }) { tmpdir.refresh(); diff --git a/benchmark/napi/buffer/.gitignore b/benchmark/napi/buffer/.gitignore new file mode 100644 index 00000000000..567609b1234 --- /dev/null +++ b/benchmark/napi/buffer/.gitignore @@ -0,0 +1 @@ +build/ diff --git a/benchmark/napi/buffer/binding.cc b/benchmark/napi/buffer/binding.cc new file mode 100644 index 00000000000..d593ecbc384 --- /dev/null +++ b/benchmark/napi/buffer/binding.cc @@ -0,0 +1,85 @@ +#include +#include +#include + +#define NODE_API_CALL(call) \ + do { \ + napi_status status = call; \ + if (status != napi_ok) { \ + fprintf(stderr, #call " failed: %d\n", status); \ + abort(); \ + } \ + } while (0) + +#define ABORT_IF_FALSE(condition) \ + if (!(condition)) { \ + fprintf(stderr, #condition " failed\n"); \ + abort(); \ + } + +static void Finalize(node_api_basic_env env, void* data, void* hint) { + delete[] static_cast(data); +} + +static napi_value CreateExternalBuffer(napi_env env, napi_callback_info info) { + napi_value argv[2], undefined, start, end; + size_t argc = 2; + int32_t n = 0; + napi_valuetype val_type = napi_undefined; + + // Validate params and retrieve start and end function. + NODE_API_CALL(napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr)); + ABORT_IF_FALSE(argc == 2); + NODE_API_CALL(napi_typeof(env, argv[0], &val_type)); + ABORT_IF_FALSE(val_type == napi_object); + NODE_API_CALL(napi_typeof(env, argv[1], &val_type)); + ABORT_IF_FALSE(val_type == napi_number); + NODE_API_CALL(napi_get_named_property(env, argv[0], "start", &start)); + NODE_API_CALL(napi_typeof(env, start, &val_type)); + ABORT_IF_FALSE(val_type == napi_function); + NODE_API_CALL(napi_get_named_property(env, argv[0], "end", &end)); + NODE_API_CALL(napi_typeof(env, end, &val_type)); + ABORT_IF_FALSE(val_type == napi_function); + NODE_API_CALL(napi_get_value_int32(env, argv[1], &n)); + + NODE_API_CALL(napi_get_undefined(env, &undefined)); + + constexpr uint32_t kBufferLen = 32; + + // Start the benchmark. + napi_call_function(env, argv[0], start, 0, nullptr, nullptr); + + for (int32_t idx = 0; idx < n; idx++) { + napi_handle_scope scope; + uint8_t* buffer = new uint8_t[kBufferLen]; + napi_value jsbuffer; + NODE_API_CALL(napi_open_handle_scope(env, &scope)); + NODE_API_CALL(napi_create_external_buffer( + env, kBufferLen, buffer, Finalize, nullptr, &jsbuffer)); + NODE_API_CALL(napi_close_handle_scope(env, scope)); + } + + // Conclude the benchmark. + napi_value end_argv[] = {argv[1]}; + NODE_API_CALL(napi_call_function(env, argv[0], end, 1, end_argv, nullptr)); + + return undefined; +} + +NAPI_MODULE_INIT() { + napi_property_descriptor props[] = { + {"createExternalBuffer", + nullptr, + CreateExternalBuffer, + nullptr, + nullptr, + nullptr, + static_cast(napi_writable | napi_configurable | + napi_enumerable), + nullptr}, + }; + + NODE_API_CALL(napi_define_properties( + env, exports, sizeof(props) / sizeof(*props), props)); + return exports; +} diff --git a/benchmark/napi/buffer/binding.gyp b/benchmark/napi/buffer/binding.gyp new file mode 100644 index 00000000000..c80eb5357b7 --- /dev/null +++ b/benchmark/napi/buffer/binding.gyp @@ -0,0 +1,18 @@ +{ + 'targets': [ + { + 'target_name': 'binding', + 'sources': [ 'binding.cc' ], + 'defines': [ + 'NAPI_EXPERIMENTAL' + ] + }, + { + 'target_name': 'binding_node_api_v8', + 'sources': [ 'binding.cc' ], + 'defines': [ + 'NAPI_VERSION=8' + ] + } + ] +} diff --git a/benchmark/napi/buffer/index.js b/benchmark/napi/buffer/index.js new file mode 100644 index 00000000000..25429a93fab --- /dev/null +++ b/benchmark/napi/buffer/index.js @@ -0,0 +1,14 @@ +'use strict'; + +const common = require('../../common.js'); + +const bench = common.createBenchmark(main, { + n: [5e6], + addon: ['binding', 'binding_node_api_v8'], + implem: ['createExternalBuffer'], +}); + +function main({ n, implem, addon }) { + const binding = require(`./build/${common.buildType}/${addon}`); + binding[implem](bench, n); +} diff --git a/benchmark/path/relative-win32.js b/benchmark/path/relative-win32.js index e513b828533..219c6a31e6a 100644 --- a/benchmark/path/relative-win32.js +++ b/benchmark/path/relative-win32.js @@ -9,6 +9,7 @@ const bench = common.createBenchmark(main, { ['C:\\foo\\bar\\baz', 'C:\\foo\\bar\\baz'].join('|'), ['C:\\foo\\BAR\\BAZ', 'C:\\foo\\bar\\baz'].join('|'), ['C:\\foo\\bar\\baz\\quux', 'C:\\'].join('|'), + ['c:\\İ\\a\\İ', 'c:\\İ\\b\\İ\\test.txt', '..\\..\\b\\İ\\test.txt'].join('|'), ], n: [1e5], }); diff --git a/benchmark/streams/compose.js b/benchmark/streams/compose.js new file mode 100644 index 00000000000..b98596ffbd1 --- /dev/null +++ b/benchmark/streams/compose.js @@ -0,0 +1,42 @@ +'use strict'; +const common = require('../common.js'); + +const { + PassThrough, + Readable, + Writable, + compose, +} = require('node:stream'); + +const bench = common.createBenchmark(main, { + n: [1e3], +}); + +function main({ n }) { + const cachedPassThroughs = []; + const cachedReadables = []; + const cachedWritables = []; + + for (let i = 0; i < n; i++) { + const numberOfPassThroughs = 100; + const passThroughs = []; + + for (let i = 0; i < numberOfPassThroughs; i++) { + passThroughs.push(new PassThrough()); + } + + const readable = Readable.from(['hello', 'world']); + const writable = new Writable({ objectMode: true, write: (chunk, encoding, cb) => cb() }); + + cachedPassThroughs.push(passThroughs); + cachedReadables.push(readable); + cachedWritables.push(writable); + } + + bench.start(); + for (let i = 0; i < n; i++) { + const composed = compose(cachedReadables[i], ...cachedPassThroughs[i], cachedWritables[i]); + composed.end(); + } + bench.end(n); +} diff --git a/benchmark/url/url-searchparams-update.js b/benchmark/url/url-searchparams-update.js index 082d476a5d2..3c42de61110 100644 --- a/benchmark/url/url-searchparams-update.js +++ b/benchmark/url/url-searchparams-update.js @@ -17,7 +17,7 @@ function getMethod(url, property) { function main({ searchParams, property, n }) { const url = new URL('https://nodejs.org'); - if (searchParams === 'true') assert(url.searchParams); + if (searchParams === 'true') assert.ok(url.searchParams); const method = getMethod(url, property); diff --git a/benchmark/url/whatwg-url-to-and-from-path.js b/benchmark/url/whatwg-url-to-and-from-path.js index 3b87c0670a8..366a8c98991 100644 --- a/benchmark/url/whatwg-url-to-and-from-path.js +++ b/benchmark/url/whatwg-url-to-and-from-path.js @@ -3,28 +3,46 @@ const common = require('../common.js'); const { fileURLToPath, pathToFileURL } = require('node:url'); const isWindows = process.platform === 'win32'; -const bench = common.createBenchmark(main, { - input: isWindows ? [ - 'file:///c/', - ] : [ - 'file:///dev/null', - 'file:///dev/null?key=param&bool', - 'file:///dev/null?key=param&bool#hash', - ], - method: isWindows ? [ - 'fileURLToPath', - ] : [ - 'fileURLToPath', - 'pathToFileURL', - ], - n: [5e6], -}); +const inputs = isWindows ? [ + 'C:\\foo', + 'C:\\Program Files\\Music\\Web Sys\\main.html?REQUEST=RADIO', + '\\\\nas\\My Docs\\File.doc', + '\\\\?\\UNC\\server\\share\\folder\\file.txt', + 'file:///C:/foo', + 'file:///C:/dir/foo?query=1', + 'file:///C:/dir/foo#fragment', +] : [ + '/dev/null', + '/dev/null?key=param&bool', + '/dev/null?key=param&bool#hash', + 'file:///dev/null', + 'file:///dev/null?key=param&bool', + 'file:///dev/null?key=param&bool#hash', +]; -function main({ n, input, method }) { - method = method === 'fileURLOrPath' ? fileURLToPath : pathToFileURL; +const bench = common.createBenchmark( + main, + { + method: ['pathToFileURL', 'fileURLToPath'], + input: Object.values(inputs), + n: [5e6], + }, + { + combinationFilter: (p) => ( + (isWindows ? + (!p.input.startsWith('file://') && p.method === 'pathToFileURL') : + p.method === 'pathToFileURL' + ) || + (p.input.startsWith('file://') && p.method === 'fileURLToPath') + ), + }, +); + +function main({ method, input, n }) { + const methodFunc = method === 'fileURLToPath' ? fileURLToPath : pathToFileURL; bench.start(); for (let i = 0; i < n; i++) { - method(input); + methodFunc(input); } bench.end(n); } diff --git a/common.gypi b/common.gypi index 9bbe42622be..a886c435fcb 100644 --- a/common.gypi +++ b/common.gypi @@ -3,7 +3,6 @@ 'configuring_node%': 0, 'asan%': 0, 'ubsan%': 0, - 'werror': '', # Turn off -Werror in V8 build. 'visibility%': 'hidden', # V8's visibility setting 'target_arch%': 'ia32', # set v8's target architecture 'host_arch%': 'ia32', # set v8's host architecture @@ -110,7 +109,6 @@ 'v8_base': '<(PRODUCT_DIR)/obj.target/tools/v8_gypfiles/libv8_snapshot.a', }], ['OS=="mac"', { - 'clang%': 1, 'obj_dir%': '<(PRODUCT_DIR)/obj.target', 'v8_base': '<(PRODUCT_DIR)/libv8_snapshot.a', }], @@ -186,10 +184,10 @@ }, { 'MSVC_runtimeType': 2 # MultiThreadedDLL (/MD) }], - ['llvm_version=="0.0"', { - 'lto': ' -flto=4 -fuse-linker-plugin -ffat-lto-objects ', # GCC - }, { + ['clang==1', { 'lto': ' -flto ', # Clang + }, { + 'lto': ' -flto=4 -fuse-linker-plugin -ffat-lto-objects ', # GCC }], ], }, diff --git a/configure.py b/configure.py index a8222a2612c..d010b0550f9 100755 --- a/configure.py +++ b/configure.py @@ -381,6 +381,28 @@ dest='shared_openssl_libpath', help='a directory to search for the shared OpenSSL DLLs') +shared_optgroup.add_argument('--shared-uvwasi', + action='store_true', + dest='shared_uvwasi', + default=None, + help='link to a shared uvwasi DLL instead of static linking') + +shared_optgroup.add_argument('--shared-uvwasi-includes', + action='store', + dest='shared_uvwasi_includes', + help='directory containing uvwasi header files') + +shared_optgroup.add_argument('--shared-uvwasi-libname', + action='store', + dest='shared_uvwasi_libname', + default='uvwasi', + help='alternative lib name to link to [default: %(default)s]') + +shared_optgroup.add_argument('--shared-uvwasi-libpath', + action='store', + dest='shared_uvwasi_libpath', + help='a directory to search for the shared uvwasi DLL') + shared_optgroup.add_argument('--shared-zlib', action='store_true', dest='shared_zlib', @@ -1115,6 +1137,7 @@ def get_gas_version(cc): # quite prepared to go that far yet. def check_compiler(o): if sys.platform == 'win32': + o['variables']['clang'] = 0 o['variables']['llvm_version'] = '0.0' if not options.openssl_no_asm and options.dest_cpu in ('x86', 'x64'): nasm_version = get_nasm_version('nasm') @@ -1124,6 +1147,7 @@ def check_compiler(o): return ok, is_clang, clang_version, gcc_version = try_check_compiler(CXX, 'c++') + o['variables']['clang'] = B(is_clang) version_str = ".".join(map(str, clang_version if is_clang else gcc_version)) print_verbose(f"Detected {'clang ' if is_clang else ''}C++ compiler (CXX={CXX}) version: {version_str}") if not ok: @@ -1383,7 +1407,9 @@ def configure_node(o): o['variables']['node_use_node_snapshot'] = b( not cross_compiling and not options.shared) - if options.without_node_code_cache or options.without_node_snapshot or options.node_builtin_modules_path: + # Do not use code cache when Node.js is built for collecting coverage of itself, this allows more + # precise coverage for the JS built-ins. + if options.without_node_code_cache or options.without_node_snapshot or options.node_builtin_modules_path or options.coverage: o['variables']['node_use_node_code_cache'] = 'false' else: # TODO(refack): fix this when implementing embedded code-cache when cross-compiling. @@ -1613,7 +1639,7 @@ def configure_v8(o): o['variables']['v8_enable_short_builtin_calls'] = 1 if options.v8_enable_snapshot_compression: o['variables']['v8_enable_snapshot_compression'] = 1 - if options.v8_enable_object_print and options.v8_disable_object_print: + if all(opt in sys.argv for opt in ['--v8-enable-object-print', '--v8-disable-object-print']): raise Exception( 'Only one of the --v8-enable-object-print or --v8-disable-object-print options ' 'can be specified at a time.') @@ -2135,6 +2161,7 @@ def make_bin_override(): configure_library('nghttp2', output, pkgname='libnghttp2') configure_library('nghttp3', output, pkgname='libnghttp3') configure_library('ngtcp2', output, pkgname='libngtcp2') +configure_library('uvwasi', output, pkgname='libuvwasi') configure_v8(output) configure_openssl(output) configure_intl(output) diff --git a/deps/acorn/acorn/CHANGELOG.md b/deps/acorn/acorn/CHANGELOG.md index eb848a58b8a..c404a235c5e 100644 --- a/deps/acorn/acorn/CHANGELOG.md +++ b/deps/acorn/acorn/CHANGELOG.md @@ -1,3 +1,33 @@ +## 8.12.1 (2024-07-03) + +### Bug fixes + +Fix a regression that caused Acorn to no longer run on Node versions <8.10. + +## 8.12.0 (2024-06-14) + +### New features + +Support ES2025 duplicate capture group names in regular expressions. + +### Bug fixes + +Include `VariableDeclarator` in the `AnyNode` type so that walker objects can refer to it without getting a type error. + +Properly raise a parse error for invalid `for`/`of` statements using `async` as binding name. + +Properly recognize \"use strict\" when preceded by a string with an escaped newline. + +Mark the `Parser` constructor as protected, not private, so plugins can extend it without type errors. + +Fix a bug where some invalid `delete` expressions were let through when the operand was parenthesized and `preserveParens` was enabled. + +Properly normalize line endings in raw strings of invalid template tokens. + +Properly track line numbers for escaped newlines in strings. + +Fix a bug that broke line number accounting after a template literal with invalid escape sequences. + ## 8.11.3 (2023-12-29) ### Bug fixes diff --git a/deps/acorn/acorn/README.md b/deps/acorn/acorn/README.md index cfc51b384a3..f7ff9662419 100644 --- a/deps/acorn/acorn/README.md +++ b/deps/acorn/acorn/README.md @@ -50,12 +50,11 @@ Options are provided by in a second argument, which should be an object containing any of these fields (only `ecmaVersion` is required): -- **ecmaVersion**: Indicates the ECMAScript version to parse. Must be - either 3, 5, 6 (or 2015), 7 (2016), 8 (2017), 9 (2018), 10 (2019), - 11 (2020), 12 (2021), 13 (2022), 14 (2023), or `"latest"` (the - latest the library supports). This influences support for strict - mode, the set of reserved words, and support for new syntax - features. +- **ecmaVersion**: Indicates the ECMAScript version to parse. Can be a + number, either in year (`2022`) or plain version number (`6`) form, + or `"latest"` (the latest the library supports). This influences + support for strict mode, the set of reserved words, and support for + new syntax features. **NOTE**: Only 'stage 4' (finalized) ECMAScript features are being implemented by Acorn. Other proposed new features must be diff --git a/deps/acorn/acorn/dist/acorn.d.mts b/deps/acorn/acorn/dist/acorn.d.mts index 6ad58121195..cd204b1c50d 100644 --- a/deps/acorn/acorn/dist/acorn.d.mts +++ b/deps/acorn/acorn/dist/acorn.d.mts @@ -562,7 +562,7 @@ export type ModuleDeclaration = | ExportDefaultDeclaration | ExportAllDeclaration -export type AnyNode = Statement | Expression | Declaration | ModuleDeclaration | Literal | Program | SwitchCase | CatchClause | Property | Super | SpreadElement | TemplateElement | AssignmentProperty | ObjectPattern | ArrayPattern | RestElement | AssignmentPattern | ClassBody | MethodDefinition | MetaProperty | ImportSpecifier | ImportDefaultSpecifier | ImportNamespaceSpecifier | ExportSpecifier | AnonymousFunctionDeclaration | AnonymousClassDeclaration | PropertyDefinition | PrivateIdentifier | StaticBlock +export type AnyNode = Statement | Expression | Declaration | ModuleDeclaration | Literal | Program | SwitchCase | CatchClause | Property | Super | SpreadElement | TemplateElement | AssignmentProperty | ObjectPattern | ArrayPattern | RestElement | AssignmentPattern | ClassBody | MethodDefinition | MetaProperty | ImportSpecifier | ImportDefaultSpecifier | ImportNamespaceSpecifier | ExportSpecifier | AnonymousFunctionDeclaration | AnonymousClassDeclaration | PropertyDefinition | PrivateIdentifier | StaticBlock | VariableDeclarator export function parse(input: string, options: Options): Program @@ -573,16 +573,15 @@ export function tokenizer(input: string, options: Options): { [Symbol.iterator](): Iterator } -export type ecmaVersion = 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 2015 | 2016 | 2017 | 2018 | 2019 | 2020 | 2021 | 2022 | 2023 | 2024 | "latest" +export type ecmaVersion = 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 2015 | 2016 | 2017 | 2018 | 2019 | 2020 | 2021 | 2022 | 2023 | 2024 | 2025 | "latest" export interface Options { /** - * `ecmaVersion` indicates the ECMAScript version to parse. Must be - * either 3, 5, 6 (or 2015), 7 (2016), 8 (2017), 9 (2018), 10 - * (2019), 11 (2020), 12 (2021), 13 (2022), 14 (2023), or `"latest"` - * (the latest version the library supports). This influences - * support for strict mode, the set of reserved words, and support - * for new syntax features. + * `ecmaVersion` indicates the ECMAScript version to parse. Can be a + * number, either in year (`2022`) or plain version number (`6`) form, + * or `"latest"` (the latest the library supports). This influences + * support for strict mode, the set of reserved words, and support for + * new syntax features. */ ecmaVersion: ecmaVersion @@ -733,7 +732,7 @@ export class Parser { options: Options input: string - private constructor(options: Options, input: string, startPos?: number) + protected constructor(options: Options, input: string, startPos?: number) parse(): Program static parse(input: string, options: Options): Program diff --git a/deps/acorn/acorn/dist/acorn.d.ts b/deps/acorn/acorn/dist/acorn.d.ts index 6ad58121195..cd204b1c50d 100644 --- a/deps/acorn/acorn/dist/acorn.d.ts +++ b/deps/acorn/acorn/dist/acorn.d.ts @@ -562,7 +562,7 @@ export type ModuleDeclaration = | ExportDefaultDeclaration | ExportAllDeclaration -export type AnyNode = Statement | Expression | Declaration | ModuleDeclaration | Literal | Program | SwitchCase | CatchClause | Property | Super | SpreadElement | TemplateElement | AssignmentProperty | ObjectPattern | ArrayPattern | RestElement | AssignmentPattern | ClassBody | MethodDefinition | MetaProperty | ImportSpecifier | ImportDefaultSpecifier | ImportNamespaceSpecifier | ExportSpecifier | AnonymousFunctionDeclaration | AnonymousClassDeclaration | PropertyDefinition | PrivateIdentifier | StaticBlock +export type AnyNode = Statement | Expression | Declaration | ModuleDeclaration | Literal | Program | SwitchCase | CatchClause | Property | Super | SpreadElement | TemplateElement | AssignmentProperty | ObjectPattern | ArrayPattern | RestElement | AssignmentPattern | ClassBody | MethodDefinition | MetaProperty | ImportSpecifier | ImportDefaultSpecifier | ImportNamespaceSpecifier | ExportSpecifier | AnonymousFunctionDeclaration | AnonymousClassDeclaration | PropertyDefinition | PrivateIdentifier | StaticBlock | VariableDeclarator export function parse(input: string, options: Options): Program @@ -573,16 +573,15 @@ export function tokenizer(input: string, options: Options): { [Symbol.iterator](): Iterator } -export type ecmaVersion = 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 2015 | 2016 | 2017 | 2018 | 2019 | 2020 | 2021 | 2022 | 2023 | 2024 | "latest" +export type ecmaVersion = 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 2015 | 2016 | 2017 | 2018 | 2019 | 2020 | 2021 | 2022 | 2023 | 2024 | 2025 | "latest" export interface Options { /** - * `ecmaVersion` indicates the ECMAScript version to parse. Must be - * either 3, 5, 6 (or 2015), 7 (2016), 8 (2017), 9 (2018), 10 - * (2019), 11 (2020), 12 (2021), 13 (2022), 14 (2023), or `"latest"` - * (the latest version the library supports). This influences - * support for strict mode, the set of reserved words, and support - * for new syntax features. + * `ecmaVersion` indicates the ECMAScript version to parse. Can be a + * number, either in year (`2022`) or plain version number (`6`) form, + * or `"latest"` (the latest the library supports). This influences + * support for strict mode, the set of reserved words, and support for + * new syntax features. */ ecmaVersion: ecmaVersion @@ -733,7 +732,7 @@ export class Parser { options: Options input: string - private constructor(options: Options, input: string, startPos?: number) + protected constructor(options: Options, input: string, startPos?: number) parse(): Program static parse(input: string, options: Options): Program diff --git a/deps/acorn/acorn/dist/acorn.js b/deps/acorn/acorn/dist/acorn.js index 3a6a3a2aeed..68bf2a714e2 100644 --- a/deps/acorn/acorn/dist/acorn.js +++ b/deps/acorn/acorn/dist/acorn.js @@ -667,7 +667,7 @@ // ## Parser utilities - var literal = /^(?:'((?:\\.|[^'\\])*?)'|"((?:\\.|[^"\\])*?)")/; + var literal = /^(?:'((?:\\[^]|[^'\\])*?)'|"((?:\\[^]|[^"\\])*?)")/; pp$9.strictDirective = function(start) { if (this.options.ecmaVersion < 5) { return false } for (;;) { @@ -853,7 +853,7 @@ // Statement) is allowed here. If context is not empty then only a Statement // is allowed. However, `let [` is an explicit negative lookahead for // ExpressionStatement, so special-case it first. - if (nextCh === 91 || nextCh === 92) { return true } // '[', '/' + if (nextCh === 91 || nextCh === 92) { return true } // '[', '\' if (context) { return false } if (nextCh === 123 || nextCh > 0xd7ff && nextCh < 0xdc00) { return true } // '{', astral @@ -1046,13 +1046,19 @@ return this.parseFor(node, init$1) } var startsWithLet = this.isContextual("let"), isForOf = false; + var containsEsc = this.containsEsc; var refDestructuringErrors = new DestructuringErrors; - var init = this.parseExpression(awaitAt > -1 ? "await" : true, refDestructuringErrors); + var initPos = this.start; + var init = awaitAt > -1 + ? this.parseExprSubscripts(refDestructuringErrors, "await") + : this.parseExpression(true, refDestructuringErrors); if (this.type === types$1._in || (isForOf = this.options.ecmaVersion >= 6 && this.isContextual("of"))) { - if (this.options.ecmaVersion >= 9) { - if (this.type === types$1._in) { - if (awaitAt > -1) { this.unexpected(awaitAt); } - } else { node.await = awaitAt > -1; } + if (awaitAt > -1) { // implies `ecmaVersion >= 9` (see declaration of awaitAt) + if (this.type === types$1._in) { this.unexpected(awaitAt); } + node.await = true; + } else if (isForOf && this.options.ecmaVersion >= 8) { + if (init.start === initPos && !containsEsc && init.type === "Identifier" && init.name === "async") { this.unexpected(); } + else if (this.options.ecmaVersion >= 9) { node.await = false; } } if (startsWithLet && isForOf) { this.raise(init.start, "The left-hand side of a for-of loop may not start with 'let'."); } this.toAssignable(init, false, refDestructuringErrors); @@ -2665,8 +2671,7 @@ node.argument = this.parseMaybeUnary(null, true, update, forInit); this.checkExpressionErrors(refDestructuringErrors, true); if (update) { this.checkLValSimple(node.argument); } - else if (this.strict && node.operator === "delete" && - node.argument.type === "Identifier") + else if (this.strict && node.operator === "delete" && isLocalVariableAccess(node.argument)) { this.raiseRecoverable(node.start, "Deleting local variable in strict mode"); } else if (node.operator === "delete" && isPrivateFieldAccess(node.argument)) { this.raiseRecoverable(node.start, "Private fields can not be deleted"); } @@ -2701,10 +2706,18 @@ } }; + function isLocalVariableAccess(node) { + return ( + node.type === "Identifier" || + node.type === "ParenthesizedExpression" && isLocalVariableAccess(node.expression) + ) + } + function isPrivateFieldAccess(node) { return ( node.type === "MemberExpression" && node.property.type === "PrivateIdentifier" || - node.type === "ChainExpression" && isPrivateFieldAccess(node.expression) + node.type === "ChainExpression" && isPrivateFieldAccess(node.expression) || + node.type === "ParenthesizedExpression" && isPrivateFieldAccess(node.expression) ) } @@ -3131,7 +3144,7 @@ this.raiseRecoverable(this.start, "Bad escape sequence in untagged template literal"); } elem.value = { - raw: this.value, + raw: this.value.replace(/\r\n?/g, "\n"), cooked: null }; } else { @@ -3806,6 +3819,30 @@ var pp$1 = Parser.prototype; + // Track disjunction structure to determine whether a duplicate + // capture group name is allowed because it is in a separate branch. + var BranchID = function BranchID(parent, base) { + // Parent disjunction branch + this.parent = parent; + // Identifies this set of sibling branches + this.base = base || this; + }; + + BranchID.prototype.separatedFrom = function separatedFrom (alt) { + // A branch is separate from another branch if they or any of + // their parents are siblings in a given disjunction + for (var self = this; self; self = self.parent) { + for (var other = alt; other; other = other.parent) { + if (self.base === other.base && self !== other) { return true } + } + } + return false + }; + + BranchID.prototype.sibling = function sibling () { + return new BranchID(this.parent, this.base) + }; + var RegExpValidationState = function RegExpValidationState(parser) { this.parser = parser; this.validFlags = "gim" + (parser.options.ecmaVersion >= 6 ? "uy" : "") + (parser.options.ecmaVersion >= 9 ? "s" : "") + (parser.options.ecmaVersion >= 13 ? "d" : "") + (parser.options.ecmaVersion >= 15 ? "v" : ""); @@ -3822,8 +3859,9 @@ this.lastAssertionIsQuantifiable = false; this.numCapturingParens = 0; this.maxBackReference = 0; - this.groupNames = []; + this.groupNames = Object.create(null); this.backReferenceNames = []; + this.branchID = null; }; RegExpValidationState.prototype.reset = function reset (start, pattern, flags) { @@ -3955,6 +3993,11 @@ } }; + function hasProp(obj) { + for (var _ in obj) { return true } + return false + } + /** * Validate the pattern part of a given RegExpLiteral. * @@ -3969,7 +4012,7 @@ // |Pattern[~U, +N]| and use this result instead. Throw a *SyntaxError* // exception if _P_ did not conform to the grammar, if any elements of _P_ // were not matched by the parse, or if any Early Error conditions exist. - if (!state.switchN && this.options.ecmaVersion >= 9 && state.groupNames.length > 0) { + if (!state.switchN && this.options.ecmaVersion >= 9 && hasProp(state.groupNames)) { state.switchN = true; this.regexp_pattern(state); } @@ -3983,8 +4026,9 @@ state.lastAssertionIsQuantifiable = false; state.numCapturingParens = 0; state.maxBackReference = 0; - state.groupNames.length = 0; + state.groupNames = Object.create(null); state.backReferenceNames.length = 0; + state.branchID = null; this.regexp_disjunction(state); @@ -4003,7 +4047,7 @@ for (var i = 0, list = state.backReferenceNames; i < list.length; i += 1) { var name = list[i]; - if (state.groupNames.indexOf(name) === -1) { + if (!state.groupNames[name]) { state.raise("Invalid named capture referenced"); } } @@ -4011,10 +4055,14 @@ // https://www.ecma-international.org/ecma-262/8.0/#prod-Disjunction pp$1.regexp_disjunction = function(state) { + var trackDisjunction = this.options.ecmaVersion >= 16; + if (trackDisjunction) { state.branchID = new BranchID(state.branchID, null); } this.regexp_alternative(state); while (state.eat(0x7C /* | */)) { + if (trackDisjunction) { state.branchID = state.branchID.sibling(); } this.regexp_alternative(state); } + if (trackDisjunction) { state.branchID = state.branchID.parent; } // Make the same message as V8. if (this.regexp_eatQuantifier(state, true)) { @@ -4027,8 +4075,7 @@ // https://www.ecma-international.org/ecma-262/8.0/#prod-Alternative pp$1.regexp_alternative = function(state) { - while (state.pos < state.source.length && this.regexp_eatTerm(state)) - { } + while (state.pos < state.source.length && this.regexp_eatTerm(state)) {} }; // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-Term @@ -4266,14 +4313,26 @@ // `?` GroupName pp$1.regexp_groupSpecifier = function(state) { if (state.eat(0x3F /* ? */)) { - if (this.regexp_eatGroupName(state)) { - if (state.groupNames.indexOf(state.lastStringValue) !== -1) { + if (!this.regexp_eatGroupName(state)) { state.raise("Invalid group"); } + var trackDisjunction = this.options.ecmaVersion >= 16; + var known = state.groupNames[state.lastStringValue]; + if (known) { + if (trackDisjunction) { + for (var i = 0, list = known; i < list.length; i += 1) { + var altID = list[i]; + + if (!altID.separatedFrom(state.branchID)) + { state.raise("Duplicate capture group name"); } + } + } else { state.raise("Duplicate capture group name"); } - state.groupNames.push(state.lastStringValue); - return } - state.raise("Invalid group"); + if (trackDisjunction) { + (known || (state.groupNames[state.lastStringValue] = [])).push(state.branchID); + } else { + state.groupNames[state.lastStringValue] = true; + } } }; @@ -5778,15 +5837,18 @@ break case "$": - if (this.input[this.pos + 1] !== "{") { - break - } - - // falls through + if (this.input[this.pos + 1] !== "{") { break } + // fall through case "`": return this.finishToken(types$1.invalidTemplate, this.input.slice(this.start, this.pos)) - // no default + case "\r": + if (this.input[this.pos + 1] === "\n") { ++this.pos; } + // fall through + case "\n": case "\u2028": case "\u2029": + ++this.curLine; + this.lineStart = this.pos + 1; + break } } this.raise(this.start, "Unterminated template"); @@ -5849,6 +5911,7 @@ if (isNewLine(ch)) { // Unicode new line characters after \ get removed from output in both // template literals and strings + if (this.options.locations) { this.lineStart = this.pos; ++this.curLine; } return "" } return String.fromCharCode(ch) @@ -5927,7 +5990,7 @@ // [walk]: util/walk.js - var version = "8.11.3"; + var version = "8.12.1"; Parser.acorn = { Parser: Parser, diff --git a/deps/acorn/acorn/dist/acorn.mjs b/deps/acorn/acorn/dist/acorn.mjs index d1f81ef4851..3fd7cb30c67 100644 --- a/deps/acorn/acorn/dist/acorn.mjs +++ b/deps/acorn/acorn/dist/acorn.mjs @@ -661,7 +661,7 @@ var pp$9 = Parser.prototype; // ## Parser utilities -var literal = /^(?:'((?:\\.|[^'\\])*?)'|"((?:\\.|[^"\\])*?)")/; +var literal = /^(?:'((?:\\[^]|[^'\\])*?)'|"((?:\\[^]|[^"\\])*?)")/; pp$9.strictDirective = function(start) { if (this.options.ecmaVersion < 5) { return false } for (;;) { @@ -847,7 +847,7 @@ pp$8.isLet = function(context) { // Statement) is allowed here. If context is not empty then only a Statement // is allowed. However, `let [` is an explicit negative lookahead for // ExpressionStatement, so special-case it first. - if (nextCh === 91 || nextCh === 92) { return true } // '[', '/' + if (nextCh === 91 || nextCh === 92) { return true } // '[', '\' if (context) { return false } if (nextCh === 123 || nextCh > 0xd7ff && nextCh < 0xdc00) { return true } // '{', astral @@ -1040,13 +1040,19 @@ pp$8.parseForStatement = function(node) { return this.parseFor(node, init$1) } var startsWithLet = this.isContextual("let"), isForOf = false; + var containsEsc = this.containsEsc; var refDestructuringErrors = new DestructuringErrors; - var init = this.parseExpression(awaitAt > -1 ? "await" : true, refDestructuringErrors); + var initPos = this.start; + var init = awaitAt > -1 + ? this.parseExprSubscripts(refDestructuringErrors, "await") + : this.parseExpression(true, refDestructuringErrors); if (this.type === types$1._in || (isForOf = this.options.ecmaVersion >= 6 && this.isContextual("of"))) { - if (this.options.ecmaVersion >= 9) { - if (this.type === types$1._in) { - if (awaitAt > -1) { this.unexpected(awaitAt); } - } else { node.await = awaitAt > -1; } + if (awaitAt > -1) { // implies `ecmaVersion >= 9` (see declaration of awaitAt) + if (this.type === types$1._in) { this.unexpected(awaitAt); } + node.await = true; + } else if (isForOf && this.options.ecmaVersion >= 8) { + if (init.start === initPos && !containsEsc && init.type === "Identifier" && init.name === "async") { this.unexpected(); } + else if (this.options.ecmaVersion >= 9) { node.await = false; } } if (startsWithLet && isForOf) { this.raise(init.start, "The left-hand side of a for-of loop may not start with 'let'."); } this.toAssignable(init, false, refDestructuringErrors); @@ -2659,8 +2665,7 @@ pp$5.parseMaybeUnary = function(refDestructuringErrors, sawUnary, incDec, forIni node.argument = this.parseMaybeUnary(null, true, update, forInit); this.checkExpressionErrors(refDestructuringErrors, true); if (update) { this.checkLValSimple(node.argument); } - else if (this.strict && node.operator === "delete" && - node.argument.type === "Identifier") + else if (this.strict && node.operator === "delete" && isLocalVariableAccess(node.argument)) { this.raiseRecoverable(node.start, "Deleting local variable in strict mode"); } else if (node.operator === "delete" && isPrivateFieldAccess(node.argument)) { this.raiseRecoverable(node.start, "Private fields can not be deleted"); } @@ -2695,10 +2700,18 @@ pp$5.parseMaybeUnary = function(refDestructuringErrors, sawUnary, incDec, forIni } }; +function isLocalVariableAccess(node) { + return ( + node.type === "Identifier" || + node.type === "ParenthesizedExpression" && isLocalVariableAccess(node.expression) + ) +} + function isPrivateFieldAccess(node) { return ( node.type === "MemberExpression" && node.property.type === "PrivateIdentifier" || - node.type === "ChainExpression" && isPrivateFieldAccess(node.expression) + node.type === "ChainExpression" && isPrivateFieldAccess(node.expression) || + node.type === "ParenthesizedExpression" && isPrivateFieldAccess(node.expression) ) } @@ -3125,7 +3138,7 @@ pp$5.parseTemplateElement = function(ref) { this.raiseRecoverable(this.start, "Bad escape sequence in untagged template literal"); } elem.value = { - raw: this.value, + raw: this.value.replace(/\r\n?/g, "\n"), cooked: null }; } else { @@ -3800,6 +3813,30 @@ for (var i = 0, list = [9, 10, 11, 12, 13, 14]; i < list.length; i += 1) { var pp$1 = Parser.prototype; +// Track disjunction structure to determine whether a duplicate +// capture group name is allowed because it is in a separate branch. +var BranchID = function BranchID(parent, base) { + // Parent disjunction branch + this.parent = parent; + // Identifies this set of sibling branches + this.base = base || this; +}; + +BranchID.prototype.separatedFrom = function separatedFrom (alt) { + // A branch is separate from another branch if they or any of + // their parents are siblings in a given disjunction + for (var self = this; self; self = self.parent) { + for (var other = alt; other; other = other.parent) { + if (self.base === other.base && self !== other) { return true } + } + } + return false +}; + +BranchID.prototype.sibling = function sibling () { + return new BranchID(this.parent, this.base) +}; + var RegExpValidationState = function RegExpValidationState(parser) { this.parser = parser; this.validFlags = "gim" + (parser.options.ecmaVersion >= 6 ? "uy" : "") + (parser.options.ecmaVersion >= 9 ? "s" : "") + (parser.options.ecmaVersion >= 13 ? "d" : "") + (parser.options.ecmaVersion >= 15 ? "v" : ""); @@ -3816,8 +3853,9 @@ var RegExpValidationState = function RegExpValidationState(parser) { this.lastAssertionIsQuantifiable = false; this.numCapturingParens = 0; this.maxBackReference = 0; - this.groupNames = []; + this.groupNames = Object.create(null); this.backReferenceNames = []; + this.branchID = null; }; RegExpValidationState.prototype.reset = function reset (start, pattern, flags) { @@ -3949,6 +3987,11 @@ pp$1.validateRegExpFlags = function(state) { } }; +function hasProp(obj) { + for (var _ in obj) { return true } + return false +} + /** * Validate the pattern part of a given RegExpLiteral. * @@ -3963,7 +4006,7 @@ pp$1.validateRegExpPattern = function(state) { // |Pattern[~U, +N]| and use this result instead. Throw a *SyntaxError* // exception if _P_ did not conform to the grammar, if any elements of _P_ // were not matched by the parse, or if any Early Error conditions exist. - if (!state.switchN && this.options.ecmaVersion >= 9 && state.groupNames.length > 0) { + if (!state.switchN && this.options.ecmaVersion >= 9 && hasProp(state.groupNames)) { state.switchN = true; this.regexp_pattern(state); } @@ -3977,8 +4020,9 @@ pp$1.regexp_pattern = function(state) { state.lastAssertionIsQuantifiable = false; state.numCapturingParens = 0; state.maxBackReference = 0; - state.groupNames.length = 0; + state.groupNames = Object.create(null); state.backReferenceNames.length = 0; + state.branchID = null; this.regexp_disjunction(state); @@ -3997,7 +4041,7 @@ pp$1.regexp_pattern = function(state) { for (var i = 0, list = state.backReferenceNames; i < list.length; i += 1) { var name = list[i]; - if (state.groupNames.indexOf(name) === -1) { + if (!state.groupNames[name]) { state.raise("Invalid named capture referenced"); } } @@ -4005,10 +4049,14 @@ pp$1.regexp_pattern = function(state) { // https://www.ecma-international.org/ecma-262/8.0/#prod-Disjunction pp$1.regexp_disjunction = function(state) { + var trackDisjunction = this.options.ecmaVersion >= 16; + if (trackDisjunction) { state.branchID = new BranchID(state.branchID, null); } this.regexp_alternative(state); while (state.eat(0x7C /* | */)) { + if (trackDisjunction) { state.branchID = state.branchID.sibling(); } this.regexp_alternative(state); } + if (trackDisjunction) { state.branchID = state.branchID.parent; } // Make the same message as V8. if (this.regexp_eatQuantifier(state, true)) { @@ -4021,8 +4069,7 @@ pp$1.regexp_disjunction = function(state) { // https://www.ecma-international.org/ecma-262/8.0/#prod-Alternative pp$1.regexp_alternative = function(state) { - while (state.pos < state.source.length && this.regexp_eatTerm(state)) - { } + while (state.pos < state.source.length && this.regexp_eatTerm(state)) {} }; // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-Term @@ -4260,14 +4307,26 @@ pp$1.regexp_eatExtendedPatternCharacter = function(state) { // `?` GroupName pp$1.regexp_groupSpecifier = function(state) { if (state.eat(0x3F /* ? */)) { - if (this.regexp_eatGroupName(state)) { - if (state.groupNames.indexOf(state.lastStringValue) !== -1) { + if (!this.regexp_eatGroupName(state)) { state.raise("Invalid group"); } + var trackDisjunction = this.options.ecmaVersion >= 16; + var known = state.groupNames[state.lastStringValue]; + if (known) { + if (trackDisjunction) { + for (var i = 0, list = known; i < list.length; i += 1) { + var altID = list[i]; + + if (!altID.separatedFrom(state.branchID)) + { state.raise("Duplicate capture group name"); } + } + } else { state.raise("Duplicate capture group name"); } - state.groupNames.push(state.lastStringValue); - return } - state.raise("Invalid group"); + if (trackDisjunction) { + (known || (state.groupNames[state.lastStringValue] = [])).push(state.branchID); + } else { + state.groupNames[state.lastStringValue] = true; + } } }; @@ -5772,15 +5831,18 @@ pp.readInvalidTemplateToken = function() { break case "$": - if (this.input[this.pos + 1] !== "{") { - break - } - - // falls through + if (this.input[this.pos + 1] !== "{") { break } + // fall through case "`": return this.finishToken(types$1.invalidTemplate, this.input.slice(this.start, this.pos)) - // no default + case "\r": + if (this.input[this.pos + 1] === "\n") { ++this.pos; } + // fall through + case "\n": case "\u2028": case "\u2029": + ++this.curLine; + this.lineStart = this.pos + 1; + break } } this.raise(this.start, "Unterminated template"); @@ -5843,6 +5905,7 @@ pp.readEscapedChar = function(inTemplate) { if (isNewLine(ch)) { // Unicode new line characters after \ get removed from output in both // template literals and strings + if (this.options.locations) { this.lineStart = this.pos; ++this.curLine; } return "" } return String.fromCharCode(ch) @@ -5921,7 +5984,7 @@ pp.readWord = function() { // [walk]: util/walk.js -var version = "8.11.3"; +var version = "8.12.1"; Parser.acorn = { Parser: Parser, diff --git a/deps/acorn/acorn/package.json b/deps/acorn/acorn/package.json index 1b8dc76afc3..355692a301e 100644 --- a/deps/acorn/acorn/package.json +++ b/deps/acorn/acorn/package.json @@ -16,7 +16,7 @@ ], "./package.json": "./package.json" }, - "version": "8.11.3", + "version": "8.12.1", "engines": { "node": ">=0.4.0" }, @@ -38,13 +38,13 @@ ], "repository": { "type": "git", - "url": "https://github.com/acornjs/acorn.git" + "url": "git+https://github.com/acornjs/acorn.git" }, "license": "MIT", "scripts": { "prepare": "cd ..; npm run build:main" }, "bin": { - "acorn": "./bin/acorn" + "acorn": "bin/acorn" } } diff --git a/deps/cares/CMakeLists.txt b/deps/cares/CMakeLists.txt index 2505967d352..9862406495f 100644 --- a/deps/cares/CMakeLists.txt +++ b/deps/cares/CMakeLists.txt @@ -12,7 +12,7 @@ INCLUDE (CheckCSourceCompiles) INCLUDE (CheckStructHasMember) INCLUDE (CheckLibraryExists) -PROJECT (c-ares LANGUAGES C VERSION "1.32.3" ) +PROJECT (c-ares LANGUAGES C VERSION "1.33.1" ) # Set this version before release SET (CARES_VERSION "${PROJECT_VERSION}") @@ -30,7 +30,7 @@ INCLUDE (GNUInstallDirs) # include this *AFTER* PROJECT(), otherwise paths are w # For example, a version of 4:0:2 would generate output such as: # libname.so -> libname.so.2 # libname.so.2 -> libname.so.2.2.0 -SET (CARES_LIB_VERSIONINFO "19:3:17") +SET (CARES_LIB_VERSIONINFO "20:1:18") OPTION (CARES_STATIC "Build as a static library" OFF) @@ -42,6 +42,7 @@ OPTION (CARES_BUILD_CONTAINER_TESTS "Build and run container tests (implies CARE OPTION (CARES_BUILD_TOOLS "Build tools" ON) OPTION (CARES_SYMBOL_HIDING "Hide private symbols in shared libraries" OFF) OPTION (CARES_THREADS "Build with thread-safety support" ON) +OPTION (CARES_COVERAGE "Build for code coverage" OFF) SET (CARES_RANDOM_FILE "/dev/urandom" CACHE STRING "Suitable File / Device Path for entropy, such as /dev/urandom") @@ -265,7 +266,7 @@ IF (CMAKE_SYSTEM_NAME STREQUAL "Darwin") ELSEIF (CMAKE_SYSTEM_NAME STREQUAL "Linux") LIST (APPEND SYSFLAGS -D_GNU_SOURCE -D_POSIX_C_SOURCE=200809L -D_XOPEN_SOURCE=700) ELSEIF (CMAKE_SYSTEM_NAME STREQUAL "SunOS") - LIST (APPEND SYSFLAGS -D__EXTENSIONS__ -D_REENTRANT -D_XOPEN_SOURCE=700) + LIST (APPEND SYSFLAGS -D__EXTENSIONS__ -D_REENTRANT -D_XOPEN_SOURCE=600) ELSEIF (CMAKE_SYSTEM_NAME STREQUAL "AIX") LIST (APPEND SYSFLAGS -D_ALL_SOURCE -D_XOPEN_SOURCE=700 -D_USE_IRS) ELSEIF (CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") @@ -409,6 +410,7 @@ CHECK_STRUCT_HAS_MEMBER("struct sockaddr_in6" sin6_scope_id "${CMAKE_EXTRA_INCLU CHECK_SYMBOL_EXISTS (closesocket "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_CLOSESOCKET) CHECK_SYMBOL_EXISTS (CloseSocket "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_CLOSESOCKET_CAMEL) CHECK_SYMBOL_EXISTS (connect "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_CONNECT) +CHECK_SYMBOL_EXISTS (connectx "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_CONNECTX) CHECK_SYMBOL_EXISTS (fcntl "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_FCNTL) CHECK_SYMBOL_EXISTS (freeaddrinfo "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_FREEADDRINFO) CHECK_SYMBOL_EXISTS (getaddrinfo "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_GETADDRINFO) @@ -423,6 +425,10 @@ CHECK_SYMBOL_EXISTS (if_indextoname "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_IF_INDE CHECK_SYMBOL_EXISTS (if_nametoindex "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_IF_NAMETOINDEX) CHECK_SYMBOL_EXISTS (ConvertInterfaceIndexToLuid "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_CONVERTINTERFACEINDEXTOLUID) CHECK_SYMBOL_EXISTS (ConvertInterfaceLuidToNameA "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_CONVERTINTERFACELUIDTONAMEA) +CHECK_SYMBOL_EXISTS (NotifyIpInterfaceChange "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_NOTIFYIPINTERFACECHANGE) +CHECK_SYMBOL_EXISTS (RegisterWaitForSingleObject "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_REGISTERWAITFORSINGLEOBJECT) + + CHECK_SYMBOL_EXISTS (inet_net_pton "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_INET_NET_PTON) IF (NOT WIN32) # Disabled on Windows, because these functions are only really supported on Windows @@ -682,6 +688,27 @@ IF (HAVE_ARPA_NAMESER_COMPAT_H) SET (CARES_HAVE_ARPA_NAMESER_COMPAT_H 1) ENDIF() + +# Coverage +IF (CARES_COVERAGE) + # set compiler flags + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ftest-coverage -fprofile-arcs") + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ftest-coverage -fprofile-arcs") + + # find required tools + FIND_PROGRAM(LCOV lcov REQUIRED) + FIND_PROGRAM(GENHTML genhtml REQUIRED) + + # add coverage target + ADD_CUSTOM_TARGET(coverage + # gather data + COMMAND ${LCOV} --directory . --capture --output-file coverage.info + # generate report + COMMAND ${GENHTML} --demangle-cpp -o coverage coverage.info + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + ) +ENDIF() + # TRANSFORM_MAKEFILE_INC # # This function consumes the "Makefile.inc" autotools file, and converts it into @@ -729,6 +756,8 @@ IF (CARES_BUILD_TESTS OR CARES_BUILD_CONTAINER_TESTS) ENDIF () + + # Export targets IF (CARES_INSTALL) SET (CMAKECONFIG_INSTALL_DIR "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}") @@ -743,12 +772,11 @@ IF (CARES_INSTALL) INSTALL (EXPORT ${PROJECT_NAME}-targets COMPONENT Devel DESTINATION ${CMAKECONFIG_INSTALL_DIR} NAMESPACE ${PROJECT_NAME}::) INSTALL (FILES "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake" "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake" COMPONENT Devel DESTINATION ${CMAKECONFIG_INSTALL_DIR}) - # pkgconfig support - IF (NOT CARES_SHARED) - FOREACH (LIB ${CARES_DEPENDENT_LIBS}) - SET (CARES_PRIVATE_LIBS "${CARES_PRIVATE_LIBS} -l${LIB}") - ENDFOREACH () - ENDIF () + # pkgconfig support for static builds + FOREACH (LIB ${CARES_DEPENDENT_LIBS}) + SET (CARES_PRIVATE_LIBS "${CARES_PRIVATE_LIBS} -l${LIB}") + ENDFOREACH () + CONFIGURE_FILE("libcares.pc.cmake" "libcares.pc" @ONLY) INSTALL (FILES "${CMAKE_CURRENT_BINARY_DIR}/libcares.pc" COMPONENT Devel DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig") ENDIF () diff --git a/deps/cares/LICENSE.md b/deps/cares/LICENSE.md index e27bae933fc..910ddded5c7 100644 --- a/deps/cares/LICENSE.md +++ b/deps/cares/LICENSE.md @@ -1,5 +1,3 @@ -# c-ares license - MIT License Copyright (c) 1998 Massachusetts Institute of Technology diff --git a/deps/cares/Makefile.Watcom b/deps/cares/Makefile.Watcom index f6eb7c070b2..96ffedb1eb3 100644 --- a/deps/cares/Makefile.Watcom +++ b/deps/cares/Makefile.Watcom @@ -97,7 +97,19 @@ all: $(ARESBUILDH) $(OBJ_BASE) $(TARGETS) $(DEMOS) .SYMBOLIC $(OBJ_BASE): -$(MD) $^@ -$(MD) $^@\stat + -$(MD) $^@\stat\dsa + -$(MD) $^@\stat\event + -$(MD) $^@\stat\legacy + -$(MD) $^@\stat\record + -$(MD) $^@\stat\str + -$(MD) $^@\stat\util -$(MD) $^@\dyn + -$(MD) $^@\dyn\dsa + -$(MD) $^@\dyn\event + -$(MD) $^@\dyn\legacy + -$(MD) $^@\dyn\record + -$(MD) $^@\dyn\str + -$(MD) $^@\dyn\util -$(MD) $^@\tools $(ARESBUILDH): .EXISTSONLY @@ -129,7 +141,19 @@ vclean realclean: clean .SYMBOLIC -$(RM) $(TARGETS) $(LIBNAME).map -$(RM) $(DEMOS) $(DEMOS:.exe=.map) -$(RD) $(OBJ_BASE)\stat + -$(RD) $(OBJ_BASE)\stat\dsa + -$(RD) $(OBJ_BASE)\stat\event + -$(RD) $(OBJ_BASE)\stat\legacy + -$(RD) $(OBJ_BASE)\stat\record + -$(RD) $(OBJ_BASE)\stat\str + -$(RD) $(OBJ_BASE)\stat\util -$(RD) $(OBJ_BASE)\dyn + -$(RD) $(OBJ_BASE)\dyn\dsa + -$(RD) $(OBJ_BASE)\dyn\event + -$(RD) $(OBJ_BASE)\dyn\legacy + -$(RD) $(OBJ_BASE)\dyn\record + -$(RD) $(OBJ_BASE)\dyn\str + -$(RD) $(OBJ_BASE)\dyn\util -$(RD) $(OBJ_BASE)\tools -$(RD) $(OBJ_BASE) @@ -144,10 +168,58 @@ $(RESOURCE): src\lib\cares.rc .AUTODEPEND .c{$(OBJ_BASE)\dyn}.obj: $(CC) $(CFLAGS) -bd .\src\lib\$^& -fo=$^@ +.ERASE +{dsa}.c{$(OBJ_BASE)\dyn\dsa}.obj: + $(CC) $(CFLAGS) -bd .\src\lib\dsa\$^& -fo=$^@ + +.ERASE +{event}.c{$(OBJ_BASE)\dyn\event}.obj: + $(CC) $(CFLAGS) -bd .\src\lib\event\$^& -fo=$^@ + +.ERASE +{legacy}.c{$(OBJ_BASE)\dyn\legacy}.obj: + $(CC) $(CFLAGS) -bd .\src\lib\legacy\$^& -fo=$^@ + +.ERASE +{record}.c{$(OBJ_BASE)\dyn\record}.obj: + $(CC) $(CFLAGS) -bd .\src\lib\record\$^& -fo=$^@ + +.ERASE +{str}.c{$(OBJ_BASE)\dyn\str}.obj: + $(CC) $(CFLAGS) -bd .\src\lib\str\$^& -fo=$^@ + +.ERASE +{util}.c{$(OBJ_BASE)\dyn\util}.obj: + $(CC) $(CFLAGS) -bd .\src\lib\util\$^& -fo=$^@ + .ERASE .c{$(OBJ_BASE)\stat}.obj: $(CC) $(CFLAGS) -DCARES_STATICLIB .\src\lib\$^& -fo=$^@ +.ERASE +{dsa}.c{$(OBJ_BASE)\stat\dsa}.obj: + $(CC) $(CFLAGS) -DCARES_STATICLIB .\src\lib\dsa\$^& -fo=$^@ + +.ERASE +{event}.c{$(OBJ_BASE)\stat\event}.obj: + $(CC) $(CFLAGS) -DCARES_STATICLIB .\src\lib\event\$^& -fo=$^@ + +.ERASE +{legacy}.c{$(OBJ_BASE)\stat\legacy}.obj: + $(CC) $(CFLAGS) -DCARES_STATICLIB .\src\lib\legacy\$^& -fo=$^@ + +.ERASE +{record}.c{$(OBJ_BASE)\stat\record}.obj: + $(CC) $(CFLAGS) -DCARES_STATICLIB .\src\lib\record\$^& -fo=$^@ + +.ERASE +{str}.c{$(OBJ_BASE)\stat\str}.obj: + $(CC) $(CFLAGS) -DCARES_STATICLIB .\src\lib\str\$^& -fo=$^@ + +.ERASE +{util}.c{$(OBJ_BASE)\stat\util}.obj: + $(CC) $(CFLAGS) -DCARES_STATICLIB .\src\lib\util\$^& -fo=$^@ + $(LINK_ARG): $(__MAKEFILES__) %create $^@ @%append $^@ system nt dll diff --git a/deps/cares/Makefile.am b/deps/cares/Makefile.am index 6c71f4d77d8..e99161a45f7 100644 --- a/deps/cares/Makefile.am +++ b/deps/cares/Makefile.am @@ -22,7 +22,7 @@ AUTOMAKE_OPTIONS = foreign nostdinc 1.9.6 ACLOCAL_AMFLAGS = -I m4 --install -MSVCFILES = msvc_ver.inc buildconf.bat +MSVCFILES = buildconf.bat # adig and ahost are just sample programs and thus not mentioned with the # regular sources and headers diff --git a/deps/cares/Makefile.dj b/deps/cares/Makefile.dj index c28aefe9e22..69b3ca31851 100644 --- a/deps/cares/Makefile.dj +++ b/deps/cares/Makefile.dj @@ -5,8 +5,14 @@ # include src/lib/Makefile.inc -CSOURCES := $(addprefix src/lib/, $(CSOURCES)) -CSOURCES := $(filter-out src/lib/windows_port.c, $(CSOURCES)) +OBJ_DIR = djgpp +OBJECTS = $(addprefix $(OBJ_DIR)/, \ + $(CSOURCES:.c=.o)) + +CSRC = $(addprefix src/lib/, $(CSOURCES)) +#CSRC := $(filter-out src/lib/windows_port.c, $(CSOURCES)) + +OBJ_SUBDIRS = $(OBJ_DIR)/dsa $(OBJ_DIR)/event $(OBJ_DIR)/legacy $(OBJ_DIR)/record $(OBJ_DIR)/str $(OBJ_DIR)/util VPATH = src/lib src/tools @@ -17,8 +23,6 @@ VPATH = src/lib src/tools WATT32_ROOT = $(realpath $(WATT_ROOT)) WATT32_LIB = $(WATT32_ROOT)/lib/libwatt.a -OBJ_DIR = djgpp - CFLAGS = -g -O2 -I./include -I./src/lib \ -I$(WATT32_ROOT)/inc \ -Wall \ @@ -82,9 +86,6 @@ else CC = gcc endif -OBJECTS = $(addprefix $(OBJ_DIR)/, \ - $(notdir $(CSOURCES:.c=.o))) - GENERATED = src/lib/ares_config.h \ include/ares_build.h @@ -92,7 +93,7 @@ TARGETS = libcares.a adig.exe ahost.exe .SECONDARY: $(OBJ_DIR)/ares_getopt.o -all: $(OBJ_DIR) $(GENERATED) $(TARGETS) +all: $(OBJ_DIR) $(OBJ_SUBDIRS) $(GENERATED) $(TARGETS) @echo Welcome to c-ares. libcares.a: $(OBJECTS) @@ -111,15 +112,19 @@ include/ares_build.h: include/ares_build.h.dist # clean: - rm -f depend.dj $(GENERATED) $(OBJ_DIR)/*.o - - rmdir $(OBJ_DIR) + - rmdir $(OBJ_SUBDIRS) # Clean everything # realclean vclean: clean - rm -f $(TARGETS) $(TARGETS:.exe=.map) -$(OBJ_DIR): - - mkdir $@ +.PHONY: obj_subdirs $(OBJ_SUBDIRS) + +obj_subdirs: $(OBJ_SUBDIRS) + +$(OBJ_SUBDIRS): + mkdir $@ $(OBJ_DIR)/%.o: %.c $(CC) $(CFLAGS) -o $@ -c $< @@ -138,7 +143,7 @@ DEP_REPLACE = sed -e 's@\(.*\)\.o: @\n$$(OBJ_DIR)\/\1.o: @' \ # a foreign 'curl_config.h' is making trouble. # depend: $(GENERATED) Makefile.dj - $(CC) -MM $(CFLAGS) $(CSOURCES) | $(DEP_REPLACE) > depend.dj + $(CC) -MM $(CFLAGS) $(CSRC) | $(DEP_REPLACE) > depend.dj -include depend.dj diff --git a/deps/cares/Makefile.in b/deps/cares/Makefile.in index 7b5a962b8cc..706dafdbdfc 100644 --- a/deps/cares/Makefile.in +++ b/deps/cares/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.5 from Makefile.am. +# Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2021 Free Software Foundation, Inc. +# Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -91,6 +91,8 @@ am__make_running_with_option = \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +am__rm_f = rm -f $(am__rm_f_notfound) +am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -194,10 +196,9 @@ am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ - test -z "$$files" \ - || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ - || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ - $(am__cd) "$$dir" && rm -f $$files; }; \ + { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && echo $$files | $(am__xargs_n) 40 $(am__rm_f); }; \ } am__installdirs = "$(DESTDIR)$(pkgconfigdir)" DATA = $(pkgconfig_DATA) @@ -238,8 +239,8 @@ distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) am__remove_distdir = \ if test -d "$(distdir)"; then \ - find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ - && rm -rf "$(distdir)" \ + find "$(distdir)" -type d ! -perm -700 -exec chmod u+rwx {} ';' \ + ; rm -rf "$(distdir)" \ || { sleep 5 && rm -rf "$(distdir)"; }; \ else :; fi am__post_remove_distdir = $(am__remove_distdir) @@ -269,14 +270,16 @@ am__relativize = \ done; \ reldir="$$dir2" DIST_ARCHIVES = $(distdir).tar.gz -GZIP_ENV = --best +GZIP_ENV = -9 DIST_TARGETS = dist-gzip # Exists only to be overridden by the user if desired. AM_DISTCHECK_DVI_TARGET = dvi distuninstallcheck_listfiles = find . -type f -print am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' -distcleancheck_listfiles = find . -type f -print +distcleancheck_listfiles = \ + find . \( -type f -a \! \ + \( -name .nfs* -o -name .smb* -o -name .__afs* \) \) -print ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ @@ -325,6 +328,8 @@ FGREP = @FGREP@ FILECMD = @FILECMD@ GCOV = @GCOV@ GENHTML = @GENHTML@ +GMOCK112_CFLAGS = @GMOCK112_CFLAGS@ +GMOCK112_LIBS = @GMOCK112_LIBS@ GMOCK_CFLAGS = @GMOCK_CFLAGS@ GMOCK_LIBS = @GMOCK_LIBS@ GREP = @GREP@ @@ -387,8 +392,10 @@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ +am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ +am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ @@ -435,7 +442,7 @@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AUTOMAKE_OPTIONS = foreign nostdinc 1.9.6 ACLOCAL_AMFLAGS = -I m4 --install -MSVCFILES = msvc_ver.inc buildconf.bat +MSVCFILES = buildconf.bat # adig and ahost are just sample programs and thus not mentioned with the # regular sources and headers @@ -634,7 +641,7 @@ distdir: $(BUILT_SOURCES) distdir-am: $(DISTFILES) $(am__remove_distdir) - test -d "$(distdir)" || mkdir "$(distdir)" + $(AM_V_at)$(MKDIR_P) "$(distdir)" @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ @@ -748,7 +755,7 @@ dist dist-all: distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ - eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\ + eval GZIP= gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lz*) \ @@ -758,7 +765,7 @@ distcheck: dist *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ - eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\ + eval GZIP= gzip -dc $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ *.tar.zst*) \ @@ -859,12 +866,12 @@ install-strip: mostlyclean-generic: clean-generic: - -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + -$(am__rm_f) $(CLEANFILES) distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) + -$(am__rm_f) $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) + -$(am__rm_f) $(DISTCLEANFILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @@ -973,3 +980,10 @@ dist-hook: # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: + +# Tell GNU make to disable its built-in pattern rules. +%:: %,v +%:: RCS/%,v +%:: RCS/% +%:: s.% +%:: SCCS/s.% diff --git a/deps/cares/Makefile.msvc b/deps/cares/Makefile.msvc index 4b338f27999..619c2d39274 100644 --- a/deps/cares/Makefile.msvc +++ b/deps/cares/Makefile.msvc @@ -75,11 +75,6 @@ RTLIBD = /MTd USE_WATT32 = 0 !ENDIF -# -------------------------------------------------------- -# Detect compiler version. -# -------------------------------------------------------- -!INCLUDE .\msvc_ver.inc - # ---------------------------------------------------- # Verify that current subdir is the c-ares source one # ---------------------------------------------------- @@ -190,30 +185,13 @@ EX_LIBS_REL = ws2_32.lib advapi32.lib kernel32.lib iphlpapi.lib EX_LIBS_DBG = ws2_32.lib advapi32.lib kernel32.lib iphlpapi.lib !ENDIF -# ------------------------------------------------- -# Switches that depend on ancient compiler versions -# ------------------------------------------------- - -!IF $(CC_VERS_NUM) == 60 -PDB_NONE = /pdb:none -PDBTYPE_CONSOLIDATE = /pdbtype:consolidate -!ELSE -!UNDEF PDB_NONE -!UNDEF PDBTYPE_CONSOLIDATE -!ENDIF - -!IF $(CC_VERS_NUM) <= 70 -RT_ERROR_CHECKING = /GZ -!ELSE -RT_ERROR_CHECKING = /RTCsu -!ENDIF # ---------------------------- # Assorted commands and flags # ---------------------------- CC_CMD_REL = cl.exe /nologo $(RTLIB) /DNDEBUG /O2 -CC_CMD_DBG = cl.exe /nologo $(RTLIBD) /D_DEBUG /Od /Zi $(RT_ERROR_CHECKING) +CC_CMD_DBG = cl.exe /nologo $(RTLIBD) /D_DEBUG /Od /Zi /RTCsu CC_CFLAGS = $(CFLAGS) /D_REENTRANT /I.\src\lib /I.\include /W3 /EHsc /FD RC_CMD_REL = rc.exe /l 0x409 /d "NDEBUG" @@ -223,8 +201,8 @@ LINK_CMD_LIB = link.exe /lib /nologo LINK_CMD_DLL = link.exe /dll /nologo /incremental:no /fixed:no LINK_CMD_EXE = link.exe /nologo /incremental:no /fixed:no /subsystem:console -LINK_CMD_EXE_REL = $(LINK_CMD_EXE) /release $(PDB_NONE) -LINK_CMD_EXE_DBG = $(LINK_CMD_EXE) /debug $(PDBTYPE_CONSOLIDATE) +LINK_CMD_EXE_REL = $(LINK_CMD_EXE) /release +LINK_CMD_EXE_DBG = $(LINK_CMD_EXE) /debug # --------------------------------- # Configuration dependent settings @@ -255,7 +233,7 @@ CC_CMD = $(CC_CMD_DBG) !IF "$(CFG)" == "dll-release" CARES_TARGET = $(DYN_LIB_REL).dll CARES_CFLAGS = /DCARES_BUILDING_LIBRARY -CARES_LFLAGS = /release $(EX_LIBS_REL) /implib:$(CARES_OUTDIR)\$(IMP_LIB_REL).lib $(PDB_NONE) +CARES_LFLAGS = /release $(EX_LIBS_REL) /implib:$(CARES_OUTDIR)\$(IMP_LIB_REL).lib SPROG_CFLAGS = /DCARES_NO_DEPRECATED SPROG_LFLAGS = /libpath:$(CARES_OUTDIR) $(EX_LIBS_REL) $(IMP_LIB_REL).lib CARES_LINK = $(LINK_CMD_DLL) @@ -268,7 +246,7 @@ RC_CMD = $(RC_CMD_REL) !IF "$(CFG)" == "dll-debug" CARES_TARGET = $(DYN_LIB_DBG).dll CARES_CFLAGS = /DCARES_BUILDING_LIBRARY /DDEBUGBUILD -CARES_LFLAGS = /debug $(EX_LIBS_DBG) /implib:$(CARES_OUTDIR)\$(IMP_LIB_DBG).lib /pdb:$(CARES_OUTDIR)\$(DYN_LIB_DBG).pdb $(PDBTYPE_CONSOLIDATE) +CARES_LFLAGS = /debug $(EX_LIBS_DBG) /implib:$(CARES_OUTDIR)\$(IMP_LIB_DBG).lib /pdb:$(CARES_OUTDIR)\$(DYN_LIB_DBG).pdb SPROG_CFLAGS = /DCARES_NO_DEPRECATED SPROG_LFLAGS = /libpath:$(CARES_OUTDIR) $(EX_LIBS_DBG) $(IMP_LIB_DBG).lib CARES_LINK = $(LINK_CMD_DLL) @@ -299,6 +277,7 @@ RC_CMD = $(RC_CMD_DBG) !ERROR Problem generating CARES_OBJS list. !ENDIF CARES_OBJS = $(CARES_OBJS:.c=.obj) +CARES_OBJS = $(CARES_OBJS:/=\) !IF "$(USE_RES_FILE)" == "TRUE" CARES_OBJS = $(CARES_OBJS) $(CARES_OBJDIR)\cares.res !ENDIF @@ -341,20 +320,38 @@ PROG3_OBJS = $(PROG3_OBJS) $(PROG3_OBJDIR)\ahost.obj {$(SRCDIR)\src\lib}.c{$(CARES_OBJDIR)}.obj: $(CC_CMD) $(CC_CFLAGS) $(CARES_CFLAGS) /Fo$@ /Fd$(@D)\ /c $< +{$(SRCDIR)\src\lib\dsa}.c{$(CARES_OBJDIR)\dsa}.obj: + $(CC_CMD) $(CC_CFLAGS) $(CARES_CFLAGS) /Fo$@ /Fd$(@D)\ /c $< + +{$(SRCDIR)\src\lib\event}.c{$(CARES_OBJDIR)\event}.obj: + $(CC_CMD) $(CC_CFLAGS) $(CARES_CFLAGS) /Fo$@ /Fd$(@D)\ /c $< + +{$(SRCDIR)\src\lib\legacy}.c{$(CARES_OBJDIR)\legacy}.obj: + $(CC_CMD) $(CC_CFLAGS) $(CARES_CFLAGS) /Fo$@ /Fd$(@D)\ /c $< + +{$(SRCDIR)\src\lib\record}.c{$(CARES_OBJDIR)\record}.obj: + $(CC_CMD) $(CC_CFLAGS) $(CARES_CFLAGS) /Fo$@ /Fd$(@D)\ /c $< + +{$(SRCDIR)\src\lib\str}.c{$(CARES_OBJDIR)\str}.obj: + $(CC_CMD) $(CC_CFLAGS) $(CARES_CFLAGS) /Fo$@ /Fd$(@D)\ /c $< + +{$(SRCDIR)\src\lib\util}.c{$(CARES_OBJDIR)\util}.obj: + $(CC_CMD) $(CC_CFLAGS) $(CARES_CFLAGS) /Fo$@ /Fd$(@D)\ /c $< + {$(SRCDIR)\src\tools}.c{$(PROG2_OBJDIR)}.obj: - $(CC_CMD) $(CC_CFLAGS) $(SPROG_CFLAGS) /Fo$@ /Fd$(@D)\ /c $< + $(CC_CMD) $(CC_CFLAGS) $(SPROG_CFLAGS) /Fo$@ /Fd$(PROG2_OBJDIR)\ /c $< {$(SRCDIR)\src\tools}.c{$(PROG3_OBJDIR)}.obj: - $(CC_CMD) $(CC_CFLAGS) $(SPROG_CFLAGS) /Fo$@ /Fd$(@D)\ /c $< + $(CC_CMD) $(CC_CFLAGS) $(SPROG_CFLAGS) /Fo$@ /Fd$(PROG3_OBJDIR)\ /c $< -# Hack Alert! we reference ../lib/ files in the Makefile.inc for tools as they +# Hack Alert! we reference ../lib/str files in the Makefile.inc for tools as they # share some files with the library itself. We need to hack around that here. -{$(SRCDIR)\src\lib}.c{$(PROG2_OBJDIR)\..\lib}.obj: - $(CC_CMD) $(CC_CFLAGS) $(SPROG_CFLAGS) /Fo$(PROG2_OBJDIR)\$(@F) /Fd$(PROG2_OBJDIR)\ /c $< +{$(SRCDIR)\src\lib\str}.c{$(PROG2_OBJDIR)\..\lib\str}.obj: + $(CC_CMD) $(CC_CFLAGS) $(SPROG_CFLAGS) /Fo$(PROG2_OBJDIR)\str\$(@F) /Fd$(PROG2_OBJDIR)\str\ /c $< -{$(SRCDIR)\src\lib}.c{$(PROG3_OBJDIR)\..\lib}.obj: - $(CC_CMD) $(CC_CFLAGS) $(SPROG_CFLAGS) /Fo$(PROG3_OBJDIR)\$(@F) /Fd$(PROG3_OBJDIR)\ /c $< +{$(SRCDIR)\src\lib\str}.c{$(PROG3_OBJDIR)\..\lib\str}.obj: + $(CC_CMD) $(CC_CFLAGS) $(SPROG_CFLAGS) /Fo$(PROG3_OBJDIR)\str\$(@F) /Fd$(PROG3_OBJDIR)\str\ /c $< # ------------------------------------------------------------- # # ------------------------------------------------------------- # @@ -419,16 +416,32 @@ $(PROG3_OUTDIR): $(PROG3_DIR) $(CARES_OBJDIR): $(CARES_OUTDIR) @if not exist $(CARES_OBJDIR) mkdir $(CARES_OBJDIR) + @if not exist $(CARES_OBJDIR)\dsa mkdir $(CARES_OBJDIR)\dsa + @if not exist $(CARES_OBJDIR)\event mkdir $(CARES_OBJDIR)\event + @if not exist $(CARES_OBJDIR)\legacy mkdir $(CARES_OBJDIR)\legacy + @if not exist $(CARES_OBJDIR)\record mkdir $(CARES_OBJDIR)\record + @if not exist $(CARES_OBJDIR)\str mkdir $(CARES_OBJDIR)\str + @if not exist $(CARES_OBJDIR)\util mkdir $(CARES_OBJDIR)\util $(PROG2_OBJDIR): $(PROG2_OUTDIR) @if not exist $(PROG2_OBJDIR) mkdir $(PROG2_OBJDIR) + @if not exist $(PROG2_OBJDIR)\str mkdir $(PROG2_OBJDIR)\str $(PROG3_OBJDIR): $(PROG3_OUTDIR) @if not exist $(PROG3_OBJDIR) mkdir $(PROG3_OBJDIR) + @if not exist $(PROG3_OBJDIR)\str mkdir $(PROG3_OBJDIR)\str clean: + @-RMDIR /S /Q $(CARES_OBJDIR)\dsa >NUL 2>&1 + @-RMDIR /S /Q $(CARES_OBJDIR)\event >NUL 2>&1 + @-RMDIR /S /Q $(CARES_OBJDIR)\legacy >NUL 2>&1 + @-RMDIR /S /Q $(CARES_OBJDIR)\record >NUL 2>&1 + @-RMDIR /S /Q $(CARES_OBJDIR)\str >NUL 2>&1 + @-RMDIR /S /Q $(CARES_OBJDIR)\util >NUL 2>&1 @-RMDIR /S /Q $(CARES_OUTDIR) >NUL 2>&1 + @-RMDIR /S /Q $(PROG2_OBJDIR)\str >NUL 2>&1 @-RMDIR /S /Q $(PROG2_OUTDIR) >NUL 2>&1 + @-RMDIR /S /Q $(PROG3_OBJDIR)\str >NUL 2>&1 @-RMDIR /S /Q $(PROG3_OUTDIR) >NUL 2>&1 install: diff --git a/deps/cares/README.md b/deps/cares/README.md index 86b25bc3159..c32d0677c83 100644 --- a/deps/cares/README.md +++ b/deps/cares/README.md @@ -8,6 +8,14 @@ [![Bugs](https://sonarcloud.io/api/project_badges/measure?project=c-ares_c-ares&metric=bugs)](https://sonarcloud.io/summary/new_code?id=c-ares_c-ares) [![Coverity Scan Status](https://scan.coverity.com/projects/c-ares/badge.svg)](https://scan.coverity.com/projects/c-ares) +- [Overview](#overview) +- [Code](#code) +- [Communication](#communication) +- [Release Keys](#release-keys) + - [Verifying signatures](#verifying-signatures) +- [Features](#features) + - [RFCs and Proposals](#supported-rfcs-and-proposals) + ## Overview [c-ares](https://c-ares.org) is a modern DNS (stub) resolver library, written in C. It provides interfaces for asynchronous queries while trying to abstract the @@ -99,3 +107,47 @@ gpg: There is no indication that the signature belongs to the owner. Primary key fingerprint: 27ED EAF2 2F3A BCEB 50DB 9A12 5CC9 08FD B71E 12C2 gpg: binary signature, digest algorithm SHA512, key algorithm rsa2048 ``` + +## Features +### Supported RFCs and Proposals +- [RFC1035](https://datatracker.ietf.org/doc/html/rfc7873). + Initial/Base DNS RFC +- [RFC2671](https://datatracker.ietf.org/doc/html/rfc2671), + [RFC6891](https://datatracker.ietf.org/doc/html/rfc6891). + EDNS0 option (meta-RR) +- [RFC3596](https://datatracker.ietf.org/doc/html/rfc3596). + IPv6 Address. `AAAA` Record. +- [RFC2782](https://datatracker.ietf.org/doc/html/rfc2782). + Server Selection. `SRV` Record. +- [RFC3403](https://datatracker.ietf.org/doc/html/rfc3403). + Naming Authority Pointer. `NAPTR` Record. +- [RFC6698](https://datatracker.ietf.org/doc/html/rfc6698). + DNS-Based Authentication of Named Entities (DANE) Transport Layer Security (TLS) Protocol. + `TLSA` Record. +- [RFC9460](https://datatracker.ietf.org/doc/html/rfc9460). + General Purpose Service Binding, Service Binding type for use with HTTPS. + `SVCB` and `HTTPS` Records. +- [RFC7553](https://datatracker.ietf.org/doc/html/rfc7553). + Uniform Resource Identifier. `URI` Record. +- [RFC6844](https://datatracker.ietf.org/doc/html/rfc6844). + Certification Authority Authorization. `CAA` Record. +- [RFC2535](https://datatracker.ietf.org/doc/html/rfc2535), + [RFC2931](https://datatracker.ietf.org/doc/html/rfc2931). + `SIG0` Record. Only basic parser, not full implementation. +- [RFC7873](https://datatracker.ietf.org/doc/html/rfc7873), + [RFC9018](https://datatracker.ietf.org/doc/html/rfc9018). + DNS Cookie off-path dns poisoning and amplification mitigation. +- [draft-vixie-dnsext-dns0x20-00](https://datatracker.ietf.org/doc/html/draft-vixie-dnsext-dns0x20-00). + DNS 0x20 query name case randomization to prevent cache poisioning attacks. +- [RFC7686](https://datatracker.ietf.org/doc/html/rfc7686). + Reject queries for `.onion` domain names with `NXDOMAIN`. +- [RFC2606](https://datatracker.ietf.org/doc/html/rfc2606), + [RFC6761](https://datatracker.ietf.org/doc/html/rfc6761). + Special case treatment for `localhost`/`.localhost`. +- [RFC2308](https://datatracker.ietf.org/doc/html/rfc2308), + [RFC9520](https://datatracker.ietf.org/doc/html/rfc9520). + Negative Caching of DNS Resolution Failures. +- [RFC6724](https://datatracker.ietf.org/doc/html/rfc6724). + IPv6 address sorting as used by `ares_getaddrinfo()`. +- [RFC7413](https://datatracker.ietf.org/doc/html/rfc7413). + TCP FastOpen (TFO) for 0-RTT TCP Connection Resumption. diff --git a/deps/cares/RELEASE-NOTES.md b/deps/cares/RELEASE-NOTES.md index 69e6a475799..e9c04953dc6 100644 --- a/deps/cares/RELEASE-NOTES.md +++ b/deps/cares/RELEASE-NOTES.md @@ -1,98 +1,65 @@ -## c-ares version 1.32.3 - July 24 2024 +## c-ares version 1.33.1 - August 23 2024 This is a bugfix release. -Changes: -* Prevent complex recursion during query requeuing and connection cleanup for - stability. [e8b32b8](https://github.com/c-ares/c-ares/commit/e8b32b8) -* Better propagate error codes on requeue situations. - [a9bc0a2](https://github.com/c-ares/c-ares/commit/a9bc0a2) -* Try to prevent SIGPIPE from being generated and delivered to integrations. - [de01baa](https://github.com/c-ares/c-ares/commit/de01baa) - Bugfixes: -* Missing manpage for `ares_dns_record_set_id()` - [aa462b3](https://github.com/c-ares/c-ares/commit/aa462b3) -* Memory leak in `ares__hosts_entry_to_hostent()` due to allocation strategy. - [PR #824](https://github.com/c-ares/c-ares/pull/824) -* UDP write failure detected via ICMP unreachable should trigger faster - failover. [PR #821](https://github.com/c-ares/c-ares/pull/821) -* Fix pycares test case regression due to wrong error code being returned. - Regression from 1.31.0. [PR #820](https://github.com/c-ares/c-ares/pull/820) -* Fix possible Windows crash during `ares_destroy()` when using event threads. - [5609bd4](https://github.com/c-ares/c-ares/commit/5609bd4) -* `ARES_OPT_MAXTIMEOUTMS` wasn't being honored in all cases. - [a649c60](https://github.com/c-ares/c-ares/commit/a649c60) - -## c-ares version 1.32.2 - July 15 2024 - -This is a bugfix release. - -Bugfixes: - -* Windows: rework EventThread AFD code for better stability. - [PR #811](https://github.com/c-ares/c-ares/pull/811) -* Windows: If an IP address was detected to have changed, it could lead to a - crash due to a bad pointer. Regression introduced in 1.31.0. - [59e3a1f4](https://github.com/c-ares/c-ares/commit/59e3a1f4) -* Windows: use `QueryPerformanceCounters()` instead of `GetTickCount64()` for - better time accuracy (~15ms -> ~1us). -* Windows 32bit config change callback needs to be tagged as `stdcall` otherwise - could result in a crash. - [5c2bab35](https://github.com/c-ares/c-ares/commit/5c2bab35) -* Tests that need accurate timing should not depend on internal symbols as there - are C++ equivalents in `std::chrono`. - [PR #809](https://github.com/c-ares/c-ares/pull/809) -* Kqueue (MacOS, \*BSD): If the open socket count exceeded 8 (unlikely), it - would try to allocate a new buffer that was too small. - [5aad7981](https://github.com/c-ares/c-ares/commit/5aad7981) - - -## c-ares version 1.32.1 - July 7 2024 - -This is a bugfix release. - -Bugfixes: -* Channel lock needs to be recursive to ensure calls into c-ares functions can - be made from callbacks otherwise deadlocks will occur. This regression was - introduced in 1.32.0. +* Work around systemd-resolved quirk that returns unexpected codes for single + label names. Also adds test cases to validate the work around works and + will continue to work in future releases. + [PR #863](https://github.com/c-ares/c-ares/pull/863), + See Also https://github.com/systemd/systemd/issues/34101 +* Fix sysconfig ndots default value, also adds containerized test case to + prevent future regressions. + [PR #862](https://github.com/c-ares/c-ares/pull/862) +* Fix blank DNS name returning error code rather than valid record for + commands like: `adig -t SOA .`. Also adds test case to prevent future + regressions. + [9e574af](https://github.com/c-ares/c-ares/commit/9e574af) +* Fix calculation of query times > 1s. + [2b2eae7](https://github.com/c-ares/c-ares/commit/2b2eae7) +* Fix building on old Linux releases that don't have `TCP_FASTOPEN_CONNECT`. + [b7a89b9](https://github.com/c-ares/c-ares/commit/b7a89b9) +* Fix minor Android build warnings. + [PR #848](https://github.com/c-ares/c-ares/pull/848) +Thanks go to these friendly people for their efforts and contributions for this +release: +* Brad House (@bradh352) +* Erik Lax (@eriklax) +* Hans-Christian Egtvedt (@egtvedt) +* Mikael Lindemann (@mikaellindemann) +* Nodar Chkuaselidze (@nodech) -## c-ares version 1.32.0 - July 4 2024 +## c-ares version 1.33.0 - August 2 2024 This is a feature and bugfix release. Features: - -* Add support for DNS 0x20 to help prevent cache poisoning attacks, enabled - by specifying `ARES_FLAG_DNS0x20`. Disabled by default. [PR #800](https://github.com/c-ares/c-ares/pull/800) -* Rework query timeout logic to automatically adjust timeouts based on network - conditions. The timeout specified now is only used as a hint until there - is enough history to calculate a more valid timeout. [PR #794](https://github.com/c-ares/c-ares/pull/794) +* Add DNS cookie support (RFC7873 + RFC9018) to help prevent off-path cache + poisoning attacks. [PR #833](https://github.com/c-ares/c-ares/pull/833) +* Implement TCP FastOpen (TFO) RFC7413, which will make TCP reconnects 0-RTT + on supported systems. [PR #840](https://github.com/c-ares/c-ares/pull/840) Changes: - -* DNS RR TXT strings should not be automatically concatenated as there are use - cases outside of RFC 7208. In order to maintain ABI compliance, the ability - to retrieve TXT strings concatenated is retained as well as a new API to - retrieve the individual strings. This restores behavior from c-ares 1.20.0. - [PR #801](https://github.com/c-ares/c-ares/pull/801) -* Clean up header inclusion logic to make hacking on code easier. [PR #797](https://github.com/c-ares/c-ares/pull/797) -* GCC/Clang: Enable even more strict warnings to catch more coding flaws. [253bdee](https://github.com/c-ares/c-ares/commit/253bdee) -* MSVC: Enable `/W4` warning level. [PR #792](https://github.com/c-ares/c-ares/pull/792) +* Reorganize source tree. [PR #822](https://github.com/c-ares/c-ares/pull/822) +* Refactoring of connection handling to prevent code duplication. + [PR #839](https://github.com/c-ares/c-ares/pull/839) +* New dynamic array data structure to prevent simple logic flaws in array + handling in various code paths. + [PR #841](https://github.com/c-ares/c-ares/pull/841) Bugfixes: +* `ares_destroy()` race condition during shutdown due to missing lock. + [PR #831](https://github.com/c-ares/c-ares/pull/831) +* Android: Preserve thread name after attaching it to JVM. + [PR #838](https://github.com/c-ares/c-ares/pull/838) +* Windows UWP (Store) support fix. + [PR #845](https://github.com/c-ares/c-ares/pull/845) -* Tests: Fix thread race condition in test cases for EventThread. [PR #803](https://github.com/c-ares/c-ares/pull/803) -* Windows: Fix building with UNICODE. [PR #802](https://github.com/c-ares/c-ares/pull/802) -* Thread Saftey: `ares_timeout()` was missing lock. [74a64e4](https://github.com/c-ares/c-ares/commit/74a64e4) -* Fix building with DJGPP (32bit protected mode DOS). [PR #789](https://github.com/c-ares/c-ares/pull/789) Thanks go to these friendly people for their efforts and contributions for this release: * Brad House (@bradh352) -* Cheng (@zcbenz) - - +* Yauheni Khnykin (@Hsilgos) diff --git a/deps/cares/aclocal.m4 b/deps/cares/aclocal.m4 index dc4eb963d54..68e283c8e59 100644 --- a/deps/cares/aclocal.m4 +++ b/deps/cares/aclocal.m4 @@ -1,6 +1,6 @@ -# generated automatically by aclocal 1.16.5 -*- Autoconf -*- +# generated automatically by aclocal 1.17 -*- Autoconf -*- -# Copyright (C) 1996-2021 Free Software Foundation, Inc. +# Copyright (C) 1996-2024 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -20,7 +20,7 @@ You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically 'autoreconf'.])]) -# Copyright (C) 2002-2021 Free Software Foundation, Inc. +# Copyright (C) 2002-2024 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -32,10 +32,10 @@ To do so, use the procedure documented by the package, typically 'autoreconf'.]) # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], -[am__api_version='1.16' +[am__api_version='1.17' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. -m4_if([$1], [1.16.5], [], +m4_if([$1], [1.17], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) @@ -51,14 +51,14 @@ m4_define([_AM_AUTOCONF_VERSION], []) # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], -[AM_AUTOMAKE_VERSION([1.16.5])dnl +[AM_AUTOMAKE_VERSION([1.17])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- -# Copyright (C) 2001-2021 Free Software Foundation, Inc. +# Copyright (C) 2001-2024 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -110,7 +110,7 @@ am_aux_dir=`cd "$ac_aux_dir" && pwd` # AM_COND_IF -*- Autoconf -*- -# Copyright (C) 2008-2021 Free Software Foundation, Inc. +# Copyright (C) 2008-2024 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -147,7 +147,7 @@ fi[]dnl # AM_CONDITIONAL -*- Autoconf -*- -# Copyright (C) 1997-2021 Free Software Foundation, Inc. +# Copyright (C) 1997-2024 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -178,7 +178,7 @@ AC_CONFIG_COMMANDS_PRE( Usually this means the macro was only invoked conditionally.]]) fi])]) -# Copyright (C) 1999-2021 Free Software Foundation, Inc. +# Copyright (C) 1999-2024 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -310,7 +310,7 @@ AC_CACHE_CHECK([dependency style of $depcc], # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. - # When given -MP, icc 7.0 and 7.1 complain thusly: + # When given -MP, icc 7.0 and 7.1 complain thus: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported @@ -369,7 +369,7 @@ _AM_SUBST_NOTMAKE([am__nodep])dnl # Generate code to set up dependency tracking. -*- Autoconf -*- -# Copyright (C) 1999-2021 Free Software Foundation, Inc. +# Copyright (C) 1999-2024 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -437,7 +437,7 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], # Do all the work for Automake. -*- Autoconf -*- -# Copyright (C) 1996-2021 Free Software Foundation, Inc. +# Copyright (C) 1996-2024 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -571,7 +571,7 @@ if test -z "$CSCOPE"; then fi AC_SUBST([CSCOPE]) -AC_REQUIRE([AM_SILENT_RULES])dnl +AC_REQUIRE([_AM_SILENT_RULES])dnl dnl The testsuite driver may need to know about EXEEXT, so add the dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. @@ -579,47 +579,9 @@ AC_CONFIG_COMMANDS_PRE(dnl [m4_provide_if([_AM_COMPILER_EXEEXT], [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl -# POSIX will say in a future version that running "rm -f" with no argument -# is OK; and we want to be able to make that assumption in our Makefile -# recipes. So use an aggressive probe to check that the usage we want is -# actually supported "in the wild" to an acceptable degree. -# See automake bug#10828. -# To make any issue more visible, cause the running configure to be aborted -# by default if the 'rm' program in use doesn't match our expectations; the -# user can still override this though. -if rm -f && rm -fr && rm -rf; then : OK; else - cat >&2 <<'END' -Oops! - -Your 'rm' program seems unable to run without file operands specified -on the command line, even when the '-f' option is present. This is contrary -to the behaviour of most rm programs out there, and not conforming with -the upcoming POSIX standard: - -Please tell bug-automake@gnu.org about your system, including the value -of your $PATH and any error possibly output before this message. This -can help us improve future automake versions. +AC_REQUIRE([_AM_PROG_RM_F]) +AC_REQUIRE([_AM_PROG_XARGS_N]) -END - if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then - echo 'Configuration will proceed anyway, since you have set the' >&2 - echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 - echo >&2 - else - cat >&2 <<'END' -Aborting the configuration process, to ensure you take notice of the issue. - -You can download and install GNU coreutils to get an 'rm' implementation -that behaves properly: . - -If you want to complete the configuration process using your problematic -'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM -to "yes", and re-run configure. - -END - AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) - fi -fi dnl The trailing newline in this macro's definition is deliberate, for dnl backward compatibility and to allow trailing 'dnl'-style comments dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841. @@ -652,7 +614,7 @@ for _am_header in $config_headers :; do done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) -# Copyright (C) 2001-2021 Free Software Foundation, Inc. +# Copyright (C) 2001-2024 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -673,7 +635,7 @@ if test x"${install_sh+set}" != xset; then fi AC_SUBST([install_sh])]) -# Copyright (C) 2003-2021 Free Software Foundation, Inc. +# Copyright (C) 2003-2024 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -695,7 +657,7 @@ AC_SUBST([am__leading_dot])]) # Add --enable-maintainer-mode option to configure. -*- Autoconf -*- # From Jim Meyering -# Copyright (C) 1996-2021 Free Software Foundation, Inc. +# Copyright (C) 1996-2024 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -730,7 +692,7 @@ AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) # Check to see how 'make' treats includes. -*- Autoconf -*- -# Copyright (C) 2001-2021 Free Software Foundation, Inc. +# Copyright (C) 2001-2024 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -773,7 +735,7 @@ AC_SUBST([am__quote])]) # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- -# Copyright (C) 1997-2021 Free Software Foundation, Inc. +# Copyright (C) 1997-2024 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -807,7 +769,7 @@ fi # Helper functions for option handling. -*- Autoconf -*- -# Copyright (C) 2001-2021 Free Software Foundation, Inc. +# Copyright (C) 2001-2024 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -836,7 +798,7 @@ AC_DEFUN([_AM_SET_OPTIONS], AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) -# Copyright (C) 1999-2021 Free Software Foundation, Inc. +# Copyright (C) 1999-2024 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -883,7 +845,23 @@ AC_LANG_POP([C])]) # For backward compatibility. AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) -# Copyright (C) 2001-2021 Free Software Foundation, Inc. +# Copyright (C) 2022-2024 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_PROG_RM_F +# --------------- +# Check whether 'rm -f' without any arguments works. +# https://bugs.gnu.org/10828 +AC_DEFUN([_AM_PROG_RM_F], +[am__rm_f_notfound= +AS_IF([(rm -f && rm -fr && rm -rf) 2>/dev/null], [], [am__rm_f_notfound='""']) +AC_SUBST(am__rm_f_notfound) +]) + +# Copyright (C) 2001-2024 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -902,16 +880,169 @@ AC_DEFUN([AM_RUN_LOG], # Check to make sure that the build environment is sane. -*- Autoconf -*- -# Copyright (C) 1996-2021 Free Software Foundation, Inc. +# Copyright (C) 1996-2024 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. +# _AM_SLEEP_FRACTIONAL_SECONDS +# ---------------------------- +AC_DEFUN([_AM_SLEEP_FRACTIONAL_SECONDS], [dnl +AC_CACHE_CHECK([whether sleep supports fractional seconds], + am_cv_sleep_fractional_seconds, [dnl +AS_IF([sleep 0.001 2>/dev/null], [am_cv_sleep_fractional_seconds=yes], + [am_cv_sleep_fractional_seconds=no]) +])]) + +# _AM_FILESYSTEM_TIMESTAMP_RESOLUTION +# ----------------------------------- +# Determine the filesystem's resolution for file modification +# timestamps. The coarsest we know of is FAT, with a resolution +# of only two seconds, even with the most recent "exFAT" extensions. +# The finest (e.g. ext4 with large inodes, XFS, ZFS) is one +# nanosecond, matching clock_gettime. However, it is probably not +# possible to delay execution of a shell script for less than one +# millisecond, due to process creation overhead and scheduling +# granularity, so we don't check for anything finer than that. (See below.) +AC_DEFUN([_AM_FILESYSTEM_TIMESTAMP_RESOLUTION], [dnl +AC_REQUIRE([_AM_SLEEP_FRACTIONAL_SECONDS]) +AC_CACHE_CHECK([filesystem timestamp resolution], + am_cv_filesystem_timestamp_resolution, [dnl +# Default to the worst case. +am_cv_filesystem_timestamp_resolution=2 + +# Only try to go finer than 1 sec if sleep can do it. +# Don't try 1 sec, because if 0.01 sec and 0.1 sec don't work, +# - 1 sec is not much of a win compared to 2 sec, and +# - it takes 2 seconds to perform the test whether 1 sec works. +# +# Instead, just use the default 2s on platforms that have 1s resolution, +# accept the extra 1s delay when using $sleep in the Automake tests, in +# exchange for not incurring the 2s delay for running the test for all +# packages. +# +am_try_resolutions= +if test "$am_cv_sleep_fractional_seconds" = yes; then + # Even a millisecond often causes a bunch of false positives, + # so just try a hundredth of a second. The time saved between .001 and + # .01 is not terribly consequential. + am_try_resolutions="0.01 0.1 $am_try_resolutions" +fi + +# In order to catch current-generation FAT out, we must *modify* files +# that already exist; the *creation* timestamp is finer. Use names +# that make ls -t sort them differently when they have equal +# timestamps than when they have distinct timestamps, keeping +# in mind that ls -t prints the *newest* file first. +rm -f conftest.ts? +: > conftest.ts1 +: > conftest.ts2 +: > conftest.ts3 + +# Make sure ls -t actually works. Do 'set' in a subshell so we don't +# clobber the current shell's arguments. (Outer-level square brackets +# are removed by m4; they're present so that m4 does not expand +# ; be careful, easy to get confused.) +if ( + set X `[ls -t conftest.ts[12]]` && + { + test "$[]*" != "X conftest.ts1 conftest.ts2" || + test "$[]*" != "X conftest.ts2 conftest.ts1"; + } +); then :; else + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + _AS_ECHO_UNQUOTED( + ["Bad output from ls -t: \"`[ls -t conftest.ts[12]]`\""], + [AS_MESSAGE_LOG_FD]) + AC_MSG_FAILURE([ls -t produces unexpected output. +Make sure there is not a broken ls alias in your environment.]) +fi + +for am_try_res in $am_try_resolutions; do + # Any one fine-grained sleep might happen to cross the boundary + # between two values of a coarser actual resolution, but if we do + # two fine-grained sleeps in a row, at least one of them will fall + # entirely within a coarse interval. + echo alpha > conftest.ts1 + sleep $am_try_res + echo beta > conftest.ts2 + sleep $am_try_res + echo gamma > conftest.ts3 + + # We assume that 'ls -t' will make use of high-resolution + # timestamps if the operating system supports them at all. + if (set X `ls -t conftest.ts?` && + test "$[]2" = conftest.ts3 && + test "$[]3" = conftest.ts2 && + test "$[]4" = conftest.ts1); then + # + # Ok, ls -t worked. If we're at a resolution of 1 second, we're done, + # because we don't need to test make. + make_ok=true + if test $am_try_res != 1; then + # But if we've succeeded so far with a subsecond resolution, we + # have one more thing to check: make. It can happen that + # everything else supports the subsecond mtimes, but make doesn't; + # notably on macOS, which ships make 3.81 from 2006 (the last one + # released under GPLv2). https://bugs.gnu.org/68808 + # + # We test $MAKE if it is defined in the environment, else "make". + # It might get overridden later, but our hope is that in practice + # it does not matter: it is the system "make" which is (by far) + # the most likely to be broken, whereas if the user overrides it, + # probably they did so with a better, or at least not worse, make. + # https://lists.gnu.org/archive/html/automake/2024-06/msg00051.html + # + # Create a Makefile (real tab character here): + rm -f conftest.mk + echo 'conftest.ts1: conftest.ts2' >conftest.mk + echo ' touch conftest.ts2' >>conftest.mk + # + # Now, running + # touch conftest.ts1; touch conftest.ts2; make + # should touch ts1 because ts2 is newer. This could happen by luck, + # but most often, it will fail if make's support is insufficient. So + # test for several consecutive successes. + # + # (We reuse conftest.ts[12] because we still want to modify existing + # files, not create new ones, per above.) + n=0 + make=${MAKE-make} + until test $n -eq 3; do + echo one > conftest.ts1 + sleep $am_try_res + echo two > conftest.ts2 # ts2 should now be newer than ts1 + if $make -f conftest.mk | grep 'up to date' >/dev/null; then + make_ok=false + break # out of $n loop + fi + n=`expr $n + 1` + done + fi + # + if $make_ok; then + # Everything we know to check worked out, so call this resolution good. + am_cv_filesystem_timestamp_resolution=$am_try_res + break # out of $am_try_res loop + fi + # Otherwise, we'll go on to check the next resolution. + fi +done +rm -f conftest.ts? +# (end _am_filesystem_timestamp_resolution) +])]) + # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], -[AC_MSG_CHECKING([whether build environment is sane]) +[AC_REQUIRE([_AM_FILESYSTEM_TIMESTAMP_RESOLUTION]) +# This check should not be cached, as it may vary across builds of +# different projects. +AC_MSG_CHECKING([whether build environment is sane]) # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' @@ -930,49 +1061,40 @@ esac # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). -if ( - am_has_slept=no - for am_try in 1 2; do - echo "timestamp, slept: $am_has_slept" > conftest.file - set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` - if test "$[*]" = "X"; then - # -L didn't work. - set X `ls -t "$srcdir/configure" conftest.file` - fi - if test "$[*]" != "X $srcdir/configure conftest.file" \ - && test "$[*]" != "X conftest.file $srcdir/configure"; then - - # If neither matched, then we have a broken ls. This can happen - # if, for instance, CONFIG_SHELL is bash and it inherits a - # broken ls alias from the environment. This has actually - # happened. Such a system could not be considered "sane". - AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken - alias in your environment]) - fi - if test "$[2]" = conftest.file || test $am_try -eq 2; then - break - fi - # Just in case. - sleep 1 - am_has_slept=yes - done - test "$[2]" = conftest.file - ) -then - # Ok. - : -else - AC_MSG_ERROR([newly created file is older than distributed files! +am_build_env_is_sane=no +am_has_slept=no +rm -f conftest.file +for am_try in 1 2; do + echo "timestamp, slept: $am_has_slept" > conftest.file + if ( + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$[]*" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + test "$[]2" = conftest.file + ); then + am_build_env_is_sane=yes + break + fi + # Just in case. + sleep "$am_cv_filesystem_timestamp_resolution" + am_has_slept=yes +done + +AC_MSG_RESULT([$am_build_env_is_sane]) +if test "$am_build_env_is_sane" = no; then + AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi -AC_MSG_RESULT([yes]) + # If we didn't sleep, we still need to ensure time stamps of config.status and # generated files are strictly newer. am_sleep_pid= -if grep 'slept: no' conftest.file >/dev/null 2>&1; then - ( sleep 1 ) & +AS_IF([test -e conftest.file || grep 'slept: no' conftest.file >/dev/null 2>&1],, [dnl + ( sleep "$am_cv_filesystem_timestamp_resolution" ) & am_sleep_pid=$! -fi +]) AC_CONFIG_COMMANDS_PRE( [AC_MSG_CHECKING([that generated files are newer than configure]) if test -n "$am_sleep_pid"; then @@ -983,18 +1105,18 @@ AC_CONFIG_COMMANDS_PRE( rm -f conftest.file ]) -# Copyright (C) 2009-2021 Free Software Foundation, Inc. +# Copyright (C) 2009-2024 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# AM_SILENT_RULES([DEFAULT]) -# -------------------------- -# Enable less verbose build rules; with the default set to DEFAULT -# ("yes" being less verbose, "no" or empty being verbose). -AC_DEFUN([AM_SILENT_RULES], -[AC_ARG_ENABLE([silent-rules], [dnl +# _AM_SILENT_RULES +# ---------------- +# Enable less verbose build rules support. +AC_DEFUN([_AM_SILENT_RULES], +[AM_DEFAULT_VERBOSITY=1 +AC_ARG_ENABLE([silent-rules], [dnl AS_HELP_STRING( [--enable-silent-rules], [less verbose build output (undo: "make V=1")]) @@ -1002,11 +1124,6 @@ AS_HELP_STRING( [--disable-silent-rules], [verbose build output (undo: "make V=0")])dnl ]) -case $enable_silent_rules in @%:@ ((( - yes) AM_DEFAULT_VERBOSITY=0;; - no) AM_DEFAULT_VERBOSITY=1;; - *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; -esac dnl dnl A few 'make' implementations (e.g., NonStop OS and NextStep) dnl do not support nested variable expansions. @@ -1025,14 +1142,6 @@ am__doit: else am_cv_make_support_nested_variables=no fi]) -if test $am_cv_make_support_nested_variables = yes; then - dnl Using '$V' instead of '$(V)' breaks IRIX make. - AM_V='$(V)' - AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' -else - AM_V=$AM_DEFAULT_VERBOSITY - AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY -fi AC_SUBST([AM_V])dnl AM_SUBST_NOTMAKE([AM_V])dnl AC_SUBST([AM_DEFAULT_V])dnl @@ -1041,9 +1150,33 @@ AC_SUBST([AM_DEFAULT_VERBOSITY])dnl AM_BACKSLASH='\' AC_SUBST([AM_BACKSLASH])dnl _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl +dnl Delay evaluation of AM_DEFAULT_VERBOSITY to the end to allow multiple calls +dnl to AM_SILENT_RULES to change the default value. +AC_CONFIG_COMMANDS_PRE([dnl +case $enable_silent_rules in @%:@ ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; +esac +if test $am_cv_make_support_nested_variables = yes; then + dnl Using '$V' instead of '$(V)' breaks IRIX make. + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +])dnl ]) -# Copyright (C) 2001-2021 Free Software Foundation, Inc. +# AM_SILENT_RULES([DEFAULT]) +# -------------------------- +# Set the default verbosity level to DEFAULT ("yes" being less verbose, "no" or +# empty being verbose). +AC_DEFUN([AM_SILENT_RULES], +[AC_REQUIRE([_AM_SILENT_RULES]) +AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1])]) + +# Copyright (C) 2001-2024 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1071,7 +1204,7 @@ fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) -# Copyright (C) 2006-2021 Free Software Foundation, Inc. +# Copyright (C) 2006-2024 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1090,7 +1223,7 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Check how to create a tarball. -*- Autoconf -*- -# Copyright (C) 2004-2021 Free Software Foundation, Inc. +# Copyright (C) 2004-2024 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1136,15 +1269,19 @@ m4_if([$1], [v7], am_uid=`id -u || echo unknown` am_gid=`id -g || echo unknown` AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format]) - if test $am_uid -le $am_max_uid; then - AC_MSG_RESULT([yes]) + if test x$am_uid = xunknown; then + AC_MSG_WARN([ancient id detected; assuming current UID is ok, but dist-ustar might not work]) + elif test $am_uid -le $am_max_uid; then + AC_MSG_RESULT([yes]) else - AC_MSG_RESULT([no]) - _am_tools=none + AC_MSG_RESULT([no]) + _am_tools=none fi AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format]) - if test $am_gid -le $am_max_gid; then - AC_MSG_RESULT([yes]) + if test x$gm_gid = xunknown; then + AC_MSG_WARN([ancient id detected; assuming current GID is ok, but dist-ustar might not work]) + elif test $am_gid -le $am_max_gid; then + AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) _am_tools=none @@ -1221,6 +1358,26 @@ AC_SUBST([am__tar]) AC_SUBST([am__untar]) ]) # _AM_PROG_TAR +# Copyright (C) 2022-2024 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_PROG_XARGS_N +# ---------------- +# Check whether 'xargs -n' works. It should work everywhere, so the fallback +# is not optimized at all as we never expect to use it. +AC_DEFUN([_AM_PROG_XARGS_N], +[AC_CACHE_CHECK([xargs -n works], am_cv_xargs_n_works, [dnl +AS_IF([test "`echo 1 2 3 | xargs -n2 echo`" = "1 2 +3"], [am_cv_xargs_n_works=yes], [am_cv_xargs_n_works=no])]) +AS_IF([test "$am_cv_xargs_n_works" = yes], [am__xargs_n='xargs -n'], [dnl + am__xargs_n='am__xargs_n () { shift; sed "s/ /\\n/g" | while read am__xargs_n_arg; do "$@" "$am__xargs_n_arg"; done; }' +])dnl +AC_SUBST(am__xargs_n) +]) + m4_include([m4/ax_ac_append_to_file.m4]) m4_include([m4/ax_ac_print_to_file.m4]) m4_include([m4/ax_add_am_macro_static.m4]) diff --git a/deps/cares/aminclude_static.am b/deps/cares/aminclude_static.am index d542444c4e2..538a810c9eb 100644 --- a/deps/cares/aminclude_static.am +++ b/deps/cares/aminclude_static.am @@ -1,6 +1,6 @@ # aminclude_static.am generated automatically by Autoconf -# from AX_AM_MACROS_STATIC on Wed Jul 24 05:40:58 EDT 2024 +# from AX_AM_MACROS_STATIC on Fri Aug 23 09:37:25 EDT 2024 # Code coverage diff --git a/deps/cares/cares.gyp b/deps/cares/cares.gyp index ee011801676..6b6d520f9ee 100644 --- a/deps/cares/cares.gyp +++ b/deps/cares/cares.gyp @@ -8,60 +8,18 @@ 'include/ares_version.h', 'src/lib/ares__addrinfo2hostent.c', 'src/lib/ares__addrinfo_localhost.c', - 'src/lib/ares__buf.c', - 'src/lib/ares__buf.h', 'src/lib/ares__close_sockets.c', 'src/lib/ares__hosts_file.c', - 'src/lib/ares__htable.c', - 'src/lib/ares__htable.h', - 'src/lib/ares__htable_asvp.c', - 'src/lib/ares__htable_asvp.h', - 'src/lib/ares__htable_strvp.c', - 'src/lib/ares__htable_strvp.h', - 'src/lib/ares__htable_szvp.c', - 'src/lib/ares__htable_szvp.h', - 'src/lib/ares__htable_vpvp.c', - 'src/lib/ares__htable_vpvp.h', - 'src/lib/ares__iface_ips.c', - 'src/lib/ares__iface_ips.h', - 'src/lib/ares__llist.c', - 'src/lib/ares__llist.h', 'src/lib/ares__parse_into_addrinfo.c', - 'src/lib/ares__slist.c', - 'src/lib/ares__slist.h', 'src/lib/ares__socket.c', 'src/lib/ares__sortaddrinfo.c', - 'src/lib/ares__threads.c', - 'src/lib/ares__threads.h', - 'src/lib/ares__timeval.c', 'src/lib/ares_android.c', 'src/lib/ares_android.h', 'src/lib/ares_cancel.c', - 'src/lib/ares_create_query.c', + 'src/lib/ares_cookie.c', 'src/lib/ares_data.c', 'src/lib/ares_data.h', 'src/lib/ares_destroy.c', - 'src/lib/ares_dns_mapping.c', - 'src/lib/ares_dns_multistring.c', - 'src/lib/ares_dns_multistring.h', - 'src/lib/ares_dns_name.c', - 'src/lib/ares_dns_parse.c', - 'src/lib/ares_dns_record.c', - 'src/lib/ares_dns_private.h', - 'src/lib/ares_dns_write.c', - 'src/lib/ares_event_configchg.c', - 'src/lib/ares_event.h', - 'src/lib/ares_event_win32.h', - 'src/lib/ares_event_epoll.c', - 'src/lib/ares_event_kqueue.c', - 'src/lib/ares_event_poll.c', - 'src/lib/ares_event_select.c', - 'src/lib/ares_event_thread.c', - 'src/lib/ares_event_wake_pipe.c', - 'src/lib/ares_event_win32.c', - 'src/lib/ares_expand_name.c', - 'src/lib/ares_expand_string.c', - 'src/lib/ares_fds.c', 'src/lib/ares_free_hostent.c', 'src/lib/ares_free_string.c', 'src/lib/ares_freeaddrinfo.c', @@ -71,49 +29,94 @@ 'src/lib/ares_gethostbyaddr.c', 'src/lib/ares_gethostbyname.c', 'src/lib/ares_getnameinfo.c', - 'src/lib/ares_getsock.c', 'src/lib/ares_inet_net_pton.h', 'src/lib/ares_init.c', - 'src/lib/ares_library_init.c', 'src/lib/ares_ipv6.h', - 'src/lib/ares_math.c', + 'src/lib/ares_library_init.c', 'src/lib/ares_metrics.c', 'src/lib/ares_options.c', - 'src/lib/ares_parse_a_reply.c', - 'src/lib/ares_parse_aaaa_reply.c', - 'src/lib/ares_parse_caa_reply.c', - 'src/lib/ares_parse_mx_reply.c', - 'src/lib/ares_parse_naptr_reply.c', - 'src/lib/ares_parse_ns_reply.c', - 'src/lib/ares_parse_ptr_reply.c', - 'src/lib/ares_parse_soa_reply.c', - 'src/lib/ares_parse_srv_reply.c', - 'src/lib/ares_parse_txt_reply.c', - 'src/lib/ares_parse_uri_reply.c', 'src/lib/ares_platform.c', 'src/lib/ares_platform.h', 'src/lib/ares_private.h', 'src/lib/ares_process.c', 'src/lib/ares_qcache.c', 'src/lib/ares_query.c', - 'src/lib/ares_rand.c', 'src/lib/ares_search.c', 'src/lib/ares_send.c', 'src/lib/ares_setup.h', - 'src/lib/ares_strcasecmp.c', - 'src/lib/ares_strcasecmp.h', - 'src/lib/ares_str.c', - 'src/lib/ares_str.h', 'src/lib/ares_strerror.c', - 'src/lib/ares_strsplit.c', - 'src/lib/ares_strsplit.h', 'src/lib/ares_sysconfig.c', 'src/lib/ares_sysconfig_files.c', 'src/lib/ares_timeout.c', 'src/lib/ares_update_servers.c', 'src/lib/ares_version.c', + 'src/lib/dsa/ares__array.c', + 'src/lib/dsa/ares__array.h', + 'src/lib/dsa/ares__htable.c', + 'src/lib/dsa/ares__htable.h', + 'src/lib/dsa/ares__htable_asvp.c', + 'src/lib/dsa/ares__htable_asvp.h', + 'src/lib/dsa/ares__htable_strvp.c', + 'src/lib/dsa/ares__htable_strvp.h', + 'src/lib/dsa/ares__htable_szvp.c', + 'src/lib/dsa/ares__htable_szvp.h', + 'src/lib/dsa/ares__htable_vpvp.c', + 'src/lib/dsa/ares__htable_vpvp.h', + 'src/lib/dsa/ares__llist.c', + 'src/lib/dsa/ares__llist.h', + 'src/lib/dsa/ares__slist.c', + 'src/lib/dsa/ares__slist.h', + 'src/lib/event/ares_event.h', + 'src/lib/event/ares_event_configchg.c', + 'src/lib/event/ares_event_epoll.c', + 'src/lib/event/ares_event_kqueue.c', + 'src/lib/event/ares_event_poll.c', + 'src/lib/event/ares_event_select.c', + 'src/lib/event/ares_event_thread.c', + 'src/lib/event/ares_event_wake_pipe.c', + 'src/lib/event/ares_event_win32.c', + 'src/lib/event/ares_event_win32.h', 'src/lib/inet_net_pton.c', 'src/lib/inet_ntop.c', + 'src/lib/legacy/ares_create_query.c', + 'src/lib/legacy/ares_expand_name.c', + 'src/lib/legacy/ares_expand_string.c', + 'src/lib/legacy/ares_fds.c', + 'src/lib/legacy/ares_getsock.c', + 'src/lib/legacy/ares_parse_a_reply.c', + 'src/lib/legacy/ares_parse_aaaa_reply.c', + 'src/lib/legacy/ares_parse_caa_reply.c', + 'src/lib/legacy/ares_parse_mx_reply.c', + 'src/lib/legacy/ares_parse_naptr_reply.c', + 'src/lib/legacy/ares_parse_ns_reply.c', + 'src/lib/legacy/ares_parse_ptr_reply.c', + 'src/lib/legacy/ares_parse_soa_reply.c', + 'src/lib/legacy/ares_parse_srv_reply.c', + 'src/lib/legacy/ares_parse_txt_reply.c', + 'src/lib/legacy/ares_parse_uri_reply.c', + 'src/lib/record/ares_dns_mapping.c', + 'src/lib/record/ares_dns_multistring.c', + 'src/lib/record/ares_dns_multistring.h', + 'src/lib/record/ares_dns_name.c', + 'src/lib/record/ares_dns_parse.c', + 'src/lib/record/ares_dns_private.h', + 'src/lib/record/ares_dns_record.c', + 'src/lib/record/ares_dns_write.c', + 'src/lib/str/ares__buf.c', + 'src/lib/str/ares__buf.h', + 'src/lib/str/ares_str.c', + 'src/lib/str/ares_str.h', + 'src/lib/str/ares_strcasecmp.c', + 'src/lib/str/ares_strcasecmp.h', + 'src/lib/str/ares_strsplit.c', + 'src/lib/str/ares_strsplit.h', + 'src/lib/util/ares__iface_ips.c', + 'src/lib/util/ares__iface_ips.h', + 'src/lib/util/ares__threads.c', + 'src/lib/util/ares__threads.h', + 'src/lib/util/ares__timeval.c', + 'src/lib/util/ares_math.c', + 'src/lib/util/ares_rand.c', 'src/tools/ares_getopt.c', 'src/tools/ares_getopt.h', ], @@ -160,7 +163,7 @@ { 'target_name': 'cares', 'type': '<(library)', - 'include_dirs': [ 'include' ], + 'include_dirs': [ 'include', 'src/lib' ], 'direct_dependent_settings': { 'include_dirs': [ 'include' ], 'cflags': [ '-Wno-error=deprecated-declarations' ], diff --git a/deps/cares/configure b/deps/cares/configure index f5fc16a49bf..74e9741fe6e 100755 --- a/deps/cares/configure +++ b/deps/cares/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.72 for c-ares 1.32.3. +# Generated by GNU Autoconf 2.72 for c-ares 1.33.1. # # Report bugs to . # @@ -614,8 +614,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='c-ares' PACKAGE_TARNAME='c-ares' -PACKAGE_VERSION='1.32.3' -PACKAGE_STRING='c-ares 1.32.3' +PACKAGE_VERSION='1.33.1' +PACKAGE_STRING='c-ares 1.33.1' PACKAGE_BUGREPORT='c-ares mailing list: http://lists.haxx.se/listinfo/c-ares' PACKAGE_URL='' @@ -663,6 +663,8 @@ AM_CPPFLAGS AM_CFLAGS BUILD_TESTS_FALSE BUILD_TESTS_TRUE +GMOCK112_LIBS +GMOCK112_CFLAGS GMOCK_LIBS GMOCK_CFLAGS PKG_CONFIG_LIBDIR @@ -729,6 +731,8 @@ LIBTOOL OBJDUMP DLLTOOL AS +am__xargs_n +am__rm_f_notfound AM_BACKSLASH AM_DEFAULT_VERBOSITY AM_DEFAULT_V @@ -866,7 +870,9 @@ PKG_CONFIG PKG_CONFIG_PATH PKG_CONFIG_LIBDIR GMOCK_CFLAGS -GMOCK_LIBS' +GMOCK_LIBS +GMOCK112_CFLAGS +GMOCK112_LIBS' # Initialize some variables set by options. @@ -1415,7 +1421,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -'configure' configures c-ares 1.32.3 to adapt to many kinds of systems. +'configure' configures c-ares 1.33.1 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1486,7 +1492,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of c-ares 1.32.3:";; + short | recursive ) echo "Configuration of c-ares 1.33.1:";; esac cat <<\_ACEOF @@ -1555,6 +1561,10 @@ Some influential environment variables: GMOCK_CFLAGS C compiler flags for GMOCK, overriding pkg-config GMOCK_LIBS linker flags for GMOCK, overriding pkg-config + GMOCK112_CFLAGS + C compiler flags for GMOCK112, overriding pkg-config + GMOCK112_LIBS + linker flags for GMOCK112, overriding pkg-config Use these variables to override the choices made by 'configure' or to help it to find libraries and programs with nonstandard names/locations. @@ -1623,7 +1633,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -c-ares configure 1.32.3 +c-ares configure 1.33.1 generated by GNU Autoconf 2.72 Copyright (C) 2023 Free Software Foundation, Inc. @@ -1951,50 +1961,6 @@ fi } # ac_fn_cxx_try_link -# ac_fn_c_try_run LINENO -# ---------------------- -# Try to run conftest.$ac_ext, and return whether this succeeded. Assumes that -# executables *can* be run. -ac_fn_c_try_run () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -printf "%s\n" "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' - { { case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -printf "%s\n" "$ac_try_echo"; } >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; } -then : - ac_retval=0 -else case e in #( - e) printf "%s\n" "$as_me: program exited with status $ac_status" >&5 - printf "%s\n" "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=$ac_status ;; -esac -fi - rm -rf conftest.dSYM conftest_ipa8_conftest.oo - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_run - # ac_fn_c_try_cpp LINENO # ---------------------- # Try to preprocess conftest.$ac_ext, and return whether this succeeded. @@ -2243,6 +2209,50 @@ printf "%s\n" "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_member + +# ac_fn_c_try_run LINENO +# ---------------------- +# Try to run conftest.$ac_ext, and return whether this succeeded. Assumes that +# executables *can* be run. +ac_fn_c_try_run () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; } +then : + ac_retval=0 +else case e in #( + e) printf "%s\n" "$as_me: program exited with status $ac_status" >&5 + printf "%s\n" "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=$ac_status ;; +esac +fi + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_run ac_configure_args_raw= for ac_arg do @@ -2267,7 +2277,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by c-ares $as_me 1.32.3, which was +It was created by c-ares $as_me 1.33.1, which was generated by GNU Autoconf 2.72. Invocation command line was $ $0$ac_configure_args_raw @@ -3259,7 +3269,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu -CARES_VERSION_INFO="19:3:17" +CARES_VERSION_INFO="20:1:18" @@ -5421,7 +5431,7 @@ printf "%s\n" "#define HAVE_CXX14 1" >>confdefs.h fi -am__api_version='1.16' +am__api_version='1.17' # Find a good install program. We prefer a C program (faster), @@ -5523,6 +5533,165 @@ test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether sleep supports fractional seconds" >&5 +printf %s "checking whether sleep supports fractional seconds... " >&6; } +if test ${am_cv_sleep_fractional_seconds+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) if sleep 0.001 2>/dev/null +then : + am_cv_sleep_fractional_seconds=yes +else case e in #( + e) am_cv_sleep_fractional_seconds=no ;; +esac +fi + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_sleep_fractional_seconds" >&5 +printf "%s\n" "$am_cv_sleep_fractional_seconds" >&6; } + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking filesystem timestamp resolution" >&5 +printf %s "checking filesystem timestamp resolution... " >&6; } +if test ${am_cv_filesystem_timestamp_resolution+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) # Default to the worst case. +am_cv_filesystem_timestamp_resolution=2 + +# Only try to go finer than 1 sec if sleep can do it. +# Don't try 1 sec, because if 0.01 sec and 0.1 sec don't work, +# - 1 sec is not much of a win compared to 2 sec, and +# - it takes 2 seconds to perform the test whether 1 sec works. +# +# Instead, just use the default 2s on platforms that have 1s resolution, +# accept the extra 1s delay when using $sleep in the Automake tests, in +# exchange for not incurring the 2s delay for running the test for all +# packages. +# +am_try_resolutions= +if test "$am_cv_sleep_fractional_seconds" = yes; then + # Even a millisecond often causes a bunch of false positives, + # so just try a hundredth of a second. The time saved between .001 and + # .01 is not terribly consequential. + am_try_resolutions="0.01 0.1 $am_try_resolutions" +fi + +# In order to catch current-generation FAT out, we must *modify* files +# that already exist; the *creation* timestamp is finer. Use names +# that make ls -t sort them differently when they have equal +# timestamps than when they have distinct timestamps, keeping +# in mind that ls -t prints the *newest* file first. +rm -f conftest.ts? +: > conftest.ts1 +: > conftest.ts2 +: > conftest.ts3 + +# Make sure ls -t actually works. Do 'set' in a subshell so we don't +# clobber the current shell's arguments. (Outer-level square brackets +# are removed by m4; they're present so that m4 does not expand +# ; be careful, easy to get confused.) +if ( + set X `ls -t conftest.ts[12]` && + { + test "$*" != "X conftest.ts1 conftest.ts2" || + test "$*" != "X conftest.ts2 conftest.ts1"; + } +); then :; else + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + printf "%s\n" ""Bad output from ls -t: \"`ls -t conftest.ts[12]`\""" >&5 + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} +as_fn_error $? "ls -t produces unexpected output. +Make sure there is not a broken ls alias in your environment. +See 'config.log' for more details" "$LINENO" 5; } +fi + +for am_try_res in $am_try_resolutions; do + # Any one fine-grained sleep might happen to cross the boundary + # between two values of a coarser actual resolution, but if we do + # two fine-grained sleeps in a row, at least one of them will fall + # entirely within a coarse interval. + echo alpha > conftest.ts1 + sleep $am_try_res + echo beta > conftest.ts2 + sleep $am_try_res + echo gamma > conftest.ts3 + + # We assume that 'ls -t' will make use of high-resolution + # timestamps if the operating system supports them at all. + if (set X `ls -t conftest.ts?` && + test "$2" = conftest.ts3 && + test "$3" = conftest.ts2 && + test "$4" = conftest.ts1); then + # + # Ok, ls -t worked. If we're at a resolution of 1 second, we're done, + # because we don't need to test make. + make_ok=true + if test $am_try_res != 1; then + # But if we've succeeded so far with a subsecond resolution, we + # have one more thing to check: make. It can happen that + # everything else supports the subsecond mtimes, but make doesn't; + # notably on macOS, which ships make 3.81 from 2006 (the last one + # released under GPLv2). https://bugs.gnu.org/68808 + # + # We test $MAKE if it is defined in the environment, else "make". + # It might get overridden later, but our hope is that in practice + # it does not matter: it is the system "make" which is (by far) + # the most likely to be broken, whereas if the user overrides it, + # probably they did so with a better, or at least not worse, make. + # https://lists.gnu.org/archive/html/automake/2024-06/msg00051.html + # + # Create a Makefile (real tab character here): + rm -f conftest.mk + echo 'conftest.ts1: conftest.ts2' >conftest.mk + echo ' touch conftest.ts2' >>conftest.mk + # + # Now, running + # touch conftest.ts1; touch conftest.ts2; make + # should touch ts1 because ts2 is newer. This could happen by luck, + # but most often, it will fail if make's support is insufficient. So + # test for several consecutive successes. + # + # (We reuse conftest.ts[12] because we still want to modify existing + # files, not create new ones, per above.) + n=0 + make=${MAKE-make} + until test $n -eq 3; do + echo one > conftest.ts1 + sleep $am_try_res + echo two > conftest.ts2 # ts2 should now be newer than ts1 + if $make -f conftest.mk | grep 'up to date' >/dev/null; then + make_ok=false + break # out of $n loop + fi + n=`expr $n + 1` + done + fi + # + if $make_ok; then + # Everything we know to check worked out, so call this resolution good. + am_cv_filesystem_timestamp_resolution=$am_try_res + break # out of $am_try_res loop + fi + # Otherwise, we'll go on to check the next resolution. + fi +done +rm -f conftest.ts? +# (end _am_filesystem_timestamp_resolution) + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_filesystem_timestamp_resolution" >&5 +printf "%s\n" "$am_cv_filesystem_timestamp_resolution" >&6; } + +# This check should not be cached, as it may vary across builds of +# different projects. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 printf %s "checking whether build environment is sane... " >&6; } # Reject unsafe characters in $srcdir or the absolute working directory @@ -5543,49 +5712,45 @@ esac # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). -if ( - am_has_slept=no - for am_try in 1 2; do - echo "timestamp, slept: $am_has_slept" > conftest.file - set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` - if test "$*" = "X"; then - # -L didn't work. - set X `ls -t "$srcdir/configure" conftest.file` - fi - if test "$*" != "X $srcdir/configure conftest.file" \ - && test "$*" != "X conftest.file $srcdir/configure"; then - - # If neither matched, then we have a broken ls. This can happen - # if, for instance, CONFIG_SHELL is bash and it inherits a - # broken ls alias from the environment. This has actually - # happened. Such a system could not be considered "sane". - as_fn_error $? "ls -t appears to fail. Make sure there is not a broken - alias in your environment" "$LINENO" 5 - fi - if test "$2" = conftest.file || test $am_try -eq 2; then - break - fi - # Just in case. - sleep 1 - am_has_slept=yes - done - test "$2" = conftest.file - ) -then - # Ok. - : -else - as_fn_error $? "newly created file is older than distributed files! +am_build_env_is_sane=no +am_has_slept=no +rm -f conftest.file +for am_try in 1 2; do + echo "timestamp, slept: $am_has_slept" > conftest.file + if ( + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + test "$2" = conftest.file + ); then + am_build_env_is_sane=yes + break + fi + # Just in case. + sleep "$am_cv_filesystem_timestamp_resolution" + am_has_slept=yes +done + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_build_env_is_sane" >&5 +printf "%s\n" "$am_build_env_is_sane" >&6; } +if test "$am_build_env_is_sane" = no; then + as_fn_error $? "newly created file is older than distributed files! Check your system clock" "$LINENO" 5 fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + # If we didn't sleep, we still need to ensure time stamps of config.status and # generated files are strictly newer. am_sleep_pid= -if grep 'slept: no' conftest.file >/dev/null 2>&1; then - ( sleep 1 ) & +if test -e conftest.file || grep 'slept: no' conftest.file >/dev/null 2>&1 +then : + +else case e in #( + e) ( sleep "$am_cv_filesystem_timestamp_resolution" ) & am_sleep_pid=$! + ;; +esac fi rm -f conftest.file @@ -5935,17 +6100,13 @@ else fi +AM_DEFAULT_VERBOSITY=1 # Check whether --enable-silent-rules was given. if test ${enable_silent_rules+y} then : enableval=$enable_silent_rules; fi -case $enable_silent_rules in # ((( - yes) AM_DEFAULT_VERBOSITY=0;; - no) AM_DEFAULT_VERBOSITY=1;; - *) AM_DEFAULT_VERBOSITY=1;; -esac am_make=${MAKE-make} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 printf %s "checking whether $am_make supports nested variables... " >&6; } @@ -5968,15 +6129,45 @@ esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 printf "%s\n" "$am_cv_make_support_nested_variables" >&6; } -if test $am_cv_make_support_nested_variables = yes; then - AM_V='$(V)' - AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' -else - AM_V=$AM_DEFAULT_VERBOSITY - AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY -fi AM_BACKSLASH='\' +am__rm_f_notfound= +if (rm -f && rm -fr && rm -rf) 2>/dev/null +then : + +else case e in #( + e) am__rm_f_notfound='""' ;; +esac +fi + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking xargs -n works" >&5 +printf %s "checking xargs -n works... " >&6; } +if test ${am_cv_xargs_n_works+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) if test "`echo 1 2 3 | xargs -n2 echo`" = "1 2 +3" +then : + am_cv_xargs_n_works=yes +else case e in #( + e) am_cv_xargs_n_works=no ;; +esac +fi ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_xargs_n_works" >&5 +printf "%s\n" "$am_cv_xargs_n_works" >&6; } +if test "$am_cv_xargs_n_works" = yes +then : + am__xargs_n='xargs -n' +else case e in #( + e) am__xargs_n='am__xargs_n () { shift; sed "s/ /\\n/g" | while read am__xargs_n_arg; do "" "$am__xargs_n_arg"; done; }' + ;; +esac +fi + if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." @@ -5999,7 +6190,7 @@ fi # Define the identity of the package. PACKAGE='c-ares' - VERSION='1.32.3' + VERSION='1.33.1' printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h @@ -6140,7 +6331,7 @@ else case e in #( # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. - # When given -MP, icc 7.0 and 7.1 complain thusly: + # When given -MP, icc 7.0 and 7.1 complain thus: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported @@ -6270,7 +6461,7 @@ else case e in #( # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. - # When given -MP, icc 7.0 and 7.1 complain thusly: + # When given -MP, icc 7.0 and 7.1 complain thus: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported @@ -6320,47 +6511,9 @@ fi -# POSIX will say in a future version that running "rm -f" with no argument -# is OK; and we want to be able to make that assumption in our Makefile -# recipes. So use an aggressive probe to check that the usage we want is -# actually supported "in the wild" to an acceptable degree. -# See automake bug#10828. -# To make any issue more visible, cause the running configure to be aborted -# by default if the 'rm' program in use doesn't match our expectations; the -# user can still override this though. -if rm -f && rm -fr && rm -rf; then : OK; else - cat >&2 <<'END' -Oops! - -Your 'rm' program seems unable to run without file operands specified -on the command line, even when the '-f' option is present. This is contrary -to the behaviour of most rm programs out there, and not conforming with -the upcoming POSIX standard: - -Please tell bug-automake@gnu.org about your system, including the value -of your $PATH and any error possibly output before this message. This -can help us improve future automake versions. -END - if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then - echo 'Configuration will proceed anyway, since you have set the' >&2 - echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 - echo >&2 - else - cat >&2 <<'END' -Aborting the configuration process, to ensure you take notice of the issue. -You can download and install GNU coreutils to get an 'rm' implementation -that behaves properly: . -If you want to complete the configuration process using your problematic -'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM -to "yes", and re-run configure. - -END - as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 - fi -fi case `pwd` in *\ * | *\ *) @@ -19498,48 +19651,8 @@ fi MAINT=$MAINTAINER_MODE_TRUE -# Check whether --enable-silent-rules was given. -if test ${enable_silent_rules+y} -then : - enableval=$enable_silent_rules; -fi - -case $enable_silent_rules in # ((( - yes) AM_DEFAULT_VERBOSITY=0;; - no) AM_DEFAULT_VERBOSITY=1;; - *) AM_DEFAULT_VERBOSITY=0;; -esac -am_make=${MAKE-make} -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 -printf %s "checking whether $am_make supports nested variables... " >&6; } -if test ${am_cv_make_support_nested_variables+y} -then : - printf %s "(cached) " >&6 -else case e in #( - e) if printf "%s\n" 'TRUE=$(BAR$(V)) -BAR0=false -BAR1=true -V=1 -am__doit: - @$(TRUE) -.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then - am_cv_make_support_nested_variables=yes -else - am_cv_make_support_nested_variables=no -fi ;; -esac -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 -printf "%s\n" "$am_cv_make_support_nested_variables" >&6; } -if test $am_cv_make_support_nested_variables = yes; then - AM_V='$(V)' - AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' -else - AM_V=$AM_DEFAULT_VERBOSITY - AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY -fi -AM_BACKSLASH='\' +AM_DEFAULT_VERBOSITY=0 @@ -19939,211 +20052,27 @@ fi - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether user namespaces are supported" >&5 -printf %s "checking whether user namespaces are supported... " >&6; } -if test ${ax_cv_user_namespace+y} +# Check whether --enable-largefile was given. +if test ${enable_largefile+y} +then : + enableval=$enable_largefile; +fi +if test "$enable_largefile,$enable_year2038" != no,no +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable large file support" >&5 +printf %s "checking for $CC option to enable large file support... " >&6; } +if test ${ac_cv_sys_largefile_opts+y} then : printf %s "(cached) " >&6 else case e in #( - e) - ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - if test "$cross_compiling" = yes + e) ac_save_CC="$CC" + ac_opt_found=no + for ac_opt in "none needed" "-D_FILE_OFFSET_BITS=64" "-D_LARGE_FILES=1" "-n32"; do + if test x"$ac_opt" != x"none needed" then : - ax_cv_user_namespace=no -else case e in #( - e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#define _GNU_SOURCE -#include -#include -#include -#include -#include -#include -#include - -int userfn(void *d) { - usleep(100000); /* synchronize by sleep */ - return (getuid() != 0); -} -char userst[1024*1024]; -int main() { - char buffer[1024]; - int rc, status, fd; - pid_t child = clone(userfn, userst + 1024*1024, CLONE_NEWUSER|SIGCHLD, 0); - if (child < 0) return 1; - - snprintf(buffer, sizeof(buffer), "/proc/%d/uid_map", child); - fd = open(buffer, O_CREAT|O_WRONLY|O_TRUNC, 0755); - snprintf(buffer, sizeof(buffer), "0 %d 1\n", getuid()); - write(fd, buffer, strlen(buffer)); - close(fd); - - rc = waitpid(child, &status, 0); - if (rc <= 0) return 1; - if (!WIFEXITED(status)) return 1; - return WEXITSTATUS(status); -} - -_ACEOF -if ac_fn_c_try_run "$LINENO" -then : - ax_cv_user_namespace=yes -else case e in #( - e) ax_cv_user_namespace=no ;; -esac -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext ;; -esac -fi - - ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - ;; -esac -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_user_namespace" >&5 -printf "%s\n" "$ax_cv_user_namespace" >&6; } - if test "$ax_cv_user_namespace" = yes; then - -printf "%s\n" "#define HAVE_USER_NAMESPACE 1" >>confdefs.h - - fi - - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether UTS namespaces are supported" >&5 -printf %s "checking whether UTS namespaces are supported... " >&6; } -if test ${ax_cv_uts_namespace+y} -then : - printf %s "(cached) " >&6 -else case e in #( - e) - ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - if test "$cross_compiling" = yes -then : - ax_cv_uts_namespace=no -else case e in #( - e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#define _GNU_SOURCE -#include -#include -#include -#include -#include -#include -#include -#include - -int utsfn(void *d) { - char buffer[1024]; - const char *name = "autoconftest"; - int rc = sethostname(name, strlen(name)); - if (rc != 0) return 1; - gethostname(buffer, 1024); - return (strcmp(buffer, name) != 0); -} - -char st2[1024*1024]; -int fn(void *d) { - pid_t child; - int rc, status; - usleep(100000); /* synchronize by sleep */ - if (getuid() != 0) return 1; - child = clone(utsfn, st2 + 1024*1024, CLONE_NEWUTS|SIGCHLD, 0); - if (child < 0) return 1; - rc = waitpid(child, &status, 0); - if (rc <= 0) return 1; - if (!WIFEXITED(status)) return 1; - return WEXITSTATUS(status); -} -char st[1024*1024]; -int main() { - char buffer[1024]; - int rc, status, fd; - pid_t child = clone(fn, st + 1024*1024, CLONE_NEWUSER|SIGCHLD, 0); - if (child < 0) return 1; - - snprintf(buffer, sizeof(buffer), "/proc/%d/uid_map", child); - fd = open(buffer, O_CREAT|O_WRONLY|O_TRUNC, 0755); - snprintf(buffer, sizeof(buffer), "0 %d 1\n", getuid()); - write(fd, buffer, strlen(buffer)); - close(fd); - - rc = waitpid(child, &status, 0); - if (rc <= 0) return 1; - if (!WIFEXITED(status)) return 1; - return WEXITSTATUS(status); -} - - -_ACEOF -if ac_fn_c_try_run "$LINENO" -then : - ax_cv_uts_namespace=yes -else case e in #( - e) ax_cv_uts_namespace=no ;; -esac -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext ;; -esac -fi - - ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - ;; -esac -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_uts_namespace" >&5 -printf "%s\n" "$ax_cv_uts_namespace" >&6; } - if test "$ax_cv_uts_namespace" = yes; then - -printf "%s\n" "#define HAVE_UTS_NAMESPACE 1" >>confdefs.h - - fi - -# Check whether --enable-largefile was given. -if test ${enable_largefile+y} -then : - enableval=$enable_largefile; -fi -if test "$enable_largefile,$enable_year2038" != no,no -then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable large file support" >&5 -printf %s "checking for $CC option to enable large file support... " >&6; } -if test ${ac_cv_sys_largefile_opts+y} -then : - printf %s "(cached) " >&6 -else case e in #( - e) ac_save_CC="$CC" - ac_opt_found=no - for ac_opt in "none needed" "-D_FILE_OFFSET_BITS=64" "-D_LARGE_FILES=1" "-n32"; do - if test x"$ac_opt" != x"none needed" -then : - CC="$ac_save_CC $ac_opt" -fi - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + CC="$ac_save_CC $ac_opt" +fi + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #ifndef FTYPE @@ -20682,7 +20611,154 @@ fi if test "$enable_warnings" = "yes"; then -for flag in -std=c90 -Wall -Wextra -Waggregate-return -Wcast-align -Wcast-qual -Wconversion -Wdeclaration-after-statement -Wdouble-promotion -Wfloat-equal -Wformat-security -Winit-self -Wjump-misses-init -Wlogical-op -Wmissing-braces -Wmissing-declarations -Wmissing-format-attribute -Wmissing-include-dirs -Wmissing-prototypes -Wnested-externs -Wno-coverage-mismatch -Wold-style-definition -Wpacked -Wpedantic -Wpointer-arith -Wredundant-decls -Wshadow -Wsign-conversion -Wstrict-overflow -Wstrict-prototypes -Wtrampolines -Wundef -Wunreachable-code -Wunused -Wvariadic-macros -Wvla -Wwrite-strings -Werror=implicit-int -Werror=implicit-function-declaration -Werror=partial-availability -Wno-long-long ; do +for flag in -Wall -Wextra -Waggregate-return -Wcast-align -Wcast-qual -Wconversion -Wdeclaration-after-statement -Wdouble-promotion -Wfloat-equal -Wformat-security -Winit-self -Wjump-misses-init -Wlogical-op -Wmissing-braces -Wmissing-declarations -Wmissing-format-attribute -Wmissing-include-dirs -Wmissing-prototypes -Wnested-externs -Wno-coverage-mismatch -Wold-style-definition -Wpacked -Wpedantic -Wpointer-arith -Wredundant-decls -Wshadow -Wsign-conversion -Wstrict-overflow -Wstrict-prototypes -Wtrampolines -Wundef -Wunreachable-code -Wunused -Wvariadic-macros -Wvla -Wwrite-strings -Werror=implicit-int -Werror=implicit-function-declaration -Werror=partial-availability -Wno-long-long ; do + as_CACHEVAR=`printf "%s\n" "ax_cv_check_cflags_-Werror_$flag" | sed "$as_sed_sh"` +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts $flag" >&5 +printf %s "checking whether C compiler accepts $flag... " >&6; } +if eval test \${$as_CACHEVAR+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) + ax_check_save_flags=$CFLAGS + CFLAGS="$CFLAGS -Werror $flag" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + eval "$as_CACHEVAR=yes" +else case e in #( + e) eval "$as_CACHEVAR=no" ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + CFLAGS=$ax_check_save_flags ;; +esac +fi +eval ac_res=\$$as_CACHEVAR + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } +if test x"`eval 'as_val=${'$as_CACHEVAR'};printf "%s\n" "$as_val"'`" = xyes +then : + if test ${AM_CFLAGS+y} +then : + case " $AM_CFLAGS " in + *" $flag "*) + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: : AM_CFLAGS already contains \$flag"; } >&5 + (: AM_CFLAGS already contains $flag) 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + ;; + *) + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: : AM_CFLAGS=\"\$AM_CFLAGS \$flag\""; } >&5 + (: AM_CFLAGS="$AM_CFLAGS $flag") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + AM_CFLAGS="$AM_CFLAGS $flag" + ;; + esac +else case e in #( + e) AM_CFLAGS="$flag" ;; +esac +fi + +else case e in #( + e) : ;; +esac +fi + +done + + + case $host_os in + *android*) + + +for flag in -std=c99; do + as_CACHEVAR=`printf "%s\n" "ax_cv_check_cflags_-Werror_$flag" | sed "$as_sed_sh"` +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts $flag" >&5 +printf %s "checking whether C compiler accepts $flag... " >&6; } +if eval test \${$as_CACHEVAR+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) + ax_check_save_flags=$CFLAGS + CFLAGS="$CFLAGS -Werror $flag" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + eval "$as_CACHEVAR=yes" +else case e in #( + e) eval "$as_CACHEVAR=no" ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + CFLAGS=$ax_check_save_flags ;; +esac +fi +eval ac_res=\$$as_CACHEVAR + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } +if test x"`eval 'as_val=${'$as_CACHEVAR'};printf "%s\n" "$as_val"'`" = xyes +then : + if test ${AM_CFLAGS+y} +then : + case " $AM_CFLAGS " in + *" $flag "*) + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: : AM_CFLAGS already contains \$flag"; } >&5 + (: AM_CFLAGS already contains $flag) 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + ;; + *) + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: : AM_CFLAGS=\"\$AM_CFLAGS \$flag\""; } >&5 + (: AM_CFLAGS="$AM_CFLAGS $flag") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + AM_CFLAGS="$AM_CFLAGS $flag" + ;; + esac +else case e in #( + e) AM_CFLAGS="$flag" ;; +esac +fi + +else case e in #( + e) : ;; +esac +fi + +done + + ;; + *) + + +for flag in -std=c90; do as_CACHEVAR=`printf "%s\n" "ax_cv_check_cflags_-Werror_$flag" | sed "$as_sed_sh"` { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts $flag" >&5 printf %s "checking whether C compiler accepts $flag... " >&6; } @@ -20751,6 +20827,8 @@ fi done + ;; + esac fi if test "$ax_cv_c_compiler_vendor" = "intel"; then @@ -22622,6 +22700,14 @@ then : printf "%s\n" "#define HAVE_CONNECT 1" >>confdefs.h +fi +ac_fn_check_decl "$LINENO" "connectx" "ac_cv_have_decl_connectx" "$cares_all_includes +" "$ac_c_undeclared_builtin_options" "CFLAGS" +if test "x$ac_cv_have_decl_connectx" = xyes +then : + +printf "%s\n" "#define HAVE_CONNECTX 1" >>confdefs.h + fi ac_fn_check_decl "$LINENO" "closesocket" "ac_cv_have_decl_closesocket" "$cares_all_includes " "$ac_c_undeclared_builtin_options" "CFLAGS" @@ -22892,23 +22978,39 @@ ac_fn_check_decl "$LINENO" "epoll_create1" "ac_cv_have_decl_epoll_create1" "$car if test "x$ac_cv_have_decl_epoll_create1" = xyes then : -printf "%s\n" "#define HAVE_EPOLL 1" >>confdefs.h +printf "%s\n" "#define HAVE_EPOLL 1" >>confdefs.h + +fi +ac_fn_check_decl "$LINENO" "ConvertInterfaceIndexToLuid" "ac_cv_have_decl_ConvertInterfaceIndexToLuid" "$cares_all_includes +" "$ac_c_undeclared_builtin_options" "CFLAGS" +if test "x$ac_cv_have_decl_ConvertInterfaceIndexToLuid" = xyes +then : + +printf "%s\n" "#define HAVE_CONVERTINTERFACEINDEXTOLUID 1" >>confdefs.h + +fi +ac_fn_check_decl "$LINENO" "ConvertInterfaceLuidToNameA" "ac_cv_have_decl_ConvertInterfaceLuidToNameA" "$cares_all_includes +" "$ac_c_undeclared_builtin_options" "CFLAGS" +if test "x$ac_cv_have_decl_ConvertInterfaceLuidToNameA" = xyes +then : + +printf "%s\n" "#define HAVE_CONVERTINTERFACELUIDTONAMEA 1" >>confdefs.h fi -ac_fn_check_decl "$LINENO" "ConvertInterfaceIndexToLuid" "ac_cv_have_decl_ConvertInterfaceIndexToLuid" "$cares_all_includes +ac_fn_check_decl "$LINENO" "NotifyIpInterfaceChange" "ac_cv_have_decl_NotifyIpInterfaceChange" "$cares_all_includes " "$ac_c_undeclared_builtin_options" "CFLAGS" -if test "x$ac_cv_have_decl_ConvertInterfaceIndexToLuid" = xyes +if test "x$ac_cv_have_decl_NotifyIpInterfaceChange" = xyes then : -printf "%s\n" "#define HAVE_CONVERTINTERFACEINDEXTOLUID 1" >>confdefs.h +printf "%s\n" "#define HAVE_NOTIFYIPINTERFACECHANGE 1" >>confdefs.h fi -ac_fn_check_decl "$LINENO" "ConvertInterfaceLuidToNameA" "ac_cv_have_decl_ConvertInterfaceLuidToNameA" "$cares_all_includes +ac_fn_check_decl "$LINENO" "RegisterWaitForSingleObject" "ac_cv_have_decl_RegisterWaitForSingleObject" "$cares_all_includes " "$ac_c_undeclared_builtin_options" "CFLAGS" -if test "x$ac_cv_have_decl_ConvertInterfaceLuidToNameA" = xyes +if test "x$ac_cv_have_decl_RegisterWaitForSingleObject" = xyes then : -printf "%s\n" "#define HAVE_CONVERTINTERFACELUIDTONAMEA 1" >>confdefs.h +printf "%s\n" "#define HAVE_REGISTERWAITFORSINGLEOBJECT 1" >>confdefs.h fi ac_fn_check_decl "$LINENO" "__system_property_get" "ac_cv_have_decl___system_property_get" "$cares_all_includes @@ -24475,6 +24577,264 @@ printf "%s\n" "$as_me: WARNING: gmock could not be found, not building tests" >& else as_fn_error $? "tests require gmock" "$LINENO" 5 fi + else + +pkg_failed=no +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for gmock >= 1.12.0" >&5 +printf %s "checking for gmock >= 1.12.0... " >&6; } + +if test -n "$GMOCK112_CFLAGS"; then + pkg_cv_GMOCK112_CFLAGS="$GMOCK112_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gmock >= 1.12.0\""; } >&5 + ($PKG_CONFIG --exists --print-errors "gmock >= 1.12.0") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_GMOCK112_CFLAGS=`$PKG_CONFIG --cflags "gmock >= 1.12.0" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$GMOCK112_LIBS"; then + pkg_cv_GMOCK112_LIBS="$GMOCK112_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gmock >= 1.12.0\""; } >&5 + ($PKG_CONFIG --exists --print-errors "gmock >= 1.12.0") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_GMOCK112_LIBS=`$PKG_CONFIG --libs "gmock >= 1.12.0" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + GMOCK112_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "gmock >= 1.12.0" 2>&1` + else + GMOCK112_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "gmock >= 1.12.0" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$GMOCK112_PKG_ERRORS" >&5 + + have_gmock_v112=no +elif test $pkg_failed = untried; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + have_gmock_v112=no +else + GMOCK112_CFLAGS=$pkg_cv_GMOCK112_CFLAGS + GMOCK112_LIBS=$pkg_cv_GMOCK112_LIBS + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + have_gmock_v112=yes +fi + if test "x$have_gmock_v112" = "xyes" ; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether user namespaces are supported" >&5 +printf %s "checking whether user namespaces are supported... " >&6; } +if test ${ax_cv_user_namespace+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + if test "$cross_compiling" = yes +then : + ax_cv_user_namespace=no +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include + +int userfn(void *d) { + usleep(100000); /* synchronize by sleep */ + return (getuid() != 0); +} +char userst[1024*1024]; +int main() { + char buffer[1024]; + int rc, status, fd; + pid_t child = clone(userfn, userst + 1024*1024, CLONE_NEWUSER|SIGCHLD, 0); + if (child < 0) return 1; + + snprintf(buffer, sizeof(buffer), "/proc/%d/uid_map", child); + fd = open(buffer, O_CREAT|O_WRONLY|O_TRUNC, 0755); + snprintf(buffer, sizeof(buffer), "0 %d 1\n", getuid()); + write(fd, buffer, strlen(buffer)); + close(fd); + + rc = waitpid(child, &status, 0); + if (rc <= 0) return 1; + if (!WIFEXITED(status)) return 1; + return WEXITSTATUS(status); +} + +_ACEOF +if ac_fn_c_try_run "$LINENO" +then : + ax_cv_user_namespace=yes +else case e in #( + e) ax_cv_user_namespace=no ;; +esac +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac +fi + + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_user_namespace" >&5 +printf "%s\n" "$ax_cv_user_namespace" >&6; } + if test "$ax_cv_user_namespace" = yes; then + +printf "%s\n" "#define HAVE_USER_NAMESPACE 1" >>confdefs.h + + fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether UTS namespaces are supported" >&5 +printf %s "checking whether UTS namespaces are supported... " >&6; } +if test ${ax_cv_uts_namespace+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + if test "$cross_compiling" = yes +then : + ax_cv_uts_namespace=no +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include + +int utsfn(void *d) { + char buffer[1024]; + const char *name = "autoconftest"; + int rc = sethostname(name, strlen(name)); + if (rc != 0) return 1; + gethostname(buffer, 1024); + return (strcmp(buffer, name) != 0); +} + +char st2[1024*1024]; +int fn(void *d) { + pid_t child; + int rc, status; + usleep(100000); /* synchronize by sleep */ + if (getuid() != 0) return 1; + child = clone(utsfn, st2 + 1024*1024, CLONE_NEWUTS|SIGCHLD, 0); + if (child < 0) return 1; + rc = waitpid(child, &status, 0); + if (rc <= 0) return 1; + if (!WIFEXITED(status)) return 1; + return WEXITSTATUS(status); +} +char st[1024*1024]; +int main() { + char buffer[1024]; + int rc, status, fd; + pid_t child = clone(fn, st + 1024*1024, CLONE_NEWUSER|SIGCHLD, 0); + if (child < 0) return 1; + + snprintf(buffer, sizeof(buffer), "/proc/%d/uid_map", child); + fd = open(buffer, O_CREAT|O_WRONLY|O_TRUNC, 0755); + snprintf(buffer, sizeof(buffer), "0 %d 1\n", getuid()); + write(fd, buffer, strlen(buffer)); + close(fd); + + rc = waitpid(child, &status, 0); + if (rc <= 0) return 1; + if (!WIFEXITED(status)) return 1; + return WEXITSTATUS(status); +} + + +_ACEOF +if ac_fn_c_try_run "$LINENO" +then : + ax_cv_uts_namespace=yes +else case e in #( + e) ax_cv_uts_namespace=no ;; +esac +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac +fi + + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_uts_namespace" >&5 +printf "%s\n" "$ax_cv_uts_namespace" >&6; } + if test "$ax_cv_uts_namespace" = yes; then + +printf "%s\n" "#define HAVE_UTS_NAMESPACE 1" >>confdefs.h + + fi + + fi fi fi if test "x$build_tests" != "xno" ; then @@ -25912,6 +26272,18 @@ if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCXX\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +case $enable_silent_rules in # ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; +esac +if test $am_cv_make_support_nested_variables = yes; then + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi + if test -n "$EXEEXT"; then am__EXEEXT_TRUE= am__EXEEXT_FALSE='#' @@ -26339,7 +26711,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by c-ares $as_me 1.32.3, which was +This file was extended by c-ares $as_me 1.33.1, which was generated by GNU Autoconf 2.72. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -26407,7 +26779,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ -c-ares config.status 1.32.3 +c-ares config.status 1.33.1 configured by $0, generated by GNU Autoconf 2.72, with options \\"\$ac_cs_config\\" diff --git a/deps/cares/configure.ac b/deps/cares/configure.ac index 7abf80f68bd..59fd975b64f 100644 --- a/deps/cares/configure.ac +++ b/deps/cares/configure.ac @@ -2,10 +2,10 @@ dnl Copyright (C) The c-ares project and its contributors dnl SPDX-License-Identifier: MIT AC_PREREQ([2.69]) -AC_INIT([c-ares], [1.32.3], +AC_INIT([c-ares], [1.33.1], [c-ares mailing list: http://lists.haxx.se/listinfo/c-ares]) -CARES_VERSION_INFO="19:3:17" +CARES_VERSION_INFO="20:1:18" dnl This flag accepts an argument of the form current[:revision[:age]]. So, dnl passing -version-info 3:12:1 sets current to 3, revision to 12, and age to dnl 1. @@ -153,8 +153,6 @@ _EOF ]) AX_CODE_COVERAGE -AX_CHECK_USER_NAMESPACE -AX_CHECK_UTS_NAMESPACE AC_SYS_LARGEFILE case $host_os in @@ -245,8 +243,18 @@ AC_SUBST(CARES_SYMBOL_HIDING_CFLAG) if test "$enable_warnings" = "yes"; then - AX_APPEND_COMPILE_FLAGS([-std=c90 -Wall -Wextra -Waggregate-return -Wcast-align -Wcast-qual -Wconversion -Wdeclaration-after-statement -Wdouble-promotion -Wfloat-equal -Wformat-security -Winit-self -Wjump-misses-init -Wlogical-op -Wmissing-braces -Wmissing-declarations -Wmissing-format-attribute -Wmissing-include-dirs -Wmissing-prototypes -Wnested-externs -Wno-coverage-mismatch -Wold-style-definition -Wpacked -Wpedantic -Wpointer-arith -Wredundant-decls -Wshadow -Wsign-conversion -Wstrict-overflow -Wstrict-prototypes -Wtrampolines -Wundef -Wunreachable-code -Wunused -Wvariadic-macros -Wvla -Wwrite-strings -Werror=implicit-int -Werror=implicit-function-declaration -Werror=partial-availability -Wno-long-long ], + AX_APPEND_COMPILE_FLAGS([-Wall -Wextra -Waggregate-return -Wcast-align -Wcast-qual -Wconversion -Wdeclaration-after-statement -Wdouble-promotion -Wfloat-equal -Wformat-security -Winit-self -Wjump-misses-init -Wlogical-op -Wmissing-braces -Wmissing-declarations -Wmissing-format-attribute -Wmissing-include-dirs -Wmissing-prototypes -Wnested-externs -Wno-coverage-mismatch -Wold-style-definition -Wpacked -Wpedantic -Wpointer-arith -Wredundant-decls -Wshadow -Wsign-conversion -Wstrict-overflow -Wstrict-prototypes -Wtrampolines -Wundef -Wunreachable-code -Wunused -Wvariadic-macros -Wvla -Wwrite-strings -Werror=implicit-int -Werror=implicit-function-declaration -Werror=partial-availability -Wno-long-long ], [AM_CFLAGS], [-Werror]) + + dnl Android requires c99, all others should use c90 + case $host_os in + *android*) + AX_APPEND_COMPILE_FLAGS([-std=c99], [AM_CFLAGS], [-Werror]) + ;; + *) + AX_APPEND_COMPILE_FLAGS([-std=c90], [AM_CFLAGS], [-Werror]) + ;; + esac fi if test "$ax_cv_c_compiler_vendor" = "intel"; then @@ -538,6 +546,7 @@ AC_CHECK_DECL(send, [AC_DEFINE([HAVE_SEND], 1, [Define t AC_CHECK_DECL(getnameinfo, [AC_DEFINE([HAVE_GETNAMEINFO], 1, [Define to 1 if you have `getnameinfo`] )], [], $cares_all_includes) AC_CHECK_DECL(gethostname, [AC_DEFINE([HAVE_GETHOSTNAME], 1, [Define to 1 if you have `gethostname`] )], [], $cares_all_includes) AC_CHECK_DECL(connect, [AC_DEFINE([HAVE_CONNECT], 1, [Define to 1 if you have `connect`] )], [], $cares_all_includes) +AC_CHECK_DECL(connectx, [AC_DEFINE([HAVE_CONNECTX], 1, [Define to 1 if you have `connectx`] )], [], $cares_all_includes) AC_CHECK_DECL(closesocket, [AC_DEFINE([HAVE_CLOSESOCKET], 1, [Define to 1 if you have `closesocket`] )], [], $cares_all_includes) AC_CHECK_DECL(CloseSocket, [AC_DEFINE([HAVE_CLOSESOCKET_CAMEL], 1, [Define to 1 if you have `CloseSocket`] )], [], $cares_all_includes) AC_CHECK_DECL(fcntl, [AC_DEFINE([HAVE_FCNTL], 1, [Define to 1 if you have `fcntl`] )], [], $cares_all_includes) @@ -574,6 +583,8 @@ AC_CHECK_DECL(kqueue, [AC_DEFINE([HAVE_KQUEUE], 1, [Define t AC_CHECK_DECL(epoll_create1, [AC_DEFINE([HAVE_EPOLL], 1, [Define to 1 if you have `epoll_{create1,ctl,wait}`])], [], $cares_all_includes) AC_CHECK_DECL(ConvertInterfaceIndexToLuid, [AC_DEFINE([HAVE_CONVERTINTERFACEINDEXTOLUID], 1, [Define to 1 if you have `ConvertInterfaceIndexToLuid`])], [], $cares_all_includes) AC_CHECK_DECL(ConvertInterfaceLuidToNameA, [AC_DEFINE([HAVE_CONVERTINTERFACELUIDTONAMEA], 1, [Define to 1 if you have `ConvertInterfaceLuidToNameA`])], [], $cares_all_includes) +AC_CHECK_DECL(NotifyIpInterfaceChange, [AC_DEFINE([HAVE_NOTIFYIPINTERFACECHANGE], 1, [Define to 1 if you have `NotifyIpInterfaceChange`] )], [], $cares_all_includes) +AC_CHECK_DECL(RegisterWaitForSingleObject, [AC_DEFINE([HAVE_REGISTERWAITFORSINGLEOBJECT], 1, [Define to 1 if you have `RegisterWaitForSingleObject`])], [], $cares_all_includes) AC_CHECK_DECL(__system_property_get, [AC_DEFINE([HAVE___SYSTEM_PROPERTY_GET], 1, [Define to 1 if you have `__system_property_get`] )], [], $cares_all_includes) @@ -806,6 +817,12 @@ if test "x$build_tests" != "xno" ; then else AC_MSG_ERROR([tests require gmock]) fi + else + PKG_CHECK_MODULES([GMOCK112], [gmock >= 1.12.0], [ have_gmock_v112=yes ], [ have_gmock_v112=no ]) + if test "x$have_gmock_v112" = "xyes" ; then + AX_CHECK_USER_NAMESPACE + AX_CHECK_UTS_NAMESPACE + fi fi fi if test "x$build_tests" != "xno" ; then diff --git a/deps/cares/docs/Makefile.in b/deps/cares/docs/Makefile.in index 0b44dbd8c53..a57cd0abc18 100644 --- a/deps/cares/docs/Makefile.in +++ b/deps/cares/docs/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.5 from Makefile.am. +# Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2021 Free Software Foundation, Inc. +# Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -72,6 +72,8 @@ am__make_running_with_option = \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +am__rm_f = rm -f $(am__rm_f_notfound) +am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -166,10 +168,9 @@ am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ - test -z "$$files" \ - || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ - || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ - $(am__cd) "$$dir" && rm -f $$files; }; \ + { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && echo $$files | $(am__xargs_n) 40 $(am__rm_f); }; \ } man3dir = $(mandir)/man3 am__installdirs = "$(DESTDIR)$(man3dir)" @@ -226,6 +227,8 @@ FGREP = @FGREP@ FILECMD = @FILECMD@ GCOV = @GCOV@ GENHTML = @GENHTML@ +GMOCK112_CFLAGS = @GMOCK112_CFLAGS@ +GMOCK112_LIBS = @GMOCK112_LIBS@ GMOCK_CFLAGS = @GMOCK_CFLAGS@ GMOCK_LIBS = @GMOCK_LIBS@ GREP = @GREP@ @@ -288,8 +291,10 @@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ +am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ +am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ @@ -638,8 +643,8 @@ mostlyclean-generic: clean-generic: distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -$(am__rm_f) $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @@ -733,3 +738,10 @@ uninstall-man: uninstall-man3 # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: + +# Tell GNU make to disable its built-in pattern rules. +%:: %,v +%:: RCS/%,v +%:: RCS/% +%:: s.% +%:: SCCS/s.% diff --git a/deps/cares/docs/ares_dns_rr.3 b/deps/cares/docs/ares_dns_rr.3 index 9d5ab37515e..4da768650b5 100644 --- a/deps/cares/docs/ares_dns_rr.3 +++ b/deps/cares/docs/ares_dns_rr.3 @@ -96,6 +96,10 @@ ares_status_t ares_dns_rr_set_opt(ares_dns_rr_t *dns_rr, const unsigned char *val, size_t val_len); +ares_status_t ares_dns_rr_del_opt_byid(ares_dns_rr_t *dns_rr, + ares_dns_rr_key_t key, + unsigned short opt); + const struct in_addr *ares_dns_rr_get_addr(const ares_dns_rr_t *dns_rr, ares_dns_rr_key_t key); @@ -553,7 +557,7 @@ parameter, and the index to remove is provided in the parameter. The \fIares_dns_rr_set_opt(3)\fP function is used to set option/parameter keys and -values for the resource record when the datatype if \fIARES_DATATYPE_OPT\fP. The +values for the resource record when the datatype is \fIARES_DATATYPE_OPT\fP. The resource record to be modified is provided in the .IR dns_rr parameter. They key/parameter is provided in the @@ -568,6 +572,18 @@ enumerations. The value for the option is always provided in binary form in with length provided in .IR val_len. +The \fIares_dns_rr_del_opt_byid(3)\fP function is used to delete option/parameter +keys and values for the resource record when the datatype is +\fIARES_DATATYPE_OPT\fP. The resource record to be modified is provided in the +.IR dns_rr +parameter. They key/parameter is provided in the +.IR key +parameter. The option/parameter value specific to the resource record is provided +in the +.IR opt +parameter. This function returns \fIARES_SUCCESS\fP if the record is successfully +removed, or \fIARES_ENOTFOUND\fP if the record could not be found. + The \fIares_dns_rr_get_addr(3)\fP function is used to retrieve the IPv4 address from the resource record when the datatype is \fIARES_DATATYPE_INADDR\fP. The resource record is provided in the @@ -635,7 +651,7 @@ parameter and the key/parameter to retrieve is provided in the .IR key parameter. -The \fIares_dns_rr_get_abin(3)\fP function is used to retrive binary data from +The \fIares_dns_rr_get_abin(3)\fP function is used to retrieve binary data from the resource record array when the datatype is \fIARES_DATATYPE_ABINP\fP. The resource record is provided in the .IR dns_rr diff --git a/deps/cares/include/Makefile.in b/deps/cares/include/Makefile.in index 94e8e640fbe..99936f86497 100644 --- a/deps/cares/include/Makefile.in +++ b/deps/cares/include/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.5 from Makefile.am. +# Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2021 Free Software Foundation, Inc. +# Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -70,6 +70,8 @@ am__make_running_with_option = \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +am__rm_f = rm -f $(am__rm_f_notfound) +am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -162,10 +164,9 @@ am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ - test -z "$$files" \ - || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ - || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ - $(am__cd) "$$dir" && rm -f $$files; }; \ + { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && echo $$files | $(am__xargs_n) 40 $(am__rm_f); }; \ } am__installdirs = "$(DESTDIR)$(includedir)" HEADERS = $(include_HEADERS) @@ -237,6 +238,8 @@ FGREP = @FGREP@ FILECMD = @FILECMD@ GCOV = @GCOV@ GENHTML = @GENHTML@ +GMOCK112_CFLAGS = @GMOCK112_CFLAGS@ +GMOCK112_LIBS = @GMOCK112_LIBS@ GMOCK_CFLAGS = @GMOCK_CFLAGS@ GMOCK_LIBS = @GMOCK_LIBS@ GREP = @GREP@ @@ -299,8 +302,10 @@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ +am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ +am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ @@ -393,8 +398,8 @@ ares_build.h: stamp-h2 @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h2 stamp-h2: $(srcdir)/ares_build.h.in $(top_builddir)/config.status - @rm -f stamp-h2 - cd $(top_builddir) && $(SHELL) ./config.status include/ares_build.h + $(AM_V_at)rm -f stamp-h2 + $(AM_V_GEN)cd $(top_builddir) && $(SHELL) ./config.status include/ares_build.h distclean-hdr: -rm -f ares_build.h stamp-h2 @@ -541,8 +546,8 @@ mostlyclean-generic: clean-generic: distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -$(am__rm_f) $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @@ -635,3 +640,10 @@ uninstall-am: uninstall-includeHEADERS # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: + +# Tell GNU make to disable its built-in pattern rules. +%:: %,v +%:: RCS/%,v +%:: RCS/% +%:: s.% +%:: SCCS/s.% diff --git a/deps/cares/include/ares.h b/deps/cares/include/ares.h index afff1759b39..95fc2440a1f 100644 --- a/deps/cares/include/ares.h +++ b/deps/cares/include/ares.h @@ -95,7 +95,7 @@ #endif typedef CARES_TYPEOF_ARES_SOCKLEN_T ares_socklen_t; -typedef CARES_TYPEOF_ARES_SSIZE_T ares_ssize_t; +typedef CARES_TYPEOF_ARES_SSIZE_T ares_ssize_t; #ifdef __cplusplus extern "C" { diff --git a/deps/cares/include/ares_dns_record.h b/deps/cares/include/ares_dns_record.h index 00b6809f124..2896eab24b3 100644 --- a/deps/cares/include/ares_dns_record.h +++ b/deps/cares/include/ares_dns_record.h @@ -152,28 +152,28 @@ typedef enum { ARES_RCODE_BADNAME = 20, /*!< RFC 2930. Duplicate Key Name */ ARES_RCODE_BADALG = 21, /*!< RFC 2930. Algorithm not supported */ ARES_RCODE_BADTRUNC = 22, /*!< RFC 8945. Bad Truncation */ - ARES_RCODE_BADCOOKIE = 23 /*!< RVC 7973. Bad/missing Server Cookie */ + ARES_RCODE_BADCOOKIE = 23 /*!< RFC 7873. Bad/missing Server Cookie */ } ares_dns_rcode_t; /*! Data types used */ typedef enum { - ARES_DATATYPE_INADDR = 1, /*!< struct in_addr * type */ - ARES_DATATYPE_INADDR6 = 2, /*!< struct ares_in6_addr * type */ - ARES_DATATYPE_U8 = 3, /*!< 8bit unsigned integer */ - ARES_DATATYPE_U16 = 4, /*!< 16bit unsigned integer */ - ARES_DATATYPE_U32 = 5, /*!< 32bit unsigned integer */ - ARES_DATATYPE_NAME = 6, /*!< Null-terminated string of a domain name */ - ARES_DATATYPE_STR = 7, /*!< Null-terminated string */ - ARES_DATATYPE_BIN = 8, /*!< Binary data */ - ARES_DATATYPE_BINP = 9, /*!< Officially defined as binary data, but likely - * printable. Guaranteed to have a NULL - * terminator for convenience (not included in - * length) */ - ARES_DATATYPE_OPT = 10, /*!< Array of options. 16bit identifier, BIN - * data. */ - ARES_DATATYPE_ABINP = 11 /*!< Array of binary data, likely printable. - * Guaranteed to have a NULL terminator for - * convenience (not included in length) */ + ARES_DATATYPE_INADDR = 1, /*!< struct in_addr * type */ + ARES_DATATYPE_INADDR6 = 2, /*!< struct ares_in6_addr * type */ + ARES_DATATYPE_U8 = 3, /*!< 8bit unsigned integer */ + ARES_DATATYPE_U16 = 4, /*!< 16bit unsigned integer */ + ARES_DATATYPE_U32 = 5, /*!< 32bit unsigned integer */ + ARES_DATATYPE_NAME = 6, /*!< Null-terminated string of a domain name */ + ARES_DATATYPE_STR = 7, /*!< Null-terminated string */ + ARES_DATATYPE_BIN = 8, /*!< Binary data */ + ARES_DATATYPE_BINP = 9, /*!< Officially defined as binary data, but likely + * printable. Guaranteed to have a NULL + * terminator for convenience (not included in + * length) */ + ARES_DATATYPE_OPT = 10, /*!< Array of options. 16bit identifier, BIN + * data. */ + ARES_DATATYPE_ABINP = 11 /*!< Array of binary data, likely printable. + * Guaranteed to have a NULL terminator for + * convenience (not included in length) */ } ares_dns_datatype_t; /*! Keys used for all RR Types. We take the record type and multiply by 100 @@ -609,8 +609,8 @@ CARES_EXTERN unsigned short * \param[in] id DNS query id * \return ARES_TRUE on success, ARES_FALSE on usage error */ -CARES_EXTERN ares_bool_t - ares_dns_record_set_id(ares_dns_record_t *dnsrec, unsigned short id); +CARES_EXTERN ares_bool_t ares_dns_record_set_id(ares_dns_record_t *dnsrec, + unsigned short id); /*! Get the DNS Record Flags * @@ -885,10 +885,10 @@ CARES_EXTERN ares_status_t ares_dns_rr_set_bin(ares_dns_rr_t *dns_rr, * \param[in] len Length of binary data * \return ARES_SUCCESS on success */ -CARES_EXTERN ares_status_t ares_dns_rr_add_abin(ares_dns_rr_t *dns_rr, - ares_dns_rr_key_t key, +CARES_EXTERN ares_status_t ares_dns_rr_add_abin(ares_dns_rr_t *dns_rr, + ares_dns_rr_key_t key, const unsigned char *val, - size_t len); + size_t len); /*! Delete binary array value (ABINP) data for specified resource record and * key by specified index. Can only be used on keys with datatype @@ -899,9 +899,9 @@ CARES_EXTERN ares_status_t ares_dns_rr_add_abin(ares_dns_rr_t *dns_rr, * \param[in] idx Index to delete * \return ARES_SUCCESS on success */ -CARES_EXTERN ares_status_t ares_dns_rr_del_abin(ares_dns_rr_t *dns_rr, +CARES_EXTERN ares_status_t ares_dns_rr_del_abin(ares_dns_rr_t *dns_rr, ares_dns_rr_key_t key, - size_t idx); + size_t idx); /*! Set the option for the RR * @@ -918,6 +918,17 @@ CARES_EXTERN ares_status_t ares_dns_rr_set_opt(ares_dns_rr_t *dns_rr, const unsigned char *val, size_t val_len); +/*! Delete the option for the RR by id + * + * \param[in] dns_rr Pointer to resource record + * \param[in] key DNS Resource Record Key + * \param[in] opt Option record key id. + * \return ARES_SUCCESS if removed, ARES_ENOTFOUND if not found + */ +CARES_EXTERN ares_status_t ares_dns_rr_del_opt_byid(ares_dns_rr_t *dns_rr, + ares_dns_rr_key_t key, + unsigned short opt); + /*! Retrieve a pointer to the ipv4 address. Can only be used on keys with * datatype ARES_DATATYPE_INADDR. * @@ -1000,7 +1011,7 @@ CARES_EXTERN const unsigned char * * \return count of values */ CARES_EXTERN size_t ares_dns_rr_get_abin_cnt(const ares_dns_rr_t *dns_rr, - ares_dns_rr_key_t key); + ares_dns_rr_key_t key); /*! Retrieve a pointer to the binary array data from the specified index. Can * only be used on keys with datatype ARES_DATATYPE_ABINP. If ABINP, the data @@ -1014,8 +1025,9 @@ CARES_EXTERN size_t ares_dns_rr_get_abin_cnt(const ares_dns_rr_t *dns_rr, * \param[out] len Length of binary data returned * \return pointer binary data or NULL on error */ -CARES_EXTERN const unsigned char *ares_dns_rr_get_abin( - const ares_dns_rr_t *dns_rr, ares_dns_rr_key_t key, size_t idx, size_t *len); +CARES_EXTERN const unsigned char * + ares_dns_rr_get_abin(const ares_dns_rr_t *dns_rr, ares_dns_rr_key_t key, + size_t idx, size_t *len); /*! Retrieve the number of options stored for the RR. diff --git a/deps/cares/include/ares_version.h b/deps/cares/include/ares_version.h index 62541c31ba9..c910d79209a 100644 --- a/deps/cares/include/ares_version.h +++ b/deps/cares/include/ares_version.h @@ -31,12 +31,12 @@ #define ARES_COPYRIGHT "2004 - 2024 Daniel Stenberg, ." #define ARES_VERSION_MAJOR 1 -#define ARES_VERSION_MINOR 32 -#define ARES_VERSION_PATCH 3 +#define ARES_VERSION_MINOR 33 +#define ARES_VERSION_PATCH 1 #define ARES_VERSION \ ((ARES_VERSION_MAJOR << 16) | (ARES_VERSION_MINOR << 8) | \ (ARES_VERSION_PATCH)) -#define ARES_VERSION_STR "1.32.3" +#define ARES_VERSION_STR "1.33.1" #define CARES_HAVE_ARES_LIBRARY_INIT 1 #define CARES_HAVE_ARES_LIBRARY_CLEANUP 1 diff --git a/deps/cares/libcares.pc.cmake b/deps/cares/libcares.pc.cmake index 74e4d0cf445..257255d84d5 100644 --- a/deps/cares/libcares.pc.cmake +++ b/deps/cares/libcares.pc.cmake @@ -7,9 +7,9 @@ # Copyright (C) The c-ares project and its contributors # SPDX-License-Identifier: MIT prefix=@CMAKE_INSTALL_PREFIX@ -exec_prefix=@CMAKE_INSTALL_FULL_BINDIR@ -libdir=@CMAKE_INSTALL_FULL_LIBDIR@ -includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@ +exec_prefix=${prefix}/@CMAKE_INSTALL_BINDIR@ +libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@ +includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@ Name: c-ares URL: https://c-ares.org/ @@ -18,5 +18,6 @@ Version: @CARES_VERSION@ Requires: Requires.private: Cflags: -I${includedir} +Cflags.private: -DCARES_STATICLIB Libs: -L${libdir} -lcares Libs.private: @CARES_PRIVATE_LIBS@ diff --git a/deps/cares/msvc_ver.inc b/deps/cares/msvc_ver.inc deleted file mode 100644 index 61bdb59ae2c..00000000000 --- a/deps/cares/msvc_ver.inc +++ /dev/null @@ -1,26 +0,0 @@ -# Copyright (C) The c-ares project and its contributors -# SPDX-License-Identifier: MIT -# ----------------------------------------------- -# Detect NMAKE version deducing old MSVC versions -# ----------------------------------------------- - -!IFNDEF _NMAKE_VER -! MESSAGE Macro _NMAKE_VER not defined. -! MESSAGE Use MSVC's NMAKE to process this makefile. -! ERROR See previous message. -!ENDIF - -!IF "$(_NMAKE_VER)" == "6.00.8168.0" -CC_VERS_NUM = 60 -!ELSEIF "$(_NMAKE_VER)" == "6.00.9782.0" -CC_VERS_NUM = 60 -!ELSEIF "$(_NMAKE_VER)" == "7.00.8882" -CC_VERS_NUM = 70 -!ELSEIF "$(_NMAKE_VER)" == "7.00.9466" -CC_VERS_NUM = 70 -!ELSEIF "$(_NMAKE_VER)" == "7.00.9955" -CC_VERS_NUM = 70 -!ELSE -# Pick an arbitrary bigger number for all later versions -CC_VERS_NUM = 199 -!ENDIF diff --git a/deps/cares/src/Makefile.in b/deps/cares/src/Makefile.in index f657ef0d43e..3ad8a92a6a4 100644 --- a/deps/cares/src/Makefile.in +++ b/deps/cares/src/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.5 from Makefile.am. +# Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2021 Free Software Foundation, Inc. +# Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -69,6 +69,8 @@ am__make_running_with_option = \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +am__rm_f = rm -f $(am__rm_f_notfound) +am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -248,6 +250,8 @@ FGREP = @FGREP@ FILECMD = @FILECMD@ GCOV = @GCOV@ GENHTML = @GENHTML@ +GMOCK112_CFLAGS = @GMOCK112_CFLAGS@ +GMOCK112_LIBS = @GMOCK112_LIBS@ GMOCK_CFLAGS = @GMOCK_CFLAGS@ GMOCK_LIBS = @GMOCK_LIBS@ GREP = @GREP@ @@ -310,8 +314,10 @@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ +am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ +am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ @@ -585,8 +591,8 @@ mostlyclean-generic: clean-generic: distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -$(am__rm_f) $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @@ -678,3 +684,10 @@ uninstall-am: # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: + +# Tell GNU make to disable its built-in pattern rules. +%:: %,v +%:: RCS/%,v +%:: RCS/% +%:: s.% +%:: SCCS/s.% diff --git a/deps/cares/src/lib/Makefile.in b/deps/cares/src/lib/Makefile.in index d1758eb8adb..30d33843d5d 100644 --- a/deps/cares/src/lib/Makefile.in +++ b/deps/cares/src/lib/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.5 from Makefile.am. +# Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2021 Free Software Foundation, Inc. +# Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -15,7 +15,7 @@ @SET_MAKE@ # aminclude_static.am generated automatically by Autoconf -# from AX_AM_MACROS_STATIC on Wed Jul 24 05:40:58 EDT 2024 +# from AX_AM_MACROS_STATIC on Fri Aug 23 09:37:25 EDT 2024 # Copyright (C) The c-ares project and its contributors # SPDX-License-Identifier: MIT @@ -76,6 +76,8 @@ am__make_running_with_option = \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +am__rm_f = rm -f $(am__rm_f_notfound) +am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -152,75 +154,84 @@ am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ - test -z "$$files" \ - || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ - || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ - $(am__cd) "$$dir" && rm -f $$files; }; \ + { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && echo $$files | $(am__xargs_n) 40 $(am__rm_f); }; \ } am__installdirs = "$(DESTDIR)$(libdir)" LTLIBRARIES = $(lib_LTLIBRARIES) libcares_la_LIBADD = +am__dirstamp = $(am__leading_dot)dirstamp am__objects_1 = libcares_la-ares__addrinfo2hostent.lo \ libcares_la-ares__addrinfo_localhost.lo \ - libcares_la-ares__buf.lo libcares_la-ares__close_sockets.lo \ - libcares_la-ares__hosts_file.lo libcares_la-ares__htable.lo \ - libcares_la-ares__htable_asvp.lo \ - libcares_la-ares__htable_strvp.lo \ - libcares_la-ares__htable_szvp.lo \ - libcares_la-ares__htable_vpvp.lo \ - libcares_la-ares__iface_ips.lo libcares_la-ares__llist.lo \ + libcares_la-ares__close_sockets.lo \ + libcares_la-ares__hosts_file.lo \ libcares_la-ares__parse_into_addrinfo.lo \ - libcares_la-ares__slist.lo libcares_la-ares__socket.lo \ - libcares_la-ares__sortaddrinfo.lo libcares_la-ares__threads.lo \ - libcares_la-ares__timeval.lo libcares_la-ares_android.lo \ - libcares_la-ares_cancel.lo libcares_la-ares_data.lo \ - libcares_la-ares_destroy.lo libcares_la-ares_dns_mapping.lo \ - libcares_la-ares_dns_multistring.lo \ - libcares_la-ares_dns_name.lo libcares_la-ares_dns_parse.lo \ - libcares_la-ares_dns_record.lo libcares_la-ares_dns_write.lo \ - libcares_la-ares_event_configchg.lo \ - libcares_la-ares_event_epoll.lo \ - libcares_la-ares_event_kqueue.lo \ - libcares_la-ares_event_poll.lo \ - libcares_la-ares_event_select.lo \ - libcares_la-ares_event_thread.lo \ - libcares_la-ares_event_wake_pipe.lo \ - libcares_la-ares_event_win32.lo \ - libcares_la-ares_expand_name.lo \ - libcares_la-ares_expand_string.lo libcares_la-ares_fds.lo \ - libcares_la-ares_free_hostent.lo \ + libcares_la-ares__socket.lo libcares_la-ares__sortaddrinfo.lo \ + libcares_la-ares_android.lo libcares_la-ares_cancel.lo \ + libcares_la-ares_cookie.lo libcares_la-ares_data.lo \ + libcares_la-ares_destroy.lo libcares_la-ares_free_hostent.lo \ libcares_la-ares_free_string.lo \ libcares_la-ares_freeaddrinfo.lo \ libcares_la-ares_getaddrinfo.lo libcares_la-ares_getenv.lo \ libcares_la-ares_gethostbyaddr.lo \ libcares_la-ares_gethostbyname.lo \ - libcares_la-ares_getnameinfo.lo libcares_la-ares_getsock.lo \ - libcares_la-ares_init.lo libcares_la-ares_library_init.lo \ - libcares_la-ares_math.lo libcares_la-ares_metrics.lo \ - libcares_la-ares_create_query.lo libcares_la-ares_options.lo \ - libcares_la-ares_parse_a_reply.lo \ - libcares_la-ares_parse_aaaa_reply.lo \ - libcares_la-ares_parse_caa_reply.lo \ - libcares_la-ares_parse_mx_reply.lo \ - libcares_la-ares_parse_naptr_reply.lo \ - libcares_la-ares_parse_ns_reply.lo \ - libcares_la-ares_parse_ptr_reply.lo \ - libcares_la-ares_parse_soa_reply.lo \ - libcares_la-ares_parse_srv_reply.lo \ - libcares_la-ares_parse_txt_reply.lo \ - libcares_la-ares_parse_uri_reply.lo \ - libcares_la-ares_platform.lo libcares_la-ares_process.lo \ - libcares_la-ares_qcache.lo libcares_la-ares_query.lo \ - libcares_la-ares_rand.lo libcares_la-ares_search.lo \ - libcares_la-ares_send.lo libcares_la-ares_strcasecmp.lo \ - libcares_la-ares_str.lo libcares_la-ares_strerror.lo \ - libcares_la-ares_strsplit.lo libcares_la-ares_sysconfig.lo \ + libcares_la-ares_getnameinfo.lo libcares_la-ares_init.lo \ + libcares_la-ares_library_init.lo libcares_la-ares_metrics.lo \ + libcares_la-ares_options.lo libcares_la-ares_platform.lo \ + libcares_la-ares_process.lo libcares_la-ares_qcache.lo \ + libcares_la-ares_query.lo libcares_la-ares_search.lo \ + libcares_la-ares_send.lo libcares_la-ares_strerror.lo \ + libcares_la-ares_sysconfig.lo \ libcares_la-ares_sysconfig_files.lo \ libcares_la-ares_sysconfig_mac.lo \ libcares_la-ares_sysconfig_win.lo libcares_la-ares_timeout.lo \ libcares_la-ares_update_servers.lo libcares_la-ares_version.lo \ libcares_la-inet_net_pton.lo libcares_la-inet_ntop.lo \ - libcares_la-windows_port.lo + libcares_la-windows_port.lo dsa/libcares_la-ares__array.lo \ + dsa/libcares_la-ares__htable.lo \ + dsa/libcares_la-ares__htable_asvp.lo \ + dsa/libcares_la-ares__htable_strvp.lo \ + dsa/libcares_la-ares__htable_szvp.lo \ + dsa/libcares_la-ares__htable_vpvp.lo \ + dsa/libcares_la-ares__llist.lo dsa/libcares_la-ares__slist.lo \ + event/libcares_la-ares_event_configchg.lo \ + event/libcares_la-ares_event_epoll.lo \ + event/libcares_la-ares_event_kqueue.lo \ + event/libcares_la-ares_event_poll.lo \ + event/libcares_la-ares_event_select.lo \ + event/libcares_la-ares_event_thread.lo \ + event/libcares_la-ares_event_wake_pipe.lo \ + event/libcares_la-ares_event_win32.lo \ + legacy/libcares_la-ares_create_query.lo \ + legacy/libcares_la-ares_expand_name.lo \ + legacy/libcares_la-ares_expand_string.lo \ + legacy/libcares_la-ares_fds.lo \ + legacy/libcares_la-ares_getsock.lo \ + legacy/libcares_la-ares_parse_a_reply.lo \ + legacy/libcares_la-ares_parse_aaaa_reply.lo \ + legacy/libcares_la-ares_parse_caa_reply.lo \ + legacy/libcares_la-ares_parse_mx_reply.lo \ + legacy/libcares_la-ares_parse_naptr_reply.lo \ + legacy/libcares_la-ares_parse_ns_reply.lo \ + legacy/libcares_la-ares_parse_ptr_reply.lo \ + legacy/libcares_la-ares_parse_soa_reply.lo \ + legacy/libcares_la-ares_parse_srv_reply.lo \ + legacy/libcares_la-ares_parse_txt_reply.lo \ + legacy/libcares_la-ares_parse_uri_reply.lo \ + record/libcares_la-ares_dns_mapping.lo \ + record/libcares_la-ares_dns_multistring.lo \ + record/libcares_la-ares_dns_name.lo \ + record/libcares_la-ares_dns_parse.lo \ + record/libcares_la-ares_dns_record.lo \ + record/libcares_la-ares_dns_write.lo \ + str/libcares_la-ares__buf.lo \ + str/libcares_la-ares_strcasecmp.lo str/libcares_la-ares_str.lo \ + str/libcares_la-ares_strsplit.lo \ + util/libcares_la-ares__iface_ips.lo \ + util/libcares_la-ares__threads.lo \ + util/libcares_la-ares__timeval.lo \ + util/libcares_la-ares_math.lo util/libcares_la-ares_rand.lo am__objects_2 = am_libcares_la_OBJECTS = $(am__objects_1) $(am__objects_2) libcares_la_OBJECTS = $(am_libcares_la_OBJECTS) @@ -249,44 +260,16 @@ am__maybe_remake_depfiles = depfiles am__depfiles_remade = \ ./$(DEPDIR)/libcares_la-ares__addrinfo2hostent.Plo \ ./$(DEPDIR)/libcares_la-ares__addrinfo_localhost.Plo \ - ./$(DEPDIR)/libcares_la-ares__buf.Plo \ ./$(DEPDIR)/libcares_la-ares__close_sockets.Plo \ ./$(DEPDIR)/libcares_la-ares__hosts_file.Plo \ - ./$(DEPDIR)/libcares_la-ares__htable.Plo \ - ./$(DEPDIR)/libcares_la-ares__htable_asvp.Plo \ - ./$(DEPDIR)/libcares_la-ares__htable_strvp.Plo \ - ./$(DEPDIR)/libcares_la-ares__htable_szvp.Plo \ - ./$(DEPDIR)/libcares_la-ares__htable_vpvp.Plo \ - ./$(DEPDIR)/libcares_la-ares__iface_ips.Plo \ - ./$(DEPDIR)/libcares_la-ares__llist.Plo \ ./$(DEPDIR)/libcares_la-ares__parse_into_addrinfo.Plo \ - ./$(DEPDIR)/libcares_la-ares__slist.Plo \ ./$(DEPDIR)/libcares_la-ares__socket.Plo \ ./$(DEPDIR)/libcares_la-ares__sortaddrinfo.Plo \ - ./$(DEPDIR)/libcares_la-ares__threads.Plo \ - ./$(DEPDIR)/libcares_la-ares__timeval.Plo \ ./$(DEPDIR)/libcares_la-ares_android.Plo \ ./$(DEPDIR)/libcares_la-ares_cancel.Plo \ - ./$(DEPDIR)/libcares_la-ares_create_query.Plo \ + ./$(DEPDIR)/libcares_la-ares_cookie.Plo \ ./$(DEPDIR)/libcares_la-ares_data.Plo \ ./$(DEPDIR)/libcares_la-ares_destroy.Plo \ - ./$(DEPDIR)/libcares_la-ares_dns_mapping.Plo \ - ./$(DEPDIR)/libcares_la-ares_dns_multistring.Plo \ - ./$(DEPDIR)/libcares_la-ares_dns_name.Plo \ - ./$(DEPDIR)/libcares_la-ares_dns_parse.Plo \ - ./$(DEPDIR)/libcares_la-ares_dns_record.Plo \ - ./$(DEPDIR)/libcares_la-ares_dns_write.Plo \ - ./$(DEPDIR)/libcares_la-ares_event_configchg.Plo \ - ./$(DEPDIR)/libcares_la-ares_event_epoll.Plo \ - ./$(DEPDIR)/libcares_la-ares_event_kqueue.Plo \ - ./$(DEPDIR)/libcares_la-ares_event_poll.Plo \ - ./$(DEPDIR)/libcares_la-ares_event_select.Plo \ - ./$(DEPDIR)/libcares_la-ares_event_thread.Plo \ - ./$(DEPDIR)/libcares_la-ares_event_wake_pipe.Plo \ - ./$(DEPDIR)/libcares_la-ares_event_win32.Plo \ - ./$(DEPDIR)/libcares_la-ares_expand_name.Plo \ - ./$(DEPDIR)/libcares_la-ares_expand_string.Plo \ - ./$(DEPDIR)/libcares_la-ares_fds.Plo \ ./$(DEPDIR)/libcares_la-ares_free_hostent.Plo \ ./$(DEPDIR)/libcares_la-ares_free_string.Plo \ ./$(DEPDIR)/libcares_la-ares_freeaddrinfo.Plo \ @@ -295,34 +278,17 @@ am__depfiles_remade = \ ./$(DEPDIR)/libcares_la-ares_gethostbyaddr.Plo \ ./$(DEPDIR)/libcares_la-ares_gethostbyname.Plo \ ./$(DEPDIR)/libcares_la-ares_getnameinfo.Plo \ - ./$(DEPDIR)/libcares_la-ares_getsock.Plo \ ./$(DEPDIR)/libcares_la-ares_init.Plo \ ./$(DEPDIR)/libcares_la-ares_library_init.Plo \ - ./$(DEPDIR)/libcares_la-ares_math.Plo \ ./$(DEPDIR)/libcares_la-ares_metrics.Plo \ ./$(DEPDIR)/libcares_la-ares_options.Plo \ - ./$(DEPDIR)/libcares_la-ares_parse_a_reply.Plo \ - ./$(DEPDIR)/libcares_la-ares_parse_aaaa_reply.Plo \ - ./$(DEPDIR)/libcares_la-ares_parse_caa_reply.Plo \ - ./$(DEPDIR)/libcares_la-ares_parse_mx_reply.Plo \ - ./$(DEPDIR)/libcares_la-ares_parse_naptr_reply.Plo \ - ./$(DEPDIR)/libcares_la-ares_parse_ns_reply.Plo \ - ./$(DEPDIR)/libcares_la-ares_parse_ptr_reply.Plo \ - ./$(DEPDIR)/libcares_la-ares_parse_soa_reply.Plo \ - ./$(DEPDIR)/libcares_la-ares_parse_srv_reply.Plo \ - ./$(DEPDIR)/libcares_la-ares_parse_txt_reply.Plo \ - ./$(DEPDIR)/libcares_la-ares_parse_uri_reply.Plo \ ./$(DEPDIR)/libcares_la-ares_platform.Plo \ ./$(DEPDIR)/libcares_la-ares_process.Plo \ ./$(DEPDIR)/libcares_la-ares_qcache.Plo \ ./$(DEPDIR)/libcares_la-ares_query.Plo \ - ./$(DEPDIR)/libcares_la-ares_rand.Plo \ ./$(DEPDIR)/libcares_la-ares_search.Plo \ ./$(DEPDIR)/libcares_la-ares_send.Plo \ - ./$(DEPDIR)/libcares_la-ares_str.Plo \ - ./$(DEPDIR)/libcares_la-ares_strcasecmp.Plo \ ./$(DEPDIR)/libcares_la-ares_strerror.Plo \ - ./$(DEPDIR)/libcares_la-ares_strsplit.Plo \ ./$(DEPDIR)/libcares_la-ares_sysconfig.Plo \ ./$(DEPDIR)/libcares_la-ares_sysconfig_files.Plo \ ./$(DEPDIR)/libcares_la-ares_sysconfig_mac.Plo \ @@ -332,7 +298,54 @@ am__depfiles_remade = \ ./$(DEPDIR)/libcares_la-ares_version.Plo \ ./$(DEPDIR)/libcares_la-inet_net_pton.Plo \ ./$(DEPDIR)/libcares_la-inet_ntop.Plo \ - ./$(DEPDIR)/libcares_la-windows_port.Plo + ./$(DEPDIR)/libcares_la-windows_port.Plo \ + dsa/$(DEPDIR)/libcares_la-ares__array.Plo \ + dsa/$(DEPDIR)/libcares_la-ares__htable.Plo \ + dsa/$(DEPDIR)/libcares_la-ares__htable_asvp.Plo \ + dsa/$(DEPDIR)/libcares_la-ares__htable_strvp.Plo \ + dsa/$(DEPDIR)/libcares_la-ares__htable_szvp.Plo \ + dsa/$(DEPDIR)/libcares_la-ares__htable_vpvp.Plo \ + dsa/$(DEPDIR)/libcares_la-ares__llist.Plo \ + dsa/$(DEPDIR)/libcares_la-ares__slist.Plo \ + event/$(DEPDIR)/libcares_la-ares_event_configchg.Plo \ + event/$(DEPDIR)/libcares_la-ares_event_epoll.Plo \ + event/$(DEPDIR)/libcares_la-ares_event_kqueue.Plo \ + event/$(DEPDIR)/libcares_la-ares_event_poll.Plo \ + event/$(DEPDIR)/libcares_la-ares_event_select.Plo \ + event/$(DEPDIR)/libcares_la-ares_event_thread.Plo \ + event/$(DEPDIR)/libcares_la-ares_event_wake_pipe.Plo \ + event/$(DEPDIR)/libcares_la-ares_event_win32.Plo \ + legacy/$(DEPDIR)/libcares_la-ares_create_query.Plo \ + legacy/$(DEPDIR)/libcares_la-ares_expand_name.Plo \ + legacy/$(DEPDIR)/libcares_la-ares_expand_string.Plo \ + legacy/$(DEPDIR)/libcares_la-ares_fds.Plo \ + legacy/$(DEPDIR)/libcares_la-ares_getsock.Plo \ + legacy/$(DEPDIR)/libcares_la-ares_parse_a_reply.Plo \ + legacy/$(DEPDIR)/libcares_la-ares_parse_aaaa_reply.Plo \ + legacy/$(DEPDIR)/libcares_la-ares_parse_caa_reply.Plo \ + legacy/$(DEPDIR)/libcares_la-ares_parse_mx_reply.Plo \ + legacy/$(DEPDIR)/libcares_la-ares_parse_naptr_reply.Plo \ + legacy/$(DEPDIR)/libcares_la-ares_parse_ns_reply.Plo \ + legacy/$(DEPDIR)/libcares_la-ares_parse_ptr_reply.Plo \ + legacy/$(DEPDIR)/libcares_la-ares_parse_soa_reply.Plo \ + legacy/$(DEPDIR)/libcares_la-ares_parse_srv_reply.Plo \ + legacy/$(DEPDIR)/libcares_la-ares_parse_txt_reply.Plo \ + legacy/$(DEPDIR)/libcares_la-ares_parse_uri_reply.Plo \ + record/$(DEPDIR)/libcares_la-ares_dns_mapping.Plo \ + record/$(DEPDIR)/libcares_la-ares_dns_multistring.Plo \ + record/$(DEPDIR)/libcares_la-ares_dns_name.Plo \ + record/$(DEPDIR)/libcares_la-ares_dns_parse.Plo \ + record/$(DEPDIR)/libcares_la-ares_dns_record.Plo \ + record/$(DEPDIR)/libcares_la-ares_dns_write.Plo \ + str/$(DEPDIR)/libcares_la-ares__buf.Plo \ + str/$(DEPDIR)/libcares_la-ares_str.Plo \ + str/$(DEPDIR)/libcares_la-ares_strcasecmp.Plo \ + str/$(DEPDIR)/libcares_la-ares_strsplit.Plo \ + util/$(DEPDIR)/libcares_la-ares__iface_ips.Plo \ + util/$(DEPDIR)/libcares_la-ares__threads.Plo \ + util/$(DEPDIR)/libcares_la-ares__timeval.Plo \ + util/$(DEPDIR)/libcares_la-ares_math.Plo \ + util/$(DEPDIR)/libcares_la-ares_rand.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) @@ -477,6 +490,8 @@ FGREP = @FGREP@ FILECMD = @FILECMD@ GCOV = @GCOV@ GENHTML = @GENHTML@ +GMOCK112_CFLAGS = @GMOCK112_CFLAGS@ +GMOCK112_LIBS = @GMOCK112_LIBS@ GMOCK_CFLAGS = @GMOCK_CFLAGS@ GMOCK_LIBS = @GMOCK_LIBS@ GREP = @GREP@ @@ -539,8 +554,10 @@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ +am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ +am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ @@ -628,43 +645,16 @@ libcares_la_CFLAGS = $(AM_CFLAGS) $(libcares_la_CFLAGS_EXTRA) libcares_la_CPPFLAGS = $(AM_CPPFLAGS) $(libcares_la_CPPFLAGS_EXTRA) CSOURCES = ares__addrinfo2hostent.c \ ares__addrinfo_localhost.c \ - ares__buf.c \ ares__close_sockets.c \ ares__hosts_file.c \ - ares__htable.c \ - ares__htable_asvp.c \ - ares__htable_strvp.c \ - ares__htable_szvp.c \ - ares__htable_vpvp.c \ - ares__iface_ips.c \ - ares__llist.c \ ares__parse_into_addrinfo.c \ - ares__slist.c \ ares__socket.c \ ares__sortaddrinfo.c \ - ares__threads.c \ - ares__timeval.c \ ares_android.c \ ares_cancel.c \ + ares_cookie.c \ ares_data.c \ ares_destroy.c \ - ares_dns_mapping.c \ - ares_dns_multistring.c \ - ares_dns_name.c \ - ares_dns_parse.c \ - ares_dns_record.c \ - ares_dns_write.c \ - ares_event_configchg.c \ - ares_event_epoll.c \ - ares_event_kqueue.c \ - ares_event_poll.c \ - ares_event_select.c \ - ares_event_thread.c \ - ares_event_wake_pipe.c \ - ares_event_win32.c \ - ares_expand_name.c \ - ares_expand_string.c \ - ares_fds.c \ ares_free_hostent.c \ ares_free_string.c \ ares_freeaddrinfo.c \ @@ -673,35 +663,17 @@ CSOURCES = ares__addrinfo2hostent.c \ ares_gethostbyaddr.c \ ares_gethostbyname.c \ ares_getnameinfo.c \ - ares_getsock.c \ ares_init.c \ ares_library_init.c \ - ares_math.c \ ares_metrics.c \ - ares_create_query.c \ ares_options.c \ - ares_parse_a_reply.c \ - ares_parse_aaaa_reply.c \ - ares_parse_caa_reply.c \ - ares_parse_mx_reply.c \ - ares_parse_naptr_reply.c \ - ares_parse_ns_reply.c \ - ares_parse_ptr_reply.c \ - ares_parse_soa_reply.c \ - ares_parse_srv_reply.c \ - ares_parse_txt_reply.c \ - ares_parse_uri_reply.c \ ares_platform.c \ ares_process.c \ ares_qcache.c \ ares_query.c \ - ares_rand.c \ ares_search.c \ ares_send.c \ - ares_strcasecmp.c \ - ares_str.c \ ares_strerror.c \ - ares_strsplit.c \ ares_sysconfig.c \ ares_sysconfig_files.c \ ares_sysconfig_mac.c \ @@ -711,33 +683,81 @@ CSOURCES = ares__addrinfo2hostent.c \ ares_version.c \ inet_net_pton.c \ inet_ntop.c \ - windows_port.c - -HHEADERS = ares__buf.h \ - ares__htable.h \ - ares__htable_asvp.h \ - ares__htable_strvp.h \ - ares__htable_szvp.h \ - ares__htable_vpvp.h \ - ares__iface_ips.h \ - ares__llist.h \ - ares__slist.h \ - ares__threads.h \ - ares_android.h \ + windows_port.c \ + dsa/ares__array.c \ + dsa/ares__htable.c \ + dsa/ares__htable_asvp.c \ + dsa/ares__htable_strvp.c \ + dsa/ares__htable_szvp.c \ + dsa/ares__htable_vpvp.c \ + dsa/ares__llist.c \ + dsa/ares__slist.c \ + event/ares_event_configchg.c \ + event/ares_event_epoll.c \ + event/ares_event_kqueue.c \ + event/ares_event_poll.c \ + event/ares_event_select.c \ + event/ares_event_thread.c \ + event/ares_event_wake_pipe.c \ + event/ares_event_win32.c \ + legacy/ares_create_query.c \ + legacy/ares_expand_name.c \ + legacy/ares_expand_string.c \ + legacy/ares_fds.c \ + legacy/ares_getsock.c \ + legacy/ares_parse_a_reply.c \ + legacy/ares_parse_aaaa_reply.c \ + legacy/ares_parse_caa_reply.c \ + legacy/ares_parse_mx_reply.c \ + legacy/ares_parse_naptr_reply.c \ + legacy/ares_parse_ns_reply.c \ + legacy/ares_parse_ptr_reply.c \ + legacy/ares_parse_soa_reply.c \ + legacy/ares_parse_srv_reply.c \ + legacy/ares_parse_txt_reply.c \ + legacy/ares_parse_uri_reply.c \ + record/ares_dns_mapping.c \ + record/ares_dns_multistring.c \ + record/ares_dns_name.c \ + record/ares_dns_parse.c \ + record/ares_dns_record.c \ + record/ares_dns_write.c \ + str/ares__buf.c \ + str/ares_strcasecmp.c \ + str/ares_str.c \ + str/ares_strsplit.c \ + util/ares__iface_ips.c \ + util/ares__threads.c \ + util/ares__timeval.c \ + util/ares_math.c \ + util/ares_rand.c + +HHEADERS = ares_android.h \ ares_data.h \ - ares_dns_multistring.h \ - ares_dns_private.h \ - ares_event.h \ - ares_event_win32.h \ ares_getenv.h \ ares_inet_net_pton.h \ ares_ipv6.h \ ares_platform.h \ ares_private.h \ - ares_strcasecmp.h \ - ares_str.h \ - ares_strsplit.h \ ares_setup.h \ + dsa/ares__array.h \ + dsa/ares__htable.h \ + dsa/ares__htable_asvp.h \ + dsa/ares__htable_strvp.h \ + dsa/ares__htable_szvp.h \ + dsa/ares__htable_vpvp.h \ + dsa/ares__llist.h \ + dsa/ares__slist.h \ + event/ares_event.h \ + event/ares_event_win32.h \ + record/ares_dns_multistring.h \ + record/ares_dns_private.h \ + str/ares__buf.h \ + str/ares_strcasecmp.h \ + str/ares_str.h \ + str/ares_strsplit.h \ + util/ares__iface_ips.h \ + util/ares__threads.h \ thirdparty/apple/dnsinfo.h @@ -784,12 +804,12 @@ ares_config.h: stamp-h1 @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1 stamp-h1: $(srcdir)/ares_config.h.in $(top_builddir)/config.status - @rm -f stamp-h1 - cd $(top_builddir) && $(SHELL) ./config.status src/lib/ares_config.h + $(AM_V_at)rm -f stamp-h1 + $(AM_V_GEN)cd $(top_builddir) && $(SHELL) ./config.status src/lib/ares_config.h $(srcdir)/ares_config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) - ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) - rm -f stamp-h1 - touch $@ + $(AM_V_GEN)($(am__cd) $(top_srcdir) && $(AUTOHEADER)) + $(AM_V_at)rm -f stamp-h1 + $(AM_V_at)touch $@ distclean-hdr: -rm -f ares_config.h stamp-h1 @@ -819,65 +839,177 @@ uninstall-libLTLIBRARIES: done clean-libLTLIBRARIES: - -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + -$(am__rm_f) $(lib_LTLIBRARIES) @list='$(lib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ - test -z "$$locs" || { \ - echo rm -f $${locs}; \ - rm -f $${locs}; \ - } + echo rm -f $${locs}; \ + $(am__rm_f) $${locs} +dsa/$(am__dirstamp): + @$(MKDIR_P) dsa + @: >>dsa/$(am__dirstamp) +dsa/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) dsa/$(DEPDIR) + @: >>dsa/$(DEPDIR)/$(am__dirstamp) +dsa/libcares_la-ares__array.lo: dsa/$(am__dirstamp) \ + dsa/$(DEPDIR)/$(am__dirstamp) +dsa/libcares_la-ares__htable.lo: dsa/$(am__dirstamp) \ + dsa/$(DEPDIR)/$(am__dirstamp) +dsa/libcares_la-ares__htable_asvp.lo: dsa/$(am__dirstamp) \ + dsa/$(DEPDIR)/$(am__dirstamp) +dsa/libcares_la-ares__htable_strvp.lo: dsa/$(am__dirstamp) \ + dsa/$(DEPDIR)/$(am__dirstamp) +dsa/libcares_la-ares__htable_szvp.lo: dsa/$(am__dirstamp) \ + dsa/$(DEPDIR)/$(am__dirstamp) +dsa/libcares_la-ares__htable_vpvp.lo: dsa/$(am__dirstamp) \ + dsa/$(DEPDIR)/$(am__dirstamp) +dsa/libcares_la-ares__llist.lo: dsa/$(am__dirstamp) \ + dsa/$(DEPDIR)/$(am__dirstamp) +dsa/libcares_la-ares__slist.lo: dsa/$(am__dirstamp) \ + dsa/$(DEPDIR)/$(am__dirstamp) +event/$(am__dirstamp): + @$(MKDIR_P) event + @: >>event/$(am__dirstamp) +event/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) event/$(DEPDIR) + @: >>event/$(DEPDIR)/$(am__dirstamp) +event/libcares_la-ares_event_configchg.lo: event/$(am__dirstamp) \ + event/$(DEPDIR)/$(am__dirstamp) +event/libcares_la-ares_event_epoll.lo: event/$(am__dirstamp) \ + event/$(DEPDIR)/$(am__dirstamp) +event/libcares_la-ares_event_kqueue.lo: event/$(am__dirstamp) \ + event/$(DEPDIR)/$(am__dirstamp) +event/libcares_la-ares_event_poll.lo: event/$(am__dirstamp) \ + event/$(DEPDIR)/$(am__dirstamp) +event/libcares_la-ares_event_select.lo: event/$(am__dirstamp) \ + event/$(DEPDIR)/$(am__dirstamp) +event/libcares_la-ares_event_thread.lo: event/$(am__dirstamp) \ + event/$(DEPDIR)/$(am__dirstamp) +event/libcares_la-ares_event_wake_pipe.lo: event/$(am__dirstamp) \ + event/$(DEPDIR)/$(am__dirstamp) +event/libcares_la-ares_event_win32.lo: event/$(am__dirstamp) \ + event/$(DEPDIR)/$(am__dirstamp) +legacy/$(am__dirstamp): + @$(MKDIR_P) legacy + @: >>legacy/$(am__dirstamp) +legacy/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) legacy/$(DEPDIR) + @: >>legacy/$(DEPDIR)/$(am__dirstamp) +legacy/libcares_la-ares_create_query.lo: legacy/$(am__dirstamp) \ + legacy/$(DEPDIR)/$(am__dirstamp) +legacy/libcares_la-ares_expand_name.lo: legacy/$(am__dirstamp) \ + legacy/$(DEPDIR)/$(am__dirstamp) +legacy/libcares_la-ares_expand_string.lo: legacy/$(am__dirstamp) \ + legacy/$(DEPDIR)/$(am__dirstamp) +legacy/libcares_la-ares_fds.lo: legacy/$(am__dirstamp) \ + legacy/$(DEPDIR)/$(am__dirstamp) +legacy/libcares_la-ares_getsock.lo: legacy/$(am__dirstamp) \ + legacy/$(DEPDIR)/$(am__dirstamp) +legacy/libcares_la-ares_parse_a_reply.lo: legacy/$(am__dirstamp) \ + legacy/$(DEPDIR)/$(am__dirstamp) +legacy/libcares_la-ares_parse_aaaa_reply.lo: legacy/$(am__dirstamp) \ + legacy/$(DEPDIR)/$(am__dirstamp) +legacy/libcares_la-ares_parse_caa_reply.lo: legacy/$(am__dirstamp) \ + legacy/$(DEPDIR)/$(am__dirstamp) +legacy/libcares_la-ares_parse_mx_reply.lo: legacy/$(am__dirstamp) \ + legacy/$(DEPDIR)/$(am__dirstamp) +legacy/libcares_la-ares_parse_naptr_reply.lo: legacy/$(am__dirstamp) \ + legacy/$(DEPDIR)/$(am__dirstamp) +legacy/libcares_la-ares_parse_ns_reply.lo: legacy/$(am__dirstamp) \ + legacy/$(DEPDIR)/$(am__dirstamp) +legacy/libcares_la-ares_parse_ptr_reply.lo: legacy/$(am__dirstamp) \ + legacy/$(DEPDIR)/$(am__dirstamp) +legacy/libcares_la-ares_parse_soa_reply.lo: legacy/$(am__dirstamp) \ + legacy/$(DEPDIR)/$(am__dirstamp) +legacy/libcares_la-ares_parse_srv_reply.lo: legacy/$(am__dirstamp) \ + legacy/$(DEPDIR)/$(am__dirstamp) +legacy/libcares_la-ares_parse_txt_reply.lo: legacy/$(am__dirstamp) \ + legacy/$(DEPDIR)/$(am__dirstamp) +legacy/libcares_la-ares_parse_uri_reply.lo: legacy/$(am__dirstamp) \ + legacy/$(DEPDIR)/$(am__dirstamp) +record/$(am__dirstamp): + @$(MKDIR_P) record + @: >>record/$(am__dirstamp) +record/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) record/$(DEPDIR) + @: >>record/$(DEPDIR)/$(am__dirstamp) +record/libcares_la-ares_dns_mapping.lo: record/$(am__dirstamp) \ + record/$(DEPDIR)/$(am__dirstamp) +record/libcares_la-ares_dns_multistring.lo: record/$(am__dirstamp) \ + record/$(DEPDIR)/$(am__dirstamp) +record/libcares_la-ares_dns_name.lo: record/$(am__dirstamp) \ + record/$(DEPDIR)/$(am__dirstamp) +record/libcares_la-ares_dns_parse.lo: record/$(am__dirstamp) \ + record/$(DEPDIR)/$(am__dirstamp) +record/libcares_la-ares_dns_record.lo: record/$(am__dirstamp) \ + record/$(DEPDIR)/$(am__dirstamp) +record/libcares_la-ares_dns_write.lo: record/$(am__dirstamp) \ + record/$(DEPDIR)/$(am__dirstamp) +str/$(am__dirstamp): + @$(MKDIR_P) str + @: >>str/$(am__dirstamp) +str/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) str/$(DEPDIR) + @: >>str/$(DEPDIR)/$(am__dirstamp) +str/libcares_la-ares__buf.lo: str/$(am__dirstamp) \ + str/$(DEPDIR)/$(am__dirstamp) +str/libcares_la-ares_strcasecmp.lo: str/$(am__dirstamp) \ + str/$(DEPDIR)/$(am__dirstamp) +str/libcares_la-ares_str.lo: str/$(am__dirstamp) \ + str/$(DEPDIR)/$(am__dirstamp) +str/libcares_la-ares_strsplit.lo: str/$(am__dirstamp) \ + str/$(DEPDIR)/$(am__dirstamp) +util/$(am__dirstamp): + @$(MKDIR_P) util + @: >>util/$(am__dirstamp) +util/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) util/$(DEPDIR) + @: >>util/$(DEPDIR)/$(am__dirstamp) +util/libcares_la-ares__iface_ips.lo: util/$(am__dirstamp) \ + util/$(DEPDIR)/$(am__dirstamp) +util/libcares_la-ares__threads.lo: util/$(am__dirstamp) \ + util/$(DEPDIR)/$(am__dirstamp) +util/libcares_la-ares__timeval.lo: util/$(am__dirstamp) \ + util/$(DEPDIR)/$(am__dirstamp) +util/libcares_la-ares_math.lo: util/$(am__dirstamp) \ + util/$(DEPDIR)/$(am__dirstamp) +util/libcares_la-ares_rand.lo: util/$(am__dirstamp) \ + util/$(DEPDIR)/$(am__dirstamp) libcares.la: $(libcares_la_OBJECTS) $(libcares_la_DEPENDENCIES) $(EXTRA_libcares_la_DEPENDENCIES) $(AM_V_CCLD)$(libcares_la_LINK) -rpath $(libdir) $(libcares_la_OBJECTS) $(libcares_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) + -rm -f dsa/*.$(OBJEXT) + -rm -f dsa/*.lo + -rm -f event/*.$(OBJEXT) + -rm -f event/*.lo + -rm -f legacy/*.$(OBJEXT) + -rm -f legacy/*.lo + -rm -f record/*.$(OBJEXT) + -rm -f record/*.lo + -rm -f str/*.$(OBJEXT) + -rm -f str/*.lo + -rm -f util/*.$(OBJEXT) + -rm -f util/*.lo distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares__addrinfo2hostent.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares__addrinfo_localhost.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares__buf.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares__close_sockets.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares__hosts_file.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares__htable.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares__htable_asvp.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares__htable_strvp.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares__htable_szvp.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares__htable_vpvp.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares__iface_ips.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares__llist.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares__parse_into_addrinfo.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares__slist.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares__socket.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares__sortaddrinfo.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares__threads.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares__timeval.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_android.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_cancel.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_create_query.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_cookie.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_data.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_destroy.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_dns_mapping.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_dns_multistring.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_dns_name.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_dns_parse.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_dns_record.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_dns_write.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_event_configchg.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_event_epoll.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_event_kqueue.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_event_poll.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_event_select.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_event_thread.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_event_wake_pipe.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_event_win32.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_expand_name.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_expand_string.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_fds.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_free_hostent.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_free_string.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_freeaddrinfo.Plo@am__quote@ # am--include-marker @@ -886,34 +1018,17 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_gethostbyaddr.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_gethostbyname.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_getnameinfo.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_getsock.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_init.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_library_init.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_math.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_metrics.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_options.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_parse_a_reply.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_parse_aaaa_reply.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_parse_caa_reply.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_parse_mx_reply.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_parse_naptr_reply.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_parse_ns_reply.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_parse_ptr_reply.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_parse_soa_reply.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_parse_srv_reply.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_parse_txt_reply.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_parse_uri_reply.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_platform.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_process.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_qcache.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_query.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_rand.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_search.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_send.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_str.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_strcasecmp.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_strerror.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_strsplit.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_sysconfig.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_sysconfig_files.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_sysconfig_mac.Plo@am__quote@ # am--include-marker @@ -924,10 +1039,57 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-inet_net_pton.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-inet_ntop.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-windows_port.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@dsa/$(DEPDIR)/libcares_la-ares__array.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@dsa/$(DEPDIR)/libcares_la-ares__htable.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@dsa/$(DEPDIR)/libcares_la-ares__htable_asvp.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@dsa/$(DEPDIR)/libcares_la-ares__htable_strvp.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@dsa/$(DEPDIR)/libcares_la-ares__htable_szvp.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@dsa/$(DEPDIR)/libcares_la-ares__htable_vpvp.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@dsa/$(DEPDIR)/libcares_la-ares__llist.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@dsa/$(DEPDIR)/libcares_la-ares__slist.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@event/$(DEPDIR)/libcares_la-ares_event_configchg.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@event/$(DEPDIR)/libcares_la-ares_event_epoll.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@event/$(DEPDIR)/libcares_la-ares_event_kqueue.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@event/$(DEPDIR)/libcares_la-ares_event_poll.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@event/$(DEPDIR)/libcares_la-ares_event_select.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@event/$(DEPDIR)/libcares_la-ares_event_thread.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@event/$(DEPDIR)/libcares_la-ares_event_wake_pipe.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@event/$(DEPDIR)/libcares_la-ares_event_win32.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@legacy/$(DEPDIR)/libcares_la-ares_create_query.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@legacy/$(DEPDIR)/libcares_la-ares_expand_name.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@legacy/$(DEPDIR)/libcares_la-ares_expand_string.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@legacy/$(DEPDIR)/libcares_la-ares_fds.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@legacy/$(DEPDIR)/libcares_la-ares_getsock.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@legacy/$(DEPDIR)/libcares_la-ares_parse_a_reply.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@legacy/$(DEPDIR)/libcares_la-ares_parse_aaaa_reply.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@legacy/$(DEPDIR)/libcares_la-ares_parse_caa_reply.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@legacy/$(DEPDIR)/libcares_la-ares_parse_mx_reply.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@legacy/$(DEPDIR)/libcares_la-ares_parse_naptr_reply.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@legacy/$(DEPDIR)/libcares_la-ares_parse_ns_reply.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@legacy/$(DEPDIR)/libcares_la-ares_parse_ptr_reply.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@legacy/$(DEPDIR)/libcares_la-ares_parse_soa_reply.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@legacy/$(DEPDIR)/libcares_la-ares_parse_srv_reply.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@legacy/$(DEPDIR)/libcares_la-ares_parse_txt_reply.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@legacy/$(DEPDIR)/libcares_la-ares_parse_uri_reply.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@record/$(DEPDIR)/libcares_la-ares_dns_mapping.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@record/$(DEPDIR)/libcares_la-ares_dns_multistring.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@record/$(DEPDIR)/libcares_la-ares_dns_name.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@record/$(DEPDIR)/libcares_la-ares_dns_parse.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@record/$(DEPDIR)/libcares_la-ares_dns_record.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@record/$(DEPDIR)/libcares_la-ares_dns_write.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@str/$(DEPDIR)/libcares_la-ares__buf.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@str/$(DEPDIR)/libcares_la-ares_str.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@str/$(DEPDIR)/libcares_la-ares_strcasecmp.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@str/$(DEPDIR)/libcares_la-ares_strsplit.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@util/$(DEPDIR)/libcares_la-ares__iface_ips.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@util/$(DEPDIR)/libcares_la-ares__threads.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@util/$(DEPDIR)/libcares_la-ares__timeval.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@util/$(DEPDIR)/libcares_la-ares_math.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@util/$(DEPDIR)/libcares_la-ares_rand.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) - @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + @: >>$@ am--depfiles: $(am__depfiles_remade) @@ -969,13 +1131,6 @@ libcares_la-ares__addrinfo_localhost.lo: ares__addrinfo_localhost.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares__addrinfo_localhost.lo `test -f 'ares__addrinfo_localhost.c' || echo '$(srcdir)/'`ares__addrinfo_localhost.c -libcares_la-ares__buf.lo: ares__buf.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares__buf.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares__buf.Tpo -c -o libcares_la-ares__buf.lo `test -f 'ares__buf.c' || echo '$(srcdir)/'`ares__buf.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares__buf.Tpo $(DEPDIR)/libcares_la-ares__buf.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares__buf.c' object='libcares_la-ares__buf.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares__buf.lo `test -f 'ares__buf.c' || echo '$(srcdir)/'`ares__buf.c - libcares_la-ares__close_sockets.lo: ares__close_sockets.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares__close_sockets.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares__close_sockets.Tpo -c -o libcares_la-ares__close_sockets.lo `test -f 'ares__close_sockets.c' || echo '$(srcdir)/'`ares__close_sockets.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares__close_sockets.Tpo $(DEPDIR)/libcares_la-ares__close_sockets.Plo @@ -990,55 +1145,6 @@ libcares_la-ares__hosts_file.lo: ares__hosts_file.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares__hosts_file.lo `test -f 'ares__hosts_file.c' || echo '$(srcdir)/'`ares__hosts_file.c -libcares_la-ares__htable.lo: ares__htable.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares__htable.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares__htable.Tpo -c -o libcares_la-ares__htable.lo `test -f 'ares__htable.c' || echo '$(srcdir)/'`ares__htable.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares__htable.Tpo $(DEPDIR)/libcares_la-ares__htable.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares__htable.c' object='libcares_la-ares__htable.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares__htable.lo `test -f 'ares__htable.c' || echo '$(srcdir)/'`ares__htable.c - -libcares_la-ares__htable_asvp.lo: ares__htable_asvp.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares__htable_asvp.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares__htable_asvp.Tpo -c -o libcares_la-ares__htable_asvp.lo `test -f 'ares__htable_asvp.c' || echo '$(srcdir)/'`ares__htable_asvp.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares__htable_asvp.Tpo $(DEPDIR)/libcares_la-ares__htable_asvp.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares__htable_asvp.c' object='libcares_la-ares__htable_asvp.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares__htable_asvp.lo `test -f 'ares__htable_asvp.c' || echo '$(srcdir)/'`ares__htable_asvp.c - -libcares_la-ares__htable_strvp.lo: ares__htable_strvp.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares__htable_strvp.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares__htable_strvp.Tpo -c -o libcares_la-ares__htable_strvp.lo `test -f 'ares__htable_strvp.c' || echo '$(srcdir)/'`ares__htable_strvp.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares__htable_strvp.Tpo $(DEPDIR)/libcares_la-ares__htable_strvp.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares__htable_strvp.c' object='libcares_la-ares__htable_strvp.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares__htable_strvp.lo `test -f 'ares__htable_strvp.c' || echo '$(srcdir)/'`ares__htable_strvp.c - -libcares_la-ares__htable_szvp.lo: ares__htable_szvp.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares__htable_szvp.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares__htable_szvp.Tpo -c -o libcares_la-ares__htable_szvp.lo `test -f 'ares__htable_szvp.c' || echo '$(srcdir)/'`ares__htable_szvp.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares__htable_szvp.Tpo $(DEPDIR)/libcares_la-ares__htable_szvp.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares__htable_szvp.c' object='libcares_la-ares__htable_szvp.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares__htable_szvp.lo `test -f 'ares__htable_szvp.c' || echo '$(srcdir)/'`ares__htable_szvp.c - -libcares_la-ares__htable_vpvp.lo: ares__htable_vpvp.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares__htable_vpvp.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares__htable_vpvp.Tpo -c -o libcares_la-ares__htable_vpvp.lo `test -f 'ares__htable_vpvp.c' || echo '$(srcdir)/'`ares__htable_vpvp.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares__htable_vpvp.Tpo $(DEPDIR)/libcares_la-ares__htable_vpvp.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares__htable_vpvp.c' object='libcares_la-ares__htable_vpvp.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares__htable_vpvp.lo `test -f 'ares__htable_vpvp.c' || echo '$(srcdir)/'`ares__htable_vpvp.c - -libcares_la-ares__iface_ips.lo: ares__iface_ips.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares__iface_ips.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares__iface_ips.Tpo -c -o libcares_la-ares__iface_ips.lo `test -f 'ares__iface_ips.c' || echo '$(srcdir)/'`ares__iface_ips.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares__iface_ips.Tpo $(DEPDIR)/libcares_la-ares__iface_ips.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares__iface_ips.c' object='libcares_la-ares__iface_ips.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares__iface_ips.lo `test -f 'ares__iface_ips.c' || echo '$(srcdir)/'`ares__iface_ips.c - -libcares_la-ares__llist.lo: ares__llist.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares__llist.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares__llist.Tpo -c -o libcares_la-ares__llist.lo `test -f 'ares__llist.c' || echo '$(srcdir)/'`ares__llist.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares__llist.Tpo $(DEPDIR)/libcares_la-ares__llist.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares__llist.c' object='libcares_la-ares__llist.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares__llist.lo `test -f 'ares__llist.c' || echo '$(srcdir)/'`ares__llist.c - libcares_la-ares__parse_into_addrinfo.lo: ares__parse_into_addrinfo.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares__parse_into_addrinfo.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares__parse_into_addrinfo.Tpo -c -o libcares_la-ares__parse_into_addrinfo.lo `test -f 'ares__parse_into_addrinfo.c' || echo '$(srcdir)/'`ares__parse_into_addrinfo.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares__parse_into_addrinfo.Tpo $(DEPDIR)/libcares_la-ares__parse_into_addrinfo.Plo @@ -1046,13 +1152,6 @@ libcares_la-ares__parse_into_addrinfo.lo: ares__parse_into_addrinfo.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares__parse_into_addrinfo.lo `test -f 'ares__parse_into_addrinfo.c' || echo '$(srcdir)/'`ares__parse_into_addrinfo.c -libcares_la-ares__slist.lo: ares__slist.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares__slist.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares__slist.Tpo -c -o libcares_la-ares__slist.lo `test -f 'ares__slist.c' || echo '$(srcdir)/'`ares__slist.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares__slist.Tpo $(DEPDIR)/libcares_la-ares__slist.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares__slist.c' object='libcares_la-ares__slist.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares__slist.lo `test -f 'ares__slist.c' || echo '$(srcdir)/'`ares__slist.c - libcares_la-ares__socket.lo: ares__socket.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares__socket.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares__socket.Tpo -c -o libcares_la-ares__socket.lo `test -f 'ares__socket.c' || echo '$(srcdir)/'`ares__socket.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares__socket.Tpo $(DEPDIR)/libcares_la-ares__socket.Plo @@ -1067,20 +1166,6 @@ libcares_la-ares__sortaddrinfo.lo: ares__sortaddrinfo.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares__sortaddrinfo.lo `test -f 'ares__sortaddrinfo.c' || echo '$(srcdir)/'`ares__sortaddrinfo.c -libcares_la-ares__threads.lo: ares__threads.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares__threads.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares__threads.Tpo -c -o libcares_la-ares__threads.lo `test -f 'ares__threads.c' || echo '$(srcdir)/'`ares__threads.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares__threads.Tpo $(DEPDIR)/libcares_la-ares__threads.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares__threads.c' object='libcares_la-ares__threads.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares__threads.lo `test -f 'ares__threads.c' || echo '$(srcdir)/'`ares__threads.c - -libcares_la-ares__timeval.lo: ares__timeval.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares__timeval.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares__timeval.Tpo -c -o libcares_la-ares__timeval.lo `test -f 'ares__timeval.c' || echo '$(srcdir)/'`ares__timeval.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares__timeval.Tpo $(DEPDIR)/libcares_la-ares__timeval.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares__timeval.c' object='libcares_la-ares__timeval.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares__timeval.lo `test -f 'ares__timeval.c' || echo '$(srcdir)/'`ares__timeval.c - libcares_la-ares_android.lo: ares_android.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_android.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_android.Tpo -c -o libcares_la-ares_android.lo `test -f 'ares_android.c' || echo '$(srcdir)/'`ares_android.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_android.Tpo $(DEPDIR)/libcares_la-ares_android.Plo @@ -1095,6 +1180,13 @@ libcares_la-ares_cancel.lo: ares_cancel.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_cancel.lo `test -f 'ares_cancel.c' || echo '$(srcdir)/'`ares_cancel.c +libcares_la-ares_cookie.lo: ares_cookie.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_cookie.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_cookie.Tpo -c -o libcares_la-ares_cookie.lo `test -f 'ares_cookie.c' || echo '$(srcdir)/'`ares_cookie.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_cookie.Tpo $(DEPDIR)/libcares_la-ares_cookie.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_cookie.c' object='libcares_la-ares_cookie.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_cookie.lo `test -f 'ares_cookie.c' || echo '$(srcdir)/'`ares_cookie.c + libcares_la-ares_data.lo: ares_data.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_data.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_data.Tpo -c -o libcares_la-ares_data.lo `test -f 'ares_data.c' || echo '$(srcdir)/'`ares_data.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_data.Tpo $(DEPDIR)/libcares_la-ares_data.Plo @@ -1109,125 +1201,6 @@ libcares_la-ares_destroy.lo: ares_destroy.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_destroy.lo `test -f 'ares_destroy.c' || echo '$(srcdir)/'`ares_destroy.c -libcares_la-ares_dns_mapping.lo: ares_dns_mapping.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_dns_mapping.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_dns_mapping.Tpo -c -o libcares_la-ares_dns_mapping.lo `test -f 'ares_dns_mapping.c' || echo '$(srcdir)/'`ares_dns_mapping.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_dns_mapping.Tpo $(DEPDIR)/libcares_la-ares_dns_mapping.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_dns_mapping.c' object='libcares_la-ares_dns_mapping.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_dns_mapping.lo `test -f 'ares_dns_mapping.c' || echo '$(srcdir)/'`ares_dns_mapping.c - -libcares_la-ares_dns_multistring.lo: ares_dns_multistring.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_dns_multistring.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_dns_multistring.Tpo -c -o libcares_la-ares_dns_multistring.lo `test -f 'ares_dns_multistring.c' || echo '$(srcdir)/'`ares_dns_multistring.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_dns_multistring.Tpo $(DEPDIR)/libcares_la-ares_dns_multistring.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_dns_multistring.c' object='libcares_la-ares_dns_multistring.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_dns_multistring.lo `test -f 'ares_dns_multistring.c' || echo '$(srcdir)/'`ares_dns_multistring.c - -libcares_la-ares_dns_name.lo: ares_dns_name.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_dns_name.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_dns_name.Tpo -c -o libcares_la-ares_dns_name.lo `test -f 'ares_dns_name.c' || echo '$(srcdir)/'`ares_dns_name.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_dns_name.Tpo $(DEPDIR)/libcares_la-ares_dns_name.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_dns_name.c' object='libcares_la-ares_dns_name.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_dns_name.lo `test -f 'ares_dns_name.c' || echo '$(srcdir)/'`ares_dns_name.c - -libcares_la-ares_dns_parse.lo: ares_dns_parse.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_dns_parse.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_dns_parse.Tpo -c -o libcares_la-ares_dns_parse.lo `test -f 'ares_dns_parse.c' || echo '$(srcdir)/'`ares_dns_parse.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_dns_parse.Tpo $(DEPDIR)/libcares_la-ares_dns_parse.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_dns_parse.c' object='libcares_la-ares_dns_parse.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_dns_parse.lo `test -f 'ares_dns_parse.c' || echo '$(srcdir)/'`ares_dns_parse.c - -libcares_la-ares_dns_record.lo: ares_dns_record.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_dns_record.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_dns_record.Tpo -c -o libcares_la-ares_dns_record.lo `test -f 'ares_dns_record.c' || echo '$(srcdir)/'`ares_dns_record.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_dns_record.Tpo $(DEPDIR)/libcares_la-ares_dns_record.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_dns_record.c' object='libcares_la-ares_dns_record.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_dns_record.lo `test -f 'ares_dns_record.c' || echo '$(srcdir)/'`ares_dns_record.c - -libcares_la-ares_dns_write.lo: ares_dns_write.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_dns_write.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_dns_write.Tpo -c -o libcares_la-ares_dns_write.lo `test -f 'ares_dns_write.c' || echo '$(srcdir)/'`ares_dns_write.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_dns_write.Tpo $(DEPDIR)/libcares_la-ares_dns_write.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_dns_write.c' object='libcares_la-ares_dns_write.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_dns_write.lo `test -f 'ares_dns_write.c' || echo '$(srcdir)/'`ares_dns_write.c - -libcares_la-ares_event_configchg.lo: ares_event_configchg.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_event_configchg.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_event_configchg.Tpo -c -o libcares_la-ares_event_configchg.lo `test -f 'ares_event_configchg.c' || echo '$(srcdir)/'`ares_event_configchg.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_event_configchg.Tpo $(DEPDIR)/libcares_la-ares_event_configchg.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_event_configchg.c' object='libcares_la-ares_event_configchg.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_event_configchg.lo `test -f 'ares_event_configchg.c' || echo '$(srcdir)/'`ares_event_configchg.c - -libcares_la-ares_event_epoll.lo: ares_event_epoll.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_event_epoll.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_event_epoll.Tpo -c -o libcares_la-ares_event_epoll.lo `test -f 'ares_event_epoll.c' || echo '$(srcdir)/'`ares_event_epoll.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_event_epoll.Tpo $(DEPDIR)/libcares_la-ares_event_epoll.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_event_epoll.c' object='libcares_la-ares_event_epoll.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_event_epoll.lo `test -f 'ares_event_epoll.c' || echo '$(srcdir)/'`ares_event_epoll.c - -libcares_la-ares_event_kqueue.lo: ares_event_kqueue.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_event_kqueue.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_event_kqueue.Tpo -c -o libcares_la-ares_event_kqueue.lo `test -f 'ares_event_kqueue.c' || echo '$(srcdir)/'`ares_event_kqueue.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_event_kqueue.Tpo $(DEPDIR)/libcares_la-ares_event_kqueue.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_event_kqueue.c' object='libcares_la-ares_event_kqueue.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_event_kqueue.lo `test -f 'ares_event_kqueue.c' || echo '$(srcdir)/'`ares_event_kqueue.c - -libcares_la-ares_event_poll.lo: ares_event_poll.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_event_poll.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_event_poll.Tpo -c -o libcares_la-ares_event_poll.lo `test -f 'ares_event_poll.c' || echo '$(srcdir)/'`ares_event_poll.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_event_poll.Tpo $(DEPDIR)/libcares_la-ares_event_poll.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_event_poll.c' object='libcares_la-ares_event_poll.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_event_poll.lo `test -f 'ares_event_poll.c' || echo '$(srcdir)/'`ares_event_poll.c - -libcares_la-ares_event_select.lo: ares_event_select.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_event_select.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_event_select.Tpo -c -o libcares_la-ares_event_select.lo `test -f 'ares_event_select.c' || echo '$(srcdir)/'`ares_event_select.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_event_select.Tpo $(DEPDIR)/libcares_la-ares_event_select.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_event_select.c' object='libcares_la-ares_event_select.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_event_select.lo `test -f 'ares_event_select.c' || echo '$(srcdir)/'`ares_event_select.c - -libcares_la-ares_event_thread.lo: ares_event_thread.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_event_thread.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_event_thread.Tpo -c -o libcares_la-ares_event_thread.lo `test -f 'ares_event_thread.c' || echo '$(srcdir)/'`ares_event_thread.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_event_thread.Tpo $(DEPDIR)/libcares_la-ares_event_thread.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_event_thread.c' object='libcares_la-ares_event_thread.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_event_thread.lo `test -f 'ares_event_thread.c' || echo '$(srcdir)/'`ares_event_thread.c - -libcares_la-ares_event_wake_pipe.lo: ares_event_wake_pipe.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_event_wake_pipe.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_event_wake_pipe.Tpo -c -o libcares_la-ares_event_wake_pipe.lo `test -f 'ares_event_wake_pipe.c' || echo '$(srcdir)/'`ares_event_wake_pipe.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_event_wake_pipe.Tpo $(DEPDIR)/libcares_la-ares_event_wake_pipe.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_event_wake_pipe.c' object='libcares_la-ares_event_wake_pipe.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_event_wake_pipe.lo `test -f 'ares_event_wake_pipe.c' || echo '$(srcdir)/'`ares_event_wake_pipe.c - -libcares_la-ares_event_win32.lo: ares_event_win32.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_event_win32.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_event_win32.Tpo -c -o libcares_la-ares_event_win32.lo `test -f 'ares_event_win32.c' || echo '$(srcdir)/'`ares_event_win32.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_event_win32.Tpo $(DEPDIR)/libcares_la-ares_event_win32.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_event_win32.c' object='libcares_la-ares_event_win32.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_event_win32.lo `test -f 'ares_event_win32.c' || echo '$(srcdir)/'`ares_event_win32.c - -libcares_la-ares_expand_name.lo: ares_expand_name.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_expand_name.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_expand_name.Tpo -c -o libcares_la-ares_expand_name.lo `test -f 'ares_expand_name.c' || echo '$(srcdir)/'`ares_expand_name.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_expand_name.Tpo $(DEPDIR)/libcares_la-ares_expand_name.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_expand_name.c' object='libcares_la-ares_expand_name.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_expand_name.lo `test -f 'ares_expand_name.c' || echo '$(srcdir)/'`ares_expand_name.c - -libcares_la-ares_expand_string.lo: ares_expand_string.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_expand_string.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_expand_string.Tpo -c -o libcares_la-ares_expand_string.lo `test -f 'ares_expand_string.c' || echo '$(srcdir)/'`ares_expand_string.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_expand_string.Tpo $(DEPDIR)/libcares_la-ares_expand_string.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_expand_string.c' object='libcares_la-ares_expand_string.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_expand_string.lo `test -f 'ares_expand_string.c' || echo '$(srcdir)/'`ares_expand_string.c - -libcares_la-ares_fds.lo: ares_fds.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_fds.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_fds.Tpo -c -o libcares_la-ares_fds.lo `test -f 'ares_fds.c' || echo '$(srcdir)/'`ares_fds.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_fds.Tpo $(DEPDIR)/libcares_la-ares_fds.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_fds.c' object='libcares_la-ares_fds.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_fds.lo `test -f 'ares_fds.c' || echo '$(srcdir)/'`ares_fds.c - libcares_la-ares_free_hostent.lo: ares_free_hostent.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_free_hostent.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_free_hostent.Tpo -c -o libcares_la-ares_free_hostent.lo `test -f 'ares_free_hostent.c' || echo '$(srcdir)/'`ares_free_hostent.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_free_hostent.Tpo $(DEPDIR)/libcares_la-ares_free_hostent.Plo @@ -1284,13 +1257,6 @@ libcares_la-ares_getnameinfo.lo: ares_getnameinfo.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_getnameinfo.lo `test -f 'ares_getnameinfo.c' || echo '$(srcdir)/'`ares_getnameinfo.c -libcares_la-ares_getsock.lo: ares_getsock.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_getsock.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_getsock.Tpo -c -o libcares_la-ares_getsock.lo `test -f 'ares_getsock.c' || echo '$(srcdir)/'`ares_getsock.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_getsock.Tpo $(DEPDIR)/libcares_la-ares_getsock.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_getsock.c' object='libcares_la-ares_getsock.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_getsock.lo `test -f 'ares_getsock.c' || echo '$(srcdir)/'`ares_getsock.c - libcares_la-ares_init.lo: ares_init.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_init.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_init.Tpo -c -o libcares_la-ares_init.lo `test -f 'ares_init.c' || echo '$(srcdir)/'`ares_init.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_init.Tpo $(DEPDIR)/libcares_la-ares_init.Plo @@ -1305,13 +1271,6 @@ libcares_la-ares_library_init.lo: ares_library_init.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_library_init.lo `test -f 'ares_library_init.c' || echo '$(srcdir)/'`ares_library_init.c -libcares_la-ares_math.lo: ares_math.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_math.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_math.Tpo -c -o libcares_la-ares_math.lo `test -f 'ares_math.c' || echo '$(srcdir)/'`ares_math.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_math.Tpo $(DEPDIR)/libcares_la-ares_math.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_math.c' object='libcares_la-ares_math.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_math.lo `test -f 'ares_math.c' || echo '$(srcdir)/'`ares_math.c - libcares_la-ares_metrics.lo: ares_metrics.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_metrics.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_metrics.Tpo -c -o libcares_la-ares_metrics.lo `test -f 'ares_metrics.c' || echo '$(srcdir)/'`ares_metrics.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_metrics.Tpo $(DEPDIR)/libcares_la-ares_metrics.Plo @@ -1319,13 +1278,6 @@ libcares_la-ares_metrics.lo: ares_metrics.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_metrics.lo `test -f 'ares_metrics.c' || echo '$(srcdir)/'`ares_metrics.c -libcares_la-ares_create_query.lo: ares_create_query.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_create_query.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_create_query.Tpo -c -o libcares_la-ares_create_query.lo `test -f 'ares_create_query.c' || echo '$(srcdir)/'`ares_create_query.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_create_query.Tpo $(DEPDIR)/libcares_la-ares_create_query.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_create_query.c' object='libcares_la-ares_create_query.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_create_query.lo `test -f 'ares_create_query.c' || echo '$(srcdir)/'`ares_create_query.c - libcares_la-ares_options.lo: ares_options.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_options.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_options.Tpo -c -o libcares_la-ares_options.lo `test -f 'ares_options.c' || echo '$(srcdir)/'`ares_options.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_options.Tpo $(DEPDIR)/libcares_la-ares_options.Plo @@ -1333,83 +1285,6 @@ libcares_la-ares_options.lo: ares_options.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_options.lo `test -f 'ares_options.c' || echo '$(srcdir)/'`ares_options.c -libcares_la-ares_parse_a_reply.lo: ares_parse_a_reply.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_parse_a_reply.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_parse_a_reply.Tpo -c -o libcares_la-ares_parse_a_reply.lo `test -f 'ares_parse_a_reply.c' || echo '$(srcdir)/'`ares_parse_a_reply.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_parse_a_reply.Tpo $(DEPDIR)/libcares_la-ares_parse_a_reply.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_parse_a_reply.c' object='libcares_la-ares_parse_a_reply.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_parse_a_reply.lo `test -f 'ares_parse_a_reply.c' || echo '$(srcdir)/'`ares_parse_a_reply.c - -libcares_la-ares_parse_aaaa_reply.lo: ares_parse_aaaa_reply.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_parse_aaaa_reply.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_parse_aaaa_reply.Tpo -c -o libcares_la-ares_parse_aaaa_reply.lo `test -f 'ares_parse_aaaa_reply.c' || echo '$(srcdir)/'`ares_parse_aaaa_reply.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_parse_aaaa_reply.Tpo $(DEPDIR)/libcares_la-ares_parse_aaaa_reply.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_parse_aaaa_reply.c' object='libcares_la-ares_parse_aaaa_reply.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_parse_aaaa_reply.lo `test -f 'ares_parse_aaaa_reply.c' || echo '$(srcdir)/'`ares_parse_aaaa_reply.c - -libcares_la-ares_parse_caa_reply.lo: ares_parse_caa_reply.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_parse_caa_reply.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_parse_caa_reply.Tpo -c -o libcares_la-ares_parse_caa_reply.lo `test -f 'ares_parse_caa_reply.c' || echo '$(srcdir)/'`ares_parse_caa_reply.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_parse_caa_reply.Tpo $(DEPDIR)/libcares_la-ares_parse_caa_reply.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_parse_caa_reply.c' object='libcares_la-ares_parse_caa_reply.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_parse_caa_reply.lo `test -f 'ares_parse_caa_reply.c' || echo '$(srcdir)/'`ares_parse_caa_reply.c - -libcares_la-ares_parse_mx_reply.lo: ares_parse_mx_reply.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_parse_mx_reply.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_parse_mx_reply.Tpo -c -o libcares_la-ares_parse_mx_reply.lo `test -f 'ares_parse_mx_reply.c' || echo '$(srcdir)/'`ares_parse_mx_reply.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_parse_mx_reply.Tpo $(DEPDIR)/libcares_la-ares_parse_mx_reply.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_parse_mx_reply.c' object='libcares_la-ares_parse_mx_reply.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_parse_mx_reply.lo `test -f 'ares_parse_mx_reply.c' || echo '$(srcdir)/'`ares_parse_mx_reply.c - -libcares_la-ares_parse_naptr_reply.lo: ares_parse_naptr_reply.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_parse_naptr_reply.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_parse_naptr_reply.Tpo -c -o libcares_la-ares_parse_naptr_reply.lo `test -f 'ares_parse_naptr_reply.c' || echo '$(srcdir)/'`ares_parse_naptr_reply.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_parse_naptr_reply.Tpo $(DEPDIR)/libcares_la-ares_parse_naptr_reply.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_parse_naptr_reply.c' object='libcares_la-ares_parse_naptr_reply.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_parse_naptr_reply.lo `test -f 'ares_parse_naptr_reply.c' || echo '$(srcdir)/'`ares_parse_naptr_reply.c - -libcares_la-ares_parse_ns_reply.lo: ares_parse_ns_reply.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_parse_ns_reply.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_parse_ns_reply.Tpo -c -o libcares_la-ares_parse_ns_reply.lo `test -f 'ares_parse_ns_reply.c' || echo '$(srcdir)/'`ares_parse_ns_reply.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_parse_ns_reply.Tpo $(DEPDIR)/libcares_la-ares_parse_ns_reply.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_parse_ns_reply.c' object='libcares_la-ares_parse_ns_reply.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_parse_ns_reply.lo `test -f 'ares_parse_ns_reply.c' || echo '$(srcdir)/'`ares_parse_ns_reply.c - -libcares_la-ares_parse_ptr_reply.lo: ares_parse_ptr_reply.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_parse_ptr_reply.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_parse_ptr_reply.Tpo -c -o libcares_la-ares_parse_ptr_reply.lo `test -f 'ares_parse_ptr_reply.c' || echo '$(srcdir)/'`ares_parse_ptr_reply.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_parse_ptr_reply.Tpo $(DEPDIR)/libcares_la-ares_parse_ptr_reply.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_parse_ptr_reply.c' object='libcares_la-ares_parse_ptr_reply.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_parse_ptr_reply.lo `test -f 'ares_parse_ptr_reply.c' || echo '$(srcdir)/'`ares_parse_ptr_reply.c - -libcares_la-ares_parse_soa_reply.lo: ares_parse_soa_reply.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_parse_soa_reply.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_parse_soa_reply.Tpo -c -o libcares_la-ares_parse_soa_reply.lo `test -f 'ares_parse_soa_reply.c' || echo '$(srcdir)/'`ares_parse_soa_reply.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_parse_soa_reply.Tpo $(DEPDIR)/libcares_la-ares_parse_soa_reply.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_parse_soa_reply.c' object='libcares_la-ares_parse_soa_reply.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_parse_soa_reply.lo `test -f 'ares_parse_soa_reply.c' || echo '$(srcdir)/'`ares_parse_soa_reply.c - -libcares_la-ares_parse_srv_reply.lo: ares_parse_srv_reply.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_parse_srv_reply.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_parse_srv_reply.Tpo -c -o libcares_la-ares_parse_srv_reply.lo `test -f 'ares_parse_srv_reply.c' || echo '$(srcdir)/'`ares_parse_srv_reply.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_parse_srv_reply.Tpo $(DEPDIR)/libcares_la-ares_parse_srv_reply.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_parse_srv_reply.c' object='libcares_la-ares_parse_srv_reply.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_parse_srv_reply.lo `test -f 'ares_parse_srv_reply.c' || echo '$(srcdir)/'`ares_parse_srv_reply.c - -libcares_la-ares_parse_txt_reply.lo: ares_parse_txt_reply.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_parse_txt_reply.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_parse_txt_reply.Tpo -c -o libcares_la-ares_parse_txt_reply.lo `test -f 'ares_parse_txt_reply.c' || echo '$(srcdir)/'`ares_parse_txt_reply.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_parse_txt_reply.Tpo $(DEPDIR)/libcares_la-ares_parse_txt_reply.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_parse_txt_reply.c' object='libcares_la-ares_parse_txt_reply.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_parse_txt_reply.lo `test -f 'ares_parse_txt_reply.c' || echo '$(srcdir)/'`ares_parse_txt_reply.c - -libcares_la-ares_parse_uri_reply.lo: ares_parse_uri_reply.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_parse_uri_reply.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_parse_uri_reply.Tpo -c -o libcares_la-ares_parse_uri_reply.lo `test -f 'ares_parse_uri_reply.c' || echo '$(srcdir)/'`ares_parse_uri_reply.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_parse_uri_reply.Tpo $(DEPDIR)/libcares_la-ares_parse_uri_reply.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_parse_uri_reply.c' object='libcares_la-ares_parse_uri_reply.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_parse_uri_reply.lo `test -f 'ares_parse_uri_reply.c' || echo '$(srcdir)/'`ares_parse_uri_reply.c - libcares_la-ares_platform.lo: ares_platform.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_platform.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_platform.Tpo -c -o libcares_la-ares_platform.lo `test -f 'ares_platform.c' || echo '$(srcdir)/'`ares_platform.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_platform.Tpo $(DEPDIR)/libcares_la-ares_platform.Plo @@ -1438,13 +1313,6 @@ libcares_la-ares_query.lo: ares_query.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_query.lo `test -f 'ares_query.c' || echo '$(srcdir)/'`ares_query.c -libcares_la-ares_rand.lo: ares_rand.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_rand.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_rand.Tpo -c -o libcares_la-ares_rand.lo `test -f 'ares_rand.c' || echo '$(srcdir)/'`ares_rand.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_rand.Tpo $(DEPDIR)/libcares_la-ares_rand.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_rand.c' object='libcares_la-ares_rand.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_rand.lo `test -f 'ares_rand.c' || echo '$(srcdir)/'`ares_rand.c - libcares_la-ares_search.lo: ares_search.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_search.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_search.Tpo -c -o libcares_la-ares_search.lo `test -f 'ares_search.c' || echo '$(srcdir)/'`ares_search.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_search.Tpo $(DEPDIR)/libcares_la-ares_search.Plo @@ -1459,20 +1327,6 @@ libcares_la-ares_send.lo: ares_send.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_send.lo `test -f 'ares_send.c' || echo '$(srcdir)/'`ares_send.c -libcares_la-ares_strcasecmp.lo: ares_strcasecmp.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_strcasecmp.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_strcasecmp.Tpo -c -o libcares_la-ares_strcasecmp.lo `test -f 'ares_strcasecmp.c' || echo '$(srcdir)/'`ares_strcasecmp.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_strcasecmp.Tpo $(DEPDIR)/libcares_la-ares_strcasecmp.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_strcasecmp.c' object='libcares_la-ares_strcasecmp.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_strcasecmp.lo `test -f 'ares_strcasecmp.c' || echo '$(srcdir)/'`ares_strcasecmp.c - -libcares_la-ares_str.lo: ares_str.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_str.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_str.Tpo -c -o libcares_la-ares_str.lo `test -f 'ares_str.c' || echo '$(srcdir)/'`ares_str.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_str.Tpo $(DEPDIR)/libcares_la-ares_str.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_str.c' object='libcares_la-ares_str.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_str.lo `test -f 'ares_str.c' || echo '$(srcdir)/'`ares_str.c - libcares_la-ares_strerror.lo: ares_strerror.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_strerror.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_strerror.Tpo -c -o libcares_la-ares_strerror.lo `test -f 'ares_strerror.c' || echo '$(srcdir)/'`ares_strerror.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_strerror.Tpo $(DEPDIR)/libcares_la-ares_strerror.Plo @@ -1480,13 +1334,6 @@ libcares_la-ares_strerror.lo: ares_strerror.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_strerror.lo `test -f 'ares_strerror.c' || echo '$(srcdir)/'`ares_strerror.c -libcares_la-ares_strsplit.lo: ares_strsplit.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_strsplit.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_strsplit.Tpo -c -o libcares_la-ares_strsplit.lo `test -f 'ares_strsplit.c' || echo '$(srcdir)/'`ares_strsplit.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_strsplit.Tpo $(DEPDIR)/libcares_la-ares_strsplit.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_strsplit.c' object='libcares_la-ares_strsplit.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_strsplit.lo `test -f 'ares_strsplit.c' || echo '$(srcdir)/'`ares_strsplit.c - libcares_la-ares_sysconfig.lo: ares_sysconfig.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_sysconfig.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_sysconfig.Tpo -c -o libcares_la-ares_sysconfig.lo `test -f 'ares_sysconfig.c' || echo '$(srcdir)/'`ares_sysconfig.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_sysconfig.Tpo $(DEPDIR)/libcares_la-ares_sysconfig.Plo @@ -1557,11 +1404,346 @@ libcares_la-windows_port.lo: windows_port.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-windows_port.lo `test -f 'windows_port.c' || echo '$(srcdir)/'`windows_port.c +dsa/libcares_la-ares__array.lo: dsa/ares__array.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT dsa/libcares_la-ares__array.lo -MD -MP -MF dsa/$(DEPDIR)/libcares_la-ares__array.Tpo -c -o dsa/libcares_la-ares__array.lo `test -f 'dsa/ares__array.c' || echo '$(srcdir)/'`dsa/ares__array.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) dsa/$(DEPDIR)/libcares_la-ares__array.Tpo dsa/$(DEPDIR)/libcares_la-ares__array.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dsa/ares__array.c' object='dsa/libcares_la-ares__array.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o dsa/libcares_la-ares__array.lo `test -f 'dsa/ares__array.c' || echo '$(srcdir)/'`dsa/ares__array.c + +dsa/libcares_la-ares__htable.lo: dsa/ares__htable.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT dsa/libcares_la-ares__htable.lo -MD -MP -MF dsa/$(DEPDIR)/libcares_la-ares__htable.Tpo -c -o dsa/libcares_la-ares__htable.lo `test -f 'dsa/ares__htable.c' || echo '$(srcdir)/'`dsa/ares__htable.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) dsa/$(DEPDIR)/libcares_la-ares__htable.Tpo dsa/$(DEPDIR)/libcares_la-ares__htable.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dsa/ares__htable.c' object='dsa/libcares_la-ares__htable.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o dsa/libcares_la-ares__htable.lo `test -f 'dsa/ares__htable.c' || echo '$(srcdir)/'`dsa/ares__htable.c + +dsa/libcares_la-ares__htable_asvp.lo: dsa/ares__htable_asvp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT dsa/libcares_la-ares__htable_asvp.lo -MD -MP -MF dsa/$(DEPDIR)/libcares_la-ares__htable_asvp.Tpo -c -o dsa/libcares_la-ares__htable_asvp.lo `test -f 'dsa/ares__htable_asvp.c' || echo '$(srcdir)/'`dsa/ares__htable_asvp.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) dsa/$(DEPDIR)/libcares_la-ares__htable_asvp.Tpo dsa/$(DEPDIR)/libcares_la-ares__htable_asvp.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dsa/ares__htable_asvp.c' object='dsa/libcares_la-ares__htable_asvp.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o dsa/libcares_la-ares__htable_asvp.lo `test -f 'dsa/ares__htable_asvp.c' || echo '$(srcdir)/'`dsa/ares__htable_asvp.c + +dsa/libcares_la-ares__htable_strvp.lo: dsa/ares__htable_strvp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT dsa/libcares_la-ares__htable_strvp.lo -MD -MP -MF dsa/$(DEPDIR)/libcares_la-ares__htable_strvp.Tpo -c -o dsa/libcares_la-ares__htable_strvp.lo `test -f 'dsa/ares__htable_strvp.c' || echo '$(srcdir)/'`dsa/ares__htable_strvp.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) dsa/$(DEPDIR)/libcares_la-ares__htable_strvp.Tpo dsa/$(DEPDIR)/libcares_la-ares__htable_strvp.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dsa/ares__htable_strvp.c' object='dsa/libcares_la-ares__htable_strvp.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o dsa/libcares_la-ares__htable_strvp.lo `test -f 'dsa/ares__htable_strvp.c' || echo '$(srcdir)/'`dsa/ares__htable_strvp.c + +dsa/libcares_la-ares__htable_szvp.lo: dsa/ares__htable_szvp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT dsa/libcares_la-ares__htable_szvp.lo -MD -MP -MF dsa/$(DEPDIR)/libcares_la-ares__htable_szvp.Tpo -c -o dsa/libcares_la-ares__htable_szvp.lo `test -f 'dsa/ares__htable_szvp.c' || echo '$(srcdir)/'`dsa/ares__htable_szvp.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) dsa/$(DEPDIR)/libcares_la-ares__htable_szvp.Tpo dsa/$(DEPDIR)/libcares_la-ares__htable_szvp.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dsa/ares__htable_szvp.c' object='dsa/libcares_la-ares__htable_szvp.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o dsa/libcares_la-ares__htable_szvp.lo `test -f 'dsa/ares__htable_szvp.c' || echo '$(srcdir)/'`dsa/ares__htable_szvp.c + +dsa/libcares_la-ares__htable_vpvp.lo: dsa/ares__htable_vpvp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT dsa/libcares_la-ares__htable_vpvp.lo -MD -MP -MF dsa/$(DEPDIR)/libcares_la-ares__htable_vpvp.Tpo -c -o dsa/libcares_la-ares__htable_vpvp.lo `test -f 'dsa/ares__htable_vpvp.c' || echo '$(srcdir)/'`dsa/ares__htable_vpvp.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) dsa/$(DEPDIR)/libcares_la-ares__htable_vpvp.Tpo dsa/$(DEPDIR)/libcares_la-ares__htable_vpvp.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dsa/ares__htable_vpvp.c' object='dsa/libcares_la-ares__htable_vpvp.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o dsa/libcares_la-ares__htable_vpvp.lo `test -f 'dsa/ares__htable_vpvp.c' || echo '$(srcdir)/'`dsa/ares__htable_vpvp.c + +dsa/libcares_la-ares__llist.lo: dsa/ares__llist.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT dsa/libcares_la-ares__llist.lo -MD -MP -MF dsa/$(DEPDIR)/libcares_la-ares__llist.Tpo -c -o dsa/libcares_la-ares__llist.lo `test -f 'dsa/ares__llist.c' || echo '$(srcdir)/'`dsa/ares__llist.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) dsa/$(DEPDIR)/libcares_la-ares__llist.Tpo dsa/$(DEPDIR)/libcares_la-ares__llist.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dsa/ares__llist.c' object='dsa/libcares_la-ares__llist.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o dsa/libcares_la-ares__llist.lo `test -f 'dsa/ares__llist.c' || echo '$(srcdir)/'`dsa/ares__llist.c + +dsa/libcares_la-ares__slist.lo: dsa/ares__slist.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT dsa/libcares_la-ares__slist.lo -MD -MP -MF dsa/$(DEPDIR)/libcares_la-ares__slist.Tpo -c -o dsa/libcares_la-ares__slist.lo `test -f 'dsa/ares__slist.c' || echo '$(srcdir)/'`dsa/ares__slist.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) dsa/$(DEPDIR)/libcares_la-ares__slist.Tpo dsa/$(DEPDIR)/libcares_la-ares__slist.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dsa/ares__slist.c' object='dsa/libcares_la-ares__slist.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o dsa/libcares_la-ares__slist.lo `test -f 'dsa/ares__slist.c' || echo '$(srcdir)/'`dsa/ares__slist.c + +event/libcares_la-ares_event_configchg.lo: event/ares_event_configchg.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT event/libcares_la-ares_event_configchg.lo -MD -MP -MF event/$(DEPDIR)/libcares_la-ares_event_configchg.Tpo -c -o event/libcares_la-ares_event_configchg.lo `test -f 'event/ares_event_configchg.c' || echo '$(srcdir)/'`event/ares_event_configchg.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) event/$(DEPDIR)/libcares_la-ares_event_configchg.Tpo event/$(DEPDIR)/libcares_la-ares_event_configchg.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='event/ares_event_configchg.c' object='event/libcares_la-ares_event_configchg.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o event/libcares_la-ares_event_configchg.lo `test -f 'event/ares_event_configchg.c' || echo '$(srcdir)/'`event/ares_event_configchg.c + +event/libcares_la-ares_event_epoll.lo: event/ares_event_epoll.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT event/libcares_la-ares_event_epoll.lo -MD -MP -MF event/$(DEPDIR)/libcares_la-ares_event_epoll.Tpo -c -o event/libcares_la-ares_event_epoll.lo `test -f 'event/ares_event_epoll.c' || echo '$(srcdir)/'`event/ares_event_epoll.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) event/$(DEPDIR)/libcares_la-ares_event_epoll.Tpo event/$(DEPDIR)/libcares_la-ares_event_epoll.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='event/ares_event_epoll.c' object='event/libcares_la-ares_event_epoll.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o event/libcares_la-ares_event_epoll.lo `test -f 'event/ares_event_epoll.c' || echo '$(srcdir)/'`event/ares_event_epoll.c + +event/libcares_la-ares_event_kqueue.lo: event/ares_event_kqueue.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT event/libcares_la-ares_event_kqueue.lo -MD -MP -MF event/$(DEPDIR)/libcares_la-ares_event_kqueue.Tpo -c -o event/libcares_la-ares_event_kqueue.lo `test -f 'event/ares_event_kqueue.c' || echo '$(srcdir)/'`event/ares_event_kqueue.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) event/$(DEPDIR)/libcares_la-ares_event_kqueue.Tpo event/$(DEPDIR)/libcares_la-ares_event_kqueue.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='event/ares_event_kqueue.c' object='event/libcares_la-ares_event_kqueue.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o event/libcares_la-ares_event_kqueue.lo `test -f 'event/ares_event_kqueue.c' || echo '$(srcdir)/'`event/ares_event_kqueue.c + +event/libcares_la-ares_event_poll.lo: event/ares_event_poll.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT event/libcares_la-ares_event_poll.lo -MD -MP -MF event/$(DEPDIR)/libcares_la-ares_event_poll.Tpo -c -o event/libcares_la-ares_event_poll.lo `test -f 'event/ares_event_poll.c' || echo '$(srcdir)/'`event/ares_event_poll.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) event/$(DEPDIR)/libcares_la-ares_event_poll.Tpo event/$(DEPDIR)/libcares_la-ares_event_poll.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='event/ares_event_poll.c' object='event/libcares_la-ares_event_poll.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o event/libcares_la-ares_event_poll.lo `test -f 'event/ares_event_poll.c' || echo '$(srcdir)/'`event/ares_event_poll.c + +event/libcares_la-ares_event_select.lo: event/ares_event_select.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT event/libcares_la-ares_event_select.lo -MD -MP -MF event/$(DEPDIR)/libcares_la-ares_event_select.Tpo -c -o event/libcares_la-ares_event_select.lo `test -f 'event/ares_event_select.c' || echo '$(srcdir)/'`event/ares_event_select.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) event/$(DEPDIR)/libcares_la-ares_event_select.Tpo event/$(DEPDIR)/libcares_la-ares_event_select.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='event/ares_event_select.c' object='event/libcares_la-ares_event_select.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o event/libcares_la-ares_event_select.lo `test -f 'event/ares_event_select.c' || echo '$(srcdir)/'`event/ares_event_select.c + +event/libcares_la-ares_event_thread.lo: event/ares_event_thread.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT event/libcares_la-ares_event_thread.lo -MD -MP -MF event/$(DEPDIR)/libcares_la-ares_event_thread.Tpo -c -o event/libcares_la-ares_event_thread.lo `test -f 'event/ares_event_thread.c' || echo '$(srcdir)/'`event/ares_event_thread.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) event/$(DEPDIR)/libcares_la-ares_event_thread.Tpo event/$(DEPDIR)/libcares_la-ares_event_thread.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='event/ares_event_thread.c' object='event/libcares_la-ares_event_thread.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o event/libcares_la-ares_event_thread.lo `test -f 'event/ares_event_thread.c' || echo '$(srcdir)/'`event/ares_event_thread.c + +event/libcares_la-ares_event_wake_pipe.lo: event/ares_event_wake_pipe.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT event/libcares_la-ares_event_wake_pipe.lo -MD -MP -MF event/$(DEPDIR)/libcares_la-ares_event_wake_pipe.Tpo -c -o event/libcares_la-ares_event_wake_pipe.lo `test -f 'event/ares_event_wake_pipe.c' || echo '$(srcdir)/'`event/ares_event_wake_pipe.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) event/$(DEPDIR)/libcares_la-ares_event_wake_pipe.Tpo event/$(DEPDIR)/libcares_la-ares_event_wake_pipe.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='event/ares_event_wake_pipe.c' object='event/libcares_la-ares_event_wake_pipe.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o event/libcares_la-ares_event_wake_pipe.lo `test -f 'event/ares_event_wake_pipe.c' || echo '$(srcdir)/'`event/ares_event_wake_pipe.c + +event/libcares_la-ares_event_win32.lo: event/ares_event_win32.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT event/libcares_la-ares_event_win32.lo -MD -MP -MF event/$(DEPDIR)/libcares_la-ares_event_win32.Tpo -c -o event/libcares_la-ares_event_win32.lo `test -f 'event/ares_event_win32.c' || echo '$(srcdir)/'`event/ares_event_win32.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) event/$(DEPDIR)/libcares_la-ares_event_win32.Tpo event/$(DEPDIR)/libcares_la-ares_event_win32.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='event/ares_event_win32.c' object='event/libcares_la-ares_event_win32.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o event/libcares_la-ares_event_win32.lo `test -f 'event/ares_event_win32.c' || echo '$(srcdir)/'`event/ares_event_win32.c + +legacy/libcares_la-ares_create_query.lo: legacy/ares_create_query.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT legacy/libcares_la-ares_create_query.lo -MD -MP -MF legacy/$(DEPDIR)/libcares_la-ares_create_query.Tpo -c -o legacy/libcares_la-ares_create_query.lo `test -f 'legacy/ares_create_query.c' || echo '$(srcdir)/'`legacy/ares_create_query.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) legacy/$(DEPDIR)/libcares_la-ares_create_query.Tpo legacy/$(DEPDIR)/libcares_la-ares_create_query.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='legacy/ares_create_query.c' object='legacy/libcares_la-ares_create_query.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o legacy/libcares_la-ares_create_query.lo `test -f 'legacy/ares_create_query.c' || echo '$(srcdir)/'`legacy/ares_create_query.c + +legacy/libcares_la-ares_expand_name.lo: legacy/ares_expand_name.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT legacy/libcares_la-ares_expand_name.lo -MD -MP -MF legacy/$(DEPDIR)/libcares_la-ares_expand_name.Tpo -c -o legacy/libcares_la-ares_expand_name.lo `test -f 'legacy/ares_expand_name.c' || echo '$(srcdir)/'`legacy/ares_expand_name.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) legacy/$(DEPDIR)/libcares_la-ares_expand_name.Tpo legacy/$(DEPDIR)/libcares_la-ares_expand_name.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='legacy/ares_expand_name.c' object='legacy/libcares_la-ares_expand_name.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o legacy/libcares_la-ares_expand_name.lo `test -f 'legacy/ares_expand_name.c' || echo '$(srcdir)/'`legacy/ares_expand_name.c + +legacy/libcares_la-ares_expand_string.lo: legacy/ares_expand_string.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT legacy/libcares_la-ares_expand_string.lo -MD -MP -MF legacy/$(DEPDIR)/libcares_la-ares_expand_string.Tpo -c -o legacy/libcares_la-ares_expand_string.lo `test -f 'legacy/ares_expand_string.c' || echo '$(srcdir)/'`legacy/ares_expand_string.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) legacy/$(DEPDIR)/libcares_la-ares_expand_string.Tpo legacy/$(DEPDIR)/libcares_la-ares_expand_string.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='legacy/ares_expand_string.c' object='legacy/libcares_la-ares_expand_string.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o legacy/libcares_la-ares_expand_string.lo `test -f 'legacy/ares_expand_string.c' || echo '$(srcdir)/'`legacy/ares_expand_string.c + +legacy/libcares_la-ares_fds.lo: legacy/ares_fds.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT legacy/libcares_la-ares_fds.lo -MD -MP -MF legacy/$(DEPDIR)/libcares_la-ares_fds.Tpo -c -o legacy/libcares_la-ares_fds.lo `test -f 'legacy/ares_fds.c' || echo '$(srcdir)/'`legacy/ares_fds.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) legacy/$(DEPDIR)/libcares_la-ares_fds.Tpo legacy/$(DEPDIR)/libcares_la-ares_fds.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='legacy/ares_fds.c' object='legacy/libcares_la-ares_fds.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o legacy/libcares_la-ares_fds.lo `test -f 'legacy/ares_fds.c' || echo '$(srcdir)/'`legacy/ares_fds.c + +legacy/libcares_la-ares_getsock.lo: legacy/ares_getsock.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT legacy/libcares_la-ares_getsock.lo -MD -MP -MF legacy/$(DEPDIR)/libcares_la-ares_getsock.Tpo -c -o legacy/libcares_la-ares_getsock.lo `test -f 'legacy/ares_getsock.c' || echo '$(srcdir)/'`legacy/ares_getsock.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) legacy/$(DEPDIR)/libcares_la-ares_getsock.Tpo legacy/$(DEPDIR)/libcares_la-ares_getsock.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='legacy/ares_getsock.c' object='legacy/libcares_la-ares_getsock.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o legacy/libcares_la-ares_getsock.lo `test -f 'legacy/ares_getsock.c' || echo '$(srcdir)/'`legacy/ares_getsock.c + +legacy/libcares_la-ares_parse_a_reply.lo: legacy/ares_parse_a_reply.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT legacy/libcares_la-ares_parse_a_reply.lo -MD -MP -MF legacy/$(DEPDIR)/libcares_la-ares_parse_a_reply.Tpo -c -o legacy/libcares_la-ares_parse_a_reply.lo `test -f 'legacy/ares_parse_a_reply.c' || echo '$(srcdir)/'`legacy/ares_parse_a_reply.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) legacy/$(DEPDIR)/libcares_la-ares_parse_a_reply.Tpo legacy/$(DEPDIR)/libcares_la-ares_parse_a_reply.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='legacy/ares_parse_a_reply.c' object='legacy/libcares_la-ares_parse_a_reply.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o legacy/libcares_la-ares_parse_a_reply.lo `test -f 'legacy/ares_parse_a_reply.c' || echo '$(srcdir)/'`legacy/ares_parse_a_reply.c + +legacy/libcares_la-ares_parse_aaaa_reply.lo: legacy/ares_parse_aaaa_reply.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT legacy/libcares_la-ares_parse_aaaa_reply.lo -MD -MP -MF legacy/$(DEPDIR)/libcares_la-ares_parse_aaaa_reply.Tpo -c -o legacy/libcares_la-ares_parse_aaaa_reply.lo `test -f 'legacy/ares_parse_aaaa_reply.c' || echo '$(srcdir)/'`legacy/ares_parse_aaaa_reply.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) legacy/$(DEPDIR)/libcares_la-ares_parse_aaaa_reply.Tpo legacy/$(DEPDIR)/libcares_la-ares_parse_aaaa_reply.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='legacy/ares_parse_aaaa_reply.c' object='legacy/libcares_la-ares_parse_aaaa_reply.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o legacy/libcares_la-ares_parse_aaaa_reply.lo `test -f 'legacy/ares_parse_aaaa_reply.c' || echo '$(srcdir)/'`legacy/ares_parse_aaaa_reply.c + +legacy/libcares_la-ares_parse_caa_reply.lo: legacy/ares_parse_caa_reply.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT legacy/libcares_la-ares_parse_caa_reply.lo -MD -MP -MF legacy/$(DEPDIR)/libcares_la-ares_parse_caa_reply.Tpo -c -o legacy/libcares_la-ares_parse_caa_reply.lo `test -f 'legacy/ares_parse_caa_reply.c' || echo '$(srcdir)/'`legacy/ares_parse_caa_reply.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) legacy/$(DEPDIR)/libcares_la-ares_parse_caa_reply.Tpo legacy/$(DEPDIR)/libcares_la-ares_parse_caa_reply.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='legacy/ares_parse_caa_reply.c' object='legacy/libcares_la-ares_parse_caa_reply.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o legacy/libcares_la-ares_parse_caa_reply.lo `test -f 'legacy/ares_parse_caa_reply.c' || echo '$(srcdir)/'`legacy/ares_parse_caa_reply.c + +legacy/libcares_la-ares_parse_mx_reply.lo: legacy/ares_parse_mx_reply.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT legacy/libcares_la-ares_parse_mx_reply.lo -MD -MP -MF legacy/$(DEPDIR)/libcares_la-ares_parse_mx_reply.Tpo -c -o legacy/libcares_la-ares_parse_mx_reply.lo `test -f 'legacy/ares_parse_mx_reply.c' || echo '$(srcdir)/'`legacy/ares_parse_mx_reply.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) legacy/$(DEPDIR)/libcares_la-ares_parse_mx_reply.Tpo legacy/$(DEPDIR)/libcares_la-ares_parse_mx_reply.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='legacy/ares_parse_mx_reply.c' object='legacy/libcares_la-ares_parse_mx_reply.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o legacy/libcares_la-ares_parse_mx_reply.lo `test -f 'legacy/ares_parse_mx_reply.c' || echo '$(srcdir)/'`legacy/ares_parse_mx_reply.c + +legacy/libcares_la-ares_parse_naptr_reply.lo: legacy/ares_parse_naptr_reply.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT legacy/libcares_la-ares_parse_naptr_reply.lo -MD -MP -MF legacy/$(DEPDIR)/libcares_la-ares_parse_naptr_reply.Tpo -c -o legacy/libcares_la-ares_parse_naptr_reply.lo `test -f 'legacy/ares_parse_naptr_reply.c' || echo '$(srcdir)/'`legacy/ares_parse_naptr_reply.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) legacy/$(DEPDIR)/libcares_la-ares_parse_naptr_reply.Tpo legacy/$(DEPDIR)/libcares_la-ares_parse_naptr_reply.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='legacy/ares_parse_naptr_reply.c' object='legacy/libcares_la-ares_parse_naptr_reply.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o legacy/libcares_la-ares_parse_naptr_reply.lo `test -f 'legacy/ares_parse_naptr_reply.c' || echo '$(srcdir)/'`legacy/ares_parse_naptr_reply.c + +legacy/libcares_la-ares_parse_ns_reply.lo: legacy/ares_parse_ns_reply.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT legacy/libcares_la-ares_parse_ns_reply.lo -MD -MP -MF legacy/$(DEPDIR)/libcares_la-ares_parse_ns_reply.Tpo -c -o legacy/libcares_la-ares_parse_ns_reply.lo `test -f 'legacy/ares_parse_ns_reply.c' || echo '$(srcdir)/'`legacy/ares_parse_ns_reply.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) legacy/$(DEPDIR)/libcares_la-ares_parse_ns_reply.Tpo legacy/$(DEPDIR)/libcares_la-ares_parse_ns_reply.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='legacy/ares_parse_ns_reply.c' object='legacy/libcares_la-ares_parse_ns_reply.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o legacy/libcares_la-ares_parse_ns_reply.lo `test -f 'legacy/ares_parse_ns_reply.c' || echo '$(srcdir)/'`legacy/ares_parse_ns_reply.c + +legacy/libcares_la-ares_parse_ptr_reply.lo: legacy/ares_parse_ptr_reply.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT legacy/libcares_la-ares_parse_ptr_reply.lo -MD -MP -MF legacy/$(DEPDIR)/libcares_la-ares_parse_ptr_reply.Tpo -c -o legacy/libcares_la-ares_parse_ptr_reply.lo `test -f 'legacy/ares_parse_ptr_reply.c' || echo '$(srcdir)/'`legacy/ares_parse_ptr_reply.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) legacy/$(DEPDIR)/libcares_la-ares_parse_ptr_reply.Tpo legacy/$(DEPDIR)/libcares_la-ares_parse_ptr_reply.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='legacy/ares_parse_ptr_reply.c' object='legacy/libcares_la-ares_parse_ptr_reply.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o legacy/libcares_la-ares_parse_ptr_reply.lo `test -f 'legacy/ares_parse_ptr_reply.c' || echo '$(srcdir)/'`legacy/ares_parse_ptr_reply.c + +legacy/libcares_la-ares_parse_soa_reply.lo: legacy/ares_parse_soa_reply.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT legacy/libcares_la-ares_parse_soa_reply.lo -MD -MP -MF legacy/$(DEPDIR)/libcares_la-ares_parse_soa_reply.Tpo -c -o legacy/libcares_la-ares_parse_soa_reply.lo `test -f 'legacy/ares_parse_soa_reply.c' || echo '$(srcdir)/'`legacy/ares_parse_soa_reply.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) legacy/$(DEPDIR)/libcares_la-ares_parse_soa_reply.Tpo legacy/$(DEPDIR)/libcares_la-ares_parse_soa_reply.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='legacy/ares_parse_soa_reply.c' object='legacy/libcares_la-ares_parse_soa_reply.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o legacy/libcares_la-ares_parse_soa_reply.lo `test -f 'legacy/ares_parse_soa_reply.c' || echo '$(srcdir)/'`legacy/ares_parse_soa_reply.c + +legacy/libcares_la-ares_parse_srv_reply.lo: legacy/ares_parse_srv_reply.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT legacy/libcares_la-ares_parse_srv_reply.lo -MD -MP -MF legacy/$(DEPDIR)/libcares_la-ares_parse_srv_reply.Tpo -c -o legacy/libcares_la-ares_parse_srv_reply.lo `test -f 'legacy/ares_parse_srv_reply.c' || echo '$(srcdir)/'`legacy/ares_parse_srv_reply.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) legacy/$(DEPDIR)/libcares_la-ares_parse_srv_reply.Tpo legacy/$(DEPDIR)/libcares_la-ares_parse_srv_reply.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='legacy/ares_parse_srv_reply.c' object='legacy/libcares_la-ares_parse_srv_reply.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o legacy/libcares_la-ares_parse_srv_reply.lo `test -f 'legacy/ares_parse_srv_reply.c' || echo '$(srcdir)/'`legacy/ares_parse_srv_reply.c + +legacy/libcares_la-ares_parse_txt_reply.lo: legacy/ares_parse_txt_reply.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT legacy/libcares_la-ares_parse_txt_reply.lo -MD -MP -MF legacy/$(DEPDIR)/libcares_la-ares_parse_txt_reply.Tpo -c -o legacy/libcares_la-ares_parse_txt_reply.lo `test -f 'legacy/ares_parse_txt_reply.c' || echo '$(srcdir)/'`legacy/ares_parse_txt_reply.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) legacy/$(DEPDIR)/libcares_la-ares_parse_txt_reply.Tpo legacy/$(DEPDIR)/libcares_la-ares_parse_txt_reply.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='legacy/ares_parse_txt_reply.c' object='legacy/libcares_la-ares_parse_txt_reply.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o legacy/libcares_la-ares_parse_txt_reply.lo `test -f 'legacy/ares_parse_txt_reply.c' || echo '$(srcdir)/'`legacy/ares_parse_txt_reply.c + +legacy/libcares_la-ares_parse_uri_reply.lo: legacy/ares_parse_uri_reply.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT legacy/libcares_la-ares_parse_uri_reply.lo -MD -MP -MF legacy/$(DEPDIR)/libcares_la-ares_parse_uri_reply.Tpo -c -o legacy/libcares_la-ares_parse_uri_reply.lo `test -f 'legacy/ares_parse_uri_reply.c' || echo '$(srcdir)/'`legacy/ares_parse_uri_reply.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) legacy/$(DEPDIR)/libcares_la-ares_parse_uri_reply.Tpo legacy/$(DEPDIR)/libcares_la-ares_parse_uri_reply.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='legacy/ares_parse_uri_reply.c' object='legacy/libcares_la-ares_parse_uri_reply.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o legacy/libcares_la-ares_parse_uri_reply.lo `test -f 'legacy/ares_parse_uri_reply.c' || echo '$(srcdir)/'`legacy/ares_parse_uri_reply.c + +record/libcares_la-ares_dns_mapping.lo: record/ares_dns_mapping.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT record/libcares_la-ares_dns_mapping.lo -MD -MP -MF record/$(DEPDIR)/libcares_la-ares_dns_mapping.Tpo -c -o record/libcares_la-ares_dns_mapping.lo `test -f 'record/ares_dns_mapping.c' || echo '$(srcdir)/'`record/ares_dns_mapping.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) record/$(DEPDIR)/libcares_la-ares_dns_mapping.Tpo record/$(DEPDIR)/libcares_la-ares_dns_mapping.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='record/ares_dns_mapping.c' object='record/libcares_la-ares_dns_mapping.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o record/libcares_la-ares_dns_mapping.lo `test -f 'record/ares_dns_mapping.c' || echo '$(srcdir)/'`record/ares_dns_mapping.c + +record/libcares_la-ares_dns_multistring.lo: record/ares_dns_multistring.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT record/libcares_la-ares_dns_multistring.lo -MD -MP -MF record/$(DEPDIR)/libcares_la-ares_dns_multistring.Tpo -c -o record/libcares_la-ares_dns_multistring.lo `test -f 'record/ares_dns_multistring.c' || echo '$(srcdir)/'`record/ares_dns_multistring.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) record/$(DEPDIR)/libcares_la-ares_dns_multistring.Tpo record/$(DEPDIR)/libcares_la-ares_dns_multistring.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='record/ares_dns_multistring.c' object='record/libcares_la-ares_dns_multistring.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o record/libcares_la-ares_dns_multistring.lo `test -f 'record/ares_dns_multistring.c' || echo '$(srcdir)/'`record/ares_dns_multistring.c + +record/libcares_la-ares_dns_name.lo: record/ares_dns_name.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT record/libcares_la-ares_dns_name.lo -MD -MP -MF record/$(DEPDIR)/libcares_la-ares_dns_name.Tpo -c -o record/libcares_la-ares_dns_name.lo `test -f 'record/ares_dns_name.c' || echo '$(srcdir)/'`record/ares_dns_name.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) record/$(DEPDIR)/libcares_la-ares_dns_name.Tpo record/$(DEPDIR)/libcares_la-ares_dns_name.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='record/ares_dns_name.c' object='record/libcares_la-ares_dns_name.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o record/libcares_la-ares_dns_name.lo `test -f 'record/ares_dns_name.c' || echo '$(srcdir)/'`record/ares_dns_name.c + +record/libcares_la-ares_dns_parse.lo: record/ares_dns_parse.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT record/libcares_la-ares_dns_parse.lo -MD -MP -MF record/$(DEPDIR)/libcares_la-ares_dns_parse.Tpo -c -o record/libcares_la-ares_dns_parse.lo `test -f 'record/ares_dns_parse.c' || echo '$(srcdir)/'`record/ares_dns_parse.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) record/$(DEPDIR)/libcares_la-ares_dns_parse.Tpo record/$(DEPDIR)/libcares_la-ares_dns_parse.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='record/ares_dns_parse.c' object='record/libcares_la-ares_dns_parse.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o record/libcares_la-ares_dns_parse.lo `test -f 'record/ares_dns_parse.c' || echo '$(srcdir)/'`record/ares_dns_parse.c + +record/libcares_la-ares_dns_record.lo: record/ares_dns_record.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT record/libcares_la-ares_dns_record.lo -MD -MP -MF record/$(DEPDIR)/libcares_la-ares_dns_record.Tpo -c -o record/libcares_la-ares_dns_record.lo `test -f 'record/ares_dns_record.c' || echo '$(srcdir)/'`record/ares_dns_record.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) record/$(DEPDIR)/libcares_la-ares_dns_record.Tpo record/$(DEPDIR)/libcares_la-ares_dns_record.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='record/ares_dns_record.c' object='record/libcares_la-ares_dns_record.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o record/libcares_la-ares_dns_record.lo `test -f 'record/ares_dns_record.c' || echo '$(srcdir)/'`record/ares_dns_record.c + +record/libcares_la-ares_dns_write.lo: record/ares_dns_write.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT record/libcares_la-ares_dns_write.lo -MD -MP -MF record/$(DEPDIR)/libcares_la-ares_dns_write.Tpo -c -o record/libcares_la-ares_dns_write.lo `test -f 'record/ares_dns_write.c' || echo '$(srcdir)/'`record/ares_dns_write.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) record/$(DEPDIR)/libcares_la-ares_dns_write.Tpo record/$(DEPDIR)/libcares_la-ares_dns_write.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='record/ares_dns_write.c' object='record/libcares_la-ares_dns_write.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o record/libcares_la-ares_dns_write.lo `test -f 'record/ares_dns_write.c' || echo '$(srcdir)/'`record/ares_dns_write.c + +str/libcares_la-ares__buf.lo: str/ares__buf.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT str/libcares_la-ares__buf.lo -MD -MP -MF str/$(DEPDIR)/libcares_la-ares__buf.Tpo -c -o str/libcares_la-ares__buf.lo `test -f 'str/ares__buf.c' || echo '$(srcdir)/'`str/ares__buf.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) str/$(DEPDIR)/libcares_la-ares__buf.Tpo str/$(DEPDIR)/libcares_la-ares__buf.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='str/ares__buf.c' object='str/libcares_la-ares__buf.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o str/libcares_la-ares__buf.lo `test -f 'str/ares__buf.c' || echo '$(srcdir)/'`str/ares__buf.c + +str/libcares_la-ares_strcasecmp.lo: str/ares_strcasecmp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT str/libcares_la-ares_strcasecmp.lo -MD -MP -MF str/$(DEPDIR)/libcares_la-ares_strcasecmp.Tpo -c -o str/libcares_la-ares_strcasecmp.lo `test -f 'str/ares_strcasecmp.c' || echo '$(srcdir)/'`str/ares_strcasecmp.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) str/$(DEPDIR)/libcares_la-ares_strcasecmp.Tpo str/$(DEPDIR)/libcares_la-ares_strcasecmp.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='str/ares_strcasecmp.c' object='str/libcares_la-ares_strcasecmp.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o str/libcares_la-ares_strcasecmp.lo `test -f 'str/ares_strcasecmp.c' || echo '$(srcdir)/'`str/ares_strcasecmp.c + +str/libcares_la-ares_str.lo: str/ares_str.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT str/libcares_la-ares_str.lo -MD -MP -MF str/$(DEPDIR)/libcares_la-ares_str.Tpo -c -o str/libcares_la-ares_str.lo `test -f 'str/ares_str.c' || echo '$(srcdir)/'`str/ares_str.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) str/$(DEPDIR)/libcares_la-ares_str.Tpo str/$(DEPDIR)/libcares_la-ares_str.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='str/ares_str.c' object='str/libcares_la-ares_str.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o str/libcares_la-ares_str.lo `test -f 'str/ares_str.c' || echo '$(srcdir)/'`str/ares_str.c + +str/libcares_la-ares_strsplit.lo: str/ares_strsplit.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT str/libcares_la-ares_strsplit.lo -MD -MP -MF str/$(DEPDIR)/libcares_la-ares_strsplit.Tpo -c -o str/libcares_la-ares_strsplit.lo `test -f 'str/ares_strsplit.c' || echo '$(srcdir)/'`str/ares_strsplit.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) str/$(DEPDIR)/libcares_la-ares_strsplit.Tpo str/$(DEPDIR)/libcares_la-ares_strsplit.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='str/ares_strsplit.c' object='str/libcares_la-ares_strsplit.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o str/libcares_la-ares_strsplit.lo `test -f 'str/ares_strsplit.c' || echo '$(srcdir)/'`str/ares_strsplit.c + +util/libcares_la-ares__iface_ips.lo: util/ares__iface_ips.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT util/libcares_la-ares__iface_ips.lo -MD -MP -MF util/$(DEPDIR)/libcares_la-ares__iface_ips.Tpo -c -o util/libcares_la-ares__iface_ips.lo `test -f 'util/ares__iface_ips.c' || echo '$(srcdir)/'`util/ares__iface_ips.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) util/$(DEPDIR)/libcares_la-ares__iface_ips.Tpo util/$(DEPDIR)/libcares_la-ares__iface_ips.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='util/ares__iface_ips.c' object='util/libcares_la-ares__iface_ips.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o util/libcares_la-ares__iface_ips.lo `test -f 'util/ares__iface_ips.c' || echo '$(srcdir)/'`util/ares__iface_ips.c + +util/libcares_la-ares__threads.lo: util/ares__threads.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT util/libcares_la-ares__threads.lo -MD -MP -MF util/$(DEPDIR)/libcares_la-ares__threads.Tpo -c -o util/libcares_la-ares__threads.lo `test -f 'util/ares__threads.c' || echo '$(srcdir)/'`util/ares__threads.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) util/$(DEPDIR)/libcares_la-ares__threads.Tpo util/$(DEPDIR)/libcares_la-ares__threads.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='util/ares__threads.c' object='util/libcares_la-ares__threads.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o util/libcares_la-ares__threads.lo `test -f 'util/ares__threads.c' || echo '$(srcdir)/'`util/ares__threads.c + +util/libcares_la-ares__timeval.lo: util/ares__timeval.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT util/libcares_la-ares__timeval.lo -MD -MP -MF util/$(DEPDIR)/libcares_la-ares__timeval.Tpo -c -o util/libcares_la-ares__timeval.lo `test -f 'util/ares__timeval.c' || echo '$(srcdir)/'`util/ares__timeval.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) util/$(DEPDIR)/libcares_la-ares__timeval.Tpo util/$(DEPDIR)/libcares_la-ares__timeval.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='util/ares__timeval.c' object='util/libcares_la-ares__timeval.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o util/libcares_la-ares__timeval.lo `test -f 'util/ares__timeval.c' || echo '$(srcdir)/'`util/ares__timeval.c + +util/libcares_la-ares_math.lo: util/ares_math.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT util/libcares_la-ares_math.lo -MD -MP -MF util/$(DEPDIR)/libcares_la-ares_math.Tpo -c -o util/libcares_la-ares_math.lo `test -f 'util/ares_math.c' || echo '$(srcdir)/'`util/ares_math.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) util/$(DEPDIR)/libcares_la-ares_math.Tpo util/$(DEPDIR)/libcares_la-ares_math.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='util/ares_math.c' object='util/libcares_la-ares_math.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o util/libcares_la-ares_math.lo `test -f 'util/ares_math.c' || echo '$(srcdir)/'`util/ares_math.c + +util/libcares_la-ares_rand.lo: util/ares_rand.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT util/libcares_la-ares_rand.lo -MD -MP -MF util/$(DEPDIR)/libcares_la-ares_rand.Tpo -c -o util/libcares_la-ares_rand.lo `test -f 'util/ares_rand.c' || echo '$(srcdir)/'`util/ares_rand.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) util/$(DEPDIR)/libcares_la-ares_rand.Tpo util/$(DEPDIR)/libcares_la-ares_rand.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='util/ares_rand.c' object='util/libcares_la-ares_rand.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o util/libcares_la-ares_rand.lo `test -f 'util/ares_rand.c' || echo '$(srcdir)/'`util/ares_rand.c + mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs + -rm -rf dsa/.libs dsa/_libs + -rm -rf event/.libs event/_libs + -rm -rf legacy/.libs legacy/_libs + -rm -rf record/.libs record/_libs + -rm -rf str/.libs str/_libs + -rm -rf util/.libs util/_libs # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. @@ -1751,9 +1933,21 @@ mostlyclean-generic: clean-generic: distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) + -$(am__rm_f) $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) + -$(am__rm_f) $(DISTCLEANFILES) + -$(am__rm_f) dsa/$(DEPDIR)/$(am__dirstamp) + -$(am__rm_f) dsa/$(am__dirstamp) + -$(am__rm_f) event/$(DEPDIR)/$(am__dirstamp) + -$(am__rm_f) event/$(am__dirstamp) + -$(am__rm_f) legacy/$(DEPDIR)/$(am__dirstamp) + -$(am__rm_f) legacy/$(am__dirstamp) + -$(am__rm_f) record/$(DEPDIR)/$(am__dirstamp) + -$(am__rm_f) record/$(am__dirstamp) + -$(am__rm_f) str/$(DEPDIR)/$(am__dirstamp) + -$(am__rm_f) str/$(am__dirstamp) + -$(am__rm_f) util/$(DEPDIR)/$(am__dirstamp) + -$(am__rm_f) util/$(am__dirstamp) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @@ -1764,46 +1958,18 @@ clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ mostlyclean-am distclean: distclean-recursive - -rm -f ./$(DEPDIR)/libcares_la-ares__addrinfo2hostent.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares__addrinfo2hostent.Plo -rm -f ./$(DEPDIR)/libcares_la-ares__addrinfo_localhost.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares__buf.Plo -rm -f ./$(DEPDIR)/libcares_la-ares__close_sockets.Plo -rm -f ./$(DEPDIR)/libcares_la-ares__hosts_file.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares__htable.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares__htable_asvp.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares__htable_strvp.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares__htable_szvp.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares__htable_vpvp.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares__iface_ips.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares__llist.Plo -rm -f ./$(DEPDIR)/libcares_la-ares__parse_into_addrinfo.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares__slist.Plo -rm -f ./$(DEPDIR)/libcares_la-ares__socket.Plo -rm -f ./$(DEPDIR)/libcares_la-ares__sortaddrinfo.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares__threads.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares__timeval.Plo -rm -f ./$(DEPDIR)/libcares_la-ares_android.Plo -rm -f ./$(DEPDIR)/libcares_la-ares_cancel.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares_create_query.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_cookie.Plo -rm -f ./$(DEPDIR)/libcares_la-ares_data.Plo -rm -f ./$(DEPDIR)/libcares_la-ares_destroy.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares_dns_mapping.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares_dns_multistring.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares_dns_name.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares_dns_parse.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares_dns_record.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares_dns_write.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares_event_configchg.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares_event_epoll.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares_event_kqueue.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares_event_poll.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares_event_select.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares_event_thread.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares_event_wake_pipe.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares_event_win32.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares_expand_name.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares_expand_string.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares_fds.Plo -rm -f ./$(DEPDIR)/libcares_la-ares_free_hostent.Plo -rm -f ./$(DEPDIR)/libcares_la-ares_free_string.Plo -rm -f ./$(DEPDIR)/libcares_la-ares_freeaddrinfo.Plo @@ -1812,34 +1978,17 @@ distclean: distclean-recursive -rm -f ./$(DEPDIR)/libcares_la-ares_gethostbyaddr.Plo -rm -f ./$(DEPDIR)/libcares_la-ares_gethostbyname.Plo -rm -f ./$(DEPDIR)/libcares_la-ares_getnameinfo.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares_getsock.Plo -rm -f ./$(DEPDIR)/libcares_la-ares_init.Plo -rm -f ./$(DEPDIR)/libcares_la-ares_library_init.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares_math.Plo -rm -f ./$(DEPDIR)/libcares_la-ares_metrics.Plo -rm -f ./$(DEPDIR)/libcares_la-ares_options.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares_parse_a_reply.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares_parse_aaaa_reply.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares_parse_caa_reply.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares_parse_mx_reply.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares_parse_naptr_reply.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares_parse_ns_reply.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares_parse_ptr_reply.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares_parse_soa_reply.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares_parse_srv_reply.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares_parse_txt_reply.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares_parse_uri_reply.Plo -rm -f ./$(DEPDIR)/libcares_la-ares_platform.Plo -rm -f ./$(DEPDIR)/libcares_la-ares_process.Plo -rm -f ./$(DEPDIR)/libcares_la-ares_qcache.Plo -rm -f ./$(DEPDIR)/libcares_la-ares_query.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares_rand.Plo -rm -f ./$(DEPDIR)/libcares_la-ares_search.Plo -rm -f ./$(DEPDIR)/libcares_la-ares_send.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares_str.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares_strcasecmp.Plo -rm -f ./$(DEPDIR)/libcares_la-ares_strerror.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares_strsplit.Plo -rm -f ./$(DEPDIR)/libcares_la-ares_sysconfig.Plo -rm -f ./$(DEPDIR)/libcares_la-ares_sysconfig_files.Plo -rm -f ./$(DEPDIR)/libcares_la-ares_sysconfig_mac.Plo @@ -1850,6 +1999,53 @@ distclean: distclean-recursive -rm -f ./$(DEPDIR)/libcares_la-inet_net_pton.Plo -rm -f ./$(DEPDIR)/libcares_la-inet_ntop.Plo -rm -f ./$(DEPDIR)/libcares_la-windows_port.Plo + -rm -f dsa/$(DEPDIR)/libcares_la-ares__array.Plo + -rm -f dsa/$(DEPDIR)/libcares_la-ares__htable.Plo + -rm -f dsa/$(DEPDIR)/libcares_la-ares__htable_asvp.Plo + -rm -f dsa/$(DEPDIR)/libcares_la-ares__htable_strvp.Plo + -rm -f dsa/$(DEPDIR)/libcares_la-ares__htable_szvp.Plo + -rm -f dsa/$(DEPDIR)/libcares_la-ares__htable_vpvp.Plo + -rm -f dsa/$(DEPDIR)/libcares_la-ares__llist.Plo + -rm -f dsa/$(DEPDIR)/libcares_la-ares__slist.Plo + -rm -f event/$(DEPDIR)/libcares_la-ares_event_configchg.Plo + -rm -f event/$(DEPDIR)/libcares_la-ares_event_epoll.Plo + -rm -f event/$(DEPDIR)/libcares_la-ares_event_kqueue.Plo + -rm -f event/$(DEPDIR)/libcares_la-ares_event_poll.Plo + -rm -f event/$(DEPDIR)/libcares_la-ares_event_select.Plo + -rm -f event/$(DEPDIR)/libcares_la-ares_event_thread.Plo + -rm -f event/$(DEPDIR)/libcares_la-ares_event_wake_pipe.Plo + -rm -f event/$(DEPDIR)/libcares_la-ares_event_win32.Plo + -rm -f legacy/$(DEPDIR)/libcares_la-ares_create_query.Plo + -rm -f legacy/$(DEPDIR)/libcares_la-ares_expand_name.Plo + -rm -f legacy/$(DEPDIR)/libcares_la-ares_expand_string.Plo + -rm -f legacy/$(DEPDIR)/libcares_la-ares_fds.Plo + -rm -f legacy/$(DEPDIR)/libcares_la-ares_getsock.Plo + -rm -f legacy/$(DEPDIR)/libcares_la-ares_parse_a_reply.Plo + -rm -f legacy/$(DEPDIR)/libcares_la-ares_parse_aaaa_reply.Plo + -rm -f legacy/$(DEPDIR)/libcares_la-ares_parse_caa_reply.Plo + -rm -f legacy/$(DEPDIR)/libcares_la-ares_parse_mx_reply.Plo + -rm -f legacy/$(DEPDIR)/libcares_la-ares_parse_naptr_reply.Plo + -rm -f legacy/$(DEPDIR)/libcares_la-ares_parse_ns_reply.Plo + -rm -f legacy/$(DEPDIR)/libcares_la-ares_parse_ptr_reply.Plo + -rm -f legacy/$(DEPDIR)/libcares_la-ares_parse_soa_reply.Plo + -rm -f legacy/$(DEPDIR)/libcares_la-ares_parse_srv_reply.Plo + -rm -f legacy/$(DEPDIR)/libcares_la-ares_parse_txt_reply.Plo + -rm -f legacy/$(DEPDIR)/libcares_la-ares_parse_uri_reply.Plo + -rm -f record/$(DEPDIR)/libcares_la-ares_dns_mapping.Plo + -rm -f record/$(DEPDIR)/libcares_la-ares_dns_multistring.Plo + -rm -f record/$(DEPDIR)/libcares_la-ares_dns_name.Plo + -rm -f record/$(DEPDIR)/libcares_la-ares_dns_parse.Plo + -rm -f record/$(DEPDIR)/libcares_la-ares_dns_record.Plo + -rm -f record/$(DEPDIR)/libcares_la-ares_dns_write.Plo + -rm -f str/$(DEPDIR)/libcares_la-ares__buf.Plo + -rm -f str/$(DEPDIR)/libcares_la-ares_str.Plo + -rm -f str/$(DEPDIR)/libcares_la-ares_strcasecmp.Plo + -rm -f str/$(DEPDIR)/libcares_la-ares_strsplit.Plo + -rm -f util/$(DEPDIR)/libcares_la-ares__iface_ips.Plo + -rm -f util/$(DEPDIR)/libcares_la-ares__threads.Plo + -rm -f util/$(DEPDIR)/libcares_la-ares__timeval.Plo + -rm -f util/$(DEPDIR)/libcares_la-ares_math.Plo + -rm -f util/$(DEPDIR)/libcares_la-ares_rand.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-hdr distclean-tags @@ -1895,46 +2091,18 @@ install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive - -rm -f ./$(DEPDIR)/libcares_la-ares__addrinfo2hostent.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares__addrinfo2hostent.Plo -rm -f ./$(DEPDIR)/libcares_la-ares__addrinfo_localhost.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares__buf.Plo -rm -f ./$(DEPDIR)/libcares_la-ares__close_sockets.Plo -rm -f ./$(DEPDIR)/libcares_la-ares__hosts_file.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares__htable.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares__htable_asvp.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares__htable_strvp.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares__htable_szvp.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares__htable_vpvp.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares__iface_ips.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares__llist.Plo -rm -f ./$(DEPDIR)/libcares_la-ares__parse_into_addrinfo.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares__slist.Plo -rm -f ./$(DEPDIR)/libcares_la-ares__socket.Plo -rm -f ./$(DEPDIR)/libcares_la-ares__sortaddrinfo.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares__threads.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares__timeval.Plo -rm -f ./$(DEPDIR)/libcares_la-ares_android.Plo -rm -f ./$(DEPDIR)/libcares_la-ares_cancel.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares_create_query.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_cookie.Plo -rm -f ./$(DEPDIR)/libcares_la-ares_data.Plo -rm -f ./$(DEPDIR)/libcares_la-ares_destroy.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares_dns_mapping.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares_dns_multistring.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares_dns_name.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares_dns_parse.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares_dns_record.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares_dns_write.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares_event_configchg.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares_event_epoll.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares_event_kqueue.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares_event_poll.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares_event_select.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares_event_thread.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares_event_wake_pipe.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares_event_win32.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares_expand_name.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares_expand_string.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares_fds.Plo -rm -f ./$(DEPDIR)/libcares_la-ares_free_hostent.Plo -rm -f ./$(DEPDIR)/libcares_la-ares_free_string.Plo -rm -f ./$(DEPDIR)/libcares_la-ares_freeaddrinfo.Plo @@ -1943,34 +2111,17 @@ maintainer-clean: maintainer-clean-recursive -rm -f ./$(DEPDIR)/libcares_la-ares_gethostbyaddr.Plo -rm -f ./$(DEPDIR)/libcares_la-ares_gethostbyname.Plo -rm -f ./$(DEPDIR)/libcares_la-ares_getnameinfo.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares_getsock.Plo -rm -f ./$(DEPDIR)/libcares_la-ares_init.Plo -rm -f ./$(DEPDIR)/libcares_la-ares_library_init.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares_math.Plo -rm -f ./$(DEPDIR)/libcares_la-ares_metrics.Plo -rm -f ./$(DEPDIR)/libcares_la-ares_options.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares_parse_a_reply.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares_parse_aaaa_reply.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares_parse_caa_reply.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares_parse_mx_reply.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares_parse_naptr_reply.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares_parse_ns_reply.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares_parse_ptr_reply.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares_parse_soa_reply.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares_parse_srv_reply.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares_parse_txt_reply.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares_parse_uri_reply.Plo -rm -f ./$(DEPDIR)/libcares_la-ares_platform.Plo -rm -f ./$(DEPDIR)/libcares_la-ares_process.Plo -rm -f ./$(DEPDIR)/libcares_la-ares_qcache.Plo -rm -f ./$(DEPDIR)/libcares_la-ares_query.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares_rand.Plo -rm -f ./$(DEPDIR)/libcares_la-ares_search.Plo -rm -f ./$(DEPDIR)/libcares_la-ares_send.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares_str.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares_strcasecmp.Plo -rm -f ./$(DEPDIR)/libcares_la-ares_strerror.Plo - -rm -f ./$(DEPDIR)/libcares_la-ares_strsplit.Plo -rm -f ./$(DEPDIR)/libcares_la-ares_sysconfig.Plo -rm -f ./$(DEPDIR)/libcares_la-ares_sysconfig_files.Plo -rm -f ./$(DEPDIR)/libcares_la-ares_sysconfig_mac.Plo @@ -1981,6 +2132,53 @@ maintainer-clean: maintainer-clean-recursive -rm -f ./$(DEPDIR)/libcares_la-inet_net_pton.Plo -rm -f ./$(DEPDIR)/libcares_la-inet_ntop.Plo -rm -f ./$(DEPDIR)/libcares_la-windows_port.Plo + -rm -f dsa/$(DEPDIR)/libcares_la-ares__array.Plo + -rm -f dsa/$(DEPDIR)/libcares_la-ares__htable.Plo + -rm -f dsa/$(DEPDIR)/libcares_la-ares__htable_asvp.Plo + -rm -f dsa/$(DEPDIR)/libcares_la-ares__htable_strvp.Plo + -rm -f dsa/$(DEPDIR)/libcares_la-ares__htable_szvp.Plo + -rm -f dsa/$(DEPDIR)/libcares_la-ares__htable_vpvp.Plo + -rm -f dsa/$(DEPDIR)/libcares_la-ares__llist.Plo + -rm -f dsa/$(DEPDIR)/libcares_la-ares__slist.Plo + -rm -f event/$(DEPDIR)/libcares_la-ares_event_configchg.Plo + -rm -f event/$(DEPDIR)/libcares_la-ares_event_epoll.Plo + -rm -f event/$(DEPDIR)/libcares_la-ares_event_kqueue.Plo + -rm -f event/$(DEPDIR)/libcares_la-ares_event_poll.Plo + -rm -f event/$(DEPDIR)/libcares_la-ares_event_select.Plo + -rm -f event/$(DEPDIR)/libcares_la-ares_event_thread.Plo + -rm -f event/$(DEPDIR)/libcares_la-ares_event_wake_pipe.Plo + -rm -f event/$(DEPDIR)/libcares_la-ares_event_win32.Plo + -rm -f legacy/$(DEPDIR)/libcares_la-ares_create_query.Plo + -rm -f legacy/$(DEPDIR)/libcares_la-ares_expand_name.Plo + -rm -f legacy/$(DEPDIR)/libcares_la-ares_expand_string.Plo + -rm -f legacy/$(DEPDIR)/libcares_la-ares_fds.Plo + -rm -f legacy/$(DEPDIR)/libcares_la-ares_getsock.Plo + -rm -f legacy/$(DEPDIR)/libcares_la-ares_parse_a_reply.Plo + -rm -f legacy/$(DEPDIR)/libcares_la-ares_parse_aaaa_reply.Plo + -rm -f legacy/$(DEPDIR)/libcares_la-ares_parse_caa_reply.Plo + -rm -f legacy/$(DEPDIR)/libcares_la-ares_parse_mx_reply.Plo + -rm -f legacy/$(DEPDIR)/libcares_la-ares_parse_naptr_reply.Plo + -rm -f legacy/$(DEPDIR)/libcares_la-ares_parse_ns_reply.Plo + -rm -f legacy/$(DEPDIR)/libcares_la-ares_parse_ptr_reply.Plo + -rm -f legacy/$(DEPDIR)/libcares_la-ares_parse_soa_reply.Plo + -rm -f legacy/$(DEPDIR)/libcares_la-ares_parse_srv_reply.Plo + -rm -f legacy/$(DEPDIR)/libcares_la-ares_parse_txt_reply.Plo + -rm -f legacy/$(DEPDIR)/libcares_la-ares_parse_uri_reply.Plo + -rm -f record/$(DEPDIR)/libcares_la-ares_dns_mapping.Plo + -rm -f record/$(DEPDIR)/libcares_la-ares_dns_multistring.Plo + -rm -f record/$(DEPDIR)/libcares_la-ares_dns_name.Plo + -rm -f record/$(DEPDIR)/libcares_la-ares_dns_parse.Plo + -rm -f record/$(DEPDIR)/libcares_la-ares_dns_record.Plo + -rm -f record/$(DEPDIR)/libcares_la-ares_dns_write.Plo + -rm -f str/$(DEPDIR)/libcares_la-ares__buf.Plo + -rm -f str/$(DEPDIR)/libcares_la-ares_str.Plo + -rm -f str/$(DEPDIR)/libcares_la-ares_strcasecmp.Plo + -rm -f str/$(DEPDIR)/libcares_la-ares_strsplit.Plo + -rm -f util/$(DEPDIR)/libcares_la-ares__iface_ips.Plo + -rm -f util/$(DEPDIR)/libcares_la-ares__threads.Plo + -rm -f util/$(DEPDIR)/libcares_la-ares__timeval.Plo + -rm -f util/$(DEPDIR)/libcares_la-ares_math.Plo + -rm -f util/$(DEPDIR)/libcares_la-ares_rand.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic @@ -2123,3 +2321,10 @@ code-coverage-capture-hook: # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: + +# Tell GNU make to disable its built-in pattern rules. +%:: %,v +%:: RCS/%,v +%:: RCS/% +%:: s.% +%:: SCCS/s.% diff --git a/deps/cares/src/lib/Makefile.inc b/deps/cares/src/lib/Makefile.inc index a1f39609edc..8fa434c3e2c 100644 --- a/deps/cares/src/lib/Makefile.inc +++ b/deps/cares/src/lib/Makefile.inc @@ -3,43 +3,16 @@ CSOURCES = ares__addrinfo2hostent.c \ ares__addrinfo_localhost.c \ - ares__buf.c \ ares__close_sockets.c \ ares__hosts_file.c \ - ares__htable.c \ - ares__htable_asvp.c \ - ares__htable_strvp.c \ - ares__htable_szvp.c \ - ares__htable_vpvp.c \ - ares__iface_ips.c \ - ares__llist.c \ ares__parse_into_addrinfo.c \ - ares__slist.c \ ares__socket.c \ ares__sortaddrinfo.c \ - ares__threads.c \ - ares__timeval.c \ ares_android.c \ ares_cancel.c \ + ares_cookie.c \ ares_data.c \ ares_destroy.c \ - ares_dns_mapping.c \ - ares_dns_multistring.c \ - ares_dns_name.c \ - ares_dns_parse.c \ - ares_dns_record.c \ - ares_dns_write.c \ - ares_event_configchg.c \ - ares_event_epoll.c \ - ares_event_kqueue.c \ - ares_event_poll.c \ - ares_event_select.c \ - ares_event_thread.c \ - ares_event_wake_pipe.c \ - ares_event_win32.c \ - ares_expand_name.c \ - ares_expand_string.c \ - ares_fds.c \ ares_free_hostent.c \ ares_free_string.c \ ares_freeaddrinfo.c \ @@ -48,35 +21,17 @@ CSOURCES = ares__addrinfo2hostent.c \ ares_gethostbyaddr.c \ ares_gethostbyname.c \ ares_getnameinfo.c \ - ares_getsock.c \ ares_init.c \ ares_library_init.c \ - ares_math.c \ ares_metrics.c \ - ares_create_query.c \ ares_options.c \ - ares_parse_a_reply.c \ - ares_parse_aaaa_reply.c \ - ares_parse_caa_reply.c \ - ares_parse_mx_reply.c \ - ares_parse_naptr_reply.c \ - ares_parse_ns_reply.c \ - ares_parse_ptr_reply.c \ - ares_parse_soa_reply.c \ - ares_parse_srv_reply.c \ - ares_parse_txt_reply.c \ - ares_parse_uri_reply.c \ ares_platform.c \ ares_process.c \ ares_qcache.c \ ares_query.c \ - ares_rand.c \ ares_search.c \ ares_send.c \ - ares_strcasecmp.c \ - ares_str.c \ ares_strerror.c \ - ares_strsplit.c \ ares_sysconfig.c \ ares_sysconfig_files.c \ ares_sysconfig_mac.c \ @@ -86,32 +41,80 @@ CSOURCES = ares__addrinfo2hostent.c \ ares_version.c \ inet_net_pton.c \ inet_ntop.c \ - windows_port.c + windows_port.c \ + dsa/ares__array.c \ + dsa/ares__htable.c \ + dsa/ares__htable_asvp.c \ + dsa/ares__htable_strvp.c \ + dsa/ares__htable_szvp.c \ + dsa/ares__htable_vpvp.c \ + dsa/ares__llist.c \ + dsa/ares__slist.c \ + event/ares_event_configchg.c \ + event/ares_event_epoll.c \ + event/ares_event_kqueue.c \ + event/ares_event_poll.c \ + event/ares_event_select.c \ + event/ares_event_thread.c \ + event/ares_event_wake_pipe.c \ + event/ares_event_win32.c \ + legacy/ares_create_query.c \ + legacy/ares_expand_name.c \ + legacy/ares_expand_string.c \ + legacy/ares_fds.c \ + legacy/ares_getsock.c \ + legacy/ares_parse_a_reply.c \ + legacy/ares_parse_aaaa_reply.c \ + legacy/ares_parse_caa_reply.c \ + legacy/ares_parse_mx_reply.c \ + legacy/ares_parse_naptr_reply.c \ + legacy/ares_parse_ns_reply.c \ + legacy/ares_parse_ptr_reply.c \ + legacy/ares_parse_soa_reply.c \ + legacy/ares_parse_srv_reply.c \ + legacy/ares_parse_txt_reply.c \ + legacy/ares_parse_uri_reply.c \ + record/ares_dns_mapping.c \ + record/ares_dns_multistring.c \ + record/ares_dns_name.c \ + record/ares_dns_parse.c \ + record/ares_dns_record.c \ + record/ares_dns_write.c \ + str/ares__buf.c \ + str/ares_strcasecmp.c \ + str/ares_str.c \ + str/ares_strsplit.c \ + util/ares__iface_ips.c \ + util/ares__threads.c \ + util/ares__timeval.c \ + util/ares_math.c \ + util/ares_rand.c -HHEADERS = ares__buf.h \ - ares__htable.h \ - ares__htable_asvp.h \ - ares__htable_strvp.h \ - ares__htable_szvp.h \ - ares__htable_vpvp.h \ - ares__iface_ips.h \ - ares__llist.h \ - ares__slist.h \ - ares__threads.h \ - ares_android.h \ +HHEADERS = ares_android.h \ ares_data.h \ - ares_dns_multistring.h \ - ares_dns_private.h \ - ares_event.h \ - ares_event_win32.h \ ares_getenv.h \ ares_inet_net_pton.h \ ares_ipv6.h \ ares_platform.h \ ares_private.h \ - ares_strcasecmp.h \ - ares_str.h \ - ares_strsplit.h \ ares_setup.h \ + dsa/ares__array.h \ + dsa/ares__htable.h \ + dsa/ares__htable_asvp.h \ + dsa/ares__htable_strvp.h \ + dsa/ares__htable_szvp.h \ + dsa/ares__htable_vpvp.h \ + dsa/ares__llist.h \ + dsa/ares__slist.h \ + event/ares_event.h \ + event/ares_event_win32.h \ + record/ares_dns_multistring.h \ + record/ares_dns_private.h \ + str/ares__buf.h \ + str/ares_strcasecmp.h \ + str/ares_str.h \ + str/ares_strsplit.h \ + util/ares__iface_ips.h \ + util/ares__threads.h \ thirdparty/apple/dnsinfo.h diff --git a/deps/cares/src/lib/ares__addrinfo2hostent.c b/deps/cares/src/lib/ares__addrinfo2hostent.c index 9505af7340d..f7b6d1edd25 100644 --- a/deps/cares/src/lib/ares__addrinfo2hostent.c +++ b/deps/cares/src/lib/ares__addrinfo2hostent.c @@ -161,16 +161,16 @@ ares_status_t ares__addrinfo2hostent(const struct ares_addrinfo *ai, int family, } (*host)->h_addr_list[i] = addrs + (i * (size_t)(*host)->h_length); if (family == AF_INET6) { - memcpy( - (*host)->h_addr_list[i], - &(CARES_INADDR_CAST(const struct sockaddr_in6 *, next->ai_addr)->sin6_addr), - (size_t)(*host)->h_length); + memcpy((*host)->h_addr_list[i], + &(CARES_INADDR_CAST(const struct sockaddr_in6 *, next->ai_addr) + ->sin6_addr), + (size_t)(*host)->h_length); } if (family == AF_INET) { - memcpy( - (*host)->h_addr_list[i], - &(CARES_INADDR_CAST(const struct sockaddr_in *, next->ai_addr)->sin_addr), - (size_t)(*host)->h_length); + memcpy((*host)->h_addr_list[i], + &(CARES_INADDR_CAST(const struct sockaddr_in *, next->ai_addr) + ->sin_addr), + (size_t)(*host)->h_length); } ++i; } @@ -252,20 +252,20 @@ ares_status_t ares__addrinfo2addrttl(const struct ares_addrinfo *ai, int family, addr6ttls[*naddrttls].ttl = next->ai_ttl; } - memcpy( - &addr6ttls[*naddrttls].ip6addr, - &(CARES_INADDR_CAST(const struct sockaddr_in6 *, next->ai_addr)->sin6_addr), - sizeof(struct ares_in6_addr)); + memcpy(&addr6ttls[*naddrttls].ip6addr, + &(CARES_INADDR_CAST(const struct sockaddr_in6 *, next->ai_addr) + ->sin6_addr), + sizeof(struct ares_in6_addr)); } else { if (next->ai_ttl > cname_ttl) { addrttls[*naddrttls].ttl = cname_ttl; } else { addrttls[*naddrttls].ttl = next->ai_ttl; } - memcpy( - &addrttls[*naddrttls].ipaddr, - &(CARES_INADDR_CAST(const struct sockaddr_in *, next->ai_addr)->sin_addr), - sizeof(struct in_addr)); + memcpy(&addrttls[*naddrttls].ipaddr, + &(CARES_INADDR_CAST(const struct sockaddr_in *, next->ai_addr) + ->sin_addr), + sizeof(struct in_addr)); } (*naddrttls)++; } diff --git a/deps/cares/src/lib/ares__close_sockets.c b/deps/cares/src/lib/ares__close_sockets.c index 33a030c9d23..71c7e64f08a 100644 --- a/deps/cares/src/lib/ares__close_sockets.c +++ b/deps/cares/src/lib/ares__close_sockets.c @@ -28,31 +28,30 @@ #include "ares_private.h" #include -static void ares__requeue_queries(struct server_connection *conn, +static void ares__requeue_queries(ares_conn_t *conn, ares_status_t requeue_status) { - struct query *query; + ares_query_t *query; ares_timeval_t now; ares__tvnow(&now); while ((query = ares__llist_first_val(conn->queries_to_conn)) != NULL) { - ares__requeue_query(query, &now, requeue_status); + ares__requeue_query(query, &now, requeue_status, ARES_TRUE, NULL); } } -void ares__close_connection(struct server_connection *conn, - ares_status_t requeue_status) +void ares__close_connection(ares_conn_t *conn, ares_status_t requeue_status) { - struct server_state *server = conn->server; - ares_channel_t *channel = server->channel; + ares_server_t *server = conn->server; + ares_channel_t *channel = server->channel; /* Unlink */ ares__llist_node_claim( ares__htable_asvp_get_direct(channel->connnode_by_socket, conn->fd)); ares__htable_asvp_remove(channel->connnode_by_socket, conn->fd); - if (conn->is_tcp) { + if (conn->flags & ARES_CONN_FLAG_TCP) { /* Reset any existing input and output buffer. */ ares__buf_consume(server->tcp_parser, ares__buf_len(server->tcp_parser)); ares__buf_consume(server->tcp_send, ares__buf_len(server->tcp_send)); @@ -70,12 +69,12 @@ void ares__close_connection(struct server_connection *conn, ares_free(conn); } -void ares__close_sockets(struct server_state *server) +void ares__close_sockets(ares_server_t *server) { ares__llist_node_t *node; while ((node = ares__llist_node_first(server->connections)) != NULL) { - struct server_connection *conn = ares__llist_node_val(node); + ares_conn_t *conn = ares__llist_node_val(node); ares__close_connection(conn, ARES_SUCCESS); } } @@ -91,17 +90,16 @@ void ares__check_cleanup_conns(const ares_channel_t *channel) /* Iterate across each server */ for (snode = ares__slist_node_first(channel->servers); snode != NULL; snode = ares__slist_node_next(snode)) { - - struct server_state *server = ares__slist_node_val(snode); - ares__llist_node_t *cnode; + ares_server_t *server = ares__slist_node_val(snode); + ares__llist_node_t *cnode; /* Iterate across each connection */ cnode = ares__llist_node_first(server->connections); while (cnode != NULL) { - ares__llist_node_t *next = ares__llist_node_next(cnode); - struct server_connection *conn = ares__llist_node_val(cnode); - ares_bool_t do_cleanup = ARES_FALSE; - cnode = next; + ares__llist_node_t *next = ares__llist_node_next(cnode); + ares_conn_t *conn = ares__llist_node_val(cnode); + ares_bool_t do_cleanup = ARES_FALSE; + cnode = next; /* Has connections, not eligible */ if (ares__llist_len(conn->queries_to_conn)) { @@ -122,7 +120,7 @@ void ares__check_cleanup_conns(const ares_channel_t *channel) } /* If the udp connection hit its max queries, always close it */ - if (!conn->is_tcp && channel->udp_max_queries > 0 && + if (!(conn->flags & ARES_CONN_FLAG_TCP) && channel->udp_max_queries > 0 && conn->total_queries >= channel->udp_max_queries) { do_cleanup = ARES_TRUE; } diff --git a/deps/cares/src/lib/ares__socket.c b/deps/cares/src/lib/ares__socket.c index 3db19f7e823..86e281fcdda 100644 --- a/deps/cares/src/lib/ares__socket.c +++ b/deps/cares/src/lib/ares__socket.c @@ -56,6 +56,77 @@ #include #include +#if defined(__linux__) && defined(TCP_FASTOPEN_CONNECT) +# define TFO_SUPPORTED 1 +# define TFO_SKIP_CONNECT 0 +# define TFO_USE_SENDTO 0 +# define TFO_USE_CONNECTX 0 +# define TFO_CLIENT_SOCKOPT TCP_FASTOPEN_CONNECT +#elif defined(__FreeBSD__) && defined(TCP_FASTOPEN) +# define TFO_SUPPORTED 1 +# define TFO_SKIP_CONNECT 1 +# define TFO_USE_SENDTO 1 +# define TFO_USE_CONNECTX 0 +# define TFO_CLIENT_SOCKOPT TCP_FASTOPEN +#elif defined(__APPLE__) && defined(HAVE_CONNECTX) +# define TFO_SUPPORTED 1 +# define TFO_SKIP_CONNECT 0 +# define TFO_USE_SENDTO 0 +# define TFO_USE_CONNECTX 1 +# undef TFO_CLIENT_SOCKOPT +#else +# define TFO_SUPPORTED 0 +#endif + + +#ifndef HAVE_WRITEV +/* Structure for scatter/gather I/O. */ +struct iovec { + void *iov_base; /* Pointer to data. */ + size_t iov_len; /* Length of data. */ +}; +#endif + + +/* Return 1 if the specified error number describes a readiness error, or 0 + * otherwise. This is mostly for HP-UX, which could return EAGAIN or + * EWOULDBLOCK. See this man page + * + * http://devrsrc1.external.hp.com/STKS/cgi-bin/man2html? + * manpage=/usr/share/man/man2.Z/send.2 + */ +ares_bool_t ares__socket_try_again(int errnum) +{ +#if !defined EWOULDBLOCK && !defined EAGAIN +# error "Neither EWOULDBLOCK nor EAGAIN defined" +#endif + +#ifdef EWOULDBLOCK + if (errnum == EWOULDBLOCK) { + return ARES_TRUE; + } +#endif + +#if defined EAGAIN && EAGAIN != EWOULDBLOCK + if (errnum == EAGAIN) { + return ARES_TRUE; + } +#endif + + return ARES_FALSE; +} + +ares_ssize_t ares__socket_recv(ares_channel_t *channel, ares_socket_t s, + void *data, size_t data_len) +{ + if (channel->sock_funcs && channel->sock_funcs->arecvfrom) { + return channel->sock_funcs->arecvfrom(s, data, data_len, 0, 0, 0, + channel->sock_func_cb_data); + } + + return (ares_ssize_t)recv((RECV_TYPE_ARG1)s, (RECV_TYPE_ARG2)data, + (RECV_TYPE_ARG3)data_len, (RECV_TYPE_ARG4)(0)); +} ares_ssize_t ares__socket_recvfrom(ares_channel_t *channel, ares_socket_t s, void *data, size_t data_len, int flags, @@ -71,20 +142,142 @@ ares_ssize_t ares__socket_recvfrom(ares_channel_t *channel, ares_socket_t s, return (ares_ssize_t)recvfrom(s, data, (RECVFROM_TYPE_ARG3)data_len, flags, from, from_len); #else - return sread(s, data, data_len); + return ares__socket_recv(channel, s, data, data_len); #endif } -ares_ssize_t ares__socket_recv(ares_channel_t *channel, ares_socket_t s, - void *data, size_t data_len) +/* Use like: + * struct sockaddr_storage sa_storage; + * ares_socklen_t salen = sizeof(sa_storage); + * struct sockaddr *sa = (struct sockaddr *)&sa_storage; + * ares__conn_set_sockaddr(conn, sa, &salen); + */ +static ares_status_t ares__conn_set_sockaddr(const ares_conn_t *conn, + struct sockaddr *sa, + ares_socklen_t *salen) { - if (channel->sock_funcs && channel->sock_funcs->arecvfrom) { - return channel->sock_funcs->arecvfrom(s, data, data_len, 0, 0, 0, - channel->sock_func_cb_data); + const ares_server_t *server = conn->server; + unsigned short port = + conn->flags & ARES_CONN_FLAG_TCP ? server->tcp_port : server->udp_port; + struct sockaddr_in *sin; + struct sockaddr_in6 *sin6; + + switch (server->addr.family) { + case AF_INET: + sin = (struct sockaddr_in *)(void *)sa; + if (*salen < (ares_socklen_t)sizeof(*sin)) { + return ARES_EFORMERR; + } + *salen = sizeof(*sin); + memset(sin, 0, sizeof(*sin)); + sin->sin_family = AF_INET; + sin->sin_port = htons(port); + memcpy(&sin->sin_addr, &server->addr.addr.addr4, sizeof(sin->sin_addr)); + return ARES_SUCCESS; + case AF_INET6: + sin6 = (struct sockaddr_in6 *)(void *)sa; + if (*salen < (ares_socklen_t)sizeof(*sin6)) { + return ARES_EFORMERR; + } + *salen = sizeof(*sin6); + memset(sin6, 0, sizeof(*sin6)); + sin6->sin6_family = AF_INET6; + sin6->sin6_port = htons(port); + memcpy(&sin6->sin6_addr, &server->addr.addr.addr6, + sizeof(sin6->sin6_addr)); +#ifdef HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID + sin6->sin6_scope_id = server->ll_scope; +#endif + return ARES_SUCCESS; + default: + break; } - /* sread() is a wrapper for read() or recv() depending on the system */ - return sread(s, data, data_len); + return ARES_EBADFAMILY; +} + +static ares_status_t ares_conn_set_self_ip(ares_conn_t *conn, ares_bool_t early) +{ + struct sockaddr_storage sa_storage; + int rv; + ares_socklen_t len = sizeof(sa_storage); + + /* We call this twice on TFO, if we already have the IP we can go ahead and + * skip processing */ + if (!early && conn->self_ip.family != AF_UNSPEC) { + return ARES_SUCCESS; + } + + memset(&sa_storage, 0, sizeof(sa_storage)); + + rv = getsockname(conn->fd, (struct sockaddr *)(void *)&sa_storage, &len); + if (rv != 0) { + /* During TCP FastOpen, we can't get the IP this early since connect() + * may not be called. That's ok, we'll try again later */ + if (early && conn->flags & ARES_CONN_FLAG_TCP && + conn->flags & ARES_CONN_FLAG_TFO) { + memset(&conn->self_ip, 0, sizeof(conn->self_ip)); + return ARES_SUCCESS; + } + return ARES_ECONNREFUSED; + } + + if (!ares_sockaddr_to_ares_addr(&conn->self_ip, NULL, + (struct sockaddr *)(void *)&sa_storage)) { + return ARES_ECONNREFUSED; + } + + return ARES_SUCCESS; +} + +ares_ssize_t ares__conn_write(ares_conn_t *conn, const void *data, size_t len) +{ + ares_channel_t *channel = conn->server->channel; + int flags = 0; + +#ifdef HAVE_MSG_NOSIGNAL + flags |= MSG_NOSIGNAL; +#endif + + if (channel->sock_funcs && channel->sock_funcs->asendv) { + struct iovec vec; + vec.iov_base = (void *)((size_t)data); /* Cast off const */ + vec.iov_len = len; + return channel->sock_funcs->asendv(conn->fd, &vec, 1, + channel->sock_func_cb_data); + } + + if (conn->flags & ARES_CONN_FLAG_TFO_INITIAL) { + conn->flags &= ~((unsigned int)ARES_CONN_FLAG_TFO_INITIAL); + +#if defined(TFO_USE_SENDTO) && TFO_USE_SENDTO + { + struct sockaddr_storage sa_storage; + ares_socklen_t salen = sizeof(sa_storage); + struct sockaddr *sa = (struct sockaddr *)&sa_storage; + ares_status_t status; + ares_ssize_t rv; + + status = ares__conn_set_sockaddr(conn, sa, &salen); + if (status != ARES_SUCCESS) { + return status; + } + + rv = (ares_ssize_t)sendto((SEND_TYPE_ARG1)conn->fd, (SEND_TYPE_ARG2)data, + (SEND_TYPE_ARG3)len, (SEND_TYPE_ARG4)flags, sa, + salen); + + /* If using TFO, we might not have been able to get an IP earlier, since + * we hadn't informed the OS of the destination. When using sendto() + * now we have so we should be able to fetch it */ + ares_conn_set_self_ip(conn, ARES_TRUE); + return rv; + } +#endif + } + + return (ares_ssize_t)send((SEND_TYPE_ARG1)conn->fd, (SEND_TYPE_ARG2)data, + (SEND_TYPE_ARG3)len, (SEND_TYPE_ARG4)flags); } /* @@ -159,7 +352,7 @@ static void set_ipv6_v6only(ares_socket_t sockfd, int on) # define set_ipv6_v6only(s, v) #endif -static int configure_socket(ares_socket_t s, struct server_state *server) +static ares_status_t configure_socket(ares_conn_t *conn) { union { struct sockaddr sa; @@ -168,19 +361,20 @@ static int configure_socket(ares_socket_t s, struct server_state *server) } local; ares_socklen_t bindlen = 0; + ares_server_t *server = conn->server; ares_channel_t *channel = server->channel; /* do not set options for user-managed sockets */ if (channel->sock_funcs && channel->sock_funcs->asocket) { - return 0; + return ARES_SUCCESS; } - (void)setsocknonblock(s, 1); + (void)setsocknonblock(conn->fd, 1); #if defined(FD_CLOEXEC) && !defined(MSDOS) /* Configure the socket fd as close-on-exec. */ - if (fcntl(s, F_SETFD, FD_CLOEXEC) == -1) { - return -1; /* LCOV_EXCL_LINE */ + if (fcntl(conn->fd, F_SETFD, FD_CLOEXEC) != 0) { + return ARES_ECONNREFUSED; /* LCOV_EXCL_LINE */ } #endif @@ -188,31 +382,32 @@ static int configure_socket(ares_socket_t s, struct server_state *server) #if defined(SO_NOSIGPIPE) { int opt = 1; - setsockopt(s, SOL_SOCKET, SO_NOSIGPIPE, (void *)&opt, sizeof(opt)); + (void)setsockopt(conn->fd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&opt, + sizeof(opt)); } #endif /* Set the socket's send and receive buffer sizes. */ - if ((channel->socket_send_buffer_size > 0) && - setsockopt(s, SOL_SOCKET, SO_SNDBUF, + if (channel->socket_send_buffer_size > 0 && + setsockopt(conn->fd, SOL_SOCKET, SO_SNDBUF, (void *)&channel->socket_send_buffer_size, - sizeof(channel->socket_send_buffer_size)) == -1) { - return -1; /* LCOV_EXCL_LINE: UntestablePath */ + sizeof(channel->socket_send_buffer_size)) != 0) { + return ARES_ECONNREFUSED; /* LCOV_EXCL_LINE: UntestablePath */ } - if ((channel->socket_receive_buffer_size > 0) && - setsockopt(s, SOL_SOCKET, SO_RCVBUF, + if (channel->socket_receive_buffer_size > 0 && + setsockopt(conn->fd, SOL_SOCKET, SO_RCVBUF, (void *)&channel->socket_receive_buffer_size, - sizeof(channel->socket_receive_buffer_size)) == -1) { - return -1; /* LCOV_EXCL_LINE: UntestablePath */ + sizeof(channel->socket_receive_buffer_size)) != 0) { + return ARES_ECONNREFUSED; /* LCOV_EXCL_LINE: UntestablePath */ } #ifdef SO_BINDTODEVICE - if (channel->local_dev_name[0] && - setsockopt(s, SOL_SOCKET, SO_BINDTODEVICE, channel->local_dev_name, - sizeof(channel->local_dev_name))) { - /* Only root can do this, and usually not fatal if it doesn't work, so */ - /* just continue on. */ + if (ares_strlen(channel->local_dev_name)) { + /* Only root can do this, and usually not fatal if it doesn't work, so + * just continue on. */ + (void)setsockopt(conn->fd, SOL_SOCKET, SO_BINDTODEVICE, + channel->local_dev_name, sizeof(channel->local_dev_name)); } #endif @@ -232,134 +427,217 @@ static int configure_socket(ares_socket_t s, struct server_state *server) bindlen = sizeof(local.sa6); } - if (bindlen && bind(s, &local.sa, bindlen) < 0) { - return -1; + if (bindlen && bind(conn->fd, &local.sa, bindlen) < 0) { + return ARES_ECONNREFUSED; } if (server->addr.family == AF_INET6) { - set_ipv6_v6only(s, 0); - } - - return 0; -} - -ares_status_t ares__open_connection(ares_channel_t *channel, - struct server_state *server, - ares_bool_t is_tcp) -{ - ares_socket_t s; - int opt; - ares_socklen_t salen; - - union { - struct sockaddr_in sa4; - struct sockaddr_in6 sa6; - } saddr; - struct sockaddr *sa; - struct server_connection *conn; - ares__llist_node_t *node; - int type = is_tcp ? SOCK_STREAM : SOCK_DGRAM; - - switch (server->addr.family) { - case AF_INET: - sa = (void *)&saddr.sa4; - salen = sizeof(saddr.sa4); - memset(sa, 0, (size_t)salen); - saddr.sa4.sin_family = AF_INET; - saddr.sa4.sin_port = htons(is_tcp ? server->tcp_port : server->udp_port); - memcpy(&saddr.sa4.sin_addr, &server->addr.addr.addr4, - sizeof(saddr.sa4.sin_addr)); - break; - case AF_INET6: - sa = (void *)&saddr.sa6; - salen = sizeof(saddr.sa6); - memset(sa, 0, (size_t)salen); - saddr.sa6.sin6_family = AF_INET6; - saddr.sa6.sin6_port = htons(is_tcp ? server->tcp_port : server->udp_port); - memcpy(&saddr.sa6.sin6_addr, &server->addr.addr.addr6, - sizeof(saddr.sa6.sin6_addr)); -#ifdef HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID - saddr.sa6.sin6_scope_id = server->ll_scope; -#endif - break; - default: - return ARES_EBADFAMILY; /* LCOV_EXCL_LINE */ - } - - /* Acquire a socket. */ - s = ares__open_socket(channel, server->addr.family, type, 0); - if (s == ARES_SOCKET_BAD) { - return ARES_ECONNREFUSED; + set_ipv6_v6only(conn->fd, 0); } - /* Configure it. */ - if (configure_socket(s, server) < 0) { - ares__close_socket(channel, s); - return ARES_ECONNREFUSED; - } + if (conn->flags & ARES_CONN_FLAG_TCP) { + int opt = 1; #ifdef TCP_NODELAY - if (is_tcp) { /* * Disable the Nagle algorithm (only relevant for TCP sockets, and thus not * in configure_socket). In general, in DNS lookups we're pretty much * interested in firing off a single request and then waiting for a reply, * so batching isn't very interesting. */ - opt = 1; - if ((!channel->sock_funcs || !channel->sock_funcs->asocket) && - setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (void *)&opt, sizeof(opt)) == - -1) { - ares__close_socket(channel, s); /* LCOV_EXCL_LINE: UntestablePath */ - return ARES_ECONNREFUSED; /* LCOV_EXCL_LINE: UntestablePath */ + if (setsockopt(conn->fd, IPPROTO_TCP, TCP_NODELAY, (void *)&opt, + sizeof(opt)) != 0) { + return ARES_ECONNREFUSED; } - } #endif - if (channel->sock_config_cb) { - int err = channel->sock_config_cb(s, type, channel->sock_config_cb_data); - if (err < 0) { - ares__close_socket(channel, s); - return ARES_ECONNREFUSED; +#if defined(TFO_CLIENT_SOCKOPT) + if (conn->flags & ARES_CONN_FLAG_TFO && + setsockopt(conn->fd, IPPROTO_TCP, TFO_CLIENT_SOCKOPT, (void *)&opt, + sizeof(opt)) != 0) { + /* Disable TFO if flag can't be set. */ + conn->flags &= ~((unsigned int)ARES_CONN_FLAG_TFO); } +#endif } - /* Connect to the server. */ - if (ares__connect_socket(channel, s, sa, salen) == -1) { - int err = SOCKERRNO; + return ARES_SUCCESS; +} - if (err != EINPROGRESS && err != EWOULDBLOCK) { - ares__close_socket(channel, s); - return ARES_ECONNREFUSED; +ares_bool_t ares_sockaddr_to_ares_addr(struct ares_addr *ares_addr, + unsigned short *port, + const struct sockaddr *sockaddr) +{ + if (sockaddr->sa_family == AF_INET) { + /* NOTE: memcpy sockaddr_in due to alignment issues found by UBSAN due to + * dnsinfo packing on MacOS */ + struct sockaddr_in sockaddr_in; + memcpy(&sockaddr_in, sockaddr, sizeof(sockaddr_in)); + + ares_addr->family = AF_INET; + memcpy(&ares_addr->addr.addr4, &(sockaddr_in.sin_addr), + sizeof(ares_addr->addr.addr4)); + + if (port) { + *port = ntohs(sockaddr_in.sin_port); } + return ARES_TRUE; } - if (channel->sock_create_cb) { - int err = channel->sock_create_cb(s, type, channel->sock_create_cb_data); - if (err < 0) { - ares__close_socket(channel, s); - return ARES_ECONNREFUSED; + if (sockaddr->sa_family == AF_INET6) { + /* NOTE: memcpy sockaddr_in6 due to alignment issues found by UBSAN due to + * dnsinfo packing on MacOS */ + struct sockaddr_in6 sockaddr_in6; + memcpy(&sockaddr_in6, sockaddr, sizeof(sockaddr_in6)); + + ares_addr->family = AF_INET6; + memcpy(&ares_addr->addr.addr6, &(sockaddr_in6.sin6_addr), + sizeof(ares_addr->addr.addr6)); + if (port) { + *port = ntohs(sockaddr_in6.sin6_port); } + return ARES_TRUE; } + return ARES_FALSE; +} + +static ares_status_t ares__conn_connect(ares_conn_t *conn, struct sockaddr *sa, + ares_socklen_t salen) +{ + /* Normal non TCPFastOpen style connect */ + if (!(conn->flags & ARES_CONN_FLAG_TFO)) { + return ares__connect_socket(conn->server->channel, conn->fd, sa, salen); + } + + /* FreeBSD don't want any sort of connect() so skip */ +#if defined(TFO_SKIP_CONNECT) && TFO_SKIP_CONNECT + return ARES_SUCCESS; +#elif defined(TFO_USE_CONNECTX) && TFO_USE_CONNECTX + { + int rv; + int err; + + do { + sa_endpoints_t endpoints; + memset(&endpoints, 0, sizeof(endpoints)); + endpoints.sae_dstaddr = sa; + endpoints.sae_dstaddrlen = salen; + + rv = connectx(conn->fd, &endpoints, SAE_ASSOCID_ANY, + CONNECT_DATA_IDEMPOTENT | CONNECT_RESUME_ON_READ_WRITE, + NULL, 0, NULL, NULL); + + err = SOCKERRNO; + if (rv == -1 && err != EINPROGRESS && err != EWOULDBLOCK) { + return ARES_ECONNREFUSED; + } + + } while (rv == -1 && err == EINTR); + } + return ARES_SUCCESS; +#elif defined(TFO_SUPPORTED) && TFO_SUPPORTED + return ares__connect_socket(conn->server->channel, conn->fd, sa, salen); +#else + /* Shouldn't be possible */ + return ARES_ECONNREFUSED; +#endif +} + +ares_status_t ares__open_connection(ares_conn_t **conn_out, + ares_channel_t *channel, + ares_server_t *server, ares_bool_t is_tcp) +{ + ares_status_t status; + struct sockaddr_storage sa_storage; + ares_socklen_t salen = sizeof(sa_storage); + struct sockaddr *sa = (struct sockaddr *)&sa_storage; + ares_conn_t *conn; + ares__llist_node_t *node = NULL; + int stype = is_tcp ? SOCK_STREAM : SOCK_DGRAM; + + *conn_out = NULL; + conn = ares_malloc(sizeof(*conn)); if (conn == NULL) { - ares__close_socket(channel, s); /* LCOV_EXCL_LINE: OutOfMemory */ - return ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ + return ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ } + memset(conn, 0, sizeof(*conn)); - conn->fd = s; + conn->fd = ARES_SOCKET_BAD; conn->server = server; conn->queries_to_conn = ares__llist_create(NULL); - conn->is_tcp = is_tcp; + conn->flags = is_tcp ? ARES_CONN_FLAG_TCP : ARES_CONN_FLAG_NONE; + + /* Enable TFO if the OS supports it and we were passed in data to send during + * the connect. It might be disabled later if an error is encountered. Make + * sure a user isn't overriding anything. */ + if (conn->flags & ARES_CONN_FLAG_TCP && channel->sock_funcs == NULL && + TFO_SUPPORTED) { + conn->flags |= ARES_CONN_FLAG_TFO; + } + if (conn->queries_to_conn == NULL) { /* LCOV_EXCL_START: OutOfMemory */ - ares__close_socket(channel, s); - ares_free(conn); - return ARES_ENOMEM; + status = ARES_ENOMEM; + goto done; /* LCOV_EXCL_STOP */ } + /* Convert into the struct sockaddr structure needed by the OS */ + status = ares__conn_set_sockaddr(conn, sa, &salen); + if (status != ARES_SUCCESS) { + goto done; + } + + /* Acquire a socket. */ + conn->fd = ares__open_socket(channel, server->addr.family, stype, 0); + if (conn->fd == ARES_SOCKET_BAD) { + status = ARES_ECONNREFUSED; + goto done; + } + + /* Configure it. */ + status = configure_socket(conn); + if (status != ARES_SUCCESS) { + goto done; + } + + if (channel->sock_config_cb) { + int err = + channel->sock_config_cb(conn->fd, stype, channel->sock_config_cb_data); + if (err < 0) { + status = ARES_ECONNREFUSED; + goto done; + } + } + + /* Connect */ + status = ares__conn_connect(conn, sa, salen); + if (status != ARES_SUCCESS) { + goto done; + } + + if (channel->sock_create_cb) { + int err = + channel->sock_create_cb(conn->fd, stype, channel->sock_create_cb_data); + if (err < 0) { + status = ARES_ECONNREFUSED; + goto done; + } + } + + /* Let the connection know we haven't written our first packet yet for TFO */ + if (conn->flags & ARES_CONN_FLAG_TFO) { + conn->flags |= ARES_CONN_FLAG_TFO_INITIAL; + } + + /* Need to store our own ip for DNS cookie support */ + status = ares_conn_set_self_ip(conn, ARES_FALSE); + if (status != ARES_SUCCESS) { + goto done; /* LCOV_EXCL_LINE: UntestablePath */ + } + /* TCP connections are thrown to the end as we don't spawn multiple TCP * connections. UDP connections are put on front where the newest connection * can be quickly pulled */ @@ -370,32 +648,36 @@ ares_status_t ares__open_connection(ares_channel_t *channel, } if (node == NULL) { /* LCOV_EXCL_START: OutOfMemory */ - ares__close_socket(channel, s); - ares__llist_destroy(conn->queries_to_conn); - ares_free(conn); - return ARES_ENOMEM; + status = ARES_ENOMEM; + goto done; /* LCOV_EXCL_STOP */ } /* Register globally to quickly map event on file descriptor to connection * node object */ - if (!ares__htable_asvp_insert(channel->connnode_by_socket, s, node)) { + if (!ares__htable_asvp_insert(channel->connnode_by_socket, conn->fd, node)) { /* LCOV_EXCL_START: OutOfMemory */ - ares__close_socket(channel, s); - ares__llist_destroy(conn->queries_to_conn); - ares__llist_node_claim(node); - ares_free(conn); - return ARES_ENOMEM; + status = ARES_ENOMEM; + goto done; /* LCOV_EXCL_STOP */ } - SOCK_STATE_CALLBACK(channel, s, 1, 0); + SOCK_STATE_CALLBACK(channel, conn->fd, 1, is_tcp ? 1 : 0); if (is_tcp) { server->tcp_conn = conn; } - return ARES_SUCCESS; +done: + if (status != ARES_SUCCESS) { + ares__llist_node_claim(node); + ares__llist_destroy(conn->queries_to_conn); + ares__close_socket(channel, conn->fd); + ares_free(conn); + } else { + *conn_out = conn; + } + return status; } ares_socket_t ares__open_socket(ares_channel_t *channel, int af, int type, @@ -409,15 +691,31 @@ ares_socket_t ares__open_socket(ares_channel_t *channel, int af, int type, return socket(af, type, protocol); } -int ares__connect_socket(ares_channel_t *channel, ares_socket_t sockfd, - const struct sockaddr *addr, ares_socklen_t addrlen) +ares_status_t ares__connect_socket(ares_channel_t *channel, + ares_socket_t sockfd, + const struct sockaddr *addr, + ares_socklen_t addrlen) { - if (channel->sock_funcs && channel->sock_funcs->aconnect) { - return channel->sock_funcs->aconnect(sockfd, addr, addrlen, + int rv; + int err; + + do { + if (channel->sock_funcs && channel->sock_funcs->aconnect) { + rv = channel->sock_funcs->aconnect(sockfd, addr, addrlen, channel->sock_func_cb_data); - } + } else { + rv = connect(sockfd, addr, addrlen); + } + + err = SOCKERRNO; + + if (rv == -1 && err != EINPROGRESS && err != EWOULDBLOCK) { + return ARES_ECONNREFUSED; + } - return connect(sockfd, addr, addrlen); + } while (rv == -1 && err == EINTR); + + return ARES_SUCCESS; } void ares__close_socket(ares_channel_t *channel, ares_socket_t s) @@ -433,26 +731,6 @@ void ares__close_socket(ares_channel_t *channel, ares_socket_t s) } } -#ifndef HAVE_WRITEV -/* Structure for scatter/gather I/O. */ -struct iovec { - void *iov_base; /* Pointer to data. */ - size_t iov_len; /* Length of data. */ -}; -#endif - -ares_ssize_t ares__socket_write(ares_channel_t *channel, ares_socket_t s, - const void *data, size_t len) -{ - if (channel->sock_funcs && channel->sock_funcs->asendv) { - struct iovec vec; - vec.iov_base = (void *)((size_t)data); /* Cast off const */ - vec.iov_len = len; - return channel->sock_funcs->asendv(s, &vec, 1, channel->sock_func_cb_data); - } - return swrite(s, data, len); -} - void ares_set_socket_callback(ares_channel_t *channel, ares_sock_create_callback cb, void *data) { diff --git a/deps/cares/src/lib/ares__sortaddrinfo.c b/deps/cares/src/lib/ares__sortaddrinfo.c index e9bca4e386d..1aab81ecf84 100644 --- a/deps/cares/src/lib/ares__sortaddrinfo.c +++ b/deps/cares/src/lib/ares__sortaddrinfo.c @@ -51,7 +51,6 @@ #include #include - struct addrinfo_sort_elem { struct ares_addrinfo_node *ai; ares_bool_t has_src_addr; @@ -347,7 +346,6 @@ static int find_src_addr(ares_channel_t *channel, const struct sockaddr *addr, struct sockaddr *src_addr) { ares_socket_t sock; - int ret; ares_socklen_t len; switch (addr->sa_family) { @@ -364,18 +362,14 @@ static int find_src_addr(ares_channel_t *channel, const struct sockaddr *addr, sock = ares__open_socket(channel, addr->sa_family, SOCK_DGRAM, IPPROTO_UDP); if (sock == ARES_SOCKET_BAD) { - if (errno == EAFNOSUPPORT) { + if (SOCKERRNO == EAFNOSUPPORT) { return 0; } else { return -1; } } - do { - ret = ares__connect_socket(channel, sock, addr, len); - } while (ret == -1 && errno == EINTR); - - if (ret == -1) { + if (ares__connect_socket(channel, sock, addr, len) != ARES_SUCCESS) { ares__close_socket(channel, sock); return 0; } diff --git a/deps/cares/src/lib/ares_android.c b/deps/cares/src/lib/ares_android.c index 67a9482d72e..06ab8940ad7 100644 --- a/deps/cares/src/lib/ares_android.c +++ b/deps/cares/src/lib/ares_android.c @@ -26,6 +26,8 @@ #if defined(ANDROID) || defined(__ANDROID__) # include "ares_private.h" # include +# include +# include "ares_android.h" static JavaVM *android_jvm = NULL; static jobject android_connectivity_manager = NULL; @@ -80,6 +82,23 @@ static jmethodID jni_get_method_id(JNIEnv *env, jclass cls, return mid; } +static int jvm_attach(JNIEnv **env) +{ + char name[17] = {0}; + + JavaVMAttachArgs args; + + args.version = JNI_VERSION_1_6; + if (prctl(PR_GET_NAME, name) == 0) { + args.name = name; + } else { + args.name = NULL; + } + args.group = NULL; + + return (*android_jvm)->AttachCurrentThread(android_jvm, env, &args); +} + void ares_library_init_jvm(JavaVM *jvm) { android_jvm = jvm; @@ -100,7 +119,7 @@ int ares_library_init_android(jobject connectivity_manager) res = (*android_jvm)->GetEnv(android_jvm, (void **)&env, JNI_VERSION_1_6); if (res == JNI_EDETACHED) { env = NULL; - res = (*android_jvm)->AttachCurrentThread(android_jvm, &env, NULL); + res = jvm_attach(&env); need_detatch = 1; } if (res != JNI_OK || env == NULL) { @@ -209,7 +228,7 @@ int ares_library_init_android(jobject connectivity_manager) (*android_jvm)->DetachCurrentThread(android_jvm); } - return ret; + return (int)ret; } int ares_library_android_initialized(void) @@ -233,7 +252,7 @@ void ares_library_cleanup_android(void) res = (*android_jvm)->GetEnv(android_jvm, (void **)&env, JNI_VERSION_1_6); if (res == JNI_EDETACHED) { env = NULL; - res = (*android_jvm)->AttachCurrentThread(android_jvm, &env, NULL); + res = jvm_attach(&env); need_detatch = 1; } if (res != JNI_OK || env == NULL) { @@ -285,7 +304,7 @@ char **ares_get_android_server_list(size_t max_servers, size_t *num_servers) res = (*android_jvm)->GetEnv(android_jvm, (void **)&env, JNI_VERSION_1_6); if (res == JNI_EDETACHED) { env = NULL; - res = (*android_jvm)->AttachCurrentThread(android_jvm, &env, NULL); + res = jvm_attach(&env); need_detatch = 1; } if (res != JNI_OK || env == NULL) { @@ -403,7 +422,7 @@ char *ares_get_android_search_domains_list(void) res = (*android_jvm)->GetEnv(android_jvm, (void **)&env, JNI_VERSION_1_6); if (res == JNI_EDETACHED) { env = NULL; - res = (*android_jvm)->AttachCurrentThread(android_jvm, &env, NULL); + res = jvm_attach(&env); need_detatch = 1; } if (res != JNI_OK || env == NULL) { diff --git a/deps/cares/src/lib/ares_cancel.c b/deps/cares/src/lib/ares_cancel.c index 4312b5e188e..c29d8ef82f4 100644 --- a/deps/cares/src/lib/ares_cancel.c +++ b/deps/cares/src/lib/ares_cancel.c @@ -59,7 +59,7 @@ void ares_cancel(ares_channel_t *channel) node = ares__llist_node_first(list_copy); while (node != NULL) { - struct query *query; + ares_query_t *query; /* Cache next since this node is being deleted */ next = ares__llist_node_next(node); diff --git a/deps/cares/src/lib/ares_config.h.cmake b/deps/cares/src/lib/ares_config.h.cmake index cafdadd9bbc..da738671971 100644 --- a/deps/cares/src/lib/ares_config.h.cmake +++ b/deps/cares/src/lib/ares_config.h.cmake @@ -67,6 +67,9 @@ /* Define to 1 if you have the connect function. */ #cmakedefine HAVE_CONNECT 1 +/* Define to 1 if you have the connectx function. */ +#cmakedefine HAVE_CONNECTX 1 + /* define if the compiler supports basic C++11 syntax */ #cmakedefine HAVE_CXX11 1 @@ -145,6 +148,12 @@ /* Define to 1 if you have the `ConvertInterfaceLuidToNameA' function. */ #cmakedefine HAVE_CONVERTINTERFACELUIDTONAMEA 1 +/* Define to 1 if you have the `NotifyIpInterfaceChange' function. */ +#cmakedefine HAVE_NOTIFYIPINTERFACECHANGE 1 + +/* Define to 1 if you have the `RegisterWaitForSingleObject' function. */ +#cmakedefine HAVE_REGISTERWAITFORSINGLEOBJECT 1 + /* Define to 1 if you have a IPv6 capable working inet_net_pton function. */ #cmakedefine HAVE_INET_NET_PTON 1 diff --git a/deps/cares/src/lib/ares_config.h.in b/deps/cares/src/lib/ares_config.h.in index 0a4aa069580..3e75b4c2cd0 100644 --- a/deps/cares/src/lib/ares_config.h.in +++ b/deps/cares/src/lib/ares_config.h.in @@ -75,6 +75,9 @@ /* Define to 1 if you have `connect` */ #undef HAVE_CONNECT +/* Define to 1 if you have `connectx` */ +#undef HAVE_CONNECTX + /* Define to 1 if you have `ConvertInterfaceIndexToLuid` */ #undef HAVE_CONVERTINTERFACEINDEXTOLUID @@ -201,6 +204,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_NET_IF_H +/* Define to 1 if you have `NotifyIpInterfaceChange` */ +#undef HAVE_NOTIFYIPINTERFACECHANGE + /* Define to 1 if you have the header file. */ #undef HAVE_NTDEF_H @@ -237,6 +243,9 @@ /* Define to 1 if you have `recvfrom` */ #undef HAVE_RECVFROM +/* Define to 1 if you have `RegisterWaitForSingleObject` */ +#undef HAVE_REGISTERWAITFORSINGLEOBJECT + /* Define to 1 if you have `send` */ #undef HAVE_SEND diff --git a/deps/cares/src/lib/ares_cookie.c b/deps/cares/src/lib/ares_cookie.c new file mode 100644 index 00000000000..bf9d1ba25da --- /dev/null +++ b/deps/cares/src/lib/ares_cookie.c @@ -0,0 +1,460 @@ +/* MIT License + * + * Copyright (c) 2024 Brad House + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * SPDX-License-Identifier: MIT + */ + +/* DNS cookies are a simple form of learned mutual authentication supported by + * most DNS server implementations these days and can help prevent DNS Cache + * Poisoning attacks for clients and DNS amplification attacks for servers. + * + * A good overview is here: + * https://www.dotmagazine.online/issues/digital-responsibility-and-sustainability/dns-cookies-transaction-mechanism + * + * RFCs used for implementation are + * [RFC7873](https://datatracker.ietf.org/doc/html/rfc7873) which is extended by + * [RFC9018](https://datatracker.ietf.org/doc/html/rfc9018). + * + * Though this could be used on TCP, the likelihood of it being useful is small + * and could cause some issues. TCP is better used as a fallback in case there + * are issues with DNS Cookie support in the upstream servers (e.g. AnyCast + * cluster issues). + * + * While most recursive DNS servers support DNS Cookies, public DNS servers like + * Google (8.8.8.8, 8.8.4.4) and CloudFlare (1.1.1.1, 1.0.0.1) don't seem to + * have this enabled yet for unknown reasons. + * + * The risk to having DNS Cookie support always enabled is nearly zero as there + * is built-in detection support and it will simply bypass using cookies if the + * remote server doesn't support it. The problem arises if a remote server + * supports DNS cookies, then stops supporting them (such as if an administrator + * reconfigured the server, or maybe there are different servers in a cluster + * with different configurations). We need to detect this behavior by tracking + * how much time has gone by since we received our last valid cookie reply, and + * if we exceed the threshold, reset all cookie parameters like we haven't + * attempted a request yet. + * + * ## Implementation Plan + * + * ### Constants: + * - `COOKIE_CLIENT_TIMEOUT`: 86400s (1 day) + * - How often to regenerate the per-server client cookie, even if our + * source ip address hasn't changed. + * - `COOKIE_UNSUPPORTED_TIMEOUT`: 300s (5 minutes) + * - If a server responds without a cookie in the reply, this is how long to + * wait before attempting to send a client cookie again. + * - `COOKIE_REGRESSION_TIMEOUT`: 120s (2 minutes) + * - If a server was once known to return cookies, and all of a sudden stops + * returning cookies (but the reply is otherwise valid), this is how long + * to continue to attempt to use cookies before giving up and resetting. + * Such an event would cause an outage for this duration, but since a + * cache poisoning attack should be dropping invalid replies we should be + * able to still get the valid reply and not assume it is a server + * regression just because we received replies without cookies. + * - `COOKIE_RESEND_MAX`: 3 + * - Maximum times to resend a query to a server due to the server responding + * with `BAD_COOKIE`, after this, we switch to TCP. + * + * ### Per-server variables: + * - `cookie.state`: Known state of cookie support, enumeration. + * - `INITIAL` (0): Initial state, not yet determined. Used during startup. + * - `GENERATED` (1): Cookie has been generated and sent to a server, but no + * validated response yet. + * - `SUPPORTED` (2): Server has been determined to properly support cookies + * - `UNSUPPORTED` (3): Server has been determined to not support cookies + * - `cookie.client` : 8 byte randomly generated client cookie + * - `cookie.client_ts`: Timestamp client cookie was generated + * - `cookie.client_ip`: IP address client used to connect to server + * - `cookie.server`: 8 to 32 byte server cookie + * - `cookie.server_len`: length of server cookie + * - `cookie.unsupported_ts`: Timestamp of last attempt to use a cookies, but + * it was determined that the server didn't support them. + * + * ### Per-query variables: + * - `query.client_cookie`: Duplicate of `cookie.client` at the point in time + * the query is put on the wire. This should be available in the + * `ares_dns_record_t` for the request for verification purposes so we don't + * actually need to duplicate this, just naming it here for the ease of + * documentation below. + * - `query.cookie_try_count`: Number of tries to send a cookie but receive + * `BAD_COOKIE` responses. Used to know when we need to switch to TCP. + * + * ### Procedure: + * **NOTE**: These steps will all be done after obtaining a connection handle as + * some of these steps depend on determining the source ip address for the + * connection. + * + * 1. If the query is not using EDNS, then **skip any remaining processing**. + * 2. If using TCP, ensure there is no EDNS cookie opt (10) set (there may have + * been if this is a resend after upgrade to TCP), then **skip any remaining + * processing**. + * 3. If `cookie.state == SUPPORTED`, `cookie.unsupported_ts` is non-zero, and + * evaluates greater than `COOKIE_REGRESSION_TIMEOUT`, then clear all cookie + * settings, set `cookie.state = INITIAL`. Continue to next step (4) + * 4. If `cookie.state == UNSUPPORTED` + * - If `cookie.unsupported_ts` evaluates less than + * `COOKIE_UNSUPPORTED_TIMEOUT` + * - Ensure there is no EDNS cookie opt (10) set (shouldn't be unless + * requestor had put this themselves), then **skip any remaining + * processing** as we don't want to try to send cookies. + * - Otherwise: + * - clear all cookie settings, set `cookie.state = INITIAL`. + * - Continue to next step (5) which will send a new cookie. + * 5. If `cookie.state == INITIAL`: + * - randomly generate new `cookie.client` + * - set `cookie.client_ts` to the current timestamp. + * - set `cookie.state = GENERATED`. + * - set `cookie.client_ip` to the current source ip address. + * 6. If `cookie.state == GENERATED || cookie.state == SUPPORTED` and + * `cookie.client_ip` does not match the current source ip address: + * - clear `cookie.server` + * - randomly generate new `cookie.client` + * - set `cookie.client_ts` to the current timestamp. + * - set `cookie.client_ip` to the current source ip address. + * - do not change the `cookie.state` + * 7. If `cookie.state == SUPPORTED` and `cookie.client_ts` evaluation exceeds + * `COOKIE_CLIENT_TIMEOUT`: + * - clear `cookie.server` + * - randomly generate new `cookie.client` + * - set `cookie.client_ts` to the current timestamp. + * - set `cookie.client_ip` to the current source ip address. + * - do not change the `cookie.state` + * 8. Generate EDNS OPT record (10) for client cookie. The option value will be + * the `cookie.client` concatenated with the `cookie.server`. If there is no + * known server cookie, it will not be appended. Copy `cookie.client` to + * `query.client_cookie` to handle possible client cookie changes by other + * queries before a reply is received (technically this is in the cached + * `ares_dns_record_t` so no need to manually do this). Send request to + * server. + * 9. Evaluate response: + * 1. If invalid EDNS OPT cookie (10) length sent back in response (valid + * length is 16-40), or bad client cookie value (validate first 8 bytes + * against `query.client_cookie` not `cookie.client`), **drop response** + * as if it hadn't been received. This is likely a spoofing attack. + * Wait for valid response up to normal response timeout. + * 2. If a EDNS OPT cookie (10) server cookie is returned: + * - set `cookie.unsupported_ts` to zero and `cookie.state = SUPPORTED`. + * We can confirm this server supports cookies based on the existence + * of this record. + * - If a new EDNS OPT cookie (10) server cookie is in the response, and + * the `client.cookie` matches the `query.client_cookie` still (hasn't + * been rotated by some other parallel query), save it as + * `cookie.server`. + * 3. If dns response `rcode` is `BAD_COOKIE`: + * - Ensure a EDNS OPT cookie (10) is returned, otherwise **drop + * response**, this is completely invalid and likely an spoof of some + * sort. + * - Otherwise + * - Increment `query.cookie_try_count` + * - If `query.cookie_try_count >= COOKIE_RESEND_MAX`, set + * `query.using_tcp` to force the next attempt to use TCP. + * - **Requeue the query**, but do not increment the normal + * `try_count` as a `BAD_COOKIE` reply isn't a normal try failure. + * This should end up going all the way back to step 1 on the next + * attempt. + * 4. If EDNS OPT cookie (10) is **NOT** returned in the response: + * - If `cookie.state == SUPPORTED` + * - if `cookie.unsupported_ts` is zero, set to the current timestamp. + * - Drop the response, wait for a valid response to be returned + * - if `cookie.state == GENERATED` + * - clear all cookie settings + * - set `cookie.state = UNSUPPORTED` + * - set `cookie.unsupported_ts` to the current time + * - Accept response (state should be `UNSUPPORTED` if we're here) + */ + +#include "ares_private.h" + +/* 1 day */ +#define COOKIE_CLIENT_TIMEOUT_MS (86400 * 1000) + +/* 5 minutes */ +#define COOKIE_UNSUPPORTED_TIMEOUT_MS (300 * 1000) + +/* 2 minutes */ +#define COOKIE_REGRESSION_TIMEOUT_MS (120 * 1000) + +#define COOKIE_RESEND_MAX 3 + +static const unsigned char * + ares_dns_cookie_fetch(const ares_dns_record_t *dnsrec, size_t *len) +{ + const ares_dns_rr_t *rr = ares_dns_get_opt_rr_const(dnsrec); + const unsigned char *val = NULL; + *len = 0; + + if (rr == NULL) { + return NULL; + } + + if (!ares_dns_rr_get_opt_byid(rr, ARES_RR_OPT_OPTIONS, ARES_OPT_PARAM_COOKIE, + &val, len)) { + return NULL; + } + + return val; +} + +static ares_bool_t timeval_is_set(const ares_timeval_t *tv) +{ + if (tv->sec != 0 && tv->usec != 0) { + return ARES_TRUE; + } + return ARES_FALSE; +} + +static ares_bool_t timeval_expired(const ares_timeval_t *tv, + const ares_timeval_t *now, + unsigned long millsecs) +{ + ares_int64_t tvdiff_ms; + ares_timeval_t tvdiff; + ares__timeval_diff(&tvdiff, tv, now); + + tvdiff_ms = tvdiff.sec * 1000 + tvdiff.usec / 1000; + if (tvdiff_ms >= (ares_int64_t)millsecs) { + return ARES_TRUE; + } + return ARES_FALSE; +} + +static void ares_cookie_clear(ares_cookie_t *cookie) +{ + memset(cookie, 0, sizeof(*cookie)); + cookie->state = ARES_COOKIE_INITIAL; +} + +static void ares_cookie_generate(ares_cookie_t *cookie, ares_conn_t *conn, + const ares_timeval_t *now) +{ + ares_channel_t *channel = conn->server->channel; + + ares__rand_bytes(channel->rand_state, cookie->client, sizeof(cookie->client)); + memcpy(&cookie->client_ts, now, sizeof(cookie->client_ts)); + memcpy(&cookie->client_ip, &conn->self_ip, sizeof(cookie->client_ip)); +} + +static void ares_cookie_clear_server(ares_cookie_t *cookie) +{ + memset(cookie->server, 0, sizeof(cookie->server)); + cookie->server_len = 0; +} + +static ares_bool_t ares_addr_equal(const struct ares_addr *addr1, + const struct ares_addr *addr2) +{ + if (addr1->family != addr2->family) { + return ARES_FALSE; + } + + switch (addr1->family) { + case AF_INET: + if (memcmp(&addr1->addr.addr4, &addr2->addr.addr4, + sizeof(addr1->addr.addr4)) == 0) { + return ARES_TRUE; + } + break; + case AF_INET6: + /* This structure is weird, and due to padding SonarCloud complains if + * you don't punch all the way down. At some point we should rework + * this structure */ + if (memcmp(&addr1->addr.addr6._S6_un._S6_u8, + &addr2->addr.addr6._S6_un._S6_u8, + sizeof(addr1->addr.addr6._S6_un._S6_u8)) == 0) { + return ARES_TRUE; + } + break; + default: + break; /* LCOV_EXCL_LINE */ + } + + return ARES_FALSE; +} + +ares_status_t ares_cookie_apply(ares_dns_record_t *dnsrec, ares_conn_t *conn, + const ares_timeval_t *now) +{ + ares_server_t *server = conn->server; + ares_cookie_t *cookie = &server->cookie; + ares_dns_rr_t *rr = ares_dns_get_opt_rr(dnsrec); + unsigned char c[40]; + size_t c_len; + + /* If there is no OPT record, then EDNS isn't supported, and therefore + * cookies can't be supported */ + if (rr == NULL) { + return ARES_SUCCESS; + } + + /* No cookies on TCP, make sure we remove one if one is present */ + if (conn->flags & ARES_CONN_FLAG_TCP) { + ares_dns_rr_del_opt_byid(rr, ARES_RR_OPT_OPTIONS, ARES_OPT_PARAM_COOKIE); + return ARES_SUCCESS; + } + + /* Look for regression */ + if (cookie->state == ARES_COOKIE_SUPPORTED && + timeval_is_set(&cookie->unsupported_ts) && + timeval_expired(&cookie->unsupported_ts, now, + COOKIE_REGRESSION_TIMEOUT_MS)) { + ares_cookie_clear(cookie); + } + + /* Handle unsupported state */ + if (cookie->state == ARES_COOKIE_UNSUPPORTED) { + /* If timer hasn't expired, just delete any possible cookie and return */ + if (!timeval_expired(&cookie->unsupported_ts, now, + COOKIE_REGRESSION_TIMEOUT_MS)) { + ares_dns_rr_del_opt_byid(rr, ARES_RR_OPT_OPTIONS, ARES_OPT_PARAM_COOKIE); + return ARES_SUCCESS; + } + + /* We want to try to "learn" again */ + ares_cookie_clear(cookie); + } + + /* Generate a new cookie */ + if (cookie->state == ARES_COOKIE_INITIAL) { + ares_cookie_generate(cookie, conn, now); + cookie->state = ARES_COOKIE_GENERATED; + } + + /* Regenerate the cookie and clear the server cookie if the client ip has + * changed */ + if ((cookie->state == ARES_COOKIE_GENERATED || + cookie->state == ARES_COOKIE_SUPPORTED) && + !ares_addr_equal(&conn->self_ip, &cookie->client_ip)) { + ares_cookie_clear_server(cookie); + ares_cookie_generate(cookie, conn, now); + } + + /* If the client cookie has reached its maximum time, refresh it */ + if (cookie->state == ARES_COOKIE_SUPPORTED && + timeval_expired(&cookie->client_ts, now, COOKIE_CLIENT_TIMEOUT_MS)) { + ares_cookie_clear_server(cookie); + ares_cookie_generate(cookie, conn, now); + } + + /* Generate the full cookie which is the client cookie concatenated with the + * server cookie (if there is one) and apply it. */ + memcpy(c, cookie->client, sizeof(cookie->client)); + if (cookie->server_len) { + memcpy(c + sizeof(cookie->client), cookie->server, cookie->server_len); + } + c_len = sizeof(cookie->client) + cookie->server_len; + + return ares_dns_rr_set_opt(rr, ARES_RR_OPT_OPTIONS, ARES_OPT_PARAM_COOKIE, c, + c_len); +} + +ares_status_t ares_cookie_validate(ares_query_t *query, + const ares_dns_record_t *dnsresp, + ares_conn_t *conn, const ares_timeval_t *now) +{ + ares_server_t *server = conn->server; + ares_cookie_t *cookie = &server->cookie; + const ares_dns_record_t *dnsreq = query->query; + const unsigned char *resp_cookie; + size_t resp_cookie_len; + const unsigned char *req_cookie; + size_t req_cookie_len; + + resp_cookie = ares_dns_cookie_fetch(dnsresp, &resp_cookie_len); + + /* Invalid cookie length, drop */ + if (resp_cookie && (resp_cookie_len < 8 || resp_cookie_len > 40)) { + return ARES_EBADRESP; + } + + req_cookie = ares_dns_cookie_fetch(dnsreq, &req_cookie_len); + + /* Didn't request cookies, so we can stop evaluating */ + if (req_cookie == NULL) { + return ARES_SUCCESS; + } + + /* If 8-byte prefix for returned cookie doesn't match the requested cookie, + * drop for spoofing */ + if (resp_cookie && memcmp(req_cookie, resp_cookie, 8) != 0) { + return ARES_EBADRESP; + } + + if (resp_cookie && resp_cookie_len > 8) { + /* Make sure we record that we successfully received a cookie response */ + cookie->state = ARES_COOKIE_SUPPORTED; + memset(&cookie->unsupported_ts, 0, sizeof(cookie->unsupported_ts)); + + /* If client cookie hasn't been rotated, save the returned server cookie */ + if (memcmp(cookie->client, req_cookie, sizeof(cookie->client)) == 0) { + cookie->server_len = resp_cookie_len - 8; + memcpy(cookie->server, resp_cookie + 8, cookie->server_len); + } + } + + if (ares_dns_record_get_rcode(dnsresp) == ARES_RCODE_BADCOOKIE) { + /* Illegal to return BADCOOKIE but no cookie, drop */ + if (resp_cookie == NULL) { + return ARES_EBADRESP; + } + + /* If we have too many attempts to send a cookie, we need to requeue as + * tcp */ + query->cookie_try_count++; + if (query->cookie_try_count >= COOKIE_RESEND_MAX) { + query->using_tcp = ARES_TRUE; + } + + /* Resend the request, hopefully it will work the next time as we should + * have recorded a server cookie */ + ares__requeue_query(query, now, ARES_SUCCESS, + ARES_FALSE /* Don't increment try count */, + NULL); + + /* Parent needs to drop this response */ + return ARES_EBADRESP; + } + + /* We've got a response with a server cookie, and we've done all the + * evaluation we can, return success */ + if (resp_cookie_len > 8) { + return ARES_SUCCESS; + } + + if (cookie->state == ARES_COOKIE_SUPPORTED) { + /* If we're not currently tracking an error time yet, start */ + if (!timeval_is_set(&cookie->unsupported_ts)) { + memcpy(&cookie->unsupported_ts, now, sizeof(cookie->unsupported_ts)); + } + /* Drop it since we expected a cookie */ + return ARES_EBADRESP; + } + + if (cookie->state == ARES_COOKIE_GENERATED) { + ares_cookie_clear(cookie); + cookie->state = ARES_COOKIE_UNSUPPORTED; + memcpy(&cookie->unsupported_ts, now, sizeof(cookie->unsupported_ts)); + } + + /* Cookie state should be UNSUPPORTED if we're here */ + return ARES_SUCCESS; +} diff --git a/deps/cares/src/lib/ares_destroy.c b/deps/cares/src/lib/ares_destroy.c index 1be42b1dec1..d75b5e227cc 100644 --- a/deps/cares/src/lib/ares_destroy.c +++ b/deps/cares/src/lib/ares_destroy.c @@ -26,7 +26,7 @@ */ #include "ares_private.h" -#include "ares_event.h" +#include "event/ares_event.h" #include void ares_destroy(ares_channel_t *channel) @@ -73,7 +73,7 @@ void ares_destroy(ares_channel_t *channel) node = ares__llist_node_first(channel->all_queries); while (node != NULL) { ares__llist_node_t *next = ares__llist_node_next(node); - struct query *query = ares__llist_node_claim(node); + ares_query_t *query = ares__llist_node_claim(node); query->node_all_queries = NULL; query->callback(query->arg, ARES_EDESTRUCTION, 0, NULL); @@ -134,7 +134,7 @@ void ares_destroy(ares_channel_t *channel) ares_free(channel); } -void ares__destroy_server(struct server_state *server) +void ares__destroy_server(ares_server_t *server) { if (server == NULL) { return; /* LCOV_EXCL_LINE: DefensiveCoding */ @@ -152,7 +152,7 @@ void ares__destroy_servers_state(ares_channel_t *channel) ares__slist_node_t *node; while ((node = ares__slist_node_first(channel->servers)) != NULL) { - struct server_state *server = ares__slist_node_claim(node); + ares_server_t *server = ares__slist_node_claim(node); ares__destroy_server(server); } diff --git a/deps/cares/src/lib/ares_getaddrinfo.c b/deps/cares/src/lib/ares_getaddrinfo.c index 8a195ed0220..713acf744a0 100644 --- a/deps/cares/src/lib/ares_getaddrinfo.c +++ b/deps/cares/src/lib/ares_getaddrinfo.c @@ -252,7 +252,7 @@ static ares_bool_t fake_addrinfo(const char *name, unsigned short port, ares_bool_t valid = ARES_TRUE; const char *p; for (p = name; *p; p++) { - if (!isdigit(*p) && *p != '.') { + if (!ares__isdigit(*p) && *p != '.') { valid = ARES_FALSE; break; } else if (*p == '.') { @@ -469,7 +469,7 @@ static void terminate_retries(const struct host_query *hquery, unsigned short term_qid = (qid == hquery->qid_a) ? hquery->qid_aaaa : hquery->qid_a; const ares_channel_t *channel = hquery->channel; - struct query *query = NULL; + ares_query_t *query = NULL; /* No other outstanding queries, nothing to do */ if (!hquery->remaining) { @@ -528,6 +528,13 @@ static void host_callback(void *arg, ares_status_t status, size_t timeouts, hquery->nodata_cnt++; } next_lookup(hquery, hquery->nodata_cnt ? ARES_ENODATA : status); + } else if ( + (status == ARES_ESERVFAIL || status == ARES_EREFUSED) && + ares__name_label_cnt(hquery->names[hquery->next_name_idx-1]) == 1 + ) { + /* Issue #852, systemd-resolved may return SERVFAIL or REFUSED on a + * single label domain name. */ + next_lookup(hquery, hquery->nodata_cnt ? ARES_ENODATA : status); } else { end_hquery(hquery, status); } diff --git a/deps/cares/src/lib/ares_init.c b/deps/cares/src/lib/ares_init.c index cc7b85d783e..6dc5f4f9353 100644 --- a/deps/cares/src/lib/ares_init.c +++ b/deps/cares/src/lib/ares_init.c @@ -63,7 +63,7 @@ #include "ares_inet_net_pton.h" #include "ares_platform.h" -#include "ares_event.h" +#include "event/ares_event.h" int ares_init(ares_channel_t **channelptr) { @@ -72,8 +72,8 @@ int ares_init(ares_channel_t **channelptr) static int ares_query_timeout_cmp_cb(const void *arg1, const void *arg2) { - const struct query *q1 = arg1; - const struct query *q2 = arg2; + const ares_query_t *q1 = arg1; + const ares_query_t *q2 = arg2; if (q1->timeout.sec > q2->timeout.sec) { return 1; @@ -94,8 +94,8 @@ static int ares_query_timeout_cmp_cb(const void *arg1, const void *arg2) static int server_sort_cb(const void *data1, const void *data2) { - const struct server_state *s1 = data1; - const struct server_state *s2 = data2; + const ares_server_t *s1 = data1; + const ares_server_t *s2 = data2; if (s1->consec_failures < s2->consec_failures) { return -1; diff --git a/deps/cares/src/lib/ares_metrics.c b/deps/cares/src/lib/ares_metrics.c index 78f93bc1b7d..0e22fc37e7c 100644 --- a/deps/cares/src/lib/ares_metrics.c +++ b/deps/cares/src/lib/ares_metrics.c @@ -145,7 +145,7 @@ static time_t ares_metric_timestamp(ares_server_bucket_t bucket, return (time_t)(now->sec / divisor); } -void ares_metrics_record(const struct query *query, struct server_state *server, +void ares_metrics_record(const ares_query_t *query, ares_server_t *server, ares_status_t status, const ares_dns_record_t *dnsrec) { ares_timeval_t now; @@ -170,7 +170,7 @@ void ares_metrics_record(const struct query *query, struct server_state *server, } ares__timeval_diff(&tvdiff, &query->ts, &now); - query_ms = (unsigned int)(tvdiff.sec + (tvdiff.usec / 1000)); + query_ms = (unsigned int)((tvdiff.sec * 1000) + (tvdiff.usec / 1000)); if (query_ms == 0) { query_ms = 1; } @@ -205,8 +205,8 @@ void ares_metrics_record(const struct query *query, struct server_state *server, } } -size_t ares_metrics_server_timeout(const struct server_state *server, - const ares_timeval_t *now) +size_t ares_metrics_server_timeout(const ares_server_t *server, + const ares_timeval_t *now) { const ares_channel_t *channel = server->channel; ares_server_bucket_t i; @@ -252,7 +252,7 @@ size_t ares_metrics_server_timeout(const struct server_state *server, } /* don't go above upper bounds */ - max_timeout_ms = channel->maxtimeout?channel->maxtimeout:MAX_TIMEOUT_MS; + max_timeout_ms = channel->maxtimeout ? channel->maxtimeout : MAX_TIMEOUT_MS; if (timeout_ms > max_timeout_ms) { timeout_ms = max_timeout_ms; } diff --git a/deps/cares/src/lib/ares_options.c b/deps/cares/src/lib/ares_options.c index 19ddf6d8ca1..9aeb4bad3d7 100644 --- a/deps/cares/src/lib/ares_options.c +++ b/deps/cares/src/lib/ares_options.c @@ -66,7 +66,7 @@ static struct in_addr *ares_save_opt_servers(const ares_channel_t *channel, for (snode = ares__slist_node_first(channel->servers); snode != NULL; snode = ares__slist_node_next(snode)) { - const struct server_state *server = ares__slist_node_val(snode); + const ares_server_t *server = ares__slist_node_val(snode); if (server->addr.family != AF_INET) { continue; diff --git a/deps/cares/src/lib/ares_private.h b/deps/cares/src/lib/ares_private.h index 5506416d8ef..263c2a606d3 100644 --- a/deps/cares/src/lib/ares_private.h +++ b/deps/cares/src/lib/ares_private.h @@ -105,33 +105,34 @@ W32_FUNC const char *_w32_GetHostsFile(void); struct ares_rand_state; typedef struct ares_rand_state ares_rand_state; -#include "ares__llist.h" -#include "ares__slist.h" -#include "ares__htable_strvp.h" -#include "ares__htable_szvp.h" -#include "ares__htable_asvp.h" -#include "ares__htable_vpvp.h" -#include "ares_dns_multistring.h" -#include "ares__buf.h" -#include "ares_dns_private.h" -#include "ares__iface_ips.h" -#include "ares__threads.h" +#include "dsa/ares__array.h" +#include "dsa/ares__llist.h" +#include "dsa/ares__slist.h" +#include "dsa/ares__htable_strvp.h" +#include "dsa/ares__htable_szvp.h" +#include "dsa/ares__htable_asvp.h" +#include "dsa/ares__htable_vpvp.h" +#include "record/ares_dns_multistring.h" +#include "str/ares__buf.h" +#include "record/ares_dns_private.h" +#include "util/ares__iface_ips.h" +#include "util/ares__threads.h" #ifndef HAVE_GETENV # include "ares_getenv.h" # define getenv(ptr) ares_getenv(ptr) #endif -#include "ares_str.h" -#include "ares_strsplit.h" +#include "str/ares_str.h" +#include "str/ares_strsplit.h" #ifndef HAVE_STRCASECMP -# include "ares_strcasecmp.h" +# include "str/ares_strcasecmp.h" # define strcasecmp(p1, p2) ares_strcasecmp(p1, p2) #endif #ifndef HAVE_STRNCASECMP -# include "ares_strcasecmp.h" +# include "str/ares_strcasecmp.h" # define strncasecmp(p1, p2, n) ares_strncasecmp(p1, p2, n) #endif @@ -150,18 +151,36 @@ typedef struct ares_rand_state ares_rand_state; #define DEFAULT_SERVER_RETRY_CHANCE 10 #define DEFAULT_SERVER_RETRY_DELAY 5000 -struct query; +struct ares_query; +typedef struct ares_query ares_query_t; -struct server_state; +struct ares_server; +typedef struct ares_server ares_server_t; -struct server_connection { - struct server_state *server; - ares_socket_t fd; - ares_bool_t is_tcp; +struct ares_conn; +typedef struct ares_conn ares_conn_t; + +typedef enum { + /*! No flags */ + ARES_CONN_FLAG_NONE = 0, + /*! TCP connection, not UDP */ + ARES_CONN_FLAG_TCP = 1 << 0, + /*! TCP Fast Open is enabled and being used if supported by the OS */ + ARES_CONN_FLAG_TFO = 1 << 1, + /*! TCP Fast Open has not yet sent its first packet. Gets unset on first + * write to a connection */ + ARES_CONN_FLAG_TFO_INITIAL = 1 << 2 +} ares_conn_flags_t; + +struct ares_conn { + ares_server_t *server; + ares_socket_t fd; + struct ares_addr self_ip; + ares_conn_flags_t flags; /* total number of queries run on this connection since it was established */ - size_t total_queries; + size_t total_queries; /* list of outstanding queries to this connection */ - ares__llist_t *queries_to_conn; + ares__llist_t *queries_to_conn; }; #ifdef _MSC_VER @@ -204,70 +223,104 @@ typedef struct { ares_uint64_t prev_total_count; /*!< Previous period bucket query count */ } ares_server_metrics_t; -struct server_state { +typedef enum { + ARES_COOKIE_INITIAL = 0, + ARES_COOKIE_GENERATED = 1, + ARES_COOKIE_SUPPORTED = 2, + ARES_COOKIE_UNSUPPORTED = 3 +} ares_cookie_state_t; + +/*! Structure holding tracking data for RFC 7873/9018 DNS cookies. + * Implementation plan for this feature is here: + * https://github.com/c-ares/c-ares/issues/620 + */ +typedef struct { + /*! starts at INITIAL, transitions as needed. */ + ares_cookie_state_t state; + /*! randomly-generate client cookie */ + unsigned char client[8]; + /*! timestamp client cookie was generated, used for rotation purposes */ + ares_timeval_t client_ts; + /*! IP address last used for client to connect to server. If this changes + * The client cookie gets invalidated */ + struct ares_addr client_ip; + /*! Server Cookie last received, 8-32 bytes in length */ + unsigned char server[32]; + /*! Length of server cookie on file. */ + size_t server_len; + /*! Timestamp of last attempt to use cookies, but it was determined that the + * server didn't support them */ + ares_timeval_t unsupported_ts; +} ares_cookie_t; + +struct ares_server { /* Configuration */ - size_t idx; /* index for server in system configuration */ - struct ares_addr addr; - unsigned short udp_port; /* host byte order */ - unsigned short tcp_port; /* host byte order */ - char ll_iface[64]; /* IPv6 Link Local Interface */ - unsigned int ll_scope; /* IPv6 Link Local Scope */ - - size_t consec_failures; /* Consecutive query failure count - * can be hard errors or timeouts - */ - ares__llist_t *connections; - struct server_connection *tcp_conn; + size_t idx; /* index for server in system configuration */ + struct ares_addr addr; + unsigned short udp_port; /* host byte order */ + unsigned short tcp_port; /* host byte order */ + char ll_iface[64]; /* IPv6 Link Local Interface */ + unsigned int ll_scope; /* IPv6 Link Local Scope */ + + size_t consec_failures; /* Consecutive query failure count + * can be hard errors or timeouts + */ + ares__llist_t *connections; + ares_conn_t *tcp_conn; /* The next time when we will retry this server if it has hit failures */ - ares_timeval_t next_retry_time; + ares_timeval_t next_retry_time; /* TCP buffer since multiple responses can come back in one read, or partial * in a read */ - ares__buf_t *tcp_parser; + ares__buf_t *tcp_parser; /* TCP output queue */ - ares__buf_t *tcp_send; + ares__buf_t *tcp_send; /*! Buckets for collecting metrics about the server */ - ares_server_metrics_t metrics[ARES_METRIC_COUNT]; + ares_server_metrics_t metrics[ARES_METRIC_COUNT]; + + /*! RFC 7873/9018 DNS Cookies */ + ares_cookie_t cookie; /* Link back to owning channel */ - ares_channel_t *channel; + ares_channel_t *channel; }; /* State to represent a DNS query */ -struct query { +struct ares_query { /* Query ID from qbuf, for faster lookup, and current timeout */ - unsigned short qid; /* host byte order */ - ares_timeval_t ts; /*!< Timestamp query was sent */ - ares_timeval_t timeout; - ares_channel_t *channel; + unsigned short qid; /* host byte order */ + ares_timeval_t ts; /*!< Timestamp query was sent */ + ares_timeval_t timeout; + ares_channel_t *channel; /* * Node object for each list entry the query belongs to in order to * make removal operations O(1). */ - ares__slist_node_t *node_queries_by_timeout; - ares__llist_node_t *node_queries_to_conn; - ares__llist_node_t *node_all_queries; + ares__slist_node_t *node_queries_by_timeout; + ares__llist_node_t *node_queries_to_conn; + ares__llist_node_t *node_all_queries; /* connection handle query is associated with */ - struct server_connection *conn; + ares_conn_t *conn; /* Query */ - ares_dns_record_t *query; + ares_dns_record_t *query; - ares_callback_dnsrec callback; - void *arg; + ares_callback_dnsrec callback; + void *arg; /* Query status */ size_t try_count; /* Number of times we tried this query already. */ + size_t cookie_try_count; /* Attempt count for cookie resends */ ares_bool_t using_tcp; ares_status_t error_status; - size_t timeouts; /* number of timeouts we saw for this request */ - ares_bool_t no_retries; /* do not perform any additional retries, this is set - * when a query is to be canceled */ + size_t timeouts; /* number of timeouts we saw for this request */ + ares_bool_t no_retries; /* do not perform any additional retries, this is + * set when a query is to be canceled */ }; struct apattern { @@ -408,10 +461,15 @@ ares_bool_t ares__timedout(const ares_timeval_t *now, const ares_timeval_t *check); /* Returns one of the normal ares status codes like ARES_SUCCESS */ -ares_status_t ares__send_query(struct query *query, const ares_timeval_t *now); -ares_status_t ares__requeue_query(struct query *query, - const ares_timeval_t *now, - ares_status_t status); +ares_status_t ares__send_query(ares_query_t *query, const ares_timeval_t *now); +ares_status_t ares__requeue_query(ares_query_t *query, + const ares_timeval_t *now, + ares_status_t status, + ares_bool_t inc_try_count, + const ares_dns_record_t *dnsrec); + +/*! Count the number of labels (dots+1) in a domain */ +size_t ares__name_label_cnt(const char *name); /*! Retrieve a list of names to use for searching. The first successful * query in the list wins. This function also uses the HOSTSALIASES file @@ -439,11 +497,10 @@ void *ares__dnsrec_convert_arg(ares_callback callback, void *arg); void ares__dnsrec_convert_cb(void *arg, ares_status_t status, size_t timeouts, const ares_dns_record_t *dnsrec); -void ares__close_connection(struct server_connection *conn, - ares_status_t requeue_status); -void ares__close_sockets(struct server_state *server); +void ares__close_connection(ares_conn_t *conn, ares_status_t requeue_status); +void ares__close_sockets(ares_server_t *server); void ares__check_cleanup_conns(const ares_channel_t *channel); -void ares__free_query(struct query *query); +void ares__free_query(ares_query_t *query); ares_rand_state *ares__init_rand_state(void); void ares__destroy_rand_state(ares_rand_state *state); @@ -550,23 +607,28 @@ ares_status_t ares__addrinfo2addrttl(const struct ares_addrinfo *ai, int family, ares_status_t ares__addrinfo_localhost(const char *name, unsigned short port, const struct ares_addrinfo_hints *hints, struct ares_addrinfo *ai); -ares_status_t ares__open_connection(ares_channel_t *channel, - struct server_state *server, - ares_bool_t is_tcp); +ares_status_t ares__open_connection(ares_conn_t **conn_out, + ares_channel_t *channel, + ares_server_t *server, ares_bool_t is_tcp); +ares_bool_t ares_sockaddr_to_ares_addr(struct ares_addr *ares_addr, + unsigned short *port, + const struct sockaddr *sockaddr); ares_socket_t ares__open_socket(ares_channel_t *channel, int af, int type, int protocol); -ares_ssize_t ares__socket_write(ares_channel_t *channel, ares_socket_t s, - const void *data, size_t len); +ares_bool_t ares__socket_try_again(int errnum); +ares_ssize_t ares__conn_write(ares_conn_t *conn, const void *data, size_t len); ares_ssize_t ares__socket_recvfrom(ares_channel_t *channel, ares_socket_t s, void *data, size_t data_len, int flags, struct sockaddr *from, ares_socklen_t *from_len); ares_ssize_t ares__socket_recv(ares_channel_t *channel, ares_socket_t s, void *data, size_t data_len); -void ares__close_socket(ares_channel, ares_socket_t); -int ares__connect_socket(ares_channel_t *channel, ares_socket_t sockfd, - const struct sockaddr *addr, ares_socklen_t addrlen); -void ares__destroy_server(struct server_state *server); +void ares__close_socket(ares_channel_t *channel, ares_socket_t s); +ares_status_t ares__connect_socket(ares_channel_t *channel, + ares_socket_t sockfd, + const struct sockaddr *addr, + ares_socklen_t addrlen); +void ares__destroy_server(ares_server_t *server); ares_status_t ares__servers_update(ares_channel_t *channel, ares__llist_t *server_list, @@ -582,8 +644,8 @@ ares_status_t ares__sconfig_append_fromstr(ares__llist_t **sconfig, ares_status_t ares_in_addr_to_server_config_llist(const struct in_addr *servers, size_t nservers, ares__llist_t **llist); -ares_status_t ares_get_server_addr(const struct server_state *server, - ares__buf_t *buf); +ares_status_t ares_get_server_addr(const ares_server_t *server, + ares__buf_t *buf); struct ares_hosts_entry; typedef struct ares_hosts_entry ares_hosts_entry_t; @@ -616,8 +678,8 @@ ares_status_t ares_query_nolock(ares_channel_t *channel, const char *name, * if a channel lock is already held */ ares_status_t ares_send_nolock(ares_channel_t *channel, const ares_dns_record_t *dnsrec, - ares_callback_dnsrec callback, - void *arg, unsigned short *qid); + ares_callback_dnsrec callback, void *arg, + unsigned short *qid); /* Same as ares_gethostbyaddr() except does not take a channel lock. Use this * if a channel lock is already held */ @@ -703,17 +765,24 @@ ares_status_t ares__qcache_create(ares_rand_state *rand_state, void ares__qcache_flush(ares__qcache_t *cache); ares_status_t ares_qcache_insert(ares_channel_t *channel, const ares_timeval_t *now, - const struct query *query, + const ares_query_t *query, ares_dns_record_t *dnsrec); ares_status_t ares_qcache_fetch(ares_channel_t *channel, const ares_timeval_t *now, const ares_dns_record_t *dnsrec, const ares_dns_record_t **dnsrec_resp); -void ares_metrics_record(const struct query *query, struct server_state *server, - ares_status_t status, const ares_dns_record_t *dnsrec); -size_t ares_metrics_server_timeout(const struct server_state *server, - const ares_timeval_t *now); +void ares_metrics_record(const ares_query_t *query, ares_server_t *server, + ares_status_t status, const ares_dns_record_t *dnsrec); +size_t ares_metrics_server_timeout(const ares_server_t *server, + const ares_timeval_t *now); + +ares_status_t ares_cookie_apply(ares_dns_record_t *dnsrec, ares_conn_t *conn, + const ares_timeval_t *now); +ares_status_t ares_cookie_validate(ares_query_t *query, + const ares_dns_record_t *dnsresp, + ares_conn_t *conn, + const ares_timeval_t *now); ares_status_t ares__channel_threading_init(ares_channel_t *channel); void ares__channel_threading_destroy(ares_channel_t *channel); diff --git a/deps/cares/src/lib/ares_process.c b/deps/cares/src/lib/ares_process.c index 01d9e6a49d3..f05f67d8f2b 100644 --- a/deps/cares/src/lib/ares_process.c +++ b/deps/cares/src/lib/ares_process.c @@ -46,7 +46,6 @@ static void timeadd(ares_timeval_t *now, size_t millisecs); -static ares_bool_t try_again(int errnum); static void write_tcp_data(ares_channel_t *channel, fd_set *write_fds, ares_socket_t write_fd); static void read_packets(ares_channel_t *channel, fd_set *read_fds, @@ -55,22 +54,20 @@ static void process_timeouts(ares_channel_t *channel, const ares_timeval_t *now); static ares_status_t process_answer(ares_channel_t *channel, const unsigned char *abuf, size_t alen, - struct server_connection *conn, - ares_bool_t tcp, const ares_timeval_t *now); -static void handle_conn_error(struct server_connection *conn, - ares_bool_t critical_failure, - ares_status_t failure_status); - -static ares_bool_t same_questions(const struct query *query, - const ares_dns_record_t *arec); -static ares_bool_t same_address(const struct sockaddr *sa, - const struct ares_addr *aa); -static void end_query(ares_channel_t *channel, struct server_state *server, - struct query *query, ares_status_t status, - const ares_dns_record_t *dnsrec); - - -static void ares__query_disassociate_from_conn(struct query *query) + ares_conn_t *conn, ares_bool_t tcp, + const ares_timeval_t *now); +static void handle_conn_error(ares_conn_t *conn, ares_bool_t critical_failure, + ares_status_t failure_status); + +static ares_bool_t same_questions(const ares_query_t *query, + const ares_dns_record_t *arec); +static ares_bool_t same_address(const struct sockaddr *sa, + const struct ares_addr *aa); +static void end_query(ares_channel_t *channel, ares_server_t *server, + ares_query_t *query, ares_status_t status, + const ares_dns_record_t *dnsrec); + +static void ares__query_disassociate_from_conn(ares_query_t *query) { /* If its not part of a connection, it can't be tracked for timeouts either */ ares__slist_node_destroy(query->node_queries_by_timeout); @@ -81,7 +78,7 @@ static void ares__query_disassociate_from_conn(struct query *query) } /* Invoke the server state callback after a success or failure */ -static void invoke_server_state_cb(const struct server_state *server, +static void invoke_server_state_cb(const ares_server_t *server, ares_bool_t success, int flags) { const ares_channel_t *channel = server->channel; @@ -115,8 +112,8 @@ static void invoke_server_state_cb(const struct server_state *server, ares_free(server_string); } -static void server_increment_failures(struct server_state *server, - ares_bool_t used_tcp) +static void server_increment_failures(ares_server_t *server, + ares_bool_t used_tcp) { ares__slist_node_t *node; const ares_channel_t *channel = server->channel; @@ -139,7 +136,7 @@ static void server_increment_failures(struct server_state *server, : ARES_SERV_STATE_UDP); } -static void server_set_good(struct server_state *server, ares_bool_t used_tcp) +static void server_set_good(ares_server_t *server, ares_bool_t used_tcp) { ares__slist_node_t *node; const ares_channel_t *channel = server->channel; @@ -238,34 +235,6 @@ void ares_process_fd(ares_channel_t *channel, processfds(channel, NULL, read_fd, NULL, write_fd); } -/* Return 1 if the specified error number describes a readiness error, or 0 - * otherwise. This is mostly for HP-UX, which could return EAGAIN or - * EWOULDBLOCK. See this man page - * - * http://devrsrc1.external.hp.com/STKS/cgi-bin/man2html? - * manpage=/usr/share/man/man2.Z/send.2 - */ -static ares_bool_t try_again(int errnum) -{ -#if !defined EWOULDBLOCK && !defined EAGAIN -# error "Neither EWOULDBLOCK nor EAGAIN defined" -#endif - -#ifdef EWOULDBLOCK - if (errnum == EWOULDBLOCK) { - return ARES_TRUE; - } -#endif - -#if defined EAGAIN && EAGAIN != EWOULDBLOCK - if (errnum == EAGAIN) { - return ARES_TRUE; - } -#endif - - return ARES_FALSE; -} - /* If any TCP sockets select true for writing, write out queued data * we have for them. */ @@ -281,7 +250,7 @@ static void write_tcp_data(ares_channel_t *channel, fd_set *write_fds, for (node = ares__slist_node_first(channel->servers); node != NULL; node = ares__slist_node_next(node)) { - struct server_state *server = ares__slist_node_val(node); + ares_server_t *server = ares__slist_node_val(node); const unsigned char *data; size_t data_len; ares_ssize_t count; @@ -312,9 +281,9 @@ static void write_tcp_data(ares_channel_t *channel, fd_set *write_fds, } data = ares__buf_peek(server->tcp_send, &data_len); - count = ares__socket_write(channel, server->tcp_conn->fd, data, data_len); + count = ares__conn_write(server->tcp_conn, data, data_len); if (count <= 0) { - if (!try_again(SOCKERRNO)) { + if (!ares__socket_try_again(SOCKERRNO)) { handle_conn_error(server->tcp_conn, ARES_TRUE, ARES_ECONNREFUSED); } continue; @@ -334,21 +303,21 @@ static void write_tcp_data(ares_channel_t *channel, fd_set *write_fds, * allocate a buffer if we finish reading the length word, and process * a packet if we finish reading one. */ -static void read_tcp_data(ares_channel_t *channel, - struct server_connection *conn, - const ares_timeval_t *now) +static void read_tcp_data(ares_channel_t *channel, ares_conn_t *conn, + const ares_timeval_t *now) { - ares_ssize_t count; - struct server_state *server = conn->server; + ares_ssize_t count; + ares_server_t *server = conn->server; /* Fetch buffer to store data we are reading */ - size_t ptr_len = 65535; - unsigned char *ptr; + size_t ptr_len = 65535; + unsigned char *ptr; ptr = ares__buf_append_start(server->tcp_parser, &ptr_len); if (ptr == NULL) { - handle_conn_error(conn, ARES_FALSE /* not critical to connection */, ARES_SUCCESS); + handle_conn_error(conn, ARES_FALSE /* not critical to connection */, + ARES_SUCCESS); return; /* bail out on malloc failure. TODO: make this function return error codes */ } @@ -357,7 +326,7 @@ static void read_tcp_data(ares_channel_t *channel, count = ares__socket_recv(channel, conn->fd, ptr, ptr_len); if (count <= 0) { ares__buf_append_finish(server->tcp_parser, 0); - if (!(count == -1 && try_again(SOCKERRNO))) { + if (!(count == -1 && ares__socket_try_again(SOCKERRNO))) { handle_conn_error(conn, ARES_TRUE, ARES_ECONNREFUSED); } return; @@ -411,69 +380,48 @@ static void read_tcp_data(ares_channel_t *channel, } } -static int socket_list_append(ares_socket_t **socketlist, ares_socket_t fd, - size_t *alloc_cnt, size_t *num) -{ - if (*num >= *alloc_cnt) { - /* Grow by powers of 2 */ - size_t new_alloc = (*alloc_cnt) << 1; - ares_socket_t *new_list = - ares_realloc(socketlist, new_alloc * sizeof(*new_list)); - if (new_list == NULL) { - return 0; /* LCOV_EXCL_LINE: OutOfMemory */ - } - *alloc_cnt = new_alloc; - *socketlist = new_list; - } - - (*socketlist)[(*num)++] = fd; - return 1; -} - static ares_socket_t *channel_socket_list(const ares_channel_t *channel, size_t *num) { - size_t alloc_cnt = 1 << 4; - ares_socket_t *out = ares_malloc(alloc_cnt * sizeof(*out)); ares__slist_node_t *snode; + ares__array_t *arr = ares__array_create(sizeof(ares_socket_t), NULL); *num = 0; - if (out == NULL) { + if (arr == NULL) { return NULL; /* LCOV_EXCL_LINE: OutOfMemory */ } for (snode = ares__slist_node_first(channel->servers); snode != NULL; snode = ares__slist_node_next(snode)) { - struct server_state *server = ares__slist_node_val(snode); - ares__llist_node_t *node; + ares_server_t *server = ares__slist_node_val(snode); + ares__llist_node_t *node; for (node = ares__llist_node_first(server->connections); node != NULL; node = ares__llist_node_next(node)) { - const struct server_connection *conn = ares__llist_node_val(node); + const ares_conn_t *conn = ares__llist_node_val(node); + ares_socket_t *sptr; + ares_status_t status; if (conn->fd == ARES_SOCKET_BAD) { continue; } - if (!socket_list_append(&out, conn->fd, &alloc_cnt, num)) { - goto fail; /* LCOV_EXCL_LINE: OutOfMemory */ + status = ares__array_insert_last((void **)&sptr, arr); + if (status != ARES_SUCCESS) { + ares__array_destroy(arr); /* LCOV_EXCL_LINE: OutOfMemory */ + return NULL; /* LCOV_EXCL_LINE: OutOfMemory */ } + *sptr = conn->fd; } } - return out; - -fail: - ares_free(out); - *num = 0; - return NULL; + return ares__array_finish(arr, num); } /* If any UDP sockets select true for reading, process them. */ -static void read_udp_packets_fd(ares_channel_t *channel, - struct server_connection *conn, - const ares_timeval_t *now) +static void read_udp_packets_fd(ares_channel_t *channel, ares_conn_t *conn, + const ares_timeval_t *now) { ares_ssize_t read_len; unsigned char buf[MAXENDSSZ + 1]; @@ -511,7 +459,7 @@ static void read_udp_packets_fd(ares_channel_t *channel, * tcp */ continue; } else if (read_len < 0) { - if (try_again(SOCKERRNO)) { + if (ares__socket_try_again(SOCKERRNO)) { break; } @@ -537,11 +485,11 @@ static void read_udp_packets_fd(ares_channel_t *channel, static void read_packets(ares_channel_t *channel, fd_set *read_fds, ares_socket_t read_fd, const ares_timeval_t *now) { - size_t i; - ares_socket_t *socketlist = NULL; - size_t num_sockets = 0; - struct server_connection *conn = NULL; - ares__llist_node_t *node = NULL; + size_t i; + ares_socket_t *socketlist = NULL; + size_t num_sockets = 0; + ares_conn_t *conn = NULL; + ares__llist_node_t *node = NULL; if (!read_fds && (read_fd == ARES_SOCKET_BAD)) { /* no possible action */ @@ -557,7 +505,7 @@ static void read_packets(ares_channel_t *channel, fd_set *read_fds, conn = ares__llist_node_val(node); - if (conn->is_tcp) { + if (conn->flags & ARES_CONN_FLAG_TCP) { read_tcp_data(channel, conn, now); } else { read_udp_packets_fd(channel, conn, now); @@ -591,7 +539,7 @@ static void read_packets(ares_channel_t *channel, fd_set *read_fds, conn = ares__llist_node_val(node); - if (conn->is_tcp) { + if (conn->flags & ARES_CONN_FLAG_TCP) { read_tcp_data(channel, conn, now); } else { read_udp_packets_fd(channel, conn, now); @@ -610,8 +558,8 @@ static void process_timeouts(ares_channel_t *channel, const ares_timeval_t *now) * and go. We don't want to try to rely on 'next' as some operation might * cause a cleanup of that pointer and would become invalid */ while ((node = ares__slist_node_first(channel->queries_by_timeout)) != NULL) { - struct query *query = ares__slist_node_val(node); - struct server_connection *conn; + ares_query_t *query = ares__slist_node_val(node); + ares_conn_t *conn; /* Since this is sorted, as soon as we hit a query that isn't timed out, * break */ @@ -623,15 +571,15 @@ static void process_timeouts(ares_channel_t *channel, const ares_timeval_t *now) conn = query->conn; server_increment_failures(conn->server, query->using_tcp); - ares__requeue_query(query, now, ARES_ETIMEOUT); + ares__requeue_query(query, now, ARES_ETIMEOUT, ARES_TRUE, NULL); } } -static ares_status_t rewrite_without_edns(struct query *query) +static ares_status_t rewrite_without_edns(ares_query_t *query) { - ares_status_t status = ARES_SUCCESS; - size_t i; - ares_bool_t found_opt_rr = ARES_FALSE; + ares_status_t status = ARES_SUCCESS; + size_t i; + ares_bool_t found_opt_rr = ARES_FALSE; /* Find and remove the OPT RR record */ for (i = 0; i < ares_dns_record_rr_cnt(query->query, ARES_SECTION_ADDITIONAL); @@ -659,16 +607,16 @@ static ares_status_t rewrite_without_edns(struct query *query) * the connection to be terminated after this call. */ static ares_status_t process_answer(ares_channel_t *channel, const unsigned char *abuf, size_t alen, - struct server_connection *conn, - ares_bool_t tcp, const ares_timeval_t *now) + ares_conn_t *conn, ares_bool_t tcp, + const ares_timeval_t *now) { - struct query *query; + ares_query_t *query; /* Cache these as once ares__send_query() gets called, it may end up * invalidating the connection all-together */ - struct server_state *server = conn->server; - ares_dns_record_t *rdnsrec = NULL; - ares_status_t status; - ares_bool_t is_cached = ARES_FALSE; + ares_server_t *server = conn->server; + ares_dns_record_t *rdnsrec = NULL; + ares_status_t status; + ares_bool_t is_cached = ARES_FALSE; /* Parse the response */ status = ares_dns_parse(abuf, alen, 0, &rdnsrec); @@ -697,6 +645,14 @@ static ares_status_t process_answer(ares_channel_t *channel, goto cleanup; } + /* Validate DNS cookie in response. This function may need to requeue the + * query. */ + if (ares_cookie_validate(query, rdnsrec, conn, now) != ARES_SUCCESS) { + /* Drop response and return */ + status = ARES_SUCCESS; + goto cleanup; + } + /* At this point we know we've received an answer for this query, so we should * remove it from the connection's queue so we can possibly invalidate the * connection. Delay cleaning up the connection though as we may enqueue @@ -708,7 +664,8 @@ static ares_status_t process_answer(ares_channel_t *channel, * protocol extension is not understood by the responder. We must retry the * query without EDNS enabled. */ if (ares_dns_record_get_rcode(rdnsrec) == ARES_RCODE_FORMERR && - ares_dns_has_opt_rr(query->query) && !ares_dns_has_opt_rr(rdnsrec)) { + ares_dns_get_opt_rr_const(query->query) != NULL && + ares_dns_get_opt_rr_const(rdnsrec) == NULL) { status = rewrite_without_edns(query); if (status != ARES_SUCCESS) { end_query(channel, server, query, status, NULL); @@ -754,7 +711,7 @@ static ares_status_t process_answer(ares_channel_t *channel, } server_increment_failures(server, query->using_tcp); - ares__requeue_query(query, now, status); + ares__requeue_query(query, now, status, ARES_TRUE, rdnsrec); /* Should any of these cause a connection termination? * Maybe SERVER_FAILURE? */ @@ -783,25 +740,27 @@ static ares_status_t process_answer(ares_channel_t *channel, return status; } -static void handle_conn_error(struct server_connection *conn, - ares_bool_t critical_failure, - ares_status_t failure_status) +static void handle_conn_error(ares_conn_t *conn, ares_bool_t critical_failure, + ares_status_t failure_status) { - struct server_state *server = conn->server; + ares_server_t *server = conn->server; /* Increment failures first before requeue so it is unlikely to requeue * to the same server */ if (critical_failure) { - server_increment_failures(server, conn->is_tcp); + server_increment_failures( + server, (conn->flags & ARES_CONN_FLAG_TCP) ? ARES_TRUE : ARES_FALSE); } /* This will requeue any connections automatically */ ares__close_connection(conn, failure_status); } -ares_status_t ares__requeue_query(struct query *query, - const ares_timeval_t *now, - ares_status_t status) +ares_status_t ares__requeue_query(ares_query_t *query, + const ares_timeval_t *now, + ares_status_t status, + ares_bool_t inc_try_count, + const ares_dns_record_t *dnsrec) { ares_channel_t *channel = query->channel; size_t max_tries = ares__slist_len(channel->servers) * channel->tries; @@ -812,7 +771,10 @@ ares_status_t ares__requeue_query(struct query *query, query->error_status = status; } - query->try_count++; + if (inc_try_count) { + query->try_count++; + } + if (query->try_count < max_tries && !query->no_retries) { return ares__send_query(query, now); } @@ -822,14 +784,14 @@ ares_status_t ares__requeue_query(struct query *query, query->error_status = ARES_ETIMEOUT; } - end_query(channel, NULL, query, query->error_status, NULL); + end_query(channel, NULL, query, query->error_status, dnsrec); return ARES_ETIMEOUT; } /* Pick a random server from the list, we first get a random number in the * range of the number of servers, then scan until we find that server in * the list */ -static struct server_state *ares__random_server(ares_channel_t *channel) +static ares_server_t *ares__random_server(ares_channel_t *channel) { unsigned char c; size_t cnt; @@ -873,12 +835,11 @@ static struct server_state *ares__random_server(ares_channel_t *channel) * To resolve this, with some probability we select a failed server to retry * instead. */ -static struct server_state *ares__failover_server(ares_channel_t *channel) +static ares_server_t *ares__failover_server(ares_channel_t *channel) { - struct server_state *first_server = ares__slist_first_val(channel->servers); - const struct server_state *last_server = - ares__slist_last_val(channel->servers); - unsigned short r; + ares_server_t *first_server = ares__slist_first_val(channel->servers); + const ares_server_t *last_server = ares__slist_last_val(channel->servers); + unsigned short r; /* Defensive code against no servers being available on the channel. */ if (first_server == NULL) { @@ -911,7 +872,7 @@ static struct server_state *ares__failover_server(ares_channel_t *channel) ares__tvnow(&now); for (node = ares__slist_node_first(channel->servers); node != NULL; node = ares__slist_node_next(node)) { - struct server_state *node_val = ares__slist_node_val(node); + ares_server_t *node_val = ares__slist_node_val(node); if (node_val != NULL && node_val->consec_failures > 0 && ares__timedout(&now, &node_val->next_retry_time)) { return node_val; @@ -923,65 +884,9 @@ static struct server_state *ares__failover_server(ares_channel_t *channel) return first_server; } -static ares_status_t ares__append_tcpbuf(struct server_state *server, - const struct query *query) -{ - ares_status_t status; - unsigned char *qbuf = NULL; - size_t qbuf_len = 0; - - status = ares_dns_write(query->query, &qbuf, &qbuf_len); - if (status != ARES_SUCCESS) { - goto done; - } - - status = ares__buf_append_be16(server->tcp_send, (unsigned short)qbuf_len); - if (status != ARES_SUCCESS) { - goto done; /* LCOV_EXCL_LINE: OutOfMemory */ - } - - status = ares__buf_append(server->tcp_send, qbuf, qbuf_len); - -done: - ares_free(qbuf); - return status; -} - - -static ares_status_t ares__write_udpbuf(ares_channel_t *channel, - ares_socket_t fd, - const struct query *query) -{ - ares_status_t status; - unsigned char *qbuf = NULL; - size_t qbuf_len = 0; - - status = ares_dns_write(query->query, &qbuf, &qbuf_len); - if (status != ARES_SUCCESS) { - goto done; - } - - if (ares__socket_write(channel, fd, qbuf, qbuf_len) == -1) { - if (try_again(SOCKERRNO)) { - status = ARES_ESERVFAIL; - } else { - /* UDP is connection-less, but we might receive an ICMP unreachable which - * means we can't talk to the remote host at all and that will be - * reflected here */ - status = ARES_ECONNREFUSED; - } - } else { - status = ARES_SUCCESS; - } - -done: - ares_free(qbuf); - return status; -} - -static size_t ares__calc_query_timeout(const struct query *query, - const struct server_state *server, - const ares_timeval_t *now) +static size_t ares__calc_query_timeout(const ares_query_t *query, + const ares_server_t *server, + const ares_timeval_t *now) { const ares_channel_t *channel = query->channel; size_t timeout = ares_metrics_server_timeout(server, now); @@ -1031,150 +936,187 @@ static size_t ares__calc_query_timeout(const struct query *query, return timeplus; } -ares_status_t ares__send_query(struct query *query, const ares_timeval_t *now) +static ares_conn_t *ares__fetch_connection(const ares_channel_t *channel, + ares_server_t *server, + const ares_query_t *query) { - ares_channel_t *channel = query->channel; - struct server_state *server; - struct server_connection *conn; - size_t timeplus; - ares_status_t status; - ares_bool_t new_connection = ARES_FALSE; + ares__llist_node_t *node; + ares_conn_t *conn; - /* Choose the server to send the query to */ - if (channel->rotate) { - /* Pull random server */ - server = ares__random_server(channel); - } else { - /* Pull server with failover behavior */ - server = ares__failover_server(channel); + if (query->using_tcp) { + return server->tcp_conn; } - if (server == NULL) { - end_query(channel, server, query, ARES_ENOSERVER /* ? */, NULL); - return ARES_ENOSERVER; + /* Fetch existing UDP connection */ + node = ares__llist_node_first(server->connections); + if (node == NULL) { + return NULL; } - if (query->using_tcp) { - size_t prior_len = 0; - /* Make sure the TCP socket for this server is set up and queue - * a send request. - */ - if (server->tcp_conn == NULL) { - new_connection = ARES_TRUE; - status = ares__open_connection(channel, server, ARES_TRUE); - switch (status) { - /* Good result, continue on */ - case ARES_SUCCESS: - break; + conn = ares__llist_node_val(node); + /* Not UDP, skip */ + if (conn->flags & ARES_CONN_FLAG_TCP) { + return NULL; + } - /* These conditions are retryable as they are server-specific - * error codes */ - case ARES_ECONNREFUSED: - case ARES_EBADFAMILY: - server_increment_failures(server, query->using_tcp); - return ares__requeue_query(query, now, status); + /* Used too many times */ + if (channel->udp_max_queries > 0 && + conn->total_queries >= channel->udp_max_queries) { + return NULL; + } - /* Anything else is not retryable, likely ENOMEM */ - default: - end_query(channel, server, query, status, NULL); - return status; - } - } + return conn; +} - conn = server->tcp_conn; +static ares_status_t ares__conn_query_write(ares_conn_t *conn, + ares_query_t *query, + const ares_timeval_t *now) +{ + unsigned char *qbuf = NULL; + size_t qbuf_len = 0; + ares_ssize_t len; + ares_server_t *server = conn->server; + ares_channel_t *channel = server->channel; + ares_status_t status; + + status = ares_cookie_apply(query->query, conn, now); + if (status != ARES_SUCCESS) { + return status; + } - prior_len = ares__buf_len(server->tcp_send); + if (conn->flags & ARES_CONN_FLAG_TCP) { + size_t prior_len = ares__buf_len(server->tcp_send); - status = ares__append_tcpbuf(server, query); + status = ares_dns_write_buf_tcp(query->query, server->tcp_send); if (status != ARES_SUCCESS) { - end_query(channel, server, query, status, NULL); + return status; + } + + if (conn->flags & ARES_CONN_FLAG_TFO_INITIAL) { + /* When using TFO, we need to put it on the wire immediately. */ + size_t data_len; + const unsigned char *data = NULL; + + data = ares__buf_peek(server->tcp_send, &data_len); + len = ares__conn_write(conn, data, data_len); + if (len <= 0) { + if (ares__socket_try_again(SOCKERRNO)) { + /* This means we must not have qualified for TFO, keep the data + * buffered, wait on write signal. */ + return ARES_SUCCESS; + } - /* Only safe to kill connection if it was new, otherwise it should be - * cleaned up by another process later */ - if (new_connection) { - ares__close_connection(conn, status); + /* TCP TFO might delay failure. Reflect that here */ + return ARES_ECONNREFUSED; } - return status; + + /* Consume what was written */ + ares__buf_consume(server->tcp_send, (size_t)len); + return ARES_SUCCESS; } if (prior_len == 0) { SOCK_STATE_CALLBACK(channel, conn->fd, 1, 1); } - } else { - ares__llist_node_t *node = ares__llist_node_first(server->connections); - - /* Don't use the found connection if we've gone over the maximum number - * of queries. Also, skip over the TCP connection if it is the first in - * the list */ - if (node != NULL) { - conn = ares__llist_node_val(node); - if (conn->is_tcp) { - node = NULL; - } else if (channel->udp_max_queries > 0 && - conn->total_queries >= channel->udp_max_queries) { - node = NULL; - } - } + return ARES_SUCCESS; + } - if (node == NULL) { - new_connection = ARES_TRUE; - status = ares__open_connection(channel, server, ARES_FALSE); - switch (status) { - /* Good result, continue on */ - case ARES_SUCCESS: - break; + /* UDP Here */ + status = ares_dns_write(query->query, &qbuf, &qbuf_len); + if (status != ARES_SUCCESS) { + return status; + } - /* These conditions are retryable as they are server-specific - * error codes */ - case ARES_ECONNREFUSED: - case ARES_EBADFAMILY: - server_increment_failures(server, query->using_tcp); - return ares__requeue_query(query, now, status); + len = ares__conn_write(conn, qbuf, qbuf_len); + ares_free(qbuf); - /* Anything else is not retryable, likely ENOMEM */ - default: - end_query(channel, server, query, status, NULL); - return status; - } - node = ares__llist_node_first(server->connections); + if (len == -1) { + if (ares__socket_try_again(SOCKERRNO)) { + return ARES_ESERVFAIL; } + /* UDP is connection-less, but we might receive an ICMP unreachable which + * means we can't talk to the remote host at all and that will be + * reflected here */ + return ARES_ECONNREFUSED; + } - conn = ares__llist_node_val(node); + return ARES_SUCCESS; +} - status = ares__write_udpbuf(channel, conn->fd, query); - if (status != ARES_SUCCESS) { - if (status == ARES_ENOMEM) { - /* Not retryable */ - end_query(channel, server, query, status, NULL); - return status; - } +ares_status_t ares__send_query(ares_query_t *query, const ares_timeval_t *now) +{ + ares_channel_t *channel = query->channel; + ares_server_t *server; + ares_conn_t *conn; + size_t timeplus; + ares_status_t status; - if (status == ARES_ECONNREFUSED) { - handle_conn_error(conn, ARES_TRUE, status); + /* Choose the server to send the query to */ + if (channel->rotate) { + /* Pull random server */ + server = ares__random_server(channel); + } else { + /* Pull server with failover behavior */ + server = ares__failover_server(channel); + } - /* This query wasn't yet bound to the connection, need to manually - * requeue it and return an appropriate error */ - status = ares__requeue_query(query, now, status); - if (status == ARES_ETIMEOUT) { - status = ARES_ECONNREFUSED; - } + if (server == NULL) { + end_query(channel, server, query, ARES_ENOSERVER /* ? */, NULL); + return ARES_ENOSERVER; + } + + conn = ares__fetch_connection(channel, server, query); + if (conn == NULL) { + status = ares__open_connection(&conn, channel, server, query->using_tcp); + switch (status) { + /* Good result, continue on */ + case ARES_SUCCESS: + break; + + /* These conditions are retryable as they are server-specific + * error codes */ + case ARES_ECONNREFUSED: + case ARES_EBADFAMILY: + server_increment_failures(server, query->using_tcp); + return ares__requeue_query(query, now, status, ARES_TRUE, NULL); + + /* Anything else is not retryable, likely ENOMEM */ + default: + end_query(channel, server, query, status, NULL); return status; - } + } + } - /* FIXME: Handle EAGAIN here since it likely can happen. Right now we - * just requeue to a different server/connection. */ - server_increment_failures(server, query->using_tcp); - status = ares__requeue_query(query, now, status); + /* Write the query */ + status = ares__conn_query_write(conn, query, now); + switch (status) { + /* Good result, continue on */ + case ARES_SUCCESS: + break; - /* Only safe to kill connection if it was new, otherwise it should be - * cleaned up by another process later */ - if (new_connection) { - ares__close_connection(conn, status); + case ARES_ENOMEM: + /* Not retryable */ + end_query(channel, server, query, status, NULL); + return status; + + /* These conditions are retryable as they are server-specific + * error codes */ + case ARES_ECONNREFUSED: + case ARES_EBADFAMILY: + handle_conn_error(conn, ARES_TRUE, status); + status = ares__requeue_query(query, now, status, ARES_TRUE, NULL); + if (status == ARES_ETIMEOUT) { + status = ARES_ECONNREFUSED; } + return status; + /* FIXME: Handle EAGAIN here since it likely can happen. Right now we + * just requeue to a different server/connection. */ + default: + server_increment_failures(server, query->using_tcp); + status = ares__requeue_query(query, now, status, ARES_TRUE, NULL); return status; - } } timeplus = ares__calc_query_timeout(query, server, now); @@ -1190,11 +1132,6 @@ ares_status_t ares__send_query(struct query *query, const ares_timeval_t *now) if (!query->node_queries_by_timeout) { /* LCOV_EXCL_START: OutOfMemory */ end_query(channel, server, query, ARES_ENOMEM, NULL); - /* Only safe to kill connection if it was new, otherwise it should be - * cleaned up by another process later */ - if (new_connection) { - ares__close_connection(conn, ARES_SUCCESS); - } return ARES_ENOMEM; /* LCOV_EXCL_STOP */ } @@ -1208,11 +1145,6 @@ ares_status_t ares__send_query(struct query *query, const ares_timeval_t *now) if (query->node_queries_to_conn == NULL) { /* LCOV_EXCL_START: OutOfMemory */ end_query(channel, server, query, ARES_ENOMEM, NULL); - /* Only safe to kill connection if it was new, otherwise it should be - * cleaned up by another process later */ - if (new_connection) { - ares__close_connection(conn, ARES_SUCCESS); - } return ARES_ENOMEM; /* LCOV_EXCL_STOP */ } @@ -1222,7 +1154,7 @@ ares_status_t ares__send_query(struct query *query, const ares_timeval_t *now) return ARES_SUCCESS; } -static ares_bool_t same_questions(const struct query *query, +static ares_bool_t same_questions(const ares_query_t *query, const ares_dns_record_t *arec) { size_t i; @@ -1299,7 +1231,8 @@ static ares_bool_t same_address(const struct sockaddr *sa, break; case AF_INET6: addr1 = &aa->addr.addr6; - addr2 = &(CARES_INADDR_CAST(const struct sockaddr_in6 *, sa))->sin6_addr; + addr2 = + &(CARES_INADDR_CAST(const struct sockaddr_in6 *, sa))->sin6_addr; if (memcmp(addr1, addr2, sizeof(aa->addr.addr6)) == 0) { return ARES_TRUE; /* match */ } @@ -1311,17 +1244,17 @@ static ares_bool_t same_address(const struct sockaddr *sa, return ARES_FALSE; /* different */ } -static void ares_detach_query(struct query *query) +static void ares_detach_query(ares_query_t *query) { /* Remove the query from all the lists in which it is linked */ ares__query_disassociate_from_conn(query); ares__htable_szvp_remove(query->channel->queries_by_qid, query->qid); ares__llist_node_destroy(query->node_all_queries); - query->node_all_queries = NULL; + query->node_all_queries = NULL; } -static void end_query(ares_channel_t *channel, struct server_state *server, - struct query *query, ares_status_t status, +static void end_query(ares_channel_t *channel, ares_server_t *server, + ares_query_t *query, ares_status_t status, const ares_dns_record_t *dnsrec) { ares_metrics_record(query, server, status, dnsrec); @@ -1338,7 +1271,7 @@ static void end_query(ares_channel_t *channel, struct server_state *server, ares_queue_notify_empty(channel); } -void ares__free_query(struct query *query) +void ares__free_query(ares_query_t *query) { ares_detach_query(query); /* Zero out some important stuff, to help catch bugs */ diff --git a/deps/cares/src/lib/ares_qcache.c b/deps/cares/src/lib/ares_qcache.c index 2d9919fd104..9725212fded 100644 --- a/deps/cares/src/lib/ares_qcache.c +++ b/deps/cares/src/lib/ares_qcache.c @@ -121,9 +121,11 @@ static char *ares__qcache_calc_key(const ares_dns_record_t *dnsrec) name_len--; } - status = ares__buf_append(buf, (const unsigned char *)name, name_len); - if (status != ARES_SUCCESS) { - goto fail; /* LCOV_EXCL_LINE: OutOfMemory */ + if (name_len > 0) { + status = ares__buf_append(buf, (const unsigned char *)name, name_len); + if (status != ARES_SUCCESS) { + goto fail; /* LCOV_EXCL_LINE: OutOfMemory */ + } } } @@ -300,10 +302,10 @@ static unsigned int ares__qcache_soa_minimum(ares_dns_record_t *dnsrec) } /* On success, takes ownership of dnsrec */ -static ares_status_t ares__qcache_insert(ares__qcache_t *qcache, - ares_dns_record_t *qresp, - const ares_dns_record_t *qreq, - const ares_timeval_t *now) +static ares_status_t ares__qcache_insert(ares__qcache_t *qcache, + ares_dns_record_t *qresp, + const ares_dns_record_t *qreq, + const ares_timeval_t *now) { ares__qcache_entry_t *entry; unsigned int ttl; @@ -346,8 +348,8 @@ static ares_status_t ares__qcache_insert(ares__qcache_t *qcache, } entry->dnsrec = qresp; - entry->expire_ts = now->sec + (time_t)ttl; - entry->insert_ts = now->sec; + entry->expire_ts = (time_t)now->sec + (time_t)ttl; + entry->insert_ts = (time_t)now->sec; /* We can't guarantee the server responded with the same flags as the * request had, so we have to re-parse the request in order to generate the @@ -422,9 +424,8 @@ ares_status_t ares_qcache_fetch(ares_channel_t *channel, ares_status_t ares_qcache_insert(ares_channel_t *channel, const ares_timeval_t *now, - const struct query *query, + const ares_query_t *query, ares_dns_record_t *dnsrec) { - return ares__qcache_insert(channel->qcache, dnsrec, query->query, - now); + return ares__qcache_insert(channel->qcache, dnsrec, query->query, now); } diff --git a/deps/cares/src/lib/ares_search.c b/deps/cares/src/lib/ares_search.c index ae98df39a80..2d3c0fc5145 100644 --- a/deps/cares/src/lib/ares_search.c +++ b/deps/cares/src/lib/ares_search.c @@ -107,26 +107,37 @@ static void search_callback(void *arg, ares_status_t status, size_t timeouts, { struct search_query *squery = (struct search_query *)arg; ares_channel_t *channel = squery->channel; - ares_dns_rcode_t rcode; - size_t ancount; + ares_status_t mystatus; ares_bool_t skip_cleanup = ARES_FALSE; squery->timeouts += timeouts; - if (status != ARES_SUCCESS) { - end_squery(squery, status, dnsrec); - return; - } - - rcode = ares_dns_record_get_rcode(dnsrec); - ancount = ares_dns_record_rr_cnt(dnsrec, ARES_SECTION_ANSWER); - mystatus = ares_dns_query_reply_tostatus(rcode, ancount); - - if (mystatus != ARES_ENODATA && mystatus != ARES_ESERVFAIL && - mystatus != ARES_ENOTFOUND) { - end_squery(squery, mystatus, dnsrec); - return; + if (dnsrec) { + ares_dns_rcode_t rcode = ares_dns_record_get_rcode(dnsrec); + size_t ancount = ares_dns_record_rr_cnt(dnsrec, + ARES_SECTION_ANSWER); + mystatus = ares_dns_query_reply_tostatus(rcode, ancount); + } else { + mystatus = status; + } + + switch (mystatus) { + case ARES_ENODATA: + case ARES_ENOTFOUND: + break; + case ARES_ESERVFAIL: + case ARES_EREFUSED: + /* Issue #852, systemd-resolved may return SERVFAIL or REFUSED on a + * single label domain name. */ + if (ares__name_label_cnt(squery->names[squery->next_name_idx-1]) != 1) { + end_squery(squery, mystatus, dnsrec); + return; + } + break; + default: + end_squery(squery, mystatus, dnsrec); + return; } /* If we ever get ARES_ENODATA along the way, record that; if the search @@ -147,7 +158,6 @@ static void search_callback(void *arg, ares_status_t status, size_t timeouts, return; } - /* We have no more domains to search, return an appropriate response. */ if (mystatus == ARES_ENOTFOUND && squery->ever_got_nodata) { end_squery(squery, ARES_ENODATA, NULL); @@ -176,6 +186,25 @@ static ares_bool_t ares__search_eligible(const ares_channel_t *channel, return ARES_TRUE; } +size_t ares__name_label_cnt(const char *name) +{ + const char *p; + size_t ndots = 0; + + if (name == NULL) { + return 0; + } + + for (p = name; p != NULL && *p != 0; p++) { + if (*p == '.') { + ndots++; + } + } + + /* Label count is 1 greater than ndots */ + return ndots+1; +} + ares_status_t ares__search_name_list(const ares_channel_t *channel, const char *name, char ***names, size_t *names_len) @@ -186,7 +215,6 @@ ares_status_t ares__search_name_list(const ares_channel_t *channel, char *alias = NULL; size_t ndots = 0; size_t idx = 0; - const char *p; size_t i; /* Perform HOSTALIASES resolution */ @@ -223,12 +251,10 @@ ares_status_t ares__search_name_list(const ares_channel_t *channel, goto done; } - /* Count the number of dots in name */ - ndots = 0; - for (p = name; *p != 0; p++) { - if (*p == '.') { - ndots++; - } + /* Count the number of dots in name, 1 less than label count */ + ndots = ares__name_label_cnt(name); + if (ndots > 0) { + ndots--; } /* Allocate an entry for each search domain, plus one for as-is */ diff --git a/deps/cares/src/lib/ares_send.c b/deps/cares/src/lib/ares_send.c index e07ef5b51fe..64ff7edd3ac 100644 --- a/deps/cares/src/lib/ares_send.c +++ b/deps/cares/src/lib/ares_send.c @@ -43,13 +43,12 @@ static unsigned short generate_unique_qid(ares_channel_t *channel) return id; } - /* https://datatracker.ietf.org/doc/html/draft-vixie-dnsext-dns0x20-00 */ -static ares_status_t ares_apply_dns0x20(ares_channel_t *channel, +static ares_status_t ares_apply_dns0x20(ares_channel_t *channel, ares_dns_record_t *dnsrec) { - ares_status_t status = ARES_SUCCESS; - const char *name = NULL; + ares_status_t status = ARES_SUCCESS; + const char *name = NULL; char dns0x20name[256]; unsigned char randdata[256 / 8]; size_t len; @@ -63,7 +62,11 @@ static ares_status_t ares_apply_dns0x20(ares_channel_t *channel, } len = ares_strlen(name); - if (len == 0 || len >= sizeof(dns0x20name)) { + if (len == 0) { + return ARES_SUCCESS; + } + + if (len >= sizeof(dns0x20name)) { status = ARES_EBADNAME; goto done; } @@ -72,16 +75,16 @@ static ares_status_t ares_apply_dns0x20(ares_channel_t *channel, /* Fetch the minimum amount of random data we'd need for the string, which * is 1 bit per byte */ - total_bits = ((len + 7) / 8) * 8; + total_bits = ((len + 7) / 8) * 8; remaining_bits = total_bits; ares__rand_bytes(channel->rand_state, randdata, total_bits / 8); /* Randomly apply 0x20 to name */ - for (i=0; iqid = id; query->timeout.sec = 0; query->timeout.usec = 0; - query->using_tcp = (channel->flags & ARES_FLAG_USEVC)?ARES_TRUE:ARES_FALSE; + query->using_tcp = + (channel->flags & ARES_FLAG_USEVC) ? ARES_TRUE : ARES_FALSE; /* Duplicate Query */ status = ares_dns_record_duplicate_ex(&query->query, dnsrec); diff --git a/deps/cares/src/lib/ares_setup.h b/deps/cares/src/lib/ares_setup.h index 1b554f1974c..b6ce077ff64 100644 --- a/deps/cares/src/lib/ares_setup.h +++ b/deps/cares/src/lib/ares_setup.h @@ -231,95 +231,6 @@ struct timeval { }; #endif - -/* - * If we have the MSG_NOSIGNAL define, make sure we use - * it as the fourth argument of function send() - */ - -#ifdef HAVE_MSG_NOSIGNAL -# define SEND_4TH_ARG MSG_NOSIGNAL -#else -# define SEND_4TH_ARG 0 -#endif - - -#if defined(__minix) -/* Minix doesn't support recv on TCP sockets */ -# define sread(x, y, z) \ - (ares_ssize_t) \ - read((RECV_TYPE_ARG1)(x), (RECV_TYPE_ARG2)(y), (RECV_TYPE_ARG3)(z)) - -#elif defined(HAVE_RECV) -/* - * The definitions for the return type and arguments types - * of functions recv() and send() belong and come from the - * configuration file. Do not define them in any other place. - * - * HAVE_RECV is defined if you have a function named recv() - * which is used to read incoming data from sockets. If your - * function has another name then don't define HAVE_RECV. - * - * If HAVE_RECV is defined then RECV_TYPE_ARG1, RECV_TYPE_ARG2, - * RECV_TYPE_ARG3, RECV_TYPE_ARG4 and RECV_TYPE_RETV must also - * be defined. - * - * HAVE_SEND is defined if you have a function named send() - * which is used to write outgoing data on a connected socket. - * If yours has another name then don't define HAVE_SEND. - * - * If HAVE_SEND is defined then SEND_TYPE_ARG1, - * SEND_TYPE_ARG2, SEND_TYPE_ARG3, SEND_TYPE_ARG4 and - * SEND_TYPE_RETV must also be defined. - */ - -# if !defined(RECV_TYPE_ARG1) || !defined(RECV_TYPE_ARG2) || \ - !defined(RECV_TYPE_ARG3) || !defined(RECV_TYPE_ARG4) || \ - !defined(RECV_TYPE_RETV) -/* */ -Error Missing_definition_of_return_and_arguments_types_of_recv -/* */ -# else -# define sread(x, y, z) \ - (ares_ssize_t) recv((RECV_TYPE_ARG1)(x), (RECV_TYPE_ARG2)(y), \ - (RECV_TYPE_ARG3)(z), (RECV_TYPE_ARG4)(0)) -# endif -#else /* HAVE_RECV */ -# ifndef sread -/* */ -Error Missing_definition_of_macro_sread -/* */ -# endif -#endif /* HAVE_RECV */ - - -#if defined(__minix) -/* Minix doesn't support send on TCP sockets */ -# define swrite(x, y, z) \ - (ares_ssize_t) \ - write((SEND_TYPE_ARG1)(x), (SEND_TYPE_ARG2)(y), (SEND_TYPE_ARG3)(z)) - -#elif defined(HAVE_SEND) -# if !defined(SEND_TYPE_ARG1) || \ - !defined(SEND_TYPE_ARG2) || !defined(SEND_TYPE_ARG3) || \ - !defined(SEND_TYPE_ARG4) || !defined(SEND_TYPE_RETV) - /* */ - Error Missing_definition_of_return_and_arguments_types_of_send -/* */ -# else -# define swrite(x, y, z) \ - (ares_ssize_t) send((SEND_TYPE_ARG1)(x), (SEND_TYPE_ARG2)(y), \ - (SEND_TYPE_ARG3)(z), (SEND_TYPE_ARG4)(SEND_4TH_ARG)) -# endif -#else /* HAVE_SEND */ -# ifndef swrite - /* */ - Error Missing_definition_of_macro_swrite -/* */ -# endif -#endif /* HAVE_SEND */ - - /* * Function-like macro definition used to close a socket. */ @@ -343,7 +254,7 @@ Error Missing_definition_of_macro_sread #else # define DEBUGF(x) \ do { \ - } while(0) + } while (0) #endif /* diff --git a/deps/cares/src/lib/ares_sysconfig.c b/deps/cares/src/lib/ares_sysconfig.c index 2cd3df28235..61e6a423a75 100644 --- a/deps/cares/src/lib/ares_sysconfig.c +++ b/deps/cares/src/lib/ares_sysconfig.c @@ -239,7 +239,7 @@ static ares_status_t ares__init_sysconfig_android(ares_sysconfig_t *sysconfig) char propname[PROP_NAME_MAX]; char propvalue[PROP_VALUE_MAX] = ""; for (i = 1; i <= MAX_DNS_PROPERTIES; i++) { - snprintf(propname, sizeof(propname), "%s%u", DNS_PROP_NAME_PREFIX, i); + snprintf(propname, sizeof(propname), "%s%zu", DNS_PROP_NAME_PREFIX, i); if (__system_property_get(propname, propvalue) < 1) { break; } @@ -494,6 +494,7 @@ ares_status_t ares__init_by_sysconfig(ares_channel_t *channel) ares_sysconfig_t sysconfig; memset(&sysconfig, 0, sizeof(sysconfig)); + sysconfig.ndots = 1; /* Default value if not otherwise set */ #if defined(USE_WINSOCK) status = ares__init_sysconfig_windows(&sysconfig); diff --git a/deps/cares/src/lib/ares_sysconfig_mac.c b/deps/cares/src/lib/ares_sysconfig_mac.c index e2136201f68..38ac451ca5f 100644 --- a/deps/cares/src/lib/ares_sysconfig_mac.c +++ b/deps/cares/src/lib/ares_sysconfig_mac.c @@ -115,11 +115,11 @@ static ares_status_t dnsinfo_init(dnsinfo_t **dnsinfo_out) continue; } - dnsinfo->dns_configuration_copy = (dns_config_t *(*)(void)) + dnsinfo->dns_configuration_copy = (dns_config_t * (*)(void)) dlsym(dnsinfo->handle, "dns_configuration_copy"); - dnsinfo->dns_configuration_free = (void (*)(dns_config_t *)) - dlsym(dnsinfo->handle, "dns_configuration_free"); + dnsinfo->dns_configuration_free = (void (*)(dns_config_t *))dlsym( + dnsinfo->handle, "dns_configuration_free"); if (dnsinfo->dns_configuration_copy != NULL && dnsinfo->dns_configuration_free != NULL) { @@ -274,25 +274,7 @@ static ares_status_t read_resolver(const dns_resolver_t *resolver, /* UBSAN alignment workaround to fetch memory address */ memcpy(&sockaddr, resolver->nameserver + i, sizeof(sockaddr)); - if (sockaddr->sa_family == AF_INET) { - /* NOTE: memcpy sockaddr_in due to alignment issues found by UBSAN due to - * dnsinfo packing */ - struct sockaddr_in addr_in; - memcpy(&addr_in, sockaddr, sizeof(addr_in)); - - addr.family = AF_INET; - memcpy(&addr.addr.addr4, &(addr_in.sin_addr), sizeof(addr.addr.addr4)); - addrport = ntohs(addr_in.sin_port); - } else if (sockaddr->sa_family == AF_INET6) { - /* NOTE: memcpy sockaddr_in6 due to alignment issues found by UBSAN due to - * dnsinfo packing */ - struct sockaddr_in6 addr_in6; - memcpy(&addr_in6, sockaddr, sizeof(addr_in6)); - - addr.family = AF_INET6; - memcpy(&addr.addr.addr6, &(addr_in6.sin6_addr), sizeof(addr.addr.addr6)); - addrport = ntohs(addr_in6.sin6_port); - } else { + if (!ares_sockaddr_to_ares_addr(&addr, &addrport, sockaddr)) { continue; } diff --git a/deps/cares/src/lib/ares_timeout.c b/deps/cares/src/lib/ares_timeout.c index dac439b1b43..5ed8b553a3c 100644 --- a/deps/cares/src/lib/ares_timeout.c +++ b/deps/cares/src/lib/ares_timeout.c @@ -65,7 +65,8 @@ void ares__timeval_diff(ares_timeval_t *tvdiff, const ares_timeval_t *tvstart, } } -static void ares_timeval_to_struct_timeval(struct timeval *tv, const ares_timeval_t *atv) +static void ares_timeval_to_struct_timeval(struct timeval *tv, + const ares_timeval_t *atv) { #ifdef USE_WINSOCK tv->tv_sec = (long)atv->sec; @@ -76,17 +77,18 @@ static void ares_timeval_to_struct_timeval(struct timeval *tv, const ares_timeva tv->tv_usec = (int)atv->usec; } -static void struct_timeval_to_ares_timeval(ares_timeval_t *atv, const struct timeval *tv) +static void struct_timeval_to_ares_timeval(ares_timeval_t *atv, + const struct timeval *tv) { atv->sec = (ares_int64_t)tv->tv_sec; atv->usec = (unsigned int)tv->tv_usec; } static struct timeval *ares_timeout_int(const ares_channel_t *channel, - struct timeval *maxtv, - struct timeval *tvbuf) + struct timeval *maxtv, + struct timeval *tvbuf) { - const struct query *query; + const ares_query_t *query; ares__slist_node_t *node; ares_timeval_t now; ares_timeval_t atvbuf; @@ -135,8 +137,9 @@ struct timeval *ares_timeout(const ares_channel_t *channel, { struct timeval *rv; - if (channel == NULL || tvbuf == NULL) + if (channel == NULL || tvbuf == NULL) { return NULL; + } ares__channel_lock(channel); diff --git a/deps/cares/src/lib/ares_update_servers.c b/deps/cares/src/lib/ares_update_servers.c index 455e3001d5c..639f79d8159 100644 --- a/deps/cares/src/lib/ares_update_servers.c +++ b/deps/cares/src/lib/ares_update_servers.c @@ -525,7 +525,7 @@ static ares__slist_node_t *ares__server_find(ares_channel_t *channel, for (node = ares__slist_node_first(channel->servers); node != NULL; node = ares__slist_node_next(node)) { - const struct server_state *server = ares__slist_node_val(node); + const ares_server_t *server = ares__slist_node_val(node); if (!ares__addr_match(&server->addr, &s->addr)) { continue; @@ -579,8 +579,8 @@ static ares_status_t ares__server_create(ares_channel_t *channel, const ares_sconfig_t *sconfig, size_t idx) { - ares_status_t status; - struct server_state *server = ares_malloc_zero(sizeof(*server)); + ares_status_t status; + ares_server_t *server = ares_malloc_zero(sizeof(*server)); if (server == NULL) { return ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ @@ -641,8 +641,8 @@ static ares_status_t ares__server_create(ares_channel_t *channel, return status; } -static ares_bool_t ares__server_in_newconfig(const struct server_state *server, - ares__llist_t *srvlist) +static ares_bool_t ares__server_in_newconfig(const ares_server_t *server, + ares__llist_t *srvlist) { ares__llist_node_t *node; const ares_channel_t *channel = server->channel; @@ -676,8 +676,8 @@ static ares_bool_t ares__servers_remove_stale(ares_channel_t *channel, ares__slist_node_t *snode = ares__slist_node_first(channel->servers); while (snode != NULL) { - ares__slist_node_t *snext = ares__slist_node_next(snode); - const struct server_state *server = ares__slist_node_val(snode); + ares__slist_node_t *snext = ares__slist_node_next(snode); + const ares_server_t *server = ares__slist_node_val(snode); if (!ares__server_in_newconfig(server, srvlist)) { /* This will clean up all server state via the destruction callback and * move any queries to new servers */ @@ -726,7 +726,7 @@ ares_status_t ares__servers_update(ares_channel_t *channel, snode = ares__server_find(channel, sconfig); if (snode != NULL) { - struct server_state *server = ares__slist_node_val(snode); + ares_server_t *server = ares__slist_node_val(snode); /* Copy over link-local settings. Its possible some of this data has * changed, maybe ... */ @@ -928,8 +928,8 @@ ares_status_t ares_in_addr_to_server_config_llist(const struct in_addr *servers, } /* Write out the details of a server to a buffer */ -ares_status_t ares_get_server_addr(const struct server_state *server, - ares__buf_t *buf) +ares_status_t ares_get_server_addr(const ares_server_t *server, + ares__buf_t *buf) { ares_status_t status; char addr[INET6_ADDRSTRLEN]; @@ -1000,7 +1000,7 @@ int ares_get_servers(const ares_channel_t *channel, for (node = ares__slist_node_first(channel->servers); node != NULL; node = ares__slist_node_next(node)) { - const struct server_state *server = ares__slist_node_val(node); + const ares_server_t *server = ares__slist_node_val(node); /* Allocate storage for this server node appending it to the list */ srvr_curr = ares_malloc_data(ARES_DATATYPE_ADDR_NODE); @@ -1055,7 +1055,7 @@ int ares_get_servers_ports(const ares_channel_t *channel, for (node = ares__slist_node_first(channel->servers); node != NULL; node = ares__slist_node_next(node)) { - const struct server_state *server = ares__slist_node_val(node); + const ares_server_t *server = ares__slist_node_val(node); /* Allocate storage for this server node appending it to the list */ srvr_curr = ares_malloc_data(ARES_DATATYPE_ADDR_PORT_NODE); @@ -1203,8 +1203,8 @@ char *ares_get_servers_csv(const ares_channel_t *channel) for (node = ares__slist_node_first(channel->servers); node != NULL; node = ares__slist_node_next(node)) { - ares_status_t status; - const struct server_state *server = ares__slist_node_val(node); + ares_status_t status; + const ares_server_t *server = ares__slist_node_val(node); if (ares__buf_len(buf)) { status = ares__buf_append_byte(buf, ','); diff --git a/deps/cares/src/lib/config-win32.h b/deps/cares/src/lib/config-win32.h index da5c7483879..b9c4ec17336 100644 --- a/deps/cares/src/lib/config-win32.h +++ b/deps/cares/src/lib/config-win32.h @@ -352,6 +352,9 @@ # define HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID 1 #endif +/* Define to 1 if you have the `RegisterWaitForSingleObject' function. */ +#define HAVE_REGISTERWAITFORSINGLEOBJECT 1 + #if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0600) && \ !defined(__WATCOMC__) && !defined(WATT32) /* Define if you have if_nametoindex() */ @@ -362,6 +365,8 @@ # define HAVE_CONVERTINTERFACEINDEXTOLUID 1 /* Define to 1 if you have the `ConvertInterfaceLuidToNameA' function. */ # define HAVE_CONVERTINTERFACELUIDTONAMEA 1 +/* Define to 1 if you have the `NotifyIpInterfaceChange' function. */ +# define HAVE_NOTIFYIPINTERFACECHANGE 1 #endif /* ---------------------------------------------------------------- */ diff --git a/deps/cares/src/lib/dsa/ares__array.c b/deps/cares/src/lib/dsa/ares__array.c new file mode 100644 index 00000000000..0c724248bf2 --- /dev/null +++ b/deps/cares/src/lib/dsa/ares__array.c @@ -0,0 +1,356 @@ +/* MIT License + * + * Copyright (c) 2024 Brad House + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * SPDX-License-Identifier: MIT + */ +#include "ares_private.h" +#include "ares__array.h" + +#define ARES__ARRAY_MIN 4 + +struct ares__array { + ares__array_destructor_t destruct; + void *arr; + size_t member_size; + size_t cnt; + size_t offset; + size_t alloc_cnt; +}; + +ares__array_t *ares__array_create(size_t member_size, + ares__array_destructor_t destruct) +{ + ares__array_t *arr; + + if (member_size == 0) { + return NULL; + } + + arr = ares_malloc_zero(sizeof(*arr)); + if (arr == NULL) { + return NULL; + } + + arr->member_size = member_size; + arr->destruct = destruct; + return arr; +} + +size_t ares__array_len(const ares__array_t *arr) +{ + if (arr == NULL) { + return 0; + } + return arr->cnt; +} + +void *ares__array_at(ares__array_t *arr, size_t idx) +{ + if (arr == NULL || idx >= arr->cnt) { + return NULL; + } + return (unsigned char *)arr->arr + ((idx + arr->offset) * arr->member_size); +} + +const void *ares__array_at_const(const ares__array_t *arr, size_t idx) +{ + if (arr == NULL || idx >= arr->cnt) { + return NULL; + } + return (unsigned char *)arr->arr + ((idx + arr->offset) * arr->member_size); +} + +ares_status_t ares__array_sort(ares__array_t *arr, ares__array_cmp_t cmp) +{ + if (arr == NULL || cmp == NULL) { + return ARES_EFORMERR; + } + + /* Nothing to sort */ + if (arr->cnt < 2) { + return ARES_SUCCESS; + } + + qsort((unsigned char *)arr->arr + (arr->offset * arr->member_size), arr->cnt, + arr->member_size, cmp); + return ARES_SUCCESS; +} + +void ares__array_destroy(ares__array_t *arr) +{ + size_t i; + + if (arr == NULL) { + return; + } + + if (arr->destruct != NULL) { + for (i = 0; i < arr->cnt; i++) { + arr->destruct(ares__array_at(arr, i)); + } + } + + ares_free(arr->arr); + ares_free(arr); +} + +/* NOTE: this function operates on actual indexes, NOT indexes using the + * arr->offset */ +static ares_status_t ares__array_move(ares__array_t *arr, size_t dest_idx, + size_t src_idx) +{ + void *dest_ptr; + const void *src_ptr; + size_t nmembers; + + if (arr == NULL || dest_idx >= arr->alloc_cnt || src_idx >= arr->alloc_cnt) { + return ARES_EFORMERR; + } + + /* Nothing to do */ + if (dest_idx == src_idx) { + return ARES_SUCCESS; + } + + dest_ptr = (unsigned char *)arr->arr + (dest_idx * arr->member_size); + src_ptr = (unsigned char *)arr->arr + (src_idx * arr->member_size); + + /* Check to make sure shifting to the right won't overflow our allocation + * boundary */ + if (dest_idx > src_idx && arr->cnt + (dest_idx - src_idx) > arr->alloc_cnt) { + return ARES_EFORMERR; + } + if (dest_idx < src_idx) { + nmembers = arr->cnt - dest_idx; + } else { + nmembers = arr->cnt - src_idx; + } + + memmove(dest_ptr, src_ptr, nmembers * arr->member_size); + + return ARES_SUCCESS; +} + +void *ares__array_finish(ares__array_t *arr, size_t *num_members) +{ + void *ptr; + + if (arr == NULL || num_members == NULL) { + return NULL; + } + + /* Make sure we move data to beginning of allocation */ + if (arr->offset != 0) { + if (ares__array_move(arr, 0, arr->offset) != ARES_SUCCESS) { + return NULL; + } + arr->offset = 0; + } + + ptr = arr->arr; + *num_members = arr->cnt; + ares_free(arr); + return ptr; +} + +ares_status_t ares__array_set_size(ares__array_t *arr, size_t size) +{ + void *temp; + + if (arr == NULL || size == 0 || size < arr->cnt) { + return ARES_EFORMERR; + } + + /* Always operate on powers of 2 */ + size = ares__round_up_pow2(size); + + if (size < ARES__ARRAY_MIN) { + size = ARES__ARRAY_MIN; + } + + /* If our allocation size is already large enough, skip */ + if (size <= arr->alloc_cnt) { + return ARES_SUCCESS; + } + + temp = ares_realloc_zero(arr->arr, arr->alloc_cnt * arr->member_size, + size * arr->member_size); + if (temp == NULL) { + return ARES_ENOMEM; + } + arr->alloc_cnt = size; + arr->arr = temp; + return ARES_SUCCESS; +} + +ares_status_t ares__array_insert_at(void **elem_ptr, ares__array_t *arr, + size_t idx) +{ + void *ptr; + ares_status_t status; + + if (arr == NULL) { + return ARES_EFORMERR; + } + + /* Not >= since we are allowed to append to the end */ + if (idx > arr->cnt) { + return ARES_EFORMERR; + } + + /* Allocate more if needed */ + status = ares__array_set_size(arr, arr->cnt + 1); + if (status != ARES_SUCCESS) { + return status; + } + + /* Shift if we have memory but not enough room at the end */ + if (arr->cnt + 1 + arr->offset > arr->alloc_cnt) { + status = ares__array_move(arr, 0, arr->offset); + if (status != ARES_SUCCESS) { + return status; + } + arr->offset = 0; + } + + /* If we're inserting anywhere other than the end, we need to move some + * elements out of the way */ + if (idx != arr->cnt) { + status = ares__array_move(arr, idx + arr->offset + 1, idx + arr->offset); + if (status != ARES_SUCCESS) { + return status; + } + } + + /* Ok, we're guaranteed to have a gap where we need it, lets zero it out, + * and return it */ + ptr = (unsigned char *)arr->arr + ((idx + arr->offset) * arr->member_size); + memset(ptr, 0, arr->member_size); + arr->cnt++; + + if (elem_ptr) { + *elem_ptr = ptr; + } + + return ARES_SUCCESS; +} + +ares_status_t ares__array_insert_last(void **elem_ptr, ares__array_t *arr) +{ + return ares__array_insert_at(elem_ptr, arr, ares__array_len(arr)); +} + +ares_status_t ares__array_insert_first(void **elem_ptr, ares__array_t *arr) +{ + return ares__array_insert_at(elem_ptr, arr, 0); +} + +void *ares__array_first(ares__array_t *arr) +{ + return ares__array_at(arr, 0); +} + +void *ares__array_last(ares__array_t *arr) +{ + size_t cnt = ares__array_len(arr); + if (cnt == 0) { + return NULL; + } + return ares__array_at(arr, cnt - 1); +} + +const void *ares__array_first_const(const ares__array_t *arr) +{ + return ares__array_at_const(arr, 0); +} + +const void *ares__array_last_const(const ares__array_t *arr) +{ + size_t cnt = ares__array_len(arr); + if (cnt == 0) { + return NULL; + } + return ares__array_at_const(arr, cnt - 1); +} + +ares_status_t ares__array_claim_at(void *dest, size_t dest_size, + ares__array_t *arr, size_t idx) +{ + ares_status_t status; + + if (arr == NULL || idx >= arr->cnt) { + return ARES_EFORMERR; + } + + if (dest != NULL && dest_size < arr->member_size) { + return ARES_EFORMERR; + } + + if (dest) { + memcpy(dest, ares__array_at(arr, idx), arr->member_size); + } + + if (idx == 0) { + /* Optimization, if first element, just increment offset, makes removing a + * lot from the start quick */ + arr->offset++; + } else if (idx != arr->cnt - 1) { + /* Must shift entire array if removing an element from the middle. Does + * nothing if removing last element other than decrement count. */ + status = ares__array_move(arr, idx + arr->offset, idx + arr->offset + 1); + if (status != ARES_SUCCESS) { + return status; + } + } + + arr->cnt--; + return ARES_SUCCESS; +} + +ares_status_t ares__array_remove_at(ares__array_t *arr, size_t idx) +{ + void *ptr = ares__array_at(arr, idx); + if (arr == NULL || ptr == NULL) { + return ARES_EFORMERR; + } + + if (arr->destruct != NULL) { + arr->destruct(ptr); + } + + return ares__array_claim_at(NULL, 0, arr, idx); +} + +ares_status_t ares__array_remove_first(ares__array_t *arr) +{ + return ares__array_remove_at(arr, 0); +} + +ares_status_t ares__array_remove_last(ares__array_t *arr) +{ + size_t cnt = ares__array_len(arr); + if (cnt == 0) { + return ARES_EFORMERR; + } + return ares__array_remove_at(arr, cnt - 1); +} diff --git a/deps/cares/src/lib/dsa/ares__array.h b/deps/cares/src/lib/dsa/ares__array.h new file mode 100644 index 00000000000..6fa1c0e15e9 --- /dev/null +++ b/deps/cares/src/lib/dsa/ares__array.h @@ -0,0 +1,223 @@ +/* MIT License + * + * Copyright (c) 2024 Brad House + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * SPDX-License-Identifier: MIT + */ +#ifndef __ARES__ARRAY_H +#define __ARES__ARRAY_H + +/*! \addtogroup ares__array Array Data Structure + * + * This is an array with helpers. It is meant to have as little overhead + * as possible over direct array management by applications but to provide + * safety and some optimization features. It can also return the array in + * native form once all manipulation has been performed. + * + * @{ + */ + +struct ares__array; + +/*! Opaque data structure for array */ +typedef struct ares__array ares__array_t; + +/*! Callback to free user-defined member data + * + * \param[in] data pointer to member of array to be destroyed. The pointer + * itself must not be destroyed, just the data it contains. + */ +typedef void (*ares__array_destructor_t)(void *data); + +/*! Callback to compare two array elements used for sorting + * + * \param[in] data1 array member 1 + * \param[in] data2 array member 2 + * \return < 0 if data1 < data2, > 0 if data1 > data2, 0 if data1 == data2 + */ +typedef int (*ares__array_cmp_t)(const void *data1, const void *data2); + +/*! Create an array object + * + * NOTE: members of the array are typically going to be an going to be a + * struct with compiler/ABI specific padding to ensure proper alignment. + * Care needs to be taken if using primitive types, especially floating + * point numbers which size may not indicate the required alignment. + * For example, a double may be 80 bits (10 bytes), but required + * alignment of 16 bytes. In such a case, a member_size of 16 would be + * required to be used. + * + * \param[in] destruct Optional. Destructor to call on a removed member + * \param[in] member_size Size of array member, usually determined using + * sizeof() for the member such as a struct. + * + * \return array object or NULL on out of memory + */ +ares__array_t *ares__array_create(size_t member_size, + ares__array_destructor_t destruct); + + +/*! Request the array be at least the requested size. Useful if the desired + * array size is known prior to populating the array to prevent reallocations. + * + * \param[in] arr Initialized array object. + * \param[in] size Minimum number of members + * \return ARES_SUCCESS on success, ARES_EFORMERR on misuse, + * ARES_ENOMEM on out of memory */ +ares_status_t ares__array_set_size(ares__array_t *arr, size_t size); + +/*! Sort the array using the given comparison function. This is not + * persistent, any future elements inserted will not maintain this sort. + * + * \param[in] arr Initialized array object. + * \param[in] cb Sort callback + * \return ARES_SUCCESS on success + */ +ares_status_t ares__array_sort(ares__array_t *arr, ares__array_cmp_t cmp); + +/*! Destroy an array object. If a destructor is set, will be called on each + * member of the array. + * + * \param[in] arr Initialized array object. + */ +void ares__array_destroy(ares__array_t *arr); + +/*! Retrieve the array in the native format. This will also destroy the + * container. It is the responsibility of the caller to free the returned + * pointer and also any data within each array element. + * + * \param[in] arr Initialized array object + * \param[out] num_members the number of members in the returned array + * \return pointer to native array on success, NULL on failure. + */ +void *ares__array_finish(ares__array_t *arr, size_t *num_members); + +/*! Retrieve the number of members in the array + * + * \param[in] arr Initialized array object. + * \return numbrer of members + */ +size_t ares__array_len(const ares__array_t *arr); + +/*! Insert a new array member at the given index + * + * \param[out] elem_ptr Optional. Pointer to the returned array element. + * \param[in] arr Initialized array object. + * \param[in] idx Index in array to place new element, will shift any + * elements down that exist after this point. + * \return ARES_SUCCESS on success, ARES_EFORMERR on bad index, + * ARES_ENOMEM on out of memory. + */ +ares_status_t ares__array_insert_at(void **elem_ptr, ares__array_t *arr, + size_t idx); + +/*! Insert a new array member at the end of the array + * + * \param[out] elem_ptr Optional. Pointer to the returned array element. + * \param[in] arr Initialized array object. + * \return ARES_SUCCESS on success, ARES_ENOMEM on out of memory. + */ +ares_status_t ares__array_insert_last(void **elem_ptr, ares__array_t *arr); + +/*! Insert a new array member at the beginning of the array + * + * \param[out] elem_ptr Optional. Pointer to the returned array element. + * \param[in] arr Initialized array object. + * \return ARES_SUCCESS on success, ARES_ENOMEM on out of memory. + */ +ares_status_t ares__array_insert_first(void **elem_ptr, ares__array_t *arr); + +/*! Fetch a pointer to the given element in the array + * \param[in] array Initialized array object + * \param[in] idx Index to fetch + * \return pointer on success, NULL on failure */ +void *ares__array_at(ares__array_t *arr, size_t idx); + +/*! Fetch a pointer to the first element in the array + * \param[in] array Initialized array object + * \return pointer on success, NULL on failure */ +void *ares__array_first(ares__array_t *arr); + +/*! Fetch a pointer to the last element in the array + * \param[in] array Initialized array object + * \return pointer on success, NULL on failure */ +void *ares__array_last(ares__array_t *arr); + +/*! Fetch a constant pointer to the given element in the array + * \param[in] array Initialized array object + * \param[in] idx Index to fetch + * \return pointer on success, NULL on failure */ +const void *ares__array_at_const(const ares__array_t *arr, size_t idx); + +/*! Fetch a constant pointer to the first element in the array + * \param[in] array Initialized array object + * \return pointer on success, NULL on failure */ +const void *ares__array_first_const(const ares__array_t *arr); + +/*! Fetch a constant pointer to the last element in the array + * \param[in] array Initialized array object + * \return pointer on success, NULL on failure */ +const void *ares__array_last_const(const ares__array_t *arr); + +/*! Claim the data from the specified array index, copying it to the buffer + * provided by the caller. The index specified in the array will then be + * removed (without calling any possible destructor) + * + * \param[in,out] dest Optional. Buffer to hold array member. Pass NULL + * if not needed. This could leak memory if array + * member needs destructor if not provided. + * \param[in] dest_size Size of buffer provided, used as a sanity check. + * Must match member_size provided to + * ares__array_create() if dest_size specified. + * \param[in] arr Initialized array object + * \param[in] idx Index to claim + * \return ARES_SUCCESS on success, ARES_EFORMERR on usage failure. + */ +ares_status_t ares__array_claim_at(void *dest, size_t dest_size, + ares__array_t *arr, size_t idx); + +/*! Remove the member at the specified array index. The destructor will be + * called. + * + * \param[in] arr Initialized array object + * \param[in] idx Index to remove + * \return ARES_SUCCESS if removed, ARES_EFORMERR on invalid use + */ +ares_status_t ares__array_remove_at(ares__array_t *arr, size_t idx); + +/*! Remove the first member of the array. + * + * \param[in] arr Initialized array object + * \return ARES_SUCCESS if removed, ARES_EFORMERR on invalid use + */ +ares_status_t ares__array_remove_first(ares__array_t *arr); + +/*! Remove the last member of the array. + * + * \param[in] arr Initialized array object + * \return ARES_SUCCESS if removed, ARES_EFORMERR on invalid use + */ +ares_status_t ares__array_remove_last(ares__array_t *arr); + +/*! @} */ + +#endif /* __ARES__ARRAY_H */ diff --git a/deps/cares/src/lib/ares__htable.c b/deps/cares/src/lib/dsa/ares__htable.c similarity index 99% rename from deps/cares/src/lib/ares__htable.c rename to deps/cares/src/lib/dsa/ares__htable.c index d608d60ce3a..9049b3246b3 100644 --- a/deps/cares/src/lib/ares__htable.c +++ b/deps/cares/src/lib/dsa/ares__htable.c @@ -59,7 +59,7 @@ static unsigned int ares__htable_generate_seed(ares__htable_t *htable) * collision attack is very low with a small amount of effort */ seed |= (unsigned int)((size_t)htable & 0xFFFFFFFF); seed |= (unsigned int)((size_t)&seed & 0xFFFFFFFF); - seed |= (unsigned int)(t & 0xFFFFFFFF); + seed |= (unsigned int)(((ares_uint64_t)t) & 0xFFFFFFFF); return seed; } diff --git a/deps/cares/src/lib/ares__htable.h b/deps/cares/src/lib/dsa/ares__htable.h similarity index 100% rename from deps/cares/src/lib/ares__htable.h rename to deps/cares/src/lib/dsa/ares__htable.h diff --git a/deps/cares/src/lib/ares__htable_asvp.c b/deps/cares/src/lib/dsa/ares__htable_asvp.c similarity index 100% rename from deps/cares/src/lib/ares__htable_asvp.c rename to deps/cares/src/lib/dsa/ares__htable_asvp.c diff --git a/deps/cares/src/lib/ares__htable_asvp.h b/deps/cares/src/lib/dsa/ares__htable_asvp.h similarity index 100% rename from deps/cares/src/lib/ares__htable_asvp.h rename to deps/cares/src/lib/dsa/ares__htable_asvp.h diff --git a/deps/cares/src/lib/ares__htable_strvp.c b/deps/cares/src/lib/dsa/ares__htable_strvp.c similarity index 100% rename from deps/cares/src/lib/ares__htable_strvp.c rename to deps/cares/src/lib/dsa/ares__htable_strvp.c diff --git a/deps/cares/src/lib/ares__htable_strvp.h b/deps/cares/src/lib/dsa/ares__htable_strvp.h similarity index 100% rename from deps/cares/src/lib/ares__htable_strvp.h rename to deps/cares/src/lib/dsa/ares__htable_strvp.h diff --git a/deps/cares/src/lib/ares__htable_szvp.c b/deps/cares/src/lib/dsa/ares__htable_szvp.c similarity index 100% rename from deps/cares/src/lib/ares__htable_szvp.c rename to deps/cares/src/lib/dsa/ares__htable_szvp.c diff --git a/deps/cares/src/lib/ares__htable_szvp.h b/deps/cares/src/lib/dsa/ares__htable_szvp.h similarity index 100% rename from deps/cares/src/lib/ares__htable_szvp.h rename to deps/cares/src/lib/dsa/ares__htable_szvp.h diff --git a/deps/cares/src/lib/ares__htable_vpvp.c b/deps/cares/src/lib/dsa/ares__htable_vpvp.c similarity index 100% rename from deps/cares/src/lib/ares__htable_vpvp.c rename to deps/cares/src/lib/dsa/ares__htable_vpvp.c diff --git a/deps/cares/src/lib/ares__htable_vpvp.h b/deps/cares/src/lib/dsa/ares__htable_vpvp.h similarity index 100% rename from deps/cares/src/lib/ares__htable_vpvp.h rename to deps/cares/src/lib/dsa/ares__htable_vpvp.h diff --git a/deps/cares/src/lib/ares__llist.c b/deps/cares/src/lib/dsa/ares__llist.c similarity index 100% rename from deps/cares/src/lib/ares__llist.c rename to deps/cares/src/lib/dsa/ares__llist.c diff --git a/deps/cares/src/lib/ares__llist.h b/deps/cares/src/lib/dsa/ares__llist.h similarity index 100% rename from deps/cares/src/lib/ares__llist.h rename to deps/cares/src/lib/dsa/ares__llist.h diff --git a/deps/cares/src/lib/ares__slist.c b/deps/cares/src/lib/dsa/ares__slist.c similarity index 100% rename from deps/cares/src/lib/ares__slist.c rename to deps/cares/src/lib/dsa/ares__slist.c diff --git a/deps/cares/src/lib/ares__slist.h b/deps/cares/src/lib/dsa/ares__slist.h similarity index 100% rename from deps/cares/src/lib/ares__slist.h rename to deps/cares/src/lib/dsa/ares__slist.h diff --git a/deps/cares/src/lib/ares_event.h b/deps/cares/src/lib/event/ares_event.h similarity index 100% rename from deps/cares/src/lib/ares_event.h rename to deps/cares/src/lib/event/ares_event.h diff --git a/deps/cares/src/lib/ares_event_configchg.c b/deps/cares/src/lib/event/ares_event_configchg.c similarity index 94% rename from deps/cares/src/lib/ares_event_configchg.c rename to deps/cares/src/lib/event/ares_event_configchg.c index 1d5d026ba39..10f0e21dde7 100644 --- a/deps/cares/src/lib/ares_event_configchg.c +++ b/deps/cares/src/lib/event/ares_event_configchg.c @@ -31,6 +31,8 @@ ares_status_t ares_event_configchg_init(ares_event_configchg_t **configchg, ares_event_thread_t *e) { + (void)configchg; + (void)e; /* No ability */ return ARES_ENOTIMP; } @@ -38,6 +40,7 @@ ares_status_t ares_event_configchg_init(ares_event_configchg_t **configchg, void ares_event_configchg_destroy(ares_event_configchg_t *configchg) { /* No-op */ + (void)configchg; } #elif defined(__linux__) @@ -107,7 +110,7 @@ static void ares_event_configchg_cb(ares_event_thread_t *e, ares_socket_t fd, * size provided, so I assume it won't ever return partial events. */ for (ptr = buf; ptr < buf + len; ptr += sizeof(struct inotify_event) + event->len) { - event = (const struct inotify_event *)ptr; + event = (const struct inotify_event *)((const void *)ptr); if (event->len == 0 || ares_strlen(event->name) == 0) { continue; @@ -195,13 +198,14 @@ void ares_event_configchg_destroy(ares_event_configchg_t *configchg) return; } -# ifndef __WATCOMC__ +# ifdef HAVE_NOTIFYIPINTERFACECHANGE if (configchg->ifchg_hnd != NULL) { CancelMibChangeNotify2(configchg->ifchg_hnd); configchg->ifchg_hnd = NULL; } # endif +# ifdef HAVE_REGISTERWAITFORSINGLEOBJECT if (configchg->regip4_wait != NULL) { UnregisterWait(configchg->regip4_wait); configchg->regip4_wait = NULL; @@ -231,15 +235,15 @@ void ares_event_configchg_destroy(ares_event_configchg_t *configchg) CloseHandle(configchg->regip6_event); configchg->regip6_event = NULL; } +# endif ares_free(configchg); } -# ifndef __WATCOMC__ +# ifdef HAVE_NOTIFYIPINTERFACECHANGE static void NETIOAPI_API_ - ares_event_configchg_ip_cb(PVOID CallerContext, - PMIB_IPINTERFACE_ROW Row, + ares_event_configchg_ip_cb(PVOID CallerContext, PMIB_IPINTERFACE_ROW Row, MIB_NOTIFICATION_TYPE NotificationType) { ares_event_configchg_t *configchg = CallerContext; @@ -252,9 +256,10 @@ static void NETIOAPI_API_ static ares_bool_t ares_event_configchg_regnotify(ares_event_configchg_t *configchg) { -# if defined(__WATCOMC__) && !defined(REG_NOTIFY_THREAD_AGNOSTIC) -# define REG_NOTIFY_THREAD_AGNOSTIC 0x10000000L -# endif +# ifdef HAVE_REGISTERWAITFORSINGLEOBJECT +# if defined(__WATCOMC__) && !defined(REG_NOTIFY_THREAD_AGNOSTIC) +# define REG_NOTIFY_THREAD_AGNOSTIC 0x10000000L +# endif DWORD flags = REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_LAST_SET | REG_NOTIFY_THREAD_AGNOSTIC; @@ -267,7 +272,9 @@ static ares_bool_t configchg->regip6_event, TRUE) != ERROR_SUCCESS) { return ARES_FALSE; } - +# else + (void)configchg; +# endif return ARES_TRUE; } @@ -297,27 +304,27 @@ ares_status_t ares_event_configchg_init(ares_event_configchg_t **configchg, c->e = e; -# ifndef __WATCOMC__ +# ifdef HAVE_NOTIFYIPINTERFACECHANGE /* NOTE: If a user goes into the control panel and changes the network * adapter DNS addresses manually, this will NOT trigger a notification. * We've also tried listening on NotifyUnicastIpAddressChange(), but * that didn't get triggered either. */ - if (NotifyIpInterfaceChange( - AF_UNSPEC, ares_event_configchg_ip_cb, - c, FALSE, &c->ifchg_hnd) != NO_ERROR) { + if (NotifyIpInterfaceChange(AF_UNSPEC, ares_event_configchg_ip_cb, c, FALSE, + &c->ifchg_hnd) != NO_ERROR) { status = ARES_ESERVFAIL; goto done; } # endif +# ifdef HAVE_REGISTERWAITFORSINGLEOBJECT /* Monitor HKLM\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters\Interfaces * and HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces * for changes via RegNotifyChangeKeyValue() */ if (RegOpenKeyExW( HKEY_LOCAL_MACHINE, - L"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces", 0, - KEY_NOTIFY, &c->regip4) != ERROR_SUCCESS) { + L"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces", + 0, KEY_NOTIFY, &c->regip4) != ERROR_SUCCESS) { status = ARES_ESERVFAIL; goto done; } @@ -355,6 +362,7 @@ ares_status_t ares_event_configchg_init(ares_event_configchg_t **configchg, status = ARES_ESERVFAIL; goto done; } +# endif if (!ares_event_configchg_regnotify(c)) { status = ARES_ESERVFAIL; @@ -472,8 +480,8 @@ ares_status_t ares_event_configchg_init(ares_event_configchg_t **configchg, continue; } - pdns_configuration_notify_key = (const char *(*)(void)) - dlsym(handle, "dns_configuration_notify_key"); + pdns_configuration_notify_key = + (const char *(*)(void))dlsym(handle, "dns_configuration_notify_key"); if (pdns_configuration_notify_key != NULL) { break; } @@ -551,7 +559,7 @@ static ares_status_t config_change_check(ares__htable_strvp_t *filestat, { size_t i; const char *configfiles[5]; - ares_bool_t changed = ARES_FALSE; + ares_bool_t changed = ARES_FALSE; configfiles[0] = resolvconf_path; configfiles[1] = "/etc/nsswitch.conf"; diff --git a/deps/cares/src/lib/ares_event_epoll.c b/deps/cares/src/lib/event/ares_event_epoll.c similarity index 100% rename from deps/cares/src/lib/ares_event_epoll.c rename to deps/cares/src/lib/event/ares_event_epoll.c diff --git a/deps/cares/src/lib/ares_event_kqueue.c b/deps/cares/src/lib/event/ares_event_kqueue.c similarity index 96% rename from deps/cares/src/lib/ares_event_kqueue.c rename to deps/cares/src/lib/event/ares_event_kqueue.c index aedd99ec42d..1c35c14f165 100644 --- a/deps/cares/src/lib/ares_event_kqueue.c +++ b/deps/cares/src/lib/event/ares_event_kqueue.c @@ -123,11 +123,9 @@ static void ares_evsys_kqueue_enqueue(ares_evsys_kqueue_t *kq, int fd, if (kq->nchanges > kq->nchanges_alloc) { kq->nchanges_alloc <<= 1; - kq->changelist = ares_realloc_zero( - kq->changelist, - (kq->nchanges_alloc >> 1) * sizeof(*kq->changelist), - kq->nchanges_alloc * sizeof(*kq->changelist) - ); + kq->changelist = ares_realloc_zero( + kq->changelist, (kq->nchanges_alloc >> 1) * sizeof(*kq->changelist), + kq->nchanges_alloc * sizeof(*kq->changelist)); } EV_SET(&kq->changelist[idx], fd, filter, flags, 0, 0, 0); @@ -198,7 +196,7 @@ static size_t ares_evsys_kqueue_wait(ares_event_thread_t *e, size_t cnt = 0; if (timeout_ms != 0) { - ts.tv_sec = timeout_ms / 1000; + ts.tv_sec = (time_t)timeout_ms / 1000; ts.tv_nsec = (timeout_ms % 1000) * 1000 * 1000; timeout = &ts; } diff --git a/deps/cares/src/lib/ares_event_poll.c b/deps/cares/src/lib/event/ares_event_poll.c similarity index 100% rename from deps/cares/src/lib/ares_event_poll.c rename to deps/cares/src/lib/event/ares_event_poll.c diff --git a/deps/cares/src/lib/ares_event_select.c b/deps/cares/src/lib/event/ares_event_select.c similarity index 100% rename from deps/cares/src/lib/ares_event_select.c rename to deps/cares/src/lib/event/ares_event_select.c diff --git a/deps/cares/src/lib/ares_event_thread.c b/deps/cares/src/lib/event/ares_event_thread.c similarity index 95% rename from deps/cares/src/lib/ares_event_thread.c rename to deps/cares/src/lib/event/ares_event_thread.c index 63d8aa2218a..8b332e9b019 100644 --- a/deps/cares/src/lib/ares_event_thread.c +++ b/deps/cares/src/lib/event/ares_event_thread.c @@ -47,6 +47,23 @@ static void ares_event_destroy_cb(void *arg) ares_free(event); } +static void ares_event_signal(const ares_event_t *event) +{ + if (event == NULL || event->signal_cb == NULL) { + return; /* LCOV_EXCL_LINE: DefensiveCoding */ + } + event->signal_cb(event); +} + +static void ares_event_thread_wake(const ares_event_thread_t *e) +{ + if (e == NULL) { + return; /* LCOV_EXCL_LINE: DefensiveCoding */ + } + + ares_event_signal(e->ev_signal); +} + /* See if a pending update already exists. We don't want to enqueue multiple * updates for the same event handle. Right now this is O(n) based on number * of updates already enqueued. In the future, it might make sense to make @@ -86,6 +103,7 @@ ares_status_t ares_event_update(ares_event_t **event, ares_event_thread_t *e, ares_event_signal_cb_t signal_cb) { ares_event_t *ev = NULL; + ares_status_t status; if (e == NULL) { return ARES_EFORMERR; /* LCOV_EXCL_LINE: DefensiveCoding */ @@ -116,18 +134,22 @@ ares_status_t ares_event_update(ares_event_t **event, ares_event_thread_t *e, /* That's all the validation we can really do */ + ares__thread_mutex_lock(e->mutex); + /* See if we have a queued update already */ ev = ares_event_update_find(e, fd, data); if (ev == NULL) { /* Allocate a new one */ ev = ares_malloc_zero(sizeof(*ev)); if (ev == NULL) { - return ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ + status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ + goto done; /* LCOV_EXCL_LINE: OutOfMemory */ } if (ares__llist_insert_last(e->ev_updates, ev) == NULL) { - ares_free(ev); /* LCOV_EXCL_LINE: OutOfMemory */ - return ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ + ares_free(ev); /* LCOV_EXCL_LINE: OutOfMemory */ + status = ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ + goto done; /* LCOV_EXCL_LINE: OutOfMemory */ } } @@ -150,24 +172,17 @@ ares_status_t ares_event_update(ares_event_t **event, ares_event_thread_t *e, *event = ev; } - return ARES_SUCCESS; -} + status = ARES_SUCCESS; -static void ares_event_signal(const ares_event_t *event) -{ - if (event == NULL || event->signal_cb == NULL) { - return; /* LCOV_EXCL_LINE: DefensiveCoding */ +done: + if (status == ARES_SUCCESS) { + /* Wake event thread if successful so it can pull the updates */ + ares_event_thread_wake(e); } - event->signal_cb(event); -} -static void ares_event_thread_wake(const ares_event_thread_t *e) -{ - if (e == NULL) { - return; /* LCOV_EXCL_LINE: DefensiveCoding */ - } + ares__thread_mutex_unlock(e->mutex); - ares_event_signal(e->ev_signal); + return status; } static void ares_event_thread_process_fd(ares_event_thread_t *e, @@ -195,15 +210,10 @@ static void ares_event_thread_sockstate_cb(void *data, ares_socket_t socket_fd, flags |= ARES_EVENT_FLAG_WRITE; } - /* Update channel fd */ - ares__thread_mutex_lock(e->mutex); + /* Update channel fd. This function will lock e->mutex and also wake the + * event thread to process the update */ ares_event_update(NULL, e, flags, ares_event_thread_process_fd, socket_fd, NULL, NULL, NULL); - - /* Wake the event thread so it properly enqueues any updates */ - ares_event_thread_wake(e); - - ares__thread_mutex_unlock(e->mutex); } static void ares_event_process_updates(ares_event_thread_t *e) @@ -370,7 +380,7 @@ void ares_event_thread_destroy(ares_channel_t *channel) ares_event_thread_destroy_int(e); channel->sock_state_cb_data = NULL; - channel->sock_state_cb = NULL; + channel->sock_state_cb = NULL; } static const ares_event_sys_t *ares_event_fetch_sys(ares_evsys_t evsys) diff --git a/deps/cares/src/lib/ares_event_wake_pipe.c b/deps/cares/src/lib/event/ares_event_wake_pipe.c similarity index 100% rename from deps/cares/src/lib/ares_event_wake_pipe.c rename to deps/cares/src/lib/event/ares_event_wake_pipe.c diff --git a/deps/cares/src/lib/ares_event_win32.c b/deps/cares/src/lib/event/ares_event_win32.c similarity index 99% rename from deps/cares/src/lib/ares_event_win32.c rename to deps/cares/src/lib/event/ares_event_win32.c index 173d0ca9c9d..0b7e535bbbf 100644 --- a/deps/cares/src/lib/ares_event_win32.c +++ b/deps/cares/src/lib/event/ares_event_win32.c @@ -25,9 +25,13 @@ */ /* Uses an anonymous union */ -#if defined(__clang__) +#if defined(__clang__) || defined(__GNUC__) # pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wc11-extensions" +# if defined(__clang__) +# pragma GCC diagnostic ignored "-Wc11-extensions" +# else +# pragma GCC diagnostic ignored "-Wpedantic" +# endif #endif #include "ares_private.h" @@ -967,6 +971,6 @@ const ares_event_sys_t ares_evsys_win32 = { "win32", ares_evsys_win32_wait }; #endif -#if defined(__clang__) +#if defined(__clang__) || defined(__GNUC__) # pragma GCC diagnostic pop #endif diff --git a/deps/cares/src/lib/ares_event_win32.h b/deps/cares/src/lib/event/ares_event_win32.h similarity index 100% rename from deps/cares/src/lib/ares_event_win32.h rename to deps/cares/src/lib/event/ares_event_win32.h diff --git a/deps/cares/src/lib/inet_net_pton.c b/deps/cares/src/lib/inet_net_pton.c index 935058da9ce..5356778c47b 100644 --- a/deps/cares/src/lib/inet_net_pton.c +++ b/deps/cares/src/lib/inet_net_pton.c @@ -32,11 +32,6 @@ #include "ares_ipv6.h" #include "ares_inet_net_pton.h" -#define ISDIGIT(x) (isdigit((int)((unsigned char)x))) -#define ISXDIGIT(x) (isxdigit((int)((unsigned char)x))) -#define ISASCII(x) (((unsigned char)x) <= 127 ? 1 : 0) -#define ISUPPER(x) (isupper((int)((unsigned char)x))) - const struct ares_in6_addr ares_in6addr_any = { { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } } }; @@ -74,16 +69,16 @@ static int ares_inet_net_pton_ipv4(const char *src, unsigned char *dst, const unsigned char *odst = dst; ch = *src++; - if (ch == '0' && (src[0] == 'x' || src[0] == 'X') && ISASCII(src[1]) && - ISXDIGIT(src[1])) { + if (ch == '0' && (src[0] == 'x' || src[0] == 'X') && ares__isascii(src[1]) && + ares__isxdigit(src[1])) { /* Hexadecimal: Eat nybble string. */ if (!size) { goto emsgsize; } dirty = 0; src++; /* skip x or X. */ - while ((ch = *src++) != '\0' && ISASCII(ch) && ISXDIGIT(ch)) { - if (ISUPPER(ch)) { + while ((ch = *src++) != '\0' && ares__isascii(ch) && ares__isxdigit(ch)) { + if (ares__isupper(ch)) { ch = ares__tolower((unsigned char)ch); } n = (int)(strchr(xdigits, ch) - xdigits); @@ -106,7 +101,7 @@ static int ares_inet_net_pton_ipv4(const char *src, unsigned char *dst, } *dst++ = (unsigned char)(tmp << 4); } - } else if (ISASCII(ch) && ISDIGIT(ch)) { + } else if (ares__isascii(ch) && ares__isdigit(ch)) { /* Decimal: eat dotted digit string. */ for (;;) { tmp = 0; @@ -117,7 +112,7 @@ static int ares_inet_net_pton_ipv4(const char *src, unsigned char *dst, if (tmp > 255) { goto enoent; } - } while ((ch = *src++) != '\0' && ISASCII(ch) && ISDIGIT(ch)); + } while ((ch = *src++) != '\0' && ares__isascii(ch) && ares__isdigit(ch)); if (!size--) { goto emsgsize; } @@ -129,7 +124,7 @@ static int ares_inet_net_pton_ipv4(const char *src, unsigned char *dst, goto enoent; } ch = *src++; - if (!ISASCII(ch) || !ISDIGIT(ch)) { + if (!ares__isascii(ch) || !ares__isdigit(ch)) { goto enoent; } } @@ -138,7 +133,8 @@ static int ares_inet_net_pton_ipv4(const char *src, unsigned char *dst, } bits = -1; - if (ch == '/' && ISASCII(src[0]) && ISDIGIT(src[0]) && dst > odst) { + if (ch == '/' && ares__isascii(src[0]) && ares__isdigit(src[0]) && + dst > odst) { /* CIDR width specifier. Nothing can follow it. */ ch = *src++; /* Skip over the /. */ bits = 0; @@ -149,7 +145,7 @@ static int ares_inet_net_pton_ipv4(const char *src, unsigned char *dst, if (bits > 32) { goto enoent; } - } while ((ch = *src++) != '\0' && ISASCII(ch) && ISDIGIT(ch)); + } while ((ch = *src++) != '\0' && ares__isascii(ch) && ares__isdigit(ch)); if (ch != '\0') { goto enoent; } diff --git a/deps/cares/src/lib/inet_ntop.c b/deps/cares/src/lib/inet_ntop.c index 8dee8d69da7..6f96b92cccc 100644 --- a/deps/cares/src/lib/inet_ntop.c +++ b/deps/cares/src/lib/inet_ntop.c @@ -138,7 +138,7 @@ static const char *inet_ntop6(const unsigned char *src, char *dst, size_t size) if (words[i] == 0) { if (cur.base == -1) { cur.base = (ares_ssize_t)i; - cur.len = 1; + cur.len = 1; } else { cur.len++; } @@ -166,7 +166,8 @@ static const char *inet_ntop6(const unsigned char *src, char *dst, size_t size) tp = tmp; for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) { /* Are we inside the best run of 0x00's? */ - if (best.base != -1 && i >= (size_t)best.base && i < ((size_t)best.base + best.len)) { + if (best.base != -1 && i >= (size_t)best.base && + i < ((size_t)best.base + best.len)) { if (i == (size_t)best.base) { *tp++ = ':'; } @@ -205,4 +206,3 @@ static const char *inet_ntop6(const unsigned char *src, char *dst, size_t size) ares_strcpy(dst, tmp, size); return dst; } - diff --git a/deps/cares/src/lib/ares_create_query.c b/deps/cares/src/lib/legacy/ares_create_query.c similarity index 100% rename from deps/cares/src/lib/ares_create_query.c rename to deps/cares/src/lib/legacy/ares_create_query.c diff --git a/deps/cares/src/lib/ares_expand_name.c b/deps/cares/src/lib/legacy/ares_expand_name.c similarity index 100% rename from deps/cares/src/lib/ares_expand_name.c rename to deps/cares/src/lib/legacy/ares_expand_name.c diff --git a/deps/cares/src/lib/ares_expand_string.c b/deps/cares/src/lib/legacy/ares_expand_string.c similarity index 97% rename from deps/cares/src/lib/ares_expand_string.c rename to deps/cares/src/lib/legacy/ares_expand_string.c index 570ccd917a3..b3e99daa54b 100644 --- a/deps/cares/src/lib/ares_expand_string.c +++ b/deps/cares/src/lib/legacy/ares_expand_string.c @@ -74,8 +74,7 @@ ares_status_t ares_expand_string_ex(const unsigned char *encoded, } start_len = ares__buf_len(buf); - status = - ares__buf_parse_dns_binstr(buf, ares__buf_len(buf), s, &len); + status = ares__buf_parse_dns_binstr(buf, ares__buf_len(buf), s, &len); /* hrm, no way to pass back 'len' with the prototype */ if (status != ARES_SUCCESS) { goto done; diff --git a/deps/cares/src/lib/ares_fds.c b/deps/cares/src/lib/legacy/ares_fds.c similarity index 88% rename from deps/cares/src/lib/ares_fds.c rename to deps/cares/src/lib/legacy/ares_fds.c index 0502e71182a..3aedd2c90e2 100644 --- a/deps/cares/src/lib/ares_fds.c +++ b/deps/cares/src/lib/legacy/ares_fds.c @@ -45,14 +45,14 @@ int ares_fds(const ares_channel_t *channel, fd_set *read_fds, fd_set *write_fds) nfds = 0; for (snode = ares__slist_node_first(channel->servers); snode != NULL; snode = ares__slist_node_next(snode)) { - struct server_state *server = ares__slist_node_val(snode); - ares__llist_node_t *node; + ares_server_t *server = ares__slist_node_val(snode); + ares__llist_node_t *node; for (node = ares__llist_node_first(server->connections); node != NULL; node = ares__llist_node_next(node)) { - const struct server_connection *conn = ares__llist_node_val(node); + const ares_conn_t *conn = ares__llist_node_val(node); - if (!active_queries && !conn->is_tcp) { + if (!active_queries && !(conn->flags & ARES_CONN_FLAG_TCP)) { continue; } @@ -69,7 +69,7 @@ int ares_fds(const ares_channel_t *channel, fd_set *read_fds, fd_set *write_fds) } /* TCP only wait on write if we have buffered data */ - if (conn->is_tcp && ares__buf_len(server->tcp_send)) { + if (conn->flags & ARES_CONN_FLAG_TCP && ares__buf_len(server->tcp_send)) { FD_SET(conn->fd, write_fds); } } diff --git a/deps/cares/src/lib/ares_getsock.c b/deps/cares/src/lib/legacy/ares_getsock.c similarity index 87% rename from deps/cares/src/lib/ares_getsock.c rename to deps/cares/src/lib/legacy/ares_getsock.c index 836d9b973ed..8c8476fa951 100644 --- a/deps/cares/src/lib/ares_getsock.c +++ b/deps/cares/src/lib/legacy/ares_getsock.c @@ -47,12 +47,12 @@ int ares_getsock(const ares_channel_t *channel, ares_socket_t *socks, for (snode = ares__slist_node_first(channel->servers); snode != NULL; snode = ares__slist_node_next(snode)) { - struct server_state *server = ares__slist_node_val(snode); - ares__llist_node_t *node; + ares_server_t *server = ares__slist_node_val(snode); + ares__llist_node_t *node; for (node = ares__llist_node_first(server->connections); node != NULL; node = ares__llist_node_next(node)) { - const struct server_connection *conn = ares__llist_node_val(node); + const ares_conn_t *conn = ares__llist_node_val(node); if (sockindex >= (size_t)numsocks || sockindex >= ARES_GETSOCK_MAXNUM) { break; @@ -61,17 +61,17 @@ int ares_getsock(const ares_channel_t *channel, ares_socket_t *socks, /* We only need to register interest in UDP sockets if we have * outstanding queries. */ - if (!active_queries && !conn->is_tcp) { + if (!active_queries && !(conn->flags & ARES_CONN_FLAG_TCP)) { continue; } socks[sockindex] = conn->fd; - if (active_queries || conn->is_tcp) { + if (active_queries || conn->flags & ARES_CONN_FLAG_TCP) { bitmap |= ARES_GETSOCK_READABLE(setbits, sockindex); } - if (conn->is_tcp && ares__buf_len(server->tcp_send)) { + if (conn->flags & ARES_CONN_FLAG_TCP && ares__buf_len(server->tcp_send)) { /* then the tcp socket is also writable! */ bitmap |= ARES_GETSOCK_WRITABLE(setbits, sockindex); } diff --git a/deps/cares/src/lib/ares_parse_a_reply.c b/deps/cares/src/lib/legacy/ares_parse_a_reply.c similarity index 100% rename from deps/cares/src/lib/ares_parse_a_reply.c rename to deps/cares/src/lib/legacy/ares_parse_a_reply.c diff --git a/deps/cares/src/lib/ares_parse_aaaa_reply.c b/deps/cares/src/lib/legacy/ares_parse_aaaa_reply.c similarity index 100% rename from deps/cares/src/lib/ares_parse_aaaa_reply.c rename to deps/cares/src/lib/legacy/ares_parse_aaaa_reply.c diff --git a/deps/cares/src/lib/ares_parse_caa_reply.c b/deps/cares/src/lib/legacy/ares_parse_caa_reply.c similarity index 100% rename from deps/cares/src/lib/ares_parse_caa_reply.c rename to deps/cares/src/lib/legacy/ares_parse_caa_reply.c diff --git a/deps/cares/src/lib/ares_parse_mx_reply.c b/deps/cares/src/lib/legacy/ares_parse_mx_reply.c similarity index 100% rename from deps/cares/src/lib/ares_parse_mx_reply.c rename to deps/cares/src/lib/legacy/ares_parse_mx_reply.c diff --git a/deps/cares/src/lib/ares_parse_naptr_reply.c b/deps/cares/src/lib/legacy/ares_parse_naptr_reply.c similarity index 100% rename from deps/cares/src/lib/ares_parse_naptr_reply.c rename to deps/cares/src/lib/legacy/ares_parse_naptr_reply.c diff --git a/deps/cares/src/lib/ares_parse_ns_reply.c b/deps/cares/src/lib/legacy/ares_parse_ns_reply.c similarity index 100% rename from deps/cares/src/lib/ares_parse_ns_reply.c rename to deps/cares/src/lib/legacy/ares_parse_ns_reply.c diff --git a/deps/cares/src/lib/ares_parse_ptr_reply.c b/deps/cares/src/lib/legacy/ares_parse_ptr_reply.c similarity index 100% rename from deps/cares/src/lib/ares_parse_ptr_reply.c rename to deps/cares/src/lib/legacy/ares_parse_ptr_reply.c diff --git a/deps/cares/src/lib/ares_parse_soa_reply.c b/deps/cares/src/lib/legacy/ares_parse_soa_reply.c similarity index 100% rename from deps/cares/src/lib/ares_parse_soa_reply.c rename to deps/cares/src/lib/legacy/ares_parse_soa_reply.c diff --git a/deps/cares/src/lib/ares_parse_srv_reply.c b/deps/cares/src/lib/legacy/ares_parse_srv_reply.c similarity index 100% rename from deps/cares/src/lib/ares_parse_srv_reply.c rename to deps/cares/src/lib/legacy/ares_parse_srv_reply.c diff --git a/deps/cares/src/lib/ares_parse_txt_reply.c b/deps/cares/src/lib/legacy/ares_parse_txt_reply.c similarity index 99% rename from deps/cares/src/lib/ares_parse_txt_reply.c rename to deps/cares/src/lib/legacy/ares_parse_txt_reply.c index cd280332d23..71ee0841119 100644 --- a/deps/cares/src/lib/ares_parse_txt_reply.c +++ b/deps/cares/src/lib/legacy/ares_parse_txt_reply.c @@ -71,7 +71,7 @@ static int ares__parse_txt_reply(const unsigned char *abuf, size_t alen, cnt = ares_dns_rr_get_abin_cnt(rr, ARES_RR_TXT_DATA); - for (j=0; jdata); +} + ares__dns_multistring_t *ares__dns_multistring_create(void) { - return ares_malloc_zero(sizeof(ares__dns_multistring_t)); + ares__dns_multistring_t *strs = ares_malloc_zero(sizeof(*strs)); + if (strs == NULL) { + return NULL; + } + + strs->strs = ares__array_create(sizeof(multistring_data_t), + ares__dns_multistring_free_cb); + if (strs->strs == NULL) { + ares_free(strs); + return NULL; + } + + return strs; } void ares__dns_multistring_clear(ares__dns_multistring_t *strs) { - size_t i; - if (strs == NULL) { return; } - for (i = 0; i < strs->cnt; i++) { - ares_free(strs->strs[i].data); - memset(&strs->strs[i], 0, sizeof(strs->strs[i])); + while (ares__array_len(strs->strs)) { + ares__array_remove_last(strs->strs); } - strs->cnt = 0; } void ares__dns_multistring_destroy(ares__dns_multistring_t *strs) @@ -70,7 +85,7 @@ void ares__dns_multistring_destroy(ares__dns_multistring_t *strs) return; } ares__dns_multistring_clear(strs); - ares_free(strs->strs); + ares__array_destroy(strs->strs); ares_free(strs->cache_str); ares_free(strs); } @@ -79,43 +94,43 @@ ares_status_t ares__dns_multistring_replace_own(ares__dns_multistring_t *strs, size_t idx, unsigned char *str, size_t len) { - if (strs == NULL || str == NULL || len == 0 || idx >= strs->cnt) { + multistring_data_t *data; + + if (strs == NULL || str == NULL || len == 0) { return ARES_EFORMERR; } strs->cache_invalidated = ARES_TRUE; - ares_free(strs->strs[idx].data); - strs->strs[idx].data = str; - strs->strs[idx].len = len; + + data = ares__array_at(strs->strs, idx); + if (data == NULL) { + return ARES_EFORMERR; + } + + ares_free(data->data); + data->data = str; + data->len = len; return ARES_SUCCESS; } ares_status_t ares__dns_multistring_del(ares__dns_multistring_t *strs, size_t idx) { - size_t move_cnt; - - if (strs == NULL || idx >= strs->cnt) { + if (strs == NULL) { return ARES_EFORMERR; } strs->cache_invalidated = ARES_TRUE; - ares_free(strs->strs[idx].data); - - move_cnt = strs->cnt - idx - 1; - if (move_cnt) { - memmove(&strs->strs[idx], &strs->strs[idx + 1], - sizeof(*strs->strs) * move_cnt); - } - - strs->cnt--; - return ARES_SUCCESS; + return ares__array_remove_at(strs->strs, idx); } ares_status_t ares__dns_multistring_add_own(ares__dns_multistring_t *strs, unsigned char *str, size_t len) { + multistring_data_t *data; + ares_status_t status; + if (strs == NULL) { return ARES_EFORMERR; } @@ -127,20 +142,13 @@ ares_status_t ares__dns_multistring_add_own(ares__dns_multistring_t *strs, return ARES_EFORMERR; } - if (strs->alloc < strs->cnt + 1) { - size_t newalloc = (strs->alloc == 0) ? 1 : (strs->alloc << 1); - void *ptr = ares_realloc_zero(strs->strs, strs->alloc * sizeof(*strs->strs), - (newalloc) * sizeof(*strs->strs)); - if (ptr == NULL) { - return ARES_ENOMEM; - } - strs->strs = ptr; - strs->alloc = newalloc; + status = ares__array_insert_last((void **)&data, strs->strs); + if (status != ARES_SUCCESS) { + return status; } - strs->strs[strs->cnt].data = str; - strs->strs[strs->cnt].len = len; - strs->cnt++; + data->data = str; + data->len = len; return ARES_SUCCESS; } @@ -150,18 +158,26 @@ size_t ares__dns_multistring_cnt(const ares__dns_multistring_t *strs) if (strs == NULL) { return 0; } - return strs->cnt; + return ares__array_len(strs->strs); } -const unsigned char *ares__dns_multistring_get( - const ares__dns_multistring_t *strs, size_t idx, size_t *len) +const unsigned char * + ares__dns_multistring_get(const ares__dns_multistring_t *strs, size_t idx, + size_t *len) { - if (strs == NULL || idx >= strs->cnt || len == NULL) { + const multistring_data_t *data; + + if (strs == NULL || len == NULL) { + return NULL; + } + + data = ares__array_at_const(strs->strs, idx); + if (data == NULL) { return NULL; } - *len = strs->strs[idx].len; - return strs->strs[idx].data; + *len = data->len; + return data->data; } const unsigned char * @@ -189,9 +205,10 @@ const unsigned char * buf = ares__buf_create(); - for (i = 0; i < strs->cnt; i++) { - if (ares__buf_append(buf, strs->strs[i].data, strs->strs[i].len) != - ARES_SUCCESS) { + for (i = 0; i < ares__array_len(strs->strs); i++) { + const multistring_data_t *data = ares__array_at_const(strs->strs, i); + if (data == NULL || + ares__buf_append(buf, data->data, data->len) != ARES_SUCCESS) { ares__buf_destroy(buf); return NULL; } diff --git a/deps/cares/src/lib/ares_dns_multistring.h b/deps/cares/src/lib/record/ares_dns_multistring.h similarity index 94% rename from deps/cares/src/lib/ares_dns_multistring.h rename to deps/cares/src/lib/record/ares_dns_multistring.h index 3588f5615c3..d9aa7ae3784 100644 --- a/deps/cares/src/lib/ares_dns_multistring.h +++ b/deps/cares/src/lib/record/ares_dns_multistring.h @@ -40,8 +40,9 @@ ares_status_t ares__dns_multistring_del(ares__dns_multistring_t *strs, ares_status_t ares__dns_multistring_add_own(ares__dns_multistring_t *strs, unsigned char *str, size_t len); size_t ares__dns_multistring_cnt(const ares__dns_multistring_t *strs); -const unsigned char *ares__dns_multistring_get( - const ares__dns_multistring_t *strs, size_t idx, size_t *len); +const unsigned char * + ares__dns_multistring_get(const ares__dns_multistring_t *strs, size_t idx, + size_t *len); const unsigned char * ares__dns_multistring_get_combined(ares__dns_multistring_t *strs, size_t *len); diff --git a/deps/cares/src/lib/ares_dns_name.c b/deps/cares/src/lib/record/ares_dns_name.c similarity index 87% rename from deps/cares/src/lib/ares_dns_name.c rename to deps/cares/src/lib/record/ares_dns_name.c index 076d26643eb..a437553b0f2 100644 --- a/deps/cares/src/lib/ares_dns_name.c +++ b/deps/cares/src/lib/record/ares_dns_name.c @@ -131,72 +131,62 @@ static const ares_nameoffset_t *ares__nameoffset_find(ares__llist_t *list, return longest_match; } -typedef struct { - ares__buf_t **label; - size_t num; -} ares_dns_labels_t; - -static void ares_dns_labels_free(ares_dns_labels_t *labels) +static void ares_dns_labels_free_cb(void *arg) { - size_t i; - - if (labels == NULL) { - return; /* LCOV_EXCL_LINE: DefensiveCoding */ + ares__buf_t **buf = arg; + if (buf == NULL) { + return; } - for (i = 0; i < labels->num; i++) { - ares__buf_destroy(labels->label[i]); - labels->label[i] = NULL; - } - ares_free(labels->label); - labels->label = NULL; - labels->num = 0; + ares__buf_destroy(*buf); } -static ares__buf_t *ares_dns_labels_add(ares_dns_labels_t *labels) +static ares__buf_t *ares_dns_labels_add(ares__array_t *labels) { - void *temp; + ares__buf_t **buf; if (labels == NULL) { return NULL; /* LCOV_EXCL_LINE: DefensiveCoding */ } - temp = ares_realloc_zero(labels->label, sizeof(*labels->label) * labels->num, - sizeof(*labels->label) * (labels->num + 1)); - if (temp == NULL) { - return NULL; /* LCOV_EXCL_LINE: OutOfMemory */ + if (ares__array_insert_last((void **)&buf, labels) != ARES_SUCCESS) { + return NULL; } - labels->label = temp; - - labels->label[labels->num] = ares__buf_create(); - if (labels->label[labels->num] == NULL) { - return NULL; /* LCOV_EXCL_LINE: OutOfMemory */ + *buf = ares__buf_create(); + if (*buf == NULL) { + ares__array_remove_last(labels); + return NULL; } - labels->num++; - return labels->label[labels->num - 1]; + return *buf; } -static const ares__buf_t * - ares_dns_labels_get_last(const ares_dns_labels_t *labels) +static ares__buf_t *ares_dns_labels_get_last(ares__array_t *labels) { - if (labels == NULL || labels->num == 0) { - return NULL; /* LCOV_EXCL_LINE: DefensiveCoding */ + ares__buf_t **buf = ares__array_last(labels); + + if (buf == NULL) { + return NULL; } - return labels->label[labels->num - 1]; + return *buf; } -static void ares_dns_name_labels_del_last(ares_dns_labels_t *labels) +static ares__buf_t *ares_dns_labels_get_at(ares__array_t *labels, size_t idx) { - if (labels == NULL || labels->num == 0) { - return; /* LCOV_EXCL_LINE: DefensiveCoding */ + ares__buf_t **buf = ares__array_at(labels, idx); + + if (buf == NULL) { + return NULL; } - ares__buf_destroy(labels->label[labels->num - 1]); - labels->label[labels->num - 1] = NULL; - labels->num--; + return *buf; +} + +static void ares_dns_name_labels_del_last(ares__array_t *labels) +{ + ares__array_remove_last(labels); } static ares_status_t ares_parse_dns_name_escape(ares__buf_t *namebuf, @@ -212,7 +202,7 @@ static ares_status_t ares_parse_dns_name_escape(ares__buf_t *namebuf, } /* If next character is a digit, read 2 more digits */ - if (isdigit(c)) { + if (ares__isdigit(c)) { size_t i; unsigned int val = 0; @@ -224,7 +214,7 @@ static ares_status_t ares_parse_dns_name_escape(ares__buf_t *namebuf, return ARES_EBADNAME; } - if (!isdigit(c)) { + if (!ares__isdigit(c)) { return ARES_EBADNAME; } val *= 10; @@ -251,9 +241,9 @@ static ares_status_t ares_parse_dns_name_escape(ares__buf_t *namebuf, return ares__buf_append_byte(label, c); } -static ares_status_t ares_split_dns_name(ares_dns_labels_t *labels, - ares_bool_t validate_hostname, - const char *name) +static ares_status_t ares_split_dns_name(ares__array_t *labels, + ares_bool_t validate_hostname, + const char *name) { ares_status_t status; ares__buf_t *label = NULL; @@ -327,14 +317,15 @@ static ares_status_t ares_split_dns_name(ares_dns_labels_t *labels, /* If someone passed in "." there could have been 2 blank labels, check for * that */ - if (labels->num == 1 && + if (ares__array_len(labels) == 1 && ares__buf_len(ares_dns_labels_get_last(labels)) == 0) { ares_dns_name_labels_del_last(labels); } /* Scan to make sure label lengths are valid */ - for (i = 0; i < labels->num; i++) { - size_t len = ares__buf_len(labels->label[i]); + for (i = 0; i < ares__array_len(labels); i++) { + const ares__buf_t *buf = ares_dns_labels_get_at(labels, i); + size_t len = ares__buf_len(buf); /* No 0-length labels, and no labels over 63 bytes */ if (len == 0 || len > 63) { status = ARES_EBADNAME; @@ -344,7 +335,8 @@ static ares_status_t ares_split_dns_name(ares_dns_labels_t *labels, } /* Can't exceed maximum (unescaped) length */ - if (labels->num && total_len + labels->num - 1 > 255) { + if (ares__array_len(labels) && + total_len + ares__array_len(labels) - 1 > 255) { status = ARES_EBADNAME; goto done; } @@ -353,9 +345,6 @@ static ares_status_t ares_split_dns_name(ares_dns_labels_t *labels, done: ares__buf_destroy(namebuf); - if (status != ARES_SUCCESS) { - ares_dns_labels_free(labels); - } return status; } @@ -366,8 +355,8 @@ ares_status_t ares__dns_name_write(ares__buf_t *buf, ares__llist_t **list, const ares_nameoffset_t *off = NULL; size_t name_len; size_t orig_name_len; - size_t pos = ares__buf_len(buf); - ares_dns_labels_t labels; + size_t pos = ares__buf_len(buf); + ares__array_t *labels = NULL; char name_copy[512]; ares_status_t status; @@ -375,7 +364,10 @@ ares_status_t ares__dns_name_write(ares__buf_t *buf, ares__llist_t **list, return ARES_EFORMERR; /* LCOV_EXCL_LINE: DefensiveCoding */ } - memset(&labels, 0, sizeof(labels)); + labels = ares__array_create(sizeof(ares__buf_t *), ares_dns_labels_free_cb); + if (labels == NULL) { + return ARES_ENOMEM; + } /* NOTE: due to possible escaping, name_copy buffer is > 256 to allow for * this */ @@ -396,14 +388,15 @@ ares_status_t ares__dns_name_write(ares__buf_t *buf, ares__llist_t **list, if (off == NULL || off->name_len != orig_name_len) { size_t i; - status = ares_split_dns_name(&labels, validate_hostname, name_copy); + status = ares_split_dns_name(labels, validate_hostname, name_copy); if (status != ARES_SUCCESS) { goto done; } - for (i = 0; i < labels.num; i++) { - size_t len = 0; - const unsigned char *ptr = ares__buf_peek(labels.label[i], &len); + for (i = 0; i < ares__array_len(labels); i++) { + size_t len = 0; + const ares__buf_t *lbuf = ares_dns_labels_get_at(labels, i); + const unsigned char *ptr = ares__buf_peek(lbuf, &len); status = ares__buf_append_byte(buf, (unsigned char)(len & 0xFF)); if (status != ARES_SUCCESS) { @@ -448,7 +441,7 @@ ares_status_t ares__dns_name_write(ares__buf_t *buf, ares__llist_t **list, status = ARES_SUCCESS; done: - ares_dns_labels_free(&labels); + ares__array_destroy(labels); return status; } diff --git a/deps/cares/src/lib/ares_dns_parse.c b/deps/cares/src/lib/record/ares_dns_parse.c similarity index 100% rename from deps/cares/src/lib/ares_dns_parse.c rename to deps/cares/src/lib/record/ares_dns_parse.c diff --git a/deps/cares/src/lib/ares_dns_private.h b/deps/cares/src/lib/record/ares_dns_private.h similarity index 76% rename from deps/cares/src/lib/ares_dns_private.h rename to deps/cares/src/lib/record/ares_dns_private.h index 2dd468a5559..5b86fed51f9 100644 --- a/deps/cares/src/lib/ares_dns_private.h +++ b/deps/cares/src/lib/record/ares_dns_private.h @@ -26,7 +26,7 @@ #ifndef __ARES_DNS_PRIVATE_H #define __ARES_DNS_PRIVATE_H -ares_status_t ares_dns_record_duplicate_ex(ares_dns_record_t **dest, +ares_status_t ares_dns_record_duplicate_ex(ares_dns_record_t **dest, const ares_dns_record_t *src); ares_bool_t ares_dns_rec_type_allow_name_compression(ares_dns_rec_type_t type); ares_bool_t ares_dns_opcode_isvalid(ares_dns_opcode_t opcode); @@ -38,23 +38,32 @@ ares_bool_t ares_dns_class_isvalid(ares_dns_class_t qclass, ares_dns_rec_type_t type, ares_bool_t is_query); ares_bool_t ares_dns_section_isvalid(ares_dns_section_t sect); -ares_status_t ares_dns_rr_set_str_own(ares_dns_rr_t *dns_rr, - ares_dns_rr_key_t key, char *val); -ares_status_t ares_dns_rr_set_bin_own(ares_dns_rr_t *dns_rr, - ares_dns_rr_key_t key, unsigned char *val, - size_t len); -ares_status_t ares_dns_rr_set_abin_own(ares_dns_rr_t *dns_rr, - ares_dns_rr_key_t key, - ares__dns_multistring_t *strs); -ares_status_t ares_dns_rr_set_opt_own(ares_dns_rr_t *dns_rr, - ares_dns_rr_key_t key, unsigned short opt, - unsigned char *val, size_t val_len); -ares_status_t ares_dns_record_rr_prealloc(ares_dns_record_t *dnsrec, - ares_dns_section_t sect, size_t cnt); -ares_bool_t ares_dns_has_opt_rr(const ares_dns_record_t *rec); +ares_status_t ares_dns_rr_set_str_own(ares_dns_rr_t *dns_rr, + ares_dns_rr_key_t key, char *val); +ares_status_t ares_dns_rr_set_bin_own(ares_dns_rr_t *dns_rr, + ares_dns_rr_key_t key, unsigned char *val, + size_t len); +ares_status_t ares_dns_rr_set_abin_own(ares_dns_rr_t *dns_rr, + ares_dns_rr_key_t key, + ares__dns_multistring_t *strs); +ares_status_t ares_dns_rr_set_opt_own(ares_dns_rr_t *dns_rr, + ares_dns_rr_key_t key, unsigned short opt, + unsigned char *val, size_t val_len); +ares_status_t ares_dns_record_rr_prealloc(ares_dns_record_t *dnsrec, + ares_dns_section_t sect, size_t cnt); +ares_dns_rr_t *ares_dns_get_opt_rr(ares_dns_record_t *rec); +const ares_dns_rr_t *ares_dns_get_opt_rr_const(const ares_dns_record_t *rec); void ares_dns_record_write_ttl_decrement(ares_dns_record_t *dnsrec, unsigned int ttl_decrement); +/* Same as ares_dns_write() but appends to an existing buffer object */ +ares_status_t ares_dns_write_buf(const ares_dns_record_t *dnsrec, + ares__buf_t *buf); + +/* Same as ares_dns_write_buf(), but prepends a 16bit length */ +ares_status_t ares_dns_write_buf_tcp(const ares_dns_record_t *dnsrec, + ares__buf_t *buf); + /*! Create a DNS record object for a query. The arguments are the same as * those for ares_create_query(). * @@ -168,18 +177,11 @@ typedef struct { } ares__dns_optval_t; typedef struct { - ares__dns_optval_t *optval; /*!< Attribute/value pairs */ - size_t cnt; /*!< Count of Attribute/Value pairs */ - size_t alloc; /*!< Allocated count of attribute/value - * pairs */ -} ares__dns_options_t; - -typedef struct { - unsigned short udp_size; /*!< taken from class */ - unsigned char version; /*!< taken from bits 8-16 of ttl */ - unsigned short flags; /*!< Flags, remaining 16 bits, though only - * 1 currently defined */ - ares__dns_options_t *options; /*!< Attribute/Value pairs */ + unsigned short udp_size; /*!< taken from class */ + unsigned char version; /*!< taken from bits 8-16 of ttl */ + unsigned short flags; /*!< Flags, remaining 16 bits, though only + * 1 currently defined */ + ares__array_t *options; /*!< Type is ares__dns_optval_t */ } ares__dns_opt_t; typedef struct { @@ -191,9 +193,9 @@ typedef struct { } ares__dns_tlsa_t; typedef struct { - unsigned short priority; - char *target; - ares__dns_options_t *params; + unsigned short priority; + char *target; + ares__array_t *params; /*!< Type is ares__dns_optval_t */ } ares__dns_svcb_t; typedef struct { @@ -262,21 +264,10 @@ struct ares_dns_record { * the ttl of any resource records by * this amount. Used for cache */ - ares_dns_qd_t *qd; - size_t qdcount; - size_t qdalloc; - - ares_dns_rr_t *an; - size_t ancount; - size_t analloc; - - ares_dns_rr_t *ns; - size_t nscount; - size_t nsalloc; - - ares_dns_rr_t *ar; - size_t arcount; - size_t aralloc; + ares__array_t *qd; /*!< Type is ares_dns_qd_t */ + ares__array_t *an; /*!< Type is ares_dns_rr_t */ + ares__array_t *ns; /*!< Type is ares_dns_rr_t */ + ares__array_t *ar; /*!< Type is ares_dns_rr_t */ }; #endif diff --git a/deps/cares/src/lib/ares_dns_record.c b/deps/cares/src/lib/record/ares_dns_record.c similarity index 84% rename from deps/cares/src/lib/ares_dns_record.c rename to deps/cares/src/lib/record/ares_dns_record.c index 8545abecf74..14704949094 100644 --- a/deps/cares/src/lib/ares_dns_record.c +++ b/deps/cares/src/lib/record/ares_dns_record.c @@ -29,6 +29,25 @@ # include #endif +static void ares__dns_rr_free(ares_dns_rr_t *rr); + +static void ares_dns_qd_free_cb(void *arg) +{ + ares_dns_qd_t *qd = arg; + if (qd == NULL) { + return; + } + ares_free(qd->name); +} + +static void ares_dns_rr_free_cb(void *arg) +{ + ares_dns_rr_t *rr = arg; + if (rr == NULL) { + return; + } + ares__dns_rr_free(rr); +} ares_status_t ares_dns_record_create(ares_dns_record_t **dnsrec, unsigned short id, unsigned short flags, @@ -55,6 +74,22 @@ ares_status_t ares_dns_record_create(ares_dns_record_t **dnsrec, (*dnsrec)->flags = flags; (*dnsrec)->opcode = opcode; (*dnsrec)->rcode = rcode; + (*dnsrec)->qd = + ares__array_create(sizeof(ares_dns_qd_t), ares_dns_qd_free_cb); + (*dnsrec)->an = + ares__array_create(sizeof(ares_dns_rr_t), ares_dns_rr_free_cb); + (*dnsrec)->ns = + ares__array_create(sizeof(ares_dns_rr_t), ares_dns_rr_free_cb); + (*dnsrec)->ar = + ares__array_create(sizeof(ares_dns_rr_t), ares_dns_rr_free_cb); + + if ((*dnsrec)->qd == NULL || (*dnsrec)->an == NULL || (*dnsrec)->ns == NULL || + (*dnsrec)->ar == NULL) { + ares_dns_record_destroy(*dnsrec); + *dnsrec = NULL; + return ARES_ENOMEM; + } + return ARES_SUCCESS; } @@ -99,21 +134,6 @@ ares_dns_rcode_t ares_dns_record_get_rcode(const ares_dns_record_t *dnsrec) return dnsrec->rcode; } -static void ares__dns_options_free(ares__dns_options_t *options) -{ - size_t i; - - if (options == NULL) { - return; - } - - for (i = 0; i < options->cnt; i++) { - ares_free(options->optval[i].val); - } - ares_free(options->optval); - ares_free(options); -} - static void ares__dns_rr_free(ares_dns_rr_t *rr) { ares_free(rr->name); @@ -172,7 +192,7 @@ static void ares__dns_rr_free(ares_dns_rr_t *rr) break; case ARES_REC_TYPE_OPT: - ares__dns_options_free(rr->r.opt.options); + ares__array_destroy(rr->r.opt.options); break; case ARES_REC_TYPE_TLSA: @@ -181,12 +201,12 @@ static void ares__dns_rr_free(ares_dns_rr_t *rr) case ARES_REC_TYPE_SVCB: ares_free(rr->r.svcb.target); - ares__dns_options_free(rr->r.svcb.params); + ares__array_destroy(rr->r.svcb.params); break; case ARES_REC_TYPE_HTTPS: ares_free(rr->r.https.target); - ares__dns_options_free(rr->r.https.params); + ares__array_destroy(rr->r.https.params); break; case ARES_REC_TYPE_URI: @@ -206,35 +226,21 @@ static void ares__dns_rr_free(ares_dns_rr_t *rr) void ares_dns_record_destroy(ares_dns_record_t *dnsrec) { - size_t i; - if (dnsrec == NULL) { return; } /* Free questions */ - for (i = 0; i < dnsrec->qdcount; i++) { - ares_free(dnsrec->qd[i].name); - } - ares_free(dnsrec->qd); + ares__array_destroy(dnsrec->qd); /* Free answers */ - for (i = 0; i < dnsrec->ancount; i++) { - ares__dns_rr_free(&dnsrec->an[i]); - } - ares_free(dnsrec->an); + ares__array_destroy(dnsrec->an); /* Free authority */ - for (i = 0; i < dnsrec->nscount; i++) { - ares__dns_rr_free(&dnsrec->ns[i]); - } - ares_free(dnsrec->ns); + ares__array_destroy(dnsrec->ns); /* Free additional */ - for (i = 0; i < dnsrec->arcount; i++) { - ares__dns_rr_free(&dnsrec->ar[i]); - } - ares_free(dnsrec->ar); + ares__array_destroy(dnsrec->ar); ares_free(dnsrec); } @@ -244,7 +250,7 @@ size_t ares_dns_record_query_cnt(const ares_dns_record_t *dnsrec) if (dnsrec == NULL) { return 0; } - return dnsrec->qdcount; + return ares__array_len(dnsrec->qd); } ares_status_t ares_dns_record_query_add(ares_dns_record_t *dnsrec, @@ -252,8 +258,9 @@ ares_status_t ares_dns_record_query_add(ares_dns_record_t *dnsrec, ares_dns_rec_type_t qtype, ares_dns_class_t qclass) { - ares_dns_qd_t *temp = NULL; size_t idx; + ares_dns_qd_t *qd; + ares_status_t status; if (dnsrec == NULL || name == NULL || !ares_dns_rec_type_isvalid(qtype, ARES_TRUE) || @@ -261,47 +268,39 @@ ares_status_t ares_dns_record_query_add(ares_dns_record_t *dnsrec, return ARES_EFORMERR; } - if (dnsrec->qdcount >= dnsrec->qdalloc) { - size_t alloc_cnt = ares__round_up_pow2(dnsrec->qdcount + 1); - - temp = ares_realloc_zero(dnsrec->qd, sizeof(*temp) * (dnsrec->qdalloc), - sizeof(*temp) * alloc_cnt); - if (temp == NULL) { - return ARES_ENOMEM; - } - - dnsrec->qdalloc = alloc_cnt; - dnsrec->qd = temp; + idx = ares__array_len(dnsrec->qd); + status = ares__array_insert_last((void **)&qd, dnsrec->qd); + if (status != ARES_SUCCESS) { + return status; } - idx = dnsrec->qdcount; - - dnsrec->qd[idx].name = ares_strdup(name); - if (dnsrec->qd[idx].name == NULL) { - /* No need to clean up anything */ + qd->name = ares_strdup(name); + if (qd->name == NULL) { + ares__array_remove_at(dnsrec->qd, idx); return ARES_ENOMEM; } - - dnsrec->qd[idx].qtype = qtype; - dnsrec->qd[idx].qclass = qclass; - dnsrec->qdcount++; + qd->qtype = qtype; + qd->qclass = qclass; return ARES_SUCCESS; } ares_status_t ares_dns_record_query_set_name(ares_dns_record_t *dnsrec, size_t idx, const char *name) { - char *orig_name = NULL; + char *orig_name = NULL; + ares_dns_qd_t *qd; - if (dnsrec == NULL || idx >= dnsrec->qdcount || name == NULL) { + if (dnsrec == NULL || idx >= ares__array_len(dnsrec->qd) || name == NULL) { return ARES_EFORMERR; } - orig_name = dnsrec->qd[idx].name; - dnsrec->qd[idx].name = ares_strdup(name); - if (dnsrec->qd[idx].name == NULL) { - dnsrec->qd[idx].name = orig_name; /* LCOV_EXCL_LINE: OutOfMemory */ - return ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ + qd = ares__array_at(dnsrec->qd, idx); + + orig_name = qd->name; + qd->name = ares_strdup(name); + if (qd->name == NULL) { + qd->name = orig_name; /* LCOV_EXCL_LINE: OutOfMemory */ + return ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ } ares_free(orig_name); @@ -312,12 +311,15 @@ ares_status_t ares_dns_record_query_set_type(ares_dns_record_t *dnsrec, size_t idx, ares_dns_rec_type_t qtype) { - if (dnsrec == NULL || idx >= dnsrec->qdcount || + ares_dns_qd_t *qd; + + if (dnsrec == NULL || idx >= ares__array_len(dnsrec->qd) || !ares_dns_rec_type_isvalid(qtype, ARES_TRUE)) { return ARES_EFORMERR; } - dnsrec->qd[idx].qtype = qtype; + qd = ares__array_at(dnsrec->qd, idx); + qd->qtype = qtype; return ARES_SUCCESS; } @@ -327,20 +329,22 @@ ares_status_t ares_dns_record_query_get(const ares_dns_record_t *dnsrec, ares_dns_rec_type_t *qtype, ares_dns_class_t *qclass) { - if (dnsrec == NULL || idx >= dnsrec->qdcount) { + const ares_dns_qd_t *qd; + if (dnsrec == NULL || idx >= ares__array_len(dnsrec->qd)) { return ARES_EFORMERR; } + qd = ares__array_at(dnsrec->qd, idx); if (name != NULL) { - *name = dnsrec->qd[idx].name; + *name = qd->name; } if (qtype != NULL) { - *qtype = dnsrec->qd[idx].qtype; + *qtype = qd->qtype; } if (qclass != NULL) { - *qclass = dnsrec->qd[idx].qclass; + *qclass = qd->qclass; } return ARES_SUCCESS; @@ -355,11 +359,11 @@ size_t ares_dns_record_rr_cnt(const ares_dns_record_t *dnsrec, switch (sect) { case ARES_SECTION_ANSWER: - return dnsrec->ancount; + return ares__array_len(dnsrec->an); case ARES_SECTION_AUTHORITY: - return dnsrec->nscount; + return ares__array_len(dnsrec->ns); case ARES_SECTION_ADDITIONAL: - return dnsrec->arcount; + return ares__array_len(dnsrec->ar); } return 0; /* LCOV_EXCL_LINE: DefensiveCoding */ @@ -368,46 +372,29 @@ size_t ares_dns_record_rr_cnt(const ares_dns_record_t *dnsrec, ares_status_t ares_dns_record_rr_prealloc(ares_dns_record_t *dnsrec, ares_dns_section_t sect, size_t cnt) { - ares_dns_rr_t **rr_ptr = NULL; - size_t *rr_alloc = NULL; - ares_dns_rr_t *temp = NULL; + ares__array_t *arr = NULL; - if (dnsrec == NULL || cnt == 0 || !ares_dns_section_isvalid(sect)) { - return ARES_EFORMERR; /* LCOV_EXCL_LINE: DefensiveCoding */ + if (dnsrec == NULL || !ares_dns_section_isvalid(sect)) { + return ARES_EFORMERR; } switch (sect) { case ARES_SECTION_ANSWER: - rr_ptr = &dnsrec->an; - rr_alloc = &dnsrec->analloc; + arr = dnsrec->an; break; case ARES_SECTION_AUTHORITY: - rr_ptr = &dnsrec->ns; - rr_alloc = &dnsrec->nsalloc; + arr = dnsrec->ns; break; case ARES_SECTION_ADDITIONAL: - rr_ptr = &dnsrec->ar; - rr_alloc = &dnsrec->aralloc; + arr = dnsrec->ar; break; } - /* Round up cnt to a power of 2 */ - cnt = ares__round_up_pow2(cnt); - - /* Already have that */ - if (cnt <= *rr_alloc) { - return ARES_SUCCESS; - } - - temp = ares_realloc_zero(*rr_ptr, sizeof(*temp) * (*rr_alloc), - sizeof(*temp) * cnt); - if (temp == NULL) { - return ARES_ENOMEM; + if (cnt < ares__array_len(arr)) { + return ARES_EFORMERR; } - *rr_alloc = cnt; - *rr_ptr = temp; - return ARES_SUCCESS; + return ares__array_set_size(arr, cnt); } ares_status_t ares_dns_record_rr_add(ares_dns_rr_t **rr_out, @@ -416,11 +403,10 @@ ares_status_t ares_dns_record_rr_add(ares_dns_rr_t **rr_out, ares_dns_rec_type_t type, ares_dns_class_t rclass, unsigned int ttl) { - ares_dns_rr_t **rr_ptr = NULL; - ares_dns_rr_t *rr = NULL; - size_t *rr_len = NULL; - ares_status_t status; - size_t idx; + ares_dns_rr_t *rr = NULL; + ares__array_t *arr = NULL; + ares_status_t status; + size_t idx; if (dnsrec == NULL || name == NULL || rr_out == NULL || !ares_dns_section_isvalid(sect) || @@ -433,30 +419,25 @@ ares_status_t ares_dns_record_rr_add(ares_dns_rr_t **rr_out, switch (sect) { case ARES_SECTION_ANSWER: - rr_ptr = &dnsrec->an; - rr_len = &dnsrec->ancount; + arr = dnsrec->an; break; case ARES_SECTION_AUTHORITY: - rr_ptr = &dnsrec->ns; - rr_len = &dnsrec->nscount; + arr = dnsrec->ns; break; case ARES_SECTION_ADDITIONAL: - rr_ptr = &dnsrec->ar; - rr_len = &dnsrec->arcount; + arr = dnsrec->ar; break; } - status = ares_dns_record_rr_prealloc(dnsrec, sect, *rr_len + 1); + idx = ares__array_len(arr); + status = ares__array_insert_last((void **)&rr, arr); if (status != ARES_SUCCESS) { return status; /* LCOV_EXCL_LINE: OutOfMemory */ } - idx = *rr_len; - rr = &(*rr_ptr)[idx]; - rr->name = ares_strdup(name); if (rr->name == NULL) { - /* No need to clean up anything */ + ares__array_remove_at(arr, idx); return ARES_ENOMEM; } @@ -464,7 +445,6 @@ ares_status_t ares_dns_record_rr_add(ares_dns_rr_t **rr_out, rr->type = type; rr->rclass = rclass; rr->ttl = ttl; - (*rr_len)++; *rr_out = rr; @@ -474,9 +454,7 @@ ares_status_t ares_dns_record_rr_add(ares_dns_rr_t **rr_out, ares_status_t ares_dns_record_rr_del(ares_dns_record_t *dnsrec, ares_dns_section_t sect, size_t idx) { - ares_dns_rr_t *rr_ptr = NULL; - size_t *rr_len = NULL; - size_t cnt_after; + ares__array_t *arr = NULL; if (dnsrec == NULL || !ares_dns_section_isvalid(sect)) { return ARES_EFORMERR; @@ -484,40 +462,23 @@ ares_status_t ares_dns_record_rr_del(ares_dns_record_t *dnsrec, switch (sect) { case ARES_SECTION_ANSWER: - rr_ptr = dnsrec->an; - rr_len = &dnsrec->ancount; + arr = dnsrec->an; break; case ARES_SECTION_AUTHORITY: - rr_ptr = dnsrec->ns; - rr_len = &dnsrec->nscount; + arr = dnsrec->ns; break; case ARES_SECTION_ADDITIONAL: - rr_ptr = dnsrec->ar; - rr_len = &dnsrec->arcount; + arr = dnsrec->ar; break; } - if (idx >= *rr_len) { - return ARES_EFORMERR; - } - - ares__dns_rr_free(&rr_ptr[idx]); - - cnt_after = *rr_len - idx - 1; - - if (cnt_after) { - memmove(&rr_ptr[idx], &rr_ptr[idx + 1], sizeof(*rr_ptr) * cnt_after); - } - - (*rr_len)--; - return ARES_SUCCESS; + return ares__array_remove_at(arr, idx); } ares_dns_rr_t *ares_dns_record_rr_get(ares_dns_record_t *dnsrec, ares_dns_section_t sect, size_t idx) { - ares_dns_rr_t *rr_ptr = NULL; - size_t rr_len = 0; + ares__array_t *arr = NULL; if (dnsrec == NULL || !ares_dns_section_isvalid(sect)) { return NULL; @@ -525,24 +486,17 @@ ares_dns_rr_t *ares_dns_record_rr_get(ares_dns_record_t *dnsrec, switch (sect) { case ARES_SECTION_ANSWER: - rr_ptr = dnsrec->an; - rr_len = dnsrec->ancount; + arr = dnsrec->an; break; case ARES_SECTION_AUTHORITY: - rr_ptr = dnsrec->ns; - rr_len = dnsrec->nscount; + arr = dnsrec->ns; break; case ARES_SECTION_ADDITIONAL: - rr_ptr = dnsrec->ar; - rr_len = dnsrec->arcount; + arr = dnsrec->ar; break; } - if (idx >= rr_len) { - return NULL; - } - - return &rr_ptr[idx]; + return ares__array_at(arr, idx); } const ares_dns_rr_t * @@ -1040,7 +994,7 @@ const char *ares_dns_rr_get_str(const ares_dns_rr_t *dns_rr, size_t ares_dns_rr_get_opt_cnt(const ares_dns_rr_t *dns_rr, ares_dns_rr_key_t key) { - ares__dns_options_t * const *opts; + ares__array_t * const *opts; if (ares_dns_rr_key_datatype(key) != ARES_DATATYPE_OPT) { return 0; @@ -1051,14 +1005,15 @@ size_t ares_dns_rr_get_opt_cnt(const ares_dns_rr_t *dns_rr, return 0; } - return (*opts)->cnt; + return ares__array_len(*opts); } unsigned short ares_dns_rr_get_opt(const ares_dns_rr_t *dns_rr, ares_dns_rr_key_t key, size_t idx, const unsigned char **val, size_t *val_len) { - ares__dns_options_t * const *opts; + ares__array_t * const *opts; + const ares__dns_optval_t *opt; if (val) { *val = NULL; @@ -1076,26 +1031,29 @@ unsigned short ares_dns_rr_get_opt(const ares_dns_rr_t *dns_rr, return 65535; } - if (idx >= (*opts)->cnt) { + opt = ares__array_at(*opts, idx); + if (opt == NULL) { return 65535; } if (val) { - *val = (*opts)->optval[idx].val; + *val = opt->val; } if (val_len) { - *val_len = (*opts)->optval[idx].val_len; + *val_len = opt->val_len; } - return (*opts)->optval[idx].opt; + return opt->opt; } ares_bool_t ares_dns_rr_get_opt_byid(const ares_dns_rr_t *dns_rr, ares_dns_rr_key_t key, unsigned short opt, const unsigned char **val, size_t *val_len) { - ares__dns_options_t * const *opts; - size_t i; + ares__array_t * const *opts; + size_t i; + size_t cnt; + const ares__dns_optval_t *optptr = NULL; if (val) { *val = NULL; @@ -1113,21 +1071,26 @@ ares_bool_t ares_dns_rr_get_opt_byid(const ares_dns_rr_t *dns_rr, return ARES_FALSE; } - for (i = 0; i < (*opts)->cnt; i++) { - if ((*opts)->optval[i].opt == opt) { + cnt = ares__array_len(*opts); + for (i = 0; i < cnt; i++) { + optptr = ares__array_at(*opts, i); + if (optptr == NULL) { + return ARES_FALSE; + } + if (optptr->opt == opt) { break; } } - if (i >= (*opts)->cnt) { + if (i >= cnt || optptr == NULL) { return ARES_FALSE; } if (val) { - *val = (*opts)->optval[i].val; + *val = optptr->val; } if (val_len) { - *val_len = (*opts)->optval[i].val_len; + *val_len = optptr->val_len; } return ARES_TRUE; } @@ -1367,12 +1330,24 @@ ares_status_t ares_dns_rr_set_abin_own(ares_dns_rr_t *dns_rr, return ARES_SUCCESS; } +static void ares__dns_opt_free_cb(void *arg) +{ + ares__dns_optval_t *opt = arg; + if (opt == NULL) { + return; + } + ares_free(opt->val); +} + ares_status_t ares_dns_rr_set_opt_own(ares_dns_rr_t *dns_rr, ares_dns_rr_key_t key, unsigned short opt, unsigned char *val, size_t val_len) { - ares__dns_options_t **options; - size_t idx; + ares__array_t **options; + ares__dns_optval_t *optptr = NULL; + size_t idx; + size_t cnt; + ares_status_t status; if (ares_dns_rr_key_datatype(key) != ARES_DATATYPE_OPT) { return ARES_EFORMERR; @@ -1384,54 +1359,39 @@ ares_status_t ares_dns_rr_set_opt_own(ares_dns_rr_t *dns_rr, } if (*options == NULL) { - *options = ares_malloc_zero(sizeof(**options)); + *options = + ares__array_create(sizeof(ares__dns_optval_t), ares__dns_opt_free_cb); } if (*options == NULL) { return ARES_ENOMEM; } - for (idx = 0; idx < (*options)->cnt; idx++) { - if ((*options)->optval[idx].opt == opt) { + cnt = ares__array_len(*options); + for (idx = 0; idx < cnt; idx++) { + optptr = ares__array_at(*options, idx); + if (optptr == NULL) { + return ARES_EFORMERR; + } + if (optptr->opt == opt) { break; } } /* Duplicate entry, replace */ - if (idx != (*options)->cnt) { + if (idx != cnt && optptr != NULL) { goto done; } - idx = (*options)->cnt; - - /* Expand by powers of 2 */ - if (idx >= (*options)->alloc) { - size_t alloc_size = (*options)->alloc; - void *temp; - - if (alloc_size == 0) { - alloc_size = 1; - } else { - alloc_size <<= 1; - } - - temp = ares_realloc_zero((*options)->optval, - (*options)->alloc * sizeof(*(*options)->optval), - alloc_size * sizeof(*(*options)->optval)); - if (temp == NULL) { - return ARES_ENOMEM; - } - - (*options)->optval = temp; - (*options)->alloc = alloc_size; + status = ares__array_insert_last((void **)&optptr, *options); + if (status != ARES_SUCCESS) { + return status; } - (*options)->cnt++; - done: - ares_free((*options)->optval[idx].val); - (*options)->optval[idx].opt = opt; - (*options)->optval[idx].val = val; - (*options)->optval[idx].val_len = val_len; + ares_free(optptr->val); + optptr->opt = opt; + optptr->val = val; + optptr->val_len = val_len; return ARES_SUCCESS; } @@ -1460,6 +1420,43 @@ ares_status_t ares_dns_rr_set_opt(ares_dns_rr_t *dns_rr, ares_dns_rr_key_t key, return status; } +ares_status_t ares_dns_rr_del_opt_byid(ares_dns_rr_t *dns_rr, + ares_dns_rr_key_t key, + unsigned short opt) +{ + ares__array_t **options; + const ares__dns_optval_t *optptr; + size_t idx; + size_t cnt; + + if (ares_dns_rr_key_datatype(key) != ARES_DATATYPE_OPT) { + return ARES_EFORMERR; + } + + options = ares_dns_rr_data_ptr(dns_rr, key, NULL); + if (options == NULL) { + return ARES_EFORMERR; + } + + /* No options */ + if (*options == NULL) { + return ARES_SUCCESS; + } + + cnt = ares__array_len(*options); + for (idx = 0; idx < cnt; idx++) { + optptr = ares__array_at_const(*options, idx); + if (optptr == NULL) { + return ARES_ENOTFOUND; + } + if (optptr->opt == opt) { + return ares__array_remove_at(*options, idx); + } + } + + return ARES_ENOTFOUND; +} + char *ares_dns_addr_to_ptr(const struct ares_addr *addr) { ares__buf_t *buf = NULL; @@ -1532,8 +1529,20 @@ char *ares_dns_addr_to_ptr(const struct ares_addr *addr) return NULL; } -/* search for an OPT RR in the response */ -ares_bool_t ares_dns_has_opt_rr(const ares_dns_record_t *rec) +ares_dns_rr_t *ares_dns_get_opt_rr(ares_dns_record_t *rec) +{ + size_t i; + for (i = 0; i < ares_dns_record_rr_cnt(rec, ARES_SECTION_ADDITIONAL); i++) { + ares_dns_rr_t *rr = ares_dns_record_rr_get(rec, ARES_SECTION_ADDITIONAL, i); + + if (ares_dns_rr_get_type(rr) == ARES_REC_TYPE_OPT) { + return rr; + } + } + return NULL; +} + +const ares_dns_rr_t *ares_dns_get_opt_rr_const(const ares_dns_record_t *rec) { size_t i; for (i = 0; i < ares_dns_record_rr_cnt(rec, ARES_SECTION_ADDITIONAL); i++) { @@ -1541,10 +1550,10 @@ ares_bool_t ares_dns_has_opt_rr(const ares_dns_record_t *rec) ares_dns_record_rr_get_const(rec, ARES_SECTION_ADDITIONAL, i); if (ares_dns_rr_get_type(rr) == ARES_REC_TYPE_OPT) { - return ARES_TRUE; + return rr; } } - return ARES_FALSE; + return NULL; } /* Construct a DNS record for a name with given class and type. Used internally @@ -1623,12 +1632,12 @@ ares_status_t return status; } -ares_status_t ares_dns_record_duplicate_ex(ares_dns_record_t **dest, +ares_status_t ares_dns_record_duplicate_ex(ares_dns_record_t **dest, const ares_dns_record_t *src) { - unsigned char *data = NULL; - size_t data_len = 0; - ares_status_t status; + unsigned char *data = NULL; + size_t data_len = 0; + ares_status_t status; if (dest == NULL || src == NULL) { return ARES_EFORMERR; diff --git a/deps/cares/src/lib/ares_dns_write.c b/deps/cares/src/lib/record/ares_dns_write.c similarity index 93% rename from deps/cares/src/lib/ares_dns_write.c rename to deps/cares/src/lib/record/ares_dns_write.c index 60bbd702889..8a3addd9f01 100644 --- a/deps/cares/src/lib/ares_dns_write.c +++ b/deps/cares/src/lib/record/ares_dns_write.c @@ -91,7 +91,7 @@ static ares_status_t ares_dns_write_header(const ares_dns_record_t *dnsrec, } /* RCODE */ - if (dnsrec->rcode > 15 && !ares_dns_has_opt_rr(dnsrec)) { + if (dnsrec->rcode > 15 && ares_dns_get_opt_rr_const(dnsrec) == NULL) { /* Must have OPT RR in order to write extended error codes */ rcode = ARES_RCODE_SERVFAIL; } else { @@ -105,25 +105,29 @@ static ares_status_t ares_dns_write_header(const ares_dns_record_t *dnsrec, } /* QDCOUNT */ - status = ares__buf_append_be16(buf, (unsigned short)dnsrec->qdcount); + status = ares__buf_append_be16( + buf, (unsigned short)ares_dns_record_query_cnt(dnsrec)); if (status != ARES_SUCCESS) { return status; /* LCOV_EXCL_LINE: OutOfMemory */ } /* ANCOUNT */ - status = ares__buf_append_be16(buf, (unsigned short)dnsrec->ancount); + status = ares__buf_append_be16( + buf, (unsigned short)ares_dns_record_rr_cnt(dnsrec, ARES_SECTION_ANSWER)); if (status != ARES_SUCCESS) { return status; /* LCOV_EXCL_LINE: OutOfMemory */ } /* NSCOUNT */ - status = ares__buf_append_be16(buf, (unsigned short)dnsrec->nscount); + status = ares__buf_append_be16(buf, (unsigned short)ares_dns_record_rr_cnt( + dnsrec, ARES_SECTION_AUTHORITY)); if (status != ARES_SUCCESS) { return status; /* LCOV_EXCL_LINE: OutOfMemory */ } /* ARCOUNT */ - status = ares__buf_append_be16(buf, (unsigned short)dnsrec->arcount); + status = ares__buf_append_be16(buf, (unsigned short)ares_dns_record_rr_cnt( + dnsrec, ARES_SECTION_ADDITIONAL)); if (status != ARES_SUCCESS) { return status; /* LCOV_EXCL_LINE: OutOfMemory */ } @@ -1090,52 +1094,121 @@ static ares_status_t ares_dns_write_rr(const ares_dns_record_t *dnsrec, return ARES_SUCCESS; } -ares_status_t ares_dns_write(const ares_dns_record_t *dnsrec, - unsigned char **buf, size_t *buf_len) +ares_status_t ares_dns_write_buf(const ares_dns_record_t *dnsrec, + ares__buf_t *buf) { - ares__buf_t *b = NULL; - ares_status_t status; ares__llist_t *namelist = NULL; + size_t orig_len; + ares_status_t status; - if (buf == NULL || buf_len == NULL || dnsrec == NULL) { + if (dnsrec == NULL || buf == NULL) { return ARES_EFORMERR; } - *buf = NULL; - *buf_len = 0; + orig_len = ares__buf_len(buf); - b = ares__buf_create(); - if (b == NULL) { - return ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ + status = ares_dns_write_header(dnsrec, buf); + if (status != ARES_SUCCESS) { + goto done; } - status = ares_dns_write_header(dnsrec, b); + status = ares_dns_write_questions(dnsrec, &namelist, buf); if (status != ARES_SUCCESS) { goto done; } - status = ares_dns_write_questions(dnsrec, &namelist, b); + status = ares_dns_write_rr(dnsrec, &namelist, ARES_SECTION_ANSWER, buf); if (status != ARES_SUCCESS) { goto done; } - status = ares_dns_write_rr(dnsrec, &namelist, ARES_SECTION_ANSWER, b); + status = ares_dns_write_rr(dnsrec, &namelist, ARES_SECTION_AUTHORITY, buf); if (status != ARES_SUCCESS) { goto done; } - status = ares_dns_write_rr(dnsrec, &namelist, ARES_SECTION_AUTHORITY, b); + status = ares_dns_write_rr(dnsrec, &namelist, ARES_SECTION_ADDITIONAL, buf); if (status != ARES_SUCCESS) { goto done; } - status = ares_dns_write_rr(dnsrec, &namelist, ARES_SECTION_ADDITIONAL, b); +done: + ares__llist_destroy(namelist); + if (status != ARES_SUCCESS) { + ares__buf_set_length(buf, orig_len); + } + + return status; +} + +ares_status_t ares_dns_write_buf_tcp(const ares_dns_record_t *dnsrec, + ares__buf_t *buf) +{ + ares_status_t status; + size_t orig_len; + size_t msg_len; + size_t len; + + if (dnsrec == NULL || buf == NULL) { + return ARES_EFORMERR; + } + + orig_len = ares__buf_len(buf); + + /* Write placeholder for length */ + status = ares__buf_append_be16(buf, 0); if (status != ARES_SUCCESS) { + goto done; /* LCOV_EXCL_LINE: OutOfMemory */ + } + + /* Write message */ + status = ares_dns_write_buf(dnsrec, buf); + if (status != ARES_SUCCESS) { + goto done; /* LCOV_EXCL_LINE: OutOfMemory */ + } + + len = ares__buf_len(buf); + msg_len = len - orig_len - 2; + if (msg_len > 65535) { + status = ARES_EBADQUERY; goto done; } + /* Now we need to overwrite the length, so we jump back to the original + * message length, overwrite the section and jump back */ + ares__buf_set_length(buf, orig_len); + status = ares__buf_append_be16(buf, (unsigned short)(msg_len & 0xFFFF)); + if (status != ARES_SUCCESS) { + goto done; /* LCOV_EXCL_LINE: UntestablePath */ + } + ares__buf_set_length(buf, len); + done: - ares__llist_destroy(namelist); + if (status != ARES_SUCCESS) { + ares__buf_set_length(buf, orig_len); + } + return status; +} + +ares_status_t ares_dns_write(const ares_dns_record_t *dnsrec, + unsigned char **buf, size_t *buf_len) +{ + ares__buf_t *b = NULL; + ares_status_t status; + + if (buf == NULL || buf_len == NULL || dnsrec == NULL) { + return ARES_EFORMERR; + } + + *buf = NULL; + *buf_len = 0; + + b = ares__buf_create(); + if (b == NULL) { + return ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ + } + + status = ares_dns_write_buf(dnsrec, b); if (status != ARES_SUCCESS) { ares__buf_destroy(b); diff --git a/deps/cares/src/lib/ares__buf.c b/deps/cares/src/lib/str/ares__buf.c similarity index 99% rename from deps/cares/src/lib/ares__buf.c rename to deps/cares/src/lib/str/ares__buf.c index 320a73d6748..bf6d4a0e1d3 100644 --- a/deps/cares/src/lib/ares__buf.c +++ b/deps/cares/src/lib/str/ares__buf.c @@ -204,7 +204,7 @@ ares_status_t ares__buf_set_length(ares__buf_t *buf, size_t len) return ARES_EFORMERR; /* LCOV_EXCL_LINE: DefensiveCoding */ } - buf->data_len = len; + buf->data_len = len + buf->offset; return ARES_SUCCESS; } @@ -213,10 +213,14 @@ ares_status_t ares__buf_append(ares__buf_t *buf, const unsigned char *data, { ares_status_t status; - if (data == NULL || data_len == 0) { + if (data == NULL && data_len != 0) { return ARES_EFORMERR; } + if (data_len == 0) { + return ARES_SUCCESS; + } + status = ares__buf_ensure_space(buf, data_len); if (status != ARES_SUCCESS) { return status; diff --git a/deps/cares/src/lib/ares__buf.h b/deps/cares/src/lib/str/ares__buf.h similarity index 100% rename from deps/cares/src/lib/ares__buf.h rename to deps/cares/src/lib/str/ares__buf.h diff --git a/deps/cares/src/lib/ares_str.c b/deps/cares/src/lib/str/ares_str.c similarity index 100% rename from deps/cares/src/lib/ares_str.c rename to deps/cares/src/lib/str/ares_str.c diff --git a/deps/cares/src/lib/ares_str.h b/deps/cares/src/lib/str/ares_str.h similarity index 82% rename from deps/cares/src/lib/ares_str.h rename to deps/cares/src/lib/str/ares_str.h index 81353221407..440758c21be 100644 --- a/deps/cares/src/lib/ares_str.h +++ b/deps/cares/src/lib/str/ares_str.h @@ -72,5 +72,18 @@ ares_bool_t ares__is_hostname(const char *str); */ ares_bool_t ares__str_isprint(const char *str, size_t len); +/* We only care about ASCII rules */ +#define ares__isascii(x) (((unsigned char)x) <= 127) +#define ares__isdigit(x) \ + (((unsigned char)x) >= '0' && ((unsigned char)x) <= '9') +#define ares__isxdigit(x) \ + (ares__isdigit(x) || \ + (((unsigned char)x) >= 'a' && ((unsigned char)x) <= 'f') || \ + (((unsigned char)x) >= 'A' && ((unsigned char)x) <= 'F')) +#define ares__isupper(x) \ + (((unsigned char)x) >= 'A' && ((unsigned char)x) <= 'Z') +#define ares__islower(x) \ + (((unsigned char)x) >= 'a' && ((unsigned char)x) <= 'z') +#define ares__isalpha(x) (ares__islower(x) || ares__isupper(x)) #endif /* __ARES_STR_H */ diff --git a/deps/cares/src/lib/ares_strcasecmp.c b/deps/cares/src/lib/str/ares_strcasecmp.c similarity index 100% rename from deps/cares/src/lib/ares_strcasecmp.c rename to deps/cares/src/lib/str/ares_strcasecmp.c diff --git a/deps/cares/src/lib/ares_strcasecmp.h b/deps/cares/src/lib/str/ares_strcasecmp.h similarity index 100% rename from deps/cares/src/lib/ares_strcasecmp.h rename to deps/cares/src/lib/str/ares_strcasecmp.h diff --git a/deps/cares/src/lib/ares_strsplit.c b/deps/cares/src/lib/str/ares_strsplit.c similarity index 100% rename from deps/cares/src/lib/ares_strsplit.c rename to deps/cares/src/lib/str/ares_strsplit.c diff --git a/deps/cares/src/lib/ares_strsplit.h b/deps/cares/src/lib/str/ares_strsplit.h similarity index 100% rename from deps/cares/src/lib/ares_strsplit.h rename to deps/cares/src/lib/str/ares_strsplit.h diff --git a/deps/cares/src/lib/ares__iface_ips.c b/deps/cares/src/lib/util/ares__iface_ips.c similarity index 90% rename from deps/cares/src/lib/ares__iface_ips.c rename to deps/cares/src/lib/util/ares__iface_ips.c index 6c983cabb1c..56dc2579041 100644 --- a/deps/cares/src/lib/ares__iface_ips.c +++ b/deps/cares/src/lib/util/ares__iface_ips.c @@ -71,12 +71,19 @@ typedef struct { } ares__iface_ip_t; struct ares__iface_ips { - ares__iface_ip_t *ips; - size_t cnt; - size_t alloc_size; + ares__array_t *ips; /*!< Type is ares__iface_ip_t */ ares__iface_ip_flags_t enum_flags; }; +static void ares__iface_ip_free_cb(void *arg) +{ + ares__iface_ip_t *ip = arg; + if (ip == NULL) { + return; + } + ares_free(ip->name); +} + static ares__iface_ips_t *ares__iface_ips_alloc(ares__iface_ip_flags_t flags) { ares__iface_ips_t *ips = ares_malloc_zero(sizeof(*ips)); @@ -84,38 +91,23 @@ static ares__iface_ips_t *ares__iface_ips_alloc(ares__iface_ip_flags_t flags) return NULL; /* LCOV_EXCL_LINE: OutOfMemory */ } - /* Prealloc 4 entries */ - ips->alloc_size = 4; - ips->ips = ares_malloc_zero(ips->alloc_size * sizeof(*ips->ips)); + ips->enum_flags = flags; + ips->ips = + ares__array_create(sizeof(ares__iface_ip_t), ares__iface_ip_free_cb); if (ips->ips == NULL) { ares_free(ips); /* LCOV_EXCL_LINE: OutOfMemory */ return NULL; /* LCOV_EXCL_LINE: OutOfMemory */ } - ips->enum_flags = flags; return ips; } -static void ares__iface_ip_destroy(ares__iface_ip_t *ip) -{ - if (ip == NULL) { - return; /* LCOV_EXCL_LINE: DefensiveCoding */ - } - ares_free(ip->name); - memset(ip, 0, sizeof(*ip)); -} - void ares__iface_ips_destroy(ares__iface_ips_t *ips) { - size_t i; - if (ips == NULL) { return; } - for (i = 0; i < ips->cnt; i++) { - ares__iface_ip_destroy(&ips->ips[i]); - } - ares_free(ips->ips); + ares__array_destroy(ips->ips); ares_free(ips); } @@ -150,7 +142,8 @@ static ares_status_t const char *name, const struct ares_addr *addr, unsigned char netmask, unsigned int ll_scope) { - size_t idx; + ares__iface_ip_t *ip; + ares_status_t status; if (ips == NULL || name == NULL || addr == NULL) { return ARES_EFORMERR; /* LCOV_EXCL_LINE: DefensiveCoding */ @@ -197,32 +190,20 @@ static ares_status_t } } - /* Allocate more ips */ - if (ips->cnt + 1 > ips->alloc_size) { - void *temp; - size_t alloc_size; - - alloc_size = ares__round_up_pow2(ips->alloc_size + 1); - temp = ares_realloc_zero(ips->ips, ips->alloc_size * sizeof(*ips->ips), - alloc_size * sizeof(*ips->ips)); - if (temp == NULL) { - return ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ - } - ips->ips = temp; - ips->alloc_size = alloc_size; + status = ares__array_insert_last((void **)&ip, ips->ips); + if (status != ARES_SUCCESS) { + return status; } - /* Add */ - idx = ips->cnt++; - - ips->ips[idx].flags = flags; - ips->ips[idx].netmask = netmask; + ip->flags = flags; + ip->netmask = netmask; if (flags & ARES_IFACE_IP_LINKLOCAL) { - ips->ips[idx].ll_scope = ll_scope; + ip->ll_scope = ll_scope; } - memcpy(&ips->ips[idx].addr, addr, sizeof(*addr)); - ips->ips[idx].name = ares_strdup(name); - if (ips->ips[idx].name == NULL) { + memcpy(&ip->addr, addr, sizeof(*addr)); + ip->name = ares_strdup(name); + if (ip->name == NULL) { + ares__array_remove_last(ips->ips); return ARES_ENOMEM; /* LCOV_EXCL_LINE: OutOfMemory */ } @@ -234,51 +215,91 @@ size_t ares__iface_ips_cnt(const ares__iface_ips_t *ips) if (ips == NULL) { return 0; } - return ips->cnt; + return ares__array_len(ips->ips); } const char *ares__iface_ips_get_name(const ares__iface_ips_t *ips, size_t idx) { - if (ips == NULL || idx >= ips->cnt) { + const ares__iface_ip_t *ip; + + if (ips == NULL) { return NULL; } - return ips->ips[idx].name; + + ip = ares__array_at_const(ips->ips, idx); + if (ip == NULL) { + return NULL; + } + + return ip->name; } const struct ares_addr *ares__iface_ips_get_addr(const ares__iface_ips_t *ips, size_t idx) { - if (ips == NULL || idx >= ips->cnt) { + const ares__iface_ip_t *ip; + + if (ips == NULL) { return NULL; } - return &ips->ips[idx].addr; + + ip = ares__array_at_const(ips->ips, idx); + if (ip == NULL) { + return NULL; + } + + return &ip->addr; } ares__iface_ip_flags_t ares__iface_ips_get_flags(const ares__iface_ips_t *ips, size_t idx) { - if (ips == NULL || idx >= ips->cnt) { + const ares__iface_ip_t *ip; + + if (ips == NULL) { return 0; } - return ips->ips[idx].flags; + + ip = ares__array_at_const(ips->ips, idx); + if (ip == NULL) { + return 0; + } + + return ip->flags; } unsigned char ares__iface_ips_get_netmask(const ares__iface_ips_t *ips, size_t idx) { - if (ips == NULL || idx >= ips->cnt) { + const ares__iface_ip_t *ip; + + if (ips == NULL) { return 0; } - return ips->ips[idx].netmask; + + ip = ares__array_at_const(ips->ips, idx); + if (ip == NULL) { + return 0; + } + + return ip->netmask; } unsigned int ares__iface_ips_get_ll_scope(const ares__iface_ips_t *ips, size_t idx) { - if (ips == NULL || idx >= ips->cnt) { + const ares__iface_ip_t *ip; + + if (ips == NULL) { return 0; } - return ips->ips[idx].ll_scope; + + ip = ares__array_at_const(ips->ips, idx); + if (ip == NULL) { + return 0; + } + + return ip->ll_scope; } diff --git a/deps/cares/src/lib/ares__iface_ips.h b/deps/cares/src/lib/util/ares__iface_ips.h similarity index 100% rename from deps/cares/src/lib/ares__iface_ips.h rename to deps/cares/src/lib/util/ares__iface_ips.h diff --git a/deps/cares/src/lib/ares__threads.c b/deps/cares/src/lib/util/ares__threads.c similarity index 100% rename from deps/cares/src/lib/ares__threads.c rename to deps/cares/src/lib/util/ares__threads.c diff --git a/deps/cares/src/lib/ares__threads.h b/deps/cares/src/lib/util/ares__threads.h similarity index 100% rename from deps/cares/src/lib/ares__threads.h rename to deps/cares/src/lib/util/ares__threads.h diff --git a/deps/cares/src/lib/ares__timeval.c b/deps/cares/src/lib/util/ares__timeval.c similarity index 98% rename from deps/cares/src/lib/ares__timeval.c rename to deps/cares/src/lib/util/ares__timeval.c index 66d07441c80..e3a989dca87 100644 --- a/deps/cares/src/lib/ares__timeval.c +++ b/deps/cares/src/lib/util/ares__timeval.c @@ -47,7 +47,7 @@ void ares__tvnow(ares_timeval_t *now) /* We want to prevent overflows so we get the remainder, then multiply to * microseconds before dividing */ now->usec = (unsigned int)(((current.QuadPart % freq.QuadPart) * 1000000) / - freq.QuadPart); + freq.QuadPart); } #elif defined(HAVE_CLOCK_GETTIME_MONOTONIC) diff --git a/deps/cares/src/lib/ares_math.c b/deps/cares/src/lib/util/ares_math.c similarity index 100% rename from deps/cares/src/lib/ares_math.c rename to deps/cares/src/lib/util/ares_math.c diff --git a/deps/cares/src/lib/ares_rand.c b/deps/cares/src/lib/util/ares_rand.c similarity index 100% rename from deps/cares/src/lib/ares_rand.c rename to deps/cares/src/lib/util/ares_rand.c diff --git a/deps/cares/src/tools/Makefile.in b/deps/cares/src/tools/Makefile.in index 0b7a310baaa..e1b661ec1d7 100644 --- a/deps/cares/src/tools/Makefile.in +++ b/deps/cares/src/tools/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.5 from Makefile.am. +# Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2021 Free Software Foundation, Inc. +# Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -70,6 +70,8 @@ am__make_running_with_option = \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +am__rm_f = rm -f $(am__rm_f_notfound) +am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -126,7 +128,7 @@ am__EXEEXT_1 = ahost$(EXEEXT) adig$(EXEEXT) PROGRAMS = $(noinst_PROGRAMS) am__dirstamp = $(am__leading_dot)dirstamp am__objects_1 = adig-ares_getopt.$(OBJEXT) \ - ../lib/adig-ares_strcasecmp.$(OBJEXT) + ../lib/str/adig-ares_strcasecmp.$(OBJEXT) am__objects_2 = am_adig_OBJECTS = adig-adig.$(OBJEXT) $(am__objects_1) \ $(am__objects_2) @@ -143,7 +145,7 @@ adig_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(adig_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ am__objects_3 = ahost-ares_getopt.$(OBJEXT) \ - ../lib/ahost-ares_strcasecmp.$(OBJEXT) + ../lib/str/ahost-ares_strcasecmp.$(OBJEXT) am_ahost_OBJECTS = ahost-ahost.$(OBJEXT) $(am__objects_3) \ $(am__objects_2) ahost_OBJECTS = $(am_ahost_OBJECTS) @@ -168,8 +170,8 @@ am__v_at_1 = DEFAULT_INCLUDES = depcomp = $(SHELL) $(top_srcdir)/config/depcomp am__maybe_remake_depfiles = depfiles -am__depfiles_remade = ../lib/$(DEPDIR)/adig-ares_strcasecmp.Po \ - ../lib/$(DEPDIR)/ahost-ares_strcasecmp.Po \ +am__depfiles_remade = ../lib/str/$(DEPDIR)/adig-ares_strcasecmp.Po \ + ../lib/str/$(DEPDIR)/ahost-ares_strcasecmp.Po \ ./$(DEPDIR)/adig-adig.Po ./$(DEPDIR)/adig-ares_getopt.Po \ ./$(DEPDIR)/ahost-ahost.Po ./$(DEPDIR)/ahost-ares_getopt.Po am__mv = mv -f @@ -273,6 +275,8 @@ FGREP = @FGREP@ FILECMD = @FILECMD@ GCOV = @GCOV@ GENHTML = @GENHTML@ +GMOCK112_CFLAGS = @GMOCK112_CFLAGS@ +GMOCK112_LIBS = @GMOCK112_LIBS@ GMOCK_CFLAGS = @GMOCK_CFLAGS@ GMOCK_LIBS = @GMOCK_LIBS@ GREP = @GREP@ @@ -335,8 +339,10 @@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ +am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ +am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ @@ -391,10 +397,10 @@ EXTRA_DIST = CMakeLists.txt Makefile.inc # Copyright (C) The c-ares project and its contributors # SPDX-License-Identifier: MIT SAMPLESOURCES = ares_getopt.c \ - ../lib/ares_strcasecmp.c + ../lib/str/ares_strcasecmp.c SAMPLEHEADERS = ares_getopt.h \ - ../lib/ares_strcasecmp.h + ../lib/str/ares_strcasecmp.h # We're not interested in code coverage of the test apps themselves, but need @@ -442,27 +448,23 @@ $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) $(am__aclocal_m4_deps): clean-noinstPROGRAMS: - @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ - echo " rm -f" $$list; \ - rm -f $$list || exit $$?; \ - test -n "$(EXEEXT)" || exit 0; \ - list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ - echo " rm -f" $$list; \ - rm -f $$list -../lib/$(am__dirstamp): - @$(MKDIR_P) ../lib - @: > ../lib/$(am__dirstamp) -../lib/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) ../lib/$(DEPDIR) - @: > ../lib/$(DEPDIR)/$(am__dirstamp) -../lib/adig-ares_strcasecmp.$(OBJEXT): ../lib/$(am__dirstamp) \ - ../lib/$(DEPDIR)/$(am__dirstamp) + $(am__rm_f) $(noinst_PROGRAMS) + test -z "$(EXEEXT)" || $(am__rm_f) $(noinst_PROGRAMS:$(EXEEXT)=) +../lib/str/$(am__dirstamp): + @$(MKDIR_P) ../lib/str + @: >>../lib/str/$(am__dirstamp) +../lib/str/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) ../lib/str/$(DEPDIR) + @: >>../lib/str/$(DEPDIR)/$(am__dirstamp) +../lib/str/adig-ares_strcasecmp.$(OBJEXT): ../lib/str/$(am__dirstamp) \ + ../lib/str/$(DEPDIR)/$(am__dirstamp) adig$(EXEEXT): $(adig_OBJECTS) $(adig_DEPENDENCIES) $(EXTRA_adig_DEPENDENCIES) @rm -f adig$(EXEEXT) $(AM_V_CCLD)$(adig_LINK) $(adig_OBJECTS) $(adig_LDADD) $(LIBS) -../lib/ahost-ares_strcasecmp.$(OBJEXT): ../lib/$(am__dirstamp) \ - ../lib/$(DEPDIR)/$(am__dirstamp) +../lib/str/ahost-ares_strcasecmp.$(OBJEXT): \ + ../lib/str/$(am__dirstamp) \ + ../lib/str/$(DEPDIR)/$(am__dirstamp) ahost$(EXEEXT): $(ahost_OBJECTS) $(ahost_DEPENDENCIES) $(EXTRA_ahost_DEPENDENCIES) @rm -f ahost$(EXEEXT) @@ -470,13 +472,13 @@ ahost$(EXEEXT): $(ahost_OBJECTS) $(ahost_DEPENDENCIES) $(EXTRA_ahost_DEPENDENCIE mostlyclean-compile: -rm -f *.$(OBJEXT) - -rm -f ../lib/*.$(OBJEXT) + -rm -f ../lib/str/*.$(OBJEXT) distclean-compile: -rm -f *.tab.c -@AMDEP_TRUE@@am__include@ @am__quote@../lib/$(DEPDIR)/adig-ares_strcasecmp.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@../lib/$(DEPDIR)/ahost-ares_strcasecmp.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@../lib/str/$(DEPDIR)/adig-ares_strcasecmp.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@../lib/str/$(DEPDIR)/ahost-ares_strcasecmp.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/adig-adig.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/adig-ares_getopt.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ahost-ahost.Po@am__quote@ # am--include-marker @@ -484,7 +486,7 @@ distclean-compile: $(am__depfiles_remade): @$(MKDIR_P) $(@D) - @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + @: >>$@ am--depfiles: $(am__depfiles_remade) @@ -540,19 +542,19 @@ adig-ares_getopt.obj: ares_getopt.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(adig_CPPFLAGS) $(CPPFLAGS) $(adig_CFLAGS) $(CFLAGS) -c -o adig-ares_getopt.obj `if test -f 'ares_getopt.c'; then $(CYGPATH_W) 'ares_getopt.c'; else $(CYGPATH_W) '$(srcdir)/ares_getopt.c'; fi` -../lib/adig-ares_strcasecmp.o: ../lib/ares_strcasecmp.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(adig_CPPFLAGS) $(CPPFLAGS) $(adig_CFLAGS) $(CFLAGS) -MT ../lib/adig-ares_strcasecmp.o -MD -MP -MF ../lib/$(DEPDIR)/adig-ares_strcasecmp.Tpo -c -o ../lib/adig-ares_strcasecmp.o `test -f '../lib/ares_strcasecmp.c' || echo '$(srcdir)/'`../lib/ares_strcasecmp.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../lib/$(DEPDIR)/adig-ares_strcasecmp.Tpo ../lib/$(DEPDIR)/adig-ares_strcasecmp.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../lib/ares_strcasecmp.c' object='../lib/adig-ares_strcasecmp.o' libtool=no @AMDEPBACKSLASH@ +../lib/str/adig-ares_strcasecmp.o: ../lib/str/ares_strcasecmp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(adig_CPPFLAGS) $(CPPFLAGS) $(adig_CFLAGS) $(CFLAGS) -MT ../lib/str/adig-ares_strcasecmp.o -MD -MP -MF ../lib/str/$(DEPDIR)/adig-ares_strcasecmp.Tpo -c -o ../lib/str/adig-ares_strcasecmp.o `test -f '../lib/str/ares_strcasecmp.c' || echo '$(srcdir)/'`../lib/str/ares_strcasecmp.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../lib/str/$(DEPDIR)/adig-ares_strcasecmp.Tpo ../lib/str/$(DEPDIR)/adig-ares_strcasecmp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../lib/str/ares_strcasecmp.c' object='../lib/str/adig-ares_strcasecmp.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(adig_CPPFLAGS) $(CPPFLAGS) $(adig_CFLAGS) $(CFLAGS) -c -o ../lib/adig-ares_strcasecmp.o `test -f '../lib/ares_strcasecmp.c' || echo '$(srcdir)/'`../lib/ares_strcasecmp.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(adig_CPPFLAGS) $(CPPFLAGS) $(adig_CFLAGS) $(CFLAGS) -c -o ../lib/str/adig-ares_strcasecmp.o `test -f '../lib/str/ares_strcasecmp.c' || echo '$(srcdir)/'`../lib/str/ares_strcasecmp.c -../lib/adig-ares_strcasecmp.obj: ../lib/ares_strcasecmp.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(adig_CPPFLAGS) $(CPPFLAGS) $(adig_CFLAGS) $(CFLAGS) -MT ../lib/adig-ares_strcasecmp.obj -MD -MP -MF ../lib/$(DEPDIR)/adig-ares_strcasecmp.Tpo -c -o ../lib/adig-ares_strcasecmp.obj `if test -f '../lib/ares_strcasecmp.c'; then $(CYGPATH_W) '../lib/ares_strcasecmp.c'; else $(CYGPATH_W) '$(srcdir)/../lib/ares_strcasecmp.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../lib/$(DEPDIR)/adig-ares_strcasecmp.Tpo ../lib/$(DEPDIR)/adig-ares_strcasecmp.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../lib/ares_strcasecmp.c' object='../lib/adig-ares_strcasecmp.obj' libtool=no @AMDEPBACKSLASH@ +../lib/str/adig-ares_strcasecmp.obj: ../lib/str/ares_strcasecmp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(adig_CPPFLAGS) $(CPPFLAGS) $(adig_CFLAGS) $(CFLAGS) -MT ../lib/str/adig-ares_strcasecmp.obj -MD -MP -MF ../lib/str/$(DEPDIR)/adig-ares_strcasecmp.Tpo -c -o ../lib/str/adig-ares_strcasecmp.obj `if test -f '../lib/str/ares_strcasecmp.c'; then $(CYGPATH_W) '../lib/str/ares_strcasecmp.c'; else $(CYGPATH_W) '$(srcdir)/../lib/str/ares_strcasecmp.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../lib/str/$(DEPDIR)/adig-ares_strcasecmp.Tpo ../lib/str/$(DEPDIR)/adig-ares_strcasecmp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../lib/str/ares_strcasecmp.c' object='../lib/str/adig-ares_strcasecmp.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(adig_CPPFLAGS) $(CPPFLAGS) $(adig_CFLAGS) $(CFLAGS) -c -o ../lib/adig-ares_strcasecmp.obj `if test -f '../lib/ares_strcasecmp.c'; then $(CYGPATH_W) '../lib/ares_strcasecmp.c'; else $(CYGPATH_W) '$(srcdir)/../lib/ares_strcasecmp.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(adig_CPPFLAGS) $(CPPFLAGS) $(adig_CFLAGS) $(CFLAGS) -c -o ../lib/str/adig-ares_strcasecmp.obj `if test -f '../lib/str/ares_strcasecmp.c'; then $(CYGPATH_W) '../lib/str/ares_strcasecmp.c'; else $(CYGPATH_W) '$(srcdir)/../lib/str/ares_strcasecmp.c'; fi` ahost-ahost.o: ahost.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ahost_CPPFLAGS) $(CPPFLAGS) $(ahost_CFLAGS) $(CFLAGS) -MT ahost-ahost.o -MD -MP -MF $(DEPDIR)/ahost-ahost.Tpo -c -o ahost-ahost.o `test -f 'ahost.c' || echo '$(srcdir)/'`ahost.c @@ -582,19 +584,19 @@ ahost-ares_getopt.obj: ares_getopt.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ahost_CPPFLAGS) $(CPPFLAGS) $(ahost_CFLAGS) $(CFLAGS) -c -o ahost-ares_getopt.obj `if test -f 'ares_getopt.c'; then $(CYGPATH_W) 'ares_getopt.c'; else $(CYGPATH_W) '$(srcdir)/ares_getopt.c'; fi` -../lib/ahost-ares_strcasecmp.o: ../lib/ares_strcasecmp.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ahost_CPPFLAGS) $(CPPFLAGS) $(ahost_CFLAGS) $(CFLAGS) -MT ../lib/ahost-ares_strcasecmp.o -MD -MP -MF ../lib/$(DEPDIR)/ahost-ares_strcasecmp.Tpo -c -o ../lib/ahost-ares_strcasecmp.o `test -f '../lib/ares_strcasecmp.c' || echo '$(srcdir)/'`../lib/ares_strcasecmp.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../lib/$(DEPDIR)/ahost-ares_strcasecmp.Tpo ../lib/$(DEPDIR)/ahost-ares_strcasecmp.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../lib/ares_strcasecmp.c' object='../lib/ahost-ares_strcasecmp.o' libtool=no @AMDEPBACKSLASH@ +../lib/str/ahost-ares_strcasecmp.o: ../lib/str/ares_strcasecmp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ahost_CPPFLAGS) $(CPPFLAGS) $(ahost_CFLAGS) $(CFLAGS) -MT ../lib/str/ahost-ares_strcasecmp.o -MD -MP -MF ../lib/str/$(DEPDIR)/ahost-ares_strcasecmp.Tpo -c -o ../lib/str/ahost-ares_strcasecmp.o `test -f '../lib/str/ares_strcasecmp.c' || echo '$(srcdir)/'`../lib/str/ares_strcasecmp.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../lib/str/$(DEPDIR)/ahost-ares_strcasecmp.Tpo ../lib/str/$(DEPDIR)/ahost-ares_strcasecmp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../lib/str/ares_strcasecmp.c' object='../lib/str/ahost-ares_strcasecmp.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ahost_CPPFLAGS) $(CPPFLAGS) $(ahost_CFLAGS) $(CFLAGS) -c -o ../lib/ahost-ares_strcasecmp.o `test -f '../lib/ares_strcasecmp.c' || echo '$(srcdir)/'`../lib/ares_strcasecmp.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ahost_CPPFLAGS) $(CPPFLAGS) $(ahost_CFLAGS) $(CFLAGS) -c -o ../lib/str/ahost-ares_strcasecmp.o `test -f '../lib/str/ares_strcasecmp.c' || echo '$(srcdir)/'`../lib/str/ares_strcasecmp.c -../lib/ahost-ares_strcasecmp.obj: ../lib/ares_strcasecmp.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ahost_CPPFLAGS) $(CPPFLAGS) $(ahost_CFLAGS) $(CFLAGS) -MT ../lib/ahost-ares_strcasecmp.obj -MD -MP -MF ../lib/$(DEPDIR)/ahost-ares_strcasecmp.Tpo -c -o ../lib/ahost-ares_strcasecmp.obj `if test -f '../lib/ares_strcasecmp.c'; then $(CYGPATH_W) '../lib/ares_strcasecmp.c'; else $(CYGPATH_W) '$(srcdir)/../lib/ares_strcasecmp.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../lib/$(DEPDIR)/ahost-ares_strcasecmp.Tpo ../lib/$(DEPDIR)/ahost-ares_strcasecmp.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../lib/ares_strcasecmp.c' object='../lib/ahost-ares_strcasecmp.obj' libtool=no @AMDEPBACKSLASH@ +../lib/str/ahost-ares_strcasecmp.obj: ../lib/str/ares_strcasecmp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ahost_CPPFLAGS) $(CPPFLAGS) $(ahost_CFLAGS) $(CFLAGS) -MT ../lib/str/ahost-ares_strcasecmp.obj -MD -MP -MF ../lib/str/$(DEPDIR)/ahost-ares_strcasecmp.Tpo -c -o ../lib/str/ahost-ares_strcasecmp.obj `if test -f '../lib/str/ares_strcasecmp.c'; then $(CYGPATH_W) '../lib/str/ares_strcasecmp.c'; else $(CYGPATH_W) '$(srcdir)/../lib/str/ares_strcasecmp.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../lib/str/$(DEPDIR)/ahost-ares_strcasecmp.Tpo ../lib/str/$(DEPDIR)/ahost-ares_strcasecmp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../lib/str/ares_strcasecmp.c' object='../lib/str/ahost-ares_strcasecmp.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ahost_CPPFLAGS) $(CPPFLAGS) $(ahost_CFLAGS) $(CFLAGS) -c -o ../lib/ahost-ares_strcasecmp.obj `if test -f '../lib/ares_strcasecmp.c'; then $(CYGPATH_W) '../lib/ares_strcasecmp.c'; else $(CYGPATH_W) '$(srcdir)/../lib/ares_strcasecmp.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ahost_CPPFLAGS) $(CPPFLAGS) $(ahost_CFLAGS) $(CFLAGS) -c -o ../lib/str/ahost-ares_strcasecmp.obj `if test -f '../lib/str/ares_strcasecmp.c'; then $(CYGPATH_W) '../lib/str/ares_strcasecmp.c'; else $(CYGPATH_W) '$(srcdir)/../lib/str/ares_strcasecmp.c'; fi` mostlyclean-libtool: -rm -f *.lo @@ -714,10 +716,10 @@ mostlyclean-generic: clean-generic: distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -rm -f ../lib/$(DEPDIR)/$(am__dirstamp) - -rm -f ../lib/$(am__dirstamp) + -$(am__rm_f) $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) + -$(am__rm_f) ../lib/str/$(DEPDIR)/$(am__dirstamp) + -$(am__rm_f) ../lib/str/$(am__dirstamp) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @@ -728,8 +730,8 @@ clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \ mostlyclean-am distclean: distclean-am - -rm -f ../lib/$(DEPDIR)/adig-ares_strcasecmp.Po - -rm -f ../lib/$(DEPDIR)/ahost-ares_strcasecmp.Po + -rm -f ../lib/str/$(DEPDIR)/adig-ares_strcasecmp.Po + -rm -f ../lib/str/$(DEPDIR)/ahost-ares_strcasecmp.Po -rm -f ./$(DEPDIR)/adig-adig.Po -rm -f ./$(DEPDIR)/adig-ares_getopt.Po -rm -f ./$(DEPDIR)/ahost-ahost.Po @@ -779,8 +781,8 @@ install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am - -rm -f ../lib/$(DEPDIR)/adig-ares_strcasecmp.Po - -rm -f ../lib/$(DEPDIR)/ahost-ares_strcasecmp.Po + -rm -f ../lib/str/$(DEPDIR)/adig-ares_strcasecmp.Po + -rm -f ../lib/str/$(DEPDIR)/ahost-ares_strcasecmp.Po -rm -f ./$(DEPDIR)/adig-adig.Po -rm -f ./$(DEPDIR)/adig-ares_getopt.Po -rm -f ./$(DEPDIR)/ahost-ahost.Po @@ -825,3 +827,10 @@ uninstall-am: # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: + +# Tell GNU make to disable its built-in pattern rules. +%:: %,v +%:: RCS/%,v +%:: RCS/% +%:: s.% +%:: SCCS/s.% diff --git a/deps/cares/src/tools/Makefile.inc b/deps/cares/src/tools/Makefile.inc index dd081b3005d..4c6b6aaa978 100644 --- a/deps/cares/src/tools/Makefile.inc +++ b/deps/cares/src/tools/Makefile.inc @@ -1,7 +1,7 @@ # Copyright (C) The c-ares project and its contributors # SPDX-License-Identifier: MIT SAMPLESOURCES = ares_getopt.c \ - ../lib/ares_strcasecmp.c + ../lib/str/ares_strcasecmp.c SAMPLEHEADERS = ares_getopt.h \ - ../lib/ares_strcasecmp.h + ../lib/str/ares_strcasecmp.h diff --git a/deps/cares/src/tools/adig.c b/deps/cares/src/tools/adig.c index 026340c72bf..8b2ad2e96a6 100644 --- a/deps/cares/src/tools/adig.c +++ b/deps/cares/src/tools/adig.c @@ -46,17 +46,17 @@ #include "ares_dns.h" #ifndef HAVE_STRDUP -# include "ares_str.h" +# include "str/ares_str.h" # define strdup(ptr) ares_strdup(ptr) #endif #ifndef HAVE_STRCASECMP -# include "ares_strcasecmp.h" +# include "str/ares_strcasecmp.h" # define strcasecmp(p1, p2) ares_strcasecmp(p1, p2) #endif #ifndef HAVE_STRNCASECMP -# include "ares_strcasecmp.h" +# include "str/ares_strcasecmp.h" # define strncasecmp(p1, p2, n) ares_strncasecmp(p1, p2, n) #endif @@ -120,35 +120,30 @@ static void print_help(void) printf( "usage: adig [-h] [-d] [-f flag] [[-s server] ...] [-T|U port] [-c class]\n" " [-t type] name ...\n\n"); + printf(" -h : Display this help and exit.\n"); + printf(" -d : Print some extra debugging output.\n"); printf( - " -h : Display this help and exit.\n"); - printf( - " -d : Print some extra debugging output.\n"); - printf( - " -f flag : Add a behavior control flag. May be specified more than once\n" + " -f flag : Add a behavior control flag. May be specified more than " + "once\n" " to add additional flags. Possible values are:\n" " igntc - do not retry a truncated query as TCP, just\n" " return the truncated answer\n" " noaliases - don't honor the HOSTALIASES environment\n" " variable\n"); - printf( - " norecurse - don't query upstream servers recursively\n" - " primary - use the first server\n" - " stayopen - don't close the communication sockets\n" - " usevc - use TCP only\n" - " edns - use EDNS\n" - " dns0x20 - enable DNS 0x20 support\n"); + printf(" norecurse - don't query upstream servers recursively\n" + " primary - use the first server\n" + " stayopen - don't close the communication sockets\n" + " usevc - use TCP only\n" + " edns - use EDNS\n" + " dns0x20 - enable DNS 0x20 support\n"); printf( " -s server : Connect to the specified DNS server, instead of the\n" " system's default one(s). Servers are tried in round-robin,\n" " if the previous one failed.\n"); - printf( - " -T port : Connect to the specified TCP port of DNS server.\n"); - printf( - " -U port : Connect to the specified UDP port of DNS server.\n"); - printf( - " -c class : Set the query class. Possible values for class are:\n" - " ANY, CHAOS, HS and IN (default)\n"); + printf(" -T port : Connect to the specified TCP port of DNS server.\n"); + printf(" -U port : Connect to the specified UDP port of DNS server.\n"); + printf(" -c class : Set the query class. Possible values for class are:\n" + " ANY, CHAOS, HS and IN (default)\n"); printf( " -t type : Query records of the specified type. Possible values for\n" " type are:\n" @@ -156,7 +151,7 @@ static void print_help(void) " SOA, SRV, TXT, TLSA, URI, CAA, SVCB, HTTPS\n\n"); } -static ares_bool_t read_cmdline(int argc, const char * const * argv, +static ares_bool_t read_cmdline(int argc, const char * const *argv, adig_config_t *config) { ares_getopt_state_t state; @@ -219,26 +214,35 @@ static ares_bool_t read_cmdline(int argc, const char * const * argv, break; case 'T': - /* Set the TCP port number. */ - if (!isdigit(*state.optarg)) { - snprintf(config->error, sizeof(config->error), "invalid port number"); - return ARES_FALSE; + { + /* Set the TCP port number. */ + long port = strtol(state.optarg, NULL, 0); + + if (port <= 0 || port > 65535) { + snprintf(config->error, sizeof(config->error), + "invalid port number"); + return ARES_FALSE; + } + config->options.tcp_port = (unsigned short)port; + config->options.flags |= ARES_FLAG_USEVC; + config->optmask |= ARES_OPT_TCP_PORT; } - config->options.tcp_port = - (unsigned short)strtol(state.optarg, NULL, 0); - config->options.flags |= ARES_FLAG_USEVC; - config->optmask |= ARES_OPT_TCP_PORT; break; case 'U': - /* Set the UDP port number. */ - if (!isdigit(*state.optarg)) { - snprintf(config->error, sizeof(config->error), "invalid port number"); - return ARES_FALSE; + { + /* Set the TCP port number. */ + long port = strtol(state.optarg, NULL, 0); + + if (port <= 0 || port > 65535) { + snprintf(config->error, sizeof(config->error), + "invalid port number"); + return ARES_FALSE; + } + config->options.udp_port = (unsigned short)port; + config->options.flags |= ARES_FLAG_USEVC; + config->optmask |= ARES_OPT_UDP_PORT; } - config->options.udp_port = - (unsigned short)strtol(state.optarg, NULL, 0); - config->optmask |= ARES_OPT_UDP_PORT; break; case ':': @@ -630,10 +634,10 @@ static void print_binp(const ares_dns_rr_t *rr, ares_dns_rr_key_t key) static void print_abinp(const ares_dns_rr_t *rr, ares_dns_rr_key_t key) { - size_t i; - size_t cnt = ares_dns_rr_get_abin_cnt(rr, key); + size_t i; + size_t cnt = ares_dns_rr_get_abin_cnt(rr, key); - for (i=0; iopterr = 1; diff --git a/deps/cares/src/tools/ares_getopt.h b/deps/cares/src/tools/ares_getopt.h index 7ff1fdeeb28..a8007b2dee0 100644 --- a/deps/cares/src/tools/ares_getopt.h +++ b/deps/cares/src/tools/ares_getopt.h @@ -34,16 +34,17 @@ typedef struct { - const char *optarg; /* argument associated with option */ - int optind; /* index into parent argv vector */ - int opterr; /* if error message should be printed */ - int optopt; /* character checked for validity */ - const char *place; - int argc; + const char *optarg; /* argument associated with option */ + int optind; /* index into parent argv vector */ + int opterr; /* if error message should be printed */ + int optopt; /* character checked for validity */ + const char *place; + int argc; const char * const *argv; } ares_getopt_state_t; -void ares_getopt_init(ares_getopt_state_t *state, int argc, const char * const * argv); +void ares_getopt_init(ares_getopt_state_t *state, int argc, + const char * const *argv); int ares_getopt(ares_getopt_state_t *state, const char *ostr); #endif /* ARES_GETOPT_H */ diff --git a/deps/cjs-module-lexer/.gitignore b/deps/cjs-module-lexer/.gitignore deleted file mode 100755 index 55ee2f0d6cf..00000000000 --- a/deps/cjs-module-lexer/.gitignore +++ /dev/null @@ -1,11 +0,0 @@ -node_modules -*.lock -test -.* -Makefile -bench -build.js -include-wasm -include -lib -src diff --git a/deps/cjs-module-lexer/CHANGELOG.md b/deps/cjs-module-lexer/CHANGELOG.md deleted file mode 100644 index e7d12a70f1a..00000000000 --- a/deps/cjs-module-lexer/CHANGELOG.md +++ /dev/null @@ -1,40 +0,0 @@ -1.2.2 -- Fix RollupJS reexports bug (https://github.com/guybedford/cjs-module-lexer/pull/59) - -1.2.1 -- Support Unicode escapes in strings (https://github.com/guybedford/cjs-module-lexer/pull/55) -- Filter export strings to valid surrogate pairs (https://github.com/guybedford/cjs-module-lexer/pull/56) - -1.2.0 -- Support for non-identifier exports (https://github.com/guybedford/cjs-module-lexer/pull/54, @nicolo-ribaudo) - -1.1.1 -- Better support for Babel reexport getter function forms (https://github.com/guybedford/cjs-module-lexer/issues/50) -- Support Babel interopRequireWildcard reexports patterns (https://github.com/guybedford/cjs-module-lexer/issues/52) - -1.1.0 -- Support for Babel reexport conflict filter (https://github.com/guybedford/cjs-module-lexer/issues/36, @nicolo-ribaudo) -- Support trailing commas in getter patterns (https://github.com/guybedford/cjs-module-lexer/issues/31) -- Support for RollupJS reexports property checks (https://github.com/guybedford/cjs-module-lexer/issues/38) - -1.0.0 -- Unsafe getter tracking (https://github.com/guybedford/cjs-module-lexer/pull/29) - -0.6.0 -- API-only breaking change: Unify JS and Wasm interfaces (https://github.com/guybedford/cjs-module-lexer/pull/27) -- Add type definitions (https://github.com/guybedford/cjs-module-lexer/pull/28) - -0.5.2 -- Support named getter functions (https://github.com/guybedford/cjs-module-lexer/pull/26) - -0.5.1: -- Feature: Implement specific reexport getter forms (https://github.com/guybedford/cjs-module-lexer/pull/25) - -0.5.0 -- Breaking Change: No longer emit Object.defineProperty exports (https://github.com/guybedford/cjs-module-lexer/pull/24) -- Doc: Update link to WASI SDK (https://github.com/guybedford/cjs-module-lexer/pull/19) - -0.4.3 -- Support for Babel 7.12 reexports (https://github.com/guybedford/cjs-module-lexer/pull/16) -- Support module.exports = { ...require('x') } reexports (https://github.com/guybedford/cjs-module-lexer/pull/18) -- "if" keyword space parsing in exports matching (https://github.com/guybedford/cjs-module-lexer/pull/17) diff --git a/deps/cjs-module-lexer/LICENSE b/deps/cjs-module-lexer/LICENSE old mode 100755 new mode 100644 index 935b357962d..b31c17aa33c --- a/deps/cjs-module-lexer/LICENSE +++ b/deps/cjs-module-lexer/LICENSE @@ -1,10 +1,10 @@ -MIT License ------------ - -Copyright (C) 2018-2020 Guy Bedford - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +MIT License +----------- + +Copyright (C) 2018-2020 Guy Bedford + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/deps/cjs-module-lexer/README.md b/deps/cjs-module-lexer/README.md old mode 100755 new mode 100644 index a761c0c7dfd..2af01279ed2 --- a/deps/cjs-module-lexer/README.md +++ b/deps/cjs-module-lexer/README.md @@ -1,453 +1,462 @@ -# CJS Module Lexer - -[![Build Status][travis-image]][travis-url] - -A [very fast](#benchmarks) JS CommonJS module syntax lexer used to detect the most likely list of named exports of a CommonJS module. - -Outputs the list of named exports (`exports.name = ...`) and possible module reexports (`module.exports = require('...')`), including the common transpiler variations of these cases. - -Forked from https://github.com/guybedford/es-module-lexer. - -_Comprehensively handles the JS language grammar while remaining small and fast. - ~90ms per MB of JS cold and ~15ms per MB of JS warm, [see benchmarks](#benchmarks) for more info._ - -### Usage - -``` -npm install cjs-module-lexer -``` - -For use in CommonJS: - -```js -const { parse } = require('cjs-module-lexer'); - -// `init` return a promise for parity with the ESM API, but you do not have to call it - -const { exports, reexports } = parse(` - // named exports detection - module.exports.a = 'a'; - (function () { - exports.b = 'b'; - })(); - Object.defineProperty(exports, 'c', { value: 'c' }); - /* exports.d = 'not detected'; */ - - // reexports detection - if (maybe) module.exports = require('./dep1.js'); - if (another) module.exports = require('./dep2.js'); - - // literal exports assignments - module.exports = { a, b: c, d, 'e': f } - - // __esModule detection - Object.defineProperty(module.exports, '__esModule', { value: true }) -`); - -// exports === ['a', 'b', 'c', '__esModule'] -// reexports === ['./dep1.js', './dep2.js'] -``` - -When using the ESM version, Wasm is supported instead: - -```js -import { parse, init } from 'cjs-module-lexer'; -// init needs to be called and waited upon -await init(); -const { exports, reexports } = parse(source); -``` - -The Wasm build is around 1.5x faster and without a cold start. - -### Grammar - -CommonJS exports matches are run against the source token stream. - -The token grammar is: - -``` -IDENTIFIER: As defined by ECMA-262, without support for identifier `\` escapes, filtered to remove strict reserved words: - "implements", "interface", "let", "package", "private", "protected", "public", "static", "yield", "enum" - -STRING_LITERAL: A `"` or `'` bounded ECMA-262 string literal. - -MODULE_EXPORTS: `module` `.` `exports` - -EXPORTS_IDENTIFIER: MODULE_EXPORTS_IDENTIFIER | `exports` - -EXPORTS_DOT_ASSIGN: EXPORTS_IDENTIFIER `.` IDENTIFIER `=` - -EXPORTS_LITERAL_COMPUTED_ASSIGN: EXPORTS_IDENTIFIER `[` STRING_LITERAL `]` `=` - -EXPORTS_LITERAL_PROP: (IDENTIFIER (`:` IDENTIFIER)?) | (STRING_LITERAL `:` IDENTIFIER) - -EXPORTS_SPREAD: `...` (IDENTIFIER | REQUIRE) - -EXPORTS_MEMBER: EXPORTS_DOT_ASSIGN | EXPORTS_LITERAL_COMPUTED_ASSIGN - -EXPORTS_DEFINE: `Object` `.` `defineProperty `(` EXPORTS_IDENFITIER `,` STRING_LITERAL - -EXPORTS_DEFINE_VALUE: EXPORTS_DEFINE `, {` - (`enumerable: true,`)? - ( - `value:` | - `get` (`: function` IDENTIFIER? )? `() {` return IDENTIFIER (`.` IDENTIFIER | `[` STRING_LITERAL `]`)? `;`? `}` `,`? - ) - `})` - -EXPORTS_LITERAL: MODULE_EXPORTS `=` `{` (EXPORTS_LITERAL_PROP | EXPORTS_SPREAD) `,`)+ `}` - -REQUIRE: `require` `(` STRING_LITERAL `)` - -EXPORTS_ASSIGN: (`var` | `const` | `let`) IDENTIFIER `=` (`_interopRequireWildcard (`)? REQUIRE - -MODULE_EXPORTS_ASSIGN: MODULE_EXPORTS `=` REQUIRE - -EXPORT_STAR: (`__export` | `__exportStar`) `(` REQUIRE - -EXPORT_STAR_LIB: `Object.keys(` IDENTIFIER$1 `).forEach(function (` IDENTIFIER$2 `) {` - ( - ( - `if (` IDENTIFIER$2 `===` ( `'default'` | `"default"` ) `||` IDENTIFIER$2 `===` ( '__esModule' | `"__esModule"` ) `) return` `;`? - ( - (`if (Object` `.prototype`? `.hasOwnProperty.call(` IDENTIFIER `, ` IDENTIFIER$2 `)) return` `;`?)? - (`if (` IDENTIFIER$2 `in` EXPORTS_IDENTIFIER `&&` EXPORTS_IDENTIFIER `[` IDENTIFIER$2 `] ===` IDENTIFIER$1 `[` IDENTIFIER$2 `]) return` `;`)? - )? - ) | - `if (` IDENTIFIER$2 `!==` ( `'default'` | `"default"` ) (`&& !` (`Object` `.prototype`? `.hasOwnProperty.call(` IDENTIFIER `, ` IDENTIFIER$2 `)` | IDENTIFIER `.hasOwnProperty(` IDENTIFIER$2 `)`))? `)` - ) - ( - EXPORTS_IDENTIFIER `[` IDENTIFIER$2 `] =` IDENTIFIER$1 `[` IDENTIFIER$2 `]` `;`? | - `Object.defineProperty(` EXPORTS_IDENTIFIER `, ` IDENTIFIER$2 `, { enumerable: true, get` (`: function` IDENTIFIER? )? `() { return ` IDENTIFIER$1 `[` IDENTIFIER$2 `]` `;`? `}` `,`? `})` `;`? - ) - `})` -``` - -Spacing between tokens is taken to be any ECMA-262 whitespace, ECMA-262 block comment or ECMA-262 line comment. - -* The returned export names are taken to be the combination of: - 1. All `IDENTIFIER` and `STRING_LITERAL` slots for `EXPORTS_MEMBER` and `EXPORTS_LITERAL` matches. - 2. The first `STRING_LITERAL` slot for all `EXPORTS_DEFINE_VALUE` matches where that same string is not an `EXPORTS_DEFINE` match that is not also an `EXPORTS_DEFINE_VALUE` match. -* The reexport specifiers are taken to be the combination of: - 1. The `REQUIRE` matches of the last matched of either `MODULE_EXPORTS_ASSIGN` or `EXPORTS_LITERAL`. - 2. All _top-level_ `EXPORT_STAR` `REQUIRE` matches and `EXPORTS_ASSIGN` matches whose `IDENTIFIER` also matches the first `IDENTIFIER` in `EXPORT_STAR_LIB`. - -### Parsing Examples - -#### Named Exports Parsing - -The basic matching rules for named exports are `exports.name`, `exports['name']` or `Object.defineProperty(exports, 'name', ...)`. This matching is done without scope analysis and regardless of the expression position: - -```js -// DETECTS EXPORTS: a, b -(function (exports) { - exports.a = 'a'; - exports['b'] = 'b'; -})(exports); -``` - -Because there is no scope analysis, the above detection may overclassify: - -```js -// DETECTS EXPORTS: a, b, c -(function (exports, Object) { - exports.a = 'a'; - exports['b'] = 'b'; - if (false) - exports.c = 'c'; -})(NOT_EXPORTS, NOT_OBJECT); -``` - -It will in turn underclassify in cases where the identifiers are renamed: - -```js -// DETECTS: NO EXPORTS -(function (e) { - e.a = 'a'; - e['b'] = 'b'; -})(exports); -``` - -#### Getter Exports Parsing - -`Object.defineProperty` is detected for specifically value and getter forms returning an identifier or member expression: - -```js -// DETECTS: a, b, c, d, __esModule -Object.defineProperty(exports, 'a', { - enumerable: true, - get: function () { - return q.p; - } -}); -Object.defineProperty(exports, 'b', { - enumerable: true, - get: function () { - return q['p']; - } -}); -Object.defineProperty(exports, 'c', { - enumerable: true, - get () { - return b; - } -}); -Object.defineProperty(exports, 'd', { value: 'd' }); -Object.defineProperty(exports, '__esModule', { value: true }); -``` - -Value properties are also detected specifically: - -```js -Object.defineProperty(exports, 'a', { - value: 'no problem' -}); -``` - -To avoid matching getters that have side effects, any getter for an export name that does not support the forms above will -opt-out of the getter matching: - -```js -// DETECTS: NO EXPORTS -Object.defineProperty(exports, 'a', { - get () { - return 'nope'; - } -}); - -if (false) { - Object.defineProperty(module.exports, 'a', { - get () { - return dynamic(); - } - }) -} -``` - -Alternative object definition structures or getter function bodies are not detected: - -```js -// DETECTS: NO EXPORTS -Object.defineProperty(exports, 'a', { - enumerable: false, - get () { - return p; - } -}); -Object.defineProperty(exports, 'b', { - configurable: true, - get () { - return p; - } -}); -Object.defineProperty(exports, 'c', { - get: () => p -}); -Object.defineProperty(exports, 'd', { - enumerable: true, - get: function () { - return dynamic(); - } -}); -Object.defineProperty(exports, 'e', { - enumerable: true, - get () { - return 'str'; - } -}); -``` - -`Object.defineProperties` is also not supported. - -#### Exports Object Assignment - -A best-effort is made to detect `module.exports` object assignments, but because this is not a full parser, arbitrary expressions are not handled in the -object parsing process. - -Simple object definitions are supported: - -```js -// DETECTS EXPORTS: a, b, c -module.exports = { - a, - 'b': b, - c: c, - ...d -}; -``` - -Object properties that are not identifiers or string expressions will bail out of the object detection, while spreads are ignored: - -```js -// DETECTS EXPORTS: a, b -module.exports = { - a, - ...d, - b: require('c'), - c: "not detected since require('c') above bails the object detection" -} -``` - -`Object.defineProperties` is not currently supported either. - -#### module.exports reexport assignment - -Any `module.exports = require('mod')` assignment is detected as a reexport, but only the last one is returned: - -```js -// DETECTS REEXPORTS: c -module.exports = require('a'); -(module => module.exports = require('b'))(NOT_MODULE); -if (false) module.exports = require('c'); -``` - -This is to avoid over-classification in Webpack bundles with externals which include `module.exports = require('external')` in their source for every external dependency. - -In exports object assignment, any spread of `require()` are detected as multiple separate reexports: - -```js -// DETECTS REEXPORTS: a, b -module.exports = require('ignored'); -module.exports = { - ...require('a'), - ...require('b') -}; -``` - -#### Transpiler Re-exports - -For named exports, transpiler output works well with the rules described above. - -But for star re-exports, special care is taken to support common patterns of transpiler outputs from Babel and TypeScript as well as bundlers like RollupJS. -These reexport and star reexport patterns are restricted to only be detected at the top-level as provided by the direct output of these tools. - -For example, `export * from 'external'` is output by Babel as: - -```js -"use strict"; - -exports.__esModule = true; - -var _external = require("external"); - -Object.keys(_external).forEach(function (key) { - if (key === "default" || key === "__esModule") return; - exports[key] = _external[key]; -}); -``` - -Where the `var _external = require("external")` is specifically detected as well as the `Object.keys(_external)` statement, down to the exact -for of that entire expression including minor variations of the output. The `_external` and `key` identifiers are carefully matched in this -detection. - -Similarly for TypeScript, `export * from 'external'` is output as: - -```js -"use strict"; -function __export(m) { - for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; -} -Object.defineProperty(exports, "__esModule", { value: true }); -__export(require("external")); -``` - -Where the `__export(require("external"))` statement is explicitly detected as a reexport, including variations `tslib.__export` and `__exportStar`. - -### Environment Support - -Node.js 10+, and [all browsers with Web Assembly support](https://caniuse.com/#feat=wasm). - -### JS Grammar Support - -* Token state parses all line comments, block comments, strings, template strings, blocks, parens and punctuators. -* Division operator / regex token ambiguity is handled via backtracking checks against punctuator prefixes, including closing brace or paren backtracking. -* Always correctly parses valid JS source, but may parse invalid JS source without errors. - -### Benchmarks - -Benchmarks can be run with `npm run bench`. - -Current results: - -JS Build: - -``` -Module load time -> 4ms -Cold Run, All Samples -test/samples/*.js (3635 KiB) -> 299ms - -Warm Runs (average of 25 runs) -test/samples/angular.js (1410 KiB) -> 13.96ms -test/samples/angular.min.js (303 KiB) -> 4.72ms -test/samples/d3.js (553 KiB) -> 6.76ms -test/samples/d3.min.js (250 KiB) -> 4ms -test/samples/magic-string.js (34 KiB) -> 0.64ms -test/samples/magic-string.min.js (20 KiB) -> 0ms -test/samples/rollup.js (698 KiB) -> 8.48ms -test/samples/rollup.min.js (367 KiB) -> 5.36ms - -Warm Runs, All Samples (average of 25 runs) -test/samples/*.js (3635 KiB) -> 40.28ms -``` - -Wasm Build: -``` -Module load time -> 10ms -Cold Run, All Samples -test/samples/*.js (3635 KiB) -> 43ms - -Warm Runs (average of 25 runs) -test/samples/angular.js (1410 KiB) -> 9.32ms -test/samples/angular.min.js (303 KiB) -> 3.16ms -test/samples/d3.js (553 KiB) -> 5ms -test/samples/d3.min.js (250 KiB) -> 2.32ms -test/samples/magic-string.js (34 KiB) -> 0.16ms -test/samples/magic-string.min.js (20 KiB) -> 0ms -test/samples/rollup.js (698 KiB) -> 6.28ms -test/samples/rollup.min.js (367 KiB) -> 3.6ms - -Warm Runs, All Samples (average of 25 runs) -test/samples/*.js (3635 KiB) -> 27.76ms -``` - -### Wasm Build Steps - -To build download the WASI SDK from https://github.com/WebAssembly/wasi-sdk/releases. - -The Makefile assumes the existence of "wasi-sdk-11.0" and "wabt" (optional) as sibling folders to this project. - -The build through the Makefile is then run via `make lib/lexer.wasm`, which can also be triggered via `npm run build-wasm` to create `dist/lexer.js`. - -On Windows it may be preferable to use the Linux subsystem. - -After the Web Assembly build, the CJS build can be triggered via `npm run build`. - -Optimization passes are run with [Binaryen](https://github.com/WebAssembly/binaryen) prior to publish to reduce the Web Assembly footprint. - -### License - -MIT - -[travis-url]: https://travis-ci.org/guybedford/es-module-lexer -[travis-image]: https://travis-ci.org/guybedford/es-module-lexer.svg?branch=master +# CJS Module Lexer + +[![Build Status][travis-image]][travis-url] + +A [very fast](#benchmarks) JS CommonJS module syntax lexer used to detect the most likely list of named exports of a CommonJS module. + +Outputs the list of named exports (`exports.name = ...`) and possible module reexports (`module.exports = require('...')`), including the common transpiler variations of these cases. + +Forked from https://github.com/guybedford/es-module-lexer. + +_Comprehensively handles the JS language grammar while remaining small and fast. - ~90ms per MB of JS cold and ~15ms per MB of JS warm, [see benchmarks](#benchmarks) for more info._ + +### Project Status + +This project is used in Node.js core for detecting the named exports available when importing a CJS module into ESM, and is maintained for this purpose. + +PRs will be accepted and upstreamed for parser bugs, performance improvements or new syntax support only. + +_Detection patterns for this project are **frozen**_. This is because adding any new export detection patterns would result in fragmented backwards-compatibility. Specifically, it would be very difficult to figure out why an ES module named export for CommonJS might work in newer Node.js versions but not older versions. This problem would only be discovered downstream of module authors, with the fix for module authors being to then have to understand which patterns in this project provide full backwards-compatibily. Rather, by fully freezing the detected patterns, if it works in any Node.js version it will work in any other. Build tools can also reliably treat the supported syntax for this project as a part of their output target for ensuring syntax support. + +### Usage + +``` +npm install cjs-module-lexer +``` + +For use in CommonJS: + +```js +const { parse } = require('cjs-module-lexer'); + +// `init` return a promise for parity with the ESM API, but you do not have to call it + +const { exports, reexports } = parse(` + // named exports detection + module.exports.a = 'a'; + (function () { + exports.b = 'b'; + })(); + Object.defineProperty(exports, 'c', { value: 'c' }); + /* exports.d = 'not detected'; */ + + // reexports detection + if (maybe) module.exports = require('./dep1.js'); + if (another) module.exports = require('./dep2.js'); + + // literal exports assignments + module.exports = { a, b: c, d, 'e': f } + + // __esModule detection + Object.defineProperty(module.exports, '__esModule', { value: true }) +`); + +// exports === ['a', 'b', 'c', '__esModule'] +// reexports === ['./dep1.js', './dep2.js'] +``` + +When using the ESM version, Wasm is supported instead: + +```js +import { parse, init } from 'cjs-module-lexer'; +// init() needs to be called and waited upon, or use initSync() to compile +// Wasm blockingly and synchronously. +await init(); +const { exports, reexports } = parse(source); +``` + +The Wasm build is around 1.5x faster and without a cold start. + +### Grammar + +CommonJS exports matches are run against the source token stream. + +The token grammar is: + +``` +IDENTIFIER: As defined by ECMA-262, without support for identifier `\` escapes, filtered to remove strict reserved words: + "implements", "interface", "let", "package", "private", "protected", "public", "static", "yield", "enum" + +STRING_LITERAL: A `"` or `'` bounded ECMA-262 string literal. + +MODULE_EXPORTS: `module` `.` `exports` + +EXPORTS_IDENTIFIER: MODULE_EXPORTS_IDENTIFIER | `exports` + +EXPORTS_DOT_ASSIGN: EXPORTS_IDENTIFIER `.` IDENTIFIER `=` + +EXPORTS_LITERAL_COMPUTED_ASSIGN: EXPORTS_IDENTIFIER `[` STRING_LITERAL `]` `=` + +EXPORTS_LITERAL_PROP: (IDENTIFIER (`:` IDENTIFIER)?) | (STRING_LITERAL `:` IDENTIFIER) + +EXPORTS_SPREAD: `...` (IDENTIFIER | REQUIRE) + +EXPORTS_MEMBER: EXPORTS_DOT_ASSIGN | EXPORTS_LITERAL_COMPUTED_ASSIGN + +EXPORTS_DEFINE: `Object` `.` `defineProperty `(` EXPORTS_IDENFITIER `,` STRING_LITERAL + +EXPORTS_DEFINE_VALUE: EXPORTS_DEFINE `, {` + (`enumerable: true,`)? + ( + `value:` | + `get` (`: function` IDENTIFIER? )? `() {` return IDENTIFIER (`.` IDENTIFIER | `[` STRING_LITERAL `]`)? `;`? `}` `,`? + ) + `})` + +EXPORTS_LITERAL: MODULE_EXPORTS `=` `{` (EXPORTS_LITERAL_PROP | EXPORTS_SPREAD) `,`)+ `}` + +REQUIRE: `require` `(` STRING_LITERAL `)` + +EXPORTS_ASSIGN: (`var` | `const` | `let`) IDENTIFIER `=` (`_interopRequireWildcard (`)? REQUIRE + +MODULE_EXPORTS_ASSIGN: MODULE_EXPORTS `=` REQUIRE + +EXPORT_STAR: (`__export` | `__exportStar`) `(` REQUIRE + +EXPORT_STAR_LIB: `Object.keys(` IDENTIFIER$1 `).forEach(function (` IDENTIFIER$2 `) {` + ( + ( + `if (` IDENTIFIER$2 `===` ( `'default'` | `"default"` ) `||` IDENTIFIER$2 `===` ( '__esModule' | `"__esModule"` ) `) return` `;`? + ( + (`if (Object` `.prototype`? `.hasOwnProperty.call(` IDENTIFIER `, ` IDENTIFIER$2 `)) return` `;`?)? + (`if (` IDENTIFIER$2 `in` EXPORTS_IDENTIFIER `&&` EXPORTS_IDENTIFIER `[` IDENTIFIER$2 `] ===` IDENTIFIER$1 `[` IDENTIFIER$2 `]) return` `;`)? + )? + ) | + `if (` IDENTIFIER$2 `!==` ( `'default'` | `"default"` ) (`&& !` (`Object` `.prototype`? `.hasOwnProperty.call(` IDENTIFIER `, ` IDENTIFIER$2 `)` | IDENTIFIER `.hasOwnProperty(` IDENTIFIER$2 `)`))? `)` + ) + ( + EXPORTS_IDENTIFIER `[` IDENTIFIER$2 `] =` IDENTIFIER$1 `[` IDENTIFIER$2 `]` `;`? | + `Object.defineProperty(` EXPORTS_IDENTIFIER `, ` IDENTIFIER$2 `, { enumerable: true, get` (`: function` IDENTIFIER? )? `() { return ` IDENTIFIER$1 `[` IDENTIFIER$2 `]` `;`? `}` `,`? `})` `;`? + ) + `})` +``` + +Spacing between tokens is taken to be any ECMA-262 whitespace, ECMA-262 block comment or ECMA-262 line comment. + +* The returned export names are taken to be the combination of: + 1. All `IDENTIFIER` and `STRING_LITERAL` slots for `EXPORTS_MEMBER` and `EXPORTS_LITERAL` matches. + 2. The first `STRING_LITERAL` slot for all `EXPORTS_DEFINE_VALUE` matches where that same string is not an `EXPORTS_DEFINE` match that is not also an `EXPORTS_DEFINE_VALUE` match. +* The reexport specifiers are taken to be the combination of: + 1. The `REQUIRE` matches of the last matched of either `MODULE_EXPORTS_ASSIGN` or `EXPORTS_LITERAL`. + 2. All _top-level_ `EXPORT_STAR` `REQUIRE` matches and `EXPORTS_ASSIGN` matches whose `IDENTIFIER` also matches the first `IDENTIFIER` in `EXPORT_STAR_LIB`. + +### Parsing Examples + +#### Named Exports Parsing + +The basic matching rules for named exports are `exports.name`, `exports['name']` or `Object.defineProperty(exports, 'name', ...)`. This matching is done without scope analysis and regardless of the expression position: + +```js +// DETECTS EXPORTS: a, b +(function (exports) { + exports.a = 'a'; + exports['b'] = 'b'; +})(exports); +``` + +Because there is no scope analysis, the above detection may overclassify: + +```js +// DETECTS EXPORTS: a, b, c +(function (exports, Object) { + exports.a = 'a'; + exports['b'] = 'b'; + if (false) + exports.c = 'c'; +})(NOT_EXPORTS, NOT_OBJECT); +``` + +It will in turn underclassify in cases where the identifiers are renamed: + +```js +// DETECTS: NO EXPORTS +(function (e) { + e.a = 'a'; + e['b'] = 'b'; +})(exports); +``` + +#### Getter Exports Parsing + +`Object.defineProperty` is detected for specifically value and getter forms returning an identifier or member expression: + +```js +// DETECTS: a, b, c, d, __esModule +Object.defineProperty(exports, 'a', { + enumerable: true, + get: function () { + return q.p; + } +}); +Object.defineProperty(exports, 'b', { + enumerable: true, + get: function () { + return q['p']; + } +}); +Object.defineProperty(exports, 'c', { + enumerable: true, + get () { + return b; + } +}); +Object.defineProperty(exports, 'd', { value: 'd' }); +Object.defineProperty(exports, '__esModule', { value: true }); +``` + +Value properties are also detected specifically: + +```js +Object.defineProperty(exports, 'a', { + value: 'no problem' +}); +``` + +To avoid matching getters that have side effects, any getter for an export name that does not support the forms above will +opt-out of the getter matching: + +```js +// DETECTS: NO EXPORTS +Object.defineProperty(exports, 'a', { + get () { + return 'nope'; + } +}); + +if (false) { + Object.defineProperty(module.exports, 'a', { + get () { + return dynamic(); + } + }) +} +``` + +Alternative object definition structures or getter function bodies are not detected: + +```js +// DETECTS: NO EXPORTS +Object.defineProperty(exports, 'a', { + enumerable: false, + get () { + return p; + } +}); +Object.defineProperty(exports, 'b', { + configurable: true, + get () { + return p; + } +}); +Object.defineProperty(exports, 'c', { + get: () => p +}); +Object.defineProperty(exports, 'd', { + enumerable: true, + get: function () { + return dynamic(); + } +}); +Object.defineProperty(exports, 'e', { + enumerable: true, + get () { + return 'str'; + } +}); +``` + +`Object.defineProperties` is also not supported. + +#### Exports Object Assignment + +A best-effort is made to detect `module.exports` object assignments, but because this is not a full parser, arbitrary expressions are not handled in the +object parsing process. + +Simple object definitions are supported: + +```js +// DETECTS EXPORTS: a, b, c +module.exports = { + a, + 'b': b, + c: c, + ...d +}; +``` + +Object properties that are not identifiers or string expressions will bail out of the object detection, while spreads are ignored: + +```js +// DETECTS EXPORTS: a, b +module.exports = { + a, + ...d, + b: require('c'), + c: "not detected since require('c') above bails the object detection" +} +``` + +`Object.defineProperties` is not currently supported either. + +#### module.exports reexport assignment + +Any `module.exports = require('mod')` assignment is detected as a reexport, but only the last one is returned: + +```js +// DETECTS REEXPORTS: c +module.exports = require('a'); +(module => module.exports = require('b'))(NOT_MODULE); +if (false) module.exports = require('c'); +``` + +This is to avoid over-classification in Webpack bundles with externals which include `module.exports = require('external')` in their source for every external dependency. + +In exports object assignment, any spread of `require()` are detected as multiple separate reexports: + +```js +// DETECTS REEXPORTS: a, b +module.exports = require('ignored'); +module.exports = { + ...require('a'), + ...require('b') +}; +``` + +#### Transpiler Re-exports + +For named exports, transpiler output works well with the rules described above. + +But for star re-exports, special care is taken to support common patterns of transpiler outputs from Babel and TypeScript as well as bundlers like RollupJS. +These reexport and star reexport patterns are restricted to only be detected at the top-level as provided by the direct output of these tools. + +For example, `export * from 'external'` is output by Babel as: + +```js +"use strict"; + +exports.__esModule = true; + +var _external = require("external"); + +Object.keys(_external).forEach(function (key) { + if (key === "default" || key === "__esModule") return; + exports[key] = _external[key]; +}); +``` + +Where the `var _external = require("external")` is specifically detected as well as the `Object.keys(_external)` statement, down to the exact +for of that entire expression including minor variations of the output. The `_external` and `key` identifiers are carefully matched in this +detection. + +Similarly for TypeScript, `export * from 'external'` is output as: + +```js +"use strict"; +function __export(m) { + for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; +} +Object.defineProperty(exports, "__esModule", { value: true }); +__export(require("external")); +``` + +Where the `__export(require("external"))` statement is explicitly detected as a reexport, including variations `tslib.__export` and `__exportStar`. + +### Environment Support + +Node.js 10+, and [all browsers with Web Assembly support](https://caniuse.com/#feat=wasm). + +### JS Grammar Support + +* Token state parses all line comments, block comments, strings, template strings, blocks, parens and punctuators. +* Division operator / regex token ambiguity is handled via backtracking checks against punctuator prefixes, including closing brace or paren backtracking. +* Always correctly parses valid JS source, but may parse invalid JS source without errors. + +### Benchmarks + +Benchmarks can be run with `npm run bench`. + +Current results: + +JS Build: + +``` +Module load time +> 4ms +Cold Run, All Samples +test/samples/*.js (3635 KiB) +> 299ms + +Warm Runs (average of 25 runs) +test/samples/angular.js (1410 KiB) +> 13.96ms +test/samples/angular.min.js (303 KiB) +> 4.72ms +test/samples/d3.js (553 KiB) +> 6.76ms +test/samples/d3.min.js (250 KiB) +> 4ms +test/samples/magic-string.js (34 KiB) +> 0.64ms +test/samples/magic-string.min.js (20 KiB) +> 0ms +test/samples/rollup.js (698 KiB) +> 8.48ms +test/samples/rollup.min.js (367 KiB) +> 5.36ms + +Warm Runs, All Samples (average of 25 runs) +test/samples/*.js (3635 KiB) +> 40.28ms +``` + +Wasm Build: +``` +Module load time +> 10ms +Cold Run, All Samples +test/samples/*.js (3635 KiB) +> 43ms + +Warm Runs (average of 25 runs) +test/samples/angular.js (1410 KiB) +> 9.32ms +test/samples/angular.min.js (303 KiB) +> 3.16ms +test/samples/d3.js (553 KiB) +> 5ms +test/samples/d3.min.js (250 KiB) +> 2.32ms +test/samples/magic-string.js (34 KiB) +> 0.16ms +test/samples/magic-string.min.js (20 KiB) +> 0ms +test/samples/rollup.js (698 KiB) +> 6.28ms +test/samples/rollup.min.js (367 KiB) +> 3.6ms + +Warm Runs, All Samples (average of 25 runs) +test/samples/*.js (3635 KiB) +> 27.76ms +``` + +### Wasm Build Steps + +To build download the WASI SDK from https://github.com/WebAssembly/wasi-sdk/releases. + +The Makefile assumes the existence of "wasi-sdk-11.0" and "wabt" (optional) as sibling folders to this project. + +The build through the Makefile is then run via `make lib/lexer.wasm`, which can also be triggered via `npm run build-wasm` to create `dist/lexer.js`. + +On Windows it may be preferable to use the Linux subsystem. + +After the Web Assembly build, the CJS build can be triggered via `npm run build`. + +Optimization passes are run with [Binaryen](https://github.com/WebAssembly/binaryen) prior to publish to reduce the Web Assembly footprint. + +### License + +MIT + +[travis-url]: https://travis-ci.org/guybedford/es-module-lexer +[travis-image]: https://travis-ci.org/guybedford/es-module-lexer.svg?branch=master diff --git a/deps/cjs-module-lexer/dist/lexer-external.js b/deps/cjs-module-lexer/dist/lexer-external.js new file mode 100644 index 00000000000..1e5f49de622 --- /dev/null +++ b/deps/cjs-module-lexer/dist/lexer-external.js @@ -0,0 +1,91 @@ +"use strict"; + +exports.init = init; +exports.parse = parse; +let wasm; +const isLE = new Uint8Array(new Uint16Array([1]).buffer)[0] === 1; +function parse(source, name = '@') { + if (!wasm) throw new Error('Not initialized'); + const len = source.length + 1; + + // need 2 bytes per code point plus analysis space so we double again + const extraMem = (wasm.__heap_base.value || wasm.__heap_base) + len * 4 - wasm.memory.buffer.byteLength; + if (extraMem > 0) wasm.memory.grow(Math.ceil(extraMem / 65536)); + const addr = wasm.sa(len); + (isLE ? copyLE : copyBE)(source, new Uint16Array(wasm.memory.buffer, addr, len)); + const err_code = wasm.parseCJS(addr, source.length, 0, 0, 0); + if (err_code) { + const err = new Error(`Parse error ${name}${wasm.e()}:${source.slice(0, wasm.e()).split('\n').length}:${wasm.e() - source.lastIndexOf('\n', wasm.e() - 1)}`); + Object.assign(err, { + idx: wasm.e() + }); + if (err_code === 5 || err_code === 6 || err_code === 7) Object.assign(err, { + code: 'ERR_LEXER_ESM_SYNTAX' + }); + throw err; + } + let exports = new Set(), + reexports = new Set(), + unsafeGetters = new Set(); + while (wasm.rre()) { + const reexptStr = decode(source.slice(wasm.res(), wasm.ree())); + if (reexptStr) reexports.add(reexptStr); + } + while (wasm.ru()) unsafeGetters.add(decode(source.slice(wasm.us(), wasm.ue()))); + while (wasm.re()) { + let exptStr = decode(source.slice(wasm.es(), wasm.ee())); + if (exptStr !== undefined && !unsafeGetters.has(exptStr)) exports.add(exptStr); + } + return { + exports: [...exports], + reexports: [...reexports] + }; +} +function decode(str) { + if (str[0] === '"' || str[0] === '\'') { + try { + const decoded = (0, eval)(str); + // Filter to exclude non-matching UTF-16 surrogate strings + for (let i = 0; i < decoded.length; i++) { + const surrogatePrefix = decoded.charCodeAt(i) & 0xFC00; + if (surrogatePrefix < 0xD800) { + // Not a surrogate + continue; + } else if (surrogatePrefix === 0xD800) { + // Validate surrogate pair + if ((decoded.charCodeAt(++i) & 0xFC00) !== 0xDC00) return; + } else { + // Out-of-range surrogate code (above 0xD800) + return; + } + } + return decoded; + } catch {} + } else { + return str; + } +} +function copyBE(src, outBuf16) { + const len = src.length; + let i = 0; + while (i < len) { + const ch = src.charCodeAt(i); + outBuf16[i++] = (ch & 0xff) << 8 | ch >>> 8; + } +} +function copyLE(src, outBuf16) { + const len = src.length; + let i = 0; + while (i < len) outBuf16[i] = src.charCodeAt(i++); +} +let initPromise; +function init() { + if (initPromise) return initPromise; + return initPromise = (async () => { + const compiled = await WebAssembly.compile((await import('node:fs')).readFileSync(new URL(import.meta.resolve('../lib/lexer.wasm')))); + const { + exports + } = await WebAssembly.instantiate(compiled); + wasm = exports; + })(); +} \ No newline at end of file diff --git a/deps/cjs-module-lexer/dist/lexer-external.mjs b/deps/cjs-module-lexer/dist/lexer-external.mjs new file mode 100644 index 00000000000..89450a3b60b --- /dev/null +++ b/deps/cjs-module-lexer/dist/lexer-external.mjs @@ -0,0 +1,104 @@ +let wasm; + +const isLE = new Uint8Array(new Uint16Array([1]).buffer)[0] === 1; + +export function parse (source, name = '@') { + if (!wasm) + throw new Error('Not initialized'); + + const len = source.length + 1; + + // need 2 bytes per code point plus analysis space so we double again + const extraMem = (wasm.__heap_base.value || wasm.__heap_base) + len * 4 - wasm.memory.buffer.byteLength; + if (extraMem > 0) + wasm.memory.grow(Math.ceil(extraMem / 65536)); + + const addr = wasm.sa(len); + (isLE ? copyLE : copyBE)(source, new Uint16Array(wasm.memory.buffer, addr, len)); + + const err_code = wasm.parseCJS(addr, source.length, 0, 0, 0); + + if (err_code) { + const err = new Error(`Parse error ${name}${wasm.e()}:${source.slice(0, wasm.e()).split('\n').length}:${wasm.e() - source.lastIndexOf('\n', wasm.e() - 1)}`); + Object.assign(err, { idx: wasm.e() }); + if (err_code === 5 || err_code === 6 || err_code === 7) + Object.assign(err, { code: 'ERR_LEXER_ESM_SYNTAX' }); + throw err; + } + + let exports = new Set(), reexports = new Set(), unsafeGetters = new Set(); + + while (wasm.rre()) { + const reexptStr = decode(source.slice(wasm.res(), wasm.ree())); + if (reexptStr) + reexports.add(reexptStr); + } + while (wasm.ru()) + unsafeGetters.add(decode(source.slice(wasm.us(), wasm.ue()))); + while (wasm.re()) { + let exptStr = decode(source.slice(wasm.es(), wasm.ee())); + if (exptStr !== undefined && !unsafeGetters.has(exptStr)) + exports.add(exptStr); + } + + return { exports: [...exports], reexports: [...reexports] }; +} + +function decode (str) { + if (str[0] === '"' || str[0] === '\'') { + try { + const decoded = (0, eval)(str); + // Filter to exclude non-matching UTF-16 surrogate strings + for (let i = 0; i < decoded.length; i++) { + const surrogatePrefix = decoded.charCodeAt(i) & 0xFC00; + if (surrogatePrefix < 0xD800) { + // Not a surrogate + continue; + } + else if (surrogatePrefix === 0xD800) { + // Validate surrogate pair + if ((decoded.charCodeAt(++i) & 0xFC00) !== 0xDC00) + return; + } + else { + // Out-of-range surrogate code (above 0xD800) + return; + } + } + return decoded; + } + catch {} + } + else { + return str; + } +} + +function copyBE (src, outBuf16) { + const len = src.length; + let i = 0; + while (i < len) { + const ch = src.charCodeAt(i); + outBuf16[i++] = (ch & 0xff) << 8 | ch >>> 8; + } +} + +function copyLE (src, outBuf16) { + const len = src.length; + let i = 0; + while (i < len) + outBuf16[i] = src.charCodeAt(i++); +} + +let initPromise; +export function init () { + if (initPromise) + return initPromise; + return initPromise = (async () => { + const compiled = await WebAssembly.compile( + (await import('node:fs')).readFileSync(new URL(import.meta.resolve('../lib/lexer.wasm'))) + ); + const { exports } = await WebAssembly.instantiate(compiled); + wasm = exports; + })(); +} diff --git a/deps/cjs-module-lexer/dist/lexer.js b/deps/cjs-module-lexer/dist/lexer.js index 391bc5624ee..7c9b7124ae2 100644 --- a/deps/cjs-module-lexer/dist/lexer.js +++ b/deps/cjs-module-lexer/dist/lexer.js @@ -1 +1 @@ -"use strict";exports.parse=parse;exports.init=init;let A;const Q=1===new Uint8Array(new Uint16Array([1]).buffer)[0];function parse(g,I="@"){if(!A)throw new Error("Not initialized");const D=g.length+1,N=(A.__heap_base.value||A.__heap_base)+4*D-A.memory.buffer.byteLength;N>0&&A.memory.grow(Math.ceil(N/65536));const k=A.sa(D);if((Q?C:E)(g,new Uint16Array(A.memory.buffer,k,D)),!A.parseCJS(k,g.length,0,0,0))throw Object.assign(new Error(`Parse error ${I}${A.e()}:${g.slice(0,A.e()).split("\n").length}:${A.e()-g.lastIndexOf("\n",A.e()-1)}`),{idx:A.e()});let w=new Set,o=new Set,J=new Set;for(;A.rre();){const Q=B(g.slice(A.res(),A.ree()));Q&&o.add(Q)}for(;A.ru();)J.add(B(g.slice(A.us(),A.ue())));for(;A.re();){let Q=B(g.slice(A.es(),A.ee()));void 0===Q||J.has(Q)||w.add(Q)}return{exports:[...w],reexports:[...o]}}function B(A){if('"'!==A[0]&&"'"!==A[0])return A;try{const Q=(0,eval)(A);for(let A=0;A>>8}}function C(A,Q){const B=A.length;let E=0;for(;E{const Q=await WebAssembly.compile((B="AGFzbQEAAAABrAERYAJ/fwBgAABgAX8Bf2AAAX9gBn9/f39/fwF/YAF/AGAXf39/f39/f39/f39/f39/f39/f39/f38Bf2AIf39/f39/f38Bf2AHf39/f39/fwF/YAN/f38Bf2AFf39/f38Bf2AOf39/f39/f39/f39/f38Bf2AKf39/f39/f39/fwF/YAt/f39/f39/f39/fwF/YAJ/fwF/YAR/f39/AX9gCX9/f39/f39/fwF/A0NCAgMDAwMDAwMDAwMAAAABBAICBQQFAQECAgICAQUBAQUBAQYHAQIIAwICAgkKAgELAgwNDgQPCA4HAgICAhACAgMJBAUBcAEFBQUDAQABBg8CfwFB0JgCC38AQdCYAgsHXA4GbWVtb3J5AgACc2EAAAFlAAECZXMAAgJlZQADA3JlcwAEA3JlZQAFAnVzAAYCdWUABwJyZQAIA3JyZQAJAnJ1AAoIcGFyc2VDSlMADwtfX2hlYXBfYmFzZQMBCQoBAEEBCwQLDA0OCtOhAUJ4AQF/QQAoApgfIgEgAEEBdGoiAEEAOwEAQQAgAEECaiIANgLkH0EAIAA2AugfQQBBADYCwB9BAEEANgLIH0EAQQA2AsQfQQBBADYCzB9BAEEANgLUH0EAQQA2AtAfQQBBADYC2B9BAEEANgLgH0EAQQA2AtwfIAELCABBACgC7B8LFQBBACgCxB8oAgBBACgCmB9rQQF1CxUAQQAoAsQfKAIEQQAoApgfa0EBdQsVAEEAKALQHygCAEEAKAKYH2tBAXULFQBBACgC0B8oAgRBACgCmB9rQQF1CxUAQQAoAtwfKAIAQQAoApgfa0EBdQsVAEEAKALcHygCBEEAKAKYH2tBAXULJQEBf0EAQQAoAsQfIgBBCGpBwB8gABsoAgAiADYCxB8gAEEARwslAQF/QQBBACgC0B8iAEEIakHMHyAAGygCACIANgLQHyAAQQBHCyUBAX9BAEEAKALcHyIAQQhqQdgfIAAbKAIAIgA2AtwfIABBAEcLSAEBf0EAKALIHyICQQhqQcAfIAIbQQAoAugfIgI2AgBBACACNgLIH0EAIAJBDGo2AugfIAJBADYCCCACIAE2AgQgAiAANgIAC0gBAX9BACgC1B8iAkEIakHMHyACG0EAKALoHyICNgIAQQAgAjYC1B9BACACQQxqNgLoHyACQQA2AgggAiABNgIEIAIgADYCAAtIAQF/QQAoAuAfIgJBCGpB2B8gAhtBACgC6B8iAjYCAEEAIAI2AuAfQQAgAkEMajYC6B8gAkEANgIIIAIgATYCBCACIAA2AgALEgBBAEEANgLMH0EAQQA2AtQfC6MPAEEAIAE2AoBAQQAgADYCmB8CQCACRQ0AQQAgAjYCnB8LAkAgA0UNAEEAIAM2AqAfCwJAIARFDQBBACAENgKkHwtBAEH//wM7AYhAQQBBoMAANgKgYEEAQbDgADYCsKABQQBBgCA2ArSgAUEAQQAoAqwfNgKMQEEAIABBfmoiAjYCvKABQQAgAiABQQF0aiIDNgLAoAFBAEEAOwGGQEEAQQA7AYRAQQBBADoAkEBBAEEANgLsH0EAQQA6APAfQQBBADoAuKABAkACQCAALwEAQSNHDQAgAC8BAkEhRw0AQQEhAiABQQJGDQFBACAAQQJqNgK8oAEgAEEEaiEAAkADQCAAIgJBfmogA08NASACQQJqIQAgAi8BAEF2aiIBQQNLDQAgAQ4EAQAAAQELC0EAIAI2ArygAQsDQEEAIAJBAmoiADYCvKABAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQCACIANPDQACQCAALwEAIgFBd2oiA0EXSw0AQQEgA3RBn4CABHENFwsCQAJAQQAvAYZAIgMNACABQaF/aiIEQQ5NDQMgAUFZaiIEQQhNDQQgAUGFf2oiBEECTQ0FIAFBIkYNCyABQc8ARg0BIAFB8gBHDRUCQEEAEBBFDQAgABARRQ0AIAIQEgtBAEEAKAK8oAE2AoxADBgLIAFBWWoiBEEITQ0FIAFBoH9qIgRBBU0NBiABQYV/aiIEQQJNDQcgAUEiRg0KIAFBzwBGDQAgAUHtAEcNFAwTCyACQQRqQeIAQeoAQeUAQeMAQfQAEBNFDRMgABARRQ0TIANFEBQMEwtBAC8BiEBB//8DRkEALwGGQEVxQQAtAPAfRXEPCyAEDg8SBRERDhEPERERExERERASCyAEDgkGDAgQEBAQEAUGCyAEDgMJDwcJCyAEDgkECgkODg4ODgMECyAEDgYBDQ0KDQsBCyAEDgMGDAMGC0EALwGIQEH+/wNGDQMMBAsCQAJAIAIvAQQiAkEqRg0AIAJBL0cNARAVDA8LEBYMDgsCQAJAAkACQEEAKAKMQCIALwEAIgIQF0UNACACQVVqIgNBA0sNAgJAAkACQCADDgQBBQIAAQsgAEF+ai8BAEFQakH//wNxQQpJDQMMBAsgAEF+ai8BAEErRg0CDAMLIABBfmovAQBBLUYNAQwCCwJAAkAgAkH9AEYNACACQS9GDQEgAkEpRw0CQQAoArCgASADQQJ0aigCABAYRQ0CDAMLQQAoArCgASADQQJ0aigCABAZDQIgA0HQoAFqLQAARQ0BDAILQQAtAJBADQELIAAQGiEDIAJFDQBBASECIANFDQELEBtBACECC0EAIAI6AJBADAoLIAEQHAwJC0EAIANBf2oiADsBhkACQCADQQAvAYhAIgJHDQBBAEEALwGEQEF/aiICOwGEQEEAQQAoAqBgIAJB//8DcUEBdGovAQA7AYhADAILIAJB//8DRg0IIABB//8DcSACTw0ICxAdQQAhAgwMCxAeDAYLIANB0KABakEALQC4oAE6AABBACADQQFqOwGGQEEAKAKwoAEgA0ECdGpBACgCjEA2AgBBAEEAOgC4oAEMBQtBACADQX9qOwGGQAwEC0EAIANBAWo7AYZAQQAoArCgASADQQJ0akEAKAKMQDYCAAwDCyAAEBFFDQIgAi8BBEHsAEcNAiACLwEGQeEARw0CIAIvAQhB8wBHDQIgAi8BCkHzAEcNAgJAAkAgAi8BDCIDQXdqIgJBF0sNAEEBIAJ0QZ+AgARxDQELIANBoAFHDQMLQQBBAToAuKABDAILIAJBBGpB+ABB8ABB7wBB8gBB9AAQE0UNASAAEBFFDQECQCACLwEOQfMARw0AQQAQHwwCCyADDQEQIAwBCyACQQRqQe8AQeQAQfUAQewAQeUAEBNFDQAgABARRQ0AECELQQBBACgCvKABNgKMQAwCCwJAAkAgAkEEaiIDQekAQe4AQfQAQeUAQfIAQe8AQfAAQdIAQeUAQfEAQfUAQekAQfIAQeUAQdcAQekAQewAQeQAQeMAQeEAQfIAQeQAECJFDQACQCAAEBENACACLwEAQS5HDQELQQAgAkEwajYCvKABIAIvATBBKEcNAUEAIAJBMmo2ArygAUEAQQE7AYZAQQAoArCgAUEAKAKMQDYCAEEAEBBFDQEgABARRQ0BIAIQEgwBCyADQd8AQeUAQfgAQfAAQe8AQfIAQfQAECNFDQACQCAAEBENACACLwEAQS5HDQELQQAgAkESajYCvKABAkAgAi8BEiIDQdMARw0AIAIvARRB9ABHDQEgAi8BFkHhAEcNASACLwEYQfIARw0BQQAgAkEaajYCvKABIAIvARohAwsgA0H//wNxQShHDQBBACgCsKABQQAoAoxANgIAQQBBATsBhkBBAEEAKAK8oAEiAkECajYCvKABIAIvAQJB8gBHDQBBAhAQGgtBAEEAKAK8oAE2AoxADAELAkAgAkEEakHtAEHwAEHvAEHyAEH0ABATRQ0AIAAQEUUNABAkQQAoArygASEAC0EAIAA2AoxAC0EAKALAoAEhA0EAKAK8oAEhAgwACwsgAgv3AQEEf0EAIQECQEEAKAK8oAEiAkECakHlAEHxAEH1AEHpAEHyAEHlABAmRQ0AQQAhAUEAIAJBDmo2ArygAQJAECdBKEcNAEEAQQAoArygAUECajYCvKABECchA0EAKAK8oAEhBAJAIANBJ0YNACADQSJHDQELIAMQHEEAQQAoArygAUECaiIDNgK8oAEQJ0EpRw0AAkAgAEF/aiIBQQFLDQACQAJAIAEOAgEAAQsgBCADQQAoAqAfEQAAQQEPCyAEIANBACgCoB8RAABBAQ8LQQAoArSgASAENgIAQQAoArSgASADNgIEQQEPC0EAIAI2ArygAQsgAQsdAAJAQQAoApgfIABHDQBBAQ8LIABBfmovAQAQJQv+AgEEf0EAKAKYHyEBAkADQCAAQX5qIQIgAC8BACIDQSBHDQEgACABSyEEIAIhACAEDQALCwJAIANBPUcNAAJAA0AgAkF+aiEAIAIvAQBBIEcNASACIAFLIQQgACECIAQNAAsLIABBAmohAiAAQQRqIQNBACEEAkADQCACECghACACIAFNDQEgAEUNASAAQdwARg0CIAAQKUUNASACQX5BfCAAQYCABEkbaiECIAAQKiEEDAALCyAEQQFxRQ0AIAIvAQBBIEcNAEEAKAK0oAEiBEEAKAKwH0YNACAEIAM2AgwgBCACQQJqNgIIIAJBfmohAEEgIQICQANAIABBAmogAU0NASACQf//A3FBIEcNASAALwEAIQIgAEF+aiEADAALCyACQf//A3FBjn9qIgJBAksNAAJAAkACQCACDgMAAwEACyAAQfYAQeEAECsNAQwCCyAAQewAQeUAECsNACAAQeMAQe8AQe4AQfMAECxFDQELQQAgBEEQajYCtKABCws/AQF/QQAhBgJAIAAvAQAgAUcNACAALwECIAJHDQAgAC8BBCADRw0AIAAvAQYgBEcNACAALwEIIAVGIQYLIAYLpCYBCH9BAEEAKAK8oAEiAUEMajYCvKABIAFBCmohAQJAECdBLkcNAEEAQQAoArygAUECajYCvKABAkACQBAnIgJB5ABHDQBBACgCvKABIgBBAmpB5QBB5gBB6QBB7gBB5QBB0ABB8gBB7wBB8ABB5QBB8gBB9ABB+QAQL0UNAkEAIABBHGo2ArygASAAQRpqIQEQJ0EoRw0CQQBBACgCvKABQQJqNgK8oAEQJxAwRQ0CECdBLEcNAkEAQQAoArygAUECajYCvKABAkAQJyIAQSdGDQAgAEEiRw0DC0EAKAK8oAEhAiAAEBxBAEEAKAK8oAFBAmoiADYCvKABECdBLEcNAUEAQQAoArygAUECajYCvKABECdB+wBHDQFBAEEAKAK8oAFBAmo2ArygAQJAECciA0HlAEcNAEEAKAK8oAEiA0ECakHuAEH1AEHtAEHlAEHyAEHhAEHiAEHsAEHlABAxRQ0CQQAgA0EUajYCvKABECdBOkcNAkEAQQAoArygAUECajYCvKABECdB9ABHDQJBACgCvKABIgMvAQJB8gBHDQIgAy8BBEH1AEcNAiADLwEGQeUARw0CQQAgA0EIajYCvKABECdBLEcNAkEAQQAoArygAUECajYCvKABECchAwsCQCADQecARg0AIANB9gBHDQJBACgCvKABIgMvAQJB4QBHDQIgAy8BBEHsAEcNAiADLwEGQfUARw0CIAMvAQhB5QBHDQJBACADQQpqNgK8oAEQJ0E6Rw0CIAIgAEEAKAKcHxEAAEEAIAE2ArygAQ8LQQAoArygASIDLwECQeUARw0BIAMvAQRB9ABHDQFBACADQQZqNgK8oAECQBAnIgNBOkcNAEEAQQAoArygAUECajYCvKABECdB5gBHDQJBACgCvKABIgNBAmpB9QBB7gBB4wBB9ABB6QBB7wBB7gAQI0UNAkEAIANBEGoiAzYCvKABAkAQJyIEQShGDQAgA0EAKAK8oAFGDQMgBBAtRQ0DCxAnIQMLIANBKEcNAUEAQQAoArygAUECajYCvKABECdBKUcNAUEAQQAoArygAUECajYCvKABECdB+wBHDQFBAEEAKAK8oAFBAmo2ArygARAnQfIARw0BQQAoArygASIDQQJqQeUAQfQAQfUAQfIAQe4AEBNFDQFBACADQQxqNgK8oAEQJxAtRQ0BAkACQAJAECciA0HbAEYNACADQS5HDQJBAEEAKAK8oAFBAmo2ArygARAnEC0NAQwEC0EAQQAoArygAUECajYCvKABAkAQJyIDQSdGDQAgA0EiRw0ECyADEBxBAEEAKAK8oAFBAmo2ArygARAnQd0ARw0DQQBBACgCvKABQQJqNgK8oAELECchAwsCQCADQTtHDQBBAEEAKAK8oAFBAmo2ArygARAnIQMLIANB/QBHDQFBAEEAKAK8oAFBAmo2ArygAQJAECciA0EsRw0AQQBBACgCvKABQQJqNgK8oAEQJyEDCyADQf0ARw0BQQBBACgCvKABQQJqNgK8oAEQJ0EpRw0BIAIgAEEAKAKcHxEAAA8LIAJB6wBHDQEgAEUNAUEAKAK8oAEiAC8BAkHlAEcNASAALwEEQfkARw0BIAAvAQZB8wBHDQEgAEEGaiEBQQAgAEEIajYCvKABECdBKEcNAUEAQQAoArygAUECajYCvKABECchAEEAKAK8oAEhAiAAEC1FDQFBACgCvKABIQAQJ0EpRw0BQQBBACgCvKABIgFBAmo2ArygARAnQS5HDQFBAEEAKAK8oAFBAmo2ArygARAnQeYARw0BQQAoArygASIDQQJqQe8AQfIAQcUAQeEAQeMAQegAECZFDQFBACADQQ5qNgK8oAEQJyEDQQAoArygASIEQX5qIQEgA0EoRw0BQQAgBEECajYCvKABECdB5gBHDQFBACgCvKABIgNBAmpB9QBB7gBB4wBB9ABB6QBB7wBB7gAQI0UNAUEAIANBEGo2ArygARAnQShHDQFBAEEAKAK8oAFBAmo2ArygARAnIQNBACgCvKABIQQgAxAtRQ0BQQAoArygASEDECdBKUcNAUEAQQAoArygAUECajYCvKABECdB+wBHDQFBAEEAKAK8oAFBAmo2ArygARAnQekARw0BQQAoArygASIFLwECQeYARw0BQQAgBUEEajYCvKABECdBKEcNAUEAQQAoArygAUECajYCvKABECcaQQAoArygASIFIAQgAyAEayIDEEENASAAIAJrIgZBAXUhB0EAIAUgA0EBdSIIQQF0ajYCvKABAkACQAJAECciAEEhRg0AIABBPUcNBEEAKAK8oAEiAC8BAkE9Rw0EIAAvAQRBPUcNBEEAIABBBmo2ArygAQJAECciAEEnRg0AIABBIkcNBQtBACgCvKABIgVBAmpB5ABB5QBB5gBB4QBB9QBB7ABB9AAQI0UNBEEAIAVBEGo2ArygARAnIABHDQRBAEEAKAK8oAFBAmo2ArygARAnQfwARw0EQQAoArygASIALwECQfwARw0EQQAgAEEEajYCvKABECcaQQAoArygASIAIAQgAxBBDQRBACAAIAhBAXRqNgK8oAEQJ0E9Rw0EQQAoArygASIALwECQT1HDQQgAC8BBEE9Rw0EQQAgAEEGajYCvKABAkAQJyIAQSdGDQAgAEEiRw0FC0EAKAK8oAEiBUECakHfAEHfAEHlAEHzAEHNAEHvAEHkAEH1AEHsAEHlABAyRQ0EQQAgBUEWajYCvKABECcgAEcNBEEAQQAoArygAUECajYCvKABECdBKUcNBEEAQQAoArygAUECajYCvKABECdB8gBHDQRBACgCvKABIgBBAmpB5QBB9ABB9QBB8gBB7gAQE0UNBEEAIABBDGo2ArygAQJAECdBO0cNAEEAQQAoArygAUECajYCvKABCxAnIgBB6QBHDQJB6QAhAEEAKAK8oAEiBS8BAkHmAEcNAkEAIAVBBGo2ArygARAnQShHDQRBAEEAKAK8oAFBAmoiADYCvKABAkAgBCAIEDNFDQAQJ0EpRw0FQQBBACgCvKABQQJqNgK8oAEQJ0HyAEcNBUEAKAK8oAEiAEECakHlAEH0AEH1AEHyAEHuABATRQ0FQQAgAEEMajYCvKABAkAQJ0E7Rw0AQQBBACgCvKABQQJqNgK8oAELECciAEHpAEcNA0HpACEAQQAoArygASIFLwECQeYARw0DQQAgBUEEajYCvKABECdBKEcNBUEAKAK8oAFBAmohAAtBACAANgK8oAEgACAEIAMQQQ0EQQAgACAIQQF0ajYCvKABECdB6QBHDQRBACgCvKABIgAvAQJB7gBHDQQgAC8BBEEgRw0EQQAgAEEGajYCvKABECcQMEUNBBAnQSZHDQRBACgCvKABIgAvAQJBJkcNBEEAIABBBGo2ArygARAnEDBFDQQQJ0HbAEcNBEEAQQAoArygAUECajYCvKABECcaQQAoArygASIAIAQgAxBBDQRBACAAIAhBAXRqNgK8oAEQJ0HdAEcNBEEAQQAoArygAUECajYCvKABECdBPUcNBEEAKAK8oAEiAC8BAkE9Rw0EIAAvAQRBPUcNBEEAIABBBmo2ArygARAnGkEAKAK8oAEiACACIAYQQQ0EQQAgACAHQQF0ajYCvKABECdB2wBHDQRBAEEAKAK8oAFBAmo2ArygARAnGkEAKAK8oAEiACAEIAMQQQ0EQQAgACAIQQF0ajYCvKABECdB3QBHDQRBAEEAKAK8oAFBAmo2ArygARAnQSlHDQRBAEEAKAK8oAFBAmo2ArygARAnQfIARw0EQQAoArygASIAQQJqQeUAQfQAQfUAQfIAQe4AEBNFDQRBACAAQQxqNgK8oAEQJ0E7Rw0BQQBBACgCvKABQQJqNgK8oAEMAQtBACgCvKABIgAvAQJBPUcNAyAALwEEQT1HDQNBACAAQQZqNgK8oAECQBAnIgBBJ0YNACAAQSJHDQQLQQAoArygASIFQQJqQeQAQeUAQeYAQeEAQfUAQewAQfQAECNFDQNBACAFQRBqNgK8oAEQJyAARw0DQQBBACgCvKABQQJqNgK8oAECQBAnIgBBJkcNAEEAKAK8oAEiAC8BAkEmRw0EQQAgAEEEajYCvKABECdBIUcNBEEAQQAoArygAUECajYCvKABAkACQBAnIgBBzwBHDQBBACgCvKABQQJqQeIAQeoAQeUAQeMAQfQAQS4QJkUNACAEIAgQM0UNBgwBCyAAEC1FDQAQJ0EuRw0FQQBBACgCvKABQQJqNgK8oAEQJ0HoAEcNBUEAKAK8oAEiAEECakHhAEHzAEHPAEH3AEHuAEHQAEHyAEHvAEHwAEHlAEHyAEH0AEH5ABAvRQ0FQQAgAEEcajYCvKABECdBKEcNBUEAQQAoArygAUECajYCvKABECcaQQAoArygASIAIAQgAxBBDQVBACAAIAhBAXRqNgK8oAEQJ0EpRw0FQQBBACgCvKABQQJqNgK8oAELECchAAsgAEEpRw0DQQBBACgCvKABQQJqNgK8oAELECchAAsCQAJAAkAgABAwRQ0AECdB2wBHDQRBAEEAKAK8oAFBAmo2ArygARAnGkEAKAK8oAEiACAEIAMQQQ0EQQAgACAIQQF0ajYCvKABECdB3QBHDQRBAEEAKAK8oAFBAmo2ArygARAnQT1HDQRBAEEAKAK8oAFBAmo2ArygARAnGkEAKAK8oAEiACACIAYQQQ0EQQAgACAHQQF0ajYCvKABECdB2wBHDQRBAEEAKAK8oAFBAmo2ArygARAnGkEAKAK8oAEiACAEIAMQQQ0EQQAgACAIQQF0ajYCvKABECdB3QBHDQRBAEEAKAK8oAFBAmo2ArygARAnIgBBO0cNAkEAQQAoArygAUECajYCvKABDAELIABBzwBHDQNBACgCvKABIgBBAmpB4gBB6gBB5QBB4wBB9AAQE0UNA0EAIABBDGo2ArygARAnQS5HDQNBAEEAKAK8oAFBAmo2ArygARAnQeQARw0DQQAoArygASIAQQJqQeUAQeYAQekAQe4AQeUAQdAAQfIAQe8AQfAAQeUAQfIAQfQAQfkAEC9FDQNBACAAQRxqNgK8oAEQJ0EoRw0DQQBBACgCvKABQQJqNgK8oAEQJxAwRQ0DECdBLEcNA0EAQQAoArygAUECajYCvKABECcaQQAoArygASIAIAQgAxBBDQNBACAAIAhBAXRqNgK8oAEQJ0EsRw0DQQBBACgCvKABQQJqNgK8oAEQJ0H7AEcNA0EAQQAoArygAUECajYCvKABECdB5QBHDQNBACgCvKABIgBBAmpB7gBB9QBB7QBB5QBB8gBB4QBB4gBB7ABB5QAQMUUNA0EAIABBFGo2ArygARAnQTpHDQNBAEEAKAK8oAFBAmo2ArygARAnIQVBACgCvKABIQACQCAFQfQARg0AIAAvAQJB8gBHDQQgAC8BBEH1AEcNBCAALwEGQeUARw0EC0EAIABBCGo2ArygARAnQSxHDQNBAEEAKAK8oAFBAmo2ArygARAnQecARw0DQQAoArygASIALwECQeUARw0DIAAvAQRB9ABHDQNBACAAQQZqNgK8oAECQBAnIgBBOkcNAEEAQQAoArygAUECajYCvKABECdB5gBHDQRBACgCvKABIgBBAmpB9QBB7gBB4wBB9ABB6QBB7wBB7gAQI0UNBEEAIABBEGoiADYCvKABAkAQJyIFQShGDQAgAEEAKAK8oAFGDQUgBRAtRQ0FCxAnIQALIABBKEcNA0EAQQAoArygAUECajYCvKABECdBKUcNA0EAQQAoArygAUECajYCvKABECdB+wBHDQNBAEEAKAK8oAFBAmo2ArygARAnQfIARw0DQQAoArygASIAQQJqQeUAQfQAQfUAQfIAQe4AEBNFDQNBACAAQQxqNgK8oAEQJxpBACgCvKABIgAgAiAGEEENA0EAIAAgB0EBdGo2ArygARAnQdsARw0DQQBBACgCvKABQQJqNgK8oAEQJxpBACgCvKABIgAgBCADEEENA0EAIAAgCEEBdGo2ArygARAnQd0ARw0DQQBBACgCvKABQQJqNgK8oAECQBAnIgBBO0cNAEEAQQAoArygAUECajYCvKABECchAAsgAEH9AEcNA0EAQQAoArygAUECajYCvKABAkAQJyIAQSxHDQBBAEEAKAK8oAFBAmo2ArygARAnIQALIABB/QBHDQNBAEEAKAK8oAFBAmo2ArygARAnQSlHDQNBAEEAKAK8oAFBAmo2ArygARAnIgBBO0cNAUEAQQAoArygAUECajYCvKABCxAnIQALIABB/QBHDQFBAEEAKAK8oAFBAmo2ArygARAnQSlHDQFBACgCtKABIQRBgCAhAANAAkACQCAEIABGDQAgByAAQQxqKAIAIABBCGooAgAiA2tBAXVHDQEgAiADIAYQQQ0BIAAoAgAgAEEEaigCAEEAKAKgHxEAAEEAIAE2ArygAQsPCyAAQRBqIQAMAAsLIAIgAEEAKAKkHxEAAAtBACABNgK8oAELUwEEf0EAKAK8oAFBAmohAEEAKALAoAEhAQJAA0AgACICQX5qIAFPDQEgAkECaiEAIAIvAQBBdmoiA0EDSw0AIAMOBAEAAAEBCwtBACACNgK8oAELfAECf0EAQQAoArygASIAQQJqNgK8oAEgAEEGaiEAQQAoAsCgASEBA0ACQAJAAkAgAEF8aiABTw0AIABBfmovAQBBKkcNAiAALwEAQS9HDQJBACAAQX5qNgK8oAEMAQsgAEF+aiEAC0EAIAA2ArygAQ8LIABBAmohAAwACwt1AQF/AkACQCAAQV9qIgFBBUsNAEEBIAF0QTFxDQELIABBRmpB//8DcUEGSQ0AIABBWGpB//8DcUEHSSAAQSlHcQ0AAkAgAEGlf2oiAUEDSw0AIAEOBAEAAAEBCyAAQf0ARyAAQYV/akH//wNxQQRJcQ8LQQELPQEBf0EBIQECQCAAQfcAQegAQekAQewAQeUAEDQNACAAQeYAQe8AQfIAEDUNACAAQekAQeYAECshAQsgAQutAQEDf0EBIQECQAJAAkACQAJAAkACQCAALwEAIgJBRWoiA0EDTQ0AIAJBm39qIgNBA00NASACQSlGDQMgAkH5AEcNAiAAQX5qQeYAQekAQe4AQeEAQewAQewAEDYPCyADDgQCAQEFAgsgAw4EAgAAAwILQQAhAQsgAQ8LIABBfmpB5QBB7ABB8wAQNQ8LIABBfmpB4wBB4QBB9ABB4wAQLA8LIABBfmovAQBBPUYL7QMBAn9BACEBAkAgAC8BAEGcf2oiAkETSw0AAkACQAJAAkACQAJAAkACQCACDhQAAQIICAgICAgIAwQICAUIBggIBwALIABBfmovAQBBl39qIgJBA0sNBwJAAkAgAg4EAAkJAQALIABBfGpB9gBB7wAQKw8LIABBfGpB+QBB6QBB5QAQNQ8LIABBfmovAQBBjX9qIgJBAUsNBgJAAkAgAg4CAAEACwJAIABBfGovAQAiAkHhAEYNACACQewARw0IIABBempB5QAQNw8LIABBempB4wAQNw8LIABBfGpB5ABB5QBB7ABB5QAQLA8LIABBfmovAQBB7wBHDQUgAEF8ai8BAEHlAEcNBQJAIABBemovAQAiAkHwAEYNACACQeMARw0GIABBeGpB6QBB7gBB8wBB9ABB4QBB7gAQNg8LIABBeGpB9ABB+QAQKw8LQQEhASAAQX5qIgBB6QAQNw0EIABB8gBB5QBB9ABB9QBB8gAQNA8LIABBfmpB5AAQNw8LIABBfmpB5ABB5QBB4gBB9QBB5wBB5wBB5QAQOA8LIABBfmpB4QBB9wBB4QBB6QAQLA8LAkAgAEF+ai8BACICQe8ARg0AIAJB5QBHDQEgAEF8akHuABA3DwsgAEF8akH0AEHoAEHyABA1IQELIAELhwEBA38DQEEAQQAoArygASIAQQJqIgE2ArygAQJAAkACQCAAQQAoAsCgAU8NACABLwEAIgFBpX9qIgJBAU0NAgJAIAFBdmoiAEEDTQ0AIAFBL0cNBAwCCyAADgQAAwMAAAsQHQsPCwJAAkAgAg4CAQABC0EAIABBBGo2ArygAQwBCxBAGgwACwuVAQEEf0EAKAK8oAEhAUEAKALAoAEhAgJAAkADQCABIgNBAmohASADIAJPDQEgAS8BACIEIABGDQICQCAEQdwARg0AIARBdmoiA0EDSw0BIAMOBAIBAQICCyADQQRqIQEgAy8BBEENRw0AIANBBmogASADLwEGQQpGGyEBDAALC0EAIAE2ArygARAdDwtBACABNgK8oAELOAEBf0EAQQE6APAfQQAoArygASEAQQBBACgCwKABQQJqNgK8oAFBACAAQQAoApgfa0EBdTYC7B8LzgEBBX9BACgCvKABIQBBACgCwKABIQEDQCAAIgJBAmohAAJAAkAgAiABTw0AIAAvAQAiA0Gkf2oiBEEETQ0BIANBJEcNAiACLwEEQfsARw0CQQBBAC8BhEAiAEEBajsBhEBBACgCoGAgAEEBdGpBAC8BiEA7AQBBACACQQRqNgK8oAFBAEEALwGGQEEBaiIAOwGIQEEAIAA7AYZADwtBACAANgK8oAEQHQ8LAkACQCAEDgUBAgICAAELQQAgADYCvKABDwsgAkEEaiEADAALC7YCAQJ/QQBBACgCvKABIgFBDmo2ArygAQJAAkACQBAnIgJB2wBGDQAgAkE9Rg0BIAJBLkcNAkEAQQAoArygAUECajYCvKABECchAkEAKAK8oAEhACACEC1FDQJBACgCvKABIQIQJ0E9Rw0CIAAgAkEAKAKcHxEAAA8LQQBBACgCvKABQQJqNgK8oAECQBAnIgJBJ0YNACACQSJHDQILQQAoArygASEAIAIQHEEAQQAoArygAUECaiICNgK8oAEQJ0HdAEcNAUEAQQAoArygAUECajYCvKABECdBPUcNASAAIAJBACgCnB8RAAAMAQsgAEUNAEEAKAKoHxEBAEEAQQAoArygAUECajYCvKABAkAQJyICQfIARg0AIAJB+wBHDQEQLg8LQQEQEBoLQQAgAUEMajYCvKABCzYBAn9BAEEAKAK8oAFBDGoiADYCvKABECchAQJAAkBBACgCvKABIABHDQAgARA/RQ0BCxAdCwtsAQF/QQBBACgCvKABIgBBDGo2ArygAQJAECdBLkcNAEEAQQAoArygAUECajYCvKABECdB5QBHDQBBACgCvKABQQJqQfgAQfAAQe8AQfIAQfQAQfMAECZFDQBBARAfDwtBACAAQQpqNgK8oAEL6QEBAX9BACEXAkAgAC8BACABRw0AIAAvAQIgAkcNACAALwEEIANHDQAgAC8BBiAERw0AIAAvAQggBUcNACAALwEKIAZHDQAgAC8BDCAHRw0AIAAvAQ4gCEcNACAALwEQIAlHDQAgAC8BEiAKRw0AIAAvARQgC0cNACAALwEWIAxHDQAgAC8BGCANRw0AIAAvARogDkcNACAALwEcIA9HDQAgAC8BHiAQRw0AIAAvASAgEUcNACAALwEiIBJHDQAgAC8BJCATRw0AIAAvASYgFEcNACAALwEoIBVHDQAgAC8BKiAWRiEXCyAXC1MBAX9BACEIAkAgAC8BACABRw0AIAAvAQIgAkcNACAALwEEIANHDQAgAC8BBiAERw0AIAAvAQggBUcNACAALwEKIAZHDQAgAC8BDCAHRiEICyAIC6QBAQR/QQBBACgCvKABIgBBDGoiATYCvKABAkACQAJAAkACQBAnIgJBWWoiA0EHTQ0AIAJBIkYNAiACQfsARg0CDAELAkAgAw4IAgABAgEBAQMCC0EAQQAvAYZAIgNBAWo7AYZAQQAoArCgASADQQJ0aiAANgIADwtBACgCvKABIAFGDQILQQAvAYZARQ0AQQBBACgCvKABQX5qNgK8oAEPCxAdCws0AQF/QQEhAQJAIABBd2pB//8DcUEFSQ0AIABBgAFyQaABRg0AIABBLkcgABA/cSEBCyABC0kBAX9BACEHAkAgAC8BACABRw0AIAAvAQIgAkcNACAALwEEIANHDQAgAC8BBiAERw0AIAAvAQggBUcNACAALwEKIAZGIQcLIAcLegEDf0EAKAK8oAEhAAJAA0ACQCAALwEAIgFBd2pBBUkNACABQSBGDQAgAUGgAUYNACABQS9HDQICQCAALwECIgBBKkYNACAAQS9HDQMQFQwBCxAWC0EAQQAoArygASICQQJqIgA2ArygASACQQAoAsCgAUkNAAsLIAELOQEBfwJAIAAvAQAiAUGA+ANxQYC4A0cNACAAQX5qLwEAQf8HcUEKdCABQf8HcXJBgIAEaiEBCyABC30BAX8CQCAAQS9LDQAgAEEkRg8LAkAgAEE6SQ0AQQAhAQJAIABBwQBJDQAgAEHbAEkNAQJAIABB4ABLDQAgAEHfAEYPCyAAQfsASQ0BAkAgAEH//wNLDQAgAEGqAUkNASAAEDkPC0EBIQEgABA6DQAgABA7IQELIAEPC0EBC2MBAX8CQCAAQcAASw0AIABBJEYPC0EBIQECQCAAQdsASQ0AAkAgAEHgAEsNACAAQd8ARg8LIABB+wBJDQACQCAAQf//A0sNAEEAIQEgAEGqAUkNASAAEDwPCyAAEDohAQsgAQtMAQN/QQAhAwJAIABBfmoiBEEAKAKYHyIFSQ0AIAQvAQAgAUcNACAALwEAIAJHDQACQCAEIAVHDQBBAQ8LIABBfGovAQAQJSEDCyADC2YBA39BACEFAkAgAEF6aiIGQQAoApgfIgdJDQAgBi8BACABRw0AIABBfGovAQAgAkcNACAAQX5qLwEAIANHDQAgAC8BACAERw0AAkAgBiAHRw0AQQEPCyAAQXhqLwEAECUhBQsgBQuFAQECfyAAED4iABAqIQECQAJAIABB3ABGDQBBACECIAFFDQELQQAoArygAUECQQQgAEGAgARJG2ohAAJAA0BBACAANgK8oAEgAC8BABA+IgFFDQECQCABEClFDQAgAEECQQQgAUGAgARJG2ohAAwBCwtBACECIAFB3ABGDQELQQEhAgsgAgvaAwEEf0EAKAK8oAEiAEF+aiEBA0BBACAAQQJqNgK8oAECQAJAAkAgAEEAKALAoAFPDQAQJyEAQQAoArygASECAkACQCAAEC1FDQBBACgCvKABIQMCQAJAECciAEE6Rw0AQQBBACgCvKABQQJqNgK8oAEQJxAtRQ0BQQAoArygAS8BACEACyACIANBACgCnB8RAAAMAgtBACABNgK8oAEPCwJAAkAgAEEiRg0AIABBLkYNASAAQSdHDQQLQQAoArygASECIAAQHEEAQQAoArygAUECaiIDNgK8oAEQJyIAQTpHDQFBAEEAKAK8oAFBAmo2ArygAQJAECcQLUUNAEEAKAK8oAEvAQAhACACIANBACgCnB8RAAAMAgtBACABNgK8oAEPC0EAKAK8oAEiAC8BAkEuRw0CIAAvAQRBLkcNAkEAIABBBmo2ArygAQJAAkACQCAALwEGIgBB8gBHDQBBARAQIQBBACgCvKABIQIgAA0BIAIvAQAhAAsgAEH//wNxEC0NAUEAIAE2ArygAQ8LQQAgAkECajYCvKABCxAnIQALIABB//8DcSIAQSxGDQIgAEH9AEYNAEEAIAE2ArygAQsPC0EAIAE2ArygAQ8LQQAoArygASEADAALC48BAQF/QQAhDgJAIAAvAQAgAUcNACAALwECIAJHDQAgAC8BBCADRw0AIAAvAQYgBEcNACAALwEIIAVHDQAgAC8BCiAGRw0AIAAvAQwgB0cNACAALwEOIAhHDQAgAC8BECAJRw0AIAAvARIgCkcNACAALwEUIAtHDQAgAC8BFiAMRw0AIAAvARggDUYhDgsgDguoAQECf0EAIQFBACgCvKABIQICQAJAIABB7QBHDQAgAkECakHvAEHkAEH1AEHsAEHlABATRQ0BQQAgAkEMajYCvKABAkAQJ0EuRg0AQQAhAQwCC0EAQQAoArygAUECajYCvKABECchAAsgAEHlAEcNAEEAKAK8oAEiAEEOaiACIABBAmpB+ABB8ABB7wBB8gBB9ABB8wAQJiIBGyECC0EAIAI2ArygASABC2cBAX9BACEKAkAgAC8BACABRw0AIAAvAQIgAkcNACAALwEEIANHDQAgAC8BBiAERw0AIAAvAQggBUcNACAALwEKIAZHDQAgAC8BDCAHRw0AIAAvAQ4gCEcNACAALwEQIAlGIQoLIAoLcQEBf0EAIQsCQCAALwEAIAFHDQAgAC8BAiACRw0AIAAvAQQgA0cNACAALwEGIARHDQAgAC8BCCAFRw0AIAAvAQogBkcNACAALwEMIAdHDQAgAC8BDiAIRw0AIAAvARAgCUcNACAALwESIApGIQsLIAsLgwQBAn9BACECAkAQJ0HPAEcNAEEAIQJBACgCvKABIgNBAmpB4gBB6gBB5QBB4wBB9AAQE0UNAEEAIQJBACADQQxqNgK8oAEQJ0EuRw0AQQBBACgCvKABQQJqNgK8oAECQBAnIgNB8ABHDQBBACECQQAoArygASIDQQJqQfIAQe8AQfQAQe8AQfQAQfkAQfAAQeUAED1FDQFBACECQQAgA0ESajYCvKABECdBLkcNAUEAQQAoArygAUECajYCvKABECchAwtBACECIANB6ABHDQBBACECQQAoArygASIDQQJqQeEAQfMAQc8AQfcAQe4AQdAAQfIAQe8AQfAAQeUAQfIAQfQAQfkAEC9FDQBBACECQQAgA0EcajYCvKABECdBLkcNAEEAIQJBAEEAKAK8oAFBAmo2ArygARAnQeMARw0AQQAhAkEAKAK8oAEiAy8BAkHhAEcNACADLwEEQewARw0AIAMvAQZB7ABHDQBBACECQQAgA0EIajYCvKABECdBKEcNAEEAIQJBAEEAKAK8oAFBAmo2ArygARAnEC1FDQAQJ0EsRw0AQQAhAkEAQQAoArygAUECajYCvKABECcaQQAoArygASIDIAAgAUEBdCIBEEENAEEAIQJBACADIAFqNgK8oAEQJ0EpRw0AQQBBACgCvKABQQJqNgK8oAFBASECCyACC0kBA39BACEGAkAgAEF4aiIHQQAoApgfIghJDQAgByABIAIgAyAEIAUQE0UNAAJAIAcgCEcNAEEBDwsgAEF2ai8BABAlIQYLIAYLWQEDf0EAIQQCQCAAQXxqIgVBACgCmB8iBkkNACAFLwEAIAFHDQAgAEF+ai8BACACRw0AIAAvAQAgA0cNAAJAIAUgBkcNAEEBDwsgAEF6ai8BABAlIQQLIAQLSwEDf0EAIQcCQCAAQXZqIghBACgCmB8iCUkNACAIIAEgAiADIAQgBSAGECZFDQACQCAIIAlHDQBBAQ8LIABBdGovAQAQJSEHCyAHCz0BAn9BACECAkBBACgCmB8iAyAASw0AIAAvAQAgAUcNAAJAIAMgAEcNAEEBDwsgAEF+ai8BABAlIQILIAILTQEDf0EAIQgCQCAAQXRqIglBACgCmB8iCkkNACAJIAEgAiADIAQgBSAGIAcQI0UNAAJAIAkgCkcNAEEBDwsgAEFyai8BABAlIQgLIAgL+RIBA38CQCAAEDwNACAAQfS/f2pBAkkNACAAQbcBRg0AIABBgHpqQfAASQ0AIABB/XZqQQVJDQAgAEGHB0YNACAAQe90akEtSQ0AAkAgAEHBdGoiAUEISw0AQQEgAXRB7QJxDQELIABB8HNqQQtJDQAgAEG1c2pBH0kNAAJAIABBqnJqIgFBEksNAEEBIAF0Qf/8GXENAQsgAEHwDEYNACAAQZZyakEESQ0AIABBwHBqQQpJDQAgAEHacGpBC0kNACAAQdBxakEbSQ0AIABBkQ5GDQAgAEGQcmpBCkkNACAAQcJtakESSQ0AIABBxm1qQQNJDQAgAEGdbmpBIUkNACAAQa1uakEPSQ0AIABBp29qQQNJDQAgAEHXb2pBBUkNACAAQdtvakEDSQ0AIABB5W9qQQlJDQAgAEHqb2pBBEkNACAAQf0PRg0AIABBlXBqQQlJDQACQCAAQa9taiIBQRJLDQBBASABdEH/gBhxDQELIABBmm1qQQpJDQACQAJAIABBxGxqIgFBJ00NACAAQf9sakEDSQ0CDAELIAEOKAEAAQEBAQEBAQAAAQEAAAEBAQAAAAAAAAAAAAEAAAAAAAAAAAAAAQEBCyAAQf4TRg0AIABBmmxqQQpJDQACQCAAQcRraiIBQRVLDQBBASABdEH9sI4BcQ0BCyAAQf9rakEDSQ0AIABB9RRGDQAgAEGaa2pBDEkNAAJAAkAgAEHEamoiAUEnTQ0AIABB/2pqQQNJDQIMAQsgAQ4oAQABAQEBAQEBAQABAQEAAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAABAQELIABBmmpqQQpJDQAgAEGGampBBkkNAAJAAkAgAEHEaWoiAUEnTQ0AIABB/2lqQQNJDQIMAQsgAQ4oAQABAQEBAQEBAAABAQAAAQEBAAAAAAAAAAABAQAAAAAAAAAAAAABAQELIABBmmlqQQpJDQACQCAAQcJoaiIBQRlLDQBBASABdEGf7oMQcQ0BCyAAQYIXRg0AIABBmmhqQQpJDQACQAJAIABBwmdqIgFBJU0NACAAQYBoakEFSQ0CDAELIAEOJgEBAQEBAQEAAQEBAAEBAQEAAAAAAAAAAQEAAAAAAAAAAAAAAAEBAQsgAEGaZ2pBCkkNAAJAAkAgAEHEZmoiAUEnTQ0AIABB/2ZqQQNJDQIMAQsgAQ4oAQABAQEBAQEBAAEBAQABAQEBAAAAAAAAAAEBAAAAAAAAAAAAAAABAQELIABBmmZqQQpJDQAgAEF8cSICQYAaRg0AAkAgAEHFZWoiAUEoSw0AIAEOKQEBAAEBAQEBAQEAAQEBAAEBAQEAAAAAAAAAAAABAAAAAAAAAAAAAAEBAQsgAEGaZWpBCkkNAAJAIABBtmRqIgFBDEsNAEEBIAF0QeEvcQ0BCyAAQf5kakECSQ0AIABBeHFB2BtGDQAgAEGaZGpBCkkNAAJAIABBz2NqIgFBHUsNAEEBIAF0QfmHgP4DcQ0BCyAAQY5kakECSQ0AIABBsR1GDQAgAEGwY2pBCkkNAAJAIABBzGJqIgFBCEsNACABQQZHDQELIABBuGJqQQZJDQAgAEHgYWpBCkkNACAAQQFyIgFBmR5GDQAgAEGwYmpBCkkNAAJAIABBy2FqIgNBCksNAEEBIAN0QZUMcQ0BCyAAQfNgakELSQ0AIAFBhx9GDQAgAEGPYWpBFEkNACAAQe5RakEDSQ0AIABBl1lqQQlJDQAgAEGjWWpBA0kNACAAQfFeakEPSQ0AIABB/l5qQQxJDQAgAEGPX2pBBEkNACAAQZlfakEHSQ0AIABBnl9qQQNJDQAgAEGiX2pBA0kNACAAQapfakEESQ0AIABBwF9qQQpJDQAgAEHVX2pBFEkNACAAQcYfRg0AIABB52BqQSRJDQAgAEHOUWpBA0kNACAAQa5RakECSQ0AIABBjlFqQQJJDQAgAEH1T2pBA0kNACAAQaBQakEKSQ0AIABB3S9GDQAgAEHMUGpBIEkNACAAQbBGakEDSQ0AIABBsEdqQQpJDQAgAEHAR2pBCkkNACAAQdxHakEUSQ0AIABBmkhqQQ5JDQAgAEHQSGpBCkkNACAAQd9IakENSQ0AIABBgElqQQNJDQAgAEGVSWpBCUkNACAAQbBJakEKSQ0AIABBzElqQRFJDQAgAEGASmpBBUkNACAAQdBKakEOSQ0AIABB8EpqQQpJDQAgAEGBS2pBC0kNACAAQaBLakEdSQ0AIABBq0tqQQpJDQAgAEHpS2pBBUkNACAAQbBMakELSQ0AIABBuk1qQQpJDQAgAEHQTWpBDEkNACAAQeBNakEMSQ0AIABBqTFGDQAgAEHwT2pBCkkNACAAQcBEakE6SQ0AIABBiUZqQQNJDQAgAEGORmpBA0kNACAAQe05Rg0AIABBrEZqQRVJDQAgAEGFRGpBBUkNAAJAIABBwb9/aiIBQRVLDQBBASABdEGDgIABcQ0BCyAAQZu+f2pBDEkNACAAQeHBAEYNACAAQbC+f2pBDUkNACAAQZGmf2pBA0kNACAAQf/aAEYNACAAQWBxQeDbAEYNACAAQdaff2pBBkkNACAAQeeef2pBAkkNACAAQYyzfWpBCkkNACAAQe/MAkYNACAAQeCzfWpBCkkNAAJAIABB9a99aiIBQRxLDQBBASABdEGBgID4AXENAQsgAEHisn1qQQJJDQAgAEGQsn1qQQJJDQACQAJAIABB/q99aiIBQQRNDQAgAEGAr31qQQJJDQIMAQsgAQ4FAQAAAAEBCyAAQc2sfWpBDkkNACACQYDTAkYNACAAQbmtfWpBDUkNACAAQdqtfWpBCEkNACAAQYGufWpBC0kNACAAQaCufWpBEkkNACAAQcyufWpBEkkNACAAQbCufWpBCkkNACAAQderfWpBDkkNACAAQeXTAkYNACAAQV9xQbCsfWpBCkkNAAJAIABBvat9aiIBQQpLDQBBASABdEGBDHENAQsgAEGwq31qQQpJDQACQCAAQZ2ofWoiAUEKSw0AIAFBCEcNAQsCQCAAQdCqfWoiAUERSw0AQQEgAXRBnYMLcQ0BCwJAIABBlap9aiIBQQtLDQBBASABdEGfGHENAQsgAEGFq31qQQNJDQAgAEFwcSIBQYD8A0YNACAAQZ72A0YNACAAQZCofWpBCkkNACAAQb/+A0YgAEHwgXxqQQpJIABBs4N8akEDSSAAQc2DfGpBAkkgAUGg/ANGcnJycg8LQQELXAEEf0GAgAQhAUGQCCECQX4hAwJAA0BBACEEIANBAmoiA0HnA0sNASACKAIAIAFqIgEgAEsNASACQQRqIQQgAkEIaiECIAQoAgAgAWoiASAASQ0AC0EBIQQLIAQLXAEEf0GAgAQhAUGwFyECQX4hAwJAA0BBACEEIANBAmoiA0H5AUsNASACKAIAIAFqIgEgAEsNASACQQRqIQQgAkEIaiECIAQoAgAgAWoiASAASQ0AC0EBIQQLIAQL7R8BBn9BASEBAkACQAJAIABB1n5qIgJBEEsNAEEBIAJ0QYGQBHENAQsgAEG6empBDEkNACAAQYh+akHKA0kNACAAQcB+akEXSQ0AIABBqH5qQR9JDQACQCAAQZB5aiICQRxLDQBBASACdEHf+YK6AXENAQsCQCAAQaB6aiICQQ5LDQBBASACdEGfoAFxDQELIABB9nZqQaYBSQ0AIABBiXhqQYsBSQ0AIABB8nhqQRRJDQAgAEHdeGpB0wBJDQAgAEGRdGpBBEkNACAAQbB0akEbSQ0AIABBoHVqQSlJDQAgAEHZCkYNACAAQc91akEmSQ0AAkACQAJAIABBj3NqQeMASQ0AIABBAXIiAkHvDEYNACAAQeBzakErSQ0AAkAgAEGrcmoiAUE8Tw0AQoGAjLCAnIGACCABrYhCAYNQRQ0BCyAAQe5xakEeSQ0AIABBtnBqQSFJDQAgAEGxD0YNACAAQbNxakHZAEkNAAJAIABBjHBqIgFBBksNAEEBIAF0QcMAcQ0BCyAAQYBwakEWSQ0AAkACQCAAQdxvaiIDQQRNDQAgAEGaEEYNAgwBC0EBIQEgAw4FBAAAAAQECyAAQfxtakE2SQ0AIABBym5qQQhJDQAgAEHgbmpBFUkNACAAQcBvakEZSQ0AIABBoG9qQQtJDQAgAEG9EkYNACAAQdASRg0AIABBqG1qQQpJDQAgAEGPbWpBEEkNAAJAIABB+2xqIgNBDE8NAEEBIQFB/xkgA0H//wNxdkEBcQ0ECyAAQe1sakEWSQ0AAkAgAEGEbGoiAUEUSw0AQQEgAXRBgfzhAHENAQsgAEHWbGpBB0kNAAJAIABBzmxqIgFBHEsNAEEBIAF0QfGRgIABcQ0BCwJAIABBpGxqIgFBFUsNAEEBIAF0QbuAwAFxDQELIABB7WtqQRZJDQACQCAAQdZraiIBQTVPDQBC/7aDgICA4AsgAa2IQgGDUEUNAQsgAEHtampBFkkNACAAQfFqakEDSQ0AIABBjmtqQQNJDQAgAEH7ampBCUkNAAJAAkACQCAAQdZqaiIDQSZNDQAgAEGHamoiAUEXSw0BQQEgAXRBgeC/BnFFDQEMAwtBASEBIAMOJwUFBQUFBQUBBQUBBQUFBQUBAQEFAQEBAQEBAQEBAQEBAQEBAQEBBQULIABBoGpqQQJJDQELIABB7WlqQRZJDQACQAJAAkAgAEGPaWoiA0EzTQ0AIABB1mlqIgFBE0sNAUEBIAF0Qf/2I3FFDQEMAwtBASEBIAMONAUBAQEBAQEBAQEBAQEBAQEBAQUBBQUFBQUFAQEBBQUFAQUFBQUBAQEFBQEFAQUFAQEBBQUFCyAAQaRpaiIBQQVLDQAgAUECRw0BCyAAQdhoakEDSQ0AIABB7mdqQRdJDQAgAEHyZ2pBA0kNACAAQftnakEISQ0AIABB0BdGDQAgAEHSaGpBDEkNACAAQb0YRg0AIABB1mdqQRBJDQACQCAAQahnaiIBQSlPDQBCh4aAgIAgIAGtiEIBg1BFDQELIABB1mZqQQpJDQAgAEHuZmpBF0kNACAAQftmakEISQ0AIABB8mZqQQNJDQACQCAAQftlaiIBQQtLDQAgAUEIRw0BCwJAIABBy2ZqIgFBCEsNAEEBIAF0QZ8CcQ0BCwJAIABBomZqIgFBFEsNAEEBIAF0QY2A4ABxDQELIABB7mVqQSlJDQAgAEG9GkYNACAAQc4aRg0AIABBzWRqQQlJDQAgAEHmZGpBGEkNACAAQftkakESSQ0AIABBhmVqQQZJDQAgAEGsZWpBA0kNACAAQaFlakEDSQ0AAkAgAEHDZGoiA0EKTw0AQQEhAUH5ByADQf//A3F2QQFxDQQLIAJBsxxGDQAgAEH/Y2pBMEkNACAAQcBjakEHSQ0AAkAgAEH/YmoiAUEMSw0AQQEgAXRByyVxDQELIABBfHEiA0GUHUYNACAAQediakEHSQ0AAkAgAEHfYmoiAUEmTw0AQtfsm4D5BSABrYhCAYNQRQ0BCyAAQYBgakErSQ0AIABB+GBqQQVJDQAgAEG3YWpBJEkNACAAQXhxIgRBwB5GDQAgAEGAHkYNACADQdwdRg0AAkAgAEHBX2oiAUEoTw0AQoGA+MPHGCABrYhCAYNQRQ0BCyAAQZJfakEDSQ0AIABB4F5qQSZJDQAgAEGOIUYNACAAQYtfakENSQ0AIABBxyFGDQAgAEHNIUYNACAAQbZbakEESQ0AIABBsF5qQStJDQAgAEGEXmpBzQJJDQACQCAAQbBbaiIFQQlPDQBBASEBQf8CIAVB//8DcXZBAXENBAsgAEHOWmpBBEkNACAAQfBaakEhSQ0AIABB9lpqQQRJDQAgAEGmW2pBBEkNACAAQaBbakEpSQ0AAkAgAEHIWmoiBUEJTw0AQQEhAUH/AiAFQf//A3F2QQFxDQQLIABBgFFqQTRJDQAgAEGSUWpBA0kNACAAQaBRakENSQ0AIABBwFFqQRJJDQAgAEHgUWpBEkkNACAAQfJRakEESQ0AIABBgFJqQQ1JDQAgAEGSUmpBC0kNACAAQeBSakHLAEkNACAAQf9SakEaSQ0AIABBkVNqQRFJDQAgAEH/V2pB7ARJDQAgAEGIWGpBBkkNACAAQeBYakHWAEkNACAAQXBxIgVBgCdGDQAgAEHoWWpBwwBJDQAgAEHuWWpBBEkNACAAQahaakE5SQ0AIABBvlpqQQRJDQAgAEG4WmpBD0kNACAAQdcvRg0AIABB3C9GDQAgAEHgT2pB2QBJDQAgAEGATGpBF0kNACAAQdBMakEaSQ0AIABBgE1qQSxJDQAgAEGQTWpBBUkNACAAQbBNakEeSQ0AIABBgE5qQR9JDQAgAEHQTmpBxgBJDQAgAEGqMUYNBCAAQYBPakEpSQ0EIABBu0lqQQdJDQQgAEH7SWpBL0kNBCAAQac1Rg0EIABB4EtqQTVJDQQgAEGXRmpBBEkNBCAAQcNGakEDSQ0EIABB8EZqQStJDQQgAEGAR2pBCUkNBCAAQaZHakEkSQ0EIABBs0dqQQNJDQQgAEGASGpBJEkNBCAAQcZIakEsSQ0EIAJBrzdGDQQgAEH9SGpBHkkNBCAAQZJGaiIGQQlJDQEMAgtBASEBDAILQQEhAUGPAyAGQf//A3F2QQFxDQELIARB0D5GDQEgAEG4QWpBBkkNASAAQeBBakEmSQ0BIABB6EFqQQZJDQEgAEGARmpBwAFJDQEgAEGARGpBlgJJDQECQCAAQadBaiIBQQRLDQBBASABdEEVcQ0CCyAAQaFBakEfSQ0BIABBgEFqQTVJDQECQCAAQcpAaiIEQQlPDQBBASEBQf8CIARB//8DcXZBAXENAQsgAEGOQGpBA0kNASAAQaBAakENSQ0BIABBqkBqQQZJDQEgA0HQP0YNASAAQb5AakEDSQ0BIABBukBqQQdJDQEgAEGKQGpBB0kNASAAQfHAAEYNASAAQf/AAEYNASAAQfC+f2pBDUkNASAAQYLCAEYNASAAQYfCAEYNASAAQZXCAEYNASAAQfa9f2pBCkkNAQJAIABB6L1/aiIEQRFPDQBBASEBQb+gBSAEdkEBcQ0BCyAAQda9f2pBEEkNASADQbzCAEYNAQJAIABBu71/aiIEQQpPDQBBASEBQZ8EIARB//8DcXZBAXENAQsgAEGgp39qQYUBSQ0BIABB0Kd/akEvSQ0BIABBoL1/akEpSQ0BIABBgKh/akEvSQ0BAkAgAEGVpn9qIgRBCU8NAEEBIQFBjwMgBEH//wNxdkEBcQ0BCyAAQYCmf2pBJkkNASAAQafaAEYNASAAQa3aAEYNASAAQYC2fWpBjQJJDQEgAEGwtn1qQS5JDQEgAEGAwH1qQY0JSQ0BIABBgOR+akHwowFJDQEgAEGAmH9qQbYzSQ0BIAVB8OMARg0BIABB4Jx/akEbSQ0BIABBz51/akHeAEkNASAAQfudf2pBK0kNASADQfzhAEYNASAAQd+ef2pB2gBJDQEgAEHlnn9qQQVJDQEgAEG/n39qQdYASQ0BIABByJ9/akEFSQ0BIABBz59/akEFSQ0BIABB359/akEJSQ0BIABB+59/akEDSQ0BIABBqKR/akEHSQ0BIABBsKR/akEHSQ0BIABBuKR/akEHSQ0BIABBwKR/akEHSQ0BIABByKR/akEHSQ0BIABB0KR/akEHSQ0BIABB2KR/akEHSQ0BIABB4KR/akEHSQ0BIABBgKV/akEXSQ0BIABB79oARg0BIABB0KV/akE4SQ0BIABB/q59akEySQ0BIABBwK99akE0SQ0BIABB9K99akEXSQ0BIABB+a99akEESQ0BIABB/a99akEDSQ0BIABBibB9akELSQ0BIABB9bB9akEvSQ0BIABB3rF9akHnAEkNASAAQemxfWpBCUkNASAAQeCyfWpB0ABJDQEgAEGBs31qQR9JDQEgAEHAs31qQS9JDQEgAkGrzAJGDQEgBUGQzAJGDQECQCAAQY6ufWoiAkENTw0AQQEhAUG/NCACQf//A3F2QQFxDQELIABBoK19akEdSQ0BIABB9q19akEcSQ0BIABB0K19akEXSQ0BIABBvKt9akEISQ0BIABBwKt9akEDSQ0BIABBgKx9akEpSQ0BIABBhqx9akEFSQ0BIABBmqx9akEKSQ0BIABBoKx9akEFSQ0BIABBz9MCRg0BIABB/Kx9akEvSQ0BIABBgqt9akEySQ0BIABB+tQCRg0BIABBoKt9akEXSQ0BAkAgAEHPqn1qIgJBEk8NAEEBIQFBsb4KIAJ2QQFxDQELIABBgIp8akEHSQ0BIABBkIt8akHqAEkNASAAQYCOfGpB7gJJDQEgAEG10HxqQTFJDQEgAEHQ0HxqQRdJDQEgAEGAqH1qQaTXAEkNASAAQZCpfWpB8wBJDQEgAEGkqX1qQQpJDQEgAEHQqX1qQStJDQEgAEHYqX1qQQdJDQEgAEHgqX1qQQdJDQEgAEHvqX1qQQZJDQEgAEF3cUH/qX1qQQZJDQEgAEGOqn1qQQNJDQEgAEGlqn1qQQNJDQEgAEGgqn1qQQtJDQECQCAAQe2JfGoiAkELTw0AQQEhAUGfCCACQf//A3F2QQFxDQELIABB4Yl8akEKSQ0BIABB1ol8akENSQ0BAkAgAEHIiXxqIgJBDU8NAEEBIQFB3zYgAkH//wNxdkEBcQ0BCyAAQa6AfGpBBkkNASAAQbaAfGpBBkkNASAAQb6AfGpBBkkNASAAQZqBfGpB2QBJDQEgAEG/gXxqQRpJDQEgAEHfgXxqQRpJDQEgAEGKg3xqQYcBSQ0BIABBkIN8akEFSQ0BIABBkIR8akEMSQ0BIABB7oR8akE2SQ0BIABBsIV8akHAAEkNASAAQbqJfGpB7ABJDQFBASEBIABBrYh8akHrAkkNACAAQaaAfGpBA0kPCyABDwtBAQtdAQF/QQAhCQJAIAAvAQAgAUcNACAALwECIAJHDQAgAC8BBCADRw0AIAAvAQYgBEcNACAALwEIIAVHDQAgAC8BCiAGRw0AIAAvAQwgB0cNACAALwEOIAhGIQkLIAkLNQACQCAAQYD4A3FBgLADRw0AIABBCnRBgPg/cUEAKAK8oAEvAQJB/wdxckGAgARqIQALIAALaAECf0EBIQECQAJAIABBX2oiAkEFSw0AQQEgAnRBMXENAQsgAEH4/wNxQShGDQAgAEFGakH//wNxQQZJDQACQCAAQaV/aiICQQNLDQAgAkEBRw0BCyAAQYV/akH//wNxQQRJIQELIAELjQEBBX9BACgCvKABIQBBACgCwKABIQEDfyAAQQJqIQICQAJAIAAgAU8NACACLwEAIgNBpH9qIgRBAU0NASACIQAgA0F2aiIDQQNLDQIgAiEAIAMOBAACAgAAC0EAIAI2ArygARAdQQAPCwJAAkAgBA4CAQABC0EAIAI2ArygAUHdAA8LIABBBGohAAwACwtJAQN/QQAhAwJAIAJFDQACQANAIAAtAAAiBCABLQAAIgVHDQEgAUEBaiEBIABBAWohACACQX9qIgINAAwCCwsgBCAFayEDCyADCwvCFwIAQYAIC5gXAAAAAAAAAAAAAAAAAAAAAAAAAAALAAAAAgAAABkAAAACAAAAEgAAAAIAAAABAAAAAgAAAA4AAAADAAAADQAAACMAAAB6AAAARgAAADQAAAAMAQAAHAAAAAQAAAAwAAAAMAAAAB8AAAAOAAAAHQAAAAYAAAAlAAAACwAAAB0AAAADAAAAIwAAAAUAAAAHAAAAAgAAAAQAAAArAAAAnQAAABMAAAAjAAAABQAAACMAAAAFAAAAJwAAAAkAAAAzAAAAnQAAADYBAAAKAAAAFQAAAAsAAAAHAAAAmQAAAAUAAAADAAAAAAAAAAIAAAArAAAAAgAAAAEAAAAEAAAAAAAAAAMAAAAWAAAACwAAABYAAAAKAAAAHgAAAEIAAAASAAAAAgAAAAEAAAALAAAAFQAAAAsAAAAZAAAARwAAADcAAAAHAAAAAQAAAEEAAAAAAAAAEAAAAAMAAAACAAAAAgAAAAIAAAAcAAAAKwAAABwAAAAEAAAAHAAAACQAAAAHAAAAAgAAABsAAAAcAAAANQAAAAsAAAAVAAAACwAAABIAAAAOAAAAEQAAAG8AAABIAAAAOAAAADIAAAAOAAAAMgAAAA4AAAAjAAAAXQEAACkAAAAHAAAAAQAAAE8AAAAcAAAACwAAAAAAAAAJAAAAFQAAAGsAAAAUAAAAHAAAABYAAAANAAAANAAAAEwAAAAsAAAAIQAAABgAAAAbAAAAIwAAAB4AAAAAAAAAAwAAAAAAAAAJAAAAIgAAAAQAAAAAAAAADQAAAC8AAAAPAAAAAwAAABYAAAAAAAAAAgAAAAAAAAAkAAAAEQAAAAIAAAAYAAAAVQAAAAYAAAACAAAAAAAAAAIAAAADAAAAAgAAAA4AAAACAAAACQAAAAgAAAAuAAAAJwAAAAcAAAADAAAAAQAAAAMAAAAVAAAAAgAAAAYAAAACAAAAAQAAAAIAAAAEAAAABAAAAAAAAAATAAAAAAAAAA0AAAAEAAAAnwAAADQAAAATAAAAAwAAABUAAAACAAAAHwAAAC8AAAAVAAAAAQAAAAIAAAAAAAAAuQAAAC4AAAAqAAAAAwAAACUAAAAvAAAAFQAAAAAAAAA8AAAAKgAAAA4AAAAAAAAASAAAABoAAADmAAAAKwAAAHUAAAA/AAAAIAAAAAcAAAADAAAAAAAAAAMAAAAHAAAAAgAAAAEAAAACAAAAFwAAABAAAAAAAAAAAgAAAAAAAABfAAAABwAAAAMAAAAmAAAAEQAAAAAAAAACAAAAAAAAAB0AAAAAAAAACwAAACcAAAAIAAAAAAAAABYAAAAAAAAADAAAAC0AAAAUAAAAAAAAACMAAAA4AAAACAEAAAgAAAACAAAAJAAAABIAAAAAAAAAMgAAAB0AAABxAAAABgAAAAIAAAABAAAAAgAAACUAAAAWAAAAAAAAABoAAAAFAAAAAgAAAAEAAAACAAAAHwAAAA8AAAAAAAAASAEAABIAAAC+AAAAAAAAAFAAAACZAwAAZwAAAG4AAAASAAAAwwAAAL0KAAAuBAAA0g8AAEYCAAC6IQAAOAIAAAgAAAAeAAAAcgAAAB0AAAATAAAALwAAABEAAAADAAAAIAAAABQAAAAGAAAAEgAAALECAAA/AAAAgQAAAEoAAAAGAAAAAAAAAEMAAAAMAAAAQQAAAAEAAAACAAAAAAAAAB0AAAD3FwAACQAAANUEAAArAAAACAAAAPgiAAAeAQAAMgAAAAIAAAASAAAAAwAAAAkAAACLAQAABQkAAGoAAAAGAAAADAAAAAQAAAAIAAAACAAAAAkAAABnFwAAVAAAAAIAAABGAAAAAgAAAAEAAAADAAAAAAAAAAMAAAABAAAAAwAAAAMAAAACAAAACwAAAAIAAAAAAAAAAgAAAAYAAAACAAAAQAAAAAIAAAADAAAAAwAAAAcAAAACAAAABgAAAAIAAAAbAAAAAgAAAAMAAAACAAAABAAAAAIAAAAAAAAABAAAAAYAAAACAAAAUwEAAAMAAAAYAAAAAgAAABgAAAACAAAAHgAAAAIAAAAYAAAAAgAAAB4AAAACAAAAGAAAAAIAAAAeAAAAAgAAABgAAAACAAAAHgAAAAIAAAAYAAAAAgAAAAcAAAA1CQAALAAAAAsAAAAGAAAAEQAAAAAAAAByAQAAKwAAABUFAADEAAAAPAAAAEMAAAAIAAAAAAAAALUEAAADAAAAAgAAABoAAAACAAAAAQAAAAIAAAAAAAAAAwAAAAAAAAACAAAACQAAAAIAAAADAAAAAgAAAAAAAAACAAAAAAAAAAcAAAAAAAAABQAAAAAAAAACAAAAAAAAAAIAAAAAAAAAAgAAAAIAAAACAAAAAQAAAAIAAAAAAAAAAwAAAAAAAAACAAAAAAAAAAIAAAAAAAAAAgAAAAAAAAACAAAAAAAAAAIAAAABAAAAAgAAAAAAAAADAAAAAwAAAAIAAAAGAAAAAgAAAAMAAAACAAAAAwAAAAIAAAAAAAAAAgAAAAkAAAACAAAAEAAAAAYAAAACAAAAAgAAAAQAAAACAAAAEAAAAEURAADdpgAAIwAAADQQAAAMAAAA3QAAAAMAAACBFgAADwAAADAdAAAgDAAAHQIAAOMFAABKEwAA/QEAAAAAAADjAAAAAAAAAJYAAAAEAAAAJgEAAAkAAABYBQAAAgAAAAIAAAABAAAABgAAAAMAAAApAAAAAgAAAAUAAAAAAAAApgAAAAEAAAA+AgAAAwAAAAkAAAAJAAAAcgEAAAEAAACaAAAACgAAALAAAAACAAAANgAAAA4AAAAgAAAACQAAABAAAAADAAAALgAAAAoAAAA2AAAACQAAAAcAAAACAAAAJQAAAA0AAAACAAAACQAAAAYAAAABAAAALQAAAAAAAAANAAAAAgAAADEAAAANAAAACQAAAAMAAAACAAAACwAAAFMAAAALAAAABwAAAAAAAAChAAAACwAAAAYAAAAJAAAABwAAAAMAAAA4AAAAAQAAAAIAAAAGAAAAAwAAAAEAAAADAAAAAgAAAAoAAAAAAAAACwAAAAEAAAADAAAABgAAAAQAAAAEAAAAwQAAABEAAAAKAAAACQAAAAUAAAAAAAAAUgAAABMAAAANAAAACQAAANYAAAAGAAAAAwAAAAgAAAAcAAAAAQAAAFMAAAAQAAAAEAAAAAkAAABSAAAADAAAAAkAAAAJAAAAVAAAAA4AAAAFAAAACQAAAPMAAAAOAAAApgAAAAkAAABHAAAABQAAAAIAAAABAAAAAwAAAAMAAAACAAAAAAAAAAIAAAABAAAADQAAAAkAAAB4AAAABgAAAAMAAAAGAAAABAAAAAAAAAAdAAAACQAAACkAAAAGAAAAAgAAAAMAAAAJAAAAAAAAAAoAAAAKAAAALwAAAA8AAACWAQAABwAAAAIAAAAHAAAAEQAAAAkAAAA5AAAAFQAAAAIAAAANAAAAewAAAAUAAAAEAAAAAAAAAAIAAAABAAAAAgAAAAYAAAACAAAAAAAAAAkAAAAJAAAAMQAAAAQAAAACAAAAAQAAAAIAAAAEAAAACQAAAAkAAABKAQAAAwAAAGpLAAAJAAAAhwAAAAQAAAA8AAAABgAAABoAAAAJAAAA9gMAAAAAAAACAAAANgAAAAgAAAADAAAAUgAAAAAAAAAMAAAAAQAAAKxMAAABAAAAxxQAAAQAAAAEAAAABQAAAAkAAAAHAAAAAwAAAAYAAAAfAAAAAwAAAJUAAAACAAAAigUAADEAAAABAgAANgAAAAUAAAAxAAAACQAAAAAAAAAPAAAAAAAAABcAAAAEAAAAAgAAAA4AAABRBQAABgAAAAIAAAAQAAAAAwAAAAYAAAACAAAAAQAAAAIAAAAEAAAABgEAAAYAAAAKAAAACQAAAKMBAAANAAAA1wUAAAYAAABuAAAABgAAAAYAAAAJAAAAlxIAAAkAAAAHBQwA7wAAAABBmB8LHFCMAAABAAAAAgAAAAMAAAAEAAAAAAQAAPAfAAA=","undefined"!=typeof window&&"function"==typeof atob?Uint8Array.from(atob(B),A=>A.charCodeAt(0)):Buffer.from(B,"base64")));var B;const{exports:E}=await WebAssembly.instantiate(Q);A=E})())} \ No newline at end of file +"use strict";exports.init=init;exports.initSync=initSync;exports.parse=parse;let A;const Q=1===new Uint8Array(new Uint16Array([1]).buffer)[0];function parse(g,I="@"){if(!A)throw new Error("Not initialized");const D=g.length+1,N=(A.__heap_base.value||A.__heap_base)+4*D-A.memory.buffer.byteLength;N>0&&A.memory.grow(Math.ceil(N/65536));const k=A.sa(D);(Q?C:E)(g,new Uint16Array(A.memory.buffer,k,D));const w=A.parseCJS(k,g.length,0,0,0);if(w){const Q=new Error(`Parse error ${I}${A.e()}:${g.slice(0,A.e()).split("\n").length}:${A.e()-g.lastIndexOf("\n",A.e()-1)}`);throw Object.assign(Q,{idx:A.e()}),5!==w&&6!==w&&7!==w||Object.assign(Q,{code:"ERR_LEXER_ESM_SYNTAX"}),Q}let H=new Set,J=new Set,o=new Set;for(;A.rre();){const Q=B(g.slice(A.res(),A.ree()));Q&&J.add(Q)}for(;A.ru();)o.add(B(g.slice(A.us(),A.ue())));for(;A.re();){let Q=B(g.slice(A.es(),A.ee()));void 0===Q||o.has(Q)||H.add(Q)}return{exports:[...H],reexports:[...J]}}function B(A){if('"'!==A[0]&&"'"!==A[0])return A;try{const Q=(0,eval)(A);for(let A=0;A>>8}}function C(A,Q){const B=A.length;let E=0;for(;EA.charCodeAt(0))}let I;function init(){return I||(I=(async()=>{const Q=await WebAssembly.compile(g()),{exports:B}=await WebAssembly.instantiate(Q);A=B})())}function initSync(){if(A)return;const Q=new WebAssembly.Module(g()),{exports:B}=new WebAssembly.Instance(Q);A=B} \ No newline at end of file diff --git a/deps/cjs-module-lexer/dist/lexer.mjs b/deps/cjs-module-lexer/dist/lexer.mjs index 5dc4052af69..964b74cfa78 100644 --- a/deps/cjs-module-lexer/dist/lexer.mjs +++ b/deps/cjs-module-lexer/dist/lexer.mjs @@ -1,2 +1,2 @@ -/* cjs-module-lexer 1.2.2 */ -let A;const Q=1===new Uint8Array(new Uint16Array([1]).buffer)[0];export function parse(g,I="@"){if(!A)throw new Error("Not initialized");const D=g.length+1,N=(A.__heap_base.value||A.__heap_base)+4*D-A.memory.buffer.byteLength;N>0&&A.memory.grow(Math.ceil(N/65536));const k=A.sa(D);if((Q?C:E)(g,new Uint16Array(A.memory.buffer,k,D)),!A.parseCJS(k,g.length,0,0,0))throw Object.assign(new Error(`Parse error ${I}${A.e()}:${g.slice(0,A.e()).split("\n").length}:${A.e()-g.lastIndexOf("\n",A.e()-1)}`),{idx:A.e()});let w=new Set,o=new Set,J=new Set;for(;A.rre();){const Q=B(g.slice(A.res(),A.ree()));Q&&o.add(Q)}for(;A.ru();)J.add(B(g.slice(A.us(),A.ue())));for(;A.re();){let Q=B(g.slice(A.es(),A.ee()));void 0===Q||J.has(Q)||w.add(Q)}return{exports:[...w],reexports:[...o]}}function B(A){if('"'!==A[0]&&"'"!==A[0])return A;try{const Q=(0,eval)(A);for(let A=0;A>>8}}function C(A,Q){const B=A.length;let E=0;for(;E{const Q=await WebAssembly.compile((B="AGFzbQEAAAABrAERYAJ/fwBgAABgAX8Bf2AAAX9gBn9/f39/fwF/YAF/AGAXf39/f39/f39/f39/f39/f39/f39/f38Bf2AIf39/f39/f38Bf2AHf39/f39/fwF/YAN/f38Bf2AFf39/f38Bf2AOf39/f39/f39/f39/f38Bf2AKf39/f39/f39/fwF/YAt/f39/f39/f39/fwF/YAJ/fwF/YAR/f39/AX9gCX9/f39/f39/fwF/A0NCAgMDAwMDAwMDAwMAAAABBAICBQQFAQECAgICAQUBAQUBAQYHAQIIAwICAgkKAgELAgwNDgQPCA4HAgICAhACAgMJBAUBcAEFBQUDAQABBg8CfwFB0JgCC38AQdCYAgsHXA4GbWVtb3J5AgACc2EAAAFlAAECZXMAAgJlZQADA3JlcwAEA3JlZQAFAnVzAAYCdWUABwJyZQAIA3JyZQAJAnJ1AAoIcGFyc2VDSlMADwtfX2hlYXBfYmFzZQMBCQoBAEEBCwQLDA0OCtOhAUJ4AQF/QQAoApgfIgEgAEEBdGoiAEEAOwEAQQAgAEECaiIANgLkH0EAIAA2AugfQQBBADYCwB9BAEEANgLIH0EAQQA2AsQfQQBBADYCzB9BAEEANgLUH0EAQQA2AtAfQQBBADYC2B9BAEEANgLgH0EAQQA2AtwfIAELCABBACgC7B8LFQBBACgCxB8oAgBBACgCmB9rQQF1CxUAQQAoAsQfKAIEQQAoApgfa0EBdQsVAEEAKALQHygCAEEAKAKYH2tBAXULFQBBACgC0B8oAgRBACgCmB9rQQF1CxUAQQAoAtwfKAIAQQAoApgfa0EBdQsVAEEAKALcHygCBEEAKAKYH2tBAXULJQEBf0EAQQAoAsQfIgBBCGpBwB8gABsoAgAiADYCxB8gAEEARwslAQF/QQBBACgC0B8iAEEIakHMHyAAGygCACIANgLQHyAAQQBHCyUBAX9BAEEAKALcHyIAQQhqQdgfIAAbKAIAIgA2AtwfIABBAEcLSAEBf0EAKALIHyICQQhqQcAfIAIbQQAoAugfIgI2AgBBACACNgLIH0EAIAJBDGo2AugfIAJBADYCCCACIAE2AgQgAiAANgIAC0gBAX9BACgC1B8iAkEIakHMHyACG0EAKALoHyICNgIAQQAgAjYC1B9BACACQQxqNgLoHyACQQA2AgggAiABNgIEIAIgADYCAAtIAQF/QQAoAuAfIgJBCGpB2B8gAhtBACgC6B8iAjYCAEEAIAI2AuAfQQAgAkEMajYC6B8gAkEANgIIIAIgATYCBCACIAA2AgALEgBBAEEANgLMH0EAQQA2AtQfC6MPAEEAIAE2AoBAQQAgADYCmB8CQCACRQ0AQQAgAjYCnB8LAkAgA0UNAEEAIAM2AqAfCwJAIARFDQBBACAENgKkHwtBAEH//wM7AYhAQQBBoMAANgKgYEEAQbDgADYCsKABQQBBgCA2ArSgAUEAQQAoAqwfNgKMQEEAIABBfmoiAjYCvKABQQAgAiABQQF0aiIDNgLAoAFBAEEAOwGGQEEAQQA7AYRAQQBBADoAkEBBAEEANgLsH0EAQQA6APAfQQBBADoAuKABAkACQCAALwEAQSNHDQAgAC8BAkEhRw0AQQEhAiABQQJGDQFBACAAQQJqNgK8oAEgAEEEaiEAAkADQCAAIgJBfmogA08NASACQQJqIQAgAi8BAEF2aiIBQQNLDQAgAQ4EAQAAAQELC0EAIAI2ArygAQsDQEEAIAJBAmoiADYCvKABAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQCACIANPDQACQCAALwEAIgFBd2oiA0EXSw0AQQEgA3RBn4CABHENFwsCQAJAQQAvAYZAIgMNACABQaF/aiIEQQ5NDQMgAUFZaiIEQQhNDQQgAUGFf2oiBEECTQ0FIAFBIkYNCyABQc8ARg0BIAFB8gBHDRUCQEEAEBBFDQAgABARRQ0AIAIQEgtBAEEAKAK8oAE2AoxADBgLIAFBWWoiBEEITQ0FIAFBoH9qIgRBBU0NBiABQYV/aiIEQQJNDQcgAUEiRg0KIAFBzwBGDQAgAUHtAEcNFAwTCyACQQRqQeIAQeoAQeUAQeMAQfQAEBNFDRMgABARRQ0TIANFEBQMEwtBAC8BiEBB//8DRkEALwGGQEVxQQAtAPAfRXEPCyAEDg8SBRERDhEPERERExERERASCyAEDgkGDAgQEBAQEAUGCyAEDgMJDwcJCyAEDgkECgkODg4ODgMECyAEDgYBDQ0KDQsBCyAEDgMGDAMGC0EALwGIQEH+/wNGDQMMBAsCQAJAIAIvAQQiAkEqRg0AIAJBL0cNARAVDA8LEBYMDgsCQAJAAkACQEEAKAKMQCIALwEAIgIQF0UNACACQVVqIgNBA0sNAgJAAkACQCADDgQBBQIAAQsgAEF+ai8BAEFQakH//wNxQQpJDQMMBAsgAEF+ai8BAEErRg0CDAMLIABBfmovAQBBLUYNAQwCCwJAAkAgAkH9AEYNACACQS9GDQEgAkEpRw0CQQAoArCgASADQQJ0aigCABAYRQ0CDAMLQQAoArCgASADQQJ0aigCABAZDQIgA0HQoAFqLQAARQ0BDAILQQAtAJBADQELIAAQGiEDIAJFDQBBASECIANFDQELEBtBACECC0EAIAI6AJBADAoLIAEQHAwJC0EAIANBf2oiADsBhkACQCADQQAvAYhAIgJHDQBBAEEALwGEQEF/aiICOwGEQEEAQQAoAqBgIAJB//8DcUEBdGovAQA7AYhADAILIAJB//8DRg0IIABB//8DcSACTw0ICxAdQQAhAgwMCxAeDAYLIANB0KABakEALQC4oAE6AABBACADQQFqOwGGQEEAKAKwoAEgA0ECdGpBACgCjEA2AgBBAEEAOgC4oAEMBQtBACADQX9qOwGGQAwEC0EAIANBAWo7AYZAQQAoArCgASADQQJ0akEAKAKMQDYCAAwDCyAAEBFFDQIgAi8BBEHsAEcNAiACLwEGQeEARw0CIAIvAQhB8wBHDQIgAi8BCkHzAEcNAgJAAkAgAi8BDCIDQXdqIgJBF0sNAEEBIAJ0QZ+AgARxDQELIANBoAFHDQMLQQBBAToAuKABDAILIAJBBGpB+ABB8ABB7wBB8gBB9AAQE0UNASAAEBFFDQECQCACLwEOQfMARw0AQQAQHwwCCyADDQEQIAwBCyACQQRqQe8AQeQAQfUAQewAQeUAEBNFDQAgABARRQ0AECELQQBBACgCvKABNgKMQAwCCwJAAkAgAkEEaiIDQekAQe4AQfQAQeUAQfIAQe8AQfAAQdIAQeUAQfEAQfUAQekAQfIAQeUAQdcAQekAQewAQeQAQeMAQeEAQfIAQeQAECJFDQACQCAAEBENACACLwEAQS5HDQELQQAgAkEwajYCvKABIAIvATBBKEcNAUEAIAJBMmo2ArygAUEAQQE7AYZAQQAoArCgAUEAKAKMQDYCAEEAEBBFDQEgABARRQ0BIAIQEgwBCyADQd8AQeUAQfgAQfAAQe8AQfIAQfQAECNFDQACQCAAEBENACACLwEAQS5HDQELQQAgAkESajYCvKABAkAgAi8BEiIDQdMARw0AIAIvARRB9ABHDQEgAi8BFkHhAEcNASACLwEYQfIARw0BQQAgAkEaajYCvKABIAIvARohAwsgA0H//wNxQShHDQBBACgCsKABQQAoAoxANgIAQQBBATsBhkBBAEEAKAK8oAEiAkECajYCvKABIAIvAQJB8gBHDQBBAhAQGgtBAEEAKAK8oAE2AoxADAELAkAgAkEEakHtAEHwAEHvAEHyAEH0ABATRQ0AIAAQEUUNABAkQQAoArygASEAC0EAIAA2AoxAC0EAKALAoAEhA0EAKAK8oAEhAgwACwsgAgv3AQEEf0EAIQECQEEAKAK8oAEiAkECakHlAEHxAEH1AEHpAEHyAEHlABAmRQ0AQQAhAUEAIAJBDmo2ArygAQJAECdBKEcNAEEAQQAoArygAUECajYCvKABECchA0EAKAK8oAEhBAJAIANBJ0YNACADQSJHDQELIAMQHEEAQQAoArygAUECaiIDNgK8oAEQJ0EpRw0AAkAgAEF/aiIBQQFLDQACQAJAIAEOAgEAAQsgBCADQQAoAqAfEQAAQQEPCyAEIANBACgCoB8RAABBAQ8LQQAoArSgASAENgIAQQAoArSgASADNgIEQQEPC0EAIAI2ArygAQsgAQsdAAJAQQAoApgfIABHDQBBAQ8LIABBfmovAQAQJQv+AgEEf0EAKAKYHyEBAkADQCAAQX5qIQIgAC8BACIDQSBHDQEgACABSyEEIAIhACAEDQALCwJAIANBPUcNAAJAA0AgAkF+aiEAIAIvAQBBIEcNASACIAFLIQQgACECIAQNAAsLIABBAmohAiAAQQRqIQNBACEEAkADQCACECghACACIAFNDQEgAEUNASAAQdwARg0CIAAQKUUNASACQX5BfCAAQYCABEkbaiECIAAQKiEEDAALCyAEQQFxRQ0AIAIvAQBBIEcNAEEAKAK0oAEiBEEAKAKwH0YNACAEIAM2AgwgBCACQQJqNgIIIAJBfmohAEEgIQICQANAIABBAmogAU0NASACQf//A3FBIEcNASAALwEAIQIgAEF+aiEADAALCyACQf//A3FBjn9qIgJBAksNAAJAAkACQCACDgMAAwEACyAAQfYAQeEAECsNAQwCCyAAQewAQeUAECsNACAAQeMAQe8AQe4AQfMAECxFDQELQQAgBEEQajYCtKABCws/AQF/QQAhBgJAIAAvAQAgAUcNACAALwECIAJHDQAgAC8BBCADRw0AIAAvAQYgBEcNACAALwEIIAVGIQYLIAYLpCYBCH9BAEEAKAK8oAEiAUEMajYCvKABIAFBCmohAQJAECdBLkcNAEEAQQAoArygAUECajYCvKABAkACQBAnIgJB5ABHDQBBACgCvKABIgBBAmpB5QBB5gBB6QBB7gBB5QBB0ABB8gBB7wBB8ABB5QBB8gBB9ABB+QAQL0UNAkEAIABBHGo2ArygASAAQRpqIQEQJ0EoRw0CQQBBACgCvKABQQJqNgK8oAEQJxAwRQ0CECdBLEcNAkEAQQAoArygAUECajYCvKABAkAQJyIAQSdGDQAgAEEiRw0DC0EAKAK8oAEhAiAAEBxBAEEAKAK8oAFBAmoiADYCvKABECdBLEcNAUEAQQAoArygAUECajYCvKABECdB+wBHDQFBAEEAKAK8oAFBAmo2ArygAQJAECciA0HlAEcNAEEAKAK8oAEiA0ECakHuAEH1AEHtAEHlAEHyAEHhAEHiAEHsAEHlABAxRQ0CQQAgA0EUajYCvKABECdBOkcNAkEAQQAoArygAUECajYCvKABECdB9ABHDQJBACgCvKABIgMvAQJB8gBHDQIgAy8BBEH1AEcNAiADLwEGQeUARw0CQQAgA0EIajYCvKABECdBLEcNAkEAQQAoArygAUECajYCvKABECchAwsCQCADQecARg0AIANB9gBHDQJBACgCvKABIgMvAQJB4QBHDQIgAy8BBEHsAEcNAiADLwEGQfUARw0CIAMvAQhB5QBHDQJBACADQQpqNgK8oAEQJ0E6Rw0CIAIgAEEAKAKcHxEAAEEAIAE2ArygAQ8LQQAoArygASIDLwECQeUARw0BIAMvAQRB9ABHDQFBACADQQZqNgK8oAECQBAnIgNBOkcNAEEAQQAoArygAUECajYCvKABECdB5gBHDQJBACgCvKABIgNBAmpB9QBB7gBB4wBB9ABB6QBB7wBB7gAQI0UNAkEAIANBEGoiAzYCvKABAkAQJyIEQShGDQAgA0EAKAK8oAFGDQMgBBAtRQ0DCxAnIQMLIANBKEcNAUEAQQAoArygAUECajYCvKABECdBKUcNAUEAQQAoArygAUECajYCvKABECdB+wBHDQFBAEEAKAK8oAFBAmo2ArygARAnQfIARw0BQQAoArygASIDQQJqQeUAQfQAQfUAQfIAQe4AEBNFDQFBACADQQxqNgK8oAEQJxAtRQ0BAkACQAJAECciA0HbAEYNACADQS5HDQJBAEEAKAK8oAFBAmo2ArygARAnEC0NAQwEC0EAQQAoArygAUECajYCvKABAkAQJyIDQSdGDQAgA0EiRw0ECyADEBxBAEEAKAK8oAFBAmo2ArygARAnQd0ARw0DQQBBACgCvKABQQJqNgK8oAELECchAwsCQCADQTtHDQBBAEEAKAK8oAFBAmo2ArygARAnIQMLIANB/QBHDQFBAEEAKAK8oAFBAmo2ArygAQJAECciA0EsRw0AQQBBACgCvKABQQJqNgK8oAEQJyEDCyADQf0ARw0BQQBBACgCvKABQQJqNgK8oAEQJ0EpRw0BIAIgAEEAKAKcHxEAAA8LIAJB6wBHDQEgAEUNAUEAKAK8oAEiAC8BAkHlAEcNASAALwEEQfkARw0BIAAvAQZB8wBHDQEgAEEGaiEBQQAgAEEIajYCvKABECdBKEcNAUEAQQAoArygAUECajYCvKABECchAEEAKAK8oAEhAiAAEC1FDQFBACgCvKABIQAQJ0EpRw0BQQBBACgCvKABIgFBAmo2ArygARAnQS5HDQFBAEEAKAK8oAFBAmo2ArygARAnQeYARw0BQQAoArygASIDQQJqQe8AQfIAQcUAQeEAQeMAQegAECZFDQFBACADQQ5qNgK8oAEQJyEDQQAoArygASIEQX5qIQEgA0EoRw0BQQAgBEECajYCvKABECdB5gBHDQFBACgCvKABIgNBAmpB9QBB7gBB4wBB9ABB6QBB7wBB7gAQI0UNAUEAIANBEGo2ArygARAnQShHDQFBAEEAKAK8oAFBAmo2ArygARAnIQNBACgCvKABIQQgAxAtRQ0BQQAoArygASEDECdBKUcNAUEAQQAoArygAUECajYCvKABECdB+wBHDQFBAEEAKAK8oAFBAmo2ArygARAnQekARw0BQQAoArygASIFLwECQeYARw0BQQAgBUEEajYCvKABECdBKEcNAUEAQQAoArygAUECajYCvKABECcaQQAoArygASIFIAQgAyAEayIDEEENASAAIAJrIgZBAXUhB0EAIAUgA0EBdSIIQQF0ajYCvKABAkACQAJAECciAEEhRg0AIABBPUcNBEEAKAK8oAEiAC8BAkE9Rw0EIAAvAQRBPUcNBEEAIABBBmo2ArygAQJAECciAEEnRg0AIABBIkcNBQtBACgCvKABIgVBAmpB5ABB5QBB5gBB4QBB9QBB7ABB9AAQI0UNBEEAIAVBEGo2ArygARAnIABHDQRBAEEAKAK8oAFBAmo2ArygARAnQfwARw0EQQAoArygASIALwECQfwARw0EQQAgAEEEajYCvKABECcaQQAoArygASIAIAQgAxBBDQRBACAAIAhBAXRqNgK8oAEQJ0E9Rw0EQQAoArygASIALwECQT1HDQQgAC8BBEE9Rw0EQQAgAEEGajYCvKABAkAQJyIAQSdGDQAgAEEiRw0FC0EAKAK8oAEiBUECakHfAEHfAEHlAEHzAEHNAEHvAEHkAEH1AEHsAEHlABAyRQ0EQQAgBUEWajYCvKABECcgAEcNBEEAQQAoArygAUECajYCvKABECdBKUcNBEEAQQAoArygAUECajYCvKABECdB8gBHDQRBACgCvKABIgBBAmpB5QBB9ABB9QBB8gBB7gAQE0UNBEEAIABBDGo2ArygAQJAECdBO0cNAEEAQQAoArygAUECajYCvKABCxAnIgBB6QBHDQJB6QAhAEEAKAK8oAEiBS8BAkHmAEcNAkEAIAVBBGo2ArygARAnQShHDQRBAEEAKAK8oAFBAmoiADYCvKABAkAgBCAIEDNFDQAQJ0EpRw0FQQBBACgCvKABQQJqNgK8oAEQJ0HyAEcNBUEAKAK8oAEiAEECakHlAEH0AEH1AEHyAEHuABATRQ0FQQAgAEEMajYCvKABAkAQJ0E7Rw0AQQBBACgCvKABQQJqNgK8oAELECciAEHpAEcNA0HpACEAQQAoArygASIFLwECQeYARw0DQQAgBUEEajYCvKABECdBKEcNBUEAKAK8oAFBAmohAAtBACAANgK8oAEgACAEIAMQQQ0EQQAgACAIQQF0ajYCvKABECdB6QBHDQRBACgCvKABIgAvAQJB7gBHDQQgAC8BBEEgRw0EQQAgAEEGajYCvKABECcQMEUNBBAnQSZHDQRBACgCvKABIgAvAQJBJkcNBEEAIABBBGo2ArygARAnEDBFDQQQJ0HbAEcNBEEAQQAoArygAUECajYCvKABECcaQQAoArygASIAIAQgAxBBDQRBACAAIAhBAXRqNgK8oAEQJ0HdAEcNBEEAQQAoArygAUECajYCvKABECdBPUcNBEEAKAK8oAEiAC8BAkE9Rw0EIAAvAQRBPUcNBEEAIABBBmo2ArygARAnGkEAKAK8oAEiACACIAYQQQ0EQQAgACAHQQF0ajYCvKABECdB2wBHDQRBAEEAKAK8oAFBAmo2ArygARAnGkEAKAK8oAEiACAEIAMQQQ0EQQAgACAIQQF0ajYCvKABECdB3QBHDQRBAEEAKAK8oAFBAmo2ArygARAnQSlHDQRBAEEAKAK8oAFBAmo2ArygARAnQfIARw0EQQAoArygASIAQQJqQeUAQfQAQfUAQfIAQe4AEBNFDQRBACAAQQxqNgK8oAEQJ0E7Rw0BQQBBACgCvKABQQJqNgK8oAEMAQtBACgCvKABIgAvAQJBPUcNAyAALwEEQT1HDQNBACAAQQZqNgK8oAECQBAnIgBBJ0YNACAAQSJHDQQLQQAoArygASIFQQJqQeQAQeUAQeYAQeEAQfUAQewAQfQAECNFDQNBACAFQRBqNgK8oAEQJyAARw0DQQBBACgCvKABQQJqNgK8oAECQBAnIgBBJkcNAEEAKAK8oAEiAC8BAkEmRw0EQQAgAEEEajYCvKABECdBIUcNBEEAQQAoArygAUECajYCvKABAkACQBAnIgBBzwBHDQBBACgCvKABQQJqQeIAQeoAQeUAQeMAQfQAQS4QJkUNACAEIAgQM0UNBgwBCyAAEC1FDQAQJ0EuRw0FQQBBACgCvKABQQJqNgK8oAEQJ0HoAEcNBUEAKAK8oAEiAEECakHhAEHzAEHPAEH3AEHuAEHQAEHyAEHvAEHwAEHlAEHyAEH0AEH5ABAvRQ0FQQAgAEEcajYCvKABECdBKEcNBUEAQQAoArygAUECajYCvKABECcaQQAoArygASIAIAQgAxBBDQVBACAAIAhBAXRqNgK8oAEQJ0EpRw0FQQBBACgCvKABQQJqNgK8oAELECchAAsgAEEpRw0DQQBBACgCvKABQQJqNgK8oAELECchAAsCQAJAAkAgABAwRQ0AECdB2wBHDQRBAEEAKAK8oAFBAmo2ArygARAnGkEAKAK8oAEiACAEIAMQQQ0EQQAgACAIQQF0ajYCvKABECdB3QBHDQRBAEEAKAK8oAFBAmo2ArygARAnQT1HDQRBAEEAKAK8oAFBAmo2ArygARAnGkEAKAK8oAEiACACIAYQQQ0EQQAgACAHQQF0ajYCvKABECdB2wBHDQRBAEEAKAK8oAFBAmo2ArygARAnGkEAKAK8oAEiACAEIAMQQQ0EQQAgACAIQQF0ajYCvKABECdB3QBHDQRBAEEAKAK8oAFBAmo2ArygARAnIgBBO0cNAkEAQQAoArygAUECajYCvKABDAELIABBzwBHDQNBACgCvKABIgBBAmpB4gBB6gBB5QBB4wBB9AAQE0UNA0EAIABBDGo2ArygARAnQS5HDQNBAEEAKAK8oAFBAmo2ArygARAnQeQARw0DQQAoArygASIAQQJqQeUAQeYAQekAQe4AQeUAQdAAQfIAQe8AQfAAQeUAQfIAQfQAQfkAEC9FDQNBACAAQRxqNgK8oAEQJ0EoRw0DQQBBACgCvKABQQJqNgK8oAEQJxAwRQ0DECdBLEcNA0EAQQAoArygAUECajYCvKABECcaQQAoArygASIAIAQgAxBBDQNBACAAIAhBAXRqNgK8oAEQJ0EsRw0DQQBBACgCvKABQQJqNgK8oAEQJ0H7AEcNA0EAQQAoArygAUECajYCvKABECdB5QBHDQNBACgCvKABIgBBAmpB7gBB9QBB7QBB5QBB8gBB4QBB4gBB7ABB5QAQMUUNA0EAIABBFGo2ArygARAnQTpHDQNBAEEAKAK8oAFBAmo2ArygARAnIQVBACgCvKABIQACQCAFQfQARg0AIAAvAQJB8gBHDQQgAC8BBEH1AEcNBCAALwEGQeUARw0EC0EAIABBCGo2ArygARAnQSxHDQNBAEEAKAK8oAFBAmo2ArygARAnQecARw0DQQAoArygASIALwECQeUARw0DIAAvAQRB9ABHDQNBACAAQQZqNgK8oAECQBAnIgBBOkcNAEEAQQAoArygAUECajYCvKABECdB5gBHDQRBACgCvKABIgBBAmpB9QBB7gBB4wBB9ABB6QBB7wBB7gAQI0UNBEEAIABBEGoiADYCvKABAkAQJyIFQShGDQAgAEEAKAK8oAFGDQUgBRAtRQ0FCxAnIQALIABBKEcNA0EAQQAoArygAUECajYCvKABECdBKUcNA0EAQQAoArygAUECajYCvKABECdB+wBHDQNBAEEAKAK8oAFBAmo2ArygARAnQfIARw0DQQAoArygASIAQQJqQeUAQfQAQfUAQfIAQe4AEBNFDQNBACAAQQxqNgK8oAEQJxpBACgCvKABIgAgAiAGEEENA0EAIAAgB0EBdGo2ArygARAnQdsARw0DQQBBACgCvKABQQJqNgK8oAEQJxpBACgCvKABIgAgBCADEEENA0EAIAAgCEEBdGo2ArygARAnQd0ARw0DQQBBACgCvKABQQJqNgK8oAECQBAnIgBBO0cNAEEAQQAoArygAUECajYCvKABECchAAsgAEH9AEcNA0EAQQAoArygAUECajYCvKABAkAQJyIAQSxHDQBBAEEAKAK8oAFBAmo2ArygARAnIQALIABB/QBHDQNBAEEAKAK8oAFBAmo2ArygARAnQSlHDQNBAEEAKAK8oAFBAmo2ArygARAnIgBBO0cNAUEAQQAoArygAUECajYCvKABCxAnIQALIABB/QBHDQFBAEEAKAK8oAFBAmo2ArygARAnQSlHDQFBACgCtKABIQRBgCAhAANAAkACQCAEIABGDQAgByAAQQxqKAIAIABBCGooAgAiA2tBAXVHDQEgAiADIAYQQQ0BIAAoAgAgAEEEaigCAEEAKAKgHxEAAEEAIAE2ArygAQsPCyAAQRBqIQAMAAsLIAIgAEEAKAKkHxEAAAtBACABNgK8oAELUwEEf0EAKAK8oAFBAmohAEEAKALAoAEhAQJAA0AgACICQX5qIAFPDQEgAkECaiEAIAIvAQBBdmoiA0EDSw0AIAMOBAEAAAEBCwtBACACNgK8oAELfAECf0EAQQAoArygASIAQQJqNgK8oAEgAEEGaiEAQQAoAsCgASEBA0ACQAJAAkAgAEF8aiABTw0AIABBfmovAQBBKkcNAiAALwEAQS9HDQJBACAAQX5qNgK8oAEMAQsgAEF+aiEAC0EAIAA2ArygAQ8LIABBAmohAAwACwt1AQF/AkACQCAAQV9qIgFBBUsNAEEBIAF0QTFxDQELIABBRmpB//8DcUEGSQ0AIABBWGpB//8DcUEHSSAAQSlHcQ0AAkAgAEGlf2oiAUEDSw0AIAEOBAEAAAEBCyAAQf0ARyAAQYV/akH//wNxQQRJcQ8LQQELPQEBf0EBIQECQCAAQfcAQegAQekAQewAQeUAEDQNACAAQeYAQe8AQfIAEDUNACAAQekAQeYAECshAQsgAQutAQEDf0EBIQECQAJAAkACQAJAAkACQCAALwEAIgJBRWoiA0EDTQ0AIAJBm39qIgNBA00NASACQSlGDQMgAkH5AEcNAiAAQX5qQeYAQekAQe4AQeEAQewAQewAEDYPCyADDgQCAQEFAgsgAw4EAgAAAwILQQAhAQsgAQ8LIABBfmpB5QBB7ABB8wAQNQ8LIABBfmpB4wBB4QBB9ABB4wAQLA8LIABBfmovAQBBPUYL7QMBAn9BACEBAkAgAC8BAEGcf2oiAkETSw0AAkACQAJAAkACQAJAAkACQCACDhQAAQIICAgICAgIAwQICAUIBggIBwALIABBfmovAQBBl39qIgJBA0sNBwJAAkAgAg4EAAkJAQALIABBfGpB9gBB7wAQKw8LIABBfGpB+QBB6QBB5QAQNQ8LIABBfmovAQBBjX9qIgJBAUsNBgJAAkAgAg4CAAEACwJAIABBfGovAQAiAkHhAEYNACACQewARw0IIABBempB5QAQNw8LIABBempB4wAQNw8LIABBfGpB5ABB5QBB7ABB5QAQLA8LIABBfmovAQBB7wBHDQUgAEF8ai8BAEHlAEcNBQJAIABBemovAQAiAkHwAEYNACACQeMARw0GIABBeGpB6QBB7gBB8wBB9ABB4QBB7gAQNg8LIABBeGpB9ABB+QAQKw8LQQEhASAAQX5qIgBB6QAQNw0EIABB8gBB5QBB9ABB9QBB8gAQNA8LIABBfmpB5AAQNw8LIABBfmpB5ABB5QBB4gBB9QBB5wBB5wBB5QAQOA8LIABBfmpB4QBB9wBB4QBB6QAQLA8LAkAgAEF+ai8BACICQe8ARg0AIAJB5QBHDQEgAEF8akHuABA3DwsgAEF8akH0AEHoAEHyABA1IQELIAELhwEBA38DQEEAQQAoArygASIAQQJqIgE2ArygAQJAAkACQCAAQQAoAsCgAU8NACABLwEAIgFBpX9qIgJBAU0NAgJAIAFBdmoiAEEDTQ0AIAFBL0cNBAwCCyAADgQAAwMAAAsQHQsPCwJAAkAgAg4CAQABC0EAIABBBGo2ArygAQwBCxBAGgwACwuVAQEEf0EAKAK8oAEhAUEAKALAoAEhAgJAAkADQCABIgNBAmohASADIAJPDQEgAS8BACIEIABGDQICQCAEQdwARg0AIARBdmoiA0EDSw0BIAMOBAIBAQICCyADQQRqIQEgAy8BBEENRw0AIANBBmogASADLwEGQQpGGyEBDAALC0EAIAE2ArygARAdDwtBACABNgK8oAELOAEBf0EAQQE6APAfQQAoArygASEAQQBBACgCwKABQQJqNgK8oAFBACAAQQAoApgfa0EBdTYC7B8LzgEBBX9BACgCvKABIQBBACgCwKABIQEDQCAAIgJBAmohAAJAAkAgAiABTw0AIAAvAQAiA0Gkf2oiBEEETQ0BIANBJEcNAiACLwEEQfsARw0CQQBBAC8BhEAiAEEBajsBhEBBACgCoGAgAEEBdGpBAC8BiEA7AQBBACACQQRqNgK8oAFBAEEALwGGQEEBaiIAOwGIQEEAIAA7AYZADwtBACAANgK8oAEQHQ8LAkACQCAEDgUBAgICAAELQQAgADYCvKABDwsgAkEEaiEADAALC7YCAQJ/QQBBACgCvKABIgFBDmo2ArygAQJAAkACQBAnIgJB2wBGDQAgAkE9Rg0BIAJBLkcNAkEAQQAoArygAUECajYCvKABECchAkEAKAK8oAEhACACEC1FDQJBACgCvKABIQIQJ0E9Rw0CIAAgAkEAKAKcHxEAAA8LQQBBACgCvKABQQJqNgK8oAECQBAnIgJBJ0YNACACQSJHDQILQQAoArygASEAIAIQHEEAQQAoArygAUECaiICNgK8oAEQJ0HdAEcNAUEAQQAoArygAUECajYCvKABECdBPUcNASAAIAJBACgCnB8RAAAMAQsgAEUNAEEAKAKoHxEBAEEAQQAoArygAUECajYCvKABAkAQJyICQfIARg0AIAJB+wBHDQEQLg8LQQEQEBoLQQAgAUEMajYCvKABCzYBAn9BAEEAKAK8oAFBDGoiADYCvKABECchAQJAAkBBACgCvKABIABHDQAgARA/RQ0BCxAdCwtsAQF/QQBBACgCvKABIgBBDGo2ArygAQJAECdBLkcNAEEAQQAoArygAUECajYCvKABECdB5QBHDQBBACgCvKABQQJqQfgAQfAAQe8AQfIAQfQAQfMAECZFDQBBARAfDwtBACAAQQpqNgK8oAEL6QEBAX9BACEXAkAgAC8BACABRw0AIAAvAQIgAkcNACAALwEEIANHDQAgAC8BBiAERw0AIAAvAQggBUcNACAALwEKIAZHDQAgAC8BDCAHRw0AIAAvAQ4gCEcNACAALwEQIAlHDQAgAC8BEiAKRw0AIAAvARQgC0cNACAALwEWIAxHDQAgAC8BGCANRw0AIAAvARogDkcNACAALwEcIA9HDQAgAC8BHiAQRw0AIAAvASAgEUcNACAALwEiIBJHDQAgAC8BJCATRw0AIAAvASYgFEcNACAALwEoIBVHDQAgAC8BKiAWRiEXCyAXC1MBAX9BACEIAkAgAC8BACABRw0AIAAvAQIgAkcNACAALwEEIANHDQAgAC8BBiAERw0AIAAvAQggBUcNACAALwEKIAZHDQAgAC8BDCAHRiEICyAIC6QBAQR/QQBBACgCvKABIgBBDGoiATYCvKABAkACQAJAAkACQBAnIgJBWWoiA0EHTQ0AIAJBIkYNAiACQfsARg0CDAELAkAgAw4IAgABAgEBAQMCC0EAQQAvAYZAIgNBAWo7AYZAQQAoArCgASADQQJ0aiAANgIADwtBACgCvKABIAFGDQILQQAvAYZARQ0AQQBBACgCvKABQX5qNgK8oAEPCxAdCws0AQF/QQEhAQJAIABBd2pB//8DcUEFSQ0AIABBgAFyQaABRg0AIABBLkcgABA/cSEBCyABC0kBAX9BACEHAkAgAC8BACABRw0AIAAvAQIgAkcNACAALwEEIANHDQAgAC8BBiAERw0AIAAvAQggBUcNACAALwEKIAZGIQcLIAcLegEDf0EAKAK8oAEhAAJAA0ACQCAALwEAIgFBd2pBBUkNACABQSBGDQAgAUGgAUYNACABQS9HDQICQCAALwECIgBBKkYNACAAQS9HDQMQFQwBCxAWC0EAQQAoArygASICQQJqIgA2ArygASACQQAoAsCgAUkNAAsLIAELOQEBfwJAIAAvAQAiAUGA+ANxQYC4A0cNACAAQX5qLwEAQf8HcUEKdCABQf8HcXJBgIAEaiEBCyABC30BAX8CQCAAQS9LDQAgAEEkRg8LAkAgAEE6SQ0AQQAhAQJAIABBwQBJDQAgAEHbAEkNAQJAIABB4ABLDQAgAEHfAEYPCyAAQfsASQ0BAkAgAEH//wNLDQAgAEGqAUkNASAAEDkPC0EBIQEgABA6DQAgABA7IQELIAEPC0EBC2MBAX8CQCAAQcAASw0AIABBJEYPC0EBIQECQCAAQdsASQ0AAkAgAEHgAEsNACAAQd8ARg8LIABB+wBJDQACQCAAQf//A0sNAEEAIQEgAEGqAUkNASAAEDwPCyAAEDohAQsgAQtMAQN/QQAhAwJAIABBfmoiBEEAKAKYHyIFSQ0AIAQvAQAgAUcNACAALwEAIAJHDQACQCAEIAVHDQBBAQ8LIABBfGovAQAQJSEDCyADC2YBA39BACEFAkAgAEF6aiIGQQAoApgfIgdJDQAgBi8BACABRw0AIABBfGovAQAgAkcNACAAQX5qLwEAIANHDQAgAC8BACAERw0AAkAgBiAHRw0AQQEPCyAAQXhqLwEAECUhBQsgBQuFAQECfyAAED4iABAqIQECQAJAIABB3ABGDQBBACECIAFFDQELQQAoArygAUECQQQgAEGAgARJG2ohAAJAA0BBACAANgK8oAEgAC8BABA+IgFFDQECQCABEClFDQAgAEECQQQgAUGAgARJG2ohAAwBCwtBACECIAFB3ABGDQELQQEhAgsgAgvaAwEEf0EAKAK8oAEiAEF+aiEBA0BBACAAQQJqNgK8oAECQAJAAkAgAEEAKALAoAFPDQAQJyEAQQAoArygASECAkACQCAAEC1FDQBBACgCvKABIQMCQAJAECciAEE6Rw0AQQBBACgCvKABQQJqNgK8oAEQJxAtRQ0BQQAoArygAS8BACEACyACIANBACgCnB8RAAAMAgtBACABNgK8oAEPCwJAAkAgAEEiRg0AIABBLkYNASAAQSdHDQQLQQAoArygASECIAAQHEEAQQAoArygAUECaiIDNgK8oAEQJyIAQTpHDQFBAEEAKAK8oAFBAmo2ArygAQJAECcQLUUNAEEAKAK8oAEvAQAhACACIANBACgCnB8RAAAMAgtBACABNgK8oAEPC0EAKAK8oAEiAC8BAkEuRw0CIAAvAQRBLkcNAkEAIABBBmo2ArygAQJAAkACQCAALwEGIgBB8gBHDQBBARAQIQBBACgCvKABIQIgAA0BIAIvAQAhAAsgAEH//wNxEC0NAUEAIAE2ArygAQ8LQQAgAkECajYCvKABCxAnIQALIABB//8DcSIAQSxGDQIgAEH9AEYNAEEAIAE2ArygAQsPC0EAIAE2ArygAQ8LQQAoArygASEADAALC48BAQF/QQAhDgJAIAAvAQAgAUcNACAALwECIAJHDQAgAC8BBCADRw0AIAAvAQYgBEcNACAALwEIIAVHDQAgAC8BCiAGRw0AIAAvAQwgB0cNACAALwEOIAhHDQAgAC8BECAJRw0AIAAvARIgCkcNACAALwEUIAtHDQAgAC8BFiAMRw0AIAAvARggDUYhDgsgDguoAQECf0EAIQFBACgCvKABIQICQAJAIABB7QBHDQAgAkECakHvAEHkAEH1AEHsAEHlABATRQ0BQQAgAkEMajYCvKABAkAQJ0EuRg0AQQAhAQwCC0EAQQAoArygAUECajYCvKABECchAAsgAEHlAEcNAEEAKAK8oAEiAEEOaiACIABBAmpB+ABB8ABB7wBB8gBB9ABB8wAQJiIBGyECC0EAIAI2ArygASABC2cBAX9BACEKAkAgAC8BACABRw0AIAAvAQIgAkcNACAALwEEIANHDQAgAC8BBiAERw0AIAAvAQggBUcNACAALwEKIAZHDQAgAC8BDCAHRw0AIAAvAQ4gCEcNACAALwEQIAlGIQoLIAoLcQEBf0EAIQsCQCAALwEAIAFHDQAgAC8BAiACRw0AIAAvAQQgA0cNACAALwEGIARHDQAgAC8BCCAFRw0AIAAvAQogBkcNACAALwEMIAdHDQAgAC8BDiAIRw0AIAAvARAgCUcNACAALwESIApGIQsLIAsLgwQBAn9BACECAkAQJ0HPAEcNAEEAIQJBACgCvKABIgNBAmpB4gBB6gBB5QBB4wBB9AAQE0UNAEEAIQJBACADQQxqNgK8oAEQJ0EuRw0AQQBBACgCvKABQQJqNgK8oAECQBAnIgNB8ABHDQBBACECQQAoArygASIDQQJqQfIAQe8AQfQAQe8AQfQAQfkAQfAAQeUAED1FDQFBACECQQAgA0ESajYCvKABECdBLkcNAUEAQQAoArygAUECajYCvKABECchAwtBACECIANB6ABHDQBBACECQQAoArygASIDQQJqQeEAQfMAQc8AQfcAQe4AQdAAQfIAQe8AQfAAQeUAQfIAQfQAQfkAEC9FDQBBACECQQAgA0EcajYCvKABECdBLkcNAEEAIQJBAEEAKAK8oAFBAmo2ArygARAnQeMARw0AQQAhAkEAKAK8oAEiAy8BAkHhAEcNACADLwEEQewARw0AIAMvAQZB7ABHDQBBACECQQAgA0EIajYCvKABECdBKEcNAEEAIQJBAEEAKAK8oAFBAmo2ArygARAnEC1FDQAQJ0EsRw0AQQAhAkEAQQAoArygAUECajYCvKABECcaQQAoArygASIDIAAgAUEBdCIBEEENAEEAIQJBACADIAFqNgK8oAEQJ0EpRw0AQQBBACgCvKABQQJqNgK8oAFBASECCyACC0kBA39BACEGAkAgAEF4aiIHQQAoApgfIghJDQAgByABIAIgAyAEIAUQE0UNAAJAIAcgCEcNAEEBDwsgAEF2ai8BABAlIQYLIAYLWQEDf0EAIQQCQCAAQXxqIgVBACgCmB8iBkkNACAFLwEAIAFHDQAgAEF+ai8BACACRw0AIAAvAQAgA0cNAAJAIAUgBkcNAEEBDwsgAEF6ai8BABAlIQQLIAQLSwEDf0EAIQcCQCAAQXZqIghBACgCmB8iCUkNACAIIAEgAiADIAQgBSAGECZFDQACQCAIIAlHDQBBAQ8LIABBdGovAQAQJSEHCyAHCz0BAn9BACECAkBBACgCmB8iAyAASw0AIAAvAQAgAUcNAAJAIAMgAEcNAEEBDwsgAEF+ai8BABAlIQILIAILTQEDf0EAIQgCQCAAQXRqIglBACgCmB8iCkkNACAJIAEgAiADIAQgBSAGIAcQI0UNAAJAIAkgCkcNAEEBDwsgAEFyai8BABAlIQgLIAgL+RIBA38CQCAAEDwNACAAQfS/f2pBAkkNACAAQbcBRg0AIABBgHpqQfAASQ0AIABB/XZqQQVJDQAgAEGHB0YNACAAQe90akEtSQ0AAkAgAEHBdGoiAUEISw0AQQEgAXRB7QJxDQELIABB8HNqQQtJDQAgAEG1c2pBH0kNAAJAIABBqnJqIgFBEksNAEEBIAF0Qf/8GXENAQsgAEHwDEYNACAAQZZyakEESQ0AIABBwHBqQQpJDQAgAEHacGpBC0kNACAAQdBxakEbSQ0AIABBkQ5GDQAgAEGQcmpBCkkNACAAQcJtakESSQ0AIABBxm1qQQNJDQAgAEGdbmpBIUkNACAAQa1uakEPSQ0AIABBp29qQQNJDQAgAEHXb2pBBUkNACAAQdtvakEDSQ0AIABB5W9qQQlJDQAgAEHqb2pBBEkNACAAQf0PRg0AIABBlXBqQQlJDQACQCAAQa9taiIBQRJLDQBBASABdEH/gBhxDQELIABBmm1qQQpJDQACQAJAIABBxGxqIgFBJ00NACAAQf9sakEDSQ0CDAELIAEOKAEAAQEBAQEBAQAAAQEAAAEBAQAAAAAAAAAAAAEAAAAAAAAAAAAAAQEBCyAAQf4TRg0AIABBmmxqQQpJDQACQCAAQcRraiIBQRVLDQBBASABdEH9sI4BcQ0BCyAAQf9rakEDSQ0AIABB9RRGDQAgAEGaa2pBDEkNAAJAAkAgAEHEamoiAUEnTQ0AIABB/2pqQQNJDQIMAQsgAQ4oAQABAQEBAQEBAQABAQEAAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAABAQELIABBmmpqQQpJDQAgAEGGampBBkkNAAJAAkAgAEHEaWoiAUEnTQ0AIABB/2lqQQNJDQIMAQsgAQ4oAQABAQEBAQEBAAABAQAAAQEBAAAAAAAAAAABAQAAAAAAAAAAAAABAQELIABBmmlqQQpJDQACQCAAQcJoaiIBQRlLDQBBASABdEGf7oMQcQ0BCyAAQYIXRg0AIABBmmhqQQpJDQACQAJAIABBwmdqIgFBJU0NACAAQYBoakEFSQ0CDAELIAEOJgEBAQEBAQEAAQEBAAEBAQEAAAAAAAAAAQEAAAAAAAAAAAAAAAEBAQsgAEGaZ2pBCkkNAAJAAkAgAEHEZmoiAUEnTQ0AIABB/2ZqQQNJDQIMAQsgAQ4oAQABAQEBAQEBAAEBAQABAQEBAAAAAAAAAAEBAAAAAAAAAAAAAAABAQELIABBmmZqQQpJDQAgAEF8cSICQYAaRg0AAkAgAEHFZWoiAUEoSw0AIAEOKQEBAAEBAQEBAQEAAQEBAAEBAQEAAAAAAAAAAAABAAAAAAAAAAAAAAEBAQsgAEGaZWpBCkkNAAJAIABBtmRqIgFBDEsNAEEBIAF0QeEvcQ0BCyAAQf5kakECSQ0AIABBeHFB2BtGDQAgAEGaZGpBCkkNAAJAIABBz2NqIgFBHUsNAEEBIAF0QfmHgP4DcQ0BCyAAQY5kakECSQ0AIABBsR1GDQAgAEGwY2pBCkkNAAJAIABBzGJqIgFBCEsNACABQQZHDQELIABBuGJqQQZJDQAgAEHgYWpBCkkNACAAQQFyIgFBmR5GDQAgAEGwYmpBCkkNAAJAIABBy2FqIgNBCksNAEEBIAN0QZUMcQ0BCyAAQfNgakELSQ0AIAFBhx9GDQAgAEGPYWpBFEkNACAAQe5RakEDSQ0AIABBl1lqQQlJDQAgAEGjWWpBA0kNACAAQfFeakEPSQ0AIABB/l5qQQxJDQAgAEGPX2pBBEkNACAAQZlfakEHSQ0AIABBnl9qQQNJDQAgAEGiX2pBA0kNACAAQapfakEESQ0AIABBwF9qQQpJDQAgAEHVX2pBFEkNACAAQcYfRg0AIABB52BqQSRJDQAgAEHOUWpBA0kNACAAQa5RakECSQ0AIABBjlFqQQJJDQAgAEH1T2pBA0kNACAAQaBQakEKSQ0AIABB3S9GDQAgAEHMUGpBIEkNACAAQbBGakEDSQ0AIABBsEdqQQpJDQAgAEHAR2pBCkkNACAAQdxHakEUSQ0AIABBmkhqQQ5JDQAgAEHQSGpBCkkNACAAQd9IakENSQ0AIABBgElqQQNJDQAgAEGVSWpBCUkNACAAQbBJakEKSQ0AIABBzElqQRFJDQAgAEGASmpBBUkNACAAQdBKakEOSQ0AIABB8EpqQQpJDQAgAEGBS2pBC0kNACAAQaBLakEdSQ0AIABBq0tqQQpJDQAgAEHpS2pBBUkNACAAQbBMakELSQ0AIABBuk1qQQpJDQAgAEHQTWpBDEkNACAAQeBNakEMSQ0AIABBqTFGDQAgAEHwT2pBCkkNACAAQcBEakE6SQ0AIABBiUZqQQNJDQAgAEGORmpBA0kNACAAQe05Rg0AIABBrEZqQRVJDQAgAEGFRGpBBUkNAAJAIABBwb9/aiIBQRVLDQBBASABdEGDgIABcQ0BCyAAQZu+f2pBDEkNACAAQeHBAEYNACAAQbC+f2pBDUkNACAAQZGmf2pBA0kNACAAQf/aAEYNACAAQWBxQeDbAEYNACAAQdaff2pBBkkNACAAQeeef2pBAkkNACAAQYyzfWpBCkkNACAAQe/MAkYNACAAQeCzfWpBCkkNAAJAIABB9a99aiIBQRxLDQBBASABdEGBgID4AXENAQsgAEHisn1qQQJJDQAgAEGQsn1qQQJJDQACQAJAIABB/q99aiIBQQRNDQAgAEGAr31qQQJJDQIMAQsgAQ4FAQAAAAEBCyAAQc2sfWpBDkkNACACQYDTAkYNACAAQbmtfWpBDUkNACAAQdqtfWpBCEkNACAAQYGufWpBC0kNACAAQaCufWpBEkkNACAAQcyufWpBEkkNACAAQbCufWpBCkkNACAAQderfWpBDkkNACAAQeXTAkYNACAAQV9xQbCsfWpBCkkNAAJAIABBvat9aiIBQQpLDQBBASABdEGBDHENAQsgAEGwq31qQQpJDQACQCAAQZ2ofWoiAUEKSw0AIAFBCEcNAQsCQCAAQdCqfWoiAUERSw0AQQEgAXRBnYMLcQ0BCwJAIABBlap9aiIBQQtLDQBBASABdEGfGHENAQsgAEGFq31qQQNJDQAgAEFwcSIBQYD8A0YNACAAQZ72A0YNACAAQZCofWpBCkkNACAAQb/+A0YgAEHwgXxqQQpJIABBs4N8akEDSSAAQc2DfGpBAkkgAUGg/ANGcnJycg8LQQELXAEEf0GAgAQhAUGQCCECQX4hAwJAA0BBACEEIANBAmoiA0HnA0sNASACKAIAIAFqIgEgAEsNASACQQRqIQQgAkEIaiECIAQoAgAgAWoiASAASQ0AC0EBIQQLIAQLXAEEf0GAgAQhAUGwFyECQX4hAwJAA0BBACEEIANBAmoiA0H5AUsNASACKAIAIAFqIgEgAEsNASACQQRqIQQgAkEIaiECIAQoAgAgAWoiASAASQ0AC0EBIQQLIAQL7R8BBn9BASEBAkACQAJAIABB1n5qIgJBEEsNAEEBIAJ0QYGQBHENAQsgAEG6empBDEkNACAAQYh+akHKA0kNACAAQcB+akEXSQ0AIABBqH5qQR9JDQACQCAAQZB5aiICQRxLDQBBASACdEHf+YK6AXENAQsCQCAAQaB6aiICQQ5LDQBBASACdEGfoAFxDQELIABB9nZqQaYBSQ0AIABBiXhqQYsBSQ0AIABB8nhqQRRJDQAgAEHdeGpB0wBJDQAgAEGRdGpBBEkNACAAQbB0akEbSQ0AIABBoHVqQSlJDQAgAEHZCkYNACAAQc91akEmSQ0AAkACQAJAIABBj3NqQeMASQ0AIABBAXIiAkHvDEYNACAAQeBzakErSQ0AAkAgAEGrcmoiAUE8Tw0AQoGAjLCAnIGACCABrYhCAYNQRQ0BCyAAQe5xakEeSQ0AIABBtnBqQSFJDQAgAEGxD0YNACAAQbNxakHZAEkNAAJAIABBjHBqIgFBBksNAEEBIAF0QcMAcQ0BCyAAQYBwakEWSQ0AAkACQCAAQdxvaiIDQQRNDQAgAEGaEEYNAgwBC0EBIQEgAw4FBAAAAAQECyAAQfxtakE2SQ0AIABBym5qQQhJDQAgAEHgbmpBFUkNACAAQcBvakEZSQ0AIABBoG9qQQtJDQAgAEG9EkYNACAAQdASRg0AIABBqG1qQQpJDQAgAEGPbWpBEEkNAAJAIABB+2xqIgNBDE8NAEEBIQFB/xkgA0H//wNxdkEBcQ0ECyAAQe1sakEWSQ0AAkAgAEGEbGoiAUEUSw0AQQEgAXRBgfzhAHENAQsgAEHWbGpBB0kNAAJAIABBzmxqIgFBHEsNAEEBIAF0QfGRgIABcQ0BCwJAIABBpGxqIgFBFUsNAEEBIAF0QbuAwAFxDQELIABB7WtqQRZJDQACQCAAQdZraiIBQTVPDQBC/7aDgICA4AsgAa2IQgGDUEUNAQsgAEHtampBFkkNACAAQfFqakEDSQ0AIABBjmtqQQNJDQAgAEH7ampBCUkNAAJAAkACQCAAQdZqaiIDQSZNDQAgAEGHamoiAUEXSw0BQQEgAXRBgeC/BnFFDQEMAwtBASEBIAMOJwUFBQUFBQUBBQUBBQUFBQUBAQEFAQEBAQEBAQEBAQEBAQEBAQEBBQULIABBoGpqQQJJDQELIABB7WlqQRZJDQACQAJAAkAgAEGPaWoiA0EzTQ0AIABB1mlqIgFBE0sNAUEBIAF0Qf/2I3FFDQEMAwtBASEBIAMONAUBAQEBAQEBAQEBAQEBAQEBAQUBBQUFBQUFAQEBBQUFAQUFBQUBAQEFBQEFAQUFAQEBBQUFCyAAQaRpaiIBQQVLDQAgAUECRw0BCyAAQdhoakEDSQ0AIABB7mdqQRdJDQAgAEHyZ2pBA0kNACAAQftnakEISQ0AIABB0BdGDQAgAEHSaGpBDEkNACAAQb0YRg0AIABB1mdqQRBJDQACQCAAQahnaiIBQSlPDQBCh4aAgIAgIAGtiEIBg1BFDQELIABB1mZqQQpJDQAgAEHuZmpBF0kNACAAQftmakEISQ0AIABB8mZqQQNJDQACQCAAQftlaiIBQQtLDQAgAUEIRw0BCwJAIABBy2ZqIgFBCEsNAEEBIAF0QZ8CcQ0BCwJAIABBomZqIgFBFEsNAEEBIAF0QY2A4ABxDQELIABB7mVqQSlJDQAgAEG9GkYNACAAQc4aRg0AIABBzWRqQQlJDQAgAEHmZGpBGEkNACAAQftkakESSQ0AIABBhmVqQQZJDQAgAEGsZWpBA0kNACAAQaFlakEDSQ0AAkAgAEHDZGoiA0EKTw0AQQEhAUH5ByADQf//A3F2QQFxDQQLIAJBsxxGDQAgAEH/Y2pBMEkNACAAQcBjakEHSQ0AAkAgAEH/YmoiAUEMSw0AQQEgAXRByyVxDQELIABBfHEiA0GUHUYNACAAQediakEHSQ0AAkAgAEHfYmoiAUEmTw0AQtfsm4D5BSABrYhCAYNQRQ0BCyAAQYBgakErSQ0AIABB+GBqQQVJDQAgAEG3YWpBJEkNACAAQXhxIgRBwB5GDQAgAEGAHkYNACADQdwdRg0AAkAgAEHBX2oiAUEoTw0AQoGA+MPHGCABrYhCAYNQRQ0BCyAAQZJfakEDSQ0AIABB4F5qQSZJDQAgAEGOIUYNACAAQYtfakENSQ0AIABBxyFGDQAgAEHNIUYNACAAQbZbakEESQ0AIABBsF5qQStJDQAgAEGEXmpBzQJJDQACQCAAQbBbaiIFQQlPDQBBASEBQf8CIAVB//8DcXZBAXENBAsgAEHOWmpBBEkNACAAQfBaakEhSQ0AIABB9lpqQQRJDQAgAEGmW2pBBEkNACAAQaBbakEpSQ0AAkAgAEHIWmoiBUEJTw0AQQEhAUH/AiAFQf//A3F2QQFxDQQLIABBgFFqQTRJDQAgAEGSUWpBA0kNACAAQaBRakENSQ0AIABBwFFqQRJJDQAgAEHgUWpBEkkNACAAQfJRakEESQ0AIABBgFJqQQ1JDQAgAEGSUmpBC0kNACAAQeBSakHLAEkNACAAQf9SakEaSQ0AIABBkVNqQRFJDQAgAEH/V2pB7ARJDQAgAEGIWGpBBkkNACAAQeBYakHWAEkNACAAQXBxIgVBgCdGDQAgAEHoWWpBwwBJDQAgAEHuWWpBBEkNACAAQahaakE5SQ0AIABBvlpqQQRJDQAgAEG4WmpBD0kNACAAQdcvRg0AIABB3C9GDQAgAEHgT2pB2QBJDQAgAEGATGpBF0kNACAAQdBMakEaSQ0AIABBgE1qQSxJDQAgAEGQTWpBBUkNACAAQbBNakEeSQ0AIABBgE5qQR9JDQAgAEHQTmpBxgBJDQAgAEGqMUYNBCAAQYBPakEpSQ0EIABBu0lqQQdJDQQgAEH7SWpBL0kNBCAAQac1Rg0EIABB4EtqQTVJDQQgAEGXRmpBBEkNBCAAQcNGakEDSQ0EIABB8EZqQStJDQQgAEGAR2pBCUkNBCAAQaZHakEkSQ0EIABBs0dqQQNJDQQgAEGASGpBJEkNBCAAQcZIakEsSQ0EIAJBrzdGDQQgAEH9SGpBHkkNBCAAQZJGaiIGQQlJDQEMAgtBASEBDAILQQEhAUGPAyAGQf//A3F2QQFxDQELIARB0D5GDQEgAEG4QWpBBkkNASAAQeBBakEmSQ0BIABB6EFqQQZJDQEgAEGARmpBwAFJDQEgAEGARGpBlgJJDQECQCAAQadBaiIBQQRLDQBBASABdEEVcQ0CCyAAQaFBakEfSQ0BIABBgEFqQTVJDQECQCAAQcpAaiIEQQlPDQBBASEBQf8CIARB//8DcXZBAXENAQsgAEGOQGpBA0kNASAAQaBAakENSQ0BIABBqkBqQQZJDQEgA0HQP0YNASAAQb5AakEDSQ0BIABBukBqQQdJDQEgAEGKQGpBB0kNASAAQfHAAEYNASAAQf/AAEYNASAAQfC+f2pBDUkNASAAQYLCAEYNASAAQYfCAEYNASAAQZXCAEYNASAAQfa9f2pBCkkNAQJAIABB6L1/aiIEQRFPDQBBASEBQb+gBSAEdkEBcQ0BCyAAQda9f2pBEEkNASADQbzCAEYNAQJAIABBu71/aiIEQQpPDQBBASEBQZ8EIARB//8DcXZBAXENAQsgAEGgp39qQYUBSQ0BIABB0Kd/akEvSQ0BIABBoL1/akEpSQ0BIABBgKh/akEvSQ0BAkAgAEGVpn9qIgRBCU8NAEEBIQFBjwMgBEH//wNxdkEBcQ0BCyAAQYCmf2pBJkkNASAAQafaAEYNASAAQa3aAEYNASAAQYC2fWpBjQJJDQEgAEGwtn1qQS5JDQEgAEGAwH1qQY0JSQ0BIABBgOR+akHwowFJDQEgAEGAmH9qQbYzSQ0BIAVB8OMARg0BIABB4Jx/akEbSQ0BIABBz51/akHeAEkNASAAQfudf2pBK0kNASADQfzhAEYNASAAQd+ef2pB2gBJDQEgAEHlnn9qQQVJDQEgAEG/n39qQdYASQ0BIABByJ9/akEFSQ0BIABBz59/akEFSQ0BIABB359/akEJSQ0BIABB+59/akEDSQ0BIABBqKR/akEHSQ0BIABBsKR/akEHSQ0BIABBuKR/akEHSQ0BIABBwKR/akEHSQ0BIABByKR/akEHSQ0BIABB0KR/akEHSQ0BIABB2KR/akEHSQ0BIABB4KR/akEHSQ0BIABBgKV/akEXSQ0BIABB79oARg0BIABB0KV/akE4SQ0BIABB/q59akEySQ0BIABBwK99akE0SQ0BIABB9K99akEXSQ0BIABB+a99akEESQ0BIABB/a99akEDSQ0BIABBibB9akELSQ0BIABB9bB9akEvSQ0BIABB3rF9akHnAEkNASAAQemxfWpBCUkNASAAQeCyfWpB0ABJDQEgAEGBs31qQR9JDQEgAEHAs31qQS9JDQEgAkGrzAJGDQEgBUGQzAJGDQECQCAAQY6ufWoiAkENTw0AQQEhAUG/NCACQf//A3F2QQFxDQELIABBoK19akEdSQ0BIABB9q19akEcSQ0BIABB0K19akEXSQ0BIABBvKt9akEISQ0BIABBwKt9akEDSQ0BIABBgKx9akEpSQ0BIABBhqx9akEFSQ0BIABBmqx9akEKSQ0BIABBoKx9akEFSQ0BIABBz9MCRg0BIABB/Kx9akEvSQ0BIABBgqt9akEySQ0BIABB+tQCRg0BIABBoKt9akEXSQ0BAkAgAEHPqn1qIgJBEk8NAEEBIQFBsb4KIAJ2QQFxDQELIABBgIp8akEHSQ0BIABBkIt8akHqAEkNASAAQYCOfGpB7gJJDQEgAEG10HxqQTFJDQEgAEHQ0HxqQRdJDQEgAEGAqH1qQaTXAEkNASAAQZCpfWpB8wBJDQEgAEGkqX1qQQpJDQEgAEHQqX1qQStJDQEgAEHYqX1qQQdJDQEgAEHgqX1qQQdJDQEgAEHvqX1qQQZJDQEgAEF3cUH/qX1qQQZJDQEgAEGOqn1qQQNJDQEgAEGlqn1qQQNJDQEgAEGgqn1qQQtJDQECQCAAQe2JfGoiAkELTw0AQQEhAUGfCCACQf//A3F2QQFxDQELIABB4Yl8akEKSQ0BIABB1ol8akENSQ0BAkAgAEHIiXxqIgJBDU8NAEEBIQFB3zYgAkH//wNxdkEBcQ0BCyAAQa6AfGpBBkkNASAAQbaAfGpBBkkNASAAQb6AfGpBBkkNASAAQZqBfGpB2QBJDQEgAEG/gXxqQRpJDQEgAEHfgXxqQRpJDQEgAEGKg3xqQYcBSQ0BIABBkIN8akEFSQ0BIABBkIR8akEMSQ0BIABB7oR8akE2SQ0BIABBsIV8akHAAEkNASAAQbqJfGpB7ABJDQFBASEBIABBrYh8akHrAkkNACAAQaaAfGpBA0kPCyABDwtBAQtdAQF/QQAhCQJAIAAvAQAgAUcNACAALwECIAJHDQAgAC8BBCADRw0AIAAvAQYgBEcNACAALwEIIAVHDQAgAC8BCiAGRw0AIAAvAQwgB0cNACAALwEOIAhGIQkLIAkLNQACQCAAQYD4A3FBgLADRw0AIABBCnRBgPg/cUEAKAK8oAEvAQJB/wdxckGAgARqIQALIAALaAECf0EBIQECQAJAIABBX2oiAkEFSw0AQQEgAnRBMXENAQsgAEH4/wNxQShGDQAgAEFGakH//wNxQQZJDQACQCAAQaV/aiICQQNLDQAgAkEBRw0BCyAAQYV/akH//wNxQQRJIQELIAELjQEBBX9BACgCvKABIQBBACgCwKABIQEDfyAAQQJqIQICQAJAIAAgAU8NACACLwEAIgNBpH9qIgRBAU0NASACIQAgA0F2aiIDQQNLDQIgAiEAIAMOBAACAgAAC0EAIAI2ArygARAdQQAPCwJAAkAgBA4CAQABC0EAIAI2ArygAUHdAA8LIABBBGohAAwACwtJAQN/QQAhAwJAIAJFDQACQANAIAAtAAAiBCABLQAAIgVHDQEgAUEBaiEBIABBAWohACACQX9qIgINAAwCCwsgBCAFayEDCyADCwvCFwIAQYAIC5gXAAAAAAAAAAAAAAAAAAAAAAAAAAALAAAAAgAAABkAAAACAAAAEgAAAAIAAAABAAAAAgAAAA4AAAADAAAADQAAACMAAAB6AAAARgAAADQAAAAMAQAAHAAAAAQAAAAwAAAAMAAAAB8AAAAOAAAAHQAAAAYAAAAlAAAACwAAAB0AAAADAAAAIwAAAAUAAAAHAAAAAgAAAAQAAAArAAAAnQAAABMAAAAjAAAABQAAACMAAAAFAAAAJwAAAAkAAAAzAAAAnQAAADYBAAAKAAAAFQAAAAsAAAAHAAAAmQAAAAUAAAADAAAAAAAAAAIAAAArAAAAAgAAAAEAAAAEAAAAAAAAAAMAAAAWAAAACwAAABYAAAAKAAAAHgAAAEIAAAASAAAAAgAAAAEAAAALAAAAFQAAAAsAAAAZAAAARwAAADcAAAAHAAAAAQAAAEEAAAAAAAAAEAAAAAMAAAACAAAAAgAAAAIAAAAcAAAAKwAAABwAAAAEAAAAHAAAACQAAAAHAAAAAgAAABsAAAAcAAAANQAAAAsAAAAVAAAACwAAABIAAAAOAAAAEQAAAG8AAABIAAAAOAAAADIAAAAOAAAAMgAAAA4AAAAjAAAAXQEAACkAAAAHAAAAAQAAAE8AAAAcAAAACwAAAAAAAAAJAAAAFQAAAGsAAAAUAAAAHAAAABYAAAANAAAANAAAAEwAAAAsAAAAIQAAABgAAAAbAAAAIwAAAB4AAAAAAAAAAwAAAAAAAAAJAAAAIgAAAAQAAAAAAAAADQAAAC8AAAAPAAAAAwAAABYAAAAAAAAAAgAAAAAAAAAkAAAAEQAAAAIAAAAYAAAAVQAAAAYAAAACAAAAAAAAAAIAAAADAAAAAgAAAA4AAAACAAAACQAAAAgAAAAuAAAAJwAAAAcAAAADAAAAAQAAAAMAAAAVAAAAAgAAAAYAAAACAAAAAQAAAAIAAAAEAAAABAAAAAAAAAATAAAAAAAAAA0AAAAEAAAAnwAAADQAAAATAAAAAwAAABUAAAACAAAAHwAAAC8AAAAVAAAAAQAAAAIAAAAAAAAAuQAAAC4AAAAqAAAAAwAAACUAAAAvAAAAFQAAAAAAAAA8AAAAKgAAAA4AAAAAAAAASAAAABoAAADmAAAAKwAAAHUAAAA/AAAAIAAAAAcAAAADAAAAAAAAAAMAAAAHAAAAAgAAAAEAAAACAAAAFwAAABAAAAAAAAAAAgAAAAAAAABfAAAABwAAAAMAAAAmAAAAEQAAAAAAAAACAAAAAAAAAB0AAAAAAAAACwAAACcAAAAIAAAAAAAAABYAAAAAAAAADAAAAC0AAAAUAAAAAAAAACMAAAA4AAAACAEAAAgAAAACAAAAJAAAABIAAAAAAAAAMgAAAB0AAABxAAAABgAAAAIAAAABAAAAAgAAACUAAAAWAAAAAAAAABoAAAAFAAAAAgAAAAEAAAACAAAAHwAAAA8AAAAAAAAASAEAABIAAAC+AAAAAAAAAFAAAACZAwAAZwAAAG4AAAASAAAAwwAAAL0KAAAuBAAA0g8AAEYCAAC6IQAAOAIAAAgAAAAeAAAAcgAAAB0AAAATAAAALwAAABEAAAADAAAAIAAAABQAAAAGAAAAEgAAALECAAA/AAAAgQAAAEoAAAAGAAAAAAAAAEMAAAAMAAAAQQAAAAEAAAACAAAAAAAAAB0AAAD3FwAACQAAANUEAAArAAAACAAAAPgiAAAeAQAAMgAAAAIAAAASAAAAAwAAAAkAAACLAQAABQkAAGoAAAAGAAAADAAAAAQAAAAIAAAACAAAAAkAAABnFwAAVAAAAAIAAABGAAAAAgAAAAEAAAADAAAAAAAAAAMAAAABAAAAAwAAAAMAAAACAAAACwAAAAIAAAAAAAAAAgAAAAYAAAACAAAAQAAAAAIAAAADAAAAAwAAAAcAAAACAAAABgAAAAIAAAAbAAAAAgAAAAMAAAACAAAABAAAAAIAAAAAAAAABAAAAAYAAAACAAAAUwEAAAMAAAAYAAAAAgAAABgAAAACAAAAHgAAAAIAAAAYAAAAAgAAAB4AAAACAAAAGAAAAAIAAAAeAAAAAgAAABgAAAACAAAAHgAAAAIAAAAYAAAAAgAAAAcAAAA1CQAALAAAAAsAAAAGAAAAEQAAAAAAAAByAQAAKwAAABUFAADEAAAAPAAAAEMAAAAIAAAAAAAAALUEAAADAAAAAgAAABoAAAACAAAAAQAAAAIAAAAAAAAAAwAAAAAAAAACAAAACQAAAAIAAAADAAAAAgAAAAAAAAACAAAAAAAAAAcAAAAAAAAABQAAAAAAAAACAAAAAAAAAAIAAAAAAAAAAgAAAAIAAAACAAAAAQAAAAIAAAAAAAAAAwAAAAAAAAACAAAAAAAAAAIAAAAAAAAAAgAAAAAAAAACAAAAAAAAAAIAAAABAAAAAgAAAAAAAAADAAAAAwAAAAIAAAAGAAAAAgAAAAMAAAACAAAAAwAAAAIAAAAAAAAAAgAAAAkAAAACAAAAEAAAAAYAAAACAAAAAgAAAAQAAAACAAAAEAAAAEURAADdpgAAIwAAADQQAAAMAAAA3QAAAAMAAACBFgAADwAAADAdAAAgDAAAHQIAAOMFAABKEwAA/QEAAAAAAADjAAAAAAAAAJYAAAAEAAAAJgEAAAkAAABYBQAAAgAAAAIAAAABAAAABgAAAAMAAAApAAAAAgAAAAUAAAAAAAAApgAAAAEAAAA+AgAAAwAAAAkAAAAJAAAAcgEAAAEAAACaAAAACgAAALAAAAACAAAANgAAAA4AAAAgAAAACQAAABAAAAADAAAALgAAAAoAAAA2AAAACQAAAAcAAAACAAAAJQAAAA0AAAACAAAACQAAAAYAAAABAAAALQAAAAAAAAANAAAAAgAAADEAAAANAAAACQAAAAMAAAACAAAACwAAAFMAAAALAAAABwAAAAAAAAChAAAACwAAAAYAAAAJAAAABwAAAAMAAAA4AAAAAQAAAAIAAAAGAAAAAwAAAAEAAAADAAAAAgAAAAoAAAAAAAAACwAAAAEAAAADAAAABgAAAAQAAAAEAAAAwQAAABEAAAAKAAAACQAAAAUAAAAAAAAAUgAAABMAAAANAAAACQAAANYAAAAGAAAAAwAAAAgAAAAcAAAAAQAAAFMAAAAQAAAAEAAAAAkAAABSAAAADAAAAAkAAAAJAAAAVAAAAA4AAAAFAAAACQAAAPMAAAAOAAAApgAAAAkAAABHAAAABQAAAAIAAAABAAAAAwAAAAMAAAACAAAAAAAAAAIAAAABAAAADQAAAAkAAAB4AAAABgAAAAMAAAAGAAAABAAAAAAAAAAdAAAACQAAACkAAAAGAAAAAgAAAAMAAAAJAAAAAAAAAAoAAAAKAAAALwAAAA8AAACWAQAABwAAAAIAAAAHAAAAEQAAAAkAAAA5AAAAFQAAAAIAAAANAAAAewAAAAUAAAAEAAAAAAAAAAIAAAABAAAAAgAAAAYAAAACAAAAAAAAAAkAAAAJAAAAMQAAAAQAAAACAAAAAQAAAAIAAAAEAAAACQAAAAkAAABKAQAAAwAAAGpLAAAJAAAAhwAAAAQAAAA8AAAABgAAABoAAAAJAAAA9gMAAAAAAAACAAAANgAAAAgAAAADAAAAUgAAAAAAAAAMAAAAAQAAAKxMAAABAAAAxxQAAAQAAAAEAAAABQAAAAkAAAAHAAAAAwAAAAYAAAAfAAAAAwAAAJUAAAACAAAAigUAADEAAAABAgAANgAAAAUAAAAxAAAACQAAAAAAAAAPAAAAAAAAABcAAAAEAAAAAgAAAA4AAABRBQAABgAAAAIAAAAQAAAAAwAAAAYAAAACAAAAAQAAAAIAAAAEAAAABgEAAAYAAAAKAAAACQAAAKMBAAANAAAA1wUAAAYAAABuAAAABgAAAAYAAAAJAAAAlxIAAAkAAAAHBQwA7wAAAABBmB8LHFCMAAABAAAAAgAAAAMAAAAEAAAAAAQAAPAfAAA=","undefined"!=typeof window&&"function"==typeof atob?Uint8Array.from(atob(B),A=>A.charCodeAt(0)):Buffer.from(B,"base64")));var B;const{exports:E}=await WebAssembly.instantiate(Q);A=E})())} \ No newline at end of file +/* cjs-module-lexer 1.4.1 */ +let A;const Q=1===new Uint8Array(new Uint16Array([1]).buffer)[0];export function parse(g,I="@"){if(!A)throw new Error("Not initialized");const D=g.length+1,N=(A.__heap_base.value||A.__heap_base)+4*D-A.memory.buffer.byteLength;N>0&&A.memory.grow(Math.ceil(N/65536));const k=A.sa(D);(Q?C:E)(g,new Uint16Array(A.memory.buffer,k,D));const w=A.parseCJS(k,g.length,0,0,0);if(w){const Q=new Error(`Parse error ${I}${A.e()}:${g.slice(0,A.e()).split("\n").length}:${A.e()-g.lastIndexOf("\n",A.e()-1)}`);throw Object.assign(Q,{idx:A.e()}),5!==w&&6!==w&&7!==w||Object.assign(Q,{code:"ERR_LEXER_ESM_SYNTAX"}),Q}let H=new Set,J=new Set,o=new Set;for(;A.rre();){const Q=B(g.slice(A.res(),A.ree()));Q&&J.add(Q)}for(;A.ru();)o.add(B(g.slice(A.us(),A.ue())));for(;A.re();){let Q=B(g.slice(A.es(),A.ee()));void 0===Q||o.has(Q)||H.add(Q)}return{exports:[...H],reexports:[...J]}}function B(A){if('"'!==A[0]&&"'"!==A[0])return A;try{const Q=(0,eval)(A);for(let A=0;A>>8}}function C(A,Q){const B=A.length;let E=0;for(;EA.charCodeAt(0))}let I;export function init(){return I||(I=(async()=>{const Q=await WebAssembly.compile(g()),{exports:B}=await WebAssembly.instantiate(Q);A=B})())}export function initSync(){if(A)return;const Q=new WebAssembly.Module(g()),{exports:B}=new WebAssembly.Instance(Q);A=B} \ No newline at end of file diff --git a/deps/cjs-module-lexer/lexer.d.ts b/deps/cjs-module-lexer/lexer.d.ts new file mode 100644 index 00000000000..c7d8a523f36 --- /dev/null +++ b/deps/cjs-module-lexer/lexer.d.ts @@ -0,0 +1,8 @@ +export interface Exports { + exports: string[]; + reexports: string[]; +} + +export declare function parse(source: string, name?: string): Exports; +export declare function init(): Promise; +export declare function initSync(): void; diff --git a/deps/cjs-module-lexer/lexer.js b/deps/cjs-module-lexer/lexer.js old mode 100755 new mode 100644 index 1bf3123c172..aaf7dde807f --- a/deps/cjs-module-lexer/lexer.js +++ b/deps/cjs-module-lexer/lexer.js @@ -1149,6 +1149,10 @@ function codePointAtLast (bPos) { return ch; } +function esmSyntaxErr (msg) { + return Object.assign(new Error(msg), { code: 'ERR_LEXER_ESM_SYNTAX' }); +} + function throwIfImportStatement () { const startPos = pos; pos += 6; @@ -1160,7 +1164,7 @@ function throwIfImportStatement () { return; // import.meta case 46/*.*/: - throw new Error('Unexpected import.meta in CJS module.'); + throw esmSyntaxErr('Unexpected import.meta in CJS module.'); default: // no space after "import" -> not an import keyword @@ -1176,7 +1180,7 @@ function throwIfImportStatement () { return; } // import statements are a syntax error in CommonJS - throw new Error('Unexpected import statement in CJS module.'); + throw esmSyntaxErr('Unexpected import statement in CJS module.'); } } @@ -1186,7 +1190,7 @@ function throwIfExportStatement () { const ch = commentWhitespace(); if (pos === curPos && !isPunctuator(ch)) return; - throw new Error('Unexpected export statement in CJS module.'); + throw esmSyntaxErr('Unexpected export statement in CJS module.'); } function commentWhitespace () { @@ -1435,4 +1439,5 @@ function isExpressionTerminator (curPos) { const initPromise = Promise.resolve(); module.exports.init = () => initPromise; +module.exports.initSync = () => {}; module.exports.parse = parseCJS; diff --git a/deps/cjs-module-lexer/package.json b/deps/cjs-module-lexer/package.json old mode 100755 new mode 100644 index 13d13ca93c8..6b9a771168e --- a/deps/cjs-module-lexer/package.json +++ b/deps/cjs-module-lexer/package.json @@ -1,43 +1,48 @@ -{ - "name": "cjs-module-lexer", - "version": "1.2.2", - "description": "Lexes CommonJS modules, returning their named exports metadata", - "main": "lexer.js", - "exports": { - "import": "./dist/lexer.mjs", - "default": "./lexer.js" - }, - "types": "lexer.d.ts", - "scripts": { - "test-js": "mocha -b -u tdd test/*.js", - "test-wasm": "WASM=1 mocha -b -u tdd test/*.js", - "test": "npm run test-wasm && npm run test-js", - "bench": "node --expose-gc bench/index.mjs", - "build": "node build.js && babel dist/lexer.mjs | terser -o dist/lexer.js", - "build-wasm": "make lib/lexer.wasm && node build.js", - "prepublishOnly": "make && npm run build", - "footprint": "npm run build && cat dist/lexer.js | gzip -9f | wc -c" - }, - "author": "Guy Bedford", - "license": "MIT", - "devDependencies": { - "@babel/cli": "^7.5.5", - "@babel/core": "^7.5.5", - "@babel/plugin-transform-modules-commonjs": "^7.5.0", - "kleur": "^2.0.2", - "mocha": "^5.2.0", - "terser": "^4.1.4" - }, - "files": [ - "dist", - "lexer.d.ts" - ], - "repository": { - "type": "git", - "url": "git+https://github.com/guybedford/cjs-module-lexer.git" - }, - "bugs": { - "url": "https://github.com/guybedford/cjs-module-lexer/issues" - }, - "homepage": "https://github.com/guybedford/cjs-module-lexer#readme" -} +{ + "name": "cjs-module-lexer", + "version": "1.4.1", + "description": "Lexes CommonJS modules, returning their named exports metadata", + "main": "lexer.js", + "exports": { + "import": { + "types": "./lexer.d.mts", + "default": "./dist/lexer.mjs" + }, + "default": "./lexer.js" + }, + "types": "lexer.d.ts", + "scripts": { + "test-js": "mocha -b -u tdd test/*.js", + "test-wasm": "cross-env WASM=1 mocha -b -u tdd test/*.js", + "test-wasm-sync": "cross-env WASM_SYNC=1 mocha -b -u tdd test/*.js", + "test": "npm run test-wasm ; npm run test-wasm-sync ; npm run test-js", + "bench": "node --expose-gc bench/index.mjs", + "build": "node build.js ; babel dist/lexer.mjs -o dist/lexer.js ; terser dist/lexer.js -o dist/lexer.js", + "build-wasm": "make lib/lexer.wasm ; node build.js", + "prepublishOnly": "make && npm run build", + "footprint": "npm run build && cat dist/lexer.js | gzip -9f | wc -c" + }, + "author": "Guy Bedford", + "license": "MIT", + "devDependencies": { + "@babel/cli": "^7.5.5", + "@babel/core": "^7.5.5", + "@babel/plugin-transform-modules-commonjs": "^7.5.0", + "cross-env": "^7.0.3", + "kleur": "^2.0.2", + "mocha": "^9.1.3", + "terser": "^4.1.4" + }, + "files": [ + "dist", + "lexer.d.ts" + ], + "repository": { + "type": "git", + "url": "git+https://github.com/nodejs/cjs-module-lexer.git" + }, + "bugs": { + "url": "https://github.com/nodejs/cjs-module-lexer/issues" + }, + "homepage": "https://github.com/nodejs/cjs-module-lexer#readme" +} diff --git a/deps/openssl/openssl_common.gypi b/deps/openssl/openssl_common.gypi index 8745ec130ab..4312359e947 100644 --- a/deps/openssl/openssl_common.gypi +++ b/deps/openssl/openssl_common.gypi @@ -67,7 +67,7 @@ 'TERMIOS', ], 'conditions': [ - [ 'llvm_version=="0.0"', { + [ 'clang==0', { 'cflags': ['-Wno-old-style-declaration',], }], ], diff --git a/deps/opentelemetry-cpp/otlp-http-exporter.gyp b/deps/opentelemetry-cpp/otlp-http-exporter.gyp index 1aa3d906bea..d4c08d14713 100644 --- a/deps/opentelemetry-cpp/otlp-http-exporter.gyp +++ b/deps/opentelemetry-cpp/otlp-http-exporter.gyp @@ -88,7 +88,9 @@ '-fexceptions', '-fvisibility=hidden', '-pedantic', - '--std=c++17' + '--std=c++17', + '-Wno-error', + '-Wno-c++98-compat-extra-semi' ], 'msvs_settings': { }, diff --git a/deps/protobuf/protobuf.gyp b/deps/protobuf/protobuf.gyp index 6c2573f5eb3..739cfbc48a0 100644 --- a/deps/protobuf/protobuf.gyp +++ b/deps/protobuf/protobuf.gyp @@ -112,7 +112,9 @@ '-fexceptions', '-fvisibility=hidden', '-pedantic', - '--std=c++17' + '--std=c++17', + '-Wno-error', + '-Wno-c++98-compat-extra-semi' ], 'msvs_settings': { }, diff --git a/deps/simdutf/simdutf.cpp b/deps/simdutf/simdutf.cpp index e469d44466c..b04ec9773e9 100644 --- a/deps/simdutf/simdutf.cpp +++ b/deps/simdutf/simdutf.cpp @@ -1,4 +1,4 @@ -/* auto-generated on 2024-07-11 00:01:58 -0400. Do not edit! */ +/* auto-generated on 2024-09-04 18:13:32 +0200. Do not edit! */ /* begin file src/simdutf.cpp */ #include "simdutf.h" // We include base64_tables once. @@ -2140,7 +2140,7 @@ SIMDUTF_POP_DISABLE_WARNINGS #endif -// Default Haswell to on if this is x86-64. Even if we're not compiled for it, it could be selected +// Default Haswell to on if this is x86-64. Even if we are not compiled for it, it could be selected // at runtime. #ifndef SIMDUTF_IMPLEMENTATION_HASWELL // @@ -5598,6 +5598,14 @@ bool is_ascii_white_space(char_type c) { return c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '\f'; } +template +bool is_eight_byte(char_type c) { + if(sizeof(char_type) == 1) { + return true; + } + return uint8_t(c) == c; +} + // Returns true upon success. The destination buffer must be large enough. // This functions assumes that the padding (=) has been removed. template @@ -5617,7 +5625,7 @@ result base64_tail_decode(char *dst, const char_type *src, size_t length, base64 size_t idx; uint8_t buffer[4]; while (true) { - while (src + 4 <= srcend && + while (src + 4 <= srcend && is_eight_byte(src[0]) && is_eight_byte(src[1]) && is_eight_byte(src[2]) && is_eight_byte(src[3]) && (x = d0[uint8_t(src[0])] | d1[uint8_t(src[1])] | d2[uint8_t(src[2])] | d3[uint8_t(src[3])]) < 0x01FFFFFF) { if(match_system(endianness::BIG)) { @@ -5633,9 +5641,9 @@ result base64_tail_decode(char *dst, const char_type *src, size_t length, base64 char_type c = *src; uint8_t code = to_base64[uint8_t(c)]; buffer[idx] = uint8_t(code); - if (code <= 63) { + if (is_eight_byte(c) && code <= 63) { idx++; - } else if (code > 64) { + } else if (code > 64 || !scalar::base64::is_eight_byte(c)) { return {INVALID_BASE64_CHARACTER, size_t(src - srcinit)}; } else { // We have a space or a newline. We ignore it. @@ -5690,11 +5698,15 @@ result base64_tail_decode(char *dst, const char_type *src, size_t length, base64 } } -// like base64_tail_decode, but it will not write past the end of the ouput buffer. +// like base64_tail_decode, but it will not write past the end of the output buffer. // outlen is modified to reflect the number of bytes written. // This functions assumes that the padding (=) has been removed. template result base64_tail_decode_safe(char *dst, size_t& outlen, const char_type *src, size_t length, base64_options options) { + if(length == 0) { + outlen = 0; + return {SUCCESS, 0}; + } // This looks like 5 branches, but we expect the compiler to resolve this to a single branch: const uint8_t *to_base64 = (options & base64_url) ? tables::base64::to_base64_url_value : tables::base64::to_base64_value; const uint32_t *d0 = (options & base64_url) ? tables::base64::base64_url::d0 : tables::base64::base64_default::d0; @@ -5711,13 +5723,13 @@ result base64_tail_decode_safe(char *dst, size_t& outlen, const char_type *src, size_t idx; uint8_t buffer[4]; while (true) { - while (src + 4 <= srcend && + while (src + 4 <= srcend && is_eight_byte(src[0]) && is_eight_byte(src[1]) && is_eight_byte(src[2]) && is_eight_byte(src[3]) && (x = d0[uint8_t(src[0])] | d1[uint8_t(src[1])] | d2[uint8_t(src[2])] | d3[uint8_t(src[3])]) < 0x01FFFFFF) { if(match_system(endianness::BIG)) { x = scalar::utf32::swap_bytes(x); } - if(dst + 3 > dstend) { + if(dstend - dst < 3) { outlen = size_t(dst - dstinit); return {OUTPUT_BUFFER_TOO_SMALL, size_t(src - srcinit)}; } @@ -5733,9 +5745,9 @@ result base64_tail_decode_safe(char *dst, size_t& outlen, const char_type *src, char_type c = *src; uint8_t code = to_base64[uint8_t(c)]; buffer[idx] = uint8_t(code); - if (code <= 63) { + if (is_eight_byte(c) && code <= 63) { idx++; - } else if (code > 64) { + } else if (code > 64 || !scalar::base64::is_eight_byte(c)) { outlen = size_t(dst - dstinit); return {INVALID_BASE64_CHARACTER, size_t(src - srcinit)}; } else { @@ -5762,7 +5774,7 @@ result base64_tail_decode_safe(char *dst, size_t& outlen, const char_type *src, dst += 1; } else if (idx == 3) { - if(dst + 2 >= dstend) { + if(dstend - dst < 2) { outlen = size_t(dst - dstinit); return {OUTPUT_BUFFER_TOO_SMALL, size_t(srccur - srcinit)}; } @@ -5785,7 +5797,7 @@ result base64_tail_decode_safe(char *dst, size_t& outlen, const char_type *src, outlen = size_t(dst - dstinit); return {SUCCESS, size_t(dst - dstinit)}; } - if(dst + 3 >= dstend) { + if(dstend - dst < 3) { outlen = size_t(dst - dstinit); return {OUTPUT_BUFFER_TOO_SMALL, size_t(srccur - srcinit)}; } @@ -5896,6 +5908,99 @@ simdutf_warn_unused size_t base64_length_from_binary(size_t length, base64_optio #endif /* end file src/scalar/base64.h */ +/* begin file src/scalar/latin1_to_utf8/latin1_to_utf8.h */ +#ifndef SIMDUTF_LATIN1_TO_UTF8_H +#define SIMDUTF_LATIN1_TO_UTF8_H + +namespace simdutf { +namespace scalar { +namespace { +namespace latin1_to_utf8 { + +inline size_t convert(const char* buf, size_t len, char* utf8_output) { + const unsigned char *data = reinterpret_cast(buf); + size_t pos = 0; + size_t utf8_pos = 0; + while (pos < len) { + // try to convert the next block of 16 ASCII bytes + if (pos + 16 <= len) { // if it is safe to read 16 more bytes, check that they are ascii + uint64_t v1; + ::memcpy(&v1, data + pos, sizeof(uint64_t)); + uint64_t v2; + ::memcpy(&v2, data + pos + sizeof(uint64_t), sizeof(uint64_t)); + uint64_t v{v1 | v2}; // We are only interested in these bits: 1000 1000 1000 1000, so it makes sense to concatenate everything + if ((v & 0x8080808080808080) == 0) { // if NONE of these are set, e.g. all of them are zero, then everything is ASCII + size_t final_pos = pos + 16; + while(pos < final_pos) { + utf8_output[utf8_pos++] = char(buf[pos]); + pos++; + } + continue; + } + } + + unsigned char byte = data[pos]; + if((byte & 0x80) == 0) { // if ASCII + // will generate one UTF-8 bytes + utf8_output[utf8_pos++] = char(byte); + pos++; + } else { + // will generate two UTF-8 bytes + utf8_output[utf8_pos++] = char((byte>>6) | 0b11000000); + utf8_output[utf8_pos++] = char((byte & 0b111111) | 0b10000000); + pos++; + } + } + return utf8_pos; +} + +inline size_t convert_safe(const char* buf, size_t len, char* utf8_output, size_t utf8_len) { + const unsigned char *data = reinterpret_cast(buf); + size_t pos = 0; + size_t skip_pos = 0; + size_t utf8_pos = 0; + while (pos < len && utf8_pos < utf8_len) { + // try to convert the next block of 16 ASCII bytes + if (pos >= skip_pos && pos + 16 <= len && utf8_pos + 16 <= utf8_len) { // if it is safe to read 16 more bytes, check that they are ascii + uint64_t v1; + ::memcpy(&v1, data + pos, sizeof(uint64_t)); + uint64_t v2; + ::memcpy(&v2, data + pos + sizeof(uint64_t), sizeof(uint64_t)); + uint64_t v{v1 | v2}; // We are only interested in these bits: 1000 1000 1000 1000, so it makes sense to concatenate everything + if ((v & 0x8080808080808080) == 0) { // if NONE of these are set, e.g. all of them are zero, then everything is ASCII + ::memcpy(utf8_output + utf8_pos, buf + pos, 16); + utf8_pos += 16; + pos += 16; + } else { + // At least one of the next 16 bytes are not ASCII, we will process them one by one + skip_pos = pos + 16; + } + } else { + const auto byte = data[pos]; + if((byte & 0x80) == 0) { // if ASCII + // will generate one UTF-8 bytes + utf8_output[utf8_pos++] = char(byte); + pos++; + } else if (utf8_pos + 2 <= utf8_len) { + // will generate two UTF-8 bytes + utf8_output[utf8_pos++] = char((byte>>6) | 0b11000000); + utf8_output[utf8_pos++] = char((byte & 0b111111) | 0b10000000); + pos++; + } else { + break; + } + } + } + return utf8_pos; +} + +} // latin1_to_utf8 namespace +} // unnamed namespace +} // namespace scalar +} // namespace simdutf + +#endif +/* end file src/scalar/latin1_to_utf8/latin1_to_utf8.h */ namespace simdutf { bool implementation::supported_by_runtime_system() const { @@ -5937,7 +6042,7 @@ namespace internal { + SIMDUTF_IMPLEMENTATION_ARM64 + SIMDUTF_IMPLEMENTATION_PPC64 \ + SIMDUTF_IMPLEMENTATION_FALLBACK == 1) -// Static array of known implementations. We're hoping these get baked into the executable +// Static array of known implementations. We are hoping these get baked into the executable // without requiring a static initializer. @@ -6062,7 +6167,7 @@ class detect_best_supported_implementation_on_first_use final : public implement } simdutf_warn_unused size_t convert_latin1_to_utf8(const char * buf, size_t len, char* utf8_output) const noexcept final override { - return set_best()->convert_latin1_to_utf8(buf, len,utf8_output); + return set_best()->convert_latin1_to_utf8(buf, len, utf8_output); } simdutf_warn_unused size_t convert_latin1_to_utf16le(const char * buf, size_t len, char16_t* utf16_output) const noexcept final override { @@ -7235,6 +7340,31 @@ simdutf_warn_unused result base64_to_binary_safe_impl(const chartype * input, si } + +simdutf_warn_unused size_t convert_latin1_to_utf8_safe(const char * buf, size_t len, char* utf8_output, size_t utf8_len) noexcept { + const auto start{utf8_output}; + + while (true) { + // convert_latin1_to_utf8 will never write more than input length * 2 + auto read_len = std::min(len, utf8_len >> 1); + if (read_len <= 16) { + break; + } + + const auto write_len = simdutf::convert_latin1_to_utf8(buf, read_len, utf8_output); + + utf8_output += write_len; + utf8_len -= write_len; + buf += read_len; + len -= read_len; + } + + utf8_output += scalar::latin1_to_utf8::convert_safe(buf, len, utf8_output, utf8_len); + + return utf8_output - start; +} + + simdutf_warn_unused result base64_to_binary_safe(const char * input, size_t length, char* output, size_t& outlen, base64_options options) noexcept { return base64_to_binary_safe_impl(input, length, output, outlen, options); } @@ -13243,9 +13373,14 @@ inline result rewind_and_convert_with_errors(size_t prior_bytes, const char* buf bool found_leading_bytes{false}; // important: it is i <= how_far_back and not 'i < how_far_back'. for(size_t i = 0; i <= how_far_back; i++) { - unsigned char byte = buf[0-i]; + unsigned char byte = buf[-static_cast(i)]; found_leading_bytes = ((byte & 0b11000000) != 0b10000000); if(found_leading_bytes) { + if(i > 0 && byte < 128) { + // If we had to go back and the leading byte is ascii + // then we can stop right away. + return result(error_code::TOO_LONG, 0-i+1); + } buf -= i; extra_len = i; break; @@ -13519,9 +13654,14 @@ inline result rewind_and_convert_with_errors(size_t prior_bytes, const char* buf bool found_leading_bytes{false}; // important: it is i <= how_far_back and not 'i < how_far_back'. for(size_t i = 0; i <= how_far_back; i++) { - unsigned char byte = buf[0-i]; + unsigned char byte = buf[-static_cast(i)]; found_leading_bytes = ((byte & 0b11000000) != 0b10000000); if(found_leading_bytes) { + if(i > 0 && byte < 128) { + // If we had to go back and the leading byte is ascii + // then we can stop right away. + return result(error_code::TOO_LONG, 0-i+1); + } buf -= i; extra_len = i; break; @@ -13556,59 +13696,6 @@ inline result rewind_and_convert_with_errors(size_t prior_bytes, const char* buf #endif /* end file src/scalar/utf8_to_utf32/utf8_to_utf32.h */ -/* begin file src/scalar/latin1_to_utf8/latin1_to_utf8.h */ -#ifndef SIMDUTF_LATIN1_TO_UTF8_H -#define SIMDUTF_LATIN1_TO_UTF8_H - -namespace simdutf { -namespace scalar { -namespace { -namespace latin1_to_utf8 { - -inline size_t convert(const char* buf, size_t len, char* utf8_output) { - const unsigned char *data = reinterpret_cast(buf); - size_t pos = 0; - char* start{utf8_output}; - while (pos < len) { - // try to convert the next block of 16 ASCII bytes - if (pos + 16 <= len) { // if it is safe to read 16 more bytes, check that they are ascii - uint64_t v1; - ::memcpy(&v1, data + pos, sizeof(uint64_t)); - uint64_t v2; - ::memcpy(&v2, data + pos + sizeof(uint64_t), sizeof(uint64_t)); - uint64_t v{v1 | v2}; // We are only interested in these bits: 1000 1000 1000 1000, so it makes sense to concatenate everything - if ((v & 0x8080808080808080) == 0) { // if NONE of these are set, e.g. all of them are zero, then everything is ASCII - size_t final_pos = pos + 16; - while(pos < final_pos) { - *utf8_output++ = char(buf[pos]); - pos++; - } - continue; - } - } - - unsigned char byte = data[pos]; - if((byte & 0x80) == 0) { // if ASCII - // will generate one UTF-8 bytes - *utf8_output++ = char(byte); - pos++; - } else { - // will generate two UTF-8 bytes - *utf8_output++ = char((byte>>6) | 0b11000000); - *utf8_output++ = char((byte & 0b111111) | 0b10000000); - pos++; - } - } - return utf8_output - start; -} - -} // latin1_to_utf8 namespace -} // unnamed namespace -} // namespace scalar -} // namespace simdutf - -#endif -/* end file src/scalar/latin1_to_utf8/latin1_to_utf8.h */ /* begin file src/scalar/latin1_to_utf16/latin1_to_utf16.h */ #ifndef SIMDUTF_LATIN1_TO_UTF16_H #define SIMDUTF_LATIN1_TO_UTF16_H @@ -13729,7 +13816,7 @@ inline size_t convert(const char* buf, size_t len, char* latin_output) { // range check - uint32_t code_point = (leading_byte & 0b00011111) << 6 | (data[pos + 1] & 0b00111111); // assembles the Unicode code point from the two bytes. It does this by discarding the leading 110 and 10 bits from the two bytes, shifting the remaining bits of the first byte, and then combining the results with a bitwise OR operation. if (code_point < 0x80 || 0xFF < code_point) { - return 0; // We only care about the range 129-255 which is Non-ASCII latin1 characters. A code_point beneath 0x80 is invalid as it's already covered by bytes whose leading bit is zero. + return 0; // We only care about the range 129-255 which is Non-ASCII latin1 characters. A code_point beneath 0x80 is invalid as it is already covered by bytes whose leading bit is zero. } *latin_output++ = char(code_point); pos += 2; @@ -13814,9 +13901,14 @@ inline result rewind_and_convert_with_errors(size_t prior_bytes, const char* buf bool found_leading_bytes{false}; // important: it is i <= how_far_back and not 'i < how_far_back'. for(size_t i = 0; i <= how_far_back; i++) { - unsigned char byte = buf[0-i]; + unsigned char byte = buf[-static_cast(i)]; found_leading_bytes = ((byte & 0b11000000) != 0b10000000); if(found_leading_bytes) { + if(i > 0 && byte < 128) { + // If we had to go back and the leading byte is ascii + // then we can stop right away. + return result(error_code::TOO_LONG, 0-i+1); + } buf -= i; extra_len = i; break; @@ -13863,6 +13955,7 @@ namespace utf16_to_latin1 { template inline size_t convert(const char16_t* buf, size_t len, char* latin_output) { + if(len == 0) { return 0; } const uint16_t *data = reinterpret_cast(buf); size_t pos = 0; std::vector temp_output(len); @@ -13886,6 +13979,7 @@ inline size_t convert(const char16_t* buf, size_t len, char* latin_output) { template inline result convert_with_errors(const char16_t* buf, size_t len, char* latin_output) { + if(len == 0) { return result(error_code::SUCCESS,0); } const uint16_t *data = reinterpret_cast(buf); size_t pos = 0; char* start{latin_output}; @@ -13902,7 +13996,7 @@ inline result convert_with_errors(const char16_t* buf, size_t len, char* latin_o if (!match_system(big_endian)) { v1 = (v1 >> 8) | (v1 << (64 - 8)); } if (!match_system(big_endian)) { v2 = (v2 >> 8) | (v2 << (64 - 8)); } if (!match_system(big_endian)) { v3 = (v3 >> 8) | (v3 << (64 - 8)); } - if (!match_system(big_endian)) { v4 = (v1 >> 8) | (v4 << (64 - 8)); } + if (!match_system(big_endian)) { v4 = (v4 >> 8) | (v4 << (64 - 8)); } if (((v1 | v2 | v3 | v4) & 0xFF00FF00FF00FF00) == 0) { size_t final_pos = pos + 16; @@ -14098,26 +14192,32 @@ inline size_t convert_valid(const char32_t *buf, size_t len, char *latin1_output size_t pos = 0; while (pos < len) { - utf32_char = (uint32_t)data[pos]; - - if (pos + 2 <= len) { // if it is safe to read 8 more bytes, check that they are Latin1 - uint64_t v; - ::memcpy(&v, data + pos, sizeof(uint64_t)); - if ((v & 0xFFFFFF00FFFFFF00) == 0) { - *latin1_output++ = char(buf[pos]); - *latin1_output++ = char(buf[pos+1]); - pos += 2; - continue; - } - } - *latin1_output++ = (char)(utf32_char & 0xFF); - pos++; - + utf32_char = (uint32_t) data[pos]; + + if (pos + 2 <= len) { // if it is safe to read 8 more bytes, check that they are Latin1 + uint64_t v; + ::memcpy(&v, data + pos, sizeof(uint64_t)); + if ((v & 0xFFFFFF00FFFFFF00) == 0) { + *latin1_output++ = char(buf[pos]); + *latin1_output++ = char(buf[pos + 1]); + pos += 2; + continue; + } else { + // output can not be represented in latin1 + return 0; + } + } + if ((utf32_char & 0xFFFFFF00) == 0) { + *latin1_output++ = char(utf32_char); + } else { + // output can not be represented in latin1 + return 0; + } + pos++; } return latin1_output - start; } - } // utf32_to_latin1 namespace } // unnamed namespace } // namespace scalar @@ -14243,217 +14343,80 @@ simdutf_really_inline uint16x8_t convert_utf8_1_to_2_byte_to_utf16(uint8x16_t in return composed; } -/* begin file src/arm64/arm_detect_encodings.cpp */ -template -// len is known to be a multiple of 2 when this is called -int arm_detect_encodings(const char * buf, size_t len) { - const char* start = buf; - const char* end = buf + len; - - bool is_utf8 = true; - bool is_utf16 = true; - bool is_utf32 = true; - - int out = 0; - +/* begin file src/arm64/arm_validate_utf16.cpp */ +template +const char16_t* arm_validate_utf16(const char16_t* input, size_t size) { + const char16_t* end = input + size; const auto v_d8 = simd8::splat(0xd8); const auto v_f8 = simd8::splat(0xf8); + const auto v_fc = simd8::splat(0xfc); + const auto v_dc = simd8::splat(0xdc); + while (end - input >= 16) { + // 0. Load data: since the validation takes into account only higher + // byte of each word, we compress the two vectors into one which + // consists only the higher bytes. + auto in0 = simd16(input); + auto in1 = simd16(input + simd16::SIZE / sizeof(char16_t)); + if (!match_system(big_endian)) { + in0 = vreinterpretq_u16_u8(vrev16q_u8(vreinterpretq_u8_u16(in0))); + in1 = vreinterpretq_u16_u8(vrev16q_u8(vreinterpretq_u8_u16(in1))); + } + const auto t0 = in0.shr<8>(); + const auto t1 = in1.shr<8>(); + const simd8 in = simd16::pack(t0, t1); + // 1. Check whether we have any 0xD800..DFFF word (0b1101'1xxx'yyyy'yyyy). + const uint64_t surrogates_wordmask = ((in & v_f8) == v_d8).to_bitmask64(); + if(surrogates_wordmask == 0) { + input += 16; + } else { + // 2. We have some surrogates that have to be distinguished: + // - low surrogates: 0b1101'10xx'yyyy'yyyy (0xD800..0xDBFF) + // - high surrogates: 0b1101'11xx'yyyy'yyyy (0xDC00..0xDFFF) + // + // Fact: high surrogate has 11th bit set (3rd bit in the higher word) - uint32x4_t currentmax = vmovq_n_u32(0x0); - - checker check{}; - - while(buf + 64 <= end) { - uint16x8_t in = vld1q_u16(reinterpret_cast(buf)); - uint16x8_t secondin = vld1q_u16(reinterpret_cast(buf) + simd16::SIZE / sizeof(char16_t)); - uint16x8_t thirdin = vld1q_u16(reinterpret_cast(buf) + 2*simd16::SIZE / sizeof(char16_t)); - uint16x8_t fourthin = vld1q_u16(reinterpret_cast(buf) + 3*simd16::SIZE / sizeof(char16_t)); - - const auto u0 = simd16(in); - const auto u1 = simd16(secondin); - const auto u2 = simd16(thirdin); - const auto u3 = simd16(fourthin); - - const auto v0 = u0.shr<8>(); - const auto v1 = u1.shr<8>(); - const auto v2 = u2.shr<8>(); - const auto v3 = u3.shr<8>(); - - const auto in16 = simd16::pack(v0, v1); - const auto nextin16 = simd16::pack(v2, v3); - - const uint64_t surrogates_wordmask0 = ((in16 & v_f8) == v_d8).to_bitmask64(); - const uint64_t surrogates_wordmask1 = ((nextin16 & v_f8) == v_d8).to_bitmask64(); - - // Check for surrogates - if (surrogates_wordmask0 != 0 || surrogates_wordmask1 != 0) { - // Cannot be UTF8 - is_utf8 = false; - // Can still be either UTF-16LE or UTF-32 depending on the positions of the surrogates - // To be valid UTF-32, a surrogate cannot be in the two most significant bytes of any 32-bit word. - // On the other hand, to be valid UTF-16LE, at least one surrogate must be in the two most significant - // bytes of a 32-bit word since they always come in pairs in UTF-16LE. - // Note that we always proceed in multiple of 4 before this point so there is no offset in 32-bit code units. - - if (((surrogates_wordmask0 | surrogates_wordmask1) & 0xf0f0f0f0f0f0f0f0) != 0) { - is_utf32 = false; - // Code from arm_validate_utf16le.cpp - // Not efficient, we do not process surrogates_wordmask1 - const char16_t * input = reinterpret_cast(buf); - const char16_t* end16 = reinterpret_cast(start) + len/2; - - const auto v_fc = simd8::splat(0xfc); - const auto v_dc = simd8::splat(0xdc); - - const uint64_t V0 = ~surrogates_wordmask0; - - const auto vH0 = ((in16 & v_fc) == v_dc); - const uint64_t H0 = vH0.to_bitmask64(); - - const uint64_t L0 = ~H0 & surrogates_wordmask0; - - const uint64_t a0 = L0 & (H0 >> 4); + // V - non-surrogate code units + // V = not surrogates_wordmask + const uint64_t V = ~surrogates_wordmask; - const uint64_t b0 = a0 << 4; + // H - word-mask for high surrogates: the six highest bits are 0b1101'11 + const auto vH = ((in & v_fc) == v_dc); + const uint64_t H = vH.to_bitmask64(); - const uint64_t c0 = V0 | a0 | b0; - if (c0 == ~0ull) { - input += 16; - } else if (c0 == 0xfffffffffffffffull) { - input += 15; - } else { - is_utf16 = false; - break; - } + // L - word mask for low surrogates + // L = not H and surrogates_wordmask + const uint64_t L = ~H & surrogates_wordmask; - while (input + 16 < end16) { - const auto in0 = simd16(input); - const auto in1 = simd16(input + simd16::SIZE / sizeof(char16_t)); - const auto t0 = in0.shr<8>(); - const auto t1 = in1.shr<8>(); - const simd8 in_16 = simd16::pack(t0, t1); - - const uint64_t surrogates_wordmask = ((in_16 & v_f8) == v_d8).to_bitmask64(); - if(surrogates_wordmask == 0) { - input += 16; - } else { - const uint64_t V = ~surrogates_wordmask; - - const auto vH = ((in_16 & v_fc) == v_dc); - const uint64_t H = vH.to_bitmask64(); - - const uint64_t L = ~H & surrogates_wordmask; - - const uint64_t a = L & (H >> 4); - - const uint64_t b = a << 4; - - const uint64_t c = V | a | b; - if (c == ~0ull) { - input += 16; - } else if (c == 0xfffffffffffffffull) { - input += 15; - } else { - is_utf16 = false; - break; - } - } - } + const uint64_t a = L & (H >> 4); // A low surrogate must be followed by high one. + // (A low surrogate placed in the 7th register's word + // is an exception we handle.) + const uint64_t b = a << 4; // Just mark that the opposite fact is hold, + // thanks to that we have only two masks for valid case. + const uint64_t c = V | a | b; // Combine all the masks into the final one. + if (c == ~0ull) { + // The whole input register contains valid UTF-16, i.e., + // either single code units or proper surrogate pairs. + input += 16; + } else if (c == 0xfffffffffffffffull) { + // The 15 lower code units of the input register contains valid UTF-16. + // The 15th word may be either a low or high surrogate. It the next + // iteration we 1) check if the low surrogate is followed by a high + // one, 2) reject sole high surrogate. + input += 15; } else { - is_utf16 = false; - // Check for UTF-32 - if (len % 4 == 0) { - const char32_t * input = reinterpret_cast(buf); - const char32_t* end32 = reinterpret_cast(start) + len/4; - - // Must start checking for surrogates - uint32x4_t currentoffsetmax = vmovq_n_u32(0x0); - const uint32x4_t offset = vmovq_n_u32(0xffff2000); - const uint32x4_t standardoffsetmax = vmovq_n_u32(0xfffff7ff); - - const uint32x4_t in32 = vreinterpretq_u32_u16(in); - const uint32x4_t secondin32 = vreinterpretq_u32_u16(secondin); - const uint32x4_t thirdin32 = vreinterpretq_u32_u16(thirdin); - const uint32x4_t fourthin32 = vreinterpretq_u32_u16(fourthin); - - currentmax = vmaxq_u32(in32,currentmax); - currentmax = vmaxq_u32(secondin32,currentmax); - currentmax = vmaxq_u32(thirdin32,currentmax); - currentmax = vmaxq_u32(fourthin32,currentmax); - - currentoffsetmax = vmaxq_u32(vaddq_u32(in32, offset), currentoffsetmax); - currentoffsetmax = vmaxq_u32(vaddq_u32(secondin32, offset), currentoffsetmax); - currentoffsetmax = vmaxq_u32(vaddq_u32(thirdin32, offset), currentoffsetmax); - currentoffsetmax = vmaxq_u32(vaddq_u32(fourthin32, offset), currentoffsetmax); - - while (input + 4 < end32) { - const uint32x4_t in_32 = vld1q_u32(reinterpret_cast(input)); - currentmax = vmaxq_u32(in_32,currentmax); - currentoffsetmax = vmaxq_u32(vaddq_u32(in_32, offset), currentoffsetmax); - input += 4; - } - - uint32x4_t forbidden_words = veorq_u32(vmaxq_u32(currentoffsetmax, standardoffsetmax), standardoffsetmax); - if(vmaxvq_u32(forbidden_words) != 0) { - is_utf32 = false; - } - } else { - is_utf32 = false; - } + return nullptr; } - break; - } - // If no surrogate, validate under other encodings as well - - // UTF-32 validation - currentmax = vmaxq_u32(vreinterpretq_u32_u16(in),currentmax); - currentmax = vmaxq_u32(vreinterpretq_u32_u16(secondin),currentmax); - currentmax = vmaxq_u32(vreinterpretq_u32_u16(thirdin),currentmax); - currentmax = vmaxq_u32(vreinterpretq_u32_u16(fourthin),currentmax); - - // UTF-8 validation - // Relies on ../generic/utf8_validation/utf8_lookup4_algorithm.h - simd::simd8x64 in8(vreinterpretq_u8_u16(in), vreinterpretq_u8_u16(secondin), vreinterpretq_u8_u16(thirdin), vreinterpretq_u8_u16(fourthin)); - check.check_next_input(in8); - - buf += 64; - } - - // Check which encodings are possible - - if (is_utf8) { - if (static_cast(buf - start) != len) { - uint8_t block[64]{}; - std::memset(block, 0x20, 64); - std::memcpy(block, buf, len - (buf - start)); - simd::simd8x64 in(block); - check.check_next_input(in); - } - if (!check.errors()) { - out |= simdutf::encoding_type::UTF8; - } - } - - if (is_utf16 && scalar::utf16::validate(reinterpret_cast(buf), (len - (buf - start))/2)) { - out |= simdutf::encoding_type::UTF16_LE; - } - - if (is_utf32 && (len % 4 == 0)) { - const uint32x4_t standardmax = vmovq_n_u32(0x10ffff); - uint32x4_t is_zero = veorq_u32(vmaxq_u32(currentmax, standardmax), standardmax); - if (vmaxvq_u32(is_zero) == 0 && scalar::utf32::validate(reinterpret_cast(buf), (len - (buf - start))/4)) { - out |= simdutf::encoding_type::UTF32_LE; } } - - return out; + return input; } -/* end file src/arm64/arm_detect_encodings.cpp */ -/* begin file src/arm64/arm_validate_utf16.cpp */ + template -const char16_t* arm_validate_utf16(const char16_t* input, size_t size) { +const result arm_validate_utf16_with_errors(const char16_t* input, size_t size) { + const char16_t* start = input; const char16_t* end = input + size; + const auto v_d8 = simd8::splat(0xd8); const auto v_f8 = simd8::splat(0xf8); const auto v_fc = simd8::splat(0xfc); @@ -14464,77 +14427,7 @@ const char16_t* arm_validate_utf16(const char16_t* input, size_t size) { // consists only the higher bytes. auto in0 = simd16(input); auto in1 = simd16(input + simd16::SIZE / sizeof(char16_t)); - if (!match_system(big_endian)) { - in0 = vreinterpretq_u16_u8(vrev16q_u8(vreinterpretq_u8_u16(in0))); - in1 = vreinterpretq_u16_u8(vrev16q_u8(vreinterpretq_u8_u16(in1))); - } - const auto t0 = in0.shr<8>(); - const auto t1 = in1.shr<8>(); - const simd8 in = simd16::pack(t0, t1); - // 1. Check whether we have any 0xD800..DFFF word (0b1101'1xxx'yyyy'yyyy). - const uint64_t surrogates_wordmask = ((in & v_f8) == v_d8).to_bitmask64(); - if(surrogates_wordmask == 0) { - input += 16; - } else { - // 2. We have some surrogates that have to be distinguished: - // - low surrogates: 0b1101'10xx'yyyy'yyyy (0xD800..0xDBFF) - // - high surrogates: 0b1101'11xx'yyyy'yyyy (0xDC00..0xDFFF) - // - // Fact: high surrogate has 11th bit set (3rd bit in the higher word) - - // V - non-surrogate code units - // V = not surrogates_wordmask - const uint64_t V = ~surrogates_wordmask; - - // H - word-mask for high surrogates: the six highest bits are 0b1101'11 - const auto vH = ((in & v_fc) == v_dc); - const uint64_t H = vH.to_bitmask64(); - - // L - word mask for low surrogates - // L = not H and surrogates_wordmask - const uint64_t L = ~H & surrogates_wordmask; - - const uint64_t a = L & (H >> 4); // A low surrogate must be followed by high one. - // (A low surrogate placed in the 7th register's word - // is an exception we handle.) - const uint64_t b = a << 4; // Just mark that the opposite fact is hold, - // thanks to that we have only two masks for valid case. - const uint64_t c = V | a | b; // Combine all the masks into the final one. - if (c == ~0ull) { - // The whole input register contains valid UTF-16, i.e., - // either single code units or proper surrogate pairs. - input += 16; - } else if (c == 0xfffffffffffffffull) { - // The 15 lower code units of the input register contains valid UTF-16. - // The 15th word may be either a low or high surrogate. It the next - // iteration we 1) check if the low surrogate is followed by a high - // one, 2) reject sole high surrogate. - input += 15; - } else { - return nullptr; - } - } - } - return input; -} - - -template -const result arm_validate_utf16_with_errors(const char16_t* input, size_t size) { - const char16_t* start = input; - const char16_t* end = input + size; - - const auto v_d8 = simd8::splat(0xd8); - const auto v_f8 = simd8::splat(0xf8); - const auto v_fc = simd8::splat(0xfc); - const auto v_dc = simd8::splat(0xdc); - while (input + 16 < end) { - // 0. Load data: since the validation takes into account only higher - // byte of each word, we compress the two vectors into one which - // consists only the higher bytes. - auto in0 = simd16(input); - auto in1 = simd16(input + simd16::SIZE / sizeof(char16_t)); - + if (!match_system(big_endian)) { in0 = vreinterpretq_u16_u8(vrev16q_u8(vreinterpretq_u8_u16(in0))); in1 = vreinterpretq_u16_u8(vrev16q_u8(vreinterpretq_u8_u16(in1))); @@ -14600,7 +14493,7 @@ const char32_t* arm_validate_utf32le(const char32_t* input, size_t size) { uint32x4_t currentmax = vmovq_n_u32(0x0); uint32x4_t currentoffsetmax = vmovq_n_u32(0x0); - while (input + 4 < end) { + while (end - input >= 4) { const uint32x4_t in = vld1q_u32(reinterpret_cast(input)); currentmax = vmaxq_u32(in,currentmax); currentoffsetmax = vmaxq_u32(vaddq_u32(in, offset), currentoffsetmax); @@ -14631,7 +14524,7 @@ const result arm_validate_utf32le_with_errors(const char32_t* input, size_t size uint32x4_t currentmax = vmovq_n_u32(0x0); uint32x4_t currentoffsetmax = vmovq_n_u32(0x0); - while (input + 4 < end) { + while (end - input >= 4) { const uint32x4_t in = vld1q_u32(reinterpret_cast(input)); currentmax = vmaxq_u32(in,currentmax); currentoffsetmax = vmaxq_u32(vaddq_u32(in, offset), currentoffsetmax); @@ -14666,7 +14559,7 @@ arm_convert_latin1_to_utf8(const char *latin1_input, size_t len, const uint16x8_t v_c080 = vmovq_n_u16((uint16_t)0xc080); // We always write 16 bytes, of which more than the first 8 bytes // are valid. A safety margin of 8 is more than sufficient. - while (latin1_input + 16 + 8 <= end) { + while (end - latin1_input >= 16 + 8) { uint8x16_t in8 = vld1q_u8(reinterpret_cast(latin1_input)); if (vmaxvq_u8(in8) <= 0x7F) { // ASCII fast path!!!! vst1q_u8(utf8_output, in8); @@ -14730,7 +14623,7 @@ template std::pair arm_convert_latin1_to_utf16(const char* buf, size_t len, char16_t* utf16_output) { const char* end = buf + len; - while (buf + 16 <= end) { + while (end - buf >= 16) { uint8x16_t in8 = vld1q_u8(reinterpret_cast(buf)); uint16x8_t inlow = vmovl_u8(vget_low_u8(in8)); if (!match_system(big_endian)) { inlow = vreinterpretq_u16_u8(vrev16q_u8(vreinterpretq_u8_u16(inlow))); } @@ -14749,7 +14642,7 @@ std::pair arm_convert_latin1_to_utf16(const char* buf, s std::pair arm_convert_latin1_to_utf32(const char* buf, size_t len, char32_t* utf32_output) { const char* end = buf + len; - while (buf + 16 <= end) { + while (end - buf >= 16) { uint8x16_t in8 = vld1q_u8(reinterpret_cast(buf)); uint16x8_t in8low = vmovl_u8(vget_low_u8(in8)); uint32x4_t in16lowlow = vmovl_u16(vget_low_u16(in8low)); @@ -14942,8 +14835,10 @@ size_t convert_masked_utf8_to_utf16(const char *input, if (!match_system(big_endian)) { composed = vreinterpretq_u16_u8(vrev16q_u8(vreinterpretq_u8_u16(composed))); } - vst1q_u16(reinterpret_cast(utf16_output), composed); - utf16_output += 6; // We 3 32-bit surrogate pairs. + uint16_t buffer[8]; + vst1q_u16(reinterpret_cast(buffer), composed); + for(int k = 0; k < 6; k++) { utf16_output[k] = buffer[k]; } // the loop might compiler to a couple of instructions. + utf16_output += 6; // We wrote 3 32-bit surrogate pairs. return 12; // We consumed 12 bytes. } // 3 1-4 byte sequences @@ -14954,6 +14849,12 @@ size_t convert_masked_utf8_to_utf16(const char *input, // 3 byte: 00000000 1110bbbb 10cccccc 10dddddd // 4 byte: 11110aaa 10bbbbbb 10cccccc 10dddddd uint32x4_t perm = vreinterpretq_u32_u8(vqtbl1q_u8(in, sh)); + // added to fix issue https://github.com/simdutf/simdutf/issues/514 + // We only want to write 2 * 16-bit code units when that is actually what we have. + // Unfortunately, we cannot trust the input. So it is possible to get 0xff as an input byte + // and it should not result in a surrogate pair. We need to check for that. + uint32_t permbuffer[4]; + vst1q_u32(permbuffer, perm); // Mask the low and middle bytes // 00000000 00000000 00000000 0ddddddd uint32x4_t ascii = vandq_u32(perm, vmovq_n_u32(0x7f)); @@ -15009,11 +14910,14 @@ size_t convert_masked_utf8_to_utf16(const char *input, // Attempting to shuffle and store would be complex, just scalarize. uint32_t buffer[4]; vst1q_u32(buffer, selected); - // Test for the top bit of the surrogate mask. - const uint32_t SURROGATE_MASK = match_system(big_endian) ? 0x80000000 : 0x00800000; + // Test for the top bit of the surrogate mask. Remove due to issue 514 + // const uint32_t SURROGATE_MASK = match_system(big_endian) ? 0x80000000 : 0x00800000; for (size_t i = 0; i < 3; i++) { // Surrogate - if (buffer[i] & SURROGATE_MASK) { + // Used to be if (buffer[i] & SURROGATE_MASK) { + // See discussion above. + // patch for issue https://github.com/simdutf/simdutf/issues/514 + if((permbuffer[i] & 0xf8000000) == 0xf0000000) { utf16_output[0] = uint16_t(buffer[i] >> 16); utf16_output[1] = uint16_t(buffer[i] & 0xFFFF); utf16_output += 2; @@ -15052,14 +14956,14 @@ size_t convert_masked_utf8_to_utf32(const char *input, // This results in more instructions but, potentially, also higher speeds. // // We first try a few fast paths. - if((utf8_end_of_code_point_mask & 0xffff) == 0xffff) { - // We process in chunks of 16 bytes. + if(utf8_end_of_code_point_mask == 0xfff) { + // We process in chunks of 12 bytes. // use fast implementation in src/simdutf/arm64/simd.h // Ideally the compiler can keep the tables in registers. simd8 temp{vreinterpretq_s8_u8(in)}; temp.store_ascii_as_utf32_tbl(utf32_out); - utf32_output += 16; // We wrote 16 32-bit characters. - return 16; // We consumed 16 bytes. + utf32_output += 12; // We wrote 12 32-bit characters. + return 12; // We consumed 12 bytes. } if(input_utf8_end_of_code_point_mask == 0x924) { // We want to take 4 3-byte UTF-8 code units and turn them into 4 4-byte UTF-32 code units. @@ -15228,11 +15132,11 @@ size_t convert_masked_utf8_to_latin1(const char *input, // We first try a few fast paths. // The obvious first test is ASCII, which actually consumes the full 16. - if((utf8_end_of_code_point_mask & 0xFFFF) == 0xffff) { - // We process in chunks of 16 bytes + if(utf8_end_of_code_point_mask == 0xfff) { + // We process in chunks of 12 bytes vst1q_u8(reinterpret_cast(latin1_output), in); - latin1_output += 16; // We wrote 16 18-bit characters. - return 16; // We consumed 16 bytes. + latin1_output += 12; // We wrote 12 18-bit characters. + return 12; // We consumed 12 bytes. } /// We do not have a fast path available, or the fast path is unimportant, so we fallback. const uint8_t idx = @@ -15281,7 +15185,7 @@ size_t convert_masked_utf8_to_latin1(const char *input, template std::pair arm_convert_utf16_to_latin1(const char16_t* buf, size_t len, char* latin1_output) { const char16_t* end = buf + len; - while (buf + 8 <= end) { + while (end - buf >= 8) { uint16x8_t in = vld1q_u16(reinterpret_cast(buf)); if (!match_system(big_endian)) { in = vreinterpretq_u16_u8(vrev16q_u8(vreinterpretq_u8_u16(in))); } if (vmaxvq_u16(in) <= 0xff) { @@ -15303,7 +15207,7 @@ template std::pair arm_convert_utf16_to_latin1_with_errors(const char16_t* buf, size_t len, char* latin1_output) { const char16_t* start = buf; const char16_t* end = buf + len; - while (buf + 8 <= end) { + while (end - buf >= 8) { uint16x8_t in = vld1q_u16(reinterpret_cast(buf)); if (!match_system(big_endian)) { in = vreinterpretq_u16_u8(vrev16q_u8(vreinterpretq_u8_u16(in))); } if (vmaxvq_u16(in) <= 0xff) { @@ -15345,7 +15249,7 @@ std::pair arm_convert_utf16_to_latin1_with_errors(const char16_t* Ad 1. When values are less than 0x0800, it means that a 16-bit code unit - can be converted into: 1) single UTF8 byte (when it's an ASCII + can be converted into: 1) single UTF8 byte (when it is an ASCII char) or 2) two UTF8 bytes. For this case we do only some shuffle to obtain these 2-byte @@ -15391,7 +15295,7 @@ std::pair arm_convert_utf16_to_utf8(const char16_t* buf, const uint16x8_t v_d800 = vmovq_n_u16((uint16_t)0xd800); const uint16x8_t v_c080 = vmovq_n_u16((uint16_t)0xc080); const size_t safety_margin = 12; // to avoid overruns, see issue https://github.com/simdutf/simdutf/issues/92 - while (buf + 16 + safety_margin <= end) { + while (end - buf >= std::ptrdiff_t(16 + safety_margin)) { uint16x8_t in = vld1q_u16(reinterpret_cast(buf)); if (!match_system(big_endian)) { in = vreinterpretq_u16_u8(vrev16q_u8(vreinterpretq_u8_u16(in))); } if(vmaxvq_u16(in) <= 0x7F) { // ASCII fast path!!!! @@ -15645,7 +15549,7 @@ std::pair arm_convert_utf16_to_utf8_with_errors(const char16_t* b const uint16x8_t v_c080 = vmovq_n_u16((uint16_t)0xc080); const size_t safety_margin = 12; // to avoid overruns, see issue https://github.com/simdutf/simdutf/issues/92 - while (buf + 16 + safety_margin <= end) { + while (end - buf >= std::ptrdiff_t(16 + safety_margin)) { uint16x8_t in = vld1q_u16(reinterpret_cast(buf)); if (!match_system(big_endian)) { in = vreinterpretq_u16_u8(vrev16q_u8(vreinterpretq_u8_u16(in))); } if(vmaxvq_u16(in) <= 0x7F) { // ASCII fast path!!!! @@ -15897,7 +15801,7 @@ std::pair arm_convert_utf16_to_utf8_with_errors(const char16_t* b Ad 1. When values are less than 0x0800, it means that a 16-bit code unit - can be converted into: 1) single UTF8 byte (when it's an ASCII + can be converted into: 1) single UTF8 byte (when it is an ASCII char) or 2) two UTF8 bytes. For this case we do only some shuffle to obtain these 2-byte @@ -15942,7 +15846,7 @@ std::pair arm_convert_utf16_to_utf32(const char16_t* const uint16x8_t v_f800 = vmovq_n_u16((uint16_t)0xf800); const uint16x8_t v_d800 = vmovq_n_u16((uint16_t)0xd800); - while (buf + 8 <= end) { + while (end - buf >= 8) { uint16x8_t in = vld1q_u16(reinterpret_cast(buf)); if (!match_system(big_endian)) { in = vreinterpretq_u16_u8(vrev16q_u8(vreinterpretq_u8_u16(in))); } @@ -16000,7 +15904,7 @@ std::pair arm_convert_utf16_to_utf32_with_errors(const char16 const uint16x8_t v_f800 = vmovq_n_u16((uint16_t)0xf800); const uint16x8_t v_d800 = vmovq_n_u16((uint16_t)0xd800); - while (buf + 8 <= end) { + while ((end - buf) >= 8) { uint16x8_t in = vld1q_u16(reinterpret_cast(buf)); if (!match_system(big_endian)) { in = vreinterpretq_u16_u8(vrev16q_u8(vreinterpretq_u8_u16(in))); } @@ -16046,7 +15950,7 @@ std::pair arm_convert_utf16_to_utf32_with_errors(const char16 /* begin file src/arm64/arm_convert_utf32_to_latin1.cpp */ std::pair arm_convert_utf32_to_latin1(const char32_t* buf, size_t len, char* latin1_output) { const char32_t* end = buf + len; - while (buf + 8 <= end) { + while (end - buf >= 8) { uint32x4_t in1 = vld1q_u32(reinterpret_cast(buf)); uint32x4_t in2 = vld1q_u32(reinterpret_cast(buf+4)); @@ -16071,7 +15975,7 @@ std::pair arm_convert_utf32_to_latin1_with_errors(const char32_t* const char32_t* start = buf; const char32_t* end = buf + len; - while (buf + 8 <= end) { + while (end - buf >= 8) { uint32x4_t in1 = vld1q_u32(reinterpret_cast(buf)); uint32x4_t in2 = vld1q_u32(reinterpret_cast(buf+4)); @@ -16579,7 +16483,7 @@ std::pair arm_convert_utf32_to_utf16(const char32_t* uint16x4_t forbidden_bytemask = vmov_n_u16(0x0); - while(buf + 4 <= end) { + while(end - buf >= 4) { uint32x4_t in = vld1q_u32(reinterpret_cast(buf)); // Check if no bits set above 16th @@ -16637,7 +16541,7 @@ std::pair arm_convert_utf32_to_utf16_with_errors(const char32 const char32_t* start = buf; const char32_t* end = buf + len; - while(buf + 4 <= end) { + while(end - buf >= 4) { uint32x4_t in = vld1q_u32(reinterpret_cast(buf)); // Check if no bits set above 16th @@ -16801,6 +16705,7 @@ static inline void compress(uint8x16_t data, uint16_t mask, char *output) { struct block64 { uint8x16_t chunks[4]; }; + static_assert(sizeof(block64) == 64, "block64 is not 64 bytes"); template uint64_t to_base64_mask(block64 *b, bool *error) { uint8x16_t v0f = vdupq_n_u8(0xf); @@ -16822,6 +16727,7 @@ template uint64_t to_base64_mask(block64 *b, bool *error) { uint8x16_t lo_nibbles1 = vandq_u8(b->chunks[1], v0f); uint8x16_t lo_nibbles2 = vandq_u8(b->chunks[2], v0f); uint8x16_t lo_nibbles3 = vandq_u8(b->chunks[3], v0f); + // Needed by the decoding step. uint8x16_t hi_nibbles0 = vshrq_n_u8(b->chunks[0], 4); uint8x16_t hi_nibbles1 = vshrq_n_u8(b->chunks[1], 4); @@ -16831,20 +16737,16 @@ template uint64_t to_base64_mask(block64 *b, bool *error) { #ifdef SIMDUTF_REGULAR_VISUAL_STUDIO if (base64_url) { lut_lo = - simdutf_make_uint8x16_t(0x3a, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, - 0x70, 0x61, 0xe1, 0xf4, 0xf5, 0xa5, 0xf4, 0xf4); + simdutf_make_uint8x16_t(0x3a,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x61,0xe1,0xf4,0xe5,0xa5,0xf4,0xf4); } else { lut_lo = - simdutf_make_uint8x16_t(0x3a, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, - 0x70, 0x61, 0xe1, 0xb4, 0xf5, 0xe5, 0xf4, 0xb4); + simdutf_make_uint8x16_t(0x3a,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x61,0xe1,0xb4,0xe5,0xe5,0xf4,0xb4); } #else if (base64_url) { - lut_lo = uint8x16_t{0x3a, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, - 0x70, 0x61, 0xe1, 0xf4, 0xf5, 0xa5, 0xf4, 0xf4}; + lut_lo = uint8x16_t{0x3a,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x61,0xe1,0xf4,0xe5,0xa5,0xf4,0xf4}; } else { - lut_lo = uint8x16_t{0x3a, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, - 0x70, 0x61, 0xe1, 0xb4, 0xf5, 0xe5, 0xf4, 0xb4}; + lut_lo = uint8x16_t{0x3a,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x61,0xe1,0xb4,0xe5,0xe5,0xf4,0xb4}; } #endif uint8x16_t lo0 = vqtbl1q_u8(lut_lo, lo_nibbles0); @@ -17016,19 +16918,22 @@ result compress_decode_base64(char *dst, const char_type *src, size_t srclen, base64_options options) { const uint8_t *to_base64 = base64_url ? tables::base64::to_base64_url_value : tables::base64::to_base64_value; + size_t equallocation = srclen; // location of the first padding character if any // skip trailing spaces - while (srclen > 0 && to_base64[uint8_t(src[srclen - 1])] == 64) { + while (srclen > 0 && scalar::base64::is_eight_byte(src[srclen - 1]) && to_base64[uint8_t(src[srclen - 1])] == 64) { srclen--; } size_t equalsigns = 0; if (srclen > 0 && src[srclen - 1] == '=') { + equallocation = srclen - 1; srclen--; equalsigns = 1; // skip trailing spaces - while (srclen > 0 && to_base64[uint8_t(src[srclen - 1])] == 64) { + while (srclen > 0 && scalar::base64::is_eight_byte(src[srclen - 1]) && to_base64[uint8_t(src[srclen - 1])] == 64) { srclen--; } if (srclen > 0 && src[srclen - 1] == '=') { + equallocation = srclen - 1; srclen--; equalsigns = 2; } @@ -17048,21 +16953,23 @@ result compress_decode_base64(char *dst, const char_type *src, size_t srclen, src += 64; bool error = false; uint64_t badcharmask = to_base64_mask(&b, &error); - if(badcharmask) - if (error) { - src -= 64; - - while (src < srcend && to_base64[uint8_t(*src)] <= 64) { - src++; + if(badcharmask){ + if (error) { + src -= 64; + while (src < srcend && scalar::base64::is_eight_byte(*src) && to_base64[uint8_t(*src)] <= 64) { + src++; + } + if(src < srcend){ + // should never happen + } + return {error_code::INVALID_BASE64_CHARACTER, size_t(src - srcinit)}; } - return {error_code::INVALID_BASE64_CHARACTER, size_t(src - srcinit)}; } if (badcharmask != 0) { // optimization opportunity: check for simple masks like those made of // continuous 1s followed by continuous 0s. And masks containing a // single bad character. - bufferptr += compress_block(&b, badcharmask, bufferptr); } else { // optimization opportunity: if bufferptr == buffer and mask == 0, we @@ -17089,7 +16996,7 @@ result compress_decode_base64(char *dst, const char_type *src, size_t srclen, while ((bufferptr - buffer_start) % 64 != 0 && src < srcend) { uint8_t val = to_base64[uint8_t(*src)]; *bufferptr = char(val); - if (val > 64) { + if (!scalar::base64::is_eight_byte(*src) || val > 64) { return {error_code::INVALID_BASE64_CHARACTER, size_t(src - srcinit)}; } bufferptr += (val <= 63); @@ -17132,7 +17039,7 @@ result compress_decode_base64(char *dst, const char_type *src, size_t srclen, if (leftover > 0) { while (leftover < 4 && src < srcend) { uint8_t val = to_base64[uint8_t(*src)]; - if (val > 64) { + if (!scalar::base64::is_eight_byte(*src) || val > 64) { return {error_code::INVALID_BASE64_CHARACTER, size_t(src - srcinit)}; } buffer_start[leftover] = char(val); @@ -17184,13 +17091,14 @@ result compress_decode_base64(char *dst, const char_type *src, size_t srclen, // additional checks if((r.count % 3 == 0) || ((r.count % 3) + 1 + equalsigns != 4)) { r.error = error_code::INVALID_BASE64_CHARACTER; + r.count = equallocation; } } return r; } if(equalsigns > 0) { if((size_t(dst - dstinit) % 3 == 0) || ((size_t(dst - dstinit) % 3) + 1 + equalsigns != 4)) { - return {INVALID_BASE64_CHARACTER, size_t(dst - dstinit)}; + return {INVALID_BASE64_CHARACTER, equallocation}; } } return {SUCCESS, size_t(dst - dstinit)}; @@ -17280,7 +17188,7 @@ simdutf_really_inline const uint8_t *buf_block_reader::full_block() c template simdutf_really_inline size_t buf_block_reader::get_remainder(uint8_t *dst) const { if(len == idx) { return 0; } // memcpy(dst, null, 0) will trigger an error with some sanitizers - std::memset(dst, 0x20, STEP_SIZE); // std::memset STEP_SIZE because it's more efficient to write out 8 or 16 bytes at once. + std::memset(dst, 0x20, STEP_SIZE); // std::memset STEP_SIZE because it is more efficient to write out 8 or 16 bytes at once. std::memcpy(dst, buf + idx, len - idx); return len - idx; } @@ -17403,7 +17311,7 @@ using namespace simd; // // Return nonzero if there are incomplete multibyte characters at the end of the block: - // e.g. if there is a 4-byte character, but it's 3 bytes from the end. + // e.g. if there is a 4-byte character, but it is 3 bytes from the end. // simdutf_really_inline simd8 is_incomplete(const simd8 input) { // If the previous input's last 3 bytes match this, they're too short (they ended at EOF): @@ -17848,6 +17756,9 @@ using namespace simd; this->check_utf8_bytes(input.chunks[3], input.chunks[2]); } uint64_t utf8_continuation_mask = input.lt(-65 + 1); + if(utf8_continuation_mask & 1) { + return 0; // error + } uint64_t utf8_leading_mask = ~utf8_continuation_mask; uint64_t utf8_end_of_code_point_mask = utf8_leading_mask>>1; // We process in blocks of up to 12 bytes except possibly @@ -17922,14 +17833,14 @@ using namespace simd; this->check_utf8_bytes(input.chunks[2], input.chunks[1]); this->check_utf8_bytes(input.chunks[3], input.chunks[2]); } - if (errors()) { + uint64_t utf8_continuation_mask = input.lt(-65 + 1); + if (errors() || (utf8_continuation_mask & 1)) { // rewind_and_convert_with_errors will seek a potential error from in+pos onward, // with the ability to go back up to pos bytes, and read size-pos bytes forward. result res = scalar::utf8_to_utf16::rewind_and_convert_with_errors(pos, in + pos, size - pos, utf16_output); res.count += pos; return res; } - uint64_t utf8_continuation_mask = input.lt(-65 + 1); uint64_t utf8_leading_mask = ~utf8_continuation_mask; uint64_t utf8_end_of_code_point_mask = utf8_leading_mask>>1; // We process in blocks of up to 12 bytes except possibly @@ -18167,10 +18078,10 @@ using namespace simd; size_t pos = 0; char32_t* start{utf32_output}; // In the worst case, we have the haswell kernel which can cause an overflow of - // 8 bytes when calling convert_masked_utf8_to_utf32. If you skip the last 16 bytes, + // 8 words when calling convert_masked_utf8_to_utf32. If you skip the last 16 bytes, // and if the data is valid, then it is entirely safe because 16 UTF-8 bytes generate // much more than 8 bytes. However, you cannot generally assume that you have valid - // UTF-8 input, so we are going to go back from the end counting 8 leading bytes, + // UTF-8 input, so we are going to go back from the end counting 16 leading bytes, // to give us a good margin. size_t leading_byte = 0; size_t margin = size; @@ -18200,6 +18111,9 @@ using namespace simd; this->check_utf8_bytes(input.chunks[3], input.chunks[2]); } uint64_t utf8_continuation_mask = input.lt(-65 + 1); + if(utf8_continuation_mask & 1) { + return 0; // we have an error + } uint64_t utf8_leading_mask = ~utf8_continuation_mask; uint64_t utf8_end_of_code_point_mask = utf8_leading_mask>>1; // We process in blocks of up to 12 bytes except possibly @@ -18273,12 +18187,12 @@ using namespace simd; this->check_utf8_bytes(input.chunks[2], input.chunks[1]); this->check_utf8_bytes(input.chunks[3], input.chunks[2]); } - if (errors()) { + uint64_t utf8_continuation_mask = input.lt(-65 + 1); + if (errors() || (utf8_continuation_mask & 1)) { result res = scalar::utf8_to_utf32::rewind_and_convert_with_errors(pos, in + pos, size - pos, utf32_output); res.count += pos; return res; } - uint64_t utf8_continuation_mask = input.lt(-65 + 1); uint64_t utf8_leading_mask = ~utf8_continuation_mask; uint64_t utf8_end_of_code_point_mask = utf8_leading_mask>>1; // We process in blocks of up to 12 bytes except possibly @@ -18827,15 +18741,16 @@ simdutf_warn_unused int implementation::detect_encodings(const char * input, siz // If there is a BOM, then we trust it. auto bom_encoding = simdutf::BOM::check_bom(input, length); if(bom_encoding != encoding_type::unspecified) { return bom_encoding; } - if (length % 2 == 0) { - return arm_detect_encodings(input, length); - } else { - if (implementation::validate_utf8(input, length)) { - return simdutf::encoding_type::UTF8; - } else { - return simdutf::encoding_type::unspecified; - } + // todo: reimplement as a one-pass algorithm. + int out = 0; + if(validate_utf8(input, length)) { out |= encoding_type::UTF8; } + if((length % 2) == 0) { + if(validate_utf16le(reinterpret_cast(input), length/2)) { out |= encoding_type::UTF16_LE; } + } + if((length % 4) == 0) { + if(validate_utf32(reinterpret_cast(input), length/4)) { out |= encoding_type::UTF32_LE; } } + return out; } simdutf_warn_unused bool implementation::validate_utf8(const char *buf, size_t len) const noexcept { @@ -18855,6 +18770,10 @@ simdutf_warn_unused result implementation::validate_ascii_with_errors(const char } simdutf_warn_unused bool implementation::validate_utf16le(const char16_t *buf, size_t len) const noexcept { + if (simdutf_unlikely(len == 0)) { + // empty input is valid. protected the implementation from nullptr. + return true; + } const char16_t* tail = arm_validate_utf16(buf, len); if (tail) { return scalar::utf16::validate(tail, len - (tail - buf)); @@ -18864,7 +18783,11 @@ simdutf_warn_unused bool implementation::validate_utf16le(const char16_t *buf, s } simdutf_warn_unused bool implementation::validate_utf16be(const char16_t *buf, size_t len) const noexcept { - const char16_t* tail = arm_validate_utf16(buf, len); + if (simdutf_unlikely(len == 0)) { + // empty input is valid. protected the implementation from nullptr. + return true; + } + const char16_t *tail = arm_validate_utf16(buf, len); if (tail) { return scalar::utf16::validate(tail, len - (tail - buf)); } else { @@ -18873,6 +18796,9 @@ simdutf_warn_unused bool implementation::validate_utf16be(const char16_t *buf, s } simdutf_warn_unused result implementation::validate_utf16le_with_errors(const char16_t *buf, size_t len) const noexcept { + if (simdutf_unlikely(len == 0)) { + return result(error_code::SUCCESS, 0); + } result res = arm_validate_utf16_with_errors(buf, len); if (res.count != len) { result scalar_res = scalar::utf16::validate_with_errors(buf + res.count, len - res.count); @@ -18883,6 +18809,9 @@ simdutf_warn_unused result implementation::validate_utf16le_with_errors(const ch } simdutf_warn_unused result implementation::validate_utf16be_with_errors(const char16_t *buf, size_t len) const noexcept { + if (simdutf_unlikely(len == 0)) { + return result(error_code::SUCCESS, 0); + } result res = arm_validate_utf16_with_errors(buf, len); if (res.count != len) { result scalar_res = scalar::utf16::validate_with_errors(buf + res.count, len - res.count); @@ -18893,6 +18822,10 @@ simdutf_warn_unused result implementation::validate_utf16be_with_errors(const ch } simdutf_warn_unused bool implementation::validate_utf32(const char32_t *buf, size_t len) const noexcept { + if (simdutf_unlikely(len == 0)) { + // empty input is valid. protected the implementation from nullptr. + return true; + } const char32_t* tail = arm_validate_utf32le(buf, len); if (tail) { return scalar::utf32::validate(tail, len - (tail - buf)); @@ -18902,6 +18835,9 @@ simdutf_warn_unused bool implementation::validate_utf32(const char32_t *buf, siz } simdutf_warn_unused result implementation::validate_utf32_with_errors(const char32_t *buf, size_t len) const noexcept { + if (simdutf_unlikely(len == 0)) { + return result(error_code::SUCCESS, 0); + } result res = arm_validate_utf32le_with_errors(buf, len); if (res.count != len) { result scalar_res = scalar::utf32::validate_with_errors(buf + res.count, len - res.count); @@ -19158,6 +19094,9 @@ simdutf_warn_unused size_t implementation::convert_valid_utf16be_to_utf8(const c } simdutf_warn_unused size_t implementation::convert_utf32_to_utf8(const char32_t* buf, size_t len, char* utf8_output) const noexcept { + if (simdutf_unlikely(len == 0)) { + return 0; + } std::pair ret = arm_convert_utf32_to_utf8(buf, len, utf8_output); if (ret.first == nullptr) { return 0; } size_t saved_bytes = ret.second - utf8_output; @@ -19171,6 +19110,9 @@ simdutf_warn_unused size_t implementation::convert_utf32_to_utf8(const char32_t* } simdutf_warn_unused result implementation::convert_utf32_to_utf8_with_errors(const char32_t* buf, size_t len, char* utf8_output) const noexcept { + if (simdutf_unlikely(len == 0)) { + return result(error_code::SUCCESS, 0); + } // ret.first.count is always the position in the buffer, not the number of code units written even if finished std::pair ret = arm_convert_utf32_to_utf8_with_errors(buf, len, utf8_output); if (ret.first.count != len) { @@ -19550,6 +19492,8 @@ size_t implementation::binary_to_base64(const char * input, size_t length, char* +#include +#include namespace simdutf { namespace fallback { @@ -19558,6 +19502,7 @@ simdutf_warn_unused int implementation::detect_encodings(const char * input, siz // If there is a BOM, then we trust it. auto bom_encoding = simdutf::BOM::check_bom(input, length); if(bom_encoding != encoding_type::unspecified) { return bom_encoding; } + // todo: reimplement as a one-pass algorithm. int out = 0; if(validate_utf8(input, length)) { out |= encoding_type::UTF8; } if((length % 2) == 0) { @@ -19566,7 +19511,6 @@ simdutf_warn_unused int implementation::detect_encodings(const char * input, siz if((length % 4) == 0) { if(validate_utf32(reinterpret_cast(input), length/4)) { out |= encoding_type::UTF32_LE; } } - return out; } @@ -19611,7 +19555,7 @@ simdutf_warn_unused result implementation::validate_utf32_with_errors(const char } simdutf_warn_unused size_t implementation::convert_latin1_to_utf8(const char * buf, size_t len, char* utf8_output) const noexcept { - return scalar::latin1_to_utf8::convert(buf,len,utf8_output); + return scalar::latin1_to_utf8::convert(buf, len, utf8_output); } simdutf_warn_unused size_t implementation::convert_latin1_to_utf16le(const char* buf, size_t len, char16_t* utf16_output) const noexcept { @@ -19623,7 +19567,7 @@ simdutf_warn_unused size_t implementation::convert_latin1_to_utf16be(const char* } simdutf_warn_unused size_t implementation::convert_latin1_to_utf32(const char * buf, size_t len, char32_t* utf32_output) const noexcept { - return scalar::latin1_to_utf32::convert(buf,len,utf32_output); + return scalar::latin1_to_utf32::convert(buf, len, utf32_output); } simdutf_warn_unused size_t implementation::convert_utf8_to_latin1(const char* buf, size_t len, char* latin1_output) const noexcept { @@ -19824,7 +19768,31 @@ simdutf_warn_unused size_t implementation::latin1_length_from_utf32(size_t lengt } simdutf_warn_unused size_t implementation::utf8_length_from_latin1(const char * input, size_t length) const noexcept { - return scalar::latin1::utf8_length_from_latin1(input,length); + size_t answer = length; + size_t i = 0; + auto pop = [](uint64_t v) { + return (size_t)(((v>>7) & UINT64_C(0x0101010101010101)) * UINT64_C(0x0101010101010101) >> 56); + }; + for(; i + 32 <= length; i += 32) { + uint64_t v; + memcpy(&v, input + i, 8); + answer += pop(v); + memcpy(&v, input + i + 8, sizeof(v)); + answer += pop(v); + memcpy(&v, input + i + 16, sizeof(v)); + answer += pop(v); + memcpy(&v, input + i + 24, sizeof(v)); + answer += pop(v); + } + for(; i + 8 <= length; i += 8) { + uint64_t v; + memcpy(&v, input + i, sizeof(v)); + answer += pop(v); + } + for(; i + 1 <= length; i += 1) { + answer += static_cast(input[i]) >> 7; + } + return answer; } simdutf_warn_unused size_t implementation::utf8_length_from_utf16le(const char16_t * input, size_t length) const noexcept { @@ -19878,12 +19846,14 @@ simdutf_warn_unused result implementation::base64_to_binary(const char * input, size_t equallocation = length; // location of the first padding character if any size_t equalsigns = 0; if(length > 0 && input[length - 1] == '=') { + equallocation = length - 1; length -= 1; equalsigns++; while(length > 0 && scalar::base64::is_ascii_white_space(input[length - 1])) { length--; } if(length > 0 && input[length - 1] == '=') { + equallocation = length - 1; equalsigns++; length -= 1; } @@ -19915,12 +19885,14 @@ simdutf_warn_unused result implementation::base64_to_binary(const char16_t * inp size_t equallocation = length; // location of the first padding character if any size_t equalsigns = 0; if(length > 0 && input[length - 1] == '=') { + equallocation = length - 1; length -= 1; equalsigns++; while(length > 0 && scalar::base64::is_ascii_white_space(input[length - 1])) { length--; } if(length > 0 && input[length - 1] == '=') { + equallocation = length - 1; equalsigns++; length -= 1; } @@ -20825,7 +20797,7 @@ std::pair valid_utf8_to_fixed_length(const char* str, size * We check for ptr + 64 + 64 <= end because * we want to be do maskless writes without overruns. */ - while (ptr + 64 + 64 <= end) { + while (end - ptr >= 64 + 4) { const __m512i utf8 = _mm512_loadu_si512((const __m512i*)ptr); const __m512i v_80 = _mm512_set1_epi8(char(0x80)); const __mmask64 ascii = _mm512_test_epi8_mask(utf8, v_80); @@ -20847,12 +20819,12 @@ std::pair valid_utf8_to_fixed_length(const char* str, size vec0 = _mm512_mask_expand_epi32(vec0, __mmask16(((1<(utf8); int valid_count2; @@ -20866,17 +20838,17 @@ std::pair valid_utf8_to_fixed_length(const char* str, size vec2 = _mm512_mask_expand_epi32(vec2, __mmask16(((1<= 64) { const __m512i utf8 = _mm512_loadu_si512((const __m512i*)ptr); const __m512i v_80 = _mm512_set1_epi8(char(0x80)); const __mmask64 ascii = _mm512_test_epi8_mask(utf8, v_80); @@ -20978,7 +20950,7 @@ simdutf_really_inline __m512i check_special_cases(__m512i input, const __m512i p } // // Return nonzero if there are incomplete multibyte characters at the end of the block: - // e.g. if there is a 4-byte character, but it's 3 bytes from the end. + // e.g. if there is a 4-byte character, but it is 3 bytes from the end. // simdutf_really_inline __m512i is_incomplete(const __m512i input) { // If the previous input's last 3 bytes match this, they're too short (they ended at EOF): @@ -21042,7 +21014,6 @@ simdutf_really_inline __m512i check_special_cases(__m512i input, const __m512i p simdutf_really_inline bool errors() const { return _mm512_test_epi8_mask(this->error, this->error) != 0; } - }; // struct avx512_utf8_checker /* end file src/icelake/icelake_utf8_validation.inl.cpp */ /* begin file src/icelake/icelake_from_utf8.inl.cpp */ @@ -21062,7 +21033,7 @@ utf8_to_utf16_result fast_avx512_convert_utf8_to_utf16(const char *in, size_t le const char *const final_in = in + len; bool result = true; while (result) { - if (in + 64 <= final_in) { + if (final_in - in >= 64 ) { result = process_block_utf8_to_utf16(in, out, final_in - in); } else if(in < final_in) { result = process_block_utf8_to_utf16(in, out, final_in - in); @@ -21079,13 +21050,23 @@ simdutf::result fast_avx512_convert_utf8_to_utf16_with_errors(const char *in, si const char *const final_in = in + len; bool result = true; while (result) { - if (in + 64 <= final_in) { + if (final_in - in >= 64 ) { result = process_block_utf8_to_utf16(in, out, final_in - in); } else if(in < final_in) { result = process_block_utf8_to_utf16(in, out, final_in - in); } else { break; } } if(!result) { + size_t pos = size_t(in - init_in); + if (pos < len && (init_in[pos] & 0xc0) == 0x80 && pos >= 64) { + // We must check whether we are the fourth continuation byte + bool c1 = (init_in[pos - 1] & 0xc0) == 0x80; + bool c2 = (init_in[pos - 2] & 0xc0) == 0x80; + bool c3 = (init_in[pos - 3] & 0xc0) == 0x80; + if(c1 && c2 && c3) { + return {simdutf::TOO_LONG, pos}; + } + } // rewind_and_convert_with_errors will seek a potential error from in onward, // with the ability to go back up to in - init_in bytes, and read final_in - in bytes forward. simdutf::result res = scalar::utf8_to_utf16::rewind_and_convert_with_errors(in - init_in, in, final_in - in, out); @@ -21098,6 +21079,7 @@ simdutf::result fast_avx512_convert_utf8_to_utf16_with_errors(const char *in, si template +// todo: replace with the utf-8 to utf-16 routine adapted to utf-32. This code is legacy. std::pair validating_utf8_to_fixed_length(const char* str, size_t len, OUTPUT* dwords) { constexpr bool UTF32 = std::is_same::value; constexpr bool UTF16 = std::is_same::value; @@ -21121,10 +21103,9 @@ std::pair validating_utf8_to_fixed_length(const char* str, /** * In the main loop, we consume 64 bytes per iteration, * but we access 64 + 4 bytes. - * We check for ptr + 64 + 64 <= end because - * we want to be do maskless writes without overruns. + * We use masked writes to avoid overruns, see https://github.com/simdutf/simdutf/issues/471 */ - while (ptr + 64 + 64 <= end) { + while (end - ptr >= 64 + 4) { const __m512i utf8 = _mm512_loadu_si512((const __m512i*)ptr); if(checker.check_next_input(utf8)) { SIMDUTF_ICELAKE_STORE_ASCII(UTF32, utf8, output) @@ -21143,12 +21124,12 @@ std::pair validating_utf8_to_fixed_length(const char* str, vec0 = _mm512_mask_expand_epi32(vec0, __mmask16(((1<(utf8); int valid_count2; @@ -21162,12 +21143,12 @@ std::pair validating_utf8_to_fixed_length(const char* str, vec2 = _mm512_mask_expand_epi32(vec2, __mmask16(((1< validating_utf8_to_fixed_length(const char* str, // For the final pass, we validate 64 bytes, but we only transcode // 3*16 bytes, so we may end up double-validating 16 bytes. - if (ptr + 64 <= end) { + if (end - ptr >= 64) { const __m512i utf8 = _mm512_loadu_si512((const __m512i*)ptr); if(checker.check_next_input(utf8)) { SIMDUTF_ICELAKE_STORE_ASCII(UTF32, utf8, output) @@ -21208,8 +21189,8 @@ std::pair validating_utf8_to_fixed_length(const char* str, } validatedptr += 4*16; } - { - const __m512i utf8 = _mm512_maskz_loadu_epi8((1ULL<<(end - validatedptr))-1, (const __m512i*)validatedptr); + if (end != validatedptr) { + const __m512i utf8 = _mm512_maskz_loadu_epi8(~UINT64_C(0) >> (64 - (end - validatedptr)), (const __m512i*)validatedptr); checker.check_next_input(utf8); } checker.check_eof(); @@ -21220,6 +21201,7 @@ std::pair validating_utf8_to_fixed_length(const char* str, } // Like validating_utf8_to_fixed_length but returns as soon as an error is identified +// todo: replace with the utf-8 to utf-16 routine adapted to utf-32. This code is legacy. template std::tuple validating_utf8_to_fixed_length_with_constant_checks(const char* str, size_t len, OUTPUT* dwords) { constexpr bool UTF32 = std::is_same::value; @@ -21244,20 +21226,19 @@ std::tuple validating_utf8_to_fixed_length_with_cons /** * In the main loop, we consume 64 bytes per iteration, * but we access 64 + 4 bytes. - * We check for ptr + 64 + 64 <= end because - * we want to be do maskless writes without overruns. */ - while (ptr + 64 + 64 <= end) { + while (end - ptr >= 4 + 64) { const __m512i utf8 = _mm512_loadu_si512((const __m512i*)ptr); - if(checker.check_next_input(utf8)) { + bool ascii = checker.check_next_input(utf8); + if(checker.errors()) { + return {ptr, output, false}; // We found an error. + } + if(ascii) { SIMDUTF_ICELAKE_STORE_ASCII(UTF32, utf8, output) output += 64; ptr += 64; continue; } - if(checker.errors()) { - return {ptr, output, false}; // We found an error. - } const __m512i lane0 = broadcast_epi128<0>(utf8); const __m512i lane1 = broadcast_epi128<1>(utf8); int valid_count0; @@ -21269,12 +21250,12 @@ std::tuple validating_utf8_to_fixed_length_with_cons vec0 = _mm512_mask_expand_epi32(vec0, __mmask16(((1<(utf8); int valid_count2; @@ -21288,12 +21269,12 @@ std::tuple validating_utf8_to_fixed_length_with_cons vec2 = _mm512_mask_expand_epi32(vec2, __mmask16(((1< validating_utf8_to_fixed_length_with_cons // For the final pass, we validate 64 bytes, but we only transcode // 3*16 bytes, so we may end up double-validating 16 bytes. - if (ptr + 64 <= end) { + if (end - ptr >= 64) { const __m512i utf8 = _mm512_loadu_si512((const __m512i*)ptr); - if(checker.check_next_input(utf8)) { + bool ascii = checker.check_next_input(utf8); + if(checker.errors()) { + return {ptr, output, false}; // We found an error. + } + if(ascii) { SIMDUTF_ICELAKE_STORE_ASCII(UTF32, utf8, output) output += 64; ptr += 64; - } else if(checker.errors()) { - return {ptr, output, false}; // We found an error. } else { const __m512i lane0 = broadcast_epi128<0>(utf8); const __m512i lane1 = broadcast_epi128<1>(utf8); @@ -21336,8 +21319,8 @@ std::tuple validating_utf8_to_fixed_length_with_cons } validatedptr += 4*16; } - { - const __m512i utf8 = _mm512_maskz_loadu_epi8((1ULL<<(end - validatedptr))-1, (const __m512i*)validatedptr); + if (end != validatedptr) { + const __m512i utf8 = _mm512_maskz_loadu_epi8(~UINT64_C(0) >> (64 - (end - validatedptr)), (const __m512i*)validatedptr); checker.check_next_input(utf8); } checker.check_eof(); @@ -21352,7 +21335,6 @@ std::tuple validating_utf8_to_fixed_length_with_cons // File contains conversion procedure from possibly invalid UTF-8 strings. -// template template simdutf_really_inline size_t process_block_from_utf8_to_latin1(const char *buf, size_t len, char *latin_output, __m512i minus64, @@ -21363,15 +21345,17 @@ simdutf_really_inline size_t process_block_from_utf8_to_latin1(const char *buf, is_remaining ? _bzhi_u64(~0ULL, (unsigned int)len) : ~0ULL; __m512i input = _mm512_maskz_loadu_epi8(load_mask, (__m512i *)buf); __mmask64 nonascii = _mm512_movepi8_mask(input); - if (nonascii == 0) { + if(*next_leading_ptr) { // If we ended with a leading byte, it is an error. + return 0; // Indicates error + } is_remaining ? _mm512_mask_storeu_epi8((__m512i *)latin_output, load_mask, input) : _mm512_storeu_si512((__m512i *)latin_output, input); return len; } - __mmask64 leading = _mm512_cmpge_epu8_mask(input, minus64); + const __mmask64 leading = _mm512_cmpge_epu8_mask(input, minus64); __m512i highbits = _mm512_xor_si512(input, _mm512_set1_epi8(-62)); __mmask64 invalid_leading_bytes = @@ -21382,38 +21366,34 @@ simdutf_really_inline size_t process_block_from_utf8_to_latin1(const char *buf, } __mmask64 leading_shift = (leading << 1) | *next_leading_ptr; - *next_leading_ptr = leading >> 63; if ((nonascii ^ leading) != leading_shift) { return 0; // Indicates error } - __mmask64 bit6 = _mm512_cmpeq_epi8_mask(highbits, one); + const __mmask64 bit6 = _mm512_cmpeq_epi8_mask(highbits, one); input = _mm512_mask_sub_epi8(input, (bit6 << 1) | *next_bit6_ptr, input, minus64); - *next_bit6_ptr = bit6 >> 63; __mmask64 retain = ~leading & load_mask; __m512i output = _mm512_maskz_compress_epi8(retain, input); int64_t written_out = count_ones(retain); - __mmask64 store_mask = (1ULL << written_out) - 1; - - // *************************** - // Possible optimization? (Nick Nuon) - // This commented out line is 5% faster but sadly it'll also write past - // memory bounds for latin1_output: is_remaining ? - // _mm512_mask_storeu_epi8((__m512i *)latin_output, store_mask, output) : - // _mm512_storeu_si512((__m512i *)latin_output, output); I tried using - // _mm512_storeu_si512 and have the next process_block start from the - // "written_out" point but the compiler shuffles memory in such a way that it - // is significantly slower... - // **************************** + if(written_out == 0) { + return 0; // Indicates error + } + *next_bit6_ptr = bit6 >> 63; + *next_leading_ptr = leading >> 63; + + __mmask64 store_mask = ~UINT64_C(0) >> (64 - written_out); + _mm512_mask_storeu_epi8((__m512i *)latin_output, store_mask, output); return written_out; } -size_t utf8_to_latin1_avx512(const char *buf, size_t len, char *latin_output) { +size_t utf8_to_latin1_avx512(const char *&inbuf, size_t len, char *&inlatin_output) { + const char *buf = inbuf; + char *latin_output = inlatin_output; char *start = latin_output; size_t pos = 0; __m512i minus64 = _mm512_set1_epi8(-64); // 11111111111 ... 1100 0000 @@ -21425,7 +21405,9 @@ size_t utf8_to_latin1_avx512(const char *buf, size_t len, char *latin_output) { size_t written = process_block_from_utf8_to_latin1(buf + pos, 64, latin_output, minus64, one, &next_leading, &next_bit6); if (written == 0) { - return 0; // Indicates error + inlatin_output = latin_output; + inbuf = buf + pos - next_leading; + return 0; // Indicates error at pos or after, or just before pos (too short error) } latin_output += written; pos += 64; @@ -21437,12 +21419,20 @@ size_t utf8_to_latin1_avx512(const char *buf, size_t len, char *latin_output) { process_block_from_utf8_to_latin1(buf + pos, remaining, latin_output, minus64, one, &next_leading, &next_bit6); if (written == 0) { - return 0; // Indicates error + inbuf = buf + pos - next_leading; + inlatin_output = latin_output; + return 0; // Indicates error at pos or after, or just before pos (too short error) } latin_output += written; } - - return (size_t)(latin_output - start); + if(next_leading) { + inbuf = buf + len - next_leading; + inlatin_output = latin_output; + return 0; // Indicates error at end of buffer + } + inlatin_output = latin_output; + inbuf += len; + return size_t(latin_output - start); } /* end file src/icelake/icelake_convert_utf8_to_latin1.inl.cpp */ /* begin file src/icelake/icelake_convert_valid_utf8_to_latin1.inl.cpp */ @@ -21482,7 +21472,10 @@ simdutf_really_inline size_t process_valid_block_from_utf8_to_latin1(const char __mmask64 retain = ~leading & load_mask; __m512i output = _mm512_maskz_compress_epi8(retain, input); int64_t written_out = count_ones(retain); - __mmask64 store_mask = (1ULL << written_out) - 1; + if(written_out == 0) { + return 0; // Indicates error + } + __mmask64 store_mask = ~UINT64_C(0) >> (64 - written_out); // Optimization opportunity: sometimes, masked writes are not needed. _mm512_mask_storeu_epi8((__m512i *)latin_output, store_mask, output); return written_out; @@ -21530,7 +21523,7 @@ size_t icelake_convert_utf16_to_latin1(const char16_t *buf, size_t len, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 60, 58, 56, 54, 52, 50, 48, 46, 44, 42, 40, 38, 36, 34, 32, 30, 28, 26, 24, 22, 20, 18, 16, 14, 12, 10, 8, 6, 4, 2, 0); - while (buf + 32 <= end) { + while (end - buf >= 32) { __m512i in = _mm512_loadu_si512((__m512i *)buf); if (big_endian) { in = _mm512_shuffle_epi8(in, byteflip); @@ -21575,7 +21568,7 @@ icelake_convert_utf16_to_latin1_with_errors(const char16_t *buf, size_t len, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 60, 58, 56, 54, 52, 50, 48, 46, 44, 42, 40, 38, 36, 34, 32, 30, 28, 26, 24, 22, 20, 18, 16, 14, 12, 10, 8, 6, 4, 2, 0); - while (buf + 32 <= end) { + while (end - buf >= 32) { __m512i in = _mm512_loadu_si512((__m512i *)buf); if (big_endian) { in = _mm512_shuffle_epi8(in, byteflip); @@ -21646,7 +21639,7 @@ size_t utf16_to_utf8_avx512i(const char16_t *inbuf, size_t inlen, ); const char16_t * const inbuf_orig = inbuf; const unsigned char * const outbuf_orig = outbuf; - size_t adjust = 0; + int adjust = 0; int carry = 0; while (inlen >= 32) { @@ -21742,7 +21735,7 @@ size_t utf16_to_utf8_avx512i(const char16_t *inbuf, size_t inlen, const uint32_t lonohi = l & ~(h + h + carry); const uint32_t hinolo = h & ~(l >> 1); inlen = _tzcnt_u32(hinolo | lonohi); - inmask = __mmask32(0x7fffffff & ((1 << inlen) - 1)); + inmask = __mmask32(0x7fffffff & ((1U << inlen) - 1)); in = _mm512_maskz_mov_epi16(inmask, in); adjust = (int)inlen - 31; inlen = 0; @@ -21803,15 +21796,15 @@ size_t utf16_to_utf8_avx512i(const char16_t *inbuf, size_t inlen, _mm512_mask_storeu_epi8(outbuf + advlo, _cvtu64_mask64(_pext_u64(wanthi_uint64, wanthi_uint64)), outhi); outbuf += advlo + advhi; } - outbuf -= adjust; + outbuf += -adjust; tail: if (inlen != 0) { // We must have inlen < 31. - inmask = _cvtu32_mask32((1 << inlen) - 1); + inmask = _cvtu32_mask32((1U << inlen) - 1); in = _mm512_maskz_loadu_epi16(inmask, inbuf); if(big_endian) { in = _mm512_shuffle_epi8(in, byteflip); } - adjust = inlen - 31; + adjust = (int)inlen - 31; inlen = 0; goto lastiteration; } @@ -21940,7 +21933,7 @@ size_t icelake_convert_utf32_to_latin1(const char32_t *buf, size_t len, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 56, 52, 48, 44, 40, 36, 32, 28, 24, 20, 16, 12, 8, 4, 0); - while (buf + 16 <= end) { + while (end - buf >= 16) { __m512i in = _mm512_loadu_si512((__m512i *)buf); if (_mm512_cmpgt_epu32_mask(in, v_0xFF)) { return 0; @@ -21973,7 +21966,7 @@ icelake_convert_utf32_to_latin1_with_errors(const char32_t *buf, size_t len, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 56, 52, 48, 44, 40, 36, 32, 28, 24, 20, 16, 12, 8, 4, 0); - while (buf + 16 <= end) { + while (end - buf >= 16) { __m512i in = _mm512_loadu_si512((__m512i *)buf); if (_mm512_cmpgt_epu32_mask(in, v_0xFF)) { while (uint32_t(*buf) <= 0xff) { @@ -22021,7 +22014,7 @@ std::pair avx512_convert_utf32_to_utf8(const char32_t* b const size_t safety_margin = 12; // to avoid overruns, see issue https://github.com/simdutf/simdutf/issues/92 - while (buf + 16 + safety_margin <= end) { + while (end - buf >= std::ptrdiff_t(16 + safety_margin)) { __m256i in = _mm256_loadu_si256((__m256i*)buf); __m256i nextin = _mm256_loadu_si256((__m256i*)buf+1); running_max = _mm256_max_epu32(_mm256_max_epu32(in, running_max), nextin); @@ -22262,7 +22255,7 @@ std::pair avx512_convert_utf32_to_utf8_with_errors(const char32_t const size_t safety_margin = 12; // to avoid overruns, see issue https://github.com/simdutf/simdutf/issues/92 - while (buf + 16 + safety_margin <= end) { + while (end - buf >= std::ptrdiff_t(16 + safety_margin)) { __m256i in = _mm256_loadu_si256((__m256i*)buf); __m256i nextin = _mm256_loadu_si256((__m256i*)buf+1); // Check for too large input @@ -22501,7 +22494,7 @@ std::pair avx512_convert_utf32_to_utf16(const char32 __m256i forbidden_bytemask = _mm256_setzero_si256(); - while (buf + 8 + safety_margin <= end) { + while (end - buf >= std::ptrdiff_t(8 + safety_margin)) { __m256i in = _mm256_loadu_si256((__m256i*)buf); const __m256i v_00000000 = _mm256_setzero_si256(); @@ -22566,7 +22559,7 @@ std::pair avx512_convert_utf32_to_utf16_with_errors(const cha const size_t safety_margin = 12; // to avoid overruns, see issue https://github.com/simdutf/simdutf/issues/92 - while (buf + 8 + safety_margin <= end) { + while (end - buf >= std::ptrdiff_t(8 + safety_margin)) { __m256i in = _mm256_loadu_si256((__m256i*)buf); const __m256i v_00000000 = _mm256_setzero_si256(); @@ -22630,7 +22623,7 @@ bool validate_ascii(const char* buf, size_t len) { const char* end = buf + len; const __m512i ascii = _mm512_set1_epi8((uint8_t)0x80); __m512i running_or = _mm512_setzero_si512(); - for (; buf + 64 <= end; buf += 64) { + for (; end - buf >= 64; buf += 64) { const __m512i utf8 = _mm512_loadu_si512((const __m512i*)buf); running_or = _mm512_ternarylogic_epi32(running_or, utf8, ascii, 0xf8); // running_or | (utf8 & ascii) } @@ -22645,7 +22638,8 @@ bool validate_ascii(const char* buf, size_t len) { // file included directly const char32_t* validate_utf32(const char32_t* buf, size_t len) { - const char32_t* end = len >= 16 ? buf + len - 16 : nullptr; + if(len < 16) { return buf; } + const char32_t* end = buf + len - 16; const __m512i offset = _mm512_set1_epi32((uint32_t)0xffff2000); __m512i currentmax = _mm512_setzero_si512(); @@ -23010,19 +23004,22 @@ result compress_decode_base64(char *dst, const chartype *src, size_t srclen, base64_options options) { const uint8_t *to_base64 = base64_url ? tables::base64::to_base64_url_value : tables::base64::to_base64_value; + size_t equallocation = srclen; // location of the first padding character if any size_t equalsigns = 0; // skip trailing spaces - while (srclen > 0 && to_base64[uint8_t(src[srclen - 1])] == 64) { + while (srclen > 0 && scalar::base64::is_eight_byte(src[srclen - 1]) && to_base64[uint8_t(src[srclen - 1])] == 64) { srclen--; } if (srclen > 0 && src[srclen - 1] == '=') { + equallocation = srclen - 1; srclen--; equalsigns = 1; // skip trailing spaces - while (srclen > 0 && to_base64[uint8_t(src[srclen - 1])] == 64) { + while (srclen > 0 && scalar::base64::is_eight_byte(src[srclen - 1]) && to_base64[uint8_t(src[srclen - 1])] == 64) { srclen--; } if (srclen > 0 && src[srclen - 1] == '=') { + equallocation = srclen - 1; srclen--; equalsigns = 2; } @@ -23045,7 +23042,7 @@ result compress_decode_base64(char *dst, const chartype *src, size_t srclen, uint64_t badcharmask = to_base64_mask(&b, &error); if (error) { src -= 64; - while (src < srcend && to_base64[uint8_t(*src)] <= 64) { + while (src < srcend && scalar::base64::is_eight_byte(*src) && to_base64[uint8_t(*src)] <= 64) { src++; } return {error_code::INVALID_BASE64_CHARACTER, size_t(src - srcinit)}; @@ -23083,7 +23080,7 @@ result compress_decode_base64(char *dst, const chartype *src, size_t srclen, while ((bufferptr - buffer_start) % 64 != 0 && src < srcend) { uint8_t val = to_base64[uint8_t(*src)]; *bufferptr = char(val); - if (val > 64) { + if (!scalar::base64::is_eight_byte(*src) || val > 64) { return {error_code::INVALID_BASE64_CHARACTER, size_t(src - srcinit)}; } bufferptr += (val <= 63); @@ -23124,7 +23121,7 @@ result compress_decode_base64(char *dst, const chartype *src, size_t srclen, if (leftover > 0) { while (leftover < 4 && src < srcend) { uint8_t val = to_base64[uint8_t(*src)]; - if (val > 64) { + if (!scalar::base64::is_eight_byte(*src) || val > 64) { return {error_code::INVALID_BASE64_CHARACTER, size_t(src - srcinit)}; } buffer_start[leftover] = char(val); @@ -23176,13 +23173,14 @@ result compress_decode_base64(char *dst, const chartype *src, size_t srclen, // additional checks if((r.count % 3 == 0) || ((r.count % 3) + 1 + equalsigns != 4)) { r.error = error_code::INVALID_BASE64_CHARACTER; + r.count = equallocation; } } return r; } if(equalsigns > 0) { if((size_t(dst - dstinit) % 3 == 0) || ((size_t(dst - dstinit) % 3) + 1 + equalsigns != 4)) { - return {INVALID_BASE64_CHARACTER, size_t(dst - dstinit)}; + return {INVALID_BASE64_CHARACTER, equallocation}; } } return {SUCCESS, size_t(dst - dstinit)}; @@ -23204,142 +23202,32 @@ implementation::detect_encodings(const char *input, size_t length) const noexcept { // If there is a BOM, then we trust it. auto bom_encoding = simdutf::BOM::check_bom(input, length); + // todo: convert to a one-pass algorithm if(bom_encoding != encoding_type::unspecified) { return bom_encoding; } - if (length % 2 == 0) { - const char *buf = input; - - const char *start = buf; - const char *end = input + length; - - bool is_utf8 = true; - bool is_utf16 = true; - bool is_utf32 = true; - - int out = 0; - - avx512_utf8_checker checker{}; - __m512i currentmax = _mm512_setzero_si512(); - while (buf + 64 <= end) { - __m512i in = _mm512_loadu_si512((__m512i *)buf); - __m512i diff = _mm512_sub_epi16(in, _mm512_set1_epi16(uint16_t(0xD800))); - __mmask32 surrogates = - _mm512_cmplt_epu16_mask(diff, _mm512_set1_epi16(uint16_t(0x0800))); - if (surrogates) { - is_utf8 = false; - - // Can still be either UTF-16LE or UTF-32 depending on the positions - // of the surrogates To be valid UTF-32, a surrogate cannot be in the - // two most significant bytes of any 32-bit word. On the other hand, to - // be valid UTF-16LE, at least one surrogate must be in the two most - // significant bytes of a 32-bit word since they always come in pairs in - // UTF-16LE. Note that we always proceed in multiple of 4 before this - // point so there is no offset in 32-bit code units. - - if ((surrogates & 0xaaaaaaaa) != 0) { - is_utf32 = false; - __mmask32 highsurrogates = _mm512_cmplt_epu16_mask( - diff, _mm512_set1_epi16(uint16_t(0x0400))); - __mmask32 lowsurrogates = surrogates ^ highsurrogates; - // high must be followed by low - if ((highsurrogates << 1) != lowsurrogates) { - return simdutf::encoding_type::unspecified; - } - - bool ends_with_high = ((highsurrogates & 0x80000000) != 0); - if (ends_with_high) { - buf += - 31 * - sizeof(char16_t); // advance only by 31 code units so that we start - // with the high surrogate on the next round. - } else { - buf += 32 * sizeof(char16_t); - } - is_utf16 = validate_utf16le(reinterpret_cast(buf), - (end - buf) / sizeof(char16_t)); - if (!is_utf16) { - return simdutf::encoding_type::unspecified; - - } else { - return simdutf::encoding_type::UTF16_LE; - } - - } else { - is_utf16 = false; - // Check for UTF-32 - if (length % 4 == 0) { - const char32_t *input32 = reinterpret_cast(buf); - const char32_t *end32 = - reinterpret_cast(start) + length / 4; - if (validate_utf32(input32, end32 - input32)) { - return simdutf::encoding_type::UTF32_LE; - } - } - return simdutf::encoding_type::unspecified; - } - } - // If no surrogate, validate under other encodings as well - - // UTF-32 validation - currentmax = _mm512_max_epu32(in, currentmax); - - // UTF-8 validation - checker.check_next_input(in); - - buf += 64; - } - - // Check which encodings are possible - - if (is_utf8) { - size_t current_length = static_cast(buf - start); - if (current_length != length) { - const __m512i utf8 = _mm512_maskz_loadu_epi8( - (1ULL << (length - current_length)) - 1, (const __m512i *)buf); - checker.check_next_input(utf8); - } - checker.check_eof(); - if (!checker.errors()) { - out |= simdutf::encoding_type::UTF8; - } - } - - if (is_utf16 && scalar::utf16::validate( - reinterpret_cast(buf), - (length - (buf - start)) / 2)) { - out |= simdutf::encoding_type::UTF16_LE; - } - - if (is_utf32 && (length % 4 == 0)) { - currentmax = _mm512_max_epu32( - _mm512_maskz_loadu_epi8( - (1ULL << (length - static_cast(buf - start))) - 1, - (const __m512i *)buf), - currentmax); - __mmask16 outside_range = _mm512_cmp_epu32_mask(currentmax, _mm512_set1_epi32(0x10ffff), - _MM_CMPINT_GT); - if (outside_range == 0) { - out |= simdutf::encoding_type::UTF32_LE; - } - } - - return out; - } else if (implementation::validate_utf8(input, length)) { - return simdutf::encoding_type::UTF8; - } else { - return simdutf::encoding_type::unspecified; + int out = 0; + if(validate_utf8(input, length)) { out |= encoding_type::UTF8; } + if((length % 2) == 0) { + if(validate_utf16le(reinterpret_cast(input), length/2)) { out |= encoding_type::UTF16_LE; } + } + if((length % 4) == 0) { + if(validate_utf32(reinterpret_cast(input), length/4)) { out |= encoding_type::UTF32_LE; } } + return out; } simdutf_warn_unused bool implementation::validate_utf8(const char *buf, size_t len) const noexcept { + if (simdutf_unlikely(len == 0)) { + return true; + } avx512_utf8_checker checker{}; const char* ptr = buf; const char* end = ptr + len; - for (; ptr + 64 <= end; ptr += 64) { + for (; end - ptr >= 64 ; ptr += 64) { const __m512i utf8 = _mm512_loadu_si512((const __m512i*)ptr); checker.check_next_input(utf8); } - { - const __m512i utf8 = _mm512_maskz_loadu_epi8((1ULL<<(end - ptr))-1, (const __m512i*)ptr); + if(end != ptr) { + const __m512i utf8 = _mm512_maskz_loadu_epi8(~UINT64_C(0) >> (64 - (end - ptr)), (const __m512i*)ptr); checker.check_next_input(utf8); } checker.check_eof(); @@ -23347,11 +23235,14 @@ simdutf_warn_unused bool implementation::validate_utf8(const char *buf, size_t l } simdutf_warn_unused result implementation::validate_utf8_with_errors(const char *buf, size_t len) const noexcept { + if (simdutf_unlikely(len == 0)) { + return result(error_code::SUCCESS, len); + } avx512_utf8_checker checker{}; const char* ptr = buf; const char* end = ptr + len; size_t count{0}; - for (; ptr + 64 <= end; ptr += 64) { + for (; end - ptr >= 64 ; ptr += 64) { const __m512i utf8 = _mm512_loadu_si512((const __m512i*)ptr); checker.check_next_input(utf8); if(checker.errors()) { @@ -23362,18 +23253,18 @@ simdutf_warn_unused result implementation::validate_utf8_with_errors(const char } count += 64; } - { - const __m512i utf8 = _mm512_maskz_loadu_epi8((1ULL<<(end - ptr))-1, (const __m512i*)ptr); + if (end != ptr) { + const __m512i utf8 = _mm512_maskz_loadu_epi8(~UINT64_C(0) >> (64 - (end - ptr)), (const __m512i*)ptr); checker.check_next_input(utf8); - if(checker.errors()) { - if (count != 0) { count--; } // Sometimes the error is only detected in the next chunk - result res = scalar::utf8::rewind_and_validate_with_errors(reinterpret_cast(buf), reinterpret_cast(buf + count), len - count); - res.count += count; - return res; - } else { - return result(error_code::SUCCESS, len); - } } + checker.check_eof(); + if(checker.errors()) { + if (count != 0) { count--; } // Sometimes the error is only detected in the next chunk + result res = scalar::utf8::rewind_and_validate_with_errors(reinterpret_cast(buf), reinterpret_cast(buf + count), len - count); + res.count += count; + return res; + } + return result(error_code::SUCCESS, len); } simdutf_warn_unused bool implementation::validate_ascii(const char *buf, size_t len) const noexcept { @@ -23384,15 +23275,15 @@ simdutf_warn_unused result implementation::validate_ascii_with_errors(const char const char* buf_orig = buf; const char* end = buf + len; const __m512i ascii = _mm512_set1_epi8((uint8_t)0x80); - for (; buf + 64 <= end; buf += 64) { + for (; end - buf >= 64 ; buf += 64) { const __m512i input = _mm512_loadu_si512((const __m512i*)buf); __mmask64 notascii = _mm512_cmp_epu8_mask(input, ascii, _MM_CMPINT_NLT); if(notascii) { return result(error_code::TOO_LARGE, buf - buf_orig + _tzcnt_u64(notascii)); } } - { - const __m512i input = _mm512_maskz_loadu_epi8((1ULL<<(end - buf))-1, (const __m512i*)buf); + if (end != buf) { + const __m512i input = _mm512_maskz_loadu_epi8(~UINT64_C(0) >> (64 - (end - buf)), (const __m512i*)buf); __mmask64 notascii = _mm512_cmp_epu8_mask(input, ascii, _MM_CMPINT_NLT); if(notascii) { return result(error_code::TOO_LARGE, buf - buf_orig + _tzcnt_u64(notascii)); @@ -23404,7 +23295,7 @@ simdutf_warn_unused result implementation::validate_ascii_with_errors(const char simdutf_warn_unused bool implementation::validate_utf16le(const char16_t *buf, size_t len) const noexcept { const char16_t *end = buf + len; - for(;buf + 32 <= end; ) { + for(;end - buf >= 32; ) { __m512i in = _mm512_loadu_si512((__m512i*)buf); __m512i diff = _mm512_sub_epi16(in, _mm512_set1_epi16(uint16_t(0xD800))); __mmask32 surrogates = _mm512_cmplt_epu16_mask(diff, _mm512_set1_epi16(uint16_t(0x0800))); @@ -23426,7 +23317,7 @@ simdutf_warn_unused bool implementation::validate_utf16le(const char16_t *buf, s } } if(buf < end) { - __m512i in = _mm512_maskz_loadu_epi16((1<<(end-buf))-1,(__m512i*)buf); + __m512i in = _mm512_maskz_loadu_epi16((1U<<(end-buf))-1,(__m512i*)buf); __m512i diff = _mm512_sub_epi16(in, _mm512_set1_epi16(uint16_t(0xD800))); __mmask32 surrogates = _mm512_cmplt_epu16_mask(diff, _mm512_set1_epi16(uint16_t(0x0800))); if(surrogates) { @@ -23453,7 +23344,7 @@ simdutf_warn_unused bool implementation::validate_utf16be(const char16_t *buf, s 0x0607040502030001, 0x0e0f0c0d0a0b0809 ); - for(;buf + 32 <= end; ) { + for(;end - buf >= 32; ) { __m512i in = _mm512_shuffle_epi8(_mm512_loadu_si512((__m512i*)buf), byteflip); __m512i diff = _mm512_sub_epi16(in, _mm512_set1_epi16(uint16_t(0xD800))); __mmask32 surrogates = _mm512_cmplt_epu16_mask(diff, _mm512_set1_epi16(uint16_t(0x0800))); @@ -23475,7 +23366,7 @@ simdutf_warn_unused bool implementation::validate_utf16be(const char16_t *buf, s } } if(buf < end) { - __m512i in = _mm512_shuffle_epi8(_mm512_maskz_loadu_epi16((1<<(end-buf))-1,(__m512i*)buf), byteflip); + __m512i in = _mm512_shuffle_epi8(_mm512_maskz_loadu_epi16((1U<<(end-buf))-1,(__m512i*)buf), byteflip); __m512i diff = _mm512_sub_epi16(in, _mm512_set1_epi16(uint16_t(0xD800))); __mmask32 surrogates = _mm512_cmplt_epu16_mask(diff, _mm512_set1_epi16(uint16_t(0x0800))); if(surrogates) { @@ -23493,7 +23384,7 @@ simdutf_warn_unused bool implementation::validate_utf16be(const char16_t *buf, s simdutf_warn_unused result implementation::validate_utf16le_with_errors(const char16_t *buf, size_t len) const noexcept { const char16_t *start_buf = buf; const char16_t *end = buf + len; - for(;buf + 32 <= end; ) { + for(;end - buf >= 32; ) { __m512i in = _mm512_loadu_si512((__m512i*)buf); __m512i diff = _mm512_sub_epi16(in, _mm512_set1_epi16(uint16_t(0xD800))); __mmask32 surrogates = _mm512_cmplt_epu16_mask(diff, _mm512_set1_epi16(uint16_t(0x0800))); @@ -23517,7 +23408,7 @@ simdutf_warn_unused result implementation::validate_utf16le_with_errors(const ch } } if(buf < end) { - __m512i in = _mm512_maskz_loadu_epi16((1<<(end-buf))-1,(__m512i*)buf); + __m512i in = _mm512_maskz_loadu_epi16((1U<<(end-buf))-1,(__m512i*)buf); __m512i diff = _mm512_sub_epi16(in, _mm512_set1_epi16(uint16_t(0xD800))); __mmask32 surrogates = _mm512_cmplt_epu16_mask(diff, _mm512_set1_epi16(uint16_t(0x0800))); if(surrogates) { @@ -23547,7 +23438,7 @@ simdutf_warn_unused result implementation::validate_utf16be_with_errors(const ch 0x0607040502030001, 0x0e0f0c0d0a0b0809 ); - for(;buf + 32 <= end; ) { + for(;end - buf >= 32; ) { __m512i in = _mm512_shuffle_epi8(_mm512_loadu_si512((__m512i*)buf), byteflip); __m512i diff = _mm512_sub_epi16(in, _mm512_set1_epi16(uint16_t(0xD800))); __mmask32 surrogates = _mm512_cmplt_epu16_mask(diff, _mm512_set1_epi16(uint16_t(0x0800))); @@ -23571,7 +23462,7 @@ simdutf_warn_unused result implementation::validate_utf16be_with_errors(const ch } } if(buf < end) { - __m512i in = _mm512_shuffle_epi8(_mm512_maskz_loadu_epi16((1<<(end-buf))-1,(__m512i*)buf), byteflip); + __m512i in = _mm512_shuffle_epi8(_mm512_maskz_loadu_epi16((1U<<(end-buf))-1,(__m512i*)buf), byteflip); __m512i diff = _mm512_sub_epi16(in, _mm512_set1_epi16(uint16_t(0xD800))); __mmask32 surrogates = _mm512_cmplt_epu16_mask(diff, _mm512_set1_epi16(uint16_t(0x0800))); if(surrogates) { @@ -23593,48 +23484,60 @@ simdutf_warn_unused bool implementation::validate_utf32(const char32_t *buf, siz if (tail) { return scalar::utf32::validate(tail, len - (tail - buf)); } else { - return false; + // we come here if there was an error, or buf was nullptr which may happen for empty input. + return len == 0; } } simdutf_warn_unused result implementation::validate_utf32_with_errors(const char32_t *buf, size_t len) const noexcept { - - const char32_t* end = len >= 16 ? buf + len - 16 : nullptr; - const char32_t* buf_orig = buf; + const char32_t* buf_orig = buf; + if(len >= 16) { + const char32_t* end = buf + len - 16; while (buf <= end) { __m512i utf32 = _mm512_loadu_si512((const __m512i*)buf); __mmask16 outside_range = _mm512_cmp_epu32_mask(utf32, _mm512_set1_epi32(0x10ffff), _MM_CMPINT_GT); - if (outside_range) { - return result(error_code::TOO_LARGE, buf - buf_orig + _tzcnt_u32(outside_range)); - } __m512i utf32_off = _mm512_add_epi32(utf32, _mm512_set1_epi32(0xffff2000)); __mmask16 surrogate_range = _mm512_cmp_epu32_mask(utf32_off, _mm512_set1_epi32(0xfffff7ff), _MM_CMPINT_GT); - if (surrogate_range) { - return result(error_code::SURROGATE, buf - buf_orig + _tzcnt_u32(surrogate_range)); + if((outside_range | surrogate_range)) { + auto outside_idx = _tzcnt_u32(outside_range); + auto surrogate_idx = _tzcnt_u32(surrogate_range); + + if (outside_idx < surrogate_idx) { + return result(error_code::TOO_LARGE, buf - buf_orig + outside_idx); + } + + return result(error_code::SURROGATE, buf - buf_orig + surrogate_idx); } + buf += 16; } - if(buf < buf_orig + len) { - __m512i utf32 = _mm512_maskz_loadu_epi32(__mmask16((1<<(buf_orig + len - buf))-1),(const __m512i*)buf); - __mmask16 outside_range = _mm512_cmp_epu32_mask(utf32, _mm512_set1_epi32(0x10ffff), - _MM_CMPINT_GT); - if (outside_range) { - return result(error_code::TOO_LARGE, buf - buf_orig + _tzcnt_u32(outside_range)); - } - __m512i utf32_off = _mm512_add_epi32(utf32, _mm512_set1_epi32(0xffff2000)); + } + if(len > 0) { + __m512i utf32 = _mm512_maskz_loadu_epi32(__mmask16((1U<<(buf_orig + len - buf))-1),(const __m512i*)buf); + __mmask16 outside_range = _mm512_cmp_epu32_mask(utf32, _mm512_set1_epi32(0x10ffff), + _MM_CMPINT_GT); + __m512i utf32_off = _mm512_add_epi32(utf32, _mm512_set1_epi32(0xffff2000)); - __mmask16 surrogate_range = _mm512_cmp_epu32_mask(utf32_off, _mm512_set1_epi32(0xfffff7ff), - _MM_CMPINT_GT); - if (surrogate_range) { - return result(error_code::SURROGATE, buf - buf_orig + _tzcnt_u32(surrogate_range)); + __mmask16 surrogate_range = _mm512_cmp_epu32_mask(utf32_off, _mm512_set1_epi32(0xfffff7ff), + _MM_CMPINT_GT); + if((outside_range | surrogate_range)) { + auto outside_idx = _tzcnt_u32(outside_range); + auto surrogate_idx = _tzcnt_u32(surrogate_range); + + if (outside_idx < surrogate_idx) { + return result(error_code::TOO_LARGE, buf - buf_orig + outside_idx); } + + return result(error_code::SURROGATE, buf - buf_orig + surrogate_idx); } - return result(error_code::SUCCESS, len); + } + + return result(error_code::SUCCESS, len); } simdutf_warn_unused size_t implementation::convert_latin1_to_utf8(const char * buf, size_t len, char* utf8_output) const noexcept { @@ -23668,24 +23571,18 @@ simdutf_warn_unused size_t implementation::convert_utf8_to_latin1(const char* bu simdutf_warn_unused result implementation::convert_utf8_to_latin1_with_errors(const char* buf, size_t len, char* latin1_output) const noexcept { - // Initialize output length and input length counters - size_t inlen = 0; - // First, try to convert as much as possible using the SIMD implementation. - inlen = icelake::utf8_to_latin1_avx512(buf, len, latin1_output); + const char * obuf = buf; + char * olatin1_output = latin1_output; + size_t written = icelake::utf8_to_latin1_avx512(obuf, len, olatin1_output); // If we have completely converted the string - if(inlen == len) { - return {simdutf::SUCCESS, len}; + if(obuf == buf + len) { + return {simdutf::SUCCESS, written}; } - - // Else if there are remaining bytes, use the scalar function to process them. - // Note: This is assuming scalar::utf8_to_latin1::convert_with_errors is a function that takes - // the input buffer, length, and output buffer, and returns a result object with an error code - // and the number of characters processed. - result res = scalar::utf8_to_latin1::convert_with_errors(buf + inlen, len - inlen, latin1_output + inlen); - res.count += inlen; // Add the number of characters processed by the SIMD implementation - + size_t pos = obuf - buf; + result res = scalar::utf8_to_latin1::rewind_and_convert_with_errors(pos, buf + pos, len - pos, latin1_output); + res.count += pos; return res; } @@ -23790,10 +23687,9 @@ simdutf_warn_unused size_t implementation::convert_utf8_to_utf32(const char* buf // continuation bytes lie outside 16-byte window. // It means, we have to skip continuation bytes from // the beginning ret.first, as they were already consumed. - while (ret.first != end and ((uint8_t(*ret.first) & 0xc0) == 0x80)) { + while (ret.first != end && ((uint8_t(*ret.first) & 0xc0) == 0x80)) { ret.first += 1; } - if (ret.first != end) { const size_t scalar_saved_bytes = scalar::utf8_to_utf32::convert( ret.first, len - (ret.first - buf), utf32_out + saved_bytes); @@ -23805,15 +23701,33 @@ simdutf_warn_unused size_t implementation::convert_utf8_to_utf32(const char* buf } simdutf_warn_unused result implementation::convert_utf8_to_utf32_with_errors(const char* buf, size_t len, char32_t* utf32) const noexcept { + if (simdutf_unlikely(len == 0)) { + return {error_code::SUCCESS, 0}; + } uint32_t * utf32_output = reinterpret_cast(utf32); auto ret = icelake::validating_utf8_to_fixed_length_with_constant_checks(buf, len, utf32_output); + if (!std::get<2>(ret)) { - auto new_buf = std::get<0>(ret); - // rewind_and_convert_with_errors will seek a potential error from new_buf onward, - // with the ability to go back up to new_buf - buf bytes, and read len - (new_buf - buf) bytes forward. - result res = scalar::utf8_to_utf32::rewind_and_convert_with_errors(new_buf - buf, new_buf, len - (new_buf - buf), reinterpret_cast(std::get<1>(ret))); - res.count += (std::get<0>(ret) - buf); - return res; + size_t pos = std::get<0>(ret) - buf; + // We might have an error that occurs right before pos. + // This is only a concern if buf[pos] is not a continuation byte. + if((buf[pos] & 0xc0) != 0x80 && pos >= 64) { + pos -= 1; + } else if ((buf[pos] & 0xc0) == 0x80 && pos >= 64) { + // We must check whether we are the fourth continuation byte + bool c1 = (buf[pos - 1] & 0xc0) == 0x80; + bool c2 = (buf[pos - 2] & 0xc0) == 0x80; + bool c3 = (buf[pos - 3] & 0xc0) == 0x80; + if(c1 && c2 && c3) { + return {simdutf::TOO_LONG, pos}; + } + } + // todo: we reset the output to utf32 instead of using std::get<2.(ret) as you'd expect. + // that is because validating_utf8_to_fixed_length_with_constant_checks may have processed + // data beyond the error. + result res = scalar::utf8_to_utf32::rewind_and_convert_with_errors(pos, buf + pos, len - pos, utf32); + res.count += pos; + return res; } size_t saved_bytes = std::get<1>(ret) - utf32_output; const char* end = buf + len; @@ -23918,7 +23832,7 @@ simdutf_warn_unused result implementation::convert_utf16le_to_utf8_with_errors(c size_t outlen; size_t inlen = utf16_to_utf8_avx512i(buf, len, (unsigned char*)utf8_output, &outlen); if(inlen != len) { - result res = scalar::utf16_to_utf8::convert_with_errors(buf + inlen, len - outlen, utf8_output + outlen); + result res = scalar::utf16_to_utf8::convert_with_errors(buf + inlen, len - inlen, utf8_output + outlen); res.count += inlen; return res; } @@ -23929,7 +23843,7 @@ simdutf_warn_unused result implementation::convert_utf16be_to_utf8_with_errors(c size_t outlen; size_t inlen = utf16_to_utf8_avx512i(buf, len, (unsigned char*)utf8_output, &outlen); if(inlen != len) { - result res = scalar::utf16_to_utf8::convert_with_errors(buf + inlen, len - outlen, utf8_output + outlen); + result res = scalar::utf16_to_utf8::convert_with_errors(buf + inlen, len - inlen, utf8_output + outlen); res.count += inlen; return res; } @@ -24176,7 +24090,7 @@ void implementation::change_endianness_utf16(const char16_t * input, size_t leng pos += 32; } if(pos < length) { - __mmask32 m((1<< (length - pos))-1); + __mmask32 m((1U<< (length - pos))-1); __m512i utf16 = _mm512_maskz_loadu_epi16(m, (const __m512i*)(input + pos)); utf16 = _mm512_shuffle_epi8(utf16, byteflip); _mm512_mask_storeu_epi16(output + pos, m, utf16); @@ -24185,47 +24099,53 @@ void implementation::change_endianness_utf16(const char16_t * input, size_t leng simdutf_warn_unused size_t implementation::count_utf16le(const char16_t * input, size_t length) const noexcept { - const char16_t* end = length >= 32 ? input + length - 32 : nullptr; const char16_t* ptr = input; + size_t count{0}; - const __m512i low = _mm512_set1_epi16((uint16_t)0xdc00); - const __m512i high = _mm512_set1_epi16((uint16_t)0xdfff); + if(length >= 32) { + const char16_t* end = input + length - 32; - size_t count{0}; + const __m512i low = _mm512_set1_epi16((uint16_t)0xdc00); + const __m512i high = _mm512_set1_epi16((uint16_t)0xdfff); - while (ptr <= end) { - __m512i utf16 = _mm512_loadu_si512((const __m512i*)ptr); - ptr += 32; - uint64_t not_high_surrogate = static_cast(_mm512_cmpgt_epu16_mask(utf16, high) | _mm512_cmplt_epu16_mask(utf16, low)); - count += count_ones(not_high_surrogate); + + while (ptr <= end) { + __m512i utf16 = _mm512_loadu_si512((const __m512i*)ptr); + ptr += 32; + uint64_t not_high_surrogate = static_cast(_mm512_cmpgt_epu16_mask(utf16, high) | _mm512_cmplt_epu16_mask(utf16, low)); + count += count_ones(not_high_surrogate); + } } return count + scalar::utf16::count_code_points(ptr, length - (ptr - input)); } simdutf_warn_unused size_t implementation::count_utf16be(const char16_t * input, size_t length) const noexcept { - const char16_t* end = length >= 32 ? input + length - 32 : nullptr; const char16_t* ptr = input; + size_t count{0}; + if(length >= 32) { - const __m512i low = _mm512_set1_epi16((uint16_t)0xdc00); - const __m512i high = _mm512_set1_epi16((uint16_t)0xdfff); + const char16_t* end = input + length - 32; - size_t count{0}; - const __m512i byteflip = _mm512_setr_epi64( - 0x0607040502030001, - 0x0e0f0c0d0a0b0809, - 0x0607040502030001, - 0x0e0f0c0d0a0b0809, - 0x0607040502030001, - 0x0e0f0c0d0a0b0809, - 0x0607040502030001, - 0x0e0f0c0d0a0b0809 - ); - while (ptr <= end) { - __m512i utf16 = _mm512_shuffle_epi8(_mm512_loadu_si512((__m512i*)ptr), byteflip); - ptr += 32; - uint64_t not_high_surrogate = static_cast(_mm512_cmpgt_epu16_mask(utf16, high) | _mm512_cmplt_epu16_mask(utf16, low)); - count += count_ones(not_high_surrogate); + const __m512i low = _mm512_set1_epi16((uint16_t)0xdc00); + const __m512i high = _mm512_set1_epi16((uint16_t)0xdfff); + + const __m512i byteflip = _mm512_setr_epi64( + 0x0607040502030001, + 0x0e0f0c0d0a0b0809, + 0x0607040502030001, + 0x0e0f0c0d0a0b0809, + 0x0607040502030001, + 0x0e0f0c0d0a0b0809, + 0x0607040502030001, + 0x0e0f0c0d0a0b0809 + ); + while (ptr <= end) { + __m512i utf16 = _mm512_shuffle_epi8(_mm512_loadu_si512((__m512i*)ptr), byteflip); + ptr += 32; + uint64_t not_high_surrogate = static_cast(_mm512_cmpgt_epu16_mask(utf16, high) | _mm512_cmplt_epu16_mask(utf16, low)); + count += count_ones(not_high_surrogate); + } } return count + scalar::utf16::count_code_points(ptr, length - (ptr - input)); @@ -24304,69 +24224,74 @@ simdutf_warn_unused size_t implementation::latin1_length_from_utf32(size_t lengt } simdutf_warn_unused size_t implementation::utf8_length_from_utf16le(const char16_t * input, size_t length) const noexcept { - const char16_t* end = length >= 32 ? input + length - 32 : nullptr; const char16_t* ptr = input; + size_t count{0}; + if(length >= 32) { + const char16_t* end = input + length - 32; - const __m512i v_007f = _mm512_set1_epi16((uint16_t)0x007f); - const __m512i v_07ff = _mm512_set1_epi16((uint16_t)0x07ff); - const __m512i v_dfff = _mm512_set1_epi16((uint16_t)0xdfff); - const __m512i v_d800 = _mm512_set1_epi16((uint16_t)0xd800); + const __m512i v_007f = _mm512_set1_epi16((uint16_t)0x007f); + const __m512i v_07ff = _mm512_set1_epi16((uint16_t)0x07ff); + const __m512i v_dfff = _mm512_set1_epi16((uint16_t)0xdfff); + const __m512i v_d800 = _mm512_set1_epi16((uint16_t)0xd800); - size_t count{0}; - while (ptr <= end) { - __m512i utf16 = _mm512_loadu_si512((const __m512i*)ptr); - ptr += 32; - __mmask32 ascii_bitmask = _mm512_cmple_epu16_mask(utf16, v_007f); - __mmask32 two_bytes_bitmask = _mm512_mask_cmple_epu16_mask(~ascii_bitmask, utf16, v_07ff); - __mmask32 not_one_two_bytes = ~(ascii_bitmask | two_bytes_bitmask); - __mmask32 surrogates_bitmask = _mm512_mask_cmple_epu16_mask(not_one_two_bytes, utf16, v_dfff) & _mm512_mask_cmpge_epu16_mask(not_one_two_bytes, utf16, v_d800); + while (ptr <= end) { + __m512i utf16 = _mm512_loadu_si512((const __m512i*)ptr); + ptr += 32; + __mmask32 ascii_bitmask = _mm512_cmple_epu16_mask(utf16, v_007f); + __mmask32 two_bytes_bitmask = _mm512_mask_cmple_epu16_mask(~ascii_bitmask, utf16, v_07ff); + __mmask32 not_one_two_bytes = ~(ascii_bitmask | two_bytes_bitmask); + __mmask32 surrogates_bitmask = _mm512_mask_cmple_epu16_mask(not_one_two_bytes, utf16, v_dfff) & _mm512_mask_cmpge_epu16_mask(not_one_two_bytes, utf16, v_d800); - size_t ascii_count = count_ones(ascii_bitmask); - size_t two_bytes_count = count_ones(two_bytes_bitmask); - size_t surrogate_bytes_count = count_ones(surrogates_bitmask); - size_t three_bytes_count = 32 - ascii_count - two_bytes_count - surrogate_bytes_count; + size_t ascii_count = count_ones(ascii_bitmask); + size_t two_bytes_count = count_ones(two_bytes_bitmask); + size_t surrogate_bytes_count = count_ones(surrogates_bitmask); + size_t three_bytes_count = 32 - ascii_count - two_bytes_count - surrogate_bytes_count; - count += ascii_count + 2*two_bytes_count + 3*three_bytes_count + 2*surrogate_bytes_count; + count += ascii_count + 2*two_bytes_count + 3*three_bytes_count + 2*surrogate_bytes_count; + } } return count + scalar::utf16::utf8_length_from_utf16(ptr, length - (ptr - input)); } simdutf_warn_unused size_t implementation::utf8_length_from_utf16be(const char16_t * input, size_t length) const noexcept { - const char16_t* end = length >= 32 ? input + length - 32 : nullptr; const char16_t* ptr = input; + size_t count{0}; - const __m512i v_007f = _mm512_set1_epi16((uint16_t)0x007f); - const __m512i v_07ff = _mm512_set1_epi16((uint16_t)0x07ff); - const __m512i v_dfff = _mm512_set1_epi16((uint16_t)0xdfff); - const __m512i v_d800 = _mm512_set1_epi16((uint16_t)0xd800); + if(length >= 32) { + const char16_t* end = input + length - 32; - size_t count{0}; - const __m512i byteflip = _mm512_setr_epi64( - 0x0607040502030001, - 0x0e0f0c0d0a0b0809, - 0x0607040502030001, - 0x0e0f0c0d0a0b0809, - 0x0607040502030001, - 0x0e0f0c0d0a0b0809, - 0x0607040502030001, - 0x0e0f0c0d0a0b0809 - ); - while (ptr <= end) { - __m512i utf16 = _mm512_loadu_si512((const __m512i*)ptr); - utf16 = _mm512_shuffle_epi8(utf16, byteflip); - ptr += 32; - __mmask32 ascii_bitmask = _mm512_cmple_epu16_mask(utf16, v_007f); - __mmask32 two_bytes_bitmask = _mm512_mask_cmple_epu16_mask(~ascii_bitmask, utf16, v_07ff); - __mmask32 not_one_two_bytes = ~(ascii_bitmask | two_bytes_bitmask); - __mmask32 surrogates_bitmask = _mm512_mask_cmple_epu16_mask(not_one_two_bytes, utf16, v_dfff) & _mm512_mask_cmpge_epu16_mask(not_one_two_bytes, utf16, v_d800); + const __m512i v_007f = _mm512_set1_epi16((uint16_t)0x007f); + const __m512i v_07ff = _mm512_set1_epi16((uint16_t)0x07ff); + const __m512i v_dfff = _mm512_set1_epi16((uint16_t)0xdfff); + const __m512i v_d800 = _mm512_set1_epi16((uint16_t)0xd800); - size_t ascii_count = count_ones(ascii_bitmask); - size_t two_bytes_count = count_ones(two_bytes_bitmask); - size_t surrogate_bytes_count = count_ones(surrogates_bitmask); - size_t three_bytes_count = 32 - ascii_count - two_bytes_count - surrogate_bytes_count; - count += ascii_count + 2*two_bytes_count + 3*three_bytes_count + 2*surrogate_bytes_count; + const __m512i byteflip = _mm512_setr_epi64( + 0x0607040502030001, + 0x0e0f0c0d0a0b0809, + 0x0607040502030001, + 0x0e0f0c0d0a0b0809, + 0x0607040502030001, + 0x0e0f0c0d0a0b0809, + 0x0607040502030001, + 0x0e0f0c0d0a0b0809 + ); + while (ptr <= end) { + __m512i utf16 = _mm512_loadu_si512((const __m512i*)ptr); + utf16 = _mm512_shuffle_epi8(utf16, byteflip); + ptr += 32; + __mmask32 ascii_bitmask = _mm512_cmple_epu16_mask(utf16, v_007f); + __mmask32 two_bytes_bitmask = _mm512_mask_cmple_epu16_mask(~ascii_bitmask, utf16, v_07ff); + __mmask32 not_one_two_bytes = ~(ascii_bitmask | two_bytes_bitmask); + __mmask32 surrogates_bitmask = _mm512_mask_cmple_epu16_mask(not_one_two_bytes, utf16, v_dfff) & _mm512_mask_cmpge_epu16_mask(not_one_two_bytes, utf16, v_d800); + + size_t ascii_count = count_ones(ascii_bitmask); + size_t two_bytes_count = count_ones(two_bytes_bitmask); + size_t surrogate_bytes_count = count_ones(surrogates_bitmask); + size_t three_bytes_count = 32 - ascii_count - two_bytes_count - surrogate_bytes_count; + count += ascii_count + 2*two_bytes_count + 3*three_bytes_count + 2*surrogate_bytes_count; + } } return count + scalar::utf16::utf8_length_from_utf16(ptr, length - (ptr - input)); @@ -24393,60 +24318,68 @@ simdutf_warn_unused size_t implementation::utf8_length_from_latin1(const char * const uint8_t *str = reinterpret_cast(input); size_t answer = length / sizeof(__m512i) * sizeof(__m512i); size_t i = 0; - unsigned char v_0xFF = 0xff; - __m512i eight_64bits = _mm512_setzero_si512(); - while (i + sizeof(__m512i) <= length) { - __m512i runner = _mm512_setzero_si512(); - size_t iterations = (length - i) / sizeof(__m512i); - if (iterations > 255) { - iterations = 255; - } - size_t max_i = i + iterations * sizeof(__m512i) - sizeof(__m512i); - for (; i + 4*sizeof(__m512i) <= max_i; i += 4*sizeof(__m512i)) { - // Load four __m512i vectors - __m512i input1 = _mm512_loadu_si512((const __m512i *)(str + i)); - __m512i input2 = _mm512_loadu_si512((const __m512i *)(str + i + sizeof(__m512i))); - __m512i input3 = _mm512_loadu_si512((const __m512i *)(str + i + 2*sizeof(__m512i))); - __m512i input4 = _mm512_loadu_si512((const __m512i *)(str + i + 3*sizeof(__m512i))); - - // Generate four masks - __mmask64 mask1 = _mm512_cmpgt_epi8_mask(_mm512_setzero_si512(), input1); - __mmask64 mask2 = _mm512_cmpgt_epi8_mask(_mm512_setzero_si512(), input2); - __mmask64 mask3 = _mm512_cmpgt_epi8_mask(_mm512_setzero_si512(), input3); - __mmask64 mask4 = _mm512_cmpgt_epi8_mask(_mm512_setzero_si512(), input4); - // Apply the masks and subtract from the runner - __m512i not_ascii1 = _mm512_mask_set1_epi8(_mm512_setzero_si512(), mask1, v_0xFF); - __m512i not_ascii2 = _mm512_mask_set1_epi8(_mm512_setzero_si512(), mask2, v_0xFF); - __m512i not_ascii3 = _mm512_mask_set1_epi8(_mm512_setzero_si512(), mask3, v_0xFF); - __m512i not_ascii4 = _mm512_mask_set1_epi8(_mm512_setzero_si512(), mask4, v_0xFF); - - runner = _mm512_sub_epi8(runner, not_ascii1); - runner = _mm512_sub_epi8(runner, not_ascii2); - runner = _mm512_sub_epi8(runner, not_ascii3); - runner = _mm512_sub_epi8(runner, not_ascii4); - } - - for (; i <= max_i; i += sizeof(__m512i)) { - __m512i more_input = _mm512_loadu_si512((const __m512i *)(str + i)); - - __mmask64 mask = _mm512_cmpgt_epi8_mask(_mm512_setzero_si512(), more_input); - __m512i not_ascii = _mm512_mask_set1_epi8(_mm512_setzero_si512(), mask, v_0xFF); - runner = _mm512_sub_epi8(runner, not_ascii); + if(answer >= 2048) { // long strings optimization + unsigned char v_0xFF = 0xff; + __m512i eight_64bits = _mm512_setzero_si512(); + while (i + sizeof(__m512i) <= length) { + __m512i runner = _mm512_setzero_si512(); + size_t iterations = (length - i) / sizeof(__m512i); + if (iterations > 255) { + iterations = 255; + } + size_t max_i = i + iterations * sizeof(__m512i) - sizeof(__m512i); + for (; i + 4*sizeof(__m512i) <= max_i; i += 4*sizeof(__m512i)) { + // Load four __m512i vectors + __m512i input1 = _mm512_loadu_si512((const __m512i *)(str + i)); + __m512i input2 = _mm512_loadu_si512((const __m512i *)(str + i + sizeof(__m512i))); + __m512i input3 = _mm512_loadu_si512((const __m512i *)(str + i + 2*sizeof(__m512i))); + __m512i input4 = _mm512_loadu_si512((const __m512i *)(str + i + 3*sizeof(__m512i))); + + // Generate four masks + __mmask64 mask1 = _mm512_cmpgt_epi8_mask(_mm512_setzero_si512(), input1); + __mmask64 mask2 = _mm512_cmpgt_epi8_mask(_mm512_setzero_si512(), input2); + __mmask64 mask3 = _mm512_cmpgt_epi8_mask(_mm512_setzero_si512(), input3); + __mmask64 mask4 = _mm512_cmpgt_epi8_mask(_mm512_setzero_si512(), input4); + // Apply the masks and subtract from the runner + __m512i not_ascii1 = _mm512_mask_set1_epi8(_mm512_setzero_si512(), mask1, v_0xFF); + __m512i not_ascii2 = _mm512_mask_set1_epi8(_mm512_setzero_si512(), mask2, v_0xFF); + __m512i not_ascii3 = _mm512_mask_set1_epi8(_mm512_setzero_si512(), mask3, v_0xFF); + __m512i not_ascii4 = _mm512_mask_set1_epi8(_mm512_setzero_si512(), mask4, v_0xFF); + + runner = _mm512_sub_epi8(runner, not_ascii1); + runner = _mm512_sub_epi8(runner, not_ascii2); + runner = _mm512_sub_epi8(runner, not_ascii3); + runner = _mm512_sub_epi8(runner, not_ascii4); + } + + for (; i <= max_i; i += sizeof(__m512i)) { + __m512i more_input = _mm512_loadu_si512((const __m512i *)(str + i)); + + __mmask64 mask = _mm512_cmpgt_epi8_mask(_mm512_setzero_si512(), more_input); + __m512i not_ascii = _mm512_mask_set1_epi8(_mm512_setzero_si512(), mask, v_0xFF); + runner = _mm512_sub_epi8(runner, not_ascii); + } + + eight_64bits = _mm512_add_epi64(eight_64bits, _mm512_sad_epu8(runner, _mm512_setzero_si512())); + } + + __m256i first_half = _mm512_extracti64x4_epi64(eight_64bits, 0); + __m256i second_half = _mm512_extracti64x4_epi64(eight_64bits, 1); + answer += (size_t)_mm256_extract_epi64(first_half, 0) + + (size_t)_mm256_extract_epi64(first_half, 1) + + (size_t)_mm256_extract_epi64(first_half, 2) + + (size_t)_mm256_extract_epi64(first_half, 3) + + (size_t)_mm256_extract_epi64(second_half, 0) + + (size_t)_mm256_extract_epi64(second_half, 1) + + (size_t)_mm256_extract_epi64(second_half, 2) + + (size_t)_mm256_extract_epi64(second_half, 3); + } else if (answer > 0) { + for(; i + sizeof(__m512i) <= length; i += sizeof(__m512i)) { + __m512i latin = _mm512_loadu_si512((const __m512i*)(str + i)); + uint64_t non_ascii = _mm512_movepi8_mask(latin); + answer += count_ones(non_ascii); } - - eight_64bits = _mm512_add_epi64(eight_64bits, _mm512_sad_epu8(runner, _mm512_setzero_si512())); } - - __m256i first_half = _mm512_extracti64x4_epi64(eight_64bits, 0); - __m256i second_half = _mm512_extracti64x4_epi64(eight_64bits, 1); - answer += (size_t)_mm256_extract_epi64(first_half, 0) + - (size_t)_mm256_extract_epi64(first_half, 1) + - (size_t)_mm256_extract_epi64(first_half, 2) + - (size_t)_mm256_extract_epi64(first_half, 3) + - (size_t)_mm256_extract_epi64(second_half, 0) + - (size_t)_mm256_extract_epi64(second_half, 1) + - (size_t)_mm256_extract_epi64(second_half, 2) + - (size_t)_mm256_extract_epi64(second_half, 3); return answer + scalar::latin1::utf8_length_from_latin1(reinterpret_cast(str + i), length - i); } @@ -24456,7 +24389,7 @@ simdutf_warn_unused size_t implementation::utf16_length_from_utf8(const char * i // This algorithm could no doubt be improved! for(;pos + 64 <= length; pos += 64) { __m512i utf8 = _mm512_loadu_si512((const __m512i*)(input+pos)); - uint64_t utf8_continuation_mask = _mm512_cmple_epi8_mask(utf8, _mm512_set1_epi8(-65+1)); + uint64_t utf8_continuation_mask = _mm512_cmplt_epi8_mask(utf8, _mm512_set1_epi8(-65+1)); // We count one word for anything that is not a continuation (so // leading bytes). count += 64 - count_ones(utf8_continuation_mask); @@ -24467,46 +24400,52 @@ simdutf_warn_unused size_t implementation::utf16_length_from_utf8(const char * i } simdutf_warn_unused size_t implementation::utf8_length_from_utf32(const char32_t * input, size_t length) const noexcept { - const char32_t* end = length >= 16 ? input + length - 16 : nullptr; const char32_t* ptr = input; + size_t count{0}; - const __m512i v_0000_007f = _mm512_set1_epi32((uint32_t)0x7f); - const __m512i v_0000_07ff = _mm512_set1_epi32((uint32_t)0x7ff); - const __m512i v_0000_ffff = _mm512_set1_epi32((uint32_t)0x0000ffff); + if(length >= 16) { + const char32_t* end = input + length - 16; + + const __m512i v_0000_007f = _mm512_set1_epi32((uint32_t)0x7f); + const __m512i v_0000_07ff = _mm512_set1_epi32((uint32_t)0x7ff); + const __m512i v_0000_ffff = _mm512_set1_epi32((uint32_t)0x0000ffff); - size_t count{0}; - while (ptr <= end) { - __m512i utf32 = _mm512_loadu_si512((const __m512i*)ptr); - ptr += 16; - __mmask16 ascii_bitmask = _mm512_cmple_epu32_mask(utf32, v_0000_007f); - __mmask16 two_bytes_bitmask = _mm512_mask_cmple_epu32_mask(_knot_mask16(ascii_bitmask), utf32, v_0000_07ff); - __mmask16 three_bytes_bitmask = _mm512_mask_cmple_epu32_mask(_knot_mask16(_mm512_kor(ascii_bitmask, two_bytes_bitmask)), utf32, v_0000_ffff); + while (ptr <= end) { + __m512i utf32 = _mm512_loadu_si512((const __m512i*)ptr); + ptr += 16; + __mmask16 ascii_bitmask = _mm512_cmple_epu32_mask(utf32, v_0000_007f); + __mmask16 two_bytes_bitmask = _mm512_mask_cmple_epu32_mask(_knot_mask16(ascii_bitmask), utf32, v_0000_07ff); + __mmask16 three_bytes_bitmask = _mm512_mask_cmple_epu32_mask(_knot_mask16(_mm512_kor(ascii_bitmask, two_bytes_bitmask)), utf32, v_0000_ffff); - size_t ascii_count = count_ones(ascii_bitmask); - size_t two_bytes_count = count_ones(two_bytes_bitmask); - size_t three_bytes_count = count_ones(three_bytes_bitmask); - size_t four_bytes_count = 16 - ascii_count - two_bytes_count - three_bytes_count; - count += ascii_count + 2*two_bytes_count + 3*three_bytes_count + 4*four_bytes_count; + size_t ascii_count = count_ones(ascii_bitmask); + size_t two_bytes_count = count_ones(two_bytes_bitmask); + size_t three_bytes_count = count_ones(three_bytes_bitmask); + size_t four_bytes_count = 16 - ascii_count - two_bytes_count - three_bytes_count; + count += ascii_count + 2*two_bytes_count + 3*three_bytes_count + 4*four_bytes_count; + } } return count + scalar::utf32::utf8_length_from_utf32(ptr, length - (ptr - input)); } simdutf_warn_unused size_t implementation::utf16_length_from_utf32(const char32_t * input, size_t length) const noexcept { - const char32_t* end = length >= 16 ? input + length - 16 : nullptr; const char32_t* ptr = input; + size_t count{0}; - const __m512i v_0000_ffff = _mm512_set1_epi32((uint32_t)0x0000ffff); + if(length >= 16) { + const char32_t* end = input + length - 16; + + const __m512i v_0000_ffff = _mm512_set1_epi32((uint32_t)0x0000ffff); - size_t count{0}; - while (ptr <= end) { - __m512i utf32 = _mm512_loadu_si512((const __m512i*)ptr); - ptr += 16; - __mmask16 surrogates_bitmask = _mm512_cmpgt_epu32_mask(utf32, v_0000_ffff); + while (ptr <= end) { + __m512i utf32 = _mm512_loadu_si512((const __m512i*)ptr); + ptr += 16; + __mmask16 surrogates_bitmask = _mm512_cmpgt_epu32_mask(utf32, v_0000_ffff); - count += 16 + count_ones(surrogates_bitmask); + count += 16 + count_ones(surrogates_bitmask); + } } return count + scalar::utf32::utf16_length_from_utf32(ptr, length - (ptr - input)); @@ -24606,195 +24545,6 @@ simdutf_really_inline simd8 must_be_2_3_continuation(const simd8 return simd8(is_third_byte | is_fourth_byte); } -/* begin file src/haswell/avx2_detect_encodings.cpp */ -template -// len is known to be a multiple of 2 when this is called -int avx2_detect_encodings(const char * buf, size_t len) { - const char* start = buf; - const char* end = buf + len; - - bool is_utf8 = true; - bool is_utf16 = true; - bool is_utf32 = true; - - int out = 0; - - const auto v_d8 = simd8::splat(0xd8); - const auto v_f8 = simd8::splat(0xf8); - - __m256i currentmax = _mm256_setzero_si256(); - - checker check{}; - - while(buf + 64 <= end) { - __m256i in = _mm256_loadu_si256((__m256i*)buf); - __m256i nextin = _mm256_loadu_si256((__m256i*)buf+1); - - const auto u0 = simd16(in); - const auto u1 = simd16(nextin); - - const auto v0 = u0.shr<8>(); - const auto v1 = u1.shr<8>(); - - const auto in16 = simd16::pack(v0, v1); - - const auto surrogates_wordmask0 = (in16 & v_f8) == v_d8; - uint32_t surrogates_bitmask0 = surrogates_wordmask0.to_bitmask(); - - // Check for surrogates - if (surrogates_bitmask0 != 0x0) { - // Cannot be UTF8 - is_utf8 = false; - // Can still be either UTF-16LE or UTF-32 depending on the positions of the surrogates - // To be valid UTF-32, a surrogate cannot be in the two most significant bytes of any 32-bit word. - // On the other hand, to be valid UTF-16LE, at least one surrogate must be in the two most significant - // bytes of a 32-bit word since they always come in pairs in UTF-16LE. - // Note that we always proceed in multiple of 4 before this point so there is no offset in 32-bit code units. - - if ((surrogates_bitmask0 & 0xaaaaaaaa) != 0) { - is_utf32 = false; - // Code from avx2_validate_utf16le.cpp - const char16_t * input = reinterpret_cast(buf); - const char16_t* end16 = reinterpret_cast(start) + len/2; - - const auto v_fc = simd8::splat(0xfc); - const auto v_dc = simd8::splat(0xdc); - - const uint32_t V0 = ~surrogates_bitmask0; - - const auto vH0 = (in16 & v_fc) == v_dc; - const uint32_t H0 = vH0.to_bitmask(); - - const uint32_t L0 = ~H0 & surrogates_bitmask0; - - const uint32_t a0 = L0 & (H0 >> 1); - const uint32_t b0 = a0 << 1; - const uint32_t c0 = V0 | a0 | b0; - - if (c0 == 0xffffffff) { - input += simd16::ELEMENTS * 2; - } else if (c0 == 0x7fffffff) { - input += simd16::ELEMENTS * 2 - 1; - } else { - return simdutf::encoding_type::unspecified; - } - - while (input + simd16::ELEMENTS * 2 < end16) { - const auto in0 = simd16(input); - const auto in1 = simd16(input + simd16::ELEMENTS); - - const auto t0 = in0.shr<8>(); - const auto t1 = in1.shr<8>(); - - const auto in_16 = simd16::pack(t0, t1); - - const auto surrogates_wordmask = (in_16 & v_f8) == v_d8; - const uint32_t surrogates_bitmask = surrogates_wordmask.to_bitmask(); - if (surrogates_bitmask == 0x0) { - input += simd16::ELEMENTS * 2; - } else { - const uint32_t V = ~surrogates_bitmask; - - const auto vH = (in_16 & v_fc) == v_dc; - const uint32_t H = vH.to_bitmask(); - - const uint32_t L = ~H & surrogates_bitmask; - - const uint32_t a = L & (H >> 1); - - const uint32_t b = a << 1; - - const uint32_t c = V | a | b; - - if (c == 0xffffffff) { - input += simd16::ELEMENTS * 2; - } else if (c == 0x7fffffff) { - input += simd16::ELEMENTS * 2 - 1; - } else { - return simdutf::encoding_type::unspecified; - } - } - } - } else { - is_utf16 = false; - // Check for UTF-32 - if (len % 4 == 0) { - const char32_t * input = reinterpret_cast(buf); - const char32_t* end32 = reinterpret_cast(start) + len/4; - - // Must start checking for surrogates - __m256i currentoffsetmax = _mm256_setzero_si256(); - const __m256i offset = _mm256_set1_epi32(0xffff2000); - const __m256i standardoffsetmax = _mm256_set1_epi32(0xfffff7ff); - - currentmax = _mm256_max_epu32(in, currentmax); - currentmax = _mm256_max_epu32(nextin, currentmax); - - currentoffsetmax = _mm256_max_epu32(_mm256_add_epi32(in, offset), currentoffsetmax); - currentoffsetmax = _mm256_max_epu32(_mm256_add_epi32(nextin, offset), currentoffsetmax); - - while (input + 8 < end32) { - const __m256i in32 = _mm256_loadu_si256((__m256i *)input); - currentmax = _mm256_max_epu32(in32,currentmax); - currentoffsetmax = _mm256_max_epu32(_mm256_add_epi32(in32, offset), currentoffsetmax); - input += 8; - } - - __m256i forbidden_words = _mm256_xor_si256(_mm256_max_epu32(currentoffsetmax, standardoffsetmax), standardoffsetmax); - if(_mm256_testz_si256(forbidden_words, forbidden_words) == 0) { - return simdutf::encoding_type::unspecified; - } - } else { - return simdutf::encoding_type::unspecified; - } - } - break; - } - // If no surrogate, validate under other encodings as well - - // UTF-32 validation - currentmax = _mm256_max_epu32(in, currentmax); - currentmax = _mm256_max_epu32(nextin, currentmax); - - // UTF-8 validation - // Relies on ../generic/utf8_validation/utf8_lookup4_algorithm.h - simd::simd8x64 in8(in, nextin); - check.check_next_input(in8); - - buf += 64; - } - - // Check which encodings are possible - - if (is_utf8) { - if (static_cast(buf - start) != len) { - uint8_t block[64]{}; - std::memset(block, 0x20, 64); - std::memcpy(block, buf, len - (buf - start)); - simd::simd8x64 in(block); - check.check_next_input(in); - } - if (!check.errors()) { - out |= simdutf::encoding_type::UTF8; - } - } - - if (is_utf16 && scalar::utf16::validate(reinterpret_cast(buf), (len - (buf - start))/2)) { - out |= simdutf::encoding_type::UTF16_LE; - } - - if (is_utf32 && (len % 4 == 0)) { - const __m256i standardmax = _mm256_set1_epi32(0x10ffff); - __m256i is_zero = _mm256_xor_si256(_mm256_max_epu32(currentmax, standardmax), standardmax); - if (_mm256_testz_si256(is_zero, is_zero) == 1 && scalar::utf32::validate(reinterpret_cast(buf), (len - (buf - start))/4)) { - out |= simdutf::encoding_type::UTF32_LE; - } - } - - return out; -} -/* end file src/haswell/avx2_detect_encodings.cpp */ - /* begin file src/haswell/avx2_validate_utf16.cpp */ /* In UTF-16 code units in range 0xD800 to 0xDFFF have special meaning. @@ -24920,7 +24670,10 @@ const char16_t* avx2_validate_utf16(const char16_t* input, size_t size) { template const result avx2_validate_utf16_with_errors(const char16_t* input, size_t size) { - const char16_t* start = input; + if (simdutf_unlikely(size == 0)) { + return result(error_code::SUCCESS, 0); + } + const char16_t *start = input; const char16_t* end = input + size; const auto v_d8 = simd8::splat(0xd8); @@ -25069,7 +24822,7 @@ std::pair avx2_convert_latin1_to_utf8(const char *latin1_i const __m256i v_ff80 = _mm256_set1_epi16((int16_t)0xff80); const size_t safety_margin = 12; - while (latin1_input + 16 + safety_margin <= end) { + while (end - latin1_input >= std::ptrdiff_t(16 + safety_margin)) { __m128i in8 = _mm_loadu_si128((__m128i *)latin1_input); // a single 16-bit UTF-16 word can yield 1, 2 or 3 UTF-8 bytes const __m128i v_80 = _mm_set1_epi8((char)0x80); @@ -25225,8 +24978,8 @@ size_t convert_masked_utf8_to_utf16(const char *input, const __m128i in = _mm_loadu_si128((__m128i *)input); const uint16_t input_utf8_end_of_code_point_mask = utf8_end_of_code_point_mask & 0xfff; - if(((utf8_end_of_code_point_mask & 0xffff) == 0xffff)) { - // We process the data in chunks of 16 bytes. + if(utf8_end_of_code_point_mask == 0xfff) { + // We process the data in chunks of 12 bytes. __m256i ascii = _mm256_cvtepu8_epi16(in); if (big_endian) { const __m256i swap256 = _mm256_setr_epi8(1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14, @@ -25234,8 +24987,8 @@ size_t convert_masked_utf8_to_utf16(const char *input, ascii = _mm256_shuffle_epi8(ascii, swap256); } _mm256_storeu_si256(reinterpret_cast<__m256i *>(utf16_output), ascii); - utf16_output += 16; // We wrote 16 16-bit characters. - return 16; // We consumed 16 bytes. + utf16_output += 12; // We wrote 12 16-bit characters. + return 12; // We consumed 12 bytes. } if(((utf8_end_of_code_point_mask & 0xffff) == 0xaaaa)) { // We want to take 8 2-byte UTF-8 code units and turn them into 8 2-byte UTF-16 code units. @@ -25405,12 +25158,12 @@ size_t convert_masked_utf8_to_utf32(const char *input, const __m128i in = _mm_loadu_si128((__m128i *)input); const uint16_t input_utf8_end_of_code_point_mask = utf8_end_of_code_point_mask & 0xfff; - if(((utf8_end_of_code_point_mask & 0xffff) == 0xffff)) { - // We process the data in chunks of 16 bytes. + if(utf8_end_of_code_point_mask == 0xfff) { + // We process the data in chunks of 12 bytes. _mm256_storeu_si256(reinterpret_cast<__m256i *>(utf32_output), _mm256_cvtepu8_epi32(in)); _mm256_storeu_si256(reinterpret_cast<__m256i *>(utf32_output+8), _mm256_cvtepu8_epi32(_mm_srli_si128(in,8))); - utf32_output += 16; // We wrote 16 32-bit characters. - return 16; // We consumed 16 bytes. + utf32_output += 12; // We wrote 12 32-bit characters. + return 12; // We consumed 12 bytes. } if(((utf8_end_of_code_point_mask & 0xffff) == 0xaaaa)) { // We want to take 8 2-byte UTF-8 code units and turn them into 8 4-byte UTF-32 code units. @@ -25515,7 +25268,7 @@ std::pair avx2_convert_utf16_to_latin1(const char16_t *buf, size_t len, char *latin1_output) { const char16_t *end = buf + len; - while (buf + 16 <= end) { + while (end - buf >= 16) { // Load 16 UTF-16 characters into 256-bit AVX2 register __m256i in = _mm256_loadu_si256(reinterpret_cast(buf)); @@ -25553,10 +25306,10 @@ avx2_convert_utf16_to_latin1_with_errors(const char16_t *buf, size_t len, char *latin1_output) { const char16_t *start = buf; const char16_t *end = buf + len; - while (buf + 16 <= end) { + while (end - buf >= 16) { __m256i in = _mm256_loadu_si256(reinterpret_cast(buf)); - if (!big_endian) { + if (!match_system(big_endian)) { const __m256i swap = _mm256_setr_epi8( 1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14, 17, 16, 19, 18, 21, 20, 23, 22, 25, 24, 27, 26, 29, 28, 31, 30); @@ -25612,7 +25365,7 @@ avx2_convert_utf16_to_latin1_with_errors(const char16_t *buf, size_t len, Ad 1. When values are less than 0x0800, it means that a 16-bit code unit - can be converted into: 1) single UTF8 byte (when it's an ASCII + can be converted into: 1) single UTF8 byte (when it is an ASCII char) or 2) two UTF8 bytes. For this case we do only some shuffle to obtain these 2-byte @@ -25660,7 +25413,7 @@ std::pair avx2_convert_utf16_to_utf8(const char16_t* buf const __m256i v_c080 = _mm256_set1_epi16((int16_t)0xc080); const size_t safety_margin = 12; // to avoid overruns, see issue https://github.com/simdutf/simdutf/issues/92 - while (buf + 16 + safety_margin <= end) { + while (end - buf >= std::ptrdiff_t(16 + safety_margin)) { __m256i in = _mm256_loadu_si256((__m256i*)buf); if (big_endian) { const __m256i swap = _mm256_setr_epi8(1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14, @@ -25903,7 +25656,7 @@ std::pair avx2_convert_utf16_to_utf8_with_errors(const char16_t* const __m256i v_c080 = _mm256_set1_epi16((int16_t)0xc080); const size_t safety_margin = 12; // to avoid overruns, see issue https://github.com/simdutf/simdutf/issues/92 - while (buf + 16 + safety_margin <= end) { + while (end - buf >= std::ptrdiff_t(16 + safety_margin)) { __m256i in = _mm256_loadu_si256((__m256i*)buf); if (big_endian) { const __m256i swap = _mm256_setr_epi8(1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14, @@ -26144,7 +25897,7 @@ std::pair avx2_convert_utf16_to_utf8_with_errors(const char16_t* Ad 1. When values are less than 0x0800, it means that a 16-bit code unit - can be converted into: 1) single UTF8 byte (when it's an ASCII + can be converted into: 1) single UTF8 byte (when it is an ASCII char) or 2) two UTF8 bytes. For this case we do only some shuffle to obtain these 2-byte @@ -26189,7 +25942,7 @@ std::pair avx2_convert_utf16_to_utf32(const char16_t const __m256i v_f800 = _mm256_set1_epi16((int16_t)0xf800); const __m256i v_d800 = _mm256_set1_epi16((int16_t)0xd800); - while (buf + 16 <= end) { + while (end - buf >= 16) { __m256i in = _mm256_loadu_si256((__m256i*)buf); if (big_endian) { const __m256i swap = _mm256_setr_epi8(1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14, @@ -26257,7 +26010,7 @@ std::pair avx2_convert_utf16_to_utf32_with_errors(const char1 const __m256i v_f800 = _mm256_set1_epi16((int16_t)0xf800); const __m256i v_d800 = _mm256_set1_epi16((int16_t)0xd800); - while (buf + 16 <= end) { + while (end - buf >= 16) { __m256i in = _mm256_loadu_si256((__m256i*)buf); if (big_endian) { const __m256i swap = _mm256_setr_epi8(1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14, @@ -26420,7 +26173,7 @@ std::pair avx2_convert_utf32_to_utf8(const char32_t* buf const size_t safety_margin = 12; // to avoid overruns, see issue https://github.com/simdutf/simdutf/issues/92 - while (buf + 16 + safety_margin <= end) { + while (end - buf >= std::ptrdiff_t(16 + safety_margin)) { __m256i in = _mm256_loadu_si256((__m256i*)buf); __m256i nextin = _mm256_loadu_si256((__m256i*)buf+1); running_max = _mm256_max_epu32(_mm256_max_epu32(in, running_max), nextin); @@ -26661,7 +26414,7 @@ std::pair avx2_convert_utf32_to_utf8_with_errors(const char32_t* const size_t safety_margin = 12; // to avoid overruns, see issue https://github.com/simdutf/simdutf/issues/92 - while (buf + 16 + safety_margin <= end) { + while (end - buf >= std::ptrdiff_t(16 + safety_margin)) { __m256i in = _mm256_loadu_si256((__m256i*)buf); __m256i nextin = _mm256_loadu_si256((__m256i*)buf+1); // Check for too large input @@ -26897,7 +26650,7 @@ std::pair avx2_convert_utf32_to_utf16(const char32_t __m256i forbidden_bytemask = _mm256_setzero_si256(); - while (buf + 8 + safety_margin <= end) { + while (end - buf >= std::ptrdiff_t(8 + safety_margin)) { __m256i in = _mm256_loadu_si256((__m256i*)buf); const __m256i v_00000000 = _mm256_setzero_si256(); @@ -26962,7 +26715,7 @@ std::pair avx2_convert_utf32_to_utf16_with_errors(const char3 const size_t safety_margin = 12; // to avoid overruns, see issue https://github.com/simdutf/simdutf/issues/92 - while (buf + 8 + safety_margin <= end) { + while (end - buf >= std::ptrdiff_t(8 + safety_margin)) { __m256i in = _mm256_loadu_si256((__m256i*)buf); const __m256i v_00000000 = _mm256_setzero_si256(); @@ -27040,30 +26793,15 @@ size_t convert_masked_utf8_to_latin1(const char *input, // This results in more instructions but, potentially, also higher speeds. // const __m128i in = _mm_loadu_si128((__m128i *)input); - const __m128i in_second_half = _mm_loadu_si128((__m128i *)(input + 16)); const uint16_t input_utf8_end_of_code_point_mask = - utf8_end_of_code_point_mask & 0xfff; //we're only processing 12 bytes in case it`s not all ASCII - - if((input_utf8_end_of_code_point_mask & 0xffffffff) == 0xffffffff) { - // Load the next 128 bits. - - // Combine the two 128-bit registers into a single 256-bit register. - __m256i in_combined = _mm256_set_m128i(in_second_half, in); + utf8_end_of_code_point_mask & 0xfff; // we are only processing 12 bytes in case it is not all ASCII - // We process the data in chunks of 32 bytes. - _mm256_storeu_si256(reinterpret_cast<__m256i *>(latin1_output), in_combined); - - latin1_output += 32; // We wrote 32 characters. - return 32; // We consumed 32 bytes. - } - - - if(((utf8_end_of_code_point_mask & 0xffff) == 0xffff)) { - // We process the data in chunks of 16 bytes. + if(utf8_end_of_code_point_mask == 0xfff) { + // We process the data in chunks of 12 bytes. _mm_storeu_si128(reinterpret_cast<__m128i *>(latin1_output), in); - latin1_output += 16; // We wrote 16 characters. - return 16; // We consumed 16 bytes. + latin1_output += 12; // We wrote 12 characters. + return 12; // We consumed 1 bytes. } /// We do not have a fast path available, so we fallback. const uint8_t idx = @@ -27350,9 +27088,8 @@ static inline uint32_t to_base64_mask(__m256i *src, bool *error) { if (base64_url) { check_asso = - _mm256_setr_epi8(0xD, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x3, - 0x7, 0xB, 0x6, 0xB, 0x12, 0xD, 0x1, 0x1, 0x1, 0x1, 0x1, - 0x1, 0x1, 0x1, 0x1, 0x3, 0x7, 0xB, 0x6, 0xB, 0x12); + _mm256_setr_epi8(0xD,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x3,0x7,0xB,0xE,0xB,0x6, + 0xD,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x3,0x7,0xB,0xE,0xB,0x6); } else { check_asso = _mm256_setr_epi8( @@ -27363,13 +27100,8 @@ static inline uint32_t to_base64_mask(__m256i *src, bool *error) { __m256i check_values; if (base64_url) { check_values = _mm256_setr_epi8( - 0x0, uint8_t(0x80), uint8_t(0x80), uint8_t(0x80), uint8_t(0xCF), - uint8_t(0xBF), uint8_t(0xD3), uint8_t(0xA6), uint8_t(0xB5), - uint8_t(0x86), uint8_t(0xD0), uint8_t(0x80), uint8_t(0xB0), - uint8_t(0x80), 0x0, 0x0, 0x0, uint8_t(0x80), uint8_t(0x80), - uint8_t(0x80), uint8_t(0xCF), uint8_t(0xBF), uint8_t(0xD3), - uint8_t(0xA6), uint8_t(0xB5), uint8_t(0x86), uint8_t(0xD0), - uint8_t(0x80), uint8_t(0xB0), uint8_t(0x80), 0x0, 0x0); + uint8_t(0x80),uint8_t(0x80),uint8_t(0x80),uint8_t(0x80),uint8_t(0xCF),uint8_t(0xBF),uint8_t(0xB6),uint8_t(0xA6),uint8_t(0xB5),uint8_t(0xA1),0x0,uint8_t(0x80),0x0,uint8_t(0x80),0x0,uint8_t(0x80), + uint8_t(0x80),uint8_t(0x80),uint8_t(0x80),uint8_t(0x80),uint8_t(0xCF),uint8_t(0xBF),uint8_t(0xB6),uint8_t(0xA6),uint8_t(0xB5),uint8_t(0xA1),0x0,uint8_t(0x80),0x0,uint8_t(0x80),0x0,uint8_t(0x80)); } else { check_values = _mm256_setr_epi8( int8_t(0x80), int8_t(0x80), int8_t(0x80), int8_t(0x80), int8_t(0xCF), @@ -27380,7 +27112,7 @@ static inline uint32_t to_base64_mask(__m256i *src, bool *error) { int8_t(0x86), int8_t(0xD1), int8_t(0x80), int8_t(0xB1), int8_t(0x80), int8_t(0x91), int8_t(0x80)); } - const __m256i shifted = _mm256_srli_epi32(*src, 3); + const __m256i shifted =_mm256_srli_epi32(*src, 3); const __m256i delta_hash = _mm256_avg_epu8(_mm256_shuffle_epi8(delta_asso, *src), shifted); const __m256i check_hash = @@ -27487,22 +27219,22 @@ result compress_decode_base64(char *dst, const chartype *src, size_t srclen, base64_options options) { const uint8_t *to_base64 = base64_url ? tables::base64::to_base64_url_value : tables::base64::to_base64_value; + size_t equallocation = srclen; // location of the first padding character if any // skip trailing spaces - while (srclen > 0 && to_base64[uint8_t(src[srclen - 1])] == 64) { + while (srclen > 0 && scalar::base64::is_eight_byte(src[srclen - 1]) && to_base64[uint8_t(src[srclen - 1])] == 64) { srclen--; } size_t equalsigns = 0; if (srclen > 0 && src[srclen - 1] == '=') { + equallocation = srclen - 1; srclen--; equalsigns = 1; // skip trailing spaces - while (srclen > 0 && to_base64[uint8_t(src[srclen - 1])] == 64) { - srclen--; - } - while (srclen > 0 && to_base64[uint8_t(src[srclen - 1])] == 64) { + while (srclen > 0 && scalar::base64::is_eight_byte(src[srclen - 1]) && to_base64[uint8_t(src[srclen - 1])] == 64) { srclen--; } if (srclen > 0 && src[srclen - 1] == '=') { + equallocation = srclen - 1; srclen--; equalsigns = 2; } @@ -27528,7 +27260,7 @@ result compress_decode_base64(char *dst, const chartype *src, size_t srclen, uint64_t badcharmask = to_base64_mask(&b, &error); if (error) { src -= 64; - while (src < srcend && to_base64[uint8_t(*src)] <= 64) { + while (src < srcend && scalar::base64::is_eight_byte(*src) && to_base64[uint8_t(*src)] <= 64) { src++; } return {error_code::INVALID_BASE64_CHARACTER, size_t(src - srcinit)}; @@ -27576,7 +27308,7 @@ result compress_decode_base64(char *dst, const chartype *src, size_t srclen, while ((bufferptr - buffer_start) % 64 != 0 && src < srcend) { uint8_t val = to_base64[uint8_t(*src)]; *bufferptr = char(val); - if (val > 64) { + if (!scalar::base64::is_eight_byte(*src) || val > 64) { return {error_code::INVALID_BASE64_CHARACTER, size_t(src - srcinit)}; } bufferptr += (val <= 63); @@ -27623,7 +27355,7 @@ result compress_decode_base64(char *dst, const chartype *src, size_t srclen, if (leftover > 0) { while (leftover < 4 && src < srcend) { uint8_t val = to_base64[uint8_t(*src)]; - if (val > 64) { + if (!scalar::base64::is_eight_byte(*src) || val > 64) { return {error_code::INVALID_BASE64_CHARACTER, size_t(src - srcinit)}; } buffer_start[leftover] = char(val); @@ -27674,13 +27406,14 @@ result compress_decode_base64(char *dst, const chartype *src, size_t srclen, // additional checks if((r.count % 3 == 0) || ((r.count % 3) + 1 + equalsigns != 4)) { r.error = error_code::INVALID_BASE64_CHARACTER; + r.count = equallocation; } } return r; } if(equalsigns > 0) { if((size_t(dst - dstinit) % 3 == 0) || ((size_t(dst - dstinit) % 3) + 1 + equalsigns != 4)) { - return {INVALID_BASE64_CHARACTER, size_t(dst - dstinit)}; + return {INVALID_BASE64_CHARACTER, equallocation}; } } return {SUCCESS, size_t(dst - dstinit)}; @@ -27771,7 +27504,7 @@ simdutf_really_inline const uint8_t *buf_block_reader::full_block() c template simdutf_really_inline size_t buf_block_reader::get_remainder(uint8_t *dst) const { if(len == idx) { return 0; } // memcpy(dst, null, 0) will trigger an error with some sanitizers - std::memset(dst, 0x20, STEP_SIZE); // std::memset STEP_SIZE because it's more efficient to write out 8 or 16 bytes at once. + std::memset(dst, 0x20, STEP_SIZE); // std::memset STEP_SIZE because it is more efficient to write out 8 or 16 bytes at once. std::memcpy(dst, buf + idx, len - idx); return len - idx; } @@ -27894,7 +27627,7 @@ using namespace simd; // // Return nonzero if there are incomplete multibyte characters at the end of the block: - // e.g. if there is a 4-byte character, but it's 3 bytes from the end. + // e.g. if there is a 4-byte character, but it is 3 bytes from the end. // simdutf_really_inline simd8 is_incomplete(const simd8 input) { // If the previous input's last 3 bytes match this, they're too short (they ended at EOF): @@ -28339,88 +28072,91 @@ using namespace simd; this->check_utf8_bytes(input.chunks[3], input.chunks[2]); } uint64_t utf8_continuation_mask = input.lt(-65 + 1); - uint64_t utf8_leading_mask = ~utf8_continuation_mask; - uint64_t utf8_end_of_code_point_mask = utf8_leading_mask>>1; - // We process in blocks of up to 12 bytes except possibly - // for fast paths which may process up to 16 bytes. For the - // slow path to work, we should have at least 12 input bytes left. - size_t max_starting_point = (pos + 64) - 12; - // Next loop is going to run at least five times. - while(pos < max_starting_point) { - // Performance note: our ability to compute 'consumed' and - // then shift and recompute is critical. If there is a - // latency of, say, 4 cycles on getting 'consumed', then - // the inner loop might have a total latency of about 6 cycles. - // Yet we process between 6 to 12 inputs bytes, thus we get - // a speed limit between 1 cycle/byte and 0.5 cycle/byte - // for this section of the code. Hence, there is a limit - // to how much we can further increase this latency before - // it seriously harms performance. - size_t consumed = convert_masked_utf8_to_utf16(in + pos, - utf8_end_of_code_point_mask, utf16_output); - pos += consumed; - utf8_end_of_code_point_mask >>= consumed; - } - // At this point there may remain between 0 and 12 bytes in the - // 64-byte block. These bytes will be processed again. So we have an - // 80% efficiency (in the worst case). In practice we expect an - // 85% to 90% efficiency. - } - } - if(errors()) { return 0; } - if(pos < size) { - size_t howmany = scalar::utf8_to_utf16::convert(in + pos, size - pos, utf16_output); - if(howmany == 0) { return 0; } - utf16_output += howmany; - } - return utf16_output - start; - } - - template - simdutf_really_inline result convert_with_errors(const char* in, size_t size, char16_t* utf16_output) { - size_t pos = 0; - char16_t* start{utf16_output}; - // In the worst case, we have the haswell kernel which can cause an overflow of - // 8 bytes when calling convert_masked_utf8_to_utf16. If you skip the last 16 bytes, - // and if the data is valid, then it is entirely safe because 16 UTF-8 bytes generate - // much more than 8 bytes. However, you cannot generally assume that you have valid - // UTF-8 input, so we are going to go back from the end counting 8 leading bytes, - // to give us a good margin. - size_t leading_byte = 0; - size_t margin = size; - for(; margin > 0 && leading_byte < 8; margin--) { - leading_byte += (int8_t(in[margin-1]) > -65); - } - // If the input is long enough, then we have that margin-1 is the eight last leading byte. - const size_t safety_margin = size - margin + 1; // to avoid overruns! - while(pos + 64 + safety_margin <= size) { - simd8x64 input(reinterpret_cast(in + pos)); - if(input.is_ascii()) { - input.store_ascii_as_utf16(utf16_output); - utf16_output += 64; - pos += 64; - } else { - // you might think that a for-loop would work, but under Visual Studio, it is not good enough. - static_assert((simd8x64::NUM_CHUNKS == 2) || (simd8x64::NUM_CHUNKS == 4), - "We support either two or four chunks per 64-byte block."); - auto zero = simd8{uint8_t(0)}; - if(simd8x64::NUM_CHUNKS == 2) { - this->check_utf8_bytes(input.chunks[0], zero); - this->check_utf8_bytes(input.chunks[1], input.chunks[0]); - } else if(simd8x64::NUM_CHUNKS == 4) { - this->check_utf8_bytes(input.chunks[0], zero); - this->check_utf8_bytes(input.chunks[1], input.chunks[0]); - this->check_utf8_bytes(input.chunks[2], input.chunks[1]); - this->check_utf8_bytes(input.chunks[3], input.chunks[2]); - } - if (errors()) { + if(utf8_continuation_mask & 1) { + return 0; // error + } + uint64_t utf8_leading_mask = ~utf8_continuation_mask; + uint64_t utf8_end_of_code_point_mask = utf8_leading_mask>>1; + // We process in blocks of up to 12 bytes except possibly + // for fast paths which may process up to 16 bytes. For the + // slow path to work, we should have at least 12 input bytes left. + size_t max_starting_point = (pos + 64) - 12; + // Next loop is going to run at least five times. + while(pos < max_starting_point) { + // Performance note: our ability to compute 'consumed' and + // then shift and recompute is critical. If there is a + // latency of, say, 4 cycles on getting 'consumed', then + // the inner loop might have a total latency of about 6 cycles. + // Yet we process between 6 to 12 inputs bytes, thus we get + // a speed limit between 1 cycle/byte and 0.5 cycle/byte + // for this section of the code. Hence, there is a limit + // to how much we can further increase this latency before + // it seriously harms performance. + size_t consumed = convert_masked_utf8_to_utf16(in + pos, + utf8_end_of_code_point_mask, utf16_output); + pos += consumed; + utf8_end_of_code_point_mask >>= consumed; + } + // At this point there may remain between 0 and 12 bytes in the + // 64-byte block. These bytes will be processed again. So we have an + // 80% efficiency (in the worst case). In practice we expect an + // 85% to 90% efficiency. + } + } + if(errors()) { return 0; } + if(pos < size) { + size_t howmany = scalar::utf8_to_utf16::convert(in + pos, size - pos, utf16_output); + if(howmany == 0) { return 0; } + utf16_output += howmany; + } + return utf16_output - start; + } + + template + simdutf_really_inline result convert_with_errors(const char* in, size_t size, char16_t* utf16_output) { + size_t pos = 0; + char16_t* start{utf16_output}; + // In the worst case, we have the haswell kernel which can cause an overflow of + // 8 bytes when calling convert_masked_utf8_to_utf16. If you skip the last 16 bytes, + // and if the data is valid, then it is entirely safe because 16 UTF-8 bytes generate + // much more than 8 bytes. However, you cannot generally assume that you have valid + // UTF-8 input, so we are going to go back from the end counting 8 leading bytes, + // to give us a good margin. + size_t leading_byte = 0; + size_t margin = size; + for(; margin > 0 && leading_byte < 8; margin--) { + leading_byte += (int8_t(in[margin-1]) > -65); + } + // If the input is long enough, then we have that margin-1 is the eight last leading byte. + const size_t safety_margin = size - margin + 1; // to avoid overruns! + while(pos + 64 + safety_margin <= size) { + simd8x64 input(reinterpret_cast(in + pos)); + if(input.is_ascii()) { + input.store_ascii_as_utf16(utf16_output); + utf16_output += 64; + pos += 64; + } else { + // you might think that a for-loop would work, but under Visual Studio, it is not good enough. + static_assert((simd8x64::NUM_CHUNKS == 2) || (simd8x64::NUM_CHUNKS == 4), + "We support either two or four chunks per 64-byte block."); + auto zero = simd8{uint8_t(0)}; + if(simd8x64::NUM_CHUNKS == 2) { + this->check_utf8_bytes(input.chunks[0], zero); + this->check_utf8_bytes(input.chunks[1], input.chunks[0]); + } else if(simd8x64::NUM_CHUNKS == 4) { + this->check_utf8_bytes(input.chunks[0], zero); + this->check_utf8_bytes(input.chunks[1], input.chunks[0]); + this->check_utf8_bytes(input.chunks[2], input.chunks[1]); + this->check_utf8_bytes(input.chunks[3], input.chunks[2]); + } + uint64_t utf8_continuation_mask = input.lt(-65 + 1); + if (errors() || (utf8_continuation_mask & 1)) { // rewind_and_convert_with_errors will seek a potential error from in+pos onward, // with the ability to go back up to pos bytes, and read size-pos bytes forward. result res = scalar::utf8_to_utf16::rewind_and_convert_with_errors(pos, in + pos, size - pos, utf16_output); res.count += pos; return res; } - uint64_t utf8_continuation_mask = input.lt(-65 + 1); uint64_t utf8_leading_mask = ~utf8_continuation_mask; uint64_t utf8_end_of_code_point_mask = utf8_leading_mask>>1; // We process in blocks of up to 12 bytes except possibly @@ -28658,10 +28394,10 @@ using namespace simd; size_t pos = 0; char32_t* start{utf32_output}; // In the worst case, we have the haswell kernel which can cause an overflow of - // 8 bytes when calling convert_masked_utf8_to_utf32. If you skip the last 16 bytes, + // 8 words when calling convert_masked_utf8_to_utf32. If you skip the last 16 bytes, // and if the data is valid, then it is entirely safe because 16 UTF-8 bytes generate // much more than 8 bytes. However, you cannot generally assume that you have valid - // UTF-8 input, so we are going to go back from the end counting 8 leading bytes, + // UTF-8 input, so we are going to go back from the end counting 16 leading bytes, // to give us a good margin. size_t leading_byte = 0; size_t margin = size; @@ -28691,6 +28427,9 @@ using namespace simd; this->check_utf8_bytes(input.chunks[3], input.chunks[2]); } uint64_t utf8_continuation_mask = input.lt(-65 + 1); + if(utf8_continuation_mask & 1) { + return 0; // we have an error + } uint64_t utf8_leading_mask = ~utf8_continuation_mask; uint64_t utf8_end_of_code_point_mask = utf8_leading_mask>>1; // We process in blocks of up to 12 bytes except possibly @@ -28764,12 +28503,12 @@ using namespace simd; this->check_utf8_bytes(input.chunks[2], input.chunks[1]); this->check_utf8_bytes(input.chunks[3], input.chunks[2]); } - if (errors()) { + uint64_t utf8_continuation_mask = input.lt(-65 + 1); + if (errors() || (utf8_continuation_mask & 1)) { result res = scalar::utf8_to_utf32::rewind_and_convert_with_errors(pos, in + pos, size - pos, utf32_output); res.count += pos; return res; } - uint64_t utf8_continuation_mask = input.lt(-65 + 1); uint64_t utf8_leading_mask = ~utf8_continuation_mask; uint64_t utf8_end_of_code_point_mask = utf8_leading_mask>>1; // We process in blocks of up to 12 bytes except possibly @@ -29315,15 +29054,15 @@ simdutf_warn_unused int implementation::detect_encodings(const char * input, siz // If there is a BOM, then we trust it. auto bom_encoding = simdutf::BOM::check_bom(input, length); if(bom_encoding != encoding_type::unspecified) { return bom_encoding; } - if (length % 2 == 0) { - return avx2_detect_encodings(input, length); - } else { - if (implementation::validate_utf8(input, length)) { - return simdutf::encoding_type::UTF8; - } else { - return simdutf::encoding_type::unspecified; - } + int out = 0; + if(validate_utf8(input, length)) { out |= encoding_type::UTF8; } + if((length % 2) == 0) { + if(validate_utf16le(reinterpret_cast(input), length/2)) { out |= encoding_type::UTF16_LE; } + } + if((length % 4) == 0) { + if(validate_utf32(reinterpret_cast(input), length/4)) { out |= encoding_type::UTF32_LE; } } + return out; } simdutf_warn_unused bool implementation::validate_utf8(const char *buf, size_t len) const noexcept { @@ -29343,7 +29082,12 @@ simdutf_warn_unused result implementation::validate_ascii_with_errors(const char } simdutf_warn_unused bool implementation::validate_utf16le(const char16_t *buf, size_t len) const noexcept { - const char16_t* tail = avx2_validate_utf16(buf, len); + if (simdutf_unlikely(len == 0)) { + // empty input is valid UTF-16. protect the implementation from + // handling nullptr + return true; + } + const char16_t *tail = avx2_validate_utf16(buf, len); if (tail) { return scalar::utf16::validate(tail, len - (tail - buf)); } else { @@ -29352,6 +29096,11 @@ simdutf_warn_unused bool implementation::validate_utf16le(const char16_t *buf, s } simdutf_warn_unused bool implementation::validate_utf16be(const char16_t *buf, size_t len) const noexcept { + if (simdutf_unlikely(len == 0)) { + // empty input is valid UTF-16. protect the implementation from + // handling nullptr + return true; + } const char16_t* tail = avx2_validate_utf16(buf, len); if (tail) { return scalar::utf16::validate(tail, len - (tail - buf)); @@ -29381,6 +29130,11 @@ simdutf_warn_unused result implementation::validate_utf16be_with_errors(const ch } simdutf_warn_unused bool implementation::validate_utf32(const char32_t *buf, size_t len) const noexcept { + if (simdutf_unlikely(len == 0)) { + // empty input is valid UTF-32. protect the implementation from + // handling nullptr + return true; + } const char32_t* tail = avx2_validate_utf32le(buf, len); if (tail) { return scalar::utf32::validate(tail, len - (tail - buf)); @@ -29390,6 +29144,11 @@ simdutf_warn_unused bool implementation::validate_utf32(const char32_t *buf, siz } simdutf_warn_unused result implementation::validate_utf32_with_errors(const char32_t *buf, size_t len) const noexcept { + if (simdutf_unlikely(len == 0)) { + // empty input is valid UTF-32. protect the implementation from + // handling nullptr + return result(error_code::SUCCESS, 0); + } result res = avx2_validate_utf32le_with_errors(buf, len); if (res.count != len) { result scalar_res = scalar::utf32::validate_with_errors(buf + res.count, len - res.count); @@ -29920,40 +29679,48 @@ simdutf_warn_unused size_t implementation::utf8_length_from_latin1(const char *i const uint8_t *data = reinterpret_cast(input); size_t answer = len / sizeof(__m256i) * sizeof(__m256i); size_t i = 0; - __m256i four_64bits = _mm256_setzero_si256(); - while (i + sizeof(__m256i) <= len) { - __m256i runner = _mm256_setzero_si256(); - // We can do up to 255 loops without overflow. - size_t iterations = (len - i) / sizeof(__m256i); - if (iterations > 255) { - iterations = 255; - } - size_t max_i = i + iterations * sizeof(__m256i) - sizeof(__m256i); - for (; i + 4*sizeof(__m256i) <= max_i; i += 4*sizeof(__m256i)) { - __m256i input1 = _mm256_loadu_si256((const __m256i *)(data + i)); - __m256i input2 = _mm256_loadu_si256((const __m256i *)(data + i + sizeof(__m256i))); - __m256i input3 = _mm256_loadu_si256((const __m256i *)(data + i + 2*sizeof(__m256i))); - __m256i input4 = _mm256_loadu_si256((const __m256i *)(data + i + 3*sizeof(__m256i))); - __m256i input12 = _mm256_add_epi8(_mm256_cmpgt_epi8(_mm256_setzero_si256(), input1), - _mm256_cmpgt_epi8(_mm256_setzero_si256(), input2)); - __m256i input23 = _mm256_add_epi8(_mm256_cmpgt_epi8(_mm256_setzero_si256(), input3), - _mm256_cmpgt_epi8(_mm256_setzero_si256(), input4)); - __m256i input1234 = _mm256_add_epi8(input12, input23); - runner = _mm256_sub_epi8( - runner, input1234); - } - for (; i <= max_i; i += sizeof(__m256i)) { - __m256i input_256_chunk = _mm256_loadu_si256((const __m256i *)(data + i)); - runner = _mm256_sub_epi8( - runner, _mm256_cmpgt_epi8(_mm256_setzero_si256(), input_256_chunk)); - } - four_64bits = _mm256_add_epi64( - four_64bits, _mm256_sad_epu8(runner, _mm256_setzero_si256())); - } - answer += _mm256_extract_epi64(four_64bits, 0) + - _mm256_extract_epi64(four_64bits, 1) + - _mm256_extract_epi64(four_64bits, 2) + - _mm256_extract_epi64(four_64bits, 3); + if(answer >= 2048) { // long strings optimization + __m256i four_64bits = _mm256_setzero_si256(); + while (i + sizeof(__m256i) <= len) { + __m256i runner = _mm256_setzero_si256(); + // We can do up to 255 loops without overflow. + size_t iterations = (len - i) / sizeof(__m256i); + if (iterations > 255) { + iterations = 255; + } + size_t max_i = i + iterations * sizeof(__m256i) - sizeof(__m256i); + for (; i + 4*sizeof(__m256i) <= max_i; i += 4*sizeof(__m256i)) { + __m256i input1 = _mm256_loadu_si256((const __m256i *)(data + i)); + __m256i input2 = _mm256_loadu_si256((const __m256i *)(data + i + sizeof(__m256i))); + __m256i input3 = _mm256_loadu_si256((const __m256i *)(data + i + 2*sizeof(__m256i))); + __m256i input4 = _mm256_loadu_si256((const __m256i *)(data + i + 3*sizeof(__m256i))); + __m256i input12 = _mm256_add_epi8(_mm256_cmpgt_epi8(_mm256_setzero_si256(), input1), + _mm256_cmpgt_epi8(_mm256_setzero_si256(), input2)); + __m256i input23 = _mm256_add_epi8(_mm256_cmpgt_epi8(_mm256_setzero_si256(), input3), + _mm256_cmpgt_epi8(_mm256_setzero_si256(), input4)); + __m256i input1234 = _mm256_add_epi8(input12, input23); + runner = _mm256_sub_epi8( + runner, input1234); + } + for (; i <= max_i; i += sizeof(__m256i)) { + __m256i input_256_chunk = _mm256_loadu_si256((const __m256i *)(data + i)); + runner = _mm256_sub_epi8( + runner, _mm256_cmpgt_epi8(_mm256_setzero_si256(), input_256_chunk)); + } + four_64bits = _mm256_add_epi64( + four_64bits, _mm256_sad_epu8(runner, _mm256_setzero_si256())); + } + answer += _mm256_extract_epi64(four_64bits, 0) + + _mm256_extract_epi64(four_64bits, 1) + + _mm256_extract_epi64(four_64bits, 2) + + _mm256_extract_epi64(four_64bits, 3); + } else if (answer > 0) { + for(; i + sizeof(__m256i) <= len; i += sizeof(__m256i)) { + __m256i latin = _mm256_loadu_si256((const __m256i*)(data + i)); + uint32_t non_ascii = _mm256_movemask_epi8(latin); + answer += count_ones(non_ascii); + } + } return answer + scalar::latin1::utf8_length_from_latin1(reinterpret_cast(data + i), len - i); } @@ -30170,7 +29937,7 @@ simdutf_really_inline const uint8_t *buf_block_reader::full_block() c template simdutf_really_inline size_t buf_block_reader::get_remainder(uint8_t *dst) const { if(len == idx) { return 0; } // memcpy(dst, null, 0) will trigger an error with some sanitizers - std::memset(dst, 0x20, STEP_SIZE); // std::memset STEP_SIZE because it's more efficient to write out 8 or 16 bytes at once. + std::memset(dst, 0x20, STEP_SIZE); // std::memset STEP_SIZE because it is more efficient to write out 8 or 16 bytes at once. std::memcpy(dst, buf + idx, len - idx); return len - idx; } @@ -30293,7 +30060,7 @@ using namespace simd; // // Return nonzero if there are incomplete multibyte characters at the end of the block: - // e.g. if there is a 4-byte character, but it's 3 bytes from the end. + // e.g. if there is a 4-byte character, but it is 3 bytes from the end. // simdutf_really_inline simd8 is_incomplete(const simd8 input) { // If the previous input's last 3 bytes match this, they're too short (they ended at EOF): @@ -30738,6 +30505,9 @@ using namespace simd; this->check_utf8_bytes(input.chunks[3], input.chunks[2]); } uint64_t utf8_continuation_mask = input.lt(-65 + 1); + if(utf8_continuation_mask & 1) { + return 0; // error + } uint64_t utf8_leading_mask = ~utf8_continuation_mask; uint64_t utf8_end_of_code_point_mask = utf8_leading_mask>>1; // We process in blocks of up to 12 bytes except possibly @@ -30812,14 +30582,14 @@ using namespace simd; this->check_utf8_bytes(input.chunks[2], input.chunks[1]); this->check_utf8_bytes(input.chunks[3], input.chunks[2]); } - if (errors()) { + uint64_t utf8_continuation_mask = input.lt(-65 + 1); + if (errors() || (utf8_continuation_mask & 1)) { // rewind_and_convert_with_errors will seek a potential error from in+pos onward, // with the ability to go back up to pos bytes, and read size-pos bytes forward. result res = scalar::utf8_to_utf16::rewind_and_convert_with_errors(pos, in + pos, size - pos, utf16_output); res.count += pos; return res; } - uint64_t utf8_continuation_mask = input.lt(-65 + 1); uint64_t utf8_leading_mask = ~utf8_continuation_mask; uint64_t utf8_end_of_code_point_mask = utf8_leading_mask>>1; // We process in blocks of up to 12 bytes except possibly @@ -31057,10 +30827,10 @@ using namespace simd; size_t pos = 0; char32_t* start{utf32_output}; // In the worst case, we have the haswell kernel which can cause an overflow of - // 8 bytes when calling convert_masked_utf8_to_utf32. If you skip the last 16 bytes, + // 8 words when calling convert_masked_utf8_to_utf32. If you skip the last 16 bytes, // and if the data is valid, then it is entirely safe because 16 UTF-8 bytes generate // much more than 8 bytes. However, you cannot generally assume that you have valid - // UTF-8 input, so we are going to go back from the end counting 8 leading bytes, + // UTF-8 input, so we are going to go back from the end counting 16 leading bytes, // to give us a good margin. size_t leading_byte = 0; size_t margin = size; @@ -31090,6 +30860,9 @@ using namespace simd; this->check_utf8_bytes(input.chunks[3], input.chunks[2]); } uint64_t utf8_continuation_mask = input.lt(-65 + 1); + if(utf8_continuation_mask & 1) { + return 0; // we have an error + } uint64_t utf8_leading_mask = ~utf8_continuation_mask; uint64_t utf8_end_of_code_point_mask = utf8_leading_mask>>1; // We process in blocks of up to 12 bytes except possibly @@ -31163,12 +30936,12 @@ using namespace simd; this->check_utf8_bytes(input.chunks[2], input.chunks[1]); this->check_utf8_bytes(input.chunks[3], input.chunks[2]); } - if (errors()) { + uint64_t utf8_continuation_mask = input.lt(-65 + 1); + if (errors() || (utf8_continuation_mask & 1)) { result res = scalar::utf8_to_utf32::rewind_and_convert_with_errors(pos, in + pos, size - pos, utf32_output); res.count += pos; return res; } - uint64_t utf8_continuation_mask = input.lt(-65 + 1); uint64_t utf8_leading_mask = ~utf8_continuation_mask; uint64_t utf8_end_of_code_point_mask = utf8_leading_mask>>1; // We process in blocks of up to 12 bytes except possibly @@ -31340,6 +31113,7 @@ simdutf_warn_unused int implementation::detect_encodings(const char * input, siz // If there is a BOM, then we trust it. auto bom_encoding = simdutf::BOM::check_bom(input, length); if(bom_encoding != encoding_type::unspecified) { return bom_encoding; } + // todo: reimplement as a one-pass algorithm. int out = 0; if(validate_utf8(input, length)) { out |= encoding_type::UTF8; } if((length % 2) == 0) { @@ -31573,12 +31347,14 @@ simdutf_warn_unused result implementation::base64_to_binary(const char * input, size_t equallocation = length; // location of the first padding character if any size_t equalsigns = 0; if(length > 0 && input[length - 1] == '=') { + equallocation = length - 1; length -= 1; equalsigns++; while(length > 0 && scalar::base64::is_ascii_white_space(input[length - 1])) { length--; } if(length > 0 && input[length - 1] == '=') { + equallocation = length - 1; equalsigns++; length -= 1; } @@ -31611,12 +31387,14 @@ simdutf_warn_unused result implementation::base64_to_binary(const char16_t * inp size_t equallocation = length; // location of the first padding character if any size_t equalsigns = 0; if(length > 0 && input[length - 1] == '=') { + equallocation = length - 1; length -= 1; equalsigns++; while(length > 0 && scalar::base64::is_ascii_white_space(input[length - 1])) { length--; } if(length > 0 && input[length - 1] == '=') { + equallocation = length - 1; equalsigns++; length -= 1; } @@ -31967,10 +31745,11 @@ simdutf_really_inline static result rvv_validate_utf16_with_errors(const char16_ break; } } - if (last - 0xD800u < 0x400u) + if (last - 0xD800u < 0x400u) { return result(error_code::SURROGATE, src - beg - 1); /* end on high surrogate */ - else + } else { return result(error_code::SUCCESS, src - beg); + } } simdutf_warn_unused result implementation::validate_utf16le_with_errors(const char16_t *src, size_t len) const noexcept { @@ -32006,11 +31785,14 @@ simdutf_warn_unused result implementation::validate_utf32_with_errors(const char vl = __riscv_vsetvl_e32m8(len); vuint32m8_t v = __riscv_vle32_v_u32m8((uint32_t*)src, vl); vuint32m8_t off = __riscv_vadd_vx_u32m8(v, 0xFFFF2000, vl); - long idx; - idx = __riscv_vfirst_m_b4(__riscv_vmsgtu_vx_u32m8_b4(v, 0x10FFFF, vl), vl); - if (idx >= 0) return result(error_code::TOO_LARGE, src - beg + idx); - idx = __riscv_vfirst_m_b4(__riscv_vmsgtu_vx_u32m8_b4(off, 0xFFFFF7FF, vl), vl); - if (idx >= 0) return result(error_code::SURROGATE, src - beg + idx); + long idx1 = __riscv_vfirst_m_b4(__riscv_vmsgtu_vx_u32m8_b4(v, 0x10FFFF, vl), vl); + long idx2 = __riscv_vfirst_m_b4(__riscv_vmsgtu_vx_u32m8_b4(off, 0xFFFFF7FF, vl), vl); + if(idx1 >= 0 && idx2 >= 0) { + if(idx1 <= idx2) { return result(error_code::TOO_LARGE, src - beg + idx1); } + else { return result(error_code::SURROGATE, src - beg + idx2); } + } + if (idx1 >= 0) { return result(error_code::TOO_LARGE, src - beg + idx1); } + if (idx2 >= 0) { return result(error_code::SURROGATE, src - beg + idx2); } } return result(error_code::SUCCESS, src - beg); } @@ -32227,6 +32009,25 @@ simdutf_really_inline static size_t rvv_utf8_to_common(char const *src, size_t l vuint8m2_t b3 = __riscv_vcompress_vm_u8m2(v2, m, vl); vuint8m2_t b4 = __riscv_vcompress_vm_u8m2(v3, m, vl); + /* remove prefix from leading bytes + * + * We could also use vrgather here, but it increases register pressure, + * and its performance varies widely on current platforms. It might be + * worth reconsidering, though, once there is more hardware available. + * Same goes for the __riscv_vsrl_vv_u32m4 correction step. + * + * We shift left and then right by the number of bytes in the prefix, + * which can be calculated as follows: + * x max(x-10, 0) + * 0xxx -> 0000-0111 -> sift by 0 or 1 -> 0 + * 10xx -> 1000-1011 -> don't care + * 110x -> 1100,1101 -> sift by 3 -> 2,3 + * 1110 -> 1110 -> sift by 4 -> 4 + * 1111 -> 1111 -> sift by 5 -> 5 + * + * vssubu.vx v, 10, (max(x-10, 0)) almost gives us what we want, we + * just need to manually detect and handle the one special case: + */ #define SIMDUTF_RVV_UTF8_TO_COMMON_M1(idx) \ vuint8m1_t c1 = __riscv_vget_v_u8m2_u8m1(b1, idx); \ vuint8m1_t c2 = __riscv_vget_v_u8m2_u8m1(b2, idx); \ @@ -32235,26 +32036,7 @@ simdutf_really_inline static size_t rvv_utf8_to_common(char const *src, size_t l /* remove prefix from trailing bytes */ \ c2 = __riscv_vand_vx_u8m1(c2, 0b00111111, vlOut); \ c3 = __riscv_vand_vx_u8m1(c3, 0b00111111, vlOut); \ - c4 = __riscv_vand_vx_u8m1(c4, 0b00111111, vlOut); \ - /* remove prefix from leading bytes - * - * We could also use vrgather here, but it increases register pressure, - * and its performance varies widely on current platforms. It might be - * worth reconsidering, though, once there is more hardware available. - * Same goes for the __riscv_vsrl_vv_u32m4 correction step. - * - * We shift left and then right by the number of bytes in the prefix, - * which can be calculated as follows: - * x max(x-10, 0) - * 0xxx -> 0000-0111 -> sift by 0 or 1 -> 0 - * 10xx -> 1000-1011 -> don't care - * 110x -> 1100,1101 -> sift by 3 -> 2,3 - * 1110 -> 1110 -> sift by 4 -> 4 - * 1111 -> 1111 -> sift by 5 -> 5 - * - * vssubu.vx v, 10, (max(x-10, 0)) almost gives us what we want, we - * just need to manually detect and handle the one special case: - */ \ + c4 = __riscv_vand_vx_u8m1(c4, 0b00111111, vlOut); \ vuint8m1_t shift = __riscv_vsrl_vx_u8m1(c1, 4, vlOut); \ shift = __riscv_vmerge_vxm_u8m1(__riscv_vssubu_vx_u8m1(shift, 10, vlOut), 3, __riscv_vmseq_vx_u8m1_b8(shift, 12, vlOut), vlOut); \ c1 = __riscv_vsll_vv_u8m1(c1, shift, vlOut); \ @@ -32314,23 +32096,41 @@ simdutf_really_inline static size_t rvv_utf8_to_common(char const *src, size_t l simdutf_warn_unused size_t implementation::convert_utf8_to_latin1(const char *src, size_t len, char *dst) const noexcept { const char *beg = dst; - uint8_t last = 0b10000000; + uint8_t last = 0; for (size_t vl, vlOut; len > 0; len -= vl, src += vl, dst += vlOut, last = src[-1]) { vl = __riscv_vsetvl_e8m2(len); vuint8m2_t v1 = __riscv_vle8_v_u8m2((uint8_t*)src, vl); - vbool4_t m = __riscv_vmsltu_vx_u8m2_b4(v1, 0b11000000, vl); - vlOut = __riscv_vcpop_m_b4(m, vl); - if (vlOut != vl || last > 0b01111111) { + // check which bytes are ASCII + vbool4_t ascii = __riscv_vmsltu_vx_u8m2_b4(v1, 0b10000000, vl); + // count ASCII bytes + vlOut = __riscv_vcpop_m_b4(ascii, vl); + // The original code would only enter the next block after this check: + // vbool4_t m = __riscv_vmsltu_vx_u8m2_b4(v1, 0b11000000, vl); + // vlOut = __riscv_vcpop_m_b4(m, vl); + // if (vlOut != vl || last > 0b01111111) {...}q + // So that everything is ASCII or continuation bytes, we just proceeded + // without any processing, going straight to __riscv_vse8_v_u8m2. + // But you need the __riscv_vslide1up_vx_u8m2 whenever there is a non-ASCII byte. + if (vlOut != vl) { // If not pure ASCII + // Non-ASCII characters + // We now want to mark the ascii and continuation bytes + vbool4_t m = __riscv_vmsltu_vx_u8m2_b4(v1, 0b11000000, vl); + // We count them, that's our new vlOut (output vector length) + vlOut = __riscv_vcpop_m_b4(m, vl); + vuint8m2_t v0 = __riscv_vslide1up_vx_u8m2(v1, last, vl); vbool4_t leading0 = __riscv_vmsgtu_vx_u8m2_b4(v0, 0b10111111, vl); vbool4_t trailing1 = __riscv_vmslt_vx_i8m2_b4(__riscv_vreinterpret_v_u8m2_i8m2(v1), (uint8_t)0b11000000, vl); + // -62 i 0b11000010, so we check whether any of v0 is too big vbool4_t tobig = __riscv_vmand_mm_b4(leading0, __riscv_vmsgtu_vx_u8m2_b4(__riscv_vxor_vx_u8m2(v0, (uint8_t)-62, vl), 1, vl), vl); if (__riscv_vfirst_m_b4(__riscv_vmor_mm_b4(tobig, __riscv_vmxor_mm_b4(leading0, trailing1, vl), vl), vl) >= 0) return 0; v1 = __riscv_vor_vx_u8m2_mu(__riscv_vmseq_vx_u8m2_b4(v0, 0b11000011, vl), v1, v1, 0b01000000, vl); v1 = __riscv_vcompress_vm_u8m2(v1, m, vl); + } else if (last >= 0b11000000) { // If last byte is a leading byte and we got only ASCII, error! + return 0; } __riscv_vse8_v_u8m2((uint8_t*)dst, v1, vlOut); } @@ -32347,13 +32147,15 @@ simdutf_warn_unused result implementation::convert_utf8_to_latin1_with_errors(co simdutf_warn_unused size_t implementation::convert_valid_utf8_to_latin1(const char *src, size_t len, char *dst) const noexcept { const char *beg = dst; - uint8_t last = 0b11000000; + uint8_t last = 0; for (size_t vl, vlOut; len > 0; len -= vl, src += vl, dst += vlOut, last = src[-1]) { vl = __riscv_vsetvl_e8m2(len); vuint8m2_t v1 = __riscv_vle8_v_u8m2((uint8_t*)src, vl); - vbool4_t m = __riscv_vmsltu_vx_u8m2_b4(v1, 0b11000000, vl); - vlOut = __riscv_vcpop_m_b4(m, vl); - if (vlOut != vl || last > 0b01111111) { + vbool4_t ascii = __riscv_vmsltu_vx_u8m2_b4(v1, 0b10000000, vl); + vlOut = __riscv_vcpop_m_b4(ascii, vl); + if (vlOut != vl) { // If not pure ASCII + vbool4_t m = __riscv_vmsltu_vx_u8m2_b4(v1, 0b11000000, vl); + vlOut = __riscv_vcpop_m_b4(m, vl); vuint8m2_t v0 = __riscv_vslide1up_vx_u8m2(v1, last, vl); v1 = __riscv_vor_vx_u8m2_mu(__riscv_vmseq_vx_u8m2_b4(v0, 0b11000011, vl), v1, v1, 0b01000000, vl); v1 = __riscv_vcompress_vm_u8m2(v1, m, vl); @@ -32424,7 +32226,7 @@ simdutf_really_inline static result rvv_utf16_to_latin1_with_errors(const char16 v = simdutf_byteflip(v, vl); long idx = __riscv_vfirst_m_b2(__riscv_vmsgtu_vx_u16m8_b2(v, 255, vl), vl); if (idx >= 0) - return result(error_code::TOO_LARGE, beg - src + idx); + return result(error_code::TOO_LARGE, src - beg + idx); __riscv_vse8_v_u8m4((uint8_t*)dst, __riscv_vncvt_x_x_w_u8m4(v, vl), vl); } return result(error_code::SUCCESS, src - beg); @@ -32676,7 +32478,11 @@ simdutf_really_inline static result rvv_utf16_to_utf32_with_errors(const char16_ const vbool8_t diff = __riscv_vmxor_mm_b8(surhi, surlo, vl); const long idx = __riscv_vfirst_m_b8(diff, vl); if (idx >= 0) { - return result(error_code::SURROGATE, src - srcBeg + idx + 1); + uint16_t word = simdutf_byteflip(src[idx]); + if(word < 0xD800 || word > 0xDBFF) { + return result(error_code::SURROGATE, src - srcBeg + idx + 1); + } + return result(error_code::SURROGATE, src - srcBeg + idx); } } @@ -32826,10 +32632,15 @@ simdutf_warn_unused result implementation::convert_utf32_to_utf8_with_errors(con n -= vl, src += vl, dst += vlOut; continue; } - + long idx1 = __riscv_vfirst_m_b8(__riscv_vmsgtu_vx_u32m4_b8(v, 0x10FFFF, vl), vl); vbool8_t sur = __riscv_vmseq_vx_u32m4_b8(__riscv_vand_vx_u32m4(v, 0xFFFFF800, vl), 0xD800, vl); - long idx = __riscv_vfirst_m_b8(sur, vl); - if (idx >= 0) return result(error_code::SURROGATE, src - srcBeg + idx); + long idx2 = __riscv_vfirst_m_b8(sur, vl); + if(idx1 >= 0 && idx2 >= 0) { + if(idx1 <= idx2) { return result(error_code::TOO_LARGE, src - srcBeg + idx1); } + else { return result(error_code::SURROGATE, src - srcBeg + idx2); } + } + if (idx1 >= 0) { return result(error_code::TOO_LARGE, src - srcBeg + idx1); } + if (idx2 >= 0) { return result(error_code::SURROGATE, src - srcBeg + idx2); } vbool8_t m4 = __riscv_vmsgtu_vx_u32m4_b8(v, 0x10000-1, vl); long first = __riscv_vfirst_m_b8(m4, vl); @@ -32904,18 +32715,21 @@ simdutf_really_inline static result rvv_convert_utf32_to_utf16_with_errors(const vl = __riscv_vsetvl_e32m4(len); vuint32m4_t v = __riscv_vle32_v_u32m4((uint32_t*)src, vl); vuint32m4_t off = __riscv_vadd_vx_u32m4(v, 0xFFFF2000, vl); - long idx; - idx = __riscv_vfirst_m_b8(__riscv_vmsgtu_vx_u32m4_b8(off, 0xFFFFF7FF, vl), vl); - if (idx >= 0) return result(error_code::SURROGATE, src - srcBeg + idx); - idx = __riscv_vfirst_m_b8(__riscv_vmsgtu_vx_u32m4_b8(v, 0xFFFF, vl), vl); + long idx1 = __riscv_vfirst_m_b8(__riscv_vmsgtu_vx_u32m4_b8(v, 0x10FFFF, vl), vl); + long idx2 = __riscv_vfirst_m_b8(__riscv_vmsgtu_vx_u32m4_b8(off, 0xFFFFF7FF, vl), vl); + if (idx1 >= 0 && idx2 >= 0) { + if (idx1 <= idx2) return result(error_code::TOO_LARGE, src - srcBeg + idx1); + return result(error_code::SURROGATE, src - srcBeg + idx2); + } + if (idx1 >= 0) return result(error_code::TOO_LARGE, src - srcBeg + idx1); + if (idx2 >= 0) return result(error_code::SURROGATE, src - srcBeg + idx2); + long idx = __riscv_vfirst_m_b8(__riscv_vmsgtu_vx_u32m4_b8(v, 0xFFFF, vl), vl); if (idx < 0) { vlOut = vl; vuint16m2_t n = simdutf_byteflip(__riscv_vncvt_x_x_w_u16m2(v, vlOut), vlOut); __riscv_vse16_v_u16m2((uint16_t*)dst, n, vlOut); continue; } - idx = __riscv_vfirst_m_b8(__riscv_vmsgtu_vx_u32m4_b8(v, 0x10FFFF, vl), vl); - if (idx >= 0) return result(error_code::TOO_LARGE, src - srcBeg + idx); vlOut = rvv_utf32_store_utf16_m4((uint16_t*)dst, v, vl, m4even); } return result(error_code::SUCCESS, dst - dstBeg); @@ -32978,6 +32792,7 @@ simdutf_warn_unused int implementation::detect_encodings(const char *input, size auto bom_encoding = simdutf::BOM::check_bom(input, length); if (bom_encoding != encoding_type::unspecified) return bom_encoding; + // todo: reimplement as a one-pass algorithm. int out = 0; if (validate_utf8(input, length)) out |= encoding_type::UTF8; @@ -33020,12 +32835,14 @@ simdutf_warn_unused result implementation::base64_to_binary(const char * input, size_t equallocation = length; // location of the first padding character if any size_t equalsigns = 0; if(length > 0 && input[length - 1] == '=') { + equallocation = length - 1; length -= 1; equalsigns++; while(length > 0 && scalar::base64::is_ascii_white_space(input[length - 1])) { length--; } if(length > 0 && input[length - 1] == '=') { + equallocation = length - 1; equalsigns++; length -= 1; } @@ -33058,12 +32875,14 @@ simdutf_warn_unused result implementation::base64_to_binary(const char16_t * inp size_t equallocation = length; // location of the first padding character if any auto equalsigns = 0; if(length > 0 && input[length - 1] == '=') { + equallocation = length - 1; length -= 1; equalsigns++; while(length > 0 && scalar::base64::is_ascii_white_space(input[length - 1])) { length--; } if(length > 0 && input[length - 1] == '=') { + equallocation = length - 1; equalsigns++; length -= 1; } @@ -33220,214 +33039,6 @@ inline void write_v_u16_11bits_to_utf8( } // namespace westmere } // namespace internal /* end file src/westmere/internal/loader.cpp */ -/* begin file src/westmere/sse_detect_encodings.cpp */ -template -// len is known to be a multiple of 2 when this is called -int sse_detect_encodings(const char * buf, size_t len) { - const char* start = buf; - const char* end = buf + len; - - bool is_utf8 = true; - bool is_utf16 = true; - bool is_utf32 = true; - - int out = 0; - - const auto v_d8 = simd8::splat(0xd8); - const auto v_f8 = simd8::splat(0xf8); - - __m128i currentmax = _mm_setzero_si128(); - - checker check{}; - - while(buf + 64 <= end) { - __m128i in = _mm_loadu_si128((__m128i*)buf); - __m128i secondin = _mm_loadu_si128((__m128i*)buf+1); - __m128i thirdin = _mm_loadu_si128((__m128i*)buf+2); - __m128i fourthin = _mm_loadu_si128((__m128i*)buf+3); - - const auto u0 = simd16(in); - const auto u1 = simd16(secondin); - const auto u2 = simd16(thirdin); - const auto u3 = simd16(fourthin); - - const auto v0 = u0.shr<8>(); - const auto v1 = u1.shr<8>(); - const auto v2 = u2.shr<8>(); - const auto v3 = u3.shr<8>(); - - const auto in16 = simd16::pack(v0, v1); - const auto nextin16 = simd16::pack(v2, v3); - - const auto surrogates_wordmask0 = (in16 & v_f8) == v_d8; - const auto surrogates_wordmask1 = (nextin16 & v_f8) == v_d8; - uint16_t surrogates_bitmask0 = static_cast(surrogates_wordmask0.to_bitmask()); - uint16_t surrogates_bitmask1 = static_cast(surrogates_wordmask1.to_bitmask()); - - // Check for surrogates - if (surrogates_bitmask0 != 0x0 || surrogates_bitmask1 != 0x0) { - // Cannot be UTF8 - is_utf8 = false; - // Can still be either UTF-16LE or UTF-32 depending on the positions of the surrogates - // To be valid UTF-32, a surrogate cannot be in the two most significant bytes of any 32-bit word. - // On the other hand, to be valid UTF-16LE, at least one surrogate must be in the two most significant - // bytes of a 32-bit word since they always come in pairs in UTF-16LE. - // Note that we always proceed in multiple of 4 before this point so there is no offset in 32-bit code units. - - if (((surrogates_bitmask0 | surrogates_bitmask1) & 0xaaaa) != 0) { - is_utf32 = false; - // Code from sse_validate_utf16le.cpp - // Not efficient, we do not process surrogates_bitmask1 - const char16_t * input = reinterpret_cast(buf); - const char16_t* end16 = reinterpret_cast(start) + len/2; - - const auto v_fc = simd8::splat(0xfc); - const auto v_dc = simd8::splat(0xdc); - - const uint16_t V0 = static_cast(~surrogates_bitmask0); - - const auto vH0 = (in16 & v_fc) == v_dc; - const uint16_t H0 = static_cast(vH0.to_bitmask()); - - const uint16_t L0 = static_cast(~H0 & surrogates_bitmask0); - - const uint16_t a0 = static_cast(L0 & (H0 >> 1)); - - const uint16_t b0 = static_cast(a0 << 1); - - const uint16_t c0 = static_cast(V0 | a0 | b0); - - if (c0 == 0xffff) { - input += 16; - } else if (c0 == 0x7fff) { - input += 15; - } else { - is_utf16 = false; - break; - } - - while (input + simd16::SIZE * 2 < end16) { - const auto in0 = simd16(input); - const auto in1 = simd16(input + simd16::SIZE / sizeof(char16_t)); - - const auto t0 = in0.shr<8>(); - const auto t1 = in1.shr<8>(); - - const auto in_16 = simd16::pack(t0, t1); - - const auto surrogates_wordmask = (in_16 & v_f8) == v_d8; - const uint16_t surrogates_bitmask = static_cast(surrogates_wordmask.to_bitmask()); - if (surrogates_bitmask == 0x0) { - input += 16; - } else { - const uint16_t V = static_cast(~surrogates_bitmask); - - const auto vH = (in_16 & v_fc) == v_dc; - const uint16_t H = static_cast(vH.to_bitmask()); - - const uint16_t L = static_cast(~H & surrogates_bitmask); - - const uint16_t a = static_cast(L & (H >> 1)); - - const uint16_t b = static_cast(a << 1); - - const uint16_t c = static_cast(V | a | b); - - if (c == 0xffff) { - input += 16; - } else if (c == 0x7fff) { - input += 15; - } else { - is_utf16 = false; - break; - } - } - } - } else { - is_utf16 = false; - // Check for UTF-32 - if (len % 4 == 0) { - const char32_t * input = reinterpret_cast(buf); - const char32_t* end32 = reinterpret_cast(start) + len/4; - - // Must start checking for surrogates - __m128i currentoffsetmax = _mm_setzero_si128(); - const __m128i offset = _mm_set1_epi32(0xffff2000); - const __m128i standardoffsetmax = _mm_set1_epi32(0xfffff7ff); - - currentmax = _mm_max_epu32(in, currentmax); - currentmax = _mm_max_epu32(secondin, currentmax); - currentmax = _mm_max_epu32(thirdin, currentmax); - currentmax = _mm_max_epu32(fourthin, currentmax); - - currentoffsetmax = _mm_max_epu32(_mm_add_epi32(in, offset), currentoffsetmax); - currentoffsetmax = _mm_max_epu32(_mm_add_epi32(secondin, offset), currentoffsetmax); - currentoffsetmax = _mm_max_epu32(_mm_add_epi32(thirdin, offset), currentoffsetmax); - currentoffsetmax = _mm_max_epu32(_mm_add_epi32(fourthin, offset), currentoffsetmax); - - while (input + 4 < end32) { - const __m128i in32 = _mm_loadu_si128((__m128i *)input); - currentmax = _mm_max_epu32(in32,currentmax); - currentoffsetmax = _mm_max_epu32(_mm_add_epi32(in32, offset), currentoffsetmax); - input += 4; - } - - __m128i forbidden_words = _mm_xor_si128(_mm_max_epu32(currentoffsetmax, standardoffsetmax), standardoffsetmax); - if(_mm_testz_si128(forbidden_words, forbidden_words) == 0) { - is_utf32 = false; - } - } else { - is_utf32 = false; - } - } - break; - } - // If no surrogate, validate under other encodings as well - - // UTF-32 validation - currentmax = _mm_max_epu32(in, currentmax); - currentmax = _mm_max_epu32(secondin, currentmax); - currentmax = _mm_max_epu32(thirdin, currentmax); - currentmax = _mm_max_epu32(fourthin, currentmax); - - // UTF-8 validation - // Relies on ../generic/utf8_validation/utf8_lookup4_algorithm.h - simd::simd8x64 in8(in, secondin, thirdin, fourthin); - check.check_next_input(in8); - - buf += 64; - } - - // Check which encodings are possible - - if (is_utf8) { - if (static_cast(buf - start) != len) { - uint8_t block[64]{}; - std::memset(block, 0x20, 64); - std::memcpy(block, buf, len - (buf - start)); - simd::simd8x64 in(block); - check.check_next_input(in); - } - if (!check.errors()) { - out |= simdutf::encoding_type::UTF8; - } - } - - if (is_utf16 && scalar::utf16::validate(reinterpret_cast(buf), (len - (buf - start))/2)) { - out |= simdutf::encoding_type::UTF16_LE; - } - - if (is_utf32 && (len % 4 == 0)) { - const __m128i standardmax = _mm_set1_epi32(0x10ffff); - __m128i is_zero = _mm_xor_si128(_mm_max_epu32(currentmax, standardmax), standardmax); - if (_mm_testz_si128(is_zero, is_zero) == 1 && scalar::utf32::validate(reinterpret_cast(buf), (len - (buf - start))/4)) { - out |= simdutf::encoding_type::UTF32_LE; - } - } - - return out; -} -/* end file src/westmere/sse_detect_encodings.cpp */ /* begin file src/westmere/sse_validate_utf16.cpp */ /* @@ -33450,7 +33061,7 @@ int sse_detect_encodings(const char * buf, size_t len) { - there must not be two consecutive high surrogates (0xdc00 .. 0xdfff) - there must not be sole low surrogate nor high surrogate - We're going to build three bitmasks based on the 3rd nibble: + We are going to build three bitmasks based on the 3rd nibble: - V = valid word, - L = low surrogate (0xd800 .. 0xdbff) - H = high surrogate (0xdc00 .. 0xdfff) @@ -33553,6 +33164,9 @@ const char16_t* sse_validate_utf16(const char16_t* input, size_t size) { template const result sse_validate_utf16_with_errors(const char16_t* input, size_t size) { + if (simdutf_unlikely(size == 0)) { + return result(error_code::SUCCESS, 0); + } const char16_t* start = input; const char16_t* end = input + size; @@ -33732,7 +33346,7 @@ std::pair sse_convert_latin1_to_utf8( // slow path writes useful 8-15 bytes twice (eagerly writes 16 bytes and then adjust the pointer) // so the last write can exceed the utf8_output size by 8-1 bytes // by reserving 8 extra input bytes, we expect the output to have 8-16 bytes free - while (latin_input + 16 + 8 <= end) { + while (end - latin_input >= 16 + 8) { // Load 16 Latin1 characters (16 bytes) into a 128-bit register __m128i v_latin = _mm_loadu_si128((__m128i*)latin_input); @@ -33757,7 +33371,7 @@ std::pair sse_convert_latin1_to_utf8( latin_input += 16; } - if (latin_input + 16 <= end) { + if (end - latin_input >= 16) { // Load 16 Latin1 characters (16 bytes) into a 128-bit register __m128i v_latin = _mm_loadu_si128((__m128i*)latin_input); @@ -33801,7 +33415,7 @@ std::pair sse_convert_latin1_to_utf16(const char *latin1 std::pair sse_convert_latin1_to_utf32(const char* buf, size_t len, char32_t* utf32_output) { const char* end = buf + len; - while (buf + 16 <= end) { + while (end - buf >= 16) { // Load 16 Latin1 characters (16 bytes) into a 128-bit register __m128i in = _mm_loadu_si128((__m128i*)buf); @@ -33857,8 +33471,9 @@ size_t convert_masked_utf8_to_utf16(const char *input, const __m128i in = _mm_loadu_si128((__m128i *)input); const uint16_t input_utf8_end_of_code_point_mask = utf8_end_of_code_point_mask & 0xfff; - if(((utf8_end_of_code_point_mask & 0xffff) == 0xffff)) { - // We process the data in chunks of 16 bytes. + if(utf8_end_of_code_point_mask == 0xfff) { + // We process the data in chunks of 12 bytes. + // Note: using 16 bytes is unsafe, see issue_ossfuzz_71218 __m128i ascii_first = _mm_cvtepu8_epi16(in); __m128i ascii_second = _mm_cvtepu8_epi16(_mm_srli_si128(in,8)); if (big_endian) { @@ -33867,8 +33482,8 @@ size_t convert_masked_utf8_to_utf16(const char *input, } _mm_storeu_si128(reinterpret_cast<__m128i *>(utf16_output), ascii_first); _mm_storeu_si128(reinterpret_cast<__m128i *>(utf16_output + 8), ascii_second); - utf16_output += 16; // We wrote 16 16-bit characters. - return 16; // We consumed 16 bytes. + utf16_output += 12; // We wrote 12 16-bit characters. + return 12; // We consumed 12 bytes. } if(((utf8_end_of_code_point_mask & 0xFFFF) == 0xaaaa)) { // We want to take 8 2-byte UTF-8 code units and turn them into 8 2-byte UTF-16 code units. @@ -34039,14 +33654,14 @@ size_t convert_masked_utf8_to_utf32(const char *input, const __m128i in = _mm_loadu_si128((__m128i *)input); const uint16_t input_utf8_end_of_code_point_mask = utf8_end_of_code_point_mask & 0xfff; - if(((utf8_end_of_code_point_mask & 0xffff) == 0xffff)) { - // We process the data in chunks of 16 bytes. + if(utf8_end_of_code_point_mask == 0xfff) { + // We process the data in chunks of 12 bytes. _mm_storeu_si128(reinterpret_cast<__m128i *>(utf32_output), _mm_cvtepu8_epi32(in)); _mm_storeu_si128(reinterpret_cast<__m128i *>(utf32_output+4), _mm_cvtepu8_epi32(_mm_srli_si128(in,4))); _mm_storeu_si128(reinterpret_cast<__m128i *>(utf32_output+8), _mm_cvtepu8_epi32(_mm_srli_si128(in,8))); _mm_storeu_si128(reinterpret_cast<__m128i *>(utf32_output+12), _mm_cvtepu8_epi32(_mm_srli_si128(in,12))); - utf32_output += 16; // We wrote 16 32-bit characters. - return 16; // We consumed 16 bytes. + utf32_output += 12; // We wrote 12 32-bit characters. + return 12; // We consumed 12 bytes. } if(((utf8_end_of_code_point_mask & 0xffff) == 0xaaaa)) { // We want to take 8 2-byte UTF-8 code units and turn them into 8 4-byte UTF-32 code units. @@ -34167,12 +33782,12 @@ size_t convert_masked_utf8_to_latin1(const char *input, // const __m128i in = _mm_loadu_si128((__m128i *)input); const uint16_t input_utf8_end_of_code_point_mask = - utf8_end_of_code_point_mask & 0xfff; //we're only processing 12 bytes in case it`s not all ASCII - if(((utf8_end_of_code_point_mask & 0xffff) == 0xffff)) { - // We process the data in chunks of 16 bytes. + utf8_end_of_code_point_mask & 0xfff; // we are only processing 12 bytes in case it is not all ASCII + if(utf8_end_of_code_point_mask == 0xfff) { + // We process the data in chunks of 12 bytes. _mm_storeu_si128(reinterpret_cast<__m128i *>(latin1_output), in); - latin1_output += 16; // We wrote 16 characters. - return 16; // We consumed 16 bytes. + latin1_output += 12; // We wrote 12 characters. + return 12; // We consumed 12 bytes. } /// We do not have a fast path available, so we fallback. const uint8_t idx = @@ -34206,7 +33821,7 @@ size_t convert_masked_utf8_to_latin1(const char *input, template std::pair sse_convert_utf16_to_latin1(const char16_t* buf, size_t len, char* latin1_output) { const char16_t* end = buf + len; - while (buf + 8 <= end) { + while (end - buf >= 8) { // Load 8 UTF-16 characters into 128-bit SSE register __m128i in = _mm_loadu_si128(reinterpret_cast(buf)); @@ -34234,10 +33849,10 @@ template std::pair sse_convert_utf16_to_latin1_with_errors(const char16_t* buf, size_t len, char* latin1_output) { const char16_t* start = buf; const char16_t* end = buf + len; - while (buf + 8 <= end) { + while (end - buf >= 8) { __m128i in = _mm_loadu_si128(reinterpret_cast(buf)); - if (!big_endian) { + if (!match_system(big_endian)) { const __m128i swap = _mm_setr_epi8(1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14); in = _mm_shuffle_epi8(in, swap); } @@ -34280,7 +33895,7 @@ std::pair sse_convert_utf16_to_latin1_with_errors(const char16_t* Ad 1. When values are less than 0x0800, it means that a 16-bit code unit - can be converted into: 1) single UTF8 byte (when it's an ASCII + can be converted into: 1) single UTF8 byte (when it is an ASCII char) or 2) two UTF8 bytes. For this case we do only some shuffle to obtain these 2-byte @@ -34328,7 +33943,7 @@ std::pair sse_convert_utf16_to_utf8(const char16_t* buf, const __m128i v_d800 = _mm_set1_epi16((int16_t)0xd800); const size_t safety_margin = 12; // to avoid overruns, see issue https://github.com/simdutf/simdutf/issues/92 - while (buf + 16 + safety_margin <= end) { + while (end - buf >= std::ptrdiff_t(16 + safety_margin)) { __m128i in = _mm_loadu_si128((__m128i*)buf); if (big_endian) { const __m128i swap = _mm_setr_epi8(1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14); @@ -34532,7 +34147,7 @@ std::pair sse_convert_utf16_to_utf8_with_errors(const char16_t* b const __m128i v_d800 = _mm_set1_epi16((int16_t)0xd800); const size_t safety_margin = 12; // to avoid overruns, see issue https://github.com/simdutf/simdutf/issues/92 - while (buf + 16 + safety_margin <= end) { + while (end - buf >= std::ptrdiff_t(16 + safety_margin)) { __m128i in = _mm_loadu_si128((__m128i*)buf); if (big_endian) { const __m128i swap = _mm_setr_epi8(1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14); @@ -34780,7 +34395,7 @@ std::pair sse_convert_utf16_to_utf32(const char16_t* const __m128i v_f800 = _mm_set1_epi16((int16_t)0xf800); const __m128i v_d800 = _mm_set1_epi16((int16_t)0xd800); - while (buf + 8 <= end) { + while (end - buf >= 8) { __m128i in = _mm_loadu_si128((__m128i*)buf); if (big_endian) { @@ -34848,7 +34463,7 @@ std::pair sse_convert_utf16_to_utf32_with_errors(const char16 const __m128i v_f800 = _mm_set1_epi16((int16_t)0xf800); const __m128i v_d800 = _mm_set1_epi16((int16_t)0xd800); - while (buf + 8 <= end) { + while (end - buf >= 8) { __m128i in = _mm_loadu_si128((__m128i*)buf); if (big_endian) { @@ -34996,7 +34611,7 @@ std::pair sse_convert_utf32_to_utf8(const char32_t* buf, __m128i forbidden_bytemask = _mm_setzero_si128(); const size_t safety_margin = 12; // to avoid overruns, see issue https://github.com/simdutf/simdutf/issues/92 - while (buf + 16 + safety_margin <= end) { //buf is a char32_t pointer, each char32_t has 4 bytes or 32 bits, thus buf + 16 * char_32t = 512 bits = 64 bytes + while (end - buf >= std::ptrdiff_t(16 + safety_margin)) { // buf is a char32_t pointer, each char32_t has 4 bytes or 32 bits, thus buf + 16 * char_32t = 512 bits = 64 bytes // We load two 16 bytes registers for a total of 32 bytes or 16 characters. __m128i in = _mm_loadu_si128((__m128i*)buf); __m128i nextin = _mm_loadu_si128((__m128i*)buf+1);//These two values can hold only 8 UTF32 chars @@ -35009,7 +34624,7 @@ std::pair sse_convert_utf32_to_utf8(const char32_t* buf, _mm_and_si128(in, v_7fffffff), _mm_and_si128(nextin, v_7fffffff) );//in this context pack the two __m128 into a single - //By ensuring the highest bit is set to 0(&v_7fffffff), we're making sure all values are interpreted as non-negative, or specifically, the values are within the range of valid Unicode code points. + //By ensuring the highest bit is set to 0(&v_7fffffff), we are making sure all values are interpreted as non-negative, or specifically, the values are within the range of valid Unicode code points. //remember : having leading byte 0 means a positive number by the two complements system. Unicode is well beneath the range where you'll start getting issues so that's OK. // Try to apply UTF-16 => UTF-8 from ./sse_convert_utf16_to_utf8.cpp @@ -35243,7 +34858,6 @@ std::pair sse_convert_utf32_to_utf8(const char32_t* buf, std::pair sse_convert_utf32_to_utf8_with_errors(const char32_t* buf, size_t len, char* utf8_output) { - const char32_t* end = buf + len; const char32_t* start = buf; @@ -35257,11 +34871,10 @@ std::pair sse_convert_utf32_to_utf8_with_errors(const char32_t* b const size_t safety_margin = 12; // to avoid overruns, see issue https://github.com/simdutf/simdutf/issues/92 - while (buf + 16 + safety_margin <= end) { - // We load two 16 bytes registers for a total of 32 bytes or 16 characters. + while (end - buf >= std::ptrdiff_t(16 + safety_margin)) { + // We load two 16 bytes registers for a total of 32 bytes or 8 characters. __m128i in = _mm_loadu_si128((__m128i*)buf); __m128i nextin = _mm_loadu_si128((__m128i*)buf+1); - // Check for too large input __m128i max_input = _mm_max_epu32(_mm_max_epu32(in, nextin), v_10ffff); if(static_cast(_mm_movemask_epi8(_mm_cmpeq_epi32(max_input, v_10ffff))) != 0xffff) { @@ -35275,14 +34888,6 @@ std::pair sse_convert_utf32_to_utf8_with_errors(const char32_t* b // Check for ASCII fast path if(_mm_testz_si128(in_16, v_ff80)) { // ASCII fast path!!!! - // We eagerly load another 32 bytes, hoping that they will be ASCII too. - // The intuition is that we try to collect 16 ASCII characters which requires - // a total of 64 bytes of input. If we fail, we just pass thirdin and fourthin - // as our new inputs. - __m128i thirdin = _mm_loadu_si128((__m128i*)buf+2); - __m128i fourthin = _mm_loadu_si128((__m128i*)buf+3); - __m128i nextin_16 = _mm_packus_epi32(_mm_and_si128(thirdin, v_7fffffff), _mm_and_si128(fourthin, v_7fffffff)); - if(!_mm_testz_si128(nextin_16, v_ff80)) { // 1. pack the bytes // obviously suboptimal. const __m128i utf8_packed = _mm_packus_epi16(in_16,in_16); @@ -35291,25 +34896,7 @@ std::pair sse_convert_utf32_to_utf8_with_errors(const char32_t* b // 3. adjust pointers buf += 8; utf8_output += 8; - // Proceed with next input - in_16 = nextin_16; - __m128i next_max_input = _mm_max_epu32(_mm_max_epu32(thirdin, fourthin), v_10ffff); - if(static_cast(_mm_movemask_epi8(_mm_cmpeq_epi32(next_max_input, v_10ffff))) != 0xffff) { - return std::make_pair(result(error_code::TOO_LARGE, buf - start), utf8_output); - } - // We need to update in and nextin because they are used later. - in = thirdin; - nextin = fourthin; - } else { - // 1. pack the bytes - const __m128i utf8_packed = _mm_packus_epi16(in_16, nextin_16); - // 2. store (16 bytes) - _mm_storeu_si128((__m128i*)utf8_output, utf8_packed); - // 3. adjust pointers - buf += 16; - utf8_output += 16; - continue; // we are done for this round! - } + continue; } // no bits set above 7th bit @@ -35491,7 +35078,6 @@ std::pair sse_convert_utf32_to_utf8_with_errors(const char32_t* b buf += k; } } // while - return std::make_pair(result(error_code::SUCCESS, buf - start), utf8_output); } /* end file src/westmere/sse_convert_utf32_to_utf8.cpp */ @@ -35505,7 +35091,7 @@ std::pair sse_convert_utf32_to_utf16(const char32_t* const __m128i v_ffff0000 = _mm_set1_epi32((int32_t)0xffff0000); __m128i forbidden_bytemask = _mm_setzero_si128(); - while (buf + 8 <= end) { + while (end - buf >= 8) { __m128i in = _mm_loadu_si128((__m128i*)buf); __m128i nextin = _mm_loadu_si128((__m128i*)buf+1); const __m128i saturation_bytemask = _mm_cmpeq_epi32(_mm_and_si128(_mm_or_si128(in, nextin), v_ffff0000), v_0000); @@ -35571,7 +35157,7 @@ std::pair sse_convert_utf32_to_utf16_with_errors(const char32 const __m128i v_0000 = _mm_setzero_si128(); const __m128i v_ffff0000 = _mm_set1_epi32((int32_t)0xffff0000); - while (buf + 8 <= end) { + while (end - buf >= 8) { __m128i in = _mm_loadu_si128((__m128i*)buf); __m128i nextin = _mm_loadu_si128((__m128i*)buf+1); const __m128i saturation_bytemask = _mm_cmpeq_epi32(_mm_and_si128(_mm_or_si128(in, nextin), v_ffff0000), v_0000); @@ -35867,8 +35453,7 @@ static inline uint16_t to_base64_mask(__m128i *src, bool *error) { } __m128i check_asso; if (base64_url) { - check_asso = _mm_setr_epi8(0xD, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, - 0x3, 0x7, 0xB, 0x6, 0xB, 0x12); + check_asso = _mm_setr_epi8(0xD,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x3,0x7,0xB,0xE,0xB,0x6); } else { check_asso = _mm_setr_epi8(0x0D, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, @@ -35876,11 +35461,9 @@ static inline uint16_t to_base64_mask(__m128i *src, bool *error) { } __m128i check_values; if (base64_url) { - check_values = _mm_setr_epi8(0x0, uint8_t(0x80), uint8_t(0x80), - uint8_t(0x80), uint8_t(0xCF), uint8_t(0xBF), - uint8_t(0xD3), uint8_t(0xA6), uint8_t(0xB5), - uint8_t(0x86), uint8_t(0xD0), uint8_t(0x80), - uint8_t(0xB0), uint8_t(0x80), 0x0, 0x0); + check_values = _mm_setr_epi8(uint8_t(0x80),uint8_t(0x80),uint8_t(0x80),uint8_t(0x80),uint8_t(0xCF), + uint8_t(0xBF),uint8_t(0xB6),uint8_t(0xA6),uint8_t(0xB5),uint8_t(0xA1),0x0,uint8_t(0x80), + 0x0,uint8_t(0x80),0x0,uint8_t(0x80)); } else { check_values = @@ -35889,7 +35472,7 @@ static inline uint16_t to_base64_mask(__m128i *src, bool *error) { int8_t(0xB5), int8_t(0x86), int8_t(0xD1), int8_t(0x80), int8_t(0xB1), int8_t(0x80), int8_t(0x91), int8_t(0x80)); } - const __m128i shifted = _mm_srli_epi32(*src, 3); + const __m128i shifted =_mm_srli_epi32(*src, 3); const __m128i delta_hash = _mm_avg_epu8(_mm_shuffle_epi8(delta_asso, *src), shifted); @@ -36019,19 +35602,22 @@ result compress_decode_base64(char *dst, const chartype *src, size_t srclen, base64_options options) { const uint8_t *to_base64 = base64_url ? tables::base64::to_base64_url_value : tables::base64::to_base64_value; + size_t equallocation = srclen; // location of the first padding character if any // skip trailing spaces - while (srclen > 0 && to_base64[uint8_t(src[srclen - 1])] == 64) { + while (srclen > 0 && scalar::base64::is_eight_byte(src[srclen - 1]) && to_base64[uint8_t(src[srclen - 1])] == 64) { srclen--; } size_t equalsigns = 0; if (srclen > 0 && src[srclen - 1] == '=') { + equallocation = srclen - 1; srclen--; equalsigns = 1; // skip trailing spaces - while (srclen > 0 && to_base64[uint8_t(src[srclen - 1])] == 64) { + while (srclen > 0 && scalar::base64::is_eight_byte(src[srclen - 1]) && to_base64[uint8_t(src[srclen - 1])] == 64) { srclen--; } if (srclen > 0 && src[srclen - 1] == '=') { + equallocation = srclen - 1; srclen--; equalsigns = 2; } @@ -36057,7 +35643,7 @@ result compress_decode_base64(char *dst, const chartype *src, size_t srclen, uint64_t badcharmask = to_base64_mask(&b, &error); if (error) { src -= 64; - while (src < srcend && to_base64[uint8_t(*src)] <= 64) { + while (src < srcend && scalar::base64::is_eight_byte(*src) && to_base64[uint8_t(*src)] <= 64) { src++; } return {error_code::INVALID_BASE64_CHARACTER, size_t(src - srcinit)}; @@ -36104,7 +35690,7 @@ result compress_decode_base64(char *dst, const chartype *src, size_t srclen, while ((bufferptr - buffer_start) % 64 != 0 && src < srcend) { uint8_t val = to_base64[uint8_t(*src)]; *bufferptr = char(val); - if (val > 64) { + if (!scalar::base64::is_eight_byte(*src) || val > 64) { return {error_code::INVALID_BASE64_CHARACTER, size_t(src - srcinit)}; } bufferptr += (val <= 63); @@ -36151,7 +35737,7 @@ result compress_decode_base64(char *dst, const chartype *src, size_t srclen, if (leftover > 0) { while (leftover < 4 && src < srcend) { uint8_t val = to_base64[uint8_t(*src)]; - if (val > 64) { + if (!scalar::base64::is_eight_byte(*src) || val > 64) { return {error_code::INVALID_BASE64_CHARACTER, size_t(src - srcinit)}; } buffer_start[leftover] = char(val); @@ -36204,13 +35790,14 @@ result compress_decode_base64(char *dst, const chartype *src, size_t srclen, // additional checks if((r.count % 3 == 0) || ((r.count % 3) + 1 + equalsigns != 4)) { r.error = error_code::INVALID_BASE64_CHARACTER; + r.count = equallocation; } } return r; } if(equalsigns > 0) { if((size_t(dst - dstinit) % 3 == 0) || ((size_t(dst - dstinit) % 3) + 1 + equalsigns != 4)) { - return {INVALID_BASE64_CHARACTER, size_t(dst - dstinit)}; + return {INVALID_BASE64_CHARACTER, equallocation}; } } return {SUCCESS, size_t(dst - dstinit)}; @@ -36301,7 +35888,7 @@ simdutf_really_inline const uint8_t *buf_block_reader::full_block() c template simdutf_really_inline size_t buf_block_reader::get_remainder(uint8_t *dst) const { if(len == idx) { return 0; } // memcpy(dst, null, 0) will trigger an error with some sanitizers - std::memset(dst, 0x20, STEP_SIZE); // std::memset STEP_SIZE because it's more efficient to write out 8 or 16 bytes at once. + std::memset(dst, 0x20, STEP_SIZE); // std::memset STEP_SIZE because it is more efficient to write out 8 or 16 bytes at once. std::memcpy(dst, buf + idx, len - idx); return len - idx; } @@ -36424,7 +36011,7 @@ using namespace simd; // // Return nonzero if there are incomplete multibyte characters at the end of the block: - // e.g. if there is a 4-byte character, but it's 3 bytes from the end. + // e.g. if there is a 4-byte character, but it is 3 bytes from the end. // simdutf_really_inline simd8 is_incomplete(const simd8 input) { // If the previous input's last 3 bytes match this, they're too short (they ended at EOF): @@ -36869,6 +36456,9 @@ using namespace simd; this->check_utf8_bytes(input.chunks[3], input.chunks[2]); } uint64_t utf8_continuation_mask = input.lt(-65 + 1); + if(utf8_continuation_mask & 1) { + return 0; // error + } uint64_t utf8_leading_mask = ~utf8_continuation_mask; uint64_t utf8_end_of_code_point_mask = utf8_leading_mask>>1; // We process in blocks of up to 12 bytes except possibly @@ -36943,14 +36533,14 @@ using namespace simd; this->check_utf8_bytes(input.chunks[2], input.chunks[1]); this->check_utf8_bytes(input.chunks[3], input.chunks[2]); } - if (errors()) { + uint64_t utf8_continuation_mask = input.lt(-65 + 1); + if (errors() || (utf8_continuation_mask & 1)) { // rewind_and_convert_with_errors will seek a potential error from in+pos onward, // with the ability to go back up to pos bytes, and read size-pos bytes forward. result res = scalar::utf8_to_utf16::rewind_and_convert_with_errors(pos, in + pos, size - pos, utf16_output); res.count += pos; return res; } - uint64_t utf8_continuation_mask = input.lt(-65 + 1); uint64_t utf8_leading_mask = ~utf8_continuation_mask; uint64_t utf8_end_of_code_point_mask = utf8_leading_mask>>1; // We process in blocks of up to 12 bytes except possibly @@ -37188,10 +36778,10 @@ using namespace simd; size_t pos = 0; char32_t* start{utf32_output}; // In the worst case, we have the haswell kernel which can cause an overflow of - // 8 bytes when calling convert_masked_utf8_to_utf32. If you skip the last 16 bytes, + // 8 words when calling convert_masked_utf8_to_utf32. If you skip the last 16 bytes, // and if the data is valid, then it is entirely safe because 16 UTF-8 bytes generate // much more than 8 bytes. However, you cannot generally assume that you have valid - // UTF-8 input, so we are going to go back from the end counting 8 leading bytes, + // UTF-8 input, so we are going to go back from the end counting 16 leading bytes, // to give us a good margin. size_t leading_byte = 0; size_t margin = size; @@ -37221,6 +36811,9 @@ using namespace simd; this->check_utf8_bytes(input.chunks[3], input.chunks[2]); } uint64_t utf8_continuation_mask = input.lt(-65 + 1); + if(utf8_continuation_mask & 1) { + return 0; // we have an error + } uint64_t utf8_leading_mask = ~utf8_continuation_mask; uint64_t utf8_end_of_code_point_mask = utf8_leading_mask>>1; // We process in blocks of up to 12 bytes except possibly @@ -37294,12 +36887,12 @@ using namespace simd; this->check_utf8_bytes(input.chunks[2], input.chunks[1]); this->check_utf8_bytes(input.chunks[3], input.chunks[2]); } - if (errors()) { + uint64_t utf8_continuation_mask = input.lt(-65 + 1); + if (errors() || (utf8_continuation_mask & 1)) { result res = scalar::utf8_to_utf32::rewind_and_convert_with_errors(pos, in + pos, size - pos, utf32_output); res.count += pos; return res; } - uint64_t utf8_continuation_mask = input.lt(-65 + 1); uint64_t utf8_leading_mask = ~utf8_continuation_mask; uint64_t utf8_end_of_code_point_mask = utf8_leading_mask>>1; // We process in blocks of up to 12 bytes except possibly @@ -37847,16 +37440,17 @@ namespace westmere { simdutf_warn_unused int implementation::detect_encodings(const char * input, size_t length) const noexcept { // If there is a BOM, then we trust it. auto bom_encoding = simdutf::BOM::check_bom(input, length); + // todo: reimplement as a one-pass algorithm. if(bom_encoding != encoding_type::unspecified) { return bom_encoding; } - if (length % 2 == 0) { - return sse_detect_encodings(input, length); - } else { - if (implementation::validate_utf8(input, length)) { - return simdutf::encoding_type::UTF8; - } else { - return simdutf::encoding_type::unspecified; - } + int out = 0; + if(validate_utf8(input, length)) { out |= encoding_type::UTF8; } + if((length % 2) == 0) { + if(validate_utf16le(reinterpret_cast(input), length/2)) { out |= encoding_type::UTF16_LE; } + } + if((length % 4) == 0) { + if(validate_utf32(reinterpret_cast(input), length/4)) { out |= encoding_type::UTF32_LE; } } + return out; } simdutf_warn_unused bool implementation::validate_utf8(const char *buf, size_t len) const noexcept { @@ -37876,7 +37470,12 @@ simdutf_warn_unused result implementation::validate_ascii_with_errors(const char } simdutf_warn_unused bool implementation::validate_utf16le(const char16_t *buf, size_t len) const noexcept { - const char16_t* tail = sse_validate_utf16(buf, len); + if (simdutf_unlikely(len == 0)) { + // empty input is valid UTF-16. protect the implementation from + // handling nullptr + return true; + } + const char16_t *tail = sse_validate_utf16(buf, len); if (tail) { return scalar::utf16::validate(tail, len - (tail - buf)); } else { @@ -37885,7 +37484,12 @@ simdutf_warn_unused bool implementation::validate_utf16le(const char16_t *buf, s } simdutf_warn_unused bool implementation::validate_utf16be(const char16_t *buf, size_t len) const noexcept { - const char16_t* tail = sse_validate_utf16(buf, len); + if (simdutf_unlikely(len == 0)) { + // empty input is valid UTF-16. protect the implementation from + // handling nullptr + return true; + } + const char16_t *tail = sse_validate_utf16(buf, len); if (tail) { return scalar::utf16::validate(tail, len - (tail - buf)); } else { @@ -37914,7 +37518,12 @@ simdutf_warn_unused result implementation::validate_utf16be_with_errors(const ch } simdutf_warn_unused bool implementation::validate_utf32(const char32_t *buf, size_t len) const noexcept { - const char32_t* tail = sse_validate_utf32le(buf, len); + if (simdutf_unlikely(len == 0)) { + // empty input is valid UTF-32. protect the implementation from + // handling nullptr + return true; + } + const char32_t *tail = sse_validate_utf32le(buf, len); if (tail) { return scalar::utf32::validate(tail, len - (tail - buf)); } else { @@ -37923,6 +37532,11 @@ simdutf_warn_unused bool implementation::validate_utf32(const char32_t *buf, siz } simdutf_warn_unused result implementation::validate_utf32_with_errors(const char32_t *buf, size_t len) const noexcept { + if (len == 0) { + // empty input is valid UTF-32. protect the implementation from + // handling nullptr + return result(error_code::SUCCESS, 0); + } result res = sse_validate_utf32le_with_errors(buf, len); if (res.count != len) { result scalar_res = scalar::utf32::validate_with_errors(buf + res.count, len - res.count); @@ -38446,46 +38060,62 @@ simdutf_warn_unused size_t implementation::utf8_length_from_latin1(const char * const uint8_t *str = reinterpret_cast(input); size_t answer = len / sizeof(__m128i) * sizeof(__m128i); size_t i = 0; - __m128i two_64bits = _mm_setzero_si128(); - while (i + sizeof(__m128i) <= len) { - __m128i runner = _mm_setzero_si128(); - size_t iterations = (len - i) / sizeof(__m128i); - if (iterations > 255) { - iterations = 255; - } - size_t max_i = i + iterations * sizeof(__m128i) - sizeof(__m128i); - for (; i + 4*sizeof(__m128i) <= max_i; i += 4*sizeof(__m128i)) { - __m128i input1 = _mm_loadu_si128((const __m128i *)(str + i)); - __m128i input2 = _mm_loadu_si128((const __m128i *)(str + i + sizeof(__m128i))); - __m128i input3 = _mm_loadu_si128((const __m128i *)(str + i + 2*sizeof(__m128i))); - __m128i input4 = _mm_loadu_si128((const __m128i *)(str + i + 3*sizeof(__m128i))); - __m128i input12 = _mm_add_epi8( - _mm_cmpgt_epi8( - _mm_setzero_si128(), - input1), - _mm_cmpgt_epi8( - _mm_setzero_si128(), - input2)); - __m128i input34 = _mm_add_epi8( - _mm_cmpgt_epi8( - _mm_setzero_si128(), - input3), - _mm_cmpgt_epi8( - _mm_setzero_si128(), - input4)); - __m128i input1234 = _mm_add_epi8(input12, input34); - runner = _mm_sub_epi8(runner, input1234); - } - for (; i <= max_i; i += sizeof(__m128i)) { - __m128i more_input = _mm_loadu_si128((const __m128i *)(str + i)); - runner = _mm_sub_epi8( - runner, _mm_cmpgt_epi8(_mm_setzero_si128(), more_input)); - } - two_64bits = _mm_add_epi64( - two_64bits, _mm_sad_epu8(runner, _mm_setzero_si128())); - } - answer += _mm_extract_epi64(two_64bits, 0) + - _mm_extract_epi64(two_64bits, 1); + if(answer >= 2048) { // long strings optimization + __m128i two_64bits = _mm_setzero_si128(); + while (i + sizeof(__m128i) <= len) { + __m128i runner = _mm_setzero_si128(); + size_t iterations = (len - i) / sizeof(__m128i); + if (iterations > 255) { + iterations = 255; + } + size_t max_i = i + iterations * sizeof(__m128i) - sizeof(__m128i); + for (; i + 4*sizeof(__m128i) <= max_i; i += 4*sizeof(__m128i)) { + __m128i input1 = _mm_loadu_si128((const __m128i *)(str + i)); + __m128i input2 = _mm_loadu_si128((const __m128i *)(str + i + sizeof(__m128i))); + __m128i input3 = _mm_loadu_si128((const __m128i *)(str + i + 2*sizeof(__m128i))); + __m128i input4 = _mm_loadu_si128((const __m128i *)(str + i + 3*sizeof(__m128i))); + __m128i input12 = _mm_add_epi8( + _mm_cmpgt_epi8( + _mm_setzero_si128(), + input1), + _mm_cmpgt_epi8( + _mm_setzero_si128(), + input2)); + __m128i input34 = _mm_add_epi8( + _mm_cmpgt_epi8( + _mm_setzero_si128(), + input3), + _mm_cmpgt_epi8( + _mm_setzero_si128(), + input4)); + __m128i input1234 = _mm_add_epi8(input12, input34); + runner = _mm_sub_epi8(runner, input1234); + } + for (; i <= max_i; i += sizeof(__m128i)) { + __m128i more_input = _mm_loadu_si128((const __m128i *)(str + i)); + runner = _mm_sub_epi8( + runner, _mm_cmpgt_epi8(_mm_setzero_si128(), more_input)); + } + two_64bits = _mm_add_epi64( + two_64bits, _mm_sad_epu8(runner, _mm_setzero_si128())); + } + answer += _mm_extract_epi64(two_64bits, 0) + + _mm_extract_epi64(two_64bits, 1); + } else if (answer > 0) { // short string optimization + for(; i + 2*sizeof(__m128i) <= len; i += 2*sizeof(__m128i)) { + __m128i latin = _mm_loadu_si128((const __m128i*)(input + i)); + uint16_t non_ascii = (uint16_t)_mm_movemask_epi8(latin); + answer += count_ones(non_ascii); + latin = _mm_loadu_si128((const __m128i*)(input + i)+1); + non_ascii = (uint16_t)_mm_movemask_epi8(latin); + answer += count_ones(non_ascii); + } + for(; i + sizeof(__m128i) <= len; i += sizeof(__m128i)) { + __m128i latin = _mm_loadu_si128((const __m128i*)(input + i)); + uint16_t non_ascii = (uint16_t)_mm_movemask_epi8(latin); + answer += count_ones(non_ascii); + } + } return answer + scalar::latin1::utf8_length_from_latin1(reinterpret_cast(str + i), len - i); } diff --git a/deps/simdutf/simdutf.h b/deps/simdutf/simdutf.h index ee7f19ce1f9..4b534c12563 100644 --- a/deps/simdutf/simdutf.h +++ b/deps/simdutf/simdutf.h @@ -1,4 +1,4 @@ -/* auto-generated on 2024-07-11 00:01:58 -0400. Do not edit! */ +/* auto-generated on 2024-09-04 18:13:32 +0200. Do not edit! */ /* begin file include/simdutf.h */ #ifndef SIMDUTF_H #define SIMDUTF_H @@ -20,6 +20,18 @@ #endif #endif + +// C++ 23 +#if !defined(SIMDUTF_CPLUSPLUS23) && (SIMDUTF_CPLUSPLUS >= 202302L) +#define SIMDUTF_CPLUSPLUS23 1 +#endif + +// C++ 20 +#if !defined(SIMDUTF_CPLUSPLUS20) && (SIMDUTF_CPLUSPLUS >= 202002L) +#define SIMDUTF_CPLUSPLUS20 1 +#endif + + // C++ 17 #if !defined(SIMDUTF_CPLUSPLUS17) && (SIMDUTF_CPLUSPLUS >= 201703L) #define SIMDUTF_CPLUSPLUS17 1 @@ -398,6 +410,8 @@ #define SIMDUTF_ISALIGNED_N(ptr, n) (((uintptr_t)(ptr) & ((n)-1)) == 0) #if defined(SIMDUTF_REGULAR_VISUAL_STUDIO) + #define SIMDUTF_DEPRECATED __declspec(deprecated) + #define simdutf_really_inline __forceinline #define simdutf_never_inline __declspec(noinline) @@ -433,8 +447,13 @@ #define SIMDUTF_POP_DISABLE_WARNINGS __pragma(warning( pop )) #else // SIMDUTF_REGULAR_VISUAL_STUDIO - +#if defined(__OPTIMIZE__) || defined(NDEBUG) #define simdutf_really_inline inline __attribute__((always_inline)) +#else + #define simdutf_really_inline inline +#endif + + #define SIMDUTF_DEPRECATED __attribute__((deprecated)) #define simdutf_never_inline inline __attribute__((noinline)) #define simdutf_unused __attribute__((unused)) @@ -594,7 +613,7 @@ SIMDUTF_DISABLE_UNDESIRED_WARNINGS #define SIMDUTF_SIMDUTF_VERSION_H /** The version of simdutf being used (major.minor.revision) */ -#define SIMDUTF_VERSION "5.3.0" +#define SIMDUTF_VERSION "5.5.0" namespace simdutf { enum { @@ -605,7 +624,7 @@ enum { /** * The minor version (major.MINOR.revision) of simdutf being used. */ - SIMDUTF_VERSION_MINOR = 3, + SIMDUTF_VERSION_MINOR = 5, /** * The revision (major.minor.REVISION) of simdutf being used. */ @@ -1117,67 +1136,79 @@ simdutf_warn_unused bool validate_utf32(const char32_t *buf, size_t len) noexcep */ simdutf_warn_unused result validate_utf32_with_errors(const char32_t *buf, size_t len) noexcept; - /** - * Convert Latin1 string into UTF8 string. - * - * This function is suitable to work with inputs from untrusted sources. - * - * @param input the Latin1 string to convert - * @param length the length of the string in bytes - * @param latin1_output the pointer to buffer that can hold conversion result - * @return the number of written char; 0 if conversion is not possible - */ - simdutf_warn_unused size_t convert_latin1_to_utf8(const char * input, size_t length, char* utf8_output) noexcept; +/** + * Convert Latin1 string into UTF8 string. + * + * This function is suitable to work with inputs from untrusted sources. + * + * @param input the Latin1 string to convert + * @param length the length of the string in bytes + * @param utf8_output the pointer to buffer that can hold conversion result + * @return the number of written char; 0 if conversion is not possible + */ +simdutf_warn_unused size_t convert_latin1_to_utf8(const char * input, size_t length, char* utf8_output) noexcept; +/** + * Convert Latin1 string into UTF8 string with output limit. + * + * This function is suitable to work with inputs from untrusted sources. + * + * @param input the Latin1 string to convert + * @param length the length of the string in bytes + * @param utf8_output the pointer to buffer that can hold conversion result + * @param utf8_len the maximum output length + * @return the number of written char; 0 if conversion is not possible + */ +simdutf_warn_unused size_t convert_latin1_to_utf8_safe(const char * input, size_t length, char* utf8_output, size_t utf8_len) noexcept; - /** - * Convert possibly Latin1 string into UTF-16LE string. - * - * This function is suitable to work with inputs from untrusted sources. - * - * @param input the Latin1 string to convert - * @param length the length of the string in bytes - * @param utf16_buffer the pointer to buffer that can hold conversion result - * @return the number of written char16_t; 0 if conversion is not possible - */ - simdutf_warn_unused size_t convert_latin1_to_utf16le(const char * input, size_t length, char16_t* utf16_output) noexcept; +/** + * Convert possibly Latin1 string into UTF-16LE string. + * + * This function is suitable to work with inputs from untrusted sources. + * + * @param input the Latin1 string to convert + * @param length the length of the string in bytes + * @param utf16_buffer the pointer to buffer that can hold conversion result + * @return the number of written char16_t; 0 if conversion is not possible + */ +simdutf_warn_unused size_t convert_latin1_to_utf16le(const char * input, size_t length, char16_t* utf16_output) noexcept; - /** - * Convert Latin1 string into UTF-16BE string. - * - * This function is suitable to work with inputs from untrusted sources. - * - * @param input the Latin1 string to convert - * @param length the length of the string in bytes - * @param utf16_buffer the pointer to buffer that can hold conversion result - * @return the number of written char16_t; 0 if conversion is not possible - */ - simdutf_warn_unused size_t convert_latin1_to_utf16be(const char * input, size_t length, char16_t* utf16_output) noexcept; +/** + * Convert Latin1 string into UTF-16BE string. + * + * This function is suitable to work with inputs from untrusted sources. + * + * @param input the Latin1 string to convert + * @param length the length of the string in bytes + * @param utf16_buffer the pointer to buffer that can hold conversion result + * @return the number of written char16_t; 0 if conversion is not possible + */ +simdutf_warn_unused size_t convert_latin1_to_utf16be(const char * input, size_t length, char16_t* utf16_output) noexcept; - /** - * Convert Latin1 string into UTF-32 string. - * - * This function is suitable to work with inputs from untrusted sources. - * - * @param input the Latin1 string to convert - * @param length the length of the string in bytes - * @param utf32_buffer the pointer to buffer that can hold conversion result - * @return the number of written char32_t; 0 if conversion is not possible - */ - simdutf_warn_unused size_t convert_latin1_to_utf32(const char * input, size_t length, char32_t* utf32_buffer) noexcept; +/** + * Convert Latin1 string into UTF-32 string. + * + * This function is suitable to work with inputs from untrusted sources. + * + * @param input the Latin1 string to convert + * @param length the length of the string in bytes + * @param utf32_buffer the pointer to buffer that can hold conversion result + * @return the number of written char32_t; 0 if conversion is not possible + */ +simdutf_warn_unused size_t convert_latin1_to_utf32(const char * input, size_t length, char32_t* utf32_buffer) noexcept; - /** - * Convert possibly broken UTF-8 string into latin1 string. - * - * During the conversion also validation of the input string is done. - * This function is suitable to work with inputs from untrusted sources. - * - * @param input the UTF-8 string to convert - * @param length the length of the string in bytes - * @param latin1_output the pointer to buffer that can hold conversion result - * @return the number of written char; 0 if the input was not valid UTF-8 string or if it cannot be represented as Latin1 - */ - simdutf_warn_unused size_t convert_utf8_to_latin1(const char * input, size_t length, char* latin1_output) noexcept; +/** + * Convert possibly broken UTF-8 string into latin1 string. + * + * During the conversion also validation of the input string is done. + * This function is suitable to work with inputs from untrusted sources. + * + * @param input the UTF-8 string to convert + * @param length the length of the string in bytes + * @param latin1_output the pointer to buffer that can hold conversion result + * @return the number of written char; 0 if the input was not valid UTF-8 string or if it cannot be represented as Latin1 + */ +simdutf_warn_unused size_t convert_utf8_to_latin1(const char * input, size_t length, char* latin1_output) noexcept; /** * Using native endianness, convert possibly broken UTF-8 string into a UTF-16 string. @@ -1192,7 +1223,6 @@ simdutf_warn_unused result validate_utf32_with_errors(const char32_t *buf, size_ */ simdutf_warn_unused size_t convert_utf8_to_utf16(const char * input, size_t length, char16_t* utf16_output) noexcept; - /** * Using native endianness, convert a Latin1 string into a UTF-16 string. * @@ -1311,19 +1341,23 @@ simdutf_warn_unused size_t convert_utf8_to_utf32(const char * input, size_t leng */ simdutf_warn_unused result convert_utf8_to_utf32_with_errors(const char * input, size_t length, char32_t* utf32_output) noexcept; - /** - * Convert valid UTF-8 string into latin1 string. - * - * This function assumes that the input string is valid UTF-8. - * - * This function is not BOM-aware. - * - * @param input the UTF-8 string to convert - * @param length the length of the string in bytes - * @param latin1_output the pointer to buffer that can hold conversion result - * @return the number of written char; 0 if the input was not valid UTF-8 string - */ - simdutf_warn_unused size_t convert_valid_utf8_to_latin1(const char * input, size_t length, char* latin1_output) noexcept; +/** + * Convert valid UTF-8 string into latin1 string. + * + * This function assumes that the input string is valid UTF-8 and that it can be represented as Latin1. + * If you violate this assumption, the result is implementation defined and may include system-dependent behavior such as crashes. + * + * This function is for expert users only and not part of our public API. Use convert_utf8_to_latin1 instead. + * The function may be removed from the library in the future. + * + * This function is not BOM-aware. + * + * @param input the UTF-8 string to convert + * @param length the length of the string in bytes + * @param latin1_output the pointer to buffer that can hold conversion result + * @return the number of written char; 0 if the input was not valid UTF-8 string + */ +simdutf_warn_unused size_t convert_valid_utf8_to_latin1(const char * input, size_t length, char* latin1_output) noexcept; /** @@ -1387,7 +1421,8 @@ simdutf_warn_unused size_t utf8_length_from_latin1(const char * input, size_t le /** * Compute the number of bytes that this UTF-8 string would require in Latin1 format. * - * This function does not validate the input. + * This function does not validate the input. It is acceptable to pass invalid UTF-8 strings but in such cases + * the result is implementation defined. * * This function is not BOM-aware. * @@ -1400,7 +1435,8 @@ simdutf_warn_unused size_t latin1_length_from_utf8(const char * input, size_t le /** * Compute the number of 2-byte code units that this UTF-8 string would require in UTF-16LE format. * - * This function does not validate the input. + * This function does not validate the input. It is acceptable to pass invalid UTF-8 strings but in such cases + * the result is implementation defined. * * This function is not BOM-aware. * @@ -1415,7 +1451,8 @@ simdutf_warn_unused size_t utf16_length_from_utf8(const char * input, size_t len * * This function is equivalent to count_utf8 * - * This function does not validate the input. + * This function does not validate the input. It is acceptable to pass invalid UTF-8 strings but in such cases + * the result is implementation defined. * * This function is not BOM-aware. * @@ -1628,7 +1665,11 @@ simdutf_warn_unused size_t convert_valid_utf16_to_utf8(const char16_t * input, s /** * Using native endianness, convert UTF-16 string into Latin1 string. * - * This function assumes that the input string is valid UTF-8. + * This function assumes that the input string is valid UTF-16 and that it can be represented as Latin1. + * If you violate this assumption, the result is implementation defined and may include system-dependent behavior such as crashes. + * + * This function is for expert users only and not part of our public API. Use convert_utf16_to_latin1 instead. + * The function may be removed from the library in the future. * * This function is not BOM-aware. * @@ -1642,7 +1683,11 @@ simdutf_warn_unused size_t convert_valid_utf16_to_latin1(const char16_t * input, /** * Convert valid UTF-16LE string into Latin1 string. * - * This function assumes that the input string is valid UTF-16LE. + * This function assumes that the input string is valid UTF-16LE and that it can be represented as Latin1. + * If you violate this assumption, the result is implementation defined and may include system-dependent behavior such as crashes. + * + * This function is for expert users only and not part of our public API. Use convert_utf16le_to_latin1 instead. + * The function may be removed from the library in the future. * * This function is not BOM-aware. * @@ -1656,7 +1701,11 @@ simdutf_warn_unused size_t convert_valid_utf16le_to_latin1(const char16_t * inpu /** * Convert valid UTF-16BE string into Latin1 string. * - * This function assumes that the input string is valid UTF-16BE. + * This function assumes that the input string is valid UTF-16BE and that it can be represented as Latin1. + * If you violate this assumption, the result is implementation defined and may include system-dependent behavior such as crashes. + * + * This function is for expert users only and not part of our public API. Use convert_utf16be_to_latin1 instead. + * The function may be removed from the library in the future. * * This function is not BOM-aware. * @@ -1671,7 +1720,7 @@ simdutf_warn_unused size_t convert_valid_utf16be_to_latin1(const char16_t * inpu /** * Convert valid UTF-16LE string into UTF-8 string. * - * This function assumes that the input string is valid UTF-16LE. + * This function assumes that the input string is valid UTF-16LE and that it can be represented as Latin1. * * This function is not BOM-aware. * @@ -1833,7 +1882,8 @@ simdutf_warn_unused size_t convert_valid_utf16be_to_utf32(const char16_t * input /* * Compute the number of bytes that this UTF-16LE/BE string would require in Latin1 format. * - * This function does not validate the input. + * This function does not validate the input. It is acceptable to pass invalid UTF-16 strings but in such cases + * the result is implementation defined. * * This function is not BOM-aware. * @@ -1847,7 +1897,8 @@ simdutf_warn_unused size_t latin1_length_from_utf16(size_t length) noexcept; * Using native endianness; Compute the number of bytes that this UTF-16 * string would require in UTF-8 format. * - * This function does not validate the input. + * This function does not validate the input. It is acceptable to pass invalid UTF-16 strings but in such cases + * the result is implementation defined. * * @param input the UTF-16 string to convert * @param length the length of the string in 2-byte code units (char16_t) @@ -1858,7 +1909,8 @@ simdutf_warn_unused size_t utf8_length_from_utf16(const char16_t * input, size_t /** * Compute the number of bytes that this UTF-16LE string would require in UTF-8 format. * - * This function does not validate the input. + * This function does not validate the input. It is acceptable to pass invalid UTF-16 strings but in such cases + * the result is implementation defined. * * @param input the UTF-16LE string to convert * @param length the length of the string in 2-byte code units (char16_t) @@ -1869,7 +1921,8 @@ simdutf_warn_unused size_t utf8_length_from_utf16le(const char16_t * input, size /** * Compute the number of bytes that this UTF-16BE string would require in UTF-8 format. * - * This function does not validate the input. + * This function does not validate the input. It is acceptable to pass invalid UTF-16 strings but in such cases + * the result is implementation defined. * * @param input the UTF-16BE string to convert * @param length the length of the string in 2-byte code units (char16_t) @@ -1986,7 +2039,11 @@ simdutf_warn_unused result convert_utf32_to_latin1_with_errors(const char32_t * /** * Convert valid UTF-32 string into Latin1 string. * - * This function assumes that the input string is valid UTF-32. + * This function assumes that the input string is valid UTF-32 and that it can be represented as Latin1. + * If you violate this assumption, the result is implementation defined and may include system-dependent behavior such as crashes. + * + * This function is for expert users only and not part of our public API. Use convert_utf32_to_latin1 instead. + * The function may be removed from the library in the future. * * This function is not BOM-aware. * @@ -2117,7 +2174,8 @@ void change_endianness_utf16(const char16_t * input, size_t length, char16_t * o /** * Compute the number of bytes that this UTF-32 string would require in UTF-8 format. * - * This function does not validate the input. + * This function does not validate the input. It is acceptable to pass invalid UTF-32 strings but in such cases + * the result is implementation defined. * * @param input the UTF-32 string to convert * @param length the length of the string in 4-byte code units (char32_t) @@ -2128,7 +2186,8 @@ simdutf_warn_unused size_t utf8_length_from_utf32(const char32_t * input, size_t /** * Compute the number of two-byte code units that this UTF-32 string would require in UTF-16 format. * - * This function does not validate the input. + * This function does not validate the input. It is acceptable to pass invalid UTF-32 strings but in such cases + * the result is implementation defined. * * @param input the UTF-32 string to convert * @param length the length of the string in 4-byte code units (char32_t) @@ -2142,7 +2201,8 @@ simdutf_warn_unused size_t utf16_length_from_utf32(const char32_t * input, size_ * * This function is equivalent to count_utf16. * - * This function does not validate the input. + * This function does not validate the input. It is acceptable to pass invalid UTF-16 strings but in such cases + * the result is implementation defined. * * This function is not BOM-aware. * @@ -2157,7 +2217,8 @@ simdutf_warn_unused size_t utf32_length_from_utf16(const char16_t * input, size_ * * This function is equivalent to count_utf16le. * - * This function does not validate the input. + * This function does not validate the input. It is acceptable to pass invalid UTF-16 strings but in such cases + * the result is implementation defined. * * This function is not BOM-aware. * @@ -2172,7 +2233,8 @@ simdutf_warn_unused size_t utf32_length_from_utf16le(const char16_t * input, siz * * This function is equivalent to count_utf16be. * - * This function does not validate the input. + * This function does not validate the input. It is acceptable to pass invalid UTF-16 strings but in such cases + * the result is implementation defined. * * This function is not BOM-aware. * @@ -2187,6 +2249,8 @@ simdutf_warn_unused size_t utf32_length_from_utf16be(const char16_t * input, siz * it is valid. * * This function assumes that the input string is valid UTF-16 (native endianness). + * It is acceptable to pass invalid UTF-16 strings but in such cases + * the result is implementation defined. * * This function is not BOM-aware. * @@ -2201,6 +2265,8 @@ simdutf_warn_unused size_t count_utf16(const char16_t * input, size_t length) no * it is valid. * * This function assumes that the input string is valid UTF-16LE. + * It is acceptable to pass invalid UTF-16 strings but in such cases + * the result is implementation defined. * * This function is not BOM-aware. * @@ -2215,6 +2281,8 @@ simdutf_warn_unused size_t count_utf16le(const char16_t * input, size_t length) * it is valid. * * This function assumes that the input string is valid UTF-16BE. + * It is acceptable to pass invalid UTF-16 strings but in such cases + * the result is implementation defined. * * This function is not BOM-aware. * @@ -2229,6 +2297,8 @@ simdutf_warn_unused size_t count_utf16be(const char16_t * input, size_t length) * it is valid. * * This function assumes that the input string is valid UTF-8. + * It is acceptable to pass invalid UTF-8 strings but in such cases + * the result is implementation defined. * * @param input the UTF-8 string to process * @param length the length of the string in bytes @@ -2300,7 +2370,6 @@ simdutf_warn_unused size_t trim_partial_utf16(const char16_t* input, size_t leng // base64_options are used to specify the base64 encoding options. using base64_options = uint64_t; -using base64_options = uint64_t; enum : base64_options { base64_default = 0, /* standard base64 format (with padding) */ base64_url = 1, /* base64url format (no padding) */ @@ -2332,7 +2401,7 @@ simdutf_warn_unused size_t maximal_binary_length_from_base64(const char * input, simdutf_warn_unused size_t maximal_binary_length_from_base64(const char16_t * input, size_t length) noexcept; /** - * Convert a base64 input to a binary ouput. + * Convert a base64 input to a binary output. * * This function follows the WHATWG forgiving-base64 format, which means that it will * ignore any ASCII spaces in the input. You may provide a padded input (with one or two @@ -2375,7 +2444,7 @@ simdutf_warn_unused result base64_to_binary(const char * input, size_t length, c simdutf_warn_unused size_t base64_length_from_binary(size_t length, base64_options options = base64_default) noexcept; /** - * Convert a binary input to a base64 ouput. + * Convert a binary input to a base64 output. * * The default option (simdutf::base64_default) uses the characters `+` and `/` as part of its alphabet. * Further, it adds padding (`=`) at the end of the output to ensure that the output length is a multiple of four. @@ -2394,7 +2463,7 @@ simdutf_warn_unused size_t base64_length_from_binary(size_t length, base64_optio size_t binary_to_base64(const char * input, size_t length, char* output, base64_options options = base64_default) noexcept; /** - * Convert a base64 input to a binary ouput. + * Convert a base64 input to a binary output. * * This function follows the WHATWG forgiving-base64 format, which means that it will * ignore any ASCII spaces in the input. You may provide a padded input (with one or two @@ -2429,7 +2498,7 @@ size_t binary_to_base64(const char * input, size_t length, char* output, base64_ simdutf_warn_unused result base64_to_binary(const char16_t * input, size_t length, char* output, base64_options options = base64_default) noexcept; /** - * Convert a base64 input to a binary ouput. + * Convert a base64 input to a binary output. * * This function follows the WHATWG forgiving-base64 format, which means that it will * ignore any ASCII spaces in the input. You may provide a padded input (with one or two @@ -2669,13 +2738,12 @@ class implementation { * * @param input the Latin1 string to convert * @param length the length of the string in bytes - * @param latin1_output the pointer to buffer that can hold conversion result + * @param utf8_output the pointer to buffer that can hold conversion result * @return the number of written char; 0 if conversion is not possible */ simdutf_warn_unused virtual size_t convert_latin1_to_utf8(const char * input, size_t length, char* utf8_output) const noexcept = 0; - - /** + /** * Convert possibly Latin1 string into UTF-16LE string. * * This function is suitable to work with inputs from untrusted sources. @@ -2739,10 +2807,13 @@ class implementation { */ simdutf_warn_unused virtual result convert_utf8_to_latin1_with_errors(const char * input, size_t length, char* latin1_output) const noexcept = 0; - /** + /** * Convert valid UTF-8 string into latin1 string. * - * This function assumes that the input string is valid UTF-8. + * This function assumes that the input string is valid UTF-8 and that it can be represented as Latin1. + * If you violate this assumption, the result is implementation defined and may include system-dependent behavior such as crashes. + * + * This function is for expert users only and not part of our public API. Use convert_utf8_to_latin1 instead. * * This function is not BOM-aware. * @@ -2871,7 +2942,8 @@ class implementation { /** * Compute the number of 2-byte code units that this UTF-8 string would require in UTF-16LE format. * - * This function does not validate the input. + * This function does not validate the input. It is acceptable to pass invalid UTF-8 strings but in such cases + * the result is implementation defined. * * @param input the UTF-8 string to process * @param length the length of the string in bytes @@ -2882,7 +2954,8 @@ class implementation { /** * Compute the number of 4-byte code units that this UTF-8 string would require in UTF-32 format. * - * This function is equivalent to count_utf8. + * This function is equivalent to count_utf8. It is acceptable to pass invalid UTF-8 strings but in such cases + * the result is implementation defined. * * This function does not validate the input. * @@ -2957,8 +3030,11 @@ class implementation { /** * Convert valid UTF-16LE string into Latin1 string. * - * This function assumes that the input string is valid UTF-8. - + * This function assumes that the input string is valid UTF-L16LE and that it can be represented as Latin1. + * If you violate this assumption, the result is implementation defined and may include system-dependent behavior such as crashes. + * + * This function is for expert users only and not part of our public API. Use convert_utf16le_to_latin1 instead. + * * This function is not BOM-aware. * * @param input the UTF-16LE string to convert @@ -2971,7 +3047,10 @@ class implementation { /** * Convert valid UTF-16BE string into Latin1 string. * - * This function assumes that the input string is valid UTF-8. + * This function assumes that the input string is valid UTF16-BE and that it can be represented as Latin1. + * If you violate this assumption, the result is implementation defined and may include system-dependent behavior such as crashes. + * + * This function is for expert users only and not part of our public API. Use convert_utf16be_to_latin1 instead. * * This function is not BOM-aware. * @@ -3161,7 +3240,8 @@ class implementation { /** * Compute the number of bytes that this UTF-16LE string would require in UTF-8 format. * - * This function does not validate the input. + * This function does not validate the input. It is acceptable to pass invalid UTF-16 strings but in such cases + * the result is implementation defined. * * This function is not BOM-aware. * @@ -3174,7 +3254,8 @@ class implementation { /** * Compute the number of bytes that this UTF-16BE string would require in UTF-8 format. * - * This function does not validate the input. + * This function does not validate the input. It is acceptable to pass invalid UTF-16 strings but in such cases + * the result is implementation defined. * * This function is not BOM-aware. * @@ -3219,7 +3300,10 @@ class implementation { /** * Convert valid UTF-32 string into Latin1 string. * - * This function assumes that the input string is valid UTF-32. + * This function assumes that the input string is valid UTF-32 and can be represented as Latin1. + * If you violate this assumption, the result is implementation defined and may include system-dependent behavior such as crashes. + * + * This function is for expert users only and not part of our public API. Use convert_utf32_to_latin1 instead. * * This function is not BOM-aware. * @@ -3275,7 +3359,7 @@ class implementation { simdutf_warn_unused virtual size_t convert_valid_utf32_to_utf8(const char32_t * input, size_t length, char* utf8_buffer) const noexcept = 0; - /** + /** * Return the number of bytes that this UTF-16 string would require in Latin1 format. * * @@ -3399,7 +3483,8 @@ class implementation { /** * Compute the number of bytes that this UTF-32 string would require in UTF-8 format. * - * This function does not validate the input. + * This function does not validate the input. It is acceptable to pass invalid UTF-32 strings but in such cases + * the result is implementation defined. * * @param input the UTF-32 string to convert * @param length the length of the string in 4-byte code units (char32_t) @@ -3410,7 +3495,8 @@ class implementation { /** * Compute the number of bytes that this UTF-32 string would require in Latin1 format. * - * This function does not validate the input. + * This function does not validate the input. It is acceptable to pass invalid UTF-32 strings but in such cases + * the result is implementation defined. * * @param length the length of the string in 4-byte code units (char32_t) * @return the number of bytes required to encode the UTF-32 string as Latin1 @@ -3420,7 +3506,8 @@ class implementation { /** * Compute the number of bytes that this UTF-8 string would require in Latin1 format. * - * This function does not validate the input. + * This function does not validate the input. It is acceptable to pass invalid UTF-8 strings but in such cases + * the result is implementation defined. * * @param input the UTF-8 string to convert * @param length the length of the string in byte @@ -3431,7 +3518,8 @@ class implementation { /* * Compute the number of bytes that this UTF-16LE/BE string would require in Latin1 format. * - * This function does not validate the input. + * This function does not validate the input. It is acceptable to pass invalid UTF-16 strings but in such cases + * the result is implementation defined. * * This function is not BOM-aware. * @@ -3444,7 +3532,8 @@ class implementation { /** * Compute the number of two-byte code units that this UTF-32 string would require in UTF-16 format. * - * This function does not validate the input. + * This function does not validate the input. It is acceptable to pass invalid UTF-32 strings but in such cases + * the result is implementation defined. * * @param input the UTF-32 string to convert * @param length the length of the string in 4-byte code units (char32_t) @@ -3453,11 +3542,9 @@ class implementation { simdutf_warn_unused virtual size_t utf16_length_from_utf32(const char32_t * input, size_t length) const noexcept = 0; - /** + /** * Return the number of bytes that this UTF-32 string would require in Latin1 format. * - * This function does not validate the input. - * * @param input the UTF-32 string to convert * @param length the length of the string in 4-byte code units (char32_t) * @return the number of bytes required to encode the UTF-32 string as Latin1 @@ -3469,7 +3556,8 @@ class implementation { * * This function is equivalent to count_utf16le. * - * This function does not validate the input. + * This function does not validate the input. It is acceptable to pass invalid UTF-16 strings but in such cases + * the result is implementation defined. * * This function is not BOM-aware. * @@ -3484,7 +3572,8 @@ class implementation { * * This function is equivalent to count_utf16be. * - * This function does not validate the input. + * This function does not validate the input. It is acceptable to pass invalid UTF-16 strings but in such cases + * the result is implementation defined. * * This function is not BOM-aware. * @@ -3499,6 +3588,8 @@ class implementation { * it is valid. * * This function assumes that the input string is valid UTF-16LE. + * It is acceptable to pass invalid UTF-16 strings but in such cases + * the result is implementation defined. * * This function is not BOM-aware. * @@ -3513,6 +3604,8 @@ class implementation { * it is valid. * * This function assumes that the input string is valid UTF-16BE. + * It is acceptable to pass invalid UTF-16 strings but in such cases + * the result is implementation defined. * * This function is not BOM-aware. * @@ -3528,6 +3621,8 @@ class implementation { * it is valid. * * This function assumes that the input string is valid UTF-8. + * It is acceptable to pass invalid UTF-8 strings but in such cases + * the result is implementation defined. * * @param input the UTF-8 string to process * @param length the length of the string in bytes @@ -3538,7 +3633,8 @@ class implementation { /** * Provide the maximal binary length in bytes given the base64 input. * In general, if the input contains ASCII spaces, the result will be less than - * the maximum length. + * the maximum length. It is acceptable to pass invalid base64 strings but in such cases + * the result is implementation defined. * * @param input the base64 input to process * @param length the length of the base64 input in bytes @@ -3549,7 +3645,8 @@ class implementation { /** * Provide the maximal binary length in bytes given the base64 input. * In general, if the input contains ASCII spaces, the result will be less than - * the maximum length. + * the maximum length. It is acceptable to pass invalid base64 strings but in such cases + * the result is implementation defined. * * @param input the base64 input to process, in ASCII stored as 16-bit units * @param length the length of the base64 input in 16-bit units @@ -3558,7 +3655,7 @@ class implementation { simdutf_warn_unused virtual size_t maximal_binary_length_from_base64(const char16_t * input, size_t length) const noexcept = 0; /** - * Convert a base64 input to a binary ouput. + * Convert a base64 input to a binary output. * * This function follows the WHATWG forgiving-base64 format, which means that it will * ignore any ASCII spaces in the input. You may provide a padded input (with one or two @@ -3583,7 +3680,7 @@ class implementation { simdutf_warn_unused virtual result base64_to_binary(const char * input, size_t length, char* output, base64_options options = base64_default) const noexcept = 0; /** - * Convert a base64 input to a binary ouput. + * Convert a base64 input to a binary output. * * This function follows the WHATWG forgiving-base64 format, which means that it will * ignore any ASCII spaces in the input. You may provide a padded input (with one or two @@ -3617,7 +3714,7 @@ class implementation { simdutf_warn_unused virtual size_t base64_length_from_binary(size_t length, base64_options options = base64_default) const noexcept = 0; /** - * Convert a binary input to a base64 ouput. + * Convert a binary input to a base64 output. * * The default option (simdutf::base64_default) uses the characters `+` and `/` as part of its alphabet. * Further, it adds padding (`=`) at the end of the output to ensure that the output length is a multiple of four. diff --git a/deps/undici/src/.c8rc.json b/deps/undici/src/.c8rc.json new file mode 100644 index 00000000000..11549ad3fac --- /dev/null +++ b/deps/undici/src/.c8rc.json @@ -0,0 +1,13 @@ +{ + "all": true, + "reporter": [ + "lcov", + "text", + "html", + "text-summary" + ], + "include": [ + "lib/**/*.js", + "index.js" + ] +} diff --git a/deps/undici/src/.dockerignore b/deps/undici/src/.dockerignore new file mode 100644 index 00000000000..4ad0cf5a2e4 --- /dev/null +++ b/deps/undici/src/.dockerignore @@ -0,0 +1,8 @@ +# Ignore everything but the stuff following the `*` with the `!` +# See https://docs.docker.com/engine/reference/builder/#dockerignore-file + +* +!package.json +!lib +!deps +!build diff --git a/deps/undici/src/.editorconfig b/deps/undici/src/.editorconfig new file mode 100644 index 00000000000..c7a0d1f6afa --- /dev/null +++ b/deps/undici/src/.editorconfig @@ -0,0 +1,9 @@ +# https://editorconfig.org/ + +root = true + +[*] +indent_size = 2 +indent_style = space +insert_final_newline = true +trim_trailing_whitespace = true diff --git a/deps/undici/src/.gitignore b/deps/undici/src/.gitignore new file mode 100644 index 00000000000..60aa663c838 --- /dev/null +++ b/deps/undici/src/.gitignore @@ -0,0 +1,86 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# TypeScript v1 declaration files +typings/ + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variables file +.env + +# next.js build output +.next + +# lock files +package-lock.json +yarn.lock + +# IDE files +.idea +.vscode + +*0x +*clinic* + +# Fuzzing +corpus/ +crash-* +fuzz-results-*.json + +# Bundle output +undici-fetch.js +/test/imports/undici-import.js + +# .npmrc has platform specific value for windows +.npmrc + +.tap diff --git a/deps/undici/src/.npmignore b/deps/undici/src/.npmignore new file mode 100644 index 00000000000..879c6669f03 --- /dev/null +++ b/deps/undici/src/.npmignore @@ -0,0 +1,13 @@ +* +!lib/**/* +!index.js +!index-fetch.js + +# The wasm files are stored as base64 strings in the corresponding .js files +lib/llhttp/llhttp_simd.wasm +lib/llhttp/llhttp.wasm + +!types/**/* +!index.d.ts +!docs/docs/**/* +!scripts/strip-comments.js diff --git a/deps/undici/src/CODE_OF_CONDUCT.md b/deps/undici/src/CODE_OF_CONDUCT.md new file mode 100644 index 00000000000..cb674bc46b0 --- /dev/null +++ b/deps/undici/src/CODE_OF_CONDUCT.md @@ -0,0 +1,6 @@ +# Code of Conduct + +Undici is committed to upholding the Node.js Code of Conduct. + +The Node.js Code of Conduct document can be found at +https://github.com/nodejs/admin/blob/main/CODE_OF_CONDUCT.md diff --git a/deps/undici/src/CONTRIBUTING.md b/deps/undici/src/CONTRIBUTING.md new file mode 100644 index 00000000000..68c9b977f1a --- /dev/null +++ b/deps/undici/src/CONTRIBUTING.md @@ -0,0 +1,214 @@ +# Contributing to Undici + +* [Guides](#guides) + * [Update `llhttp`](#update-llhttp) + * [Lint](#lint) + * [Test](#test) + * [Coverage](#coverage) + * [Releases](#releases) + * [Update `WPTs`](#update-wpts) + * [Building for externally shared node builtins](#external-builds) + * [Benchmarks](#benchmarks + * [Documentation](#documentation) +* [Developer's Certificate of Origin 1.1](#developers-certificate-of-origin) + * [Moderation Policy](#moderation-policy) + + +## Guides + +This is a collection of guides on how to run and update `undici`, and how to run different parts of the project. + + +### Update `llhttp` + +The HTTP parser used by `undici` is a WebAssembly build of [`llhttp`](https://github.com/nodejs/llhttp). + +While the project itself provides a way to compile targeting WebAssembly, at the moment we embed the sources +directly and compile the module in `undici`. + +The `deps/llhttp/include` folder contains the C header files, while the `deps/llhttp/src` folder contains +the C source files needed to compile the module. + +The `lib/llhttp` folder contains the `.js` transpiled assets required to implement a parser. + +The following are the steps required to perform an update. + +#### Clone the [llhttp](https://github.com/nodejs/llhttp) project + +```bash +git clone git@github.com:nodejs/llhttp.git + +cd llhttp +``` + +#### Checkout a `llhttp` release + +```bash +git checkout +``` + +#### Install the `llhttp` dependencies + +```bash +npm i +``` + +#### Run the wasm build script + +> This requires [docker](https://www.docker.com/) installed on your machine. + +```bash +npm run build-wasm +``` + +#### Copy the sources to `undici` + +```bash +cp build/wasm/*.js /lib/llhttp/ + +cp build/wasm/*.js.map /lib/llhttp/ + +cp build/wasm/*.d.ts /lib/llhttp/ + +cp src/native/api.c src/native/http.c build/c/llhttp.c /deps/llhttp/src/ + +cp src/native/api.h build/llhttp.h /deps/llhttp/include/ +``` + +#### Build the WebAssembly module in `undici` + +> This requires [docker](https://www.docker.com/) installed on your machine. + +```bash +cd + +npm run build:wasm +``` + +#### Commit the contents of lib/llhttp + +Create a commit which includes all of the updated files in lib/llhttp. + + +### Update `WPTs` + +`undici` runs a subset of the [`web-platform-tests`](https://github.com/web-platform-tests/wpt). + +### Requirements: +- [Node core utils](https://github.com/nodejs/node-core-utils) setup with credentials. + +To update every test, run the following commands. Typically you would only need to update the tests in a specific directory. + +```bash +git node wpt resources +git node wpt interfaces +git node wpt common +git node wpt fetch +git node wpt FileAPI +git node wpt xhr +git node wpt websockets +git node wpt mimesniff +git node wpt storage +git node wpt service-workers +git node wpt eventsource +``` + +#### Run the tests + +Run the tests to ensure that any new failures are marked as such. + +You can mark tests as failing in their corresponding [status](./test/wpt/status) file. + +```bash +npm run test:wpt +``` + + +### Lint + +```bash +npm run lint +``` + + +### Test + +```bash +npm run test +``` + + +### Coverage + +```bash +npm run coverage +``` + + +### Issuing Releases + +Release is automatic on commit to main which bumps the package.json version field. +Use the "Create release PR" github action to generate a release PR. + + +### Building for externally shared node builtins + +If you are packaging `undici` for a distro, this might help if you would like to use +an unbundled version instead of bundling one in `libnode.so`. + +To enable this, pass `EXTERNAL_PATH=/path/to/global/node_modules/undici` to `build/wasm.js`. +Pass this path with `loader.js` appended to `--shared-builtin-undici/undici-path` in Node.js's `configure.py`. +If building on a non-Alpine Linux distribution, you may need to also set the `WASM_CC`, `WASM_CFLAGS`, `WASM_LDFLAGS` and `WASM_LDLIBS` environment variables before running `build/wasm.js`. +Similarly, you can set the `WASM_OPT` environment variable to utilize your own `wasm-opt` optimizer. + + +### Benchmarks + +```bash +cd benchmarks && npm i && npm run bench +``` + +The benchmarks will be available at `http://localhost:3042`. + + +### Documentation + +```bash +cd docs && npm i && npm run serve +``` + +The documentation will be available at `http://localhost:3000`. + + +## Developer's Certificate of Origin 1.1 + +By making a contribution to this project, I certify that: + +* (a) The contribution was created in whole or in part by me and I + have the right to submit it under the open source license + indicated in the file; or + +* (b) The contribution is based upon previous work that, to the best + of my knowledge, is covered under an appropriate open source + license and I have the right under that license to submit that + work with modifications, whether created in whole or in part + by me, under the same open source license (unless I am + permitted to submit under a different license), as indicated + in the file; or + +* (c) The contribution was provided directly to me by some other + person who certified (a), (b) or (c) and I have not modified + it. + +* (d) I understand and agree that this project and the contribution + are public and that a record of the contribution (including all + personal information I submit with it, including my sign-off) is + maintained indefinitely and may be redistributed consistent with + this project or the open source license(s) involved. + + +### Moderation Policy + +The [Node.js Moderation Policy] applies to this project. + +[Node.js Moderation Policy]: https://github.com/nodejs/admin/blob/main/Moderation-Policy.md diff --git a/deps/undici/src/GOVERNANCE.md b/deps/undici/src/GOVERNANCE.md new file mode 100644 index 00000000000..3e88d4bb139 --- /dev/null +++ b/deps/undici/src/GOVERNANCE.md @@ -0,0 +1,136 @@ +### Undici Working Group + +The Node.js Undici project is governed by a Working Group (WG) +that is responsible for high-level guidance of the project. + +The WG has final authority over this project including: + +* Technical direction +* Project governance and process (including this policy) +* Contribution policy +* GitHub repository hosting +* Conduct guidelines +* Maintaining the list of additional Collaborators + +For the current list of WG members, see the project +[README.md](./README.md#collaborators). + +### Collaborators + +The undici GitHub repository is +maintained by the WG and additional Collaborators who are added by the +WG on an ongoing basis. + +Individuals making significant and valuable contributions are made +Collaborators and given commit-access to the project. These +individuals are identified by the WG and their addition as +Collaborators is discussed during the WG meeting. + +_Note:_ If you make a significant contribution and are not considered +for commit-access log an issue or contact a WG member directly and it +will be brought up in the next WG meeting. + +Modifications of the contents of the undici repository are +made on +a collaborative basis. Anybody with a GitHub account may propose a +modification via pull request and it will be considered by the project +Collaborators. All pull requests must be reviewed and accepted by a +Collaborator with sufficient expertise who is able to take full +responsibility for the change. In the case of pull requests proposed +by an existing Collaborator, an additional Collaborator is required +for sign-off. Consensus should be sought if additional Collaborators +participate and there is disagreement around a particular +modification. See _Consensus Seeking Process_ below for further detail +on the consensus model used for governance. + +Collaborators may opt to elevate significant or controversial +modifications, or modifications that have not found consensus to the +WG for discussion by assigning the ***WG-agenda*** tag to a pull +request or issue. The WG should serve as the final arbiter where +required. + +For the current list of Collaborators, see the project +[README.md](./README.md#collaborators). The list shall be in an +alphabetical order. + +### WG Membership + +WG seats are not time-limited. There is no fixed size of the WG. +However, the expected target is between 6 and 12, to ensure adequate +coverage of important areas of expertise, balanced with the ability to +make decisions efficiently. + +There is no specific set of requirements or qualifications for WG +membership beyond these rules. + +The WG may add additional members to the WG by unanimous consensus. + +A WG member may be removed from the WG by voluntary resignation, or by +unanimous consensus of all other WG members. + +Changes to WG membership should be posted in the agenda, and may be +suggested as any other agenda item (see "WG Meetings" below). + +If an addition or removal is proposed during a meeting, and the full +WG is not in attendance to participate, then the addition or removal +is added to the agenda for the subsequent meeting. This is to ensure +that all members are given the opportunity to participate in all +membership decisions. If a WG member is unable to attend a meeting +where a planned membership decision is being made, then their consent +is assumed. + +No more than 1/3 of the WG members may be affiliated with the same +employer. If removal or resignation of a WG member, or a change of +employment by a WG member, creates a situation where more than 1/3 of +the WG membership shares an employer, then the situation must be +immediately remedied by the resignation or removal of one or more WG +members affiliated with the over-represented employer(s). + +### WG Meetings + +The WG meets occasionally on Zoom. A designated moderator +approved by the WG runs the meeting. Each meeting should be +published to YouTube. + +Items are added to the WG agenda that are considered contentious or +are modifications of governance, contribution policy, WG membership, +or release process. + +The intention of the agenda is not to approve or review all patches; +that should happen continuously on GitHub and be handled by the larger +group of Collaborators. + +Any community member or contributor can ask that something be added to +the next meeting's agenda by logging a GitHub Issue. Any Collaborator, +WG member or the moderator can add the item to the agenda by adding +the ***WG-agenda*** tag to the issue. + +Prior to each WG meeting the moderator will share the Agenda with +members of the WG. WG members can add any items they like to the +agenda at the beginning of each meeting. The moderator and the WG +cannot veto or remove items. + +The WG may invite persons or representatives from certain projects to +participate in a non-voting capacity. + +The moderator is responsible for summarizing the discussion of each +agenda item and sends it as a pull request after the meeting. + +### Consensus Seeking Process + +The WG follows a +[Consensus +Seeking](http://en.wikipedia.org/wiki/Consensus-seeking_decision-making) +decision-making model. + +When an agenda item has appeared to reach a consensus the moderator +will ask "Does anyone object?" as a final call for dissent from the +consensus. + +If an agenda item cannot reach a consensus a WG member can call for +either a closing vote or a vote to table the issue to the next +meeting. The call for a vote must be seconded by a majority of the WG +or else the discussion will continue. Simple majority wins. + +Note that changes to WG membership require a majority consensus. See +"WG Membership" above. diff --git a/deps/undici/src/MAINTAINERS.md b/deps/undici/src/MAINTAINERS.md new file mode 100644 index 00000000000..b98d904e911 --- /dev/null +++ b/deps/undici/src/MAINTAINERS.md @@ -0,0 +1,33 @@ +# Maintainers + +This document details any and all processes relevant to project maintainers. Maintainers should feel empowered to contribute back to this document with any process changes they feel improve the overall experience for themselves and other maintainers. + +## Labels + +Maintainers are encouraged to use the extensive and detailed list of labels for easier repo management. + +* Generally, all issues should be labelled. The most general labels are `bug`, `enhancement`, and `Status: help-wanted`. +* Issues specific to a certain aspect of the project should be labeled using one of the specificity labels listed below. For example, a bug in the `Client` class should have the `Client` and `bug` label assigned. + * Specificity labels: + * `Agent` + * `Client` + * `Docs` + * `Performance` + * `Pool` + * `Tests` + * `Types` +* Any `question` or `usage help` issues should be converted into Q&A Discussions +* `Status:` labels should be added to all open issues indicating their relative development status. + * Status labels: + * `Status: blocked` + * `Status: help-wanted` + * `Status: in-progress` + * `Status: wontfix` +* Issues and/or pull requests with an agreed upon semver status can be assigned the appropriate `semver-` label. + * Semver labels: + * `semver-major` + * `semver-minor` + * `semver-patch` +* Issues with a low-barrier of entry should be assigned the `good first issue` label. +* Do not use the `invalid` label, instead use `bug` or `Status: wontfix`. +* Duplicate issues should initially be assigned the `duplicate` label. diff --git a/deps/undici/src/SECURITY.md b/deps/undici/src/SECURITY.md new file mode 100644 index 00000000000..dc5499ae10b --- /dev/null +++ b/deps/undici/src/SECURITY.md @@ -0,0 +1,2 @@ +If you believe you have found a security issue in the software in this +repository, please consult https://github.com/nodejs/node/blob/HEAD/SECURITY.md. diff --git a/deps/undici/src/build/Dockerfile b/deps/undici/src/build/Dockerfile new file mode 100644 index 00000000000..8bcab469b60 --- /dev/null +++ b/deps/undici/src/build/Dockerfile @@ -0,0 +1,25 @@ +FROM node:22-alpine3.19@sha256:075a5cc188c3c9a49acacd481a9e8a3c9abf4223f02c658e37fdb8e9fe2c4664 + +ARG UID=1000 +ARG GID=1000 +ARG BINARYEN_VERSION=116 + +RUN apk add -U clang lld wasi-sdk +RUN mkdir /home/node/undici + +WORKDIR /home/node/undici + +RUN wget https://github.com/WebAssembly/binaryen/releases/download/version_$BINARYEN_VERSION/binaryen-version_$BINARYEN_VERSION-x86_64-linux.tar.gz && \ + tar -zxvf binaryen-version_$BINARYEN_VERSION-x86_64-linux.tar.gz binaryen-version_$BINARYEN_VERSION/bin/wasm-opt && \ + mv binaryen-version_$BINARYEN_VERSION/bin/wasm-opt ./ && \ + rm binaryen-version_$BINARYEN_VERSION-x86_64-linux.tar.gz && \ + rm -rf binaryen-version_$BINARYEN_VERSION && \ + chmod +x ./wasm-opt + +COPY package.json . + +COPY build build +COPY deps deps +COPY lib lib + +USER node diff --git a/deps/undici/src/build/wasm.js b/deps/undici/src/build/wasm.js new file mode 100644 index 00000000000..1880ce3dfe4 --- /dev/null +++ b/deps/undici/src/build/wasm.js @@ -0,0 +1,125 @@ +'use strict' + +const { execSync } = require('node:child_process') +const { writeFileSync, readFileSync } = require('node:fs') +const { join, resolve } = require('node:path') + +const ROOT = resolve(__dirname, '../') +const WASM_SRC = resolve(__dirname, '../deps/llhttp') +const WASM_OUT = resolve(__dirname, '../lib/llhttp') +const DOCKERFILE = resolve(__dirname, './Dockerfile') + +// These are defined by build environment +const WASM_CC = process.env.WASM_CC || 'clang' +let WASM_CFLAGS = process.env.WASM_CFLAGS || '--sysroot=/usr/share/wasi-sysroot -target wasm32-unknown-wasi' +let WASM_LDFLAGS = process.env.WASM_LDFLAGS || '' +const WASM_LDLIBS = process.env.WASM_LDLIBS || '' +const WASM_OPT = process.env.WASM_OPT || './wasm-opt' + +// For compatibility with Node.js' `configure --shared-builtin-undici/undici-path ...` +const EXTERNAL_PATH = process.env.EXTERNAL_PATH + +// These are relevant for undici and should not be overridden +WASM_CFLAGS += ' -Ofast -fno-exceptions -fvisibility=hidden -mexec-model=reactor' +WASM_LDFLAGS += ' -Wl,-error-limit=0 -Wl,-O3 -Wl,--lto-O3 -Wl,--strip-all' +WASM_LDFLAGS += ' -Wl,--allow-undefined -Wl,--export-dynamic -Wl,--export-table' +WASM_LDFLAGS += ' -Wl,--export=malloc -Wl,--export=free -Wl,--no-entry' + +const WASM_OPT_FLAGS = '-O4 --converge --strip-debug --strip-dwarf --strip-producers' + +const writeWasmChunk = (path, dest) => { + const base64 = readFileSync(join(WASM_OUT, path)).toString('base64') + writeFileSync(join(WASM_OUT, dest), `'use strict' + +const { Buffer } = require('node:buffer') + +module.exports = Buffer.from('${base64}', 'base64') +`) +} + +let platform = process.env.WASM_PLATFORM +if (!platform && process.argv[2]) { + platform = execSync('docker info -f "{{.OSType}}/{{.Architecture}}"').toString().trim() +} + +if (process.argv[2] === '--rm') { + const cmd = 'docker image rm llhttp_wasm_builder' + + console.log(`> ${cmd}\n\n`) + try { + execSync(cmd, { stdio: 'inherit' }) + } catch (e) {} + + process.exit(0) +} + +if (process.argv[2] === '--prebuild') { + const cmd = `docker build --platform=${platform.toString().trim()} -t llhttp_wasm_builder -f ${DOCKERFILE} ${ROOT}` + + console.log(`> ${cmd}\n\n`) + execSync(cmd, { stdio: 'inherit' }) + + process.exit(0) +} + +if (process.argv[2] === '--docker') { + let cmd = `docker run --rm -t --platform=${platform.toString().trim()}` + if (process.platform === 'linux') { + cmd += ` --user ${process.getuid()}:${process.getegid()}` + } + + cmd += ` --mount type=bind,source=${ROOT}/lib/llhttp,target=/home/node/undici/lib/llhttp llhttp_wasm_builder node build/wasm.js` + console.log(`> ${cmd}\n\n`) + execSync(cmd, { stdio: 'inherit' }) + process.exit(0) +} + +const hasApk = (function () { + try { execSync('command -v apk'); return true } catch (error) { return false } +})() +const hasOptimizer = (function () { + try { execSync(`${WASM_OPT} --version`); return true } catch (error) { return false } +})() +if (hasApk) { + // Gather information about the tools used for the build + const buildInfo = execSync('apk info -v').toString() + if (!buildInfo.includes('wasi-sdk')) { + console.log('Failed to generate build environment information') + process.exit(-1) + } + console.log(buildInfo) +} + +// Build wasm binary +execSync(`${WASM_CC} ${WASM_CFLAGS} ${WASM_LDFLAGS} \ +${join(WASM_SRC, 'src')}/*.c \ +-I${join(WASM_SRC, 'include')} \ +-o ${join(WASM_OUT, 'llhttp.wasm')} \ +${WASM_LDLIBS}`, { stdio: 'inherit' }) + +if (hasOptimizer) { + execSync(`${WASM_OPT} ${WASM_OPT_FLAGS} -o ${join(WASM_OUT, 'llhttp.wasm')} ${join(WASM_OUT, 'llhttp.wasm')}`, { stdio: 'inherit' }) +} +writeWasmChunk('llhttp.wasm', 'llhttp-wasm.js') + +// Build wasm simd binary +execSync(`${WASM_CC} ${WASM_CFLAGS} -msimd128 ${WASM_LDFLAGS} \ +${join(WASM_SRC, 'src')}/*.c \ +-I${join(WASM_SRC, 'include')} \ +-o ${join(WASM_OUT, 'llhttp_simd.wasm')} \ +${WASM_LDLIBS}`, { stdio: 'inherit' }) + +if (hasOptimizer) { + execSync(`${WASM_OPT} ${WASM_OPT_FLAGS} --enable-simd -o ${join(WASM_OUT, 'llhttp_simd.wasm')} ${join(WASM_OUT, 'llhttp_simd.wasm')}`, { stdio: 'inherit' }) +} +writeWasmChunk('llhttp_simd.wasm', 'llhttp_simd-wasm.js') + +// For compatibility with Node.js' `configure --shared-builtin-undici/undici-path ...` +if (EXTERNAL_PATH) { + writeFileSync(join(ROOT, 'loader.js'), ` +'use strict' +globalThis.__UNDICI_IS_NODE__ = true +module.exports = require('node:module').createRequire('${EXTERNAL_PATH}/loader.js')('./index-fetch.js') +delete globalThis.__UNDICI_IS_NODE__ +`) +} diff --git a/deps/undici/src/deps/llhttp/include/llhttp.h b/deps/undici/src/deps/llhttp/include/llhttp.h new file mode 100644 index 00000000000..88ef85df0d7 --- /dev/null +++ b/deps/undici/src/deps/llhttp/include/llhttp.h @@ -0,0 +1,815 @@ +#ifndef INCLUDE_LLHTTP_H_ +#define INCLUDE_LLHTTP_H_ + +#define LLHTTP_VERSION_MAJOR 8 +#define LLHTTP_VERSION_MINOR 1 +#define LLHTTP_VERSION_PATCH 0 + +#ifndef LLHTTP_STRICT_MODE +# define LLHTTP_STRICT_MODE 0 +#endif + +#ifndef INCLUDE_LLHTTP_ITSELF_H_ +#define INCLUDE_LLHTTP_ITSELF_H_ +#ifdef __cplusplus +extern "C" { +#endif + +#include + +typedef struct llhttp__internal_s llhttp__internal_t; +struct llhttp__internal_s { + int32_t _index; + void* _span_pos0; + void* _span_cb0; + int32_t error; + const char* reason; + const char* error_pos; + void* data; + void* _current; + uint64_t content_length; + uint8_t type; + uint8_t method; + uint8_t http_major; + uint8_t http_minor; + uint8_t header_state; + uint8_t lenient_flags; + uint8_t upgrade; + uint8_t finish; + uint16_t flags; + uint16_t status_code; + uint8_t initial_message_completed; + void* settings; +}; + +int llhttp__internal_init(llhttp__internal_t* s); +int llhttp__internal_execute(llhttp__internal_t* s, const char* p, const char* endp); + +#ifdef __cplusplus +} /* extern "C" */ +#endif +#endif /* INCLUDE_LLHTTP_ITSELF_H_ */ + +#ifndef LLLLHTTP_C_HEADERS_ +#define LLLLHTTP_C_HEADERS_ +#ifdef __cplusplus +extern "C" { +#endif + +enum llhttp_errno { + HPE_OK = 0, + HPE_INTERNAL = 1, + HPE_STRICT = 2, + HPE_CR_EXPECTED = 25, + HPE_LF_EXPECTED = 3, + HPE_UNEXPECTED_CONTENT_LENGTH = 4, + HPE_UNEXPECTED_SPACE = 30, + HPE_CLOSED_CONNECTION = 5, + HPE_INVALID_METHOD = 6, + HPE_INVALID_URL = 7, + HPE_INVALID_CONSTANT = 8, + HPE_INVALID_VERSION = 9, + HPE_INVALID_HEADER_TOKEN = 10, + HPE_INVALID_CONTENT_LENGTH = 11, + HPE_INVALID_CHUNK_SIZE = 12, + HPE_INVALID_STATUS = 13, + HPE_INVALID_EOF_STATE = 14, + HPE_INVALID_TRANSFER_ENCODING = 15, + HPE_CB_MESSAGE_BEGIN = 16, + HPE_CB_HEADERS_COMPLETE = 17, + HPE_CB_MESSAGE_COMPLETE = 18, + HPE_CB_CHUNK_HEADER = 19, + HPE_CB_CHUNK_COMPLETE = 20, + HPE_PAUSED = 21, + HPE_PAUSED_UPGRADE = 22, + HPE_PAUSED_H2_UPGRADE = 23, + HPE_USER = 24, + HPE_CB_URL_COMPLETE = 26, + HPE_CB_STATUS_COMPLETE = 27, + HPE_CB_METHOD_COMPLETE = 32, + HPE_CB_VERSION_COMPLETE = 33, + HPE_CB_HEADER_FIELD_COMPLETE = 28, + HPE_CB_HEADER_VALUE_COMPLETE = 29, + HPE_CB_CHUNK_EXTENSION_NAME_COMPLETE = 34, + HPE_CB_CHUNK_EXTENSION_VALUE_COMPLETE = 35, + HPE_CB_RESET = 31 +}; +typedef enum llhttp_errno llhttp_errno_t; + +enum llhttp_flags { + F_CONNECTION_KEEP_ALIVE = 0x1, + F_CONNECTION_CLOSE = 0x2, + F_CONNECTION_UPGRADE = 0x4, + F_CHUNKED = 0x8, + F_UPGRADE = 0x10, + F_CONTENT_LENGTH = 0x20, + F_SKIPBODY = 0x40, + F_TRAILING = 0x80, + F_TRANSFER_ENCODING = 0x200 +}; +typedef enum llhttp_flags llhttp_flags_t; + +enum llhttp_lenient_flags { + LENIENT_HEADERS = 0x1, + LENIENT_CHUNKED_LENGTH = 0x2, + LENIENT_KEEP_ALIVE = 0x4, + LENIENT_TRANSFER_ENCODING = 0x8, + LENIENT_VERSION = 0x10 +}; +typedef enum llhttp_lenient_flags llhttp_lenient_flags_t; + +enum llhttp_type { + HTTP_BOTH = 0, + HTTP_REQUEST = 1, + HTTP_RESPONSE = 2 +}; +typedef enum llhttp_type llhttp_type_t; + +enum llhttp_finish { + HTTP_FINISH_SAFE = 0, + HTTP_FINISH_SAFE_WITH_CB = 1, + HTTP_FINISH_UNSAFE = 2 +}; +typedef enum llhttp_finish llhttp_finish_t; + +enum llhttp_method { + HTTP_DELETE = 0, + HTTP_GET = 1, + HTTP_HEAD = 2, + HTTP_POST = 3, + HTTP_PUT = 4, + HTTP_CONNECT = 5, + HTTP_OPTIONS = 6, + HTTP_TRACE = 7, + HTTP_COPY = 8, + HTTP_LOCK = 9, + HTTP_MKCOL = 10, + HTTP_MOVE = 11, + HTTP_PROPFIND = 12, + HTTP_PROPPATCH = 13, + HTTP_SEARCH = 14, + HTTP_UNLOCK = 15, + HTTP_BIND = 16, + HTTP_REBIND = 17, + HTTP_UNBIND = 18, + HTTP_ACL = 19, + HTTP_REPORT = 20, + HTTP_MKACTIVITY = 21, + HTTP_CHECKOUT = 22, + HTTP_MERGE = 23, + HTTP_MSEARCH = 24, + HTTP_NOTIFY = 25, + HTTP_SUBSCRIBE = 26, + HTTP_UNSUBSCRIBE = 27, + HTTP_PATCH = 28, + HTTP_PURGE = 29, + HTTP_MKCALENDAR = 30, + HTTP_LINK = 31, + HTTP_UNLINK = 32, + HTTP_SOURCE = 33, + HTTP_PRI = 34, + HTTP_DESCRIBE = 35, + HTTP_ANNOUNCE = 36, + HTTP_SETUP = 37, + HTTP_PLAY = 38, + HTTP_PAUSE = 39, + HTTP_TEARDOWN = 40, + HTTP_GET_PARAMETER = 41, + HTTP_SET_PARAMETER = 42, + HTTP_REDIRECT = 43, + HTTP_RECORD = 44, + HTTP_FLUSH = 45 +}; +typedef enum llhttp_method llhttp_method_t; + +enum llhttp_status { + HTTP_STATUS_CONTINUE = 100, + HTTP_STATUS_SWITCHING_PROTOCOLS = 101, + HTTP_STATUS_PROCESSING = 102, + HTTP_STATUS_EARLY_HINTS = 103, + HTTP_STATUS_RESPONSE_IS_STALE = 110, + HTTP_STATUS_REVALIDATION_FAILED = 111, + HTTP_STATUS_DISCONNECTED_OPERATION = 112, + HTTP_STATUS_HEURISTIC_EXPIRATION = 113, + HTTP_STATUS_MISCELLANEOUS_WARNING = 199, + HTTP_STATUS_OK = 200, + HTTP_STATUS_CREATED = 201, + HTTP_STATUS_ACCEPTED = 202, + HTTP_STATUS_NON_AUTHORITATIVE_INFORMATION = 203, + HTTP_STATUS_NO_CONTENT = 204, + HTTP_STATUS_RESET_CONTENT = 205, + HTTP_STATUS_PARTIAL_CONTENT = 206, + HTTP_STATUS_MULTI_STATUS = 207, + HTTP_STATUS_ALREADY_REPORTED = 208, + HTTP_STATUS_TRANSFORMATION_APPLIED = 214, + HTTP_STATUS_IM_USED = 226, + HTTP_STATUS_MISCELLANEOUS_PERSISTENT_WARNING = 299, + HTTP_STATUS_MULTIPLE_CHOICES = 300, + HTTP_STATUS_MOVED_PERMANENTLY = 301, + HTTP_STATUS_FOUND = 302, + HTTP_STATUS_SEE_OTHER = 303, + HTTP_STATUS_NOT_MODIFIED = 304, + HTTP_STATUS_USE_PROXY = 305, + HTTP_STATUS_SWITCH_PROXY = 306, + HTTP_STATUS_TEMPORARY_REDIRECT = 307, + HTTP_STATUS_PERMANENT_REDIRECT = 308, + HTTP_STATUS_BAD_REQUEST = 400, + HTTP_STATUS_UNAUTHORIZED = 401, + HTTP_STATUS_PAYMENT_REQUIRED = 402, + HTTP_STATUS_FORBIDDEN = 403, + HTTP_STATUS_NOT_FOUND = 404, + HTTP_STATUS_METHOD_NOT_ALLOWED = 405, + HTTP_STATUS_NOT_ACCEPTABLE = 406, + HTTP_STATUS_PROXY_AUTHENTICATION_REQUIRED = 407, + HTTP_STATUS_REQUEST_TIMEOUT = 408, + HTTP_STATUS_CONFLICT = 409, + HTTP_STATUS_GONE = 410, + HTTP_STATUS_LENGTH_REQUIRED = 411, + HTTP_STATUS_PRECONDITION_FAILED = 412, + HTTP_STATUS_PAYLOAD_TOO_LARGE = 413, + HTTP_STATUS_URI_TOO_LONG = 414, + HTTP_STATUS_UNSUPPORTED_MEDIA_TYPE = 415, + HTTP_STATUS_RANGE_NOT_SATISFIABLE = 416, + HTTP_STATUS_EXPECTATION_FAILED = 417, + HTTP_STATUS_IM_A_TEAPOT = 418, + HTTP_STATUS_PAGE_EXPIRED = 419, + HTTP_STATUS_ENHANCE_YOUR_CALM = 420, + HTTP_STATUS_MISDIRECTED_REQUEST = 421, + HTTP_STATUS_UNPROCESSABLE_ENTITY = 422, + HTTP_STATUS_LOCKED = 423, + HTTP_STATUS_FAILED_DEPENDENCY = 424, + HTTP_STATUS_TOO_EARLY = 425, + HTTP_STATUS_UPGRADE_REQUIRED = 426, + HTTP_STATUS_PRECONDITION_REQUIRED = 428, + HTTP_STATUS_TOO_MANY_REQUESTS = 429, + HTTP_STATUS_REQUEST_HEADER_FIELDS_TOO_LARGE_UNOFFICIAL = 430, + HTTP_STATUS_REQUEST_HEADER_FIELDS_TOO_LARGE = 431, + HTTP_STATUS_LOGIN_TIMEOUT = 440, + HTTP_STATUS_NO_RESPONSE = 444, + HTTP_STATUS_RETRY_WITH = 449, + HTTP_STATUS_BLOCKED_BY_PARENTAL_CONTROL = 450, + HTTP_STATUS_UNAVAILABLE_FOR_LEGAL_REASONS = 451, + HTTP_STATUS_CLIENT_CLOSED_LOAD_BALANCED_REQUEST = 460, + HTTP_STATUS_INVALID_X_FORWARDED_FOR = 463, + HTTP_STATUS_REQUEST_HEADER_TOO_LARGE = 494, + HTTP_STATUS_SSL_CERTIFICATE_ERROR = 495, + HTTP_STATUS_SSL_CERTIFICATE_REQUIRED = 496, + HTTP_STATUS_HTTP_REQUEST_SENT_TO_HTTPS_PORT = 497, + HTTP_STATUS_INVALID_TOKEN = 498, + HTTP_STATUS_CLIENT_CLOSED_REQUEST = 499, + HTTP_STATUS_INTERNAL_SERVER_ERROR = 500, + HTTP_STATUS_NOT_IMPLEMENTED = 501, + HTTP_STATUS_BAD_GATEWAY = 502, + HTTP_STATUS_SERVICE_UNAVAILABLE = 503, + HTTP_STATUS_GATEWAY_TIMEOUT = 504, + HTTP_STATUS_HTTP_VERSION_NOT_SUPPORTED = 505, + HTTP_STATUS_VARIANT_ALSO_NEGOTIATES = 506, + HTTP_STATUS_INSUFFICIENT_STORAGE = 507, + HTTP_STATUS_LOOP_DETECTED = 508, + HTTP_STATUS_BANDWIDTH_LIMIT_EXCEEDED = 509, + HTTP_STATUS_NOT_EXTENDED = 510, + HTTP_STATUS_NETWORK_AUTHENTICATION_REQUIRED = 511, + HTTP_STATUS_WEB_SERVER_UNKNOWN_ERROR = 520, + HTTP_STATUS_WEB_SERVER_IS_DOWN = 521, + HTTP_STATUS_CONNECTION_TIMEOUT = 522, + HTTP_STATUS_ORIGIN_IS_UNREACHABLE = 523, + HTTP_STATUS_TIMEOUT_OCCURED = 524, + HTTP_STATUS_SSL_HANDSHAKE_FAILED = 525, + HTTP_STATUS_INVALID_SSL_CERTIFICATE = 526, + HTTP_STATUS_RAILGUN_ERROR = 527, + HTTP_STATUS_SITE_IS_OVERLOADED = 529, + HTTP_STATUS_SITE_IS_FROZEN = 530, + HTTP_STATUS_IDENTITY_PROVIDER_AUTHENTICATION_ERROR = 561, + HTTP_STATUS_NETWORK_READ_TIMEOUT = 598, + HTTP_STATUS_NETWORK_CONNECT_TIMEOUT = 599 +}; +typedef enum llhttp_status llhttp_status_t; + +#define HTTP_ERRNO_MAP(XX) \ + XX(0, OK, OK) \ + XX(1, INTERNAL, INTERNAL) \ + XX(2, STRICT, STRICT) \ + XX(25, CR_EXPECTED, CR_EXPECTED) \ + XX(3, LF_EXPECTED, LF_EXPECTED) \ + XX(4, UNEXPECTED_CONTENT_LENGTH, UNEXPECTED_CONTENT_LENGTH) \ + XX(30, UNEXPECTED_SPACE, UNEXPECTED_SPACE) \ + XX(5, CLOSED_CONNECTION, CLOSED_CONNECTION) \ + XX(6, INVALID_METHOD, INVALID_METHOD) \ + XX(7, INVALID_URL, INVALID_URL) \ + XX(8, INVALID_CONSTANT, INVALID_CONSTANT) \ + XX(9, INVALID_VERSION, INVALID_VERSION) \ + XX(10, INVALID_HEADER_TOKEN, INVALID_HEADER_TOKEN) \ + XX(11, INVALID_CONTENT_LENGTH, INVALID_CONTENT_LENGTH) \ + XX(12, INVALID_CHUNK_SIZE, INVALID_CHUNK_SIZE) \ + XX(13, INVALID_STATUS, INVALID_STATUS) \ + XX(14, INVALID_EOF_STATE, INVALID_EOF_STATE) \ + XX(15, INVALID_TRANSFER_ENCODING, INVALID_TRANSFER_ENCODING) \ + XX(16, CB_MESSAGE_BEGIN, CB_MESSAGE_BEGIN) \ + XX(17, CB_HEADERS_COMPLETE, CB_HEADERS_COMPLETE) \ + XX(18, CB_MESSAGE_COMPLETE, CB_MESSAGE_COMPLETE) \ + XX(19, CB_CHUNK_HEADER, CB_CHUNK_HEADER) \ + XX(20, CB_CHUNK_COMPLETE, CB_CHUNK_COMPLETE) \ + XX(21, PAUSED, PAUSED) \ + XX(22, PAUSED_UPGRADE, PAUSED_UPGRADE) \ + XX(23, PAUSED_H2_UPGRADE, PAUSED_H2_UPGRADE) \ + XX(24, USER, USER) \ + XX(26, CB_URL_COMPLETE, CB_URL_COMPLETE) \ + XX(27, CB_STATUS_COMPLETE, CB_STATUS_COMPLETE) \ + XX(32, CB_METHOD_COMPLETE, CB_METHOD_COMPLETE) \ + XX(33, CB_VERSION_COMPLETE, CB_VERSION_COMPLETE) \ + XX(28, CB_HEADER_FIELD_COMPLETE, CB_HEADER_FIELD_COMPLETE) \ + XX(29, CB_HEADER_VALUE_COMPLETE, CB_HEADER_VALUE_COMPLETE) \ + XX(34, CB_CHUNK_EXTENSION_NAME_COMPLETE, CB_CHUNK_EXTENSION_NAME_COMPLETE) \ + XX(35, CB_CHUNK_EXTENSION_VALUE_COMPLETE, CB_CHUNK_EXTENSION_VALUE_COMPLETE) \ + XX(31, CB_RESET, CB_RESET) \ + + +#define HTTP_METHOD_MAP(XX) \ + XX(0, DELETE, DELETE) \ + XX(1, GET, GET) \ + XX(2, HEAD, HEAD) \ + XX(3, POST, POST) \ + XX(4, PUT, PUT) \ + XX(5, CONNECT, CONNECT) \ + XX(6, OPTIONS, OPTIONS) \ + XX(7, TRACE, TRACE) \ + XX(8, COPY, COPY) \ + XX(9, LOCK, LOCK) \ + XX(10, MKCOL, MKCOL) \ + XX(11, MOVE, MOVE) \ + XX(12, PROPFIND, PROPFIND) \ + XX(13, PROPPATCH, PROPPATCH) \ + XX(14, SEARCH, SEARCH) \ + XX(15, UNLOCK, UNLOCK) \ + XX(16, BIND, BIND) \ + XX(17, REBIND, REBIND) \ + XX(18, UNBIND, UNBIND) \ + XX(19, ACL, ACL) \ + XX(20, REPORT, REPORT) \ + XX(21, MKACTIVITY, MKACTIVITY) \ + XX(22, CHECKOUT, CHECKOUT) \ + XX(23, MERGE, MERGE) \ + XX(24, MSEARCH, M-SEARCH) \ + XX(25, NOTIFY, NOTIFY) \ + XX(26, SUBSCRIBE, SUBSCRIBE) \ + XX(27, UNSUBSCRIBE, UNSUBSCRIBE) \ + XX(28, PATCH, PATCH) \ + XX(29, PURGE, PURGE) \ + XX(30, MKCALENDAR, MKCALENDAR) \ + XX(31, LINK, LINK) \ + XX(32, UNLINK, UNLINK) \ + XX(33, SOURCE, SOURCE) \ + + +#define RTSP_METHOD_MAP(XX) \ + XX(1, GET, GET) \ + XX(3, POST, POST) \ + XX(6, OPTIONS, OPTIONS) \ + XX(35, DESCRIBE, DESCRIBE) \ + XX(36, ANNOUNCE, ANNOUNCE) \ + XX(37, SETUP, SETUP) \ + XX(38, PLAY, PLAY) \ + XX(39, PAUSE, PAUSE) \ + XX(40, TEARDOWN, TEARDOWN) \ + XX(41, GET_PARAMETER, GET_PARAMETER) \ + XX(42, SET_PARAMETER, SET_PARAMETER) \ + XX(43, REDIRECT, REDIRECT) \ + XX(44, RECORD, RECORD) \ + XX(45, FLUSH, FLUSH) \ + + +#define HTTP_ALL_METHOD_MAP(XX) \ + XX(0, DELETE, DELETE) \ + XX(1, GET, GET) \ + XX(2, HEAD, HEAD) \ + XX(3, POST, POST) \ + XX(4, PUT, PUT) \ + XX(5, CONNECT, CONNECT) \ + XX(6, OPTIONS, OPTIONS) \ + XX(7, TRACE, TRACE) \ + XX(8, COPY, COPY) \ + XX(9, LOCK, LOCK) \ + XX(10, MKCOL, MKCOL) \ + XX(11, MOVE, MOVE) \ + XX(12, PROPFIND, PROPFIND) \ + XX(13, PROPPATCH, PROPPATCH) \ + XX(14, SEARCH, SEARCH) \ + XX(15, UNLOCK, UNLOCK) \ + XX(16, BIND, BIND) \ + XX(17, REBIND, REBIND) \ + XX(18, UNBIND, UNBIND) \ + XX(19, ACL, ACL) \ + XX(20, REPORT, REPORT) \ + XX(21, MKACTIVITY, MKACTIVITY) \ + XX(22, CHECKOUT, CHECKOUT) \ + XX(23, MERGE, MERGE) \ + XX(24, MSEARCH, M-SEARCH) \ + XX(25, NOTIFY, NOTIFY) \ + XX(26, SUBSCRIBE, SUBSCRIBE) \ + XX(27, UNSUBSCRIBE, UNSUBSCRIBE) \ + XX(28, PATCH, PATCH) \ + XX(29, PURGE, PURGE) \ + XX(30, MKCALENDAR, MKCALENDAR) \ + XX(31, LINK, LINK) \ + XX(32, UNLINK, UNLINK) \ + XX(33, SOURCE, SOURCE) \ + XX(34, PRI, PRI) \ + XX(35, DESCRIBE, DESCRIBE) \ + XX(36, ANNOUNCE, ANNOUNCE) \ + XX(37, SETUP, SETUP) \ + XX(38, PLAY, PLAY) \ + XX(39, PAUSE, PAUSE) \ + XX(40, TEARDOWN, TEARDOWN) \ + XX(41, GET_PARAMETER, GET_PARAMETER) \ + XX(42, SET_PARAMETER, SET_PARAMETER) \ + XX(43, REDIRECT, REDIRECT) \ + XX(44, RECORD, RECORD) \ + XX(45, FLUSH, FLUSH) \ + + +#define HTTP_STATUS_MAP(XX) \ + XX(100, CONTINUE, CONTINUE) \ + XX(101, SWITCHING_PROTOCOLS, SWITCHING_PROTOCOLS) \ + XX(102, PROCESSING, PROCESSING) \ + XX(103, EARLY_HINTS, EARLY_HINTS) \ + XX(110, RESPONSE_IS_STALE, RESPONSE_IS_STALE) \ + XX(111, REVALIDATION_FAILED, REVALIDATION_FAILED) \ + XX(112, DISCONNECTED_OPERATION, DISCONNECTED_OPERATION) \ + XX(113, HEURISTIC_EXPIRATION, HEURISTIC_EXPIRATION) \ + XX(199, MISCELLANEOUS_WARNING, MISCELLANEOUS_WARNING) \ + XX(200, OK, OK) \ + XX(201, CREATED, CREATED) \ + XX(202, ACCEPTED, ACCEPTED) \ + XX(203, NON_AUTHORITATIVE_INFORMATION, NON_AUTHORITATIVE_INFORMATION) \ + XX(204, NO_CONTENT, NO_CONTENT) \ + XX(205, RESET_CONTENT, RESET_CONTENT) \ + XX(206, PARTIAL_CONTENT, PARTIAL_CONTENT) \ + XX(207, MULTI_STATUS, MULTI_STATUS) \ + XX(208, ALREADY_REPORTED, ALREADY_REPORTED) \ + XX(214, TRANSFORMATION_APPLIED, TRANSFORMATION_APPLIED) \ + XX(226, IM_USED, IM_USED) \ + XX(299, MISCELLANEOUS_PERSISTENT_WARNING, MISCELLANEOUS_PERSISTENT_WARNING) \ + XX(300, MULTIPLE_CHOICES, MULTIPLE_CHOICES) \ + XX(301, MOVED_PERMANENTLY, MOVED_PERMANENTLY) \ + XX(302, FOUND, FOUND) \ + XX(303, SEE_OTHER, SEE_OTHER) \ + XX(304, NOT_MODIFIED, NOT_MODIFIED) \ + XX(305, USE_PROXY, USE_PROXY) \ + XX(306, SWITCH_PROXY, SWITCH_PROXY) \ + XX(307, TEMPORARY_REDIRECT, TEMPORARY_REDIRECT) \ + XX(308, PERMANENT_REDIRECT, PERMANENT_REDIRECT) \ + XX(400, BAD_REQUEST, BAD_REQUEST) \ + XX(401, UNAUTHORIZED, UNAUTHORIZED) \ + XX(402, PAYMENT_REQUIRED, PAYMENT_REQUIRED) \ + XX(403, FORBIDDEN, FORBIDDEN) \ + XX(404, NOT_FOUND, NOT_FOUND) \ + XX(405, METHOD_NOT_ALLOWED, METHOD_NOT_ALLOWED) \ + XX(406, NOT_ACCEPTABLE, NOT_ACCEPTABLE) \ + XX(407, PROXY_AUTHENTICATION_REQUIRED, PROXY_AUTHENTICATION_REQUIRED) \ + XX(408, REQUEST_TIMEOUT, REQUEST_TIMEOUT) \ + XX(409, CONFLICT, CONFLICT) \ + XX(410, GONE, GONE) \ + XX(411, LENGTH_REQUIRED, LENGTH_REQUIRED) \ + XX(412, PRECONDITION_FAILED, PRECONDITION_FAILED) \ + XX(413, PAYLOAD_TOO_LARGE, PAYLOAD_TOO_LARGE) \ + XX(414, URI_TOO_LONG, URI_TOO_LONG) \ + XX(415, UNSUPPORTED_MEDIA_TYPE, UNSUPPORTED_MEDIA_TYPE) \ + XX(416, RANGE_NOT_SATISFIABLE, RANGE_NOT_SATISFIABLE) \ + XX(417, EXPECTATION_FAILED, EXPECTATION_FAILED) \ + XX(418, IM_A_TEAPOT, IM_A_TEAPOT) \ + XX(419, PAGE_EXPIRED, PAGE_EXPIRED) \ + XX(420, ENHANCE_YOUR_CALM, ENHANCE_YOUR_CALM) \ + XX(421, MISDIRECTED_REQUEST, MISDIRECTED_REQUEST) \ + XX(422, UNPROCESSABLE_ENTITY, UNPROCESSABLE_ENTITY) \ + XX(423, LOCKED, LOCKED) \ + XX(424, FAILED_DEPENDENCY, FAILED_DEPENDENCY) \ + XX(425, TOO_EARLY, TOO_EARLY) \ + XX(426, UPGRADE_REQUIRED, UPGRADE_REQUIRED) \ + XX(428, PRECONDITION_REQUIRED, PRECONDITION_REQUIRED) \ + XX(429, TOO_MANY_REQUESTS, TOO_MANY_REQUESTS) \ + XX(430, REQUEST_HEADER_FIELDS_TOO_LARGE_UNOFFICIAL, REQUEST_HEADER_FIELDS_TOO_LARGE_UNOFFICIAL) \ + XX(431, REQUEST_HEADER_FIELDS_TOO_LARGE, REQUEST_HEADER_FIELDS_TOO_LARGE) \ + XX(440, LOGIN_TIMEOUT, LOGIN_TIMEOUT) \ + XX(444, NO_RESPONSE, NO_RESPONSE) \ + XX(449, RETRY_WITH, RETRY_WITH) \ + XX(450, BLOCKED_BY_PARENTAL_CONTROL, BLOCKED_BY_PARENTAL_CONTROL) \ + XX(451, UNAVAILABLE_FOR_LEGAL_REASONS, UNAVAILABLE_FOR_LEGAL_REASONS) \ + XX(460, CLIENT_CLOSED_LOAD_BALANCED_REQUEST, CLIENT_CLOSED_LOAD_BALANCED_REQUEST) \ + XX(463, INVALID_X_FORWARDED_FOR, INVALID_X_FORWARDED_FOR) \ + XX(494, REQUEST_HEADER_TOO_LARGE, REQUEST_HEADER_TOO_LARGE) \ + XX(495, SSL_CERTIFICATE_ERROR, SSL_CERTIFICATE_ERROR) \ + XX(496, SSL_CERTIFICATE_REQUIRED, SSL_CERTIFICATE_REQUIRED) \ + XX(497, HTTP_REQUEST_SENT_TO_HTTPS_PORT, HTTP_REQUEST_SENT_TO_HTTPS_PORT) \ + XX(498, INVALID_TOKEN, INVALID_TOKEN) \ + XX(499, CLIENT_CLOSED_REQUEST, CLIENT_CLOSED_REQUEST) \ + XX(500, INTERNAL_SERVER_ERROR, INTERNAL_SERVER_ERROR) \ + XX(501, NOT_IMPLEMENTED, NOT_IMPLEMENTED) \ + XX(502, BAD_GATEWAY, BAD_GATEWAY) \ + XX(503, SERVICE_UNAVAILABLE, SERVICE_UNAVAILABLE) \ + XX(504, GATEWAY_TIMEOUT, GATEWAY_TIMEOUT) \ + XX(505, HTTP_VERSION_NOT_SUPPORTED, HTTP_VERSION_NOT_SUPPORTED) \ + XX(506, VARIANT_ALSO_NEGOTIATES, VARIANT_ALSO_NEGOTIATES) \ + XX(507, INSUFFICIENT_STORAGE, INSUFFICIENT_STORAGE) \ + XX(508, LOOP_DETECTED, LOOP_DETECTED) \ + XX(509, BANDWIDTH_LIMIT_EXCEEDED, BANDWIDTH_LIMIT_EXCEEDED) \ + XX(510, NOT_EXTENDED, NOT_EXTENDED) \ + XX(511, NETWORK_AUTHENTICATION_REQUIRED, NETWORK_AUTHENTICATION_REQUIRED) \ + XX(520, WEB_SERVER_UNKNOWN_ERROR, WEB_SERVER_UNKNOWN_ERROR) \ + XX(521, WEB_SERVER_IS_DOWN, WEB_SERVER_IS_DOWN) \ + XX(522, CONNECTION_TIMEOUT, CONNECTION_TIMEOUT) \ + XX(523, ORIGIN_IS_UNREACHABLE, ORIGIN_IS_UNREACHABLE) \ + XX(524, TIMEOUT_OCCURED, TIMEOUT_OCCURED) \ + XX(525, SSL_HANDSHAKE_FAILED, SSL_HANDSHAKE_FAILED) \ + XX(526, INVALID_SSL_CERTIFICATE, INVALID_SSL_CERTIFICATE) \ + XX(527, RAILGUN_ERROR, RAILGUN_ERROR) \ + XX(529, SITE_IS_OVERLOADED, SITE_IS_OVERLOADED) \ + XX(530, SITE_IS_FROZEN, SITE_IS_FROZEN) \ + XX(561, IDENTITY_PROVIDER_AUTHENTICATION_ERROR, IDENTITY_PROVIDER_AUTHENTICATION_ERROR) \ + XX(598, NETWORK_READ_TIMEOUT, NETWORK_READ_TIMEOUT) \ + XX(599, NETWORK_CONNECT_TIMEOUT, NETWORK_CONNECT_TIMEOUT) \ + + +#ifdef __cplusplus +} /* extern "C" */ +#endif +#endif /* LLLLHTTP_C_HEADERS_ */ + +#ifndef INCLUDE_LLHTTP_API_H_ +#define INCLUDE_LLHTTP_API_H_ +#ifdef __cplusplus +extern "C" { +#endif +#include + +#if defined(__wasm__) +#define LLHTTP_EXPORT __attribute__((visibility("default"))) +#else +#define LLHTTP_EXPORT +#endif + +typedef llhttp__internal_t llhttp_t; +typedef struct llhttp_settings_s llhttp_settings_t; + +typedef int (*llhttp_data_cb)(llhttp_t*, const char *at, size_t length); +typedef int (*llhttp_cb)(llhttp_t*); + +struct llhttp_settings_s { + /* Possible return values 0, -1, `HPE_PAUSED` */ + llhttp_cb on_message_begin; + + /* Possible return values 0, -1, HPE_USER */ + llhttp_data_cb on_url; + llhttp_data_cb on_status; + llhttp_data_cb on_method; + llhttp_data_cb on_version; + llhttp_data_cb on_header_field; + llhttp_data_cb on_header_value; + llhttp_data_cb on_chunk_extension_name; + llhttp_data_cb on_chunk_extension_value; + + /* Possible return values: + * 0 - Proceed normally + * 1 - Assume that request/response has no body, and proceed to parsing the + * next message + * 2 - Assume absence of body (as above) and make `llhttp_execute()` return + * `HPE_PAUSED_UPGRADE` + * -1 - Error + * `HPE_PAUSED` + */ + llhttp_cb on_headers_complete; + + /* Possible return values 0, -1, HPE_USER */ + llhttp_data_cb on_body; + + /* Possible return values 0, -1, `HPE_PAUSED` */ + llhttp_cb on_message_complete; + llhttp_cb on_url_complete; + llhttp_cb on_status_complete; + llhttp_cb on_method_complete; + llhttp_cb on_version_complete; + llhttp_cb on_header_field_complete; + llhttp_cb on_header_value_complete; + llhttp_cb on_chunk_extension_name_complete; + llhttp_cb on_chunk_extension_value_complete; + + /* When on_chunk_header is called, the current chunk length is stored + * in parser->content_length. + * Possible return values 0, -1, `HPE_PAUSED` + */ + llhttp_cb on_chunk_header; + llhttp_cb on_chunk_complete; + llhttp_cb on_reset; +}; + +/* Initialize the parser with specific type and user settings. + * + * NOTE: lifetime of `settings` has to be at least the same as the lifetime of + * the `parser` here. In practice, `settings` has to be either a static + * variable or be allocated with `malloc`, `new`, etc. + */ +LLHTTP_EXPORT +void llhttp_init(llhttp_t* parser, llhttp_type_t type, + const llhttp_settings_t* settings); + +LLHTTP_EXPORT +llhttp_t* llhttp_alloc(llhttp_type_t type); + +LLHTTP_EXPORT +void llhttp_free(llhttp_t* parser); + +LLHTTP_EXPORT +uint8_t llhttp_get_type(llhttp_t* parser); + +LLHTTP_EXPORT +uint8_t llhttp_get_http_major(llhttp_t* parser); + +LLHTTP_EXPORT +uint8_t llhttp_get_http_minor(llhttp_t* parser); + +LLHTTP_EXPORT +uint8_t llhttp_get_method(llhttp_t* parser); + +LLHTTP_EXPORT +int llhttp_get_status_code(llhttp_t* parser); + +LLHTTP_EXPORT +uint8_t llhttp_get_upgrade(llhttp_t* parser); + +/* Reset an already initialized parser back to the start state, preserving the + * existing parser type, callback settings, user data, and lenient flags. + */ +LLHTTP_EXPORT +void llhttp_reset(llhttp_t* parser); + +/* Initialize the settings object */ +LLHTTP_EXPORT +void llhttp_settings_init(llhttp_settings_t* settings); + +/* Parse full or partial request/response, invoking user callbacks along the + * way. + * + * If any of `llhttp_data_cb` returns errno not equal to `HPE_OK` - the parsing + * interrupts, and such errno is returned from `llhttp_execute()`. If + * `HPE_PAUSED` was used as a errno, the execution can be resumed with + * `llhttp_resume()` call. + * + * In a special case of CONNECT/Upgrade request/response `HPE_PAUSED_UPGRADE` + * is returned after fully parsing the request/response. If the user wishes to + * continue parsing, they need to invoke `llhttp_resume_after_upgrade()`. + * + * NOTE: if this function ever returns a non-pause type error, it will continue + * to return the same error upon each successive call up until `llhttp_init()` + * is called. + */ +LLHTTP_EXPORT +llhttp_errno_t llhttp_execute(llhttp_t* parser, const char* data, size_t len); + +/* This method should be called when the other side has no further bytes to + * send (e.g. shutdown of readable side of the TCP connection.) + * + * Requests without `Content-Length` and other messages might require treating + * all incoming bytes as the part of the body, up to the last byte of the + * connection. This method will invoke `on_message_complete()` callback if the + * request was terminated safely. Otherwise a error code would be returned. + */ +LLHTTP_EXPORT +llhttp_errno_t llhttp_finish(llhttp_t* parser); + +/* Returns `1` if the incoming message is parsed until the last byte, and has + * to be completed by calling `llhttp_finish()` on EOF + */ +LLHTTP_EXPORT +int llhttp_message_needs_eof(const llhttp_t* parser); + +/* Returns `1` if there might be any other messages following the last that was + * successfully parsed. + */ +LLHTTP_EXPORT +int llhttp_should_keep_alive(const llhttp_t* parser); + +/* Make further calls of `llhttp_execute()` return `HPE_PAUSED` and set + * appropriate error reason. + * + * Important: do not call this from user callbacks! User callbacks must return + * `HPE_PAUSED` if pausing is required. + */ +LLHTTP_EXPORT +void llhttp_pause(llhttp_t* parser); + +/* Might be called to resume the execution after the pause in user's callback. + * See `llhttp_execute()` above for details. + * + * Call this only if `llhttp_execute()` returns `HPE_PAUSED`. + */ +LLHTTP_EXPORT +void llhttp_resume(llhttp_t* parser); + +/* Might be called to resume the execution after the pause in user's callback. + * See `llhttp_execute()` above for details. + * + * Call this only if `llhttp_execute()` returns `HPE_PAUSED_UPGRADE` + */ +LLHTTP_EXPORT +void llhttp_resume_after_upgrade(llhttp_t* parser); + +/* Returns the latest return error */ +LLHTTP_EXPORT +llhttp_errno_t llhttp_get_errno(const llhttp_t* parser); + +/* Returns the verbal explanation of the latest returned error. + * + * Note: User callback should set error reason when returning the error. See + * `llhttp_set_error_reason()` for details. + */ +LLHTTP_EXPORT +const char* llhttp_get_error_reason(const llhttp_t* parser); + +/* Assign verbal description to the returned error. Must be called in user + * callbacks right before returning the errno. + * + * Note: `HPE_USER` error code might be useful in user callbacks. + */ +LLHTTP_EXPORT +void llhttp_set_error_reason(llhttp_t* parser, const char* reason); + +/* Returns the pointer to the last parsed byte before the returned error. The + * pointer is relative to the `data` argument of `llhttp_execute()`. + * + * Note: this method might be useful for counting the number of parsed bytes. + */ +LLHTTP_EXPORT +const char* llhttp_get_error_pos(const llhttp_t* parser); + +/* Returns textual name of error code */ +LLHTTP_EXPORT +const char* llhttp_errno_name(llhttp_errno_t err); + +/* Returns textual name of HTTP method */ +LLHTTP_EXPORT +const char* llhttp_method_name(llhttp_method_t method); + +/* Returns textual name of HTTP status */ +LLHTTP_EXPORT +const char* llhttp_status_name(llhttp_status_t status); + +/* Enables/disables lenient header value parsing (disabled by default). + * + * Lenient parsing disables header value token checks, extending llhttp's + * protocol support to highly non-compliant clients/server. No + * `HPE_INVALID_HEADER_TOKEN` will be raised for incorrect header values when + * lenient parsing is "on". + * + * **(USE AT YOUR OWN RISK)** + */ +LLHTTP_EXPORT +void llhttp_set_lenient_headers(llhttp_t* parser, int enabled); + + +/* Enables/disables lenient handling of conflicting `Transfer-Encoding` and + * `Content-Length` headers (disabled by default). + * + * Normally `llhttp` would error when `Transfer-Encoding` is present in + * conjunction with `Content-Length`. This error is important to prevent HTTP + * request smuggling, but may be less desirable for small number of cases + * involving legacy servers. + * + * **(USE AT YOUR OWN RISK)** + */ +LLHTTP_EXPORT +void llhttp_set_lenient_chunked_length(llhttp_t* parser, int enabled); + + +/* Enables/disables lenient handling of `Connection: close` and HTTP/1.0 + * requests responses. + * + * Normally `llhttp` would error on (in strict mode) or discard (in loose mode) + * the HTTP request/response after the request/response with `Connection: close` + * and `Content-Length`. This is important to prevent cache poisoning attacks, + * but might interact badly with outdated and insecure clients. With this flag + * the extra request/response will be parsed normally. + * + * **(USE AT YOUR OWN RISK)** + */ +LLHTTP_EXPORT +void llhttp_set_lenient_keep_alive(llhttp_t* parser, int enabled); + +/* Enables/disables lenient handling of `Transfer-Encoding` header. + * + * Normally `llhttp` would error when a `Transfer-Encoding` has `chunked` value + * and another value after it (either in a single header or in multiple + * headers whose value are internally joined using `, `). + * This is mandated by the spec to reliably determine request body size and thus + * avoid request smuggling. + * With this flag the extra value will be parsed normally. + * + * **(USE AT YOUR OWN RISK)** + */ +LLHTTP_EXPORT +void llhttp_set_lenient_transfer_encoding(llhttp_t* parser, int enabled); + +#ifdef __cplusplus +} /* extern "C" */ +#endif +#endif /* INCLUDE_LLHTTP_API_H_ */ + +#endif /* INCLUDE_LLHTTP_H_ */ diff --git a/deps/undici/src/deps/llhttp/src/api.c b/deps/undici/src/deps/llhttp/src/api.c new file mode 100644 index 00000000000..4b687a5d990 --- /dev/null +++ b/deps/undici/src/deps/llhttp/src/api.c @@ -0,0 +1,462 @@ +#include +#include +#include + +#include "llhttp.h" + +#define CALLBACK_MAYBE(PARSER, NAME) \ + do { \ + const llhttp_settings_t* settings; \ + settings = (const llhttp_settings_t*) (PARSER)->settings; \ + if (settings == NULL || settings->NAME == NULL) { \ + err = 0; \ + break; \ + } \ + err = settings->NAME((PARSER)); \ + } while (0) + +#define SPAN_CALLBACK_MAYBE(PARSER, NAME, START, LEN) \ + do { \ + const llhttp_settings_t* settings; \ + settings = (const llhttp_settings_t*) (PARSER)->settings; \ + if (settings == NULL || settings->NAME == NULL) { \ + err = 0; \ + break; \ + } \ + err = settings->NAME((PARSER), (START), (LEN)); \ + if (err == -1) { \ + err = HPE_USER; \ + llhttp_set_error_reason((PARSER), "Span callback error in " #NAME); \ + } \ + } while (0) + +void llhttp_init(llhttp_t* parser, llhttp_type_t type, + const llhttp_settings_t* settings) { + llhttp__internal_init(parser); + + parser->type = type; + parser->settings = (void*) settings; +} + + +#if defined(__wasm__) + +extern int wasm_on_message_begin(llhttp_t * p); +extern int wasm_on_url(llhttp_t* p, const char* at, size_t length); +extern int wasm_on_status(llhttp_t* p, const char* at, size_t length); +extern int wasm_on_header_field(llhttp_t* p, const char* at, size_t length); +extern int wasm_on_header_value(llhttp_t* p, const char* at, size_t length); +extern int wasm_on_headers_complete(llhttp_t * p, int status_code, + uint8_t upgrade, int should_keep_alive); +extern int wasm_on_body(llhttp_t* p, const char* at, size_t length); +extern int wasm_on_message_complete(llhttp_t * p); + +static int wasm_on_headers_complete_wrap(llhttp_t* p) { + return wasm_on_headers_complete(p, p->status_code, p->upgrade, + llhttp_should_keep_alive(p)); +} + +const llhttp_settings_t wasm_settings = { + wasm_on_message_begin, + wasm_on_url, + wasm_on_status, + NULL, + NULL, + wasm_on_header_field, + wasm_on_header_value, + NULL, + NULL, + wasm_on_headers_complete_wrap, + wasm_on_body, + wasm_on_message_complete, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, +}; + + +llhttp_t* llhttp_alloc(llhttp_type_t type) { + llhttp_t* parser = malloc(sizeof(llhttp_t)); + llhttp_init(parser, type, &wasm_settings); + return parser; +} + +void llhttp_free(llhttp_t* parser) { + free(parser); +} + +#endif // defined(__wasm__) + +/* Some getters required to get stuff from the parser */ + +uint8_t llhttp_get_type(llhttp_t* parser) { + return parser->type; +} + +uint8_t llhttp_get_http_major(llhttp_t* parser) { + return parser->http_major; +} + +uint8_t llhttp_get_http_minor(llhttp_t* parser) { + return parser->http_minor; +} + +uint8_t llhttp_get_method(llhttp_t* parser) { + return parser->method; +} + +int llhttp_get_status_code(llhttp_t* parser) { + return parser->status_code; +} + +uint8_t llhttp_get_upgrade(llhttp_t* parser) { + return parser->upgrade; +} + + +void llhttp_reset(llhttp_t* parser) { + llhttp_type_t type = parser->type; + const llhttp_settings_t* settings = parser->settings; + void* data = parser->data; + uint8_t lenient_flags = parser->lenient_flags; + + llhttp__internal_init(parser); + + parser->type = type; + parser->settings = (void*) settings; + parser->data = data; + parser->lenient_flags = lenient_flags; +} + + +llhttp_errno_t llhttp_execute(llhttp_t* parser, const char* data, size_t len) { + return llhttp__internal_execute(parser, data, data + len); +} + + +void llhttp_settings_init(llhttp_settings_t* settings) { + memset(settings, 0, sizeof(*settings)); +} + + +llhttp_errno_t llhttp_finish(llhttp_t* parser) { + int err; + + /* We're in an error state. Don't bother doing anything. */ + if (parser->error != 0) { + return 0; + } + + switch (parser->finish) { + case HTTP_FINISH_SAFE_WITH_CB: + CALLBACK_MAYBE(parser, on_message_complete); + if (err != HPE_OK) return err; + + /* FALLTHROUGH */ + case HTTP_FINISH_SAFE: + return HPE_OK; + case HTTP_FINISH_UNSAFE: + parser->reason = "Invalid EOF state"; + return HPE_INVALID_EOF_STATE; + default: + abort(); + } +} + + +void llhttp_pause(llhttp_t* parser) { + if (parser->error != HPE_OK) { + return; + } + + parser->error = HPE_PAUSED; + parser->reason = "Paused"; +} + + +void llhttp_resume(llhttp_t* parser) { + if (parser->error != HPE_PAUSED) { + return; + } + + parser->error = 0; +} + + +void llhttp_resume_after_upgrade(llhttp_t* parser) { + if (parser->error != HPE_PAUSED_UPGRADE) { + return; + } + + parser->error = 0; +} + + +llhttp_errno_t llhttp_get_errno(const llhttp_t* parser) { + return parser->error; +} + + +const char* llhttp_get_error_reason(const llhttp_t* parser) { + return parser->reason; +} + + +void llhttp_set_error_reason(llhttp_t* parser, const char* reason) { + parser->reason = reason; +} + + +const char* llhttp_get_error_pos(const llhttp_t* parser) { + return parser->error_pos; +} + + +const char* llhttp_errno_name(llhttp_errno_t err) { +#define HTTP_ERRNO_GEN(CODE, NAME, _) case HPE_##NAME: return "HPE_" #NAME; + switch (err) { + HTTP_ERRNO_MAP(HTTP_ERRNO_GEN) + default: abort(); + } +#undef HTTP_ERRNO_GEN +} + + +const char* llhttp_method_name(llhttp_method_t method) { +#define HTTP_METHOD_GEN(NUM, NAME, STRING) case HTTP_##NAME: return #STRING; + switch (method) { + HTTP_ALL_METHOD_MAP(HTTP_METHOD_GEN) + default: abort(); + } +#undef HTTP_METHOD_GEN +} + +const char* llhttp_status_name(llhttp_status_t status) { +#define HTTP_STATUS_GEN(NUM, NAME, STRING) case HTTP_STATUS_##NAME: return #STRING; + switch (status) { + HTTP_STATUS_MAP(HTTP_STATUS_GEN) + default: abort(); + } +#undef HTTP_STATUS_GEN +} + + +void llhttp_set_lenient_headers(llhttp_t* parser, int enabled) { + if (enabled) { + parser->lenient_flags |= LENIENT_HEADERS; + } else { + parser->lenient_flags &= ~LENIENT_HEADERS; + } +} + + +void llhttp_set_lenient_chunked_length(llhttp_t* parser, int enabled) { + if (enabled) { + parser->lenient_flags |= LENIENT_CHUNKED_LENGTH; + } else { + parser->lenient_flags &= ~LENIENT_CHUNKED_LENGTH; + } +} + + +void llhttp_set_lenient_keep_alive(llhttp_t* parser, int enabled) { + if (enabled) { + parser->lenient_flags |= LENIENT_KEEP_ALIVE; + } else { + parser->lenient_flags &= ~LENIENT_KEEP_ALIVE; + } +} + +void llhttp_set_lenient_transfer_encoding(llhttp_t* parser, int enabled) { + if (enabled) { + parser->lenient_flags |= LENIENT_TRANSFER_ENCODING; + } else { + parser->lenient_flags &= ~LENIENT_TRANSFER_ENCODING; + } +} + +/* Callbacks */ + + +int llhttp__on_message_begin(llhttp_t* s, const char* p, const char* endp) { + int err; + CALLBACK_MAYBE(s, on_message_begin); + return err; +} + + +int llhttp__on_url(llhttp_t* s, const char* p, const char* endp) { + int err; + SPAN_CALLBACK_MAYBE(s, on_url, p, endp - p); + return err; +} + + +int llhttp__on_url_complete(llhttp_t* s, const char* p, const char* endp) { + int err; + CALLBACK_MAYBE(s, on_url_complete); + return err; +} + + +int llhttp__on_status(llhttp_t* s, const char* p, const char* endp) { + int err; + SPAN_CALLBACK_MAYBE(s, on_status, p, endp - p); + return err; +} + + +int llhttp__on_status_complete(llhttp_t* s, const char* p, const char* endp) { + int err; + CALLBACK_MAYBE(s, on_status_complete); + return err; +} + + +int llhttp__on_method(llhttp_t* s, const char* p, const char* endp) { + int err; + SPAN_CALLBACK_MAYBE(s, on_method, p, endp - p); + return err; +} + + +int llhttp__on_method_complete(llhttp_t* s, const char* p, const char* endp) { + int err; + CALLBACK_MAYBE(s, on_method_complete); + return err; +} + + +int llhttp__on_version(llhttp_t* s, const char* p, const char* endp) { + int err; + SPAN_CALLBACK_MAYBE(s, on_version, p, endp - p); + return err; +} + + +int llhttp__on_version_complete(llhttp_t* s, const char* p, const char* endp) { + int err; + CALLBACK_MAYBE(s, on_version_complete); + return err; +} + + +int llhttp__on_header_field(llhttp_t* s, const char* p, const char* endp) { + int err; + SPAN_CALLBACK_MAYBE(s, on_header_field, p, endp - p); + return err; +} + + +int llhttp__on_header_field_complete(llhttp_t* s, const char* p, const char* endp) { + int err; + CALLBACK_MAYBE(s, on_header_field_complete); + return err; +} + + +int llhttp__on_header_value(llhttp_t* s, const char* p, const char* endp) { + int err; + SPAN_CALLBACK_MAYBE(s, on_header_value, p, endp - p); + return err; +} + + +int llhttp__on_header_value_complete(llhttp_t* s, const char* p, const char* endp) { + int err; + CALLBACK_MAYBE(s, on_header_value_complete); + return err; +} + + +int llhttp__on_headers_complete(llhttp_t* s, const char* p, const char* endp) { + int err; + CALLBACK_MAYBE(s, on_headers_complete); + return err; +} + + +int llhttp__on_message_complete(llhttp_t* s, const char* p, const char* endp) { + int err; + CALLBACK_MAYBE(s, on_message_complete); + return err; +} + + +int llhttp__on_body(llhttp_t* s, const char* p, const char* endp) { + int err; + SPAN_CALLBACK_MAYBE(s, on_body, p, endp - p); + return err; +} + + +int llhttp__on_chunk_header(llhttp_t* s, const char* p, const char* endp) { + int err; + CALLBACK_MAYBE(s, on_chunk_header); + return err; +} + + +int llhttp__on_chunk_extension_name(llhttp_t* s, const char* p, const char* endp) { + int err; + SPAN_CALLBACK_MAYBE(s, on_chunk_extension_name, p, endp - p); + return err; +} + + +int llhttp__on_chunk_extension_name_complete(llhttp_t* s, const char* p, const char* endp) { + int err; + CALLBACK_MAYBE(s, on_chunk_extension_name_complete); + return err; +} + + +int llhttp__on_chunk_extension_value(llhttp_t* s, const char* p, const char* endp) { + int err; + SPAN_CALLBACK_MAYBE(s, on_chunk_extension_value, p, endp - p); + return err; +} + + +int llhttp__on_chunk_extension_value_complete(llhttp_t* s, const char* p, const char* endp) { + int err; + CALLBACK_MAYBE(s, on_chunk_extension_value_complete); + return err; +} + + +int llhttp__on_chunk_complete(llhttp_t* s, const char* p, const char* endp) { + int err; + CALLBACK_MAYBE(s, on_chunk_complete); + return err; +} + + +int llhttp__on_reset(llhttp_t* s, const char* p, const char* endp) { + int err; + CALLBACK_MAYBE(s, on_reset); + return err; +} + + +/* Private */ + + +void llhttp__debug(llhttp_t* s, const char* p, const char* endp, + const char* msg) { + if (p == endp) { + fprintf(stderr, "p=%p type=%d flags=%02x next=null debug=%s\n", s, s->type, + s->flags, msg); + } else { + fprintf(stderr, "p=%p type=%d flags=%02x next=%02x debug=%s\n", s, + s->type, s->flags, *p, msg); + } +} diff --git a/deps/undici/src/deps/llhttp/src/http.c b/deps/undici/src/deps/llhttp/src/http.c new file mode 100644 index 00000000000..3a66044f5fb --- /dev/null +++ b/deps/undici/src/deps/llhttp/src/http.c @@ -0,0 +1,150 @@ +#include +#ifndef LLHTTP__TEST +# include "llhttp.h" +#else +# define llhttp_t llparse_t +#endif /* */ + +int llhttp_message_needs_eof(const llhttp_t* parser); +int llhttp_should_keep_alive(const llhttp_t* parser); + +int llhttp__before_headers_complete(llhttp_t* parser, const char* p, + const char* endp) { + /* Set this here so that on_headers_complete() callbacks can see it */ + if ((parser->flags & F_UPGRADE) && + (parser->flags & F_CONNECTION_UPGRADE)) { + /* For responses, "Upgrade: foo" and "Connection: upgrade" are + * mandatory only when it is a 101 Switching Protocols response, + * otherwise it is purely informational, to announce support. + */ + parser->upgrade = + (parser->type == HTTP_REQUEST || parser->status_code == 101); + } else { + parser->upgrade = (parser->method == HTTP_CONNECT); + } + return 0; +} + + +/* Return values: + * 0 - No body, `restart`, message_complete + * 1 - CONNECT request, `restart`, message_complete, and pause + * 2 - chunk_size_start + * 3 - body_identity + * 4 - body_identity_eof + * 5 - invalid transfer-encoding for request + */ +int llhttp__after_headers_complete(llhttp_t* parser, const char* p, + const char* endp) { + int hasBody; + + hasBody = parser->flags & F_CHUNKED || parser->content_length > 0; + if (parser->upgrade && (parser->method == HTTP_CONNECT || + (parser->flags & F_SKIPBODY) || !hasBody)) { + /* Exit, the rest of the message is in a different protocol. */ + return 1; + } + + if (parser->flags & F_SKIPBODY) { + return 0; + } else if (parser->flags & F_CHUNKED) { + /* chunked encoding - ignore Content-Length header, prepare for a chunk */ + return 2; + } else if (parser->flags & F_TRANSFER_ENCODING) { + if (parser->type == HTTP_REQUEST && + (parser->lenient_flags & LENIENT_CHUNKED_LENGTH) == 0 && + (parser->lenient_flags & LENIENT_TRANSFER_ENCODING) == 0) { + /* RFC 7230 3.3.3 */ + + /* If a Transfer-Encoding header field + * is present in a request and the chunked transfer coding is not + * the final encoding, the message body length cannot be determined + * reliably; the server MUST respond with the 400 (Bad Request) + * status code and then close the connection. + */ + return 5; + } else { + /* RFC 7230 3.3.3 */ + + /* If a Transfer-Encoding header field is present in a response and + * the chunked transfer coding is not the final encoding, the + * message body length is determined by reading the connection until + * it is closed by the server. + */ + return 4; + } + } else { + if (!(parser->flags & F_CONTENT_LENGTH)) { + if (!llhttp_message_needs_eof(parser)) { + /* Assume content-length 0 - read the next */ + return 0; + } else { + /* Read body until EOF */ + return 4; + } + } else if (parser->content_length == 0) { + /* Content-Length header given but zero: Content-Length: 0\r\n */ + return 0; + } else { + /* Content-Length header given and non-zero */ + return 3; + } + } +} + + +int llhttp__after_message_complete(llhttp_t* parser, const char* p, + const char* endp) { + int should_keep_alive; + + should_keep_alive = llhttp_should_keep_alive(parser); + parser->finish = HTTP_FINISH_SAFE; + parser->flags = 0; + + /* NOTE: this is ignored in loose parsing mode */ + return should_keep_alive; +} + + +int llhttp_message_needs_eof(const llhttp_t* parser) { + if (parser->type == HTTP_REQUEST) { + return 0; + } + + /* See RFC 2616 section 4.4 */ + if (parser->status_code / 100 == 1 || /* 1xx e.g. Continue */ + parser->status_code == 204 || /* No Content */ + parser->status_code == 304 || /* Not Modified */ + (parser->flags & F_SKIPBODY)) { /* response to a HEAD request */ + return 0; + } + + /* RFC 7230 3.3.3, see `llhttp__after_headers_complete` */ + if ((parser->flags & F_TRANSFER_ENCODING) && + (parser->flags & F_CHUNKED) == 0) { + return 1; + } + + if (parser->flags & (F_CHUNKED | F_CONTENT_LENGTH)) { + return 0; + } + + return 1; +} + + +int llhttp_should_keep_alive(const llhttp_t* parser) { + if (parser->http_major > 0 && parser->http_minor > 0) { + /* HTTP/1.1 */ + if (parser->flags & F_CONNECTION_CLOSE) { + return 0; + } + } else { + /* HTTP/1.0 or earlier */ + if (!(parser->flags & F_CONNECTION_KEEP_ALIVE)) { + return 0; + } + } + + return !llhttp_message_needs_eof(parser); +} diff --git a/deps/undici/src/deps/llhttp/src/llhttp.c b/deps/undici/src/deps/llhttp/src/llhttp.c new file mode 100644 index 00000000000..b92bf839ef0 --- /dev/null +++ b/deps/undici/src/deps/llhttp/src/llhttp.c @@ -0,0 +1,18232 @@ +#if LLHTTP_STRICT_MODE + +#include +#include +#include + +#ifdef __SSE4_2__ + #ifdef _MSC_VER + #include + #else /* !_MSC_VER */ + #include + #endif /* _MSC_VER */ +#endif /* __SSE4_2__ */ + +#ifdef _MSC_VER + #define ALIGN(n) _declspec(align(n)) +#else /* !_MSC_VER */ + #define ALIGN(n) __attribute__((aligned(n))) +#endif /* _MSC_VER */ + +#include "llhttp.h" + +typedef int (*llhttp__internal__span_cb)( + llhttp__internal_t*, const char*, const char*); + +static const unsigned char llparse_blob0[] = { + 0xd, 0xa +}; +static const unsigned char llparse_blob1[] = { + 'o', 'n' +}; +static const unsigned char llparse_blob2[] = { + 'e', 'c', 't', 'i', 'o', 'n' +}; +static const unsigned char llparse_blob3[] = { + 'l', 'o', 's', 'e' +}; +static const unsigned char llparse_blob4[] = { + 'e', 'e', 'p', '-', 'a', 'l', 'i', 'v', 'e' +}; +static const unsigned char llparse_blob5[] = { + 'p', 'g', 'r', 'a', 'd', 'e' +}; +static const unsigned char llparse_blob6[] = { + 'c', 'h', 'u', 'n', 'k', 'e', 'd' +}; +#ifdef __SSE4_2__ +static const unsigned char ALIGN(16) llparse_blob7[] = { + 0x9, 0x9, ' ', '~', 0x80, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0 +}; +#endif /* __SSE4_2__ */ +#ifdef __SSE4_2__ +static const unsigned char ALIGN(16) llparse_blob8[] = { + '!', '!', '#', '\'', '*', '+', '-', '.', '0', '9', 'A', + 'Z', '^', 'z', '|', '|' +}; +#endif /* __SSE4_2__ */ +#ifdef __SSE4_2__ +static const unsigned char ALIGN(16) llparse_blob9[] = { + '~', '~', 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0 +}; +#endif /* __SSE4_2__ */ +static const unsigned char llparse_blob10[] = { + 'e', 'n', 't', '-', 'l', 'e', 'n', 'g', 't', 'h' +}; +static const unsigned char llparse_blob11[] = { + 'r', 'o', 'x', 'y', '-', 'c', 'o', 'n', 'n', 'e', 'c', + 't', 'i', 'o', 'n' +}; +static const unsigned char llparse_blob12[] = { + 'r', 'a', 'n', 's', 'f', 'e', 'r', '-', 'e', 'n', 'c', + 'o', 'd', 'i', 'n', 'g' +}; +static const unsigned char llparse_blob13[] = { + 'p', 'g', 'r', 'a', 'd', 'e' +}; +static const unsigned char llparse_blob14[] = { + 'T', 'T', 'P', '/' +}; +static const unsigned char llparse_blob15[] = { + 0xd, 0xa, 0xd, 0xa, 'S', 'M', 0xd, 0xa, 0xd, 0xa +}; +static const unsigned char llparse_blob16[] = { + 'C', 'E', '/' +}; +static const unsigned char llparse_blob17[] = { + 'T', 'S', 'P', '/' +}; +static const unsigned char llparse_blob18[] = { + 'N', 'O', 'U', 'N', 'C', 'E' +}; +static const unsigned char llparse_blob19[] = { + 'I', 'N', 'D' +}; +static const unsigned char llparse_blob20[] = { + 'E', 'C', 'K', 'O', 'U', 'T' +}; +static const unsigned char llparse_blob21[] = { + 'N', 'E', 'C', 'T' +}; +static const unsigned char llparse_blob22[] = { + 'E', 'T', 'E' +}; +static const unsigned char llparse_blob23[] = { + 'C', 'R', 'I', 'B', 'E' +}; +static const unsigned char llparse_blob24[] = { + 'L', 'U', 'S', 'H' +}; +static const unsigned char llparse_blob25[] = { + 'E', 'T' +}; +static const unsigned char llparse_blob26[] = { + 'P', 'A', 'R', 'A', 'M', 'E', 'T', 'E', 'R' +}; +static const unsigned char llparse_blob27[] = { + 'E', 'A', 'D' +}; +static const unsigned char llparse_blob28[] = { + 'N', 'K' +}; +static const unsigned char llparse_blob29[] = { + 'C', 'K' +}; +static const unsigned char llparse_blob30[] = { + 'S', 'E', 'A', 'R', 'C', 'H' +}; +static const unsigned char llparse_blob31[] = { + 'R', 'G', 'E' +}; +static const unsigned char llparse_blob32[] = { + 'C', 'T', 'I', 'V', 'I', 'T', 'Y' +}; +static const unsigned char llparse_blob33[] = { + 'L', 'E', 'N', 'D', 'A', 'R' +}; +static const unsigned char llparse_blob34[] = { + 'V', 'E' +}; +static const unsigned char llparse_blob35[] = { + 'O', 'T', 'I', 'F', 'Y' +}; +static const unsigned char llparse_blob36[] = { + 'P', 'T', 'I', 'O', 'N', 'S' +}; +static const unsigned char llparse_blob37[] = { + 'C', 'H' +}; +static const unsigned char llparse_blob38[] = { + 'S', 'E' +}; +static const unsigned char llparse_blob39[] = { + 'A', 'Y' +}; +static const unsigned char llparse_blob40[] = { + 'S', 'T' +}; +static const unsigned char llparse_blob41[] = { + 'I', 'N', 'D' +}; +static const unsigned char llparse_blob42[] = { + 'A', 'T', 'C', 'H' +}; +static const unsigned char llparse_blob43[] = { + 'G', 'E' +}; +static const unsigned char llparse_blob44[] = { + 'I', 'N', 'D' +}; +static const unsigned char llparse_blob45[] = { + 'O', 'R', 'D' +}; +static const unsigned char llparse_blob46[] = { + 'I', 'R', 'E', 'C', 'T' +}; +static const unsigned char llparse_blob47[] = { + 'O', 'R', 'T' +}; +static const unsigned char llparse_blob48[] = { + 'R', 'C', 'H' +}; +static const unsigned char llparse_blob49[] = { + 'P', 'A', 'R', 'A', 'M', 'E', 'T', 'E', 'R' +}; +static const unsigned char llparse_blob50[] = { + 'U', 'R', 'C', 'E' +}; +static const unsigned char llparse_blob51[] = { + 'B', 'S', 'C', 'R', 'I', 'B', 'E' +}; +static const unsigned char llparse_blob52[] = { + 'A', 'R', 'D', 'O', 'W', 'N' +}; +static const unsigned char llparse_blob53[] = { + 'A', 'C', 'E' +}; +static const unsigned char llparse_blob54[] = { + 'I', 'N', 'D' +}; +static const unsigned char llparse_blob55[] = { + 'N', 'K' +}; +static const unsigned char llparse_blob56[] = { + 'C', 'K' +}; +static const unsigned char llparse_blob57[] = { + 'U', 'B', 'S', 'C', 'R', 'I', 'B', 'E' +}; +static const unsigned char llparse_blob58[] = { + 'H', 'T', 'T', 'P', '/' +}; +static const unsigned char llparse_blob59[] = { + 'A', 'D' +}; +static const unsigned char llparse_blob60[] = { + 'T', 'P', '/' +}; + +enum llparse_match_status_e { + kMatchComplete, + kMatchPause, + kMatchMismatch +}; +typedef enum llparse_match_status_e llparse_match_status_t; + +struct llparse_match_s { + llparse_match_status_t status; + const unsigned char* current; +}; +typedef struct llparse_match_s llparse_match_t; + +static llparse_match_t llparse__match_sequence_id( + llhttp__internal_t* s, const unsigned char* p, + const unsigned char* endp, + const unsigned char* seq, uint32_t seq_len) { + uint32_t index; + llparse_match_t res; + + index = s->_index; + for (; p != endp; p++) { + unsigned char current; + + current = *p; + if (current == seq[index]) { + if (++index == seq_len) { + res.status = kMatchComplete; + goto reset; + } + } else { + res.status = kMatchMismatch; + goto reset; + } + } + s->_index = index; + res.status = kMatchPause; + res.current = p; + return res; +reset: + s->_index = 0; + res.current = p; + return res; +} + +static llparse_match_t llparse__match_sequence_to_lower( + llhttp__internal_t* s, const unsigned char* p, + const unsigned char* endp, + const unsigned char* seq, uint32_t seq_len) { + uint32_t index; + llparse_match_t res; + + index = s->_index; + for (; p != endp; p++) { + unsigned char current; + + current = ((*p) >= 'A' && (*p) <= 'Z' ? (*p | 0x20) : (*p)); + if (current == seq[index]) { + if (++index == seq_len) { + res.status = kMatchComplete; + goto reset; + } + } else { + res.status = kMatchMismatch; + goto reset; + } + } + s->_index = index; + res.status = kMatchPause; + res.current = p; + return res; +reset: + s->_index = 0; + res.current = p; + return res; +} + +static llparse_match_t llparse__match_sequence_to_lower_unsafe( + llhttp__internal_t* s, const unsigned char* p, + const unsigned char* endp, + const unsigned char* seq, uint32_t seq_len) { + uint32_t index; + llparse_match_t res; + + index = s->_index; + for (; p != endp; p++) { + unsigned char current; + + current = ((*p) | 0x20); + if (current == seq[index]) { + if (++index == seq_len) { + res.status = kMatchComplete; + goto reset; + } + } else { + res.status = kMatchMismatch; + goto reset; + } + } + s->_index = index; + res.status = kMatchPause; + res.current = p; + return res; +reset: + s->_index = 0; + res.current = p; + return res; +} + +enum llparse_state_e { + s_error, + s_n_llhttp__internal__n_closed, + s_n_llhttp__internal__n_invoke_llhttp__after_message_complete, + s_n_llhttp__internal__n_pause_1, + s_n_llhttp__internal__n_invoke_is_equal_upgrade, + s_n_llhttp__internal__n_invoke_llhttp__on_message_complete_2, + s_n_llhttp__internal__n_chunk_data_almost_done, + s_n_llhttp__internal__n_consume_content_length, + s_n_llhttp__internal__n_span_start_llhttp__on_body, + s_n_llhttp__internal__n_invoke_is_equal_content_length, + s_n_llhttp__internal__n_chunk_size_almost_done, + s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_name_complete, + s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_name_complete_1, + s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_value_complete, + s_n_llhttp__internal__n_chunk_extension_quoted_value_done, + s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_value_complete_1, + s_n_llhttp__internal__n_error_21, + s_n_llhttp__internal__n_chunk_extension_quoted_value, + s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_value_complete_2, + s_n_llhttp__internal__n_error_23, + s_n_llhttp__internal__n_chunk_extension_value, + s_n_llhttp__internal__n_span_start_llhttp__on_chunk_extension_value, + s_n_llhttp__internal__n_error_24, + s_n_llhttp__internal__n_chunk_extension_name, + s_n_llhttp__internal__n_span_start_llhttp__on_chunk_extension_name, + s_n_llhttp__internal__n_chunk_extensions, + s_n_llhttp__internal__n_chunk_size_otherwise, + s_n_llhttp__internal__n_chunk_size, + s_n_llhttp__internal__n_chunk_size_digit, + s_n_llhttp__internal__n_invoke_update_content_length_1, + s_n_llhttp__internal__n_consume_content_length_1, + s_n_llhttp__internal__n_span_start_llhttp__on_body_1, + s_n_llhttp__internal__n_eof, + s_n_llhttp__internal__n_span_start_llhttp__on_body_2, + s_n_llhttp__internal__n_invoke_llhttp__after_headers_complete, + s_n_llhttp__internal__n_headers_almost_done, + s_n_llhttp__internal__n_header_field_colon_discard_ws, + s_n_llhttp__internal__n_error_33, + s_n_llhttp__internal__n_invoke_llhttp__on_header_value_complete, + s_n_llhttp__internal__n_span_start_llhttp__on_header_value, + s_n_llhttp__internal__n_header_value_discard_lws, + s_n_llhttp__internal__n_header_value_discard_ws_almost_done, + s_n_llhttp__internal__n_header_value_lws, + s_n_llhttp__internal__n_header_value_almost_done, + s_n_llhttp__internal__n_header_value_lenient, + s_n_llhttp__internal__n_error_40, + s_n_llhttp__internal__n_header_value_otherwise, + s_n_llhttp__internal__n_header_value_connection_token, + s_n_llhttp__internal__n_header_value_connection_ws, + s_n_llhttp__internal__n_header_value_connection_1, + s_n_llhttp__internal__n_header_value_connection_2, + s_n_llhttp__internal__n_header_value_connection_3, + s_n_llhttp__internal__n_header_value_connection, + s_n_llhttp__internal__n_error_42, + s_n_llhttp__internal__n_error_43, + s_n_llhttp__internal__n_header_value_content_length_ws, + s_n_llhttp__internal__n_header_value_content_length, + s_n_llhttp__internal__n_error_45, + s_n_llhttp__internal__n_error_44, + s_n_llhttp__internal__n_header_value_te_token_ows, + s_n_llhttp__internal__n_header_value, + s_n_llhttp__internal__n_header_value_te_token, + s_n_llhttp__internal__n_header_value_te_chunked_last, + s_n_llhttp__internal__n_header_value_te_chunked, + s_n_llhttp__internal__n_span_start_llhttp__on_header_value_1, + s_n_llhttp__internal__n_header_value_discard_ws, + s_n_llhttp__internal__n_invoke_llhttp__on_header_field_complete, + s_n_llhttp__internal__n_header_field_general_otherwise, + s_n_llhttp__internal__n_header_field_general, + s_n_llhttp__internal__n_header_field_colon, + s_n_llhttp__internal__n_header_field_3, + s_n_llhttp__internal__n_header_field_4, + s_n_llhttp__internal__n_header_field_2, + s_n_llhttp__internal__n_header_field_1, + s_n_llhttp__internal__n_header_field_5, + s_n_llhttp__internal__n_header_field_6, + s_n_llhttp__internal__n_header_field_7, + s_n_llhttp__internal__n_header_field, + s_n_llhttp__internal__n_span_start_llhttp__on_header_field, + s_n_llhttp__internal__n_header_field_start, + s_n_llhttp__internal__n_headers_start, + s_n_llhttp__internal__n_url_to_http_09, + s_n_llhttp__internal__n_url_skip_to_http09, + s_n_llhttp__internal__n_url_skip_lf_to_http09_1, + s_n_llhttp__internal__n_url_skip_lf_to_http09, + s_n_llhttp__internal__n_req_pri_upgrade, + s_n_llhttp__internal__n_req_http_complete_1, + s_n_llhttp__internal__n_req_http_complete, + s_n_llhttp__internal__n_invoke_load_method_1, + s_n_llhttp__internal__n_invoke_llhttp__on_version_complete, + s_n_llhttp__internal__n_error_50, + s_n_llhttp__internal__n_error_55, + s_n_llhttp__internal__n_req_http_minor, + s_n_llhttp__internal__n_error_56, + s_n_llhttp__internal__n_req_http_dot, + s_n_llhttp__internal__n_error_57, + s_n_llhttp__internal__n_req_http_major, + s_n_llhttp__internal__n_span_start_llhttp__on_version, + s_n_llhttp__internal__n_req_http_start_1, + s_n_llhttp__internal__n_req_http_start_2, + s_n_llhttp__internal__n_req_http_start_3, + s_n_llhttp__internal__n_req_http_start, + s_n_llhttp__internal__n_url_to_http, + s_n_llhttp__internal__n_url_skip_to_http, + s_n_llhttp__internal__n_url_fragment, + s_n_llhttp__internal__n_span_end_stub_query_3, + s_n_llhttp__internal__n_url_query, + s_n_llhttp__internal__n_url_query_or_fragment, + s_n_llhttp__internal__n_url_path, + s_n_llhttp__internal__n_span_start_stub_path_2, + s_n_llhttp__internal__n_span_start_stub_path, + s_n_llhttp__internal__n_span_start_stub_path_1, + s_n_llhttp__internal__n_url_server_with_at, + s_n_llhttp__internal__n_url_server, + s_n_llhttp__internal__n_url_schema_delim_1, + s_n_llhttp__internal__n_url_schema_delim, + s_n_llhttp__internal__n_span_end_stub_schema, + s_n_llhttp__internal__n_url_schema, + s_n_llhttp__internal__n_url_start, + s_n_llhttp__internal__n_span_start_llhttp__on_url_1, + s_n_llhttp__internal__n_url_entry_normal, + s_n_llhttp__internal__n_span_start_llhttp__on_url, + s_n_llhttp__internal__n_url_entry_connect, + s_n_llhttp__internal__n_req_spaces_before_url, + s_n_llhttp__internal__n_req_first_space_before_url, + s_n_llhttp__internal__n_invoke_llhttp__on_method_complete_1, + s_n_llhttp__internal__n_after_start_req_2, + s_n_llhttp__internal__n_after_start_req_3, + s_n_llhttp__internal__n_after_start_req_1, + s_n_llhttp__internal__n_after_start_req_4, + s_n_llhttp__internal__n_after_start_req_6, + s_n_llhttp__internal__n_after_start_req_8, + s_n_llhttp__internal__n_after_start_req_9, + s_n_llhttp__internal__n_after_start_req_7, + s_n_llhttp__internal__n_after_start_req_5, + s_n_llhttp__internal__n_after_start_req_12, + s_n_llhttp__internal__n_after_start_req_13, + s_n_llhttp__internal__n_after_start_req_11, + s_n_llhttp__internal__n_after_start_req_10, + s_n_llhttp__internal__n_after_start_req_14, + s_n_llhttp__internal__n_after_start_req_17, + s_n_llhttp__internal__n_after_start_req_16, + s_n_llhttp__internal__n_after_start_req_15, + s_n_llhttp__internal__n_after_start_req_18, + s_n_llhttp__internal__n_after_start_req_20, + s_n_llhttp__internal__n_after_start_req_21, + s_n_llhttp__internal__n_after_start_req_19, + s_n_llhttp__internal__n_after_start_req_23, + s_n_llhttp__internal__n_after_start_req_24, + s_n_llhttp__internal__n_after_start_req_26, + s_n_llhttp__internal__n_after_start_req_28, + s_n_llhttp__internal__n_after_start_req_29, + s_n_llhttp__internal__n_after_start_req_27, + s_n_llhttp__internal__n_after_start_req_25, + s_n_llhttp__internal__n_after_start_req_30, + s_n_llhttp__internal__n_after_start_req_22, + s_n_llhttp__internal__n_after_start_req_31, + s_n_llhttp__internal__n_after_start_req_32, + s_n_llhttp__internal__n_after_start_req_35, + s_n_llhttp__internal__n_after_start_req_36, + s_n_llhttp__internal__n_after_start_req_34, + s_n_llhttp__internal__n_after_start_req_37, + s_n_llhttp__internal__n_after_start_req_38, + s_n_llhttp__internal__n_after_start_req_42, + s_n_llhttp__internal__n_after_start_req_43, + s_n_llhttp__internal__n_after_start_req_41, + s_n_llhttp__internal__n_after_start_req_40, + s_n_llhttp__internal__n_after_start_req_39, + s_n_llhttp__internal__n_after_start_req_45, + s_n_llhttp__internal__n_after_start_req_44, + s_n_llhttp__internal__n_after_start_req_33, + s_n_llhttp__internal__n_after_start_req_48, + s_n_llhttp__internal__n_after_start_req_49, + s_n_llhttp__internal__n_after_start_req_50, + s_n_llhttp__internal__n_after_start_req_51, + s_n_llhttp__internal__n_after_start_req_47, + s_n_llhttp__internal__n_after_start_req_46, + s_n_llhttp__internal__n_after_start_req_54, + s_n_llhttp__internal__n_after_start_req_56, + s_n_llhttp__internal__n_after_start_req_57, + s_n_llhttp__internal__n_after_start_req_55, + s_n_llhttp__internal__n_after_start_req_53, + s_n_llhttp__internal__n_after_start_req_58, + s_n_llhttp__internal__n_after_start_req_59, + s_n_llhttp__internal__n_after_start_req_52, + s_n_llhttp__internal__n_after_start_req_61, + s_n_llhttp__internal__n_after_start_req_62, + s_n_llhttp__internal__n_after_start_req_60, + s_n_llhttp__internal__n_after_start_req_65, + s_n_llhttp__internal__n_after_start_req_67, + s_n_llhttp__internal__n_after_start_req_68, + s_n_llhttp__internal__n_after_start_req_66, + s_n_llhttp__internal__n_after_start_req_69, + s_n_llhttp__internal__n_after_start_req_64, + s_n_llhttp__internal__n_after_start_req_63, + s_n_llhttp__internal__n_after_start_req, + s_n_llhttp__internal__n_span_start_llhttp__on_method_1, + s_n_llhttp__internal__n_invoke_llhttp__on_status_complete, + s_n_llhttp__internal__n_res_line_almost_done, + s_n_llhttp__internal__n_res_status, + s_n_llhttp__internal__n_span_start_llhttp__on_status, + s_n_llhttp__internal__n_res_status_start, + s_n_llhttp__internal__n_res_status_code_otherwise, + s_n_llhttp__internal__n_res_status_code, + s_n_llhttp__internal__n_res_after_version, + s_n_llhttp__internal__n_invoke_llhttp__on_version_complete_1, + s_n_llhttp__internal__n_error_72, + s_n_llhttp__internal__n_error_79, + s_n_llhttp__internal__n_res_http_minor, + s_n_llhttp__internal__n_error_80, + s_n_llhttp__internal__n_res_http_dot, + s_n_llhttp__internal__n_error_81, + s_n_llhttp__internal__n_res_http_major, + s_n_llhttp__internal__n_span_start_llhttp__on_version_1, + s_n_llhttp__internal__n_start_res, + s_n_llhttp__internal__n_invoke_llhttp__on_method_complete, + s_n_llhttp__internal__n_req_or_res_method_2, + s_n_llhttp__internal__n_invoke_update_type_1, + s_n_llhttp__internal__n_req_or_res_method_3, + s_n_llhttp__internal__n_req_or_res_method_1, + s_n_llhttp__internal__n_req_or_res_method, + s_n_llhttp__internal__n_span_start_llhttp__on_method, + s_n_llhttp__internal__n_start_req_or_res, + s_n_llhttp__internal__n_invoke_load_type, + s_n_llhttp__internal__n_invoke_update_finish, + s_n_llhttp__internal__n_start, +}; +typedef enum llparse_state_e llparse_state_t; + +int llhttp__on_method( + llhttp__internal_t* s, const unsigned char* p, + const unsigned char* endp); + +int llhttp__on_url( + llhttp__internal_t* s, const unsigned char* p, + const unsigned char* endp); + +int llhttp__on_version( + llhttp__internal_t* s, const unsigned char* p, + const unsigned char* endp); + +int llhttp__on_header_field( + llhttp__internal_t* s, const unsigned char* p, + const unsigned char* endp); + +int llhttp__on_header_value( + llhttp__internal_t* s, const unsigned char* p, + const unsigned char* endp); + +int llhttp__on_body( + llhttp__internal_t* s, const unsigned char* p, + const unsigned char* endp); + +int llhttp__on_chunk_extension_name( + llhttp__internal_t* s, const unsigned char* p, + const unsigned char* endp); + +int llhttp__on_chunk_extension_value( + llhttp__internal_t* s, const unsigned char* p, + const unsigned char* endp); + +int llhttp__on_status( + llhttp__internal_t* s, const unsigned char* p, + const unsigned char* endp); + +int llhttp__internal__c_load_initial_message_completed( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + return state->initial_message_completed; +} + +int llhttp__on_reset( + llhttp__internal_t* s, const unsigned char* p, + const unsigned char* endp); + +int llhttp__internal__c_update_finish( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + state->finish = 2; + return 0; +} + +int llhttp__on_message_begin( + llhttp__internal_t* s, const unsigned char* p, + const unsigned char* endp); + +int llhttp__internal__c_load_type( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + return state->type; +} + +int llhttp__internal__c_store_method( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp, + int match) { + state->method = match; + return 0; +} + +int llhttp__on_method_complete( + llhttp__internal_t* s, const unsigned char* p, + const unsigned char* endp); + +int llhttp__internal__c_is_equal_method( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + return state->method == 5; +} + +int llhttp__internal__c_update_http_major( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + state->http_major = 0; + return 0; +} + +int llhttp__internal__c_update_http_minor( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + state->http_minor = 9; + return 0; +} + +int llhttp__on_url_complete( + llhttp__internal_t* s, const unsigned char* p, + const unsigned char* endp); + +int llhttp__internal__c_test_lenient_flags( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + return (state->lenient_flags & 1) == 1; +} + +int llhttp__internal__c_test_flags( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + return (state->flags & 128) == 128; +} + +int llhttp__on_chunk_complete( + llhttp__internal_t* s, const unsigned char* p, + const unsigned char* endp); + +int llhttp__on_message_complete( + llhttp__internal_t* s, const unsigned char* p, + const unsigned char* endp); + +int llhttp__internal__c_is_equal_upgrade( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + return state->upgrade == 1; +} + +int llhttp__after_message_complete( + llhttp__internal_t* s, const unsigned char* p, + const unsigned char* endp); + +int llhttp__internal__c_update_content_length( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + state->content_length = 0; + return 0; +} + +int llhttp__internal__c_update_initial_message_completed( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + state->initial_message_completed = 1; + return 0; +} + +int llhttp__internal__c_update_finish_1( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + state->finish = 0; + return 0; +} + +int llhttp__internal__c_test_lenient_flags_1( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + return (state->lenient_flags & 4) == 4; +} + +int llhttp__internal__c_test_flags_1( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + return (state->flags & 544) == 544; +} + +int llhttp__internal__c_test_lenient_flags_2( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + return (state->lenient_flags & 2) == 2; +} + +int llhttp__before_headers_complete( + llhttp__internal_t* s, const unsigned char* p, + const unsigned char* endp); + +int llhttp__on_headers_complete( + llhttp__internal_t* s, const unsigned char* p, + const unsigned char* endp); + +int llhttp__after_headers_complete( + llhttp__internal_t* s, const unsigned char* p, + const unsigned char* endp); + +int llhttp__internal__c_mul_add_content_length( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp, + int match) { + /* Multiplication overflow */ + if (state->content_length > 0xffffffffffffffffULL / 16) { + return 1; + } + + state->content_length *= 16; + + /* Addition overflow */ + if (match >= 0) { + if (state->content_length > 0xffffffffffffffffULL - match) { + return 1; + } + } else { + if (state->content_length < 0ULL - match) { + return 1; + } + } + state->content_length += match; + return 0; +} + +int llhttp__on_chunk_header( + llhttp__internal_t* s, const unsigned char* p, + const unsigned char* endp); + +int llhttp__internal__c_is_equal_content_length( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + return state->content_length == 0; +} + +int llhttp__internal__c_or_flags( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + state->flags |= 128; + return 0; +} + +int llhttp__on_chunk_extension_name_complete( + llhttp__internal_t* s, const unsigned char* p, + const unsigned char* endp); + +int llhttp__on_chunk_extension_value_complete( + llhttp__internal_t* s, const unsigned char* p, + const unsigned char* endp); + +int llhttp__internal__c_update_finish_3( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + state->finish = 1; + return 0; +} + +int llhttp__internal__c_or_flags_1( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + state->flags |= 64; + return 0; +} + +int llhttp__internal__c_update_upgrade( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + state->upgrade = 1; + return 0; +} + +int llhttp__internal__c_store_header_state( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp, + int match) { + state->header_state = match; + return 0; +} + +int llhttp__on_header_field_complete( + llhttp__internal_t* s, const unsigned char* p, + const unsigned char* endp); + +int llhttp__internal__c_load_header_state( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + return state->header_state; +} + +int llhttp__internal__c_or_flags_3( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + state->flags |= 1; + return 0; +} + +int llhttp__internal__c_update_header_state( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + state->header_state = 1; + return 0; +} + +int llhttp__on_header_value_complete( + llhttp__internal_t* s, const unsigned char* p, + const unsigned char* endp); + +int llhttp__internal__c_or_flags_4( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + state->flags |= 2; + return 0; +} + +int llhttp__internal__c_or_flags_5( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + state->flags |= 4; + return 0; +} + +int llhttp__internal__c_or_flags_6( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + state->flags |= 8; + return 0; +} + +int llhttp__internal__c_update_header_state_3( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + state->header_state = 6; + return 0; +} + +int llhttp__internal__c_update_header_state_1( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + state->header_state = 0; + return 0; +} + +int llhttp__internal__c_update_header_state_6( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + state->header_state = 5; + return 0; +} + +int llhttp__internal__c_update_header_state_7( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + state->header_state = 7; + return 0; +} + +int llhttp__internal__c_test_flags_2( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + return (state->flags & 32) == 32; +} + +int llhttp__internal__c_mul_add_content_length_1( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp, + int match) { + /* Multiplication overflow */ + if (state->content_length > 0xffffffffffffffffULL / 10) { + return 1; + } + + state->content_length *= 10; + + /* Addition overflow */ + if (match >= 0) { + if (state->content_length > 0xffffffffffffffffULL - match) { + return 1; + } + } else { + if (state->content_length < 0ULL - match) { + return 1; + } + } + state->content_length += match; + return 0; +} + +int llhttp__internal__c_or_flags_15( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + state->flags |= 32; + return 0; +} + +int llhttp__internal__c_test_flags_3( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + return (state->flags & 8) == 8; +} + +int llhttp__internal__c_test_lenient_flags_6( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + return (state->lenient_flags & 8) == 8; +} + +int llhttp__internal__c_or_flags_16( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + state->flags |= 512; + return 0; +} + +int llhttp__internal__c_and_flags( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + state->flags &= -9; + return 0; +} + +int llhttp__internal__c_update_header_state_8( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + state->header_state = 8; + return 0; +} + +int llhttp__internal__c_or_flags_18( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + state->flags |= 16; + return 0; +} + +int llhttp__internal__c_load_method( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + return state->method; +} + +int llhttp__internal__c_store_http_major( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp, + int match) { + state->http_major = match; + return 0; +} + +int llhttp__internal__c_store_http_minor( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp, + int match) { + state->http_minor = match; + return 0; +} + +int llhttp__internal__c_test_lenient_flags_8( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + return (state->lenient_flags & 16) == 16; +} + +int llhttp__on_version_complete( + llhttp__internal_t* s, const unsigned char* p, + const unsigned char* endp); + +int llhttp__internal__c_load_http_major( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + return state->http_major; +} + +int llhttp__internal__c_load_http_minor( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + return state->http_minor; +} + +int llhttp__internal__c_update_status_code( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + state->status_code = 0; + return 0; +} + +int llhttp__internal__c_mul_add_status_code( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp, + int match) { + /* Multiplication overflow */ + if (state->status_code > 0xffff / 10) { + return 1; + } + + state->status_code *= 10; + + /* Addition overflow */ + if (match >= 0) { + if (state->status_code > 0xffff - match) { + return 1; + } + } else { + if (state->status_code < 0 - match) { + return 1; + } + } + state->status_code += match; + + /* Enforce maximum */ + if (state->status_code > 999) { + return 1; + } + return 0; +} + +int llhttp__on_status_complete( + llhttp__internal_t* s, const unsigned char* p, + const unsigned char* endp); + +int llhttp__internal__c_update_type( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + state->type = 1; + return 0; +} + +int llhttp__internal__c_update_type_1( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + state->type = 2; + return 0; +} + +int llhttp__internal_init(llhttp__internal_t* state) { + memset(state, 0, sizeof(*state)); + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_start; + return 0; +} + +static llparse_state_t llhttp__internal__run( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + int match; + switch ((llparse_state_t) (intptr_t) state->_current) { + case s_n_llhttp__internal__n_closed: + s_n_llhttp__internal__n_closed: { + if (p == endp) { + return s_n_llhttp__internal__n_closed; + } + switch (*p) { + case 10: { + p++; + goto s_n_llhttp__internal__n_closed; + } + case 13: { + p++; + goto s_n_llhttp__internal__n_closed; + } + default: { + p++; + goto s_n_llhttp__internal__n_error_7; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_invoke_llhttp__after_message_complete: + s_n_llhttp__internal__n_invoke_llhttp__after_message_complete: { + switch (llhttp__after_message_complete(state, p, endp)) { + case 1: + goto s_n_llhttp__internal__n_invoke_update_content_length; + default: + goto s_n_llhttp__internal__n_invoke_update_finish_1; + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_pause_1: + s_n_llhttp__internal__n_pause_1: { + state->error = 0x16; + state->reason = "Pause on CONNECT/Upgrade"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_llhttp__after_message_complete; + return s_error; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_invoke_is_equal_upgrade: + s_n_llhttp__internal__n_invoke_is_equal_upgrade: { + switch (llhttp__internal__c_is_equal_upgrade(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_invoke_llhttp__after_message_complete; + default: + goto s_n_llhttp__internal__n_pause_1; + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_invoke_llhttp__on_message_complete_2: + s_n_llhttp__internal__n_invoke_llhttp__on_message_complete_2: { + switch (llhttp__on_message_complete(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_invoke_is_equal_upgrade; + case 21: + goto s_n_llhttp__internal__n_pause_11; + default: + goto s_n_llhttp__internal__n_error_28; + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_chunk_data_almost_done: + s_n_llhttp__internal__n_chunk_data_almost_done: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_chunk_data_almost_done; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob0, 2); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + goto s_n_llhttp__internal__n_invoke_llhttp__on_chunk_complete; + } + case kMatchPause: { + return s_n_llhttp__internal__n_chunk_data_almost_done; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_11; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_consume_content_length: + s_n_llhttp__internal__n_consume_content_length: { + size_t avail; + uint64_t need; + + avail = endp - p; + need = state->content_length; + if (avail >= need) { + p += need; + state->content_length = 0; + goto s_n_llhttp__internal__n_span_end_llhttp__on_body; + } + + state->content_length -= avail; + return s_n_llhttp__internal__n_consume_content_length; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_span_start_llhttp__on_body: + s_n_llhttp__internal__n_span_start_llhttp__on_body: { + if (p == endp) { + return s_n_llhttp__internal__n_span_start_llhttp__on_body; + } + state->_span_pos0 = (void*) p; + state->_span_cb0 = llhttp__on_body; + goto s_n_llhttp__internal__n_consume_content_length; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_invoke_is_equal_content_length: + s_n_llhttp__internal__n_invoke_is_equal_content_length: { + switch (llhttp__internal__c_is_equal_content_length(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_span_start_llhttp__on_body; + default: + goto s_n_llhttp__internal__n_invoke_or_flags; + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_chunk_size_almost_done: + s_n_llhttp__internal__n_chunk_size_almost_done: { + if (p == endp) { + return s_n_llhttp__internal__n_chunk_size_almost_done; + } + switch (*p) { + case 10: { + p++; + goto s_n_llhttp__internal__n_invoke_llhttp__on_chunk_header; + } + default: { + goto s_n_llhttp__internal__n_error_12; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_name_complete: + s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_name_complete: { + switch (llhttp__on_chunk_extension_name_complete(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_chunk_size_almost_done; + case 21: + goto s_n_llhttp__internal__n_pause_5; + default: + goto s_n_llhttp__internal__n_error_15; + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_name_complete_1: + s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_name_complete_1: { + switch (llhttp__on_chunk_extension_name_complete(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_chunk_extensions; + case 21: + goto s_n_llhttp__internal__n_pause_6; + default: + goto s_n_llhttp__internal__n_error_16; + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_value_complete: + s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_value_complete: { + switch (llhttp__on_chunk_extension_value_complete(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_chunk_size_almost_done; + case 21: + goto s_n_llhttp__internal__n_pause_7; + default: + goto s_n_llhttp__internal__n_error_18; + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_chunk_extension_quoted_value_done: + s_n_llhttp__internal__n_chunk_extension_quoted_value_done: { + if (p == endp) { + return s_n_llhttp__internal__n_chunk_extension_quoted_value_done; + } + switch (*p) { + case 13: { + p++; + goto s_n_llhttp__internal__n_chunk_size_almost_done; + } + case ';': { + p++; + goto s_n_llhttp__internal__n_chunk_extensions; + } + default: { + goto s_n_llhttp__internal__n_error_20; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_value_complete_1: + s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_value_complete_1: { + switch (llhttp__on_chunk_extension_value_complete(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_chunk_extension_quoted_value_done; + case 21: + goto s_n_llhttp__internal__n_pause_8; + default: + goto s_n_llhttp__internal__n_error_19; + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_error_21: + s_n_llhttp__internal__n_error_21: { + state->error = 0x2; + state->reason = "Invalid character in chunk extensions quoted value"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_chunk_extension_quoted_value: + s_n_llhttp__internal__n_chunk_extension_quoted_value: { + static uint8_t lookup_table[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 + }; + if (p == endp) { + return s_n_llhttp__internal__n_chunk_extension_quoted_value; + } + switch (lookup_table[(uint8_t) *p]) { + case 1: { + p++; + goto s_n_llhttp__internal__n_chunk_extension_quoted_value; + } + case 2: { + p++; + goto s_n_llhttp__internal__n_span_end_llhttp__on_chunk_extension_value_1; + } + default: { + goto s_n_llhttp__internal__n_span_end_llhttp__on_chunk_extension_value_2; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_value_complete_2: + s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_value_complete_2: { + switch (llhttp__on_chunk_extension_value_complete(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_chunk_size_otherwise; + case 21: + goto s_n_llhttp__internal__n_pause_9; + default: + goto s_n_llhttp__internal__n_error_22; + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_error_23: + s_n_llhttp__internal__n_error_23: { + state->error = 0x2; + state->reason = "Invalid character in chunk extensions value"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_chunk_extension_value: + s_n_llhttp__internal__n_chunk_extension_value: { + static uint8_t lookup_table[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2, 3, 2, 2, 2, 2, 2, 0, 0, 2, 2, 0, 2, 2, 0, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 4, 0, 0, 0, 0, + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 2, 0, 2, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + if (p == endp) { + return s_n_llhttp__internal__n_chunk_extension_value; + } + switch (lookup_table[(uint8_t) *p]) { + case 1: { + goto s_n_llhttp__internal__n_span_end_llhttp__on_chunk_extension_value; + } + case 2: { + p++; + goto s_n_llhttp__internal__n_chunk_extension_value; + } + case 3: { + p++; + goto s_n_llhttp__internal__n_chunk_extension_quoted_value; + } + case 4: { + goto s_n_llhttp__internal__n_span_end_llhttp__on_chunk_extension_value_3; + } + default: { + goto s_n_llhttp__internal__n_span_end_llhttp__on_chunk_extension_value_4; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_span_start_llhttp__on_chunk_extension_value: + s_n_llhttp__internal__n_span_start_llhttp__on_chunk_extension_value: { + if (p == endp) { + return s_n_llhttp__internal__n_span_start_llhttp__on_chunk_extension_value; + } + state->_span_pos0 = (void*) p; + state->_span_cb0 = llhttp__on_chunk_extension_value; + goto s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_name_complete_2; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_error_24: + s_n_llhttp__internal__n_error_24: { + state->error = 0x2; + state->reason = "Invalid character in chunk extensions name"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_chunk_extension_name: + s_n_llhttp__internal__n_chunk_extension_name: { + static uint8_t lookup_table[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2, 0, 2, 2, 2, 2, 2, 0, 0, 2, 2, 0, 2, 2, 0, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 3, 0, 4, 0, 0, + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 2, 0, 2, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + if (p == endp) { + return s_n_llhttp__internal__n_chunk_extension_name; + } + switch (lookup_table[(uint8_t) *p]) { + case 1: { + goto s_n_llhttp__internal__n_span_end_llhttp__on_chunk_extension_name; + } + case 2: { + p++; + goto s_n_llhttp__internal__n_chunk_extension_name; + } + case 3: { + goto s_n_llhttp__internal__n_span_end_llhttp__on_chunk_extension_name_1; + } + case 4: { + goto s_n_llhttp__internal__n_span_end_llhttp__on_chunk_extension_name_2; + } + default: { + goto s_n_llhttp__internal__n_span_end_llhttp__on_chunk_extension_name_3; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_span_start_llhttp__on_chunk_extension_name: + s_n_llhttp__internal__n_span_start_llhttp__on_chunk_extension_name: { + if (p == endp) { + return s_n_llhttp__internal__n_span_start_llhttp__on_chunk_extension_name; + } + state->_span_pos0 = (void*) p; + state->_span_cb0 = llhttp__on_chunk_extension_name; + goto s_n_llhttp__internal__n_chunk_extension_name; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_chunk_extensions: + s_n_llhttp__internal__n_chunk_extensions: { + if (p == endp) { + return s_n_llhttp__internal__n_chunk_extensions; + } + switch (*p) { + case 13: { + p++; + goto s_n_llhttp__internal__n_error_13; + } + case ' ': { + p++; + goto s_n_llhttp__internal__n_error_14; + } + default: { + goto s_n_llhttp__internal__n_span_start_llhttp__on_chunk_extension_name; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_chunk_size_otherwise: + s_n_llhttp__internal__n_chunk_size_otherwise: { + if (p == endp) { + return s_n_llhttp__internal__n_chunk_size_otherwise; + } + switch (*p) { + case 13: { + p++; + goto s_n_llhttp__internal__n_chunk_size_almost_done; + } + case ';': { + p++; + goto s_n_llhttp__internal__n_chunk_extensions; + } + default: { + goto s_n_llhttp__internal__n_error_25; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_chunk_size: + s_n_llhttp__internal__n_chunk_size: { + if (p == endp) { + return s_n_llhttp__internal__n_chunk_size; + } + switch (*p) { + case '0': { + p++; + match = 0; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case '1': { + p++; + match = 1; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case '2': { + p++; + match = 2; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case '3': { + p++; + match = 3; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case '4': { + p++; + match = 4; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case '5': { + p++; + match = 5; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case '6': { + p++; + match = 6; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case '7': { + p++; + match = 7; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case '8': { + p++; + match = 8; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case '9': { + p++; + match = 9; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case 'A': { + p++; + match = 10; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case 'B': { + p++; + match = 11; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case 'C': { + p++; + match = 12; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case 'D': { + p++; + match = 13; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case 'E': { + p++; + match = 14; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case 'F': { + p++; + match = 15; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case 'a': { + p++; + match = 10; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case 'b': { + p++; + match = 11; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case 'c': { + p++; + match = 12; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case 'd': { + p++; + match = 13; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case 'e': { + p++; + match = 14; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case 'f': { + p++; + match = 15; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + default: { + goto s_n_llhttp__internal__n_chunk_size_otherwise; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_chunk_size_digit: + s_n_llhttp__internal__n_chunk_size_digit: { + if (p == endp) { + return s_n_llhttp__internal__n_chunk_size_digit; + } + switch (*p) { + case '0': { + p++; + match = 0; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case '1': { + p++; + match = 1; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case '2': { + p++; + match = 2; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case '3': { + p++; + match = 3; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case '4': { + p++; + match = 4; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case '5': { + p++; + match = 5; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case '6': { + p++; + match = 6; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case '7': { + p++; + match = 7; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case '8': { + p++; + match = 8; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case '9': { + p++; + match = 9; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case 'A': { + p++; + match = 10; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case 'B': { + p++; + match = 11; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case 'C': { + p++; + match = 12; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case 'D': { + p++; + match = 13; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case 'E': { + p++; + match = 14; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case 'F': { + p++; + match = 15; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case 'a': { + p++; + match = 10; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case 'b': { + p++; + match = 11; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case 'c': { + p++; + match = 12; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case 'd': { + p++; + match = 13; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case 'e': { + p++; + match = 14; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case 'f': { + p++; + match = 15; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + default: { + goto s_n_llhttp__internal__n_error_27; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_invoke_update_content_length_1: + s_n_llhttp__internal__n_invoke_update_content_length_1: { + switch (llhttp__internal__c_update_content_length(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_chunk_size_digit; + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_consume_content_length_1: + s_n_llhttp__internal__n_consume_content_length_1: { + size_t avail; + uint64_t need; + + avail = endp - p; + need = state->content_length; + if (avail >= need) { + p += need; + state->content_length = 0; + goto s_n_llhttp__internal__n_span_end_llhttp__on_body_1; + } + + state->content_length -= avail; + return s_n_llhttp__internal__n_consume_content_length_1; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_span_start_llhttp__on_body_1: + s_n_llhttp__internal__n_span_start_llhttp__on_body_1: { + if (p == endp) { + return s_n_llhttp__internal__n_span_start_llhttp__on_body_1; + } + state->_span_pos0 = (void*) p; + state->_span_cb0 = llhttp__on_body; + goto s_n_llhttp__internal__n_consume_content_length_1; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_eof: + s_n_llhttp__internal__n_eof: { + if (p == endp) { + return s_n_llhttp__internal__n_eof; + } + p++; + goto s_n_llhttp__internal__n_eof; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_span_start_llhttp__on_body_2: + s_n_llhttp__internal__n_span_start_llhttp__on_body_2: { + if (p == endp) { + return s_n_llhttp__internal__n_span_start_llhttp__on_body_2; + } + state->_span_pos0 = (void*) p; + state->_span_cb0 = llhttp__on_body; + goto s_n_llhttp__internal__n_eof; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_invoke_llhttp__after_headers_complete: + s_n_llhttp__internal__n_invoke_llhttp__after_headers_complete: { + switch (llhttp__after_headers_complete(state, p, endp)) { + case 1: + goto s_n_llhttp__internal__n_invoke_llhttp__on_message_complete_1; + case 2: + goto s_n_llhttp__internal__n_invoke_update_content_length_1; + case 3: + goto s_n_llhttp__internal__n_span_start_llhttp__on_body_1; + case 4: + goto s_n_llhttp__internal__n_invoke_update_finish_3; + case 5: + goto s_n_llhttp__internal__n_error_29; + default: + goto s_n_llhttp__internal__n_invoke_llhttp__on_message_complete; + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_headers_almost_done: + s_n_llhttp__internal__n_headers_almost_done: { + if (p == endp) { + return s_n_llhttp__internal__n_headers_almost_done; + } + switch (*p) { + case 10: { + p++; + goto s_n_llhttp__internal__n_invoke_test_flags; + } + default: { + goto s_n_llhttp__internal__n_error_32; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_header_field_colon_discard_ws: + s_n_llhttp__internal__n_header_field_colon_discard_ws: { + if (p == endp) { + return s_n_llhttp__internal__n_header_field_colon_discard_ws; + } + switch (*p) { + case ' ': { + p++; + goto s_n_llhttp__internal__n_header_field_colon_discard_ws; + } + default: { + goto s_n_llhttp__internal__n_header_field_colon; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_error_33: + s_n_llhttp__internal__n_error_33: { + state->error = 0xa; + state->reason = "Invalid header field char"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_invoke_llhttp__on_header_value_complete: + s_n_llhttp__internal__n_invoke_llhttp__on_header_value_complete: { + switch (llhttp__on_header_value_complete(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_header_field_start; + case 21: + goto s_n_llhttp__internal__n_pause_14; + default: + goto s_n_llhttp__internal__n_error_36; + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_span_start_llhttp__on_header_value: + s_n_llhttp__internal__n_span_start_llhttp__on_header_value: { + if (p == endp) { + return s_n_llhttp__internal__n_span_start_llhttp__on_header_value; + } + state->_span_pos0 = (void*) p; + state->_span_cb0 = llhttp__on_header_value; + goto s_n_llhttp__internal__n_span_end_llhttp__on_header_value; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_header_value_discard_lws: + s_n_llhttp__internal__n_header_value_discard_lws: { + if (p == endp) { + return s_n_llhttp__internal__n_header_value_discard_lws; + } + switch (*p) { + case 9: { + p++; + goto s_n_llhttp__internal__n_header_value_discard_ws; + } + case ' ': { + p++; + goto s_n_llhttp__internal__n_header_value_discard_ws; + } + default: { + goto s_n_llhttp__internal__n_invoke_load_header_state; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_header_value_discard_ws_almost_done: + s_n_llhttp__internal__n_header_value_discard_ws_almost_done: { + if (p == endp) { + return s_n_llhttp__internal__n_header_value_discard_ws_almost_done; + } + switch (*p) { + case 10: { + p++; + goto s_n_llhttp__internal__n_header_value_discard_lws; + } + default: { + goto s_n_llhttp__internal__n_error_38; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_header_value_lws: + s_n_llhttp__internal__n_header_value_lws: { + if (p == endp) { + return s_n_llhttp__internal__n_header_value_lws; + } + switch (*p) { + case 9: { + goto s_n_llhttp__internal__n_invoke_load_header_state_3; + } + case ' ': { + goto s_n_llhttp__internal__n_invoke_load_header_state_3; + } + default: { + goto s_n_llhttp__internal__n_invoke_load_header_state_4; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_header_value_almost_done: + s_n_llhttp__internal__n_header_value_almost_done: { + if (p == endp) { + return s_n_llhttp__internal__n_header_value_almost_done; + } + switch (*p) { + case 10: { + p++; + goto s_n_llhttp__internal__n_header_value_lws; + } + default: { + goto s_n_llhttp__internal__n_error_39; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_header_value_lenient: + s_n_llhttp__internal__n_header_value_lenient: { + if (p == endp) { + return s_n_llhttp__internal__n_header_value_lenient; + } + switch (*p) { + case 10: { + goto s_n_llhttp__internal__n_span_end_llhttp__on_header_value_3; + } + case 13: { + goto s_n_llhttp__internal__n_span_end_llhttp__on_header_value_4; + } + default: { + p++; + goto s_n_llhttp__internal__n_header_value_lenient; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_error_40: + s_n_llhttp__internal__n_error_40: { + state->error = 0xa; + state->reason = "Invalid header value char"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_header_value_otherwise: + s_n_llhttp__internal__n_header_value_otherwise: { + if (p == endp) { + return s_n_llhttp__internal__n_header_value_otherwise; + } + switch (*p) { + case 13: { + goto s_n_llhttp__internal__n_span_end_llhttp__on_header_value_1; + } + default: { + goto s_n_llhttp__internal__n_invoke_test_lenient_flags_5; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_header_value_connection_token: + s_n_llhttp__internal__n_header_value_connection_token: { + static uint8_t lookup_table[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 + }; + if (p == endp) { + return s_n_llhttp__internal__n_header_value_connection_token; + } + switch (lookup_table[(uint8_t) *p]) { + case 1: { + p++; + goto s_n_llhttp__internal__n_header_value_connection_token; + } + case 2: { + p++; + goto s_n_llhttp__internal__n_header_value_connection; + } + default: { + goto s_n_llhttp__internal__n_header_value_otherwise; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_header_value_connection_ws: + s_n_llhttp__internal__n_header_value_connection_ws: { + if (p == endp) { + return s_n_llhttp__internal__n_header_value_connection_ws; + } + switch (*p) { + case 10: { + goto s_n_llhttp__internal__n_header_value_otherwise; + } + case 13: { + goto s_n_llhttp__internal__n_header_value_otherwise; + } + case ' ': { + p++; + goto s_n_llhttp__internal__n_header_value_connection_ws; + } + case ',': { + p++; + goto s_n_llhttp__internal__n_invoke_load_header_state_5; + } + default: { + goto s_n_llhttp__internal__n_invoke_update_header_state_5; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_header_value_connection_1: + s_n_llhttp__internal__n_header_value_connection_1: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_header_value_connection_1; + } + match_seq = llparse__match_sequence_to_lower(state, p, endp, llparse_blob3, 4); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + goto s_n_llhttp__internal__n_invoke_update_header_state_3; + } + case kMatchPause: { + return s_n_llhttp__internal__n_header_value_connection_1; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_header_value_connection_token; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_header_value_connection_2: + s_n_llhttp__internal__n_header_value_connection_2: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_header_value_connection_2; + } + match_seq = llparse__match_sequence_to_lower(state, p, endp, llparse_blob4, 9); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + goto s_n_llhttp__internal__n_invoke_update_header_state_6; + } + case kMatchPause: { + return s_n_llhttp__internal__n_header_value_connection_2; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_header_value_connection_token; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_header_value_connection_3: + s_n_llhttp__internal__n_header_value_connection_3: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_header_value_connection_3; + } + match_seq = llparse__match_sequence_to_lower(state, p, endp, llparse_blob5, 6); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + goto s_n_llhttp__internal__n_invoke_update_header_state_7; + } + case kMatchPause: { + return s_n_llhttp__internal__n_header_value_connection_3; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_header_value_connection_token; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_header_value_connection: + s_n_llhttp__internal__n_header_value_connection: { + if (p == endp) { + return s_n_llhttp__internal__n_header_value_connection; + } + switch (((*p) >= 'A' && (*p) <= 'Z' ? (*p | 0x20) : (*p))) { + case 9: { + p++; + goto s_n_llhttp__internal__n_header_value_connection; + } + case ' ': { + p++; + goto s_n_llhttp__internal__n_header_value_connection; + } + case 'c': { + p++; + goto s_n_llhttp__internal__n_header_value_connection_1; + } + case 'k': { + p++; + goto s_n_llhttp__internal__n_header_value_connection_2; + } + case 'u': { + p++; + goto s_n_llhttp__internal__n_header_value_connection_3; + } + default: { + goto s_n_llhttp__internal__n_header_value_connection_token; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_error_42: + s_n_llhttp__internal__n_error_42: { + state->error = 0xb; + state->reason = "Content-Length overflow"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_error_43: + s_n_llhttp__internal__n_error_43: { + state->error = 0xb; + state->reason = "Invalid character in Content-Length"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_header_value_content_length_ws: + s_n_llhttp__internal__n_header_value_content_length_ws: { + if (p == endp) { + return s_n_llhttp__internal__n_header_value_content_length_ws; + } + switch (*p) { + case 10: { + goto s_n_llhttp__internal__n_invoke_or_flags_15; + } + case 13: { + goto s_n_llhttp__internal__n_invoke_or_flags_15; + } + case ' ': { + p++; + goto s_n_llhttp__internal__n_header_value_content_length_ws; + } + default: { + goto s_n_llhttp__internal__n_span_end_llhttp__on_header_value_6; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_header_value_content_length: + s_n_llhttp__internal__n_header_value_content_length: { + if (p == endp) { + return s_n_llhttp__internal__n_header_value_content_length; + } + switch (*p) { + case '0': { + p++; + match = 0; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length_1; + } + case '1': { + p++; + match = 1; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length_1; + } + case '2': { + p++; + match = 2; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length_1; + } + case '3': { + p++; + match = 3; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length_1; + } + case '4': { + p++; + match = 4; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length_1; + } + case '5': { + p++; + match = 5; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length_1; + } + case '6': { + p++; + match = 6; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length_1; + } + case '7': { + p++; + match = 7; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length_1; + } + case '8': { + p++; + match = 8; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length_1; + } + case '9': { + p++; + match = 9; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length_1; + } + default: { + goto s_n_llhttp__internal__n_header_value_content_length_ws; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_error_45: + s_n_llhttp__internal__n_error_45: { + state->error = 0xf; + state->reason = "Invalid `Transfer-Encoding` header value"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_error_44: + s_n_llhttp__internal__n_error_44: { + state->error = 0xf; + state->reason = "Invalid `Transfer-Encoding` header value"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_header_value_te_token_ows: + s_n_llhttp__internal__n_header_value_te_token_ows: { + if (p == endp) { + return s_n_llhttp__internal__n_header_value_te_token_ows; + } + switch (*p) { + case 9: { + p++; + goto s_n_llhttp__internal__n_header_value_te_token_ows; + } + case ' ': { + p++; + goto s_n_llhttp__internal__n_header_value_te_token_ows; + } + default: { + goto s_n_llhttp__internal__n_header_value_te_chunked; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_header_value: + s_n_llhttp__internal__n_header_value: { + static uint8_t lookup_table[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 + }; + if (p == endp) { + return s_n_llhttp__internal__n_header_value; + } + #ifdef __SSE4_2__ + if (endp - p >= 16) { + __m128i ranges; + __m128i input; + int avail; + int match_len; + + /* Load input */ + input = _mm_loadu_si128((__m128i const*) p); + ranges = _mm_loadu_si128((__m128i const*) llparse_blob7); + + /* Find first character that does not match `ranges` */ + match_len = _mm_cmpestri(ranges, 6, + input, 16, + _SIDD_UBYTE_OPS | _SIDD_CMP_RANGES | + _SIDD_NEGATIVE_POLARITY); + + if (match_len != 0) { + p += match_len; + goto s_n_llhttp__internal__n_header_value; + } + goto s_n_llhttp__internal__n_header_value_otherwise; + } + #endif /* __SSE4_2__ */ + switch (lookup_table[(uint8_t) *p]) { + case 1: { + p++; + goto s_n_llhttp__internal__n_header_value; + } + default: { + goto s_n_llhttp__internal__n_header_value_otherwise; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_header_value_te_token: + s_n_llhttp__internal__n_header_value_te_token: { + static uint8_t lookup_table[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 + }; + if (p == endp) { + return s_n_llhttp__internal__n_header_value_te_token; + } + switch (lookup_table[(uint8_t) *p]) { + case 1: { + p++; + goto s_n_llhttp__internal__n_header_value_te_token; + } + case 2: { + p++; + goto s_n_llhttp__internal__n_header_value_te_token_ows; + } + default: { + goto s_n_llhttp__internal__n_invoke_update_header_state_9; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_header_value_te_chunked_last: + s_n_llhttp__internal__n_header_value_te_chunked_last: { + if (p == endp) { + return s_n_llhttp__internal__n_header_value_te_chunked_last; + } + switch (*p) { + case 10: { + goto s_n_llhttp__internal__n_invoke_update_header_state_8; + } + case 13: { + goto s_n_llhttp__internal__n_invoke_update_header_state_8; + } + case ' ': { + p++; + goto s_n_llhttp__internal__n_header_value_te_chunked_last; + } + case ',': { + goto s_n_llhttp__internal__n_invoke_load_type_1; + } + default: { + goto s_n_llhttp__internal__n_header_value_te_token; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_header_value_te_chunked: + s_n_llhttp__internal__n_header_value_te_chunked: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_header_value_te_chunked; + } + match_seq = llparse__match_sequence_to_lower_unsafe(state, p, endp, llparse_blob6, 7); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + goto s_n_llhttp__internal__n_header_value_te_chunked_last; + } + case kMatchPause: { + return s_n_llhttp__internal__n_header_value_te_chunked; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_header_value_te_token; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_span_start_llhttp__on_header_value_1: + s_n_llhttp__internal__n_span_start_llhttp__on_header_value_1: { + if (p == endp) { + return s_n_llhttp__internal__n_span_start_llhttp__on_header_value_1; + } + state->_span_pos0 = (void*) p; + state->_span_cb0 = llhttp__on_header_value; + goto s_n_llhttp__internal__n_invoke_load_header_state_2; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_header_value_discard_ws: + s_n_llhttp__internal__n_header_value_discard_ws: { + if (p == endp) { + return s_n_llhttp__internal__n_header_value_discard_ws; + } + switch (*p) { + case 9: { + p++; + goto s_n_llhttp__internal__n_header_value_discard_ws; + } + case 10: { + p++; + goto s_n_llhttp__internal__n_invoke_test_lenient_flags_4; + } + case 13: { + p++; + goto s_n_llhttp__internal__n_header_value_discard_ws_almost_done; + } + case ' ': { + p++; + goto s_n_llhttp__internal__n_header_value_discard_ws; + } + default: { + goto s_n_llhttp__internal__n_span_start_llhttp__on_header_value_1; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_invoke_llhttp__on_header_field_complete: + s_n_llhttp__internal__n_invoke_llhttp__on_header_field_complete: { + switch (llhttp__on_header_field_complete(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_header_value_discard_ws; + case 21: + goto s_n_llhttp__internal__n_pause_15; + default: + goto s_n_llhttp__internal__n_error_34; + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_header_field_general_otherwise: + s_n_llhttp__internal__n_header_field_general_otherwise: { + if (p == endp) { + return s_n_llhttp__internal__n_header_field_general_otherwise; + } + switch (*p) { + case ':': { + goto s_n_llhttp__internal__n_span_end_llhttp__on_header_field_2; + } + default: { + goto s_n_llhttp__internal__n_error_46; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_header_field_general: + s_n_llhttp__internal__n_header_field_general: { + static uint8_t lookup_table[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + if (p == endp) { + return s_n_llhttp__internal__n_header_field_general; + } + #ifdef __SSE4_2__ + if (endp - p >= 16) { + __m128i ranges; + __m128i input; + int avail; + int match_len; + + /* Load input */ + input = _mm_loadu_si128((__m128i const*) p); + ranges = _mm_loadu_si128((__m128i const*) llparse_blob8); + + /* Find first character that does not match `ranges` */ + match_len = _mm_cmpestri(ranges, 16, + input, 16, + _SIDD_UBYTE_OPS | _SIDD_CMP_RANGES | + _SIDD_NEGATIVE_POLARITY); + + if (match_len != 0) { + p += match_len; + goto s_n_llhttp__internal__n_header_field_general; + } + ranges = _mm_loadu_si128((__m128i const*) llparse_blob9); + + /* Find first character that does not match `ranges` */ + match_len = _mm_cmpestri(ranges, 2, + input, 16, + _SIDD_UBYTE_OPS | _SIDD_CMP_RANGES | + _SIDD_NEGATIVE_POLARITY); + + if (match_len != 0) { + p += match_len; + goto s_n_llhttp__internal__n_header_field_general; + } + goto s_n_llhttp__internal__n_header_field_general_otherwise; + } + #endif /* __SSE4_2__ */ + switch (lookup_table[(uint8_t) *p]) { + case 1: { + p++; + goto s_n_llhttp__internal__n_header_field_general; + } + default: { + goto s_n_llhttp__internal__n_header_field_general_otherwise; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_header_field_colon: + s_n_llhttp__internal__n_header_field_colon: { + if (p == endp) { + return s_n_llhttp__internal__n_header_field_colon; + } + switch (*p) { + case ' ': { + goto s_n_llhttp__internal__n_invoke_test_lenient_flags_3; + } + case ':': { + goto s_n_llhttp__internal__n_span_end_llhttp__on_header_field_1; + } + default: { + goto s_n_llhttp__internal__n_invoke_update_header_state_10; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_header_field_3: + s_n_llhttp__internal__n_header_field_3: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_header_field_3; + } + match_seq = llparse__match_sequence_to_lower(state, p, endp, llparse_blob2, 6); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 1; + goto s_n_llhttp__internal__n_invoke_store_header_state; + } + case kMatchPause: { + return s_n_llhttp__internal__n_header_field_3; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_invoke_update_header_state_11; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_header_field_4: + s_n_llhttp__internal__n_header_field_4: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_header_field_4; + } + match_seq = llparse__match_sequence_to_lower(state, p, endp, llparse_blob10, 10); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 2; + goto s_n_llhttp__internal__n_invoke_store_header_state; + } + case kMatchPause: { + return s_n_llhttp__internal__n_header_field_4; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_invoke_update_header_state_11; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_header_field_2: + s_n_llhttp__internal__n_header_field_2: { + if (p == endp) { + return s_n_llhttp__internal__n_header_field_2; + } + switch (((*p) >= 'A' && (*p) <= 'Z' ? (*p | 0x20) : (*p))) { + case 'n': { + p++; + goto s_n_llhttp__internal__n_header_field_3; + } + case 't': { + p++; + goto s_n_llhttp__internal__n_header_field_4; + } + default: { + goto s_n_llhttp__internal__n_invoke_update_header_state_11; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_header_field_1: + s_n_llhttp__internal__n_header_field_1: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_header_field_1; + } + match_seq = llparse__match_sequence_to_lower(state, p, endp, llparse_blob1, 2); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + goto s_n_llhttp__internal__n_header_field_2; + } + case kMatchPause: { + return s_n_llhttp__internal__n_header_field_1; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_invoke_update_header_state_11; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_header_field_5: + s_n_llhttp__internal__n_header_field_5: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_header_field_5; + } + match_seq = llparse__match_sequence_to_lower(state, p, endp, llparse_blob11, 15); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 1; + goto s_n_llhttp__internal__n_invoke_store_header_state; + } + case kMatchPause: { + return s_n_llhttp__internal__n_header_field_5; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_invoke_update_header_state_11; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_header_field_6: + s_n_llhttp__internal__n_header_field_6: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_header_field_6; + } + match_seq = llparse__match_sequence_to_lower(state, p, endp, llparse_blob12, 16); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 3; + goto s_n_llhttp__internal__n_invoke_store_header_state; + } + case kMatchPause: { + return s_n_llhttp__internal__n_header_field_6; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_invoke_update_header_state_11; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_header_field_7: + s_n_llhttp__internal__n_header_field_7: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_header_field_7; + } + match_seq = llparse__match_sequence_to_lower(state, p, endp, llparse_blob13, 6); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 4; + goto s_n_llhttp__internal__n_invoke_store_header_state; + } + case kMatchPause: { + return s_n_llhttp__internal__n_header_field_7; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_invoke_update_header_state_11; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_header_field: + s_n_llhttp__internal__n_header_field: { + if (p == endp) { + return s_n_llhttp__internal__n_header_field; + } + switch (((*p) >= 'A' && (*p) <= 'Z' ? (*p | 0x20) : (*p))) { + case 'c': { + p++; + goto s_n_llhttp__internal__n_header_field_1; + } + case 'p': { + p++; + goto s_n_llhttp__internal__n_header_field_5; + } + case 't': { + p++; + goto s_n_llhttp__internal__n_header_field_6; + } + case 'u': { + p++; + goto s_n_llhttp__internal__n_header_field_7; + } + default: { + goto s_n_llhttp__internal__n_invoke_update_header_state_11; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_span_start_llhttp__on_header_field: + s_n_llhttp__internal__n_span_start_llhttp__on_header_field: { + if (p == endp) { + return s_n_llhttp__internal__n_span_start_llhttp__on_header_field; + } + state->_span_pos0 = (void*) p; + state->_span_cb0 = llhttp__on_header_field; + goto s_n_llhttp__internal__n_header_field; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_header_field_start: + s_n_llhttp__internal__n_header_field_start: { + if (p == endp) { + return s_n_llhttp__internal__n_header_field_start; + } + switch (*p) { + case 10: { + goto s_n_llhttp__internal__n_headers_almost_done; + } + case 13: { + p++; + goto s_n_llhttp__internal__n_headers_almost_done; + } + default: { + goto s_n_llhttp__internal__n_span_start_llhttp__on_header_field; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_headers_start: + s_n_llhttp__internal__n_headers_start: { + if (p == endp) { + return s_n_llhttp__internal__n_headers_start; + } + switch (*p) { + case ' ': { + p++; + goto s_n_llhttp__internal__n_invoke_test_lenient_flags; + } + default: { + goto s_n_llhttp__internal__n_header_field_start; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_url_to_http_09: + s_n_llhttp__internal__n_url_to_http_09: { + if (p == endp) { + return s_n_llhttp__internal__n_url_to_http_09; + } + switch (*p) { + case 9: { + p++; + goto s_n_llhttp__internal__n_error_2; + } + case 12: { + p++; + goto s_n_llhttp__internal__n_error_2; + } + default: { + goto s_n_llhttp__internal__n_invoke_update_http_major; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_url_skip_to_http09: + s_n_llhttp__internal__n_url_skip_to_http09: { + if (p == endp) { + return s_n_llhttp__internal__n_url_skip_to_http09; + } + switch (*p) { + case 9: { + p++; + goto s_n_llhttp__internal__n_error_2; + } + case 12: { + p++; + goto s_n_llhttp__internal__n_error_2; + } + default: { + p++; + goto s_n_llhttp__internal__n_url_to_http_09; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_url_skip_lf_to_http09_1: + s_n_llhttp__internal__n_url_skip_lf_to_http09_1: { + if (p == endp) { + return s_n_llhttp__internal__n_url_skip_lf_to_http09_1; + } + switch (*p) { + case 10: { + p++; + goto s_n_llhttp__internal__n_url_to_http_09; + } + default: { + goto s_n_llhttp__internal__n_error_47; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_url_skip_lf_to_http09: + s_n_llhttp__internal__n_url_skip_lf_to_http09: { + if (p == endp) { + return s_n_llhttp__internal__n_url_skip_lf_to_http09; + } + switch (*p) { + case 9: { + p++; + goto s_n_llhttp__internal__n_error_2; + } + case 12: { + p++; + goto s_n_llhttp__internal__n_error_2; + } + case 13: { + p++; + goto s_n_llhttp__internal__n_url_skip_lf_to_http09_1; + } + default: { + goto s_n_llhttp__internal__n_error_47; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_req_pri_upgrade: + s_n_llhttp__internal__n_req_pri_upgrade: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_req_pri_upgrade; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob15, 10); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + goto s_n_llhttp__internal__n_error_53; + } + case kMatchPause: { + return s_n_llhttp__internal__n_req_pri_upgrade; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_54; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_req_http_complete_1: + s_n_llhttp__internal__n_req_http_complete_1: { + if (p == endp) { + return s_n_llhttp__internal__n_req_http_complete_1; + } + switch (*p) { + case 10: { + p++; + goto s_n_llhttp__internal__n_headers_start; + } + default: { + goto s_n_llhttp__internal__n_error_52; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_req_http_complete: + s_n_llhttp__internal__n_req_http_complete: { + if (p == endp) { + return s_n_llhttp__internal__n_req_http_complete; + } + switch (*p) { + case 10: { + p++; + goto s_n_llhttp__internal__n_headers_start; + } + case 13: { + p++; + goto s_n_llhttp__internal__n_req_http_complete_1; + } + default: { + goto s_n_llhttp__internal__n_error_52; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_invoke_load_method_1: + s_n_llhttp__internal__n_invoke_load_method_1: { + switch (llhttp__internal__c_load_method(state, p, endp)) { + case 34: + goto s_n_llhttp__internal__n_req_pri_upgrade; + default: + goto s_n_llhttp__internal__n_req_http_complete; + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_invoke_llhttp__on_version_complete: + s_n_llhttp__internal__n_invoke_llhttp__on_version_complete: { + switch (llhttp__on_version_complete(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_invoke_load_method_1; + case 21: + goto s_n_llhttp__internal__n_pause_17; + default: + goto s_n_llhttp__internal__n_error_51; + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_error_50: + s_n_llhttp__internal__n_error_50: { + state->error = 0x9; + state->reason = "Invalid HTTP version"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_error_55: + s_n_llhttp__internal__n_error_55: { + state->error = 0x9; + state->reason = "Invalid minor version"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_req_http_minor: + s_n_llhttp__internal__n_req_http_minor: { + if (p == endp) { + return s_n_llhttp__internal__n_req_http_minor; + } + switch (*p) { + case '0': { + p++; + match = 0; + goto s_n_llhttp__internal__n_invoke_store_http_minor; + } + case '1': { + p++; + match = 1; + goto s_n_llhttp__internal__n_invoke_store_http_minor; + } + case '2': { + p++; + match = 2; + goto s_n_llhttp__internal__n_invoke_store_http_minor; + } + case '3': { + p++; + match = 3; + goto s_n_llhttp__internal__n_invoke_store_http_minor; + } + case '4': { + p++; + match = 4; + goto s_n_llhttp__internal__n_invoke_store_http_minor; + } + case '5': { + p++; + match = 5; + goto s_n_llhttp__internal__n_invoke_store_http_minor; + } + case '6': { + p++; + match = 6; + goto s_n_llhttp__internal__n_invoke_store_http_minor; + } + case '7': { + p++; + match = 7; + goto s_n_llhttp__internal__n_invoke_store_http_minor; + } + case '8': { + p++; + match = 8; + goto s_n_llhttp__internal__n_invoke_store_http_minor; + } + case '9': { + p++; + match = 9; + goto s_n_llhttp__internal__n_invoke_store_http_minor; + } + default: { + goto s_n_llhttp__internal__n_span_end_llhttp__on_version_2; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_error_56: + s_n_llhttp__internal__n_error_56: { + state->error = 0x9; + state->reason = "Expected dot"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_req_http_dot: + s_n_llhttp__internal__n_req_http_dot: { + if (p == endp) { + return s_n_llhttp__internal__n_req_http_dot; + } + switch (*p) { + case '.': { + p++; + goto s_n_llhttp__internal__n_req_http_minor; + } + default: { + goto s_n_llhttp__internal__n_span_end_llhttp__on_version_3; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_error_57: + s_n_llhttp__internal__n_error_57: { + state->error = 0x9; + state->reason = "Invalid major version"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_req_http_major: + s_n_llhttp__internal__n_req_http_major: { + if (p == endp) { + return s_n_llhttp__internal__n_req_http_major; + } + switch (*p) { + case '0': { + p++; + match = 0; + goto s_n_llhttp__internal__n_invoke_store_http_major; + } + case '1': { + p++; + match = 1; + goto s_n_llhttp__internal__n_invoke_store_http_major; + } + case '2': { + p++; + match = 2; + goto s_n_llhttp__internal__n_invoke_store_http_major; + } + case '3': { + p++; + match = 3; + goto s_n_llhttp__internal__n_invoke_store_http_major; + } + case '4': { + p++; + match = 4; + goto s_n_llhttp__internal__n_invoke_store_http_major; + } + case '5': { + p++; + match = 5; + goto s_n_llhttp__internal__n_invoke_store_http_major; + } + case '6': { + p++; + match = 6; + goto s_n_llhttp__internal__n_invoke_store_http_major; + } + case '7': { + p++; + match = 7; + goto s_n_llhttp__internal__n_invoke_store_http_major; + } + case '8': { + p++; + match = 8; + goto s_n_llhttp__internal__n_invoke_store_http_major; + } + case '9': { + p++; + match = 9; + goto s_n_llhttp__internal__n_invoke_store_http_major; + } + default: { + goto s_n_llhttp__internal__n_span_end_llhttp__on_version_4; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_span_start_llhttp__on_version: + s_n_llhttp__internal__n_span_start_llhttp__on_version: { + if (p == endp) { + return s_n_llhttp__internal__n_span_start_llhttp__on_version; + } + state->_span_pos0 = (void*) p; + state->_span_cb0 = llhttp__on_version; + goto s_n_llhttp__internal__n_req_http_major; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_req_http_start_1: + s_n_llhttp__internal__n_req_http_start_1: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_req_http_start_1; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob14, 4); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + goto s_n_llhttp__internal__n_invoke_load_method; + } + case kMatchPause: { + return s_n_llhttp__internal__n_req_http_start_1; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_60; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_req_http_start_2: + s_n_llhttp__internal__n_req_http_start_2: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_req_http_start_2; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob16, 3); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + goto s_n_llhttp__internal__n_invoke_load_method_2; + } + case kMatchPause: { + return s_n_llhttp__internal__n_req_http_start_2; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_60; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_req_http_start_3: + s_n_llhttp__internal__n_req_http_start_3: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_req_http_start_3; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob17, 4); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + goto s_n_llhttp__internal__n_invoke_load_method_3; + } + case kMatchPause: { + return s_n_llhttp__internal__n_req_http_start_3; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_60; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_req_http_start: + s_n_llhttp__internal__n_req_http_start: { + if (p == endp) { + return s_n_llhttp__internal__n_req_http_start; + } + switch (*p) { + case ' ': { + p++; + goto s_n_llhttp__internal__n_req_http_start; + } + case 'H': { + p++; + goto s_n_llhttp__internal__n_req_http_start_1; + } + case 'I': { + p++; + goto s_n_llhttp__internal__n_req_http_start_2; + } + case 'R': { + p++; + goto s_n_llhttp__internal__n_req_http_start_3; + } + default: { + goto s_n_llhttp__internal__n_error_60; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_url_to_http: + s_n_llhttp__internal__n_url_to_http: { + if (p == endp) { + return s_n_llhttp__internal__n_url_to_http; + } + switch (*p) { + case 9: { + p++; + goto s_n_llhttp__internal__n_error_2; + } + case 12: { + p++; + goto s_n_llhttp__internal__n_error_2; + } + default: { + goto s_n_llhttp__internal__n_invoke_llhttp__on_url_complete_1; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_url_skip_to_http: + s_n_llhttp__internal__n_url_skip_to_http: { + if (p == endp) { + return s_n_llhttp__internal__n_url_skip_to_http; + } + switch (*p) { + case 9: { + p++; + goto s_n_llhttp__internal__n_error_2; + } + case 12: { + p++; + goto s_n_llhttp__internal__n_error_2; + } + default: { + p++; + goto s_n_llhttp__internal__n_url_to_http; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_url_fragment: + s_n_llhttp__internal__n_url_fragment: { + static uint8_t lookup_table[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 1, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + if (p == endp) { + return s_n_llhttp__internal__n_url_fragment; + } + switch (lookup_table[(uint8_t) *p]) { + case 1: { + p++; + goto s_n_llhttp__internal__n_error_2; + } + case 2: { + goto s_n_llhttp__internal__n_span_end_llhttp__on_url_6; + } + case 3: { + goto s_n_llhttp__internal__n_span_end_llhttp__on_url_7; + } + case 4: { + goto s_n_llhttp__internal__n_span_end_llhttp__on_url_8; + } + case 5: { + p++; + goto s_n_llhttp__internal__n_url_fragment; + } + default: { + goto s_n_llhttp__internal__n_error_61; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_span_end_stub_query_3: + s_n_llhttp__internal__n_span_end_stub_query_3: { + if (p == endp) { + return s_n_llhttp__internal__n_span_end_stub_query_3; + } + p++; + goto s_n_llhttp__internal__n_url_fragment; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_url_query: + s_n_llhttp__internal__n_url_query: { + static uint8_t lookup_table[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 1, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 4, 5, 5, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + if (p == endp) { + return s_n_llhttp__internal__n_url_query; + } + switch (lookup_table[(uint8_t) *p]) { + case 1: { + p++; + goto s_n_llhttp__internal__n_error_2; + } + case 2: { + goto s_n_llhttp__internal__n_span_end_llhttp__on_url_9; + } + case 3: { + goto s_n_llhttp__internal__n_span_end_llhttp__on_url_10; + } + case 4: { + goto s_n_llhttp__internal__n_span_end_llhttp__on_url_11; + } + case 5: { + p++; + goto s_n_llhttp__internal__n_url_query; + } + case 6: { + goto s_n_llhttp__internal__n_span_end_stub_query_3; + } + default: { + goto s_n_llhttp__internal__n_error_62; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_url_query_or_fragment: + s_n_llhttp__internal__n_url_query_or_fragment: { + if (p == endp) { + return s_n_llhttp__internal__n_url_query_or_fragment; + } + switch (*p) { + case 9: { + p++; + goto s_n_llhttp__internal__n_error_2; + } + case 10: { + goto s_n_llhttp__internal__n_span_end_llhttp__on_url_3; + } + case 12: { + p++; + goto s_n_llhttp__internal__n_error_2; + } + case 13: { + goto s_n_llhttp__internal__n_span_end_llhttp__on_url_4; + } + case ' ': { + goto s_n_llhttp__internal__n_span_end_llhttp__on_url_5; + } + case '#': { + p++; + goto s_n_llhttp__internal__n_url_fragment; + } + case '?': { + p++; + goto s_n_llhttp__internal__n_url_query; + } + default: { + goto s_n_llhttp__internal__n_error_63; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_url_path: + s_n_llhttp__internal__n_url_path: { + static uint8_t lookup_table[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + if (p == endp) { + return s_n_llhttp__internal__n_url_path; + } + switch (lookup_table[(uint8_t) *p]) { + case 1: { + p++; + goto s_n_llhttp__internal__n_error_2; + } + case 2: { + p++; + goto s_n_llhttp__internal__n_url_path; + } + default: { + goto s_n_llhttp__internal__n_url_query_or_fragment; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_span_start_stub_path_2: + s_n_llhttp__internal__n_span_start_stub_path_2: { + if (p == endp) { + return s_n_llhttp__internal__n_span_start_stub_path_2; + } + p++; + goto s_n_llhttp__internal__n_url_path; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_span_start_stub_path: + s_n_llhttp__internal__n_span_start_stub_path: { + if (p == endp) { + return s_n_llhttp__internal__n_span_start_stub_path; + } + p++; + goto s_n_llhttp__internal__n_url_path; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_span_start_stub_path_1: + s_n_llhttp__internal__n_span_start_stub_path_1: { + if (p == endp) { + return s_n_llhttp__internal__n_span_start_stub_path_1; + } + p++; + goto s_n_llhttp__internal__n_url_path; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_url_server_with_at: + s_n_llhttp__internal__n_url_server_with_at: { + static uint8_t lookup_table[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 1, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 4, 5, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 0, 7, + 8, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 0, 5, + 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 5, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + if (p == endp) { + return s_n_llhttp__internal__n_url_server_with_at; + } + switch (lookup_table[(uint8_t) *p]) { + case 1: { + p++; + goto s_n_llhttp__internal__n_error_2; + } + case 2: { + goto s_n_llhttp__internal__n_span_end_llhttp__on_url_12; + } + case 3: { + goto s_n_llhttp__internal__n_span_end_llhttp__on_url_13; + } + case 4: { + goto s_n_llhttp__internal__n_span_end_llhttp__on_url_14; + } + case 5: { + p++; + goto s_n_llhttp__internal__n_url_server; + } + case 6: { + goto s_n_llhttp__internal__n_span_start_stub_path_1; + } + case 7: { + p++; + goto s_n_llhttp__internal__n_url_query; + } + case 8: { + p++; + goto s_n_llhttp__internal__n_error_64; + } + default: { + goto s_n_llhttp__internal__n_error_65; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_url_server: + s_n_llhttp__internal__n_url_server: { + static uint8_t lookup_table[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 1, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 4, 5, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 0, 7, + 8, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 0, 5, + 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 5, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + if (p == endp) { + return s_n_llhttp__internal__n_url_server; + } + switch (lookup_table[(uint8_t) *p]) { + case 1: { + p++; + goto s_n_llhttp__internal__n_error_2; + } + case 2: { + goto s_n_llhttp__internal__n_span_end_llhttp__on_url; + } + case 3: { + goto s_n_llhttp__internal__n_span_end_llhttp__on_url_1; + } + case 4: { + goto s_n_llhttp__internal__n_span_end_llhttp__on_url_2; + } + case 5: { + p++; + goto s_n_llhttp__internal__n_url_server; + } + case 6: { + goto s_n_llhttp__internal__n_span_start_stub_path; + } + case 7: { + p++; + goto s_n_llhttp__internal__n_url_query; + } + case 8: { + p++; + goto s_n_llhttp__internal__n_url_server_with_at; + } + default: { + goto s_n_llhttp__internal__n_error_66; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_url_schema_delim_1: + s_n_llhttp__internal__n_url_schema_delim_1: { + if (p == endp) { + return s_n_llhttp__internal__n_url_schema_delim_1; + } + switch (*p) { + case '/': { + p++; + goto s_n_llhttp__internal__n_url_server; + } + default: { + goto s_n_llhttp__internal__n_error_68; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_url_schema_delim: + s_n_llhttp__internal__n_url_schema_delim: { + if (p == endp) { + return s_n_llhttp__internal__n_url_schema_delim; + } + switch (*p) { + case 9: { + p++; + goto s_n_llhttp__internal__n_error_2; + } + case 10: { + p++; + goto s_n_llhttp__internal__n_error_67; + } + case 12: { + p++; + goto s_n_llhttp__internal__n_error_2; + } + case 13: { + p++; + goto s_n_llhttp__internal__n_error_67; + } + case ' ': { + p++; + goto s_n_llhttp__internal__n_error_67; + } + case '/': { + p++; + goto s_n_llhttp__internal__n_url_schema_delim_1; + } + default: { + goto s_n_llhttp__internal__n_error_68; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_span_end_stub_schema: + s_n_llhttp__internal__n_span_end_stub_schema: { + if (p == endp) { + return s_n_llhttp__internal__n_span_end_stub_schema; + } + p++; + goto s_n_llhttp__internal__n_url_schema_delim; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_url_schema: + s_n_llhttp__internal__n_url_schema: { + static uint8_t lookup_table[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 1, 2, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, + 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, + 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + if (p == endp) { + return s_n_llhttp__internal__n_url_schema; + } + switch (lookup_table[(uint8_t) *p]) { + case 1: { + p++; + goto s_n_llhttp__internal__n_error_2; + } + case 2: { + p++; + goto s_n_llhttp__internal__n_error_67; + } + case 3: { + goto s_n_llhttp__internal__n_span_end_stub_schema; + } + case 4: { + p++; + goto s_n_llhttp__internal__n_url_schema; + } + default: { + goto s_n_llhttp__internal__n_error_69; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_url_start: + s_n_llhttp__internal__n_url_start: { + static uint8_t lookup_table[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 1, 2, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 3, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, + 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + if (p == endp) { + return s_n_llhttp__internal__n_url_start; + } + switch (lookup_table[(uint8_t) *p]) { + case 1: { + p++; + goto s_n_llhttp__internal__n_error_2; + } + case 2: { + p++; + goto s_n_llhttp__internal__n_error_67; + } + case 3: { + goto s_n_llhttp__internal__n_span_start_stub_path_2; + } + case 4: { + goto s_n_llhttp__internal__n_url_schema; + } + default: { + goto s_n_llhttp__internal__n_error_70; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_span_start_llhttp__on_url_1: + s_n_llhttp__internal__n_span_start_llhttp__on_url_1: { + if (p == endp) { + return s_n_llhttp__internal__n_span_start_llhttp__on_url_1; + } + state->_span_pos0 = (void*) p; + state->_span_cb0 = llhttp__on_url; + goto s_n_llhttp__internal__n_url_start; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_url_entry_normal: + s_n_llhttp__internal__n_url_entry_normal: { + if (p == endp) { + return s_n_llhttp__internal__n_url_entry_normal; + } + switch (*p) { + case 9: { + p++; + goto s_n_llhttp__internal__n_error_2; + } + case 12: { + p++; + goto s_n_llhttp__internal__n_error_2; + } + default: { + goto s_n_llhttp__internal__n_span_start_llhttp__on_url_1; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_span_start_llhttp__on_url: + s_n_llhttp__internal__n_span_start_llhttp__on_url: { + if (p == endp) { + return s_n_llhttp__internal__n_span_start_llhttp__on_url; + } + state->_span_pos0 = (void*) p; + state->_span_cb0 = llhttp__on_url; + goto s_n_llhttp__internal__n_url_server; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_url_entry_connect: + s_n_llhttp__internal__n_url_entry_connect: { + if (p == endp) { + return s_n_llhttp__internal__n_url_entry_connect; + } + switch (*p) { + case 9: { + p++; + goto s_n_llhttp__internal__n_error_2; + } + case 12: { + p++; + goto s_n_llhttp__internal__n_error_2; + } + default: { + goto s_n_llhttp__internal__n_span_start_llhttp__on_url; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_req_spaces_before_url: + s_n_llhttp__internal__n_req_spaces_before_url: { + if (p == endp) { + return s_n_llhttp__internal__n_req_spaces_before_url; + } + switch (*p) { + case ' ': { + p++; + goto s_n_llhttp__internal__n_req_spaces_before_url; + } + default: { + goto s_n_llhttp__internal__n_invoke_is_equal_method; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_req_first_space_before_url: + s_n_llhttp__internal__n_req_first_space_before_url: { + if (p == endp) { + return s_n_llhttp__internal__n_req_first_space_before_url; + } + switch (*p) { + case ' ': { + p++; + goto s_n_llhttp__internal__n_req_spaces_before_url; + } + default: { + goto s_n_llhttp__internal__n_error_71; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_invoke_llhttp__on_method_complete_1: + s_n_llhttp__internal__n_invoke_llhttp__on_method_complete_1: { + switch (llhttp__on_method_complete(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_req_first_space_before_url; + case 21: + goto s_n_llhttp__internal__n_pause_22; + default: + goto s_n_llhttp__internal__n_error_83; + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_2: + s_n_llhttp__internal__n_after_start_req_2: { + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_2; + } + switch (*p) { + case 'L': { + p++; + match = 19; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + default: { + goto s_n_llhttp__internal__n_error_84; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_3: + s_n_llhttp__internal__n_after_start_req_3: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_3; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob18, 6); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 36; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_3; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_84; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_1: + s_n_llhttp__internal__n_after_start_req_1: { + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_1; + } + switch (*p) { + case 'C': { + p++; + goto s_n_llhttp__internal__n_after_start_req_2; + } + case 'N': { + p++; + goto s_n_llhttp__internal__n_after_start_req_3; + } + default: { + goto s_n_llhttp__internal__n_error_84; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_4: + s_n_llhttp__internal__n_after_start_req_4: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_4; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob19, 3); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 16; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_4; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_84; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_6: + s_n_llhttp__internal__n_after_start_req_6: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_6; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob20, 6); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 22; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_6; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_84; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_8: + s_n_llhttp__internal__n_after_start_req_8: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_8; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob21, 4); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 5; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_8; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_84; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_9: + s_n_llhttp__internal__n_after_start_req_9: { + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_9; + } + switch (*p) { + case 'Y': { + p++; + match = 8; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + default: { + goto s_n_llhttp__internal__n_error_84; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_7: + s_n_llhttp__internal__n_after_start_req_7: { + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_7; + } + switch (*p) { + case 'N': { + p++; + goto s_n_llhttp__internal__n_after_start_req_8; + } + case 'P': { + p++; + goto s_n_llhttp__internal__n_after_start_req_9; + } + default: { + goto s_n_llhttp__internal__n_error_84; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_5: + s_n_llhttp__internal__n_after_start_req_5: { + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_5; + } + switch (*p) { + case 'H': { + p++; + goto s_n_llhttp__internal__n_after_start_req_6; + } + case 'O': { + p++; + goto s_n_llhttp__internal__n_after_start_req_7; + } + default: { + goto s_n_llhttp__internal__n_error_84; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_12: + s_n_llhttp__internal__n_after_start_req_12: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_12; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob22, 3); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 0; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_12; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_84; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_13: + s_n_llhttp__internal__n_after_start_req_13: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_13; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob23, 5); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 35; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_13; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_84; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_11: + s_n_llhttp__internal__n_after_start_req_11: { + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_11; + } + switch (*p) { + case 'L': { + p++; + goto s_n_llhttp__internal__n_after_start_req_12; + } + case 'S': { + p++; + goto s_n_llhttp__internal__n_after_start_req_13; + } + default: { + goto s_n_llhttp__internal__n_error_84; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_10: + s_n_llhttp__internal__n_after_start_req_10: { + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_10; + } + switch (*p) { + case 'E': { + p++; + goto s_n_llhttp__internal__n_after_start_req_11; + } + default: { + goto s_n_llhttp__internal__n_error_84; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_14: + s_n_llhttp__internal__n_after_start_req_14: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_14; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob24, 4); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 45; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_14; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_84; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_17: + s_n_llhttp__internal__n_after_start_req_17: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_17; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob26, 9); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 41; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_17; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_84; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_16: + s_n_llhttp__internal__n_after_start_req_16: { + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_16; + } + switch (*p) { + case '_': { + p++; + goto s_n_llhttp__internal__n_after_start_req_17; + } + default: { + match = 1; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_15: + s_n_llhttp__internal__n_after_start_req_15: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_15; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob25, 2); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + goto s_n_llhttp__internal__n_after_start_req_16; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_15; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_84; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_18: + s_n_llhttp__internal__n_after_start_req_18: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_18; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob27, 3); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 2; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_18; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_84; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_20: + s_n_llhttp__internal__n_after_start_req_20: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_20; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob28, 2); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 31; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_20; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_84; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_21: + s_n_llhttp__internal__n_after_start_req_21: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_21; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob29, 2); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 9; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_21; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_84; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_19: + s_n_llhttp__internal__n_after_start_req_19: { + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_19; + } + switch (*p) { + case 'I': { + p++; + goto s_n_llhttp__internal__n_after_start_req_20; + } + case 'O': { + p++; + goto s_n_llhttp__internal__n_after_start_req_21; + } + default: { + goto s_n_llhttp__internal__n_error_84; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_23: + s_n_llhttp__internal__n_after_start_req_23: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_23; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob30, 6); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 24; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_23; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_84; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_24: + s_n_llhttp__internal__n_after_start_req_24: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_24; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob31, 3); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 23; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_24; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_84; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_26: + s_n_llhttp__internal__n_after_start_req_26: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_26; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob32, 7); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 21; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_26; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_84; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_28: + s_n_llhttp__internal__n_after_start_req_28: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_28; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob33, 6); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 30; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_28; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_84; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_29: + s_n_llhttp__internal__n_after_start_req_29: { + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_29; + } + switch (*p) { + case 'L': { + p++; + match = 10; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + default: { + goto s_n_llhttp__internal__n_error_84; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_27: + s_n_llhttp__internal__n_after_start_req_27: { + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_27; + } + switch (*p) { + case 'A': { + p++; + goto s_n_llhttp__internal__n_after_start_req_28; + } + case 'O': { + p++; + goto s_n_llhttp__internal__n_after_start_req_29; + } + default: { + goto s_n_llhttp__internal__n_error_84; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_25: + s_n_llhttp__internal__n_after_start_req_25: { + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_25; + } + switch (*p) { + case 'A': { + p++; + goto s_n_llhttp__internal__n_after_start_req_26; + } + case 'C': { + p++; + goto s_n_llhttp__internal__n_after_start_req_27; + } + default: { + goto s_n_llhttp__internal__n_error_84; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_30: + s_n_llhttp__internal__n_after_start_req_30: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_30; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob34, 2); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 11; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_30; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_84; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_22: + s_n_llhttp__internal__n_after_start_req_22: { + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_22; + } + switch (*p) { + case '-': { + p++; + goto s_n_llhttp__internal__n_after_start_req_23; + } + case 'E': { + p++; + goto s_n_llhttp__internal__n_after_start_req_24; + } + case 'K': { + p++; + goto s_n_llhttp__internal__n_after_start_req_25; + } + case 'O': { + p++; + goto s_n_llhttp__internal__n_after_start_req_30; + } + default: { + goto s_n_llhttp__internal__n_error_84; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_31: + s_n_llhttp__internal__n_after_start_req_31: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_31; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob35, 5); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 25; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_31; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_84; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_32: + s_n_llhttp__internal__n_after_start_req_32: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_32; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob36, 6); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 6; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_32; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_84; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_35: + s_n_llhttp__internal__n_after_start_req_35: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_35; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob37, 2); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 28; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_35; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_84; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_36: + s_n_llhttp__internal__n_after_start_req_36: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_36; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob38, 2); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 39; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_36; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_84; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_34: + s_n_llhttp__internal__n_after_start_req_34: { + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_34; + } + switch (*p) { + case 'T': { + p++; + goto s_n_llhttp__internal__n_after_start_req_35; + } + case 'U': { + p++; + goto s_n_llhttp__internal__n_after_start_req_36; + } + default: { + goto s_n_llhttp__internal__n_error_84; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_37: + s_n_llhttp__internal__n_after_start_req_37: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_37; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob39, 2); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 38; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_37; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_84; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_38: + s_n_llhttp__internal__n_after_start_req_38: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_38; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob40, 2); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 3; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_38; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_84; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_42: + s_n_llhttp__internal__n_after_start_req_42: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_42; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob41, 3); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 12; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_42; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_84; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_43: + s_n_llhttp__internal__n_after_start_req_43: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_43; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob42, 4); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 13; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_43; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_84; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_41: + s_n_llhttp__internal__n_after_start_req_41: { + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_41; + } + switch (*p) { + case 'F': { + p++; + goto s_n_llhttp__internal__n_after_start_req_42; + } + case 'P': { + p++; + goto s_n_llhttp__internal__n_after_start_req_43; + } + default: { + goto s_n_llhttp__internal__n_error_84; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_40: + s_n_llhttp__internal__n_after_start_req_40: { + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_40; + } + switch (*p) { + case 'P': { + p++; + goto s_n_llhttp__internal__n_after_start_req_41; + } + default: { + goto s_n_llhttp__internal__n_error_84; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_39: + s_n_llhttp__internal__n_after_start_req_39: { + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_39; + } + switch (*p) { + case 'I': { + p++; + match = 34; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case 'O': { + p++; + goto s_n_llhttp__internal__n_after_start_req_40; + } + default: { + goto s_n_llhttp__internal__n_error_84; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_45: + s_n_llhttp__internal__n_after_start_req_45: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_45; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob43, 2); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 29; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_45; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_84; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_44: + s_n_llhttp__internal__n_after_start_req_44: { + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_44; + } + switch (*p) { + case 'R': { + p++; + goto s_n_llhttp__internal__n_after_start_req_45; + } + case 'T': { + p++; + match = 4; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + default: { + goto s_n_llhttp__internal__n_error_84; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_33: + s_n_llhttp__internal__n_after_start_req_33: { + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_33; + } + switch (*p) { + case 'A': { + p++; + goto s_n_llhttp__internal__n_after_start_req_34; + } + case 'L': { + p++; + goto s_n_llhttp__internal__n_after_start_req_37; + } + case 'O': { + p++; + goto s_n_llhttp__internal__n_after_start_req_38; + } + case 'R': { + p++; + goto s_n_llhttp__internal__n_after_start_req_39; + } + case 'U': { + p++; + goto s_n_llhttp__internal__n_after_start_req_44; + } + default: { + goto s_n_llhttp__internal__n_error_84; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_48: + s_n_llhttp__internal__n_after_start_req_48: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_48; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob44, 3); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 17; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_48; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_84; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_49: + s_n_llhttp__internal__n_after_start_req_49: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_49; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob45, 3); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 44; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_49; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_84; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_50: + s_n_llhttp__internal__n_after_start_req_50: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_50; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob46, 5); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 43; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_50; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_84; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_51: + s_n_llhttp__internal__n_after_start_req_51: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_51; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob47, 3); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 20; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_51; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_84; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_47: + s_n_llhttp__internal__n_after_start_req_47: { + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_47; + } + switch (*p) { + case 'B': { + p++; + goto s_n_llhttp__internal__n_after_start_req_48; + } + case 'C': { + p++; + goto s_n_llhttp__internal__n_after_start_req_49; + } + case 'D': { + p++; + goto s_n_llhttp__internal__n_after_start_req_50; + } + case 'P': { + p++; + goto s_n_llhttp__internal__n_after_start_req_51; + } + default: { + goto s_n_llhttp__internal__n_error_84; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_46: + s_n_llhttp__internal__n_after_start_req_46: { + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_46; + } + switch (*p) { + case 'E': { + p++; + goto s_n_llhttp__internal__n_after_start_req_47; + } + default: { + goto s_n_llhttp__internal__n_error_84; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_54: + s_n_llhttp__internal__n_after_start_req_54: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_54; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob48, 3); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 14; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_54; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_84; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_56: + s_n_llhttp__internal__n_after_start_req_56: { + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_56; + } + switch (*p) { + case 'P': { + p++; + match = 37; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + default: { + goto s_n_llhttp__internal__n_error_84; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_57: + s_n_llhttp__internal__n_after_start_req_57: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_57; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob49, 9); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 42; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_57; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_84; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_55: + s_n_llhttp__internal__n_after_start_req_55: { + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_55; + } + switch (*p) { + case 'U': { + p++; + goto s_n_llhttp__internal__n_after_start_req_56; + } + case '_': { + p++; + goto s_n_llhttp__internal__n_after_start_req_57; + } + default: { + goto s_n_llhttp__internal__n_error_84; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_53: + s_n_llhttp__internal__n_after_start_req_53: { + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_53; + } + switch (*p) { + case 'A': { + p++; + goto s_n_llhttp__internal__n_after_start_req_54; + } + case 'T': { + p++; + goto s_n_llhttp__internal__n_after_start_req_55; + } + default: { + goto s_n_llhttp__internal__n_error_84; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_58: + s_n_llhttp__internal__n_after_start_req_58: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_58; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob50, 4); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 33; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_58; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_84; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_59: + s_n_llhttp__internal__n_after_start_req_59: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_59; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob51, 7); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 26; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_59; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_84; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_52: + s_n_llhttp__internal__n_after_start_req_52: { + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_52; + } + switch (*p) { + case 'E': { + p++; + goto s_n_llhttp__internal__n_after_start_req_53; + } + case 'O': { + p++; + goto s_n_llhttp__internal__n_after_start_req_58; + } + case 'U': { + p++; + goto s_n_llhttp__internal__n_after_start_req_59; + } + default: { + goto s_n_llhttp__internal__n_error_84; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_61: + s_n_llhttp__internal__n_after_start_req_61: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_61; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob52, 6); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 40; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_61; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_84; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_62: + s_n_llhttp__internal__n_after_start_req_62: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_62; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob53, 3); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 7; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_62; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_84; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_60: + s_n_llhttp__internal__n_after_start_req_60: { + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_60; + } + switch (*p) { + case 'E': { + p++; + goto s_n_llhttp__internal__n_after_start_req_61; + } + case 'R': { + p++; + goto s_n_llhttp__internal__n_after_start_req_62; + } + default: { + goto s_n_llhttp__internal__n_error_84; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_65: + s_n_llhttp__internal__n_after_start_req_65: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_65; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob54, 3); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 18; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_65; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_84; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_67: + s_n_llhttp__internal__n_after_start_req_67: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_67; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob55, 2); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 32; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_67; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_84; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_68: + s_n_llhttp__internal__n_after_start_req_68: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_68; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob56, 2); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 15; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_68; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_84; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_66: + s_n_llhttp__internal__n_after_start_req_66: { + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_66; + } + switch (*p) { + case 'I': { + p++; + goto s_n_llhttp__internal__n_after_start_req_67; + } + case 'O': { + p++; + goto s_n_llhttp__internal__n_after_start_req_68; + } + default: { + goto s_n_llhttp__internal__n_error_84; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_69: + s_n_llhttp__internal__n_after_start_req_69: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_69; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob57, 8); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 27; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_69; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_84; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_64: + s_n_llhttp__internal__n_after_start_req_64: { + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_64; + } + switch (*p) { + case 'B': { + p++; + goto s_n_llhttp__internal__n_after_start_req_65; + } + case 'L': { + p++; + goto s_n_llhttp__internal__n_after_start_req_66; + } + case 'S': { + p++; + goto s_n_llhttp__internal__n_after_start_req_69; + } + default: { + goto s_n_llhttp__internal__n_error_84; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_63: + s_n_llhttp__internal__n_after_start_req_63: { + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_63; + } + switch (*p) { + case 'N': { + p++; + goto s_n_llhttp__internal__n_after_start_req_64; + } + default: { + goto s_n_llhttp__internal__n_error_84; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req: + s_n_llhttp__internal__n_after_start_req: { + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req; + } + switch (*p) { + case 'A': { + p++; + goto s_n_llhttp__internal__n_after_start_req_1; + } + case 'B': { + p++; + goto s_n_llhttp__internal__n_after_start_req_4; + } + case 'C': { + p++; + goto s_n_llhttp__internal__n_after_start_req_5; + } + case 'D': { + p++; + goto s_n_llhttp__internal__n_after_start_req_10; + } + case 'F': { + p++; + goto s_n_llhttp__internal__n_after_start_req_14; + } + case 'G': { + p++; + goto s_n_llhttp__internal__n_after_start_req_15; + } + case 'H': { + p++; + goto s_n_llhttp__internal__n_after_start_req_18; + } + case 'L': { + p++; + goto s_n_llhttp__internal__n_after_start_req_19; + } + case 'M': { + p++; + goto s_n_llhttp__internal__n_after_start_req_22; + } + case 'N': { + p++; + goto s_n_llhttp__internal__n_after_start_req_31; + } + case 'O': { + p++; + goto s_n_llhttp__internal__n_after_start_req_32; + } + case 'P': { + p++; + goto s_n_llhttp__internal__n_after_start_req_33; + } + case 'R': { + p++; + goto s_n_llhttp__internal__n_after_start_req_46; + } + case 'S': { + p++; + goto s_n_llhttp__internal__n_after_start_req_52; + } + case 'T': { + p++; + goto s_n_llhttp__internal__n_after_start_req_60; + } + case 'U': { + p++; + goto s_n_llhttp__internal__n_after_start_req_63; + } + default: { + goto s_n_llhttp__internal__n_error_84; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_span_start_llhttp__on_method_1: + s_n_llhttp__internal__n_span_start_llhttp__on_method_1: { + if (p == endp) { + return s_n_llhttp__internal__n_span_start_llhttp__on_method_1; + } + state->_span_pos0 = (void*) p; + state->_span_cb0 = llhttp__on_method; + goto s_n_llhttp__internal__n_after_start_req; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_invoke_llhttp__on_status_complete: + s_n_llhttp__internal__n_invoke_llhttp__on_status_complete: { + switch (llhttp__on_status_complete(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_headers_start; + case 21: + goto s_n_llhttp__internal__n_pause_20; + default: + goto s_n_llhttp__internal__n_error_75; + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_res_line_almost_done: + s_n_llhttp__internal__n_res_line_almost_done: { + if (p == endp) { + return s_n_llhttp__internal__n_res_line_almost_done; + } + switch (*p) { + case 10: { + p++; + goto s_n_llhttp__internal__n_invoke_llhttp__on_status_complete; + } + default: { + goto s_n_llhttp__internal__n_error_76; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_res_status: + s_n_llhttp__internal__n_res_status: { + if (p == endp) { + return s_n_llhttp__internal__n_res_status; + } + switch (*p) { + case 10: { + goto s_n_llhttp__internal__n_span_end_llhttp__on_status; + } + case 13: { + goto s_n_llhttp__internal__n_span_end_llhttp__on_status_1; + } + default: { + p++; + goto s_n_llhttp__internal__n_res_status; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_span_start_llhttp__on_status: + s_n_llhttp__internal__n_span_start_llhttp__on_status: { + if (p == endp) { + return s_n_llhttp__internal__n_span_start_llhttp__on_status; + } + state->_span_pos0 = (void*) p; + state->_span_cb0 = llhttp__on_status; + goto s_n_llhttp__internal__n_res_status; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_res_status_start: + s_n_llhttp__internal__n_res_status_start: { + if (p == endp) { + return s_n_llhttp__internal__n_res_status_start; + } + switch (*p) { + case 10: { + p++; + goto s_n_llhttp__internal__n_invoke_llhttp__on_status_complete; + } + case 13: { + p++; + goto s_n_llhttp__internal__n_res_line_almost_done; + } + default: { + goto s_n_llhttp__internal__n_span_start_llhttp__on_status; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_res_status_code_otherwise: + s_n_llhttp__internal__n_res_status_code_otherwise: { + if (p == endp) { + return s_n_llhttp__internal__n_res_status_code_otherwise; + } + switch (*p) { + case 10: { + goto s_n_llhttp__internal__n_res_status_start; + } + case 13: { + goto s_n_llhttp__internal__n_res_status_start; + } + case ' ': { + p++; + goto s_n_llhttp__internal__n_res_status_start; + } + default: { + goto s_n_llhttp__internal__n_error_77; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_res_status_code: + s_n_llhttp__internal__n_res_status_code: { + if (p == endp) { + return s_n_llhttp__internal__n_res_status_code; + } + switch (*p) { + case '0': { + p++; + match = 0; + goto s_n_llhttp__internal__n_invoke_mul_add_status_code; + } + case '1': { + p++; + match = 1; + goto s_n_llhttp__internal__n_invoke_mul_add_status_code; + } + case '2': { + p++; + match = 2; + goto s_n_llhttp__internal__n_invoke_mul_add_status_code; + } + case '3': { + p++; + match = 3; + goto s_n_llhttp__internal__n_invoke_mul_add_status_code; + } + case '4': { + p++; + match = 4; + goto s_n_llhttp__internal__n_invoke_mul_add_status_code; + } + case '5': { + p++; + match = 5; + goto s_n_llhttp__internal__n_invoke_mul_add_status_code; + } + case '6': { + p++; + match = 6; + goto s_n_llhttp__internal__n_invoke_mul_add_status_code; + } + case '7': { + p++; + match = 7; + goto s_n_llhttp__internal__n_invoke_mul_add_status_code; + } + case '8': { + p++; + match = 8; + goto s_n_llhttp__internal__n_invoke_mul_add_status_code; + } + case '9': { + p++; + match = 9; + goto s_n_llhttp__internal__n_invoke_mul_add_status_code; + } + default: { + goto s_n_llhttp__internal__n_res_status_code_otherwise; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_res_after_version: + s_n_llhttp__internal__n_res_after_version: { + if (p == endp) { + return s_n_llhttp__internal__n_res_after_version; + } + switch (*p) { + case ' ': { + p++; + goto s_n_llhttp__internal__n_invoke_update_status_code; + } + default: { + goto s_n_llhttp__internal__n_error_78; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_invoke_llhttp__on_version_complete_1: + s_n_llhttp__internal__n_invoke_llhttp__on_version_complete_1: { + switch (llhttp__on_version_complete(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_res_after_version; + case 21: + goto s_n_llhttp__internal__n_pause_21; + default: + goto s_n_llhttp__internal__n_error_73; + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_error_72: + s_n_llhttp__internal__n_error_72: { + state->error = 0x9; + state->reason = "Invalid HTTP version"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_error_79: + s_n_llhttp__internal__n_error_79: { + state->error = 0x9; + state->reason = "Invalid minor version"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_res_http_minor: + s_n_llhttp__internal__n_res_http_minor: { + if (p == endp) { + return s_n_llhttp__internal__n_res_http_minor; + } + switch (*p) { + case '0': { + p++; + match = 0; + goto s_n_llhttp__internal__n_invoke_store_http_minor_1; + } + case '1': { + p++; + match = 1; + goto s_n_llhttp__internal__n_invoke_store_http_minor_1; + } + case '2': { + p++; + match = 2; + goto s_n_llhttp__internal__n_invoke_store_http_minor_1; + } + case '3': { + p++; + match = 3; + goto s_n_llhttp__internal__n_invoke_store_http_minor_1; + } + case '4': { + p++; + match = 4; + goto s_n_llhttp__internal__n_invoke_store_http_minor_1; + } + case '5': { + p++; + match = 5; + goto s_n_llhttp__internal__n_invoke_store_http_minor_1; + } + case '6': { + p++; + match = 6; + goto s_n_llhttp__internal__n_invoke_store_http_minor_1; + } + case '7': { + p++; + match = 7; + goto s_n_llhttp__internal__n_invoke_store_http_minor_1; + } + case '8': { + p++; + match = 8; + goto s_n_llhttp__internal__n_invoke_store_http_minor_1; + } + case '9': { + p++; + match = 9; + goto s_n_llhttp__internal__n_invoke_store_http_minor_1; + } + default: { + goto s_n_llhttp__internal__n_span_end_llhttp__on_version_7; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_error_80: + s_n_llhttp__internal__n_error_80: { + state->error = 0x9; + state->reason = "Expected dot"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_res_http_dot: + s_n_llhttp__internal__n_res_http_dot: { + if (p == endp) { + return s_n_llhttp__internal__n_res_http_dot; + } + switch (*p) { + case '.': { + p++; + goto s_n_llhttp__internal__n_res_http_minor; + } + default: { + goto s_n_llhttp__internal__n_span_end_llhttp__on_version_8; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_error_81: + s_n_llhttp__internal__n_error_81: { + state->error = 0x9; + state->reason = "Invalid major version"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_res_http_major: + s_n_llhttp__internal__n_res_http_major: { + if (p == endp) { + return s_n_llhttp__internal__n_res_http_major; + } + switch (*p) { + case '0': { + p++; + match = 0; + goto s_n_llhttp__internal__n_invoke_store_http_major_1; + } + case '1': { + p++; + match = 1; + goto s_n_llhttp__internal__n_invoke_store_http_major_1; + } + case '2': { + p++; + match = 2; + goto s_n_llhttp__internal__n_invoke_store_http_major_1; + } + case '3': { + p++; + match = 3; + goto s_n_llhttp__internal__n_invoke_store_http_major_1; + } + case '4': { + p++; + match = 4; + goto s_n_llhttp__internal__n_invoke_store_http_major_1; + } + case '5': { + p++; + match = 5; + goto s_n_llhttp__internal__n_invoke_store_http_major_1; + } + case '6': { + p++; + match = 6; + goto s_n_llhttp__internal__n_invoke_store_http_major_1; + } + case '7': { + p++; + match = 7; + goto s_n_llhttp__internal__n_invoke_store_http_major_1; + } + case '8': { + p++; + match = 8; + goto s_n_llhttp__internal__n_invoke_store_http_major_1; + } + case '9': { + p++; + match = 9; + goto s_n_llhttp__internal__n_invoke_store_http_major_1; + } + default: { + goto s_n_llhttp__internal__n_span_end_llhttp__on_version_9; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_span_start_llhttp__on_version_1: + s_n_llhttp__internal__n_span_start_llhttp__on_version_1: { + if (p == endp) { + return s_n_llhttp__internal__n_span_start_llhttp__on_version_1; + } + state->_span_pos0 = (void*) p; + state->_span_cb0 = llhttp__on_version; + goto s_n_llhttp__internal__n_res_http_major; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_start_res: + s_n_llhttp__internal__n_start_res: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_start_res; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob58, 5); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + goto s_n_llhttp__internal__n_span_start_llhttp__on_version_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_start_res; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_85; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_invoke_llhttp__on_method_complete: + s_n_llhttp__internal__n_invoke_llhttp__on_method_complete: { + switch (llhttp__on_method_complete(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_req_first_space_before_url; + case 21: + goto s_n_llhttp__internal__n_pause_19; + default: + goto s_n_llhttp__internal__n_error_1; + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_req_or_res_method_2: + s_n_llhttp__internal__n_req_or_res_method_2: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_req_or_res_method_2; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob59, 2); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 2; + goto s_n_llhttp__internal__n_invoke_store_method; + } + case kMatchPause: { + return s_n_llhttp__internal__n_req_or_res_method_2; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_82; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_invoke_update_type_1: + s_n_llhttp__internal__n_invoke_update_type_1: { + switch (llhttp__internal__c_update_type_1(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version_1; + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_req_or_res_method_3: + s_n_llhttp__internal__n_req_or_res_method_3: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_req_or_res_method_3; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob60, 3); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + goto s_n_llhttp__internal__n_span_end_llhttp__on_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_req_or_res_method_3; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_82; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_req_or_res_method_1: + s_n_llhttp__internal__n_req_or_res_method_1: { + if (p == endp) { + return s_n_llhttp__internal__n_req_or_res_method_1; + } + switch (*p) { + case 'E': { + p++; + goto s_n_llhttp__internal__n_req_or_res_method_2; + } + case 'T': { + p++; + goto s_n_llhttp__internal__n_req_or_res_method_3; + } + default: { + goto s_n_llhttp__internal__n_error_82; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_req_or_res_method: + s_n_llhttp__internal__n_req_or_res_method: { + if (p == endp) { + return s_n_llhttp__internal__n_req_or_res_method; + } + switch (*p) { + case 'H': { + p++; + goto s_n_llhttp__internal__n_req_or_res_method_1; + } + default: { + goto s_n_llhttp__internal__n_error_82; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_span_start_llhttp__on_method: + s_n_llhttp__internal__n_span_start_llhttp__on_method: { + if (p == endp) { + return s_n_llhttp__internal__n_span_start_llhttp__on_method; + } + state->_span_pos0 = (void*) p; + state->_span_cb0 = llhttp__on_method; + goto s_n_llhttp__internal__n_req_or_res_method; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_start_req_or_res: + s_n_llhttp__internal__n_start_req_or_res: { + if (p == endp) { + return s_n_llhttp__internal__n_start_req_or_res; + } + switch (*p) { + case 'H': { + goto s_n_llhttp__internal__n_span_start_llhttp__on_method; + } + default: { + goto s_n_llhttp__internal__n_invoke_update_type_2; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_invoke_load_type: + s_n_llhttp__internal__n_invoke_load_type: { + switch (llhttp__internal__c_load_type(state, p, endp)) { + case 1: + goto s_n_llhttp__internal__n_span_start_llhttp__on_method_1; + case 2: + goto s_n_llhttp__internal__n_start_res; + default: + goto s_n_llhttp__internal__n_start_req_or_res; + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_invoke_update_finish: + s_n_llhttp__internal__n_invoke_update_finish: { + switch (llhttp__internal__c_update_finish(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_invoke_llhttp__on_message_begin; + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_start: + s_n_llhttp__internal__n_start: { + if (p == endp) { + return s_n_llhttp__internal__n_start; + } + switch (*p) { + case 10: { + p++; + goto s_n_llhttp__internal__n_start; + } + case 13: { + p++; + goto s_n_llhttp__internal__n_start; + } + default: { + goto s_n_llhttp__internal__n_invoke_load_initial_message_completed; + } + } + /* UNREACHABLE */; + abort(); + } + default: + /* UNREACHABLE */ + abort(); + } + s_n_llhttp__internal__n_error_2: { + state->error = 0x7; + state->reason = "Invalid characters in url (strict mode)"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_67: { + state->error = 0x7; + state->reason = "Invalid characters in url"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_update_finish_2: { + switch (llhttp__internal__c_update_finish_1(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_start; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_update_initial_message_completed: { + switch (llhttp__internal__c_update_initial_message_completed(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_invoke_update_finish_2; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_update_content_length: { + switch (llhttp__internal__c_update_content_length(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_invoke_update_initial_message_completed; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_7: { + state->error = 0x5; + state->reason = "Data after `Connection: close`"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_test_lenient_flags_1: { + switch (llhttp__internal__c_test_lenient_flags_1(state, p, endp)) { + case 1: + goto s_n_llhttp__internal__n_invoke_update_initial_message_completed; + default: + goto s_n_llhttp__internal__n_closed; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_update_finish_1: { + switch (llhttp__internal__c_update_finish_1(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_invoke_test_lenient_flags_1; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_pause_11: { + state->error = 0x15; + state->reason = "on_message_complete pause"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_is_equal_upgrade; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_28: { + state->error = 0x12; + state->reason = "`on_message_complete` callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_pause_13: { + state->error = 0x15; + state->reason = "on_chunk_complete pause"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_llhttp__on_message_complete_2; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_31: { + state->error = 0x14; + state->reason = "`on_chunk_complete` callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_llhttp__on_chunk_complete_1: { + switch (llhttp__on_chunk_complete(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_invoke_llhttp__on_message_complete_2; + case 21: + goto s_n_llhttp__internal__n_pause_13; + default: + goto s_n_llhttp__internal__n_error_31; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_30: { + state->error = 0x4; + state->reason = "Content-Length can't be present with Transfer-Encoding"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_pause_2: { + state->error = 0x15; + state->reason = "on_message_complete pause"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_pause_1; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_8: { + state->error = 0x12; + state->reason = "`on_message_complete` callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_llhttp__on_message_complete_1: { + switch (llhttp__on_message_complete(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_pause_1; + case 21: + goto s_n_llhttp__internal__n_pause_2; + default: + goto s_n_llhttp__internal__n_error_8; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_26: { + state->error = 0xc; + state->reason = "Chunk size overflow"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_pause_3: { + state->error = 0x15; + state->reason = "on_chunk_complete pause"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_update_content_length_1; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_10: { + state->error = 0x14; + state->reason = "`on_chunk_complete` callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_llhttp__on_chunk_complete: { + switch (llhttp__on_chunk_complete(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_invoke_update_content_length_1; + case 21: + goto s_n_llhttp__internal__n_pause_3; + default: + goto s_n_llhttp__internal__n_error_10; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_11: { + state->error = 0x2; + state->reason = "Expected CRLF after chunk"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_body: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_body(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_chunk_data_almost_done; + return s_error; + } + goto s_n_llhttp__internal__n_chunk_data_almost_done; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_or_flags: { + switch (llhttp__internal__c_or_flags(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_header_field_start; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_pause_4: { + state->error = 0x15; + state->reason = "on_chunk_header pause"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_is_equal_content_length; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_9: { + state->error = 0x13; + state->reason = "`on_chunk_header` callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_llhttp__on_chunk_header: { + switch (llhttp__on_chunk_header(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_invoke_is_equal_content_length; + case 21: + goto s_n_llhttp__internal__n_pause_4; + default: + goto s_n_llhttp__internal__n_error_9; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_12: { + state->error = 0x2; + state->reason = "Expected LF after chunk size"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_13: { + state->error = 0x2; + state->reason = "Invalid character in chunk extensions"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_14: { + state->error = 0x2; + state->reason = "Invalid character in chunk extensions"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_pause_5: { + state->error = 0x15; + state->reason = "on_chunk_extension_name pause"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_chunk_size_almost_done; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_15: { + state->error = 0x22; + state->reason = "`on_chunk_extension_name` callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_chunk_extension_name: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_chunk_extension_name(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) (p + 1); + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_name_complete; + return s_error; + } + p++; + goto s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_name_complete; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_pause_6: { + state->error = 0x15; + state->reason = "on_chunk_extension_name pause"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_chunk_extensions; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_16: { + state->error = 0x22; + state->reason = "`on_chunk_extension_name` callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_chunk_extension_name_1: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_chunk_extension_name(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) (p + 1); + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_name_complete_1; + return s_error; + } + p++; + goto s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_name_complete_1; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_pause_7: { + state->error = 0x15; + state->reason = "on_chunk_extension_value pause"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_chunk_size_almost_done; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_18: { + state->error = 0x23; + state->reason = "`on_chunk_extension_value` callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_chunk_extension_value: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_chunk_extension_value(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) (p + 1); + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_value_complete; + return s_error; + } + p++; + goto s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_value_complete; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_20: { + state->error = 0x2; + state->reason = "Invalid character in chunk extensions quote value"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_pause_8: { + state->error = 0x15; + state->reason = "on_chunk_extension_value pause"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_chunk_extension_quoted_value_done; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_19: { + state->error = 0x23; + state->reason = "`on_chunk_extension_value` callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_chunk_extension_value_1: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_chunk_extension_value(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_value_complete_1; + return s_error; + } + goto s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_value_complete_1; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_chunk_extension_value_2: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_chunk_extension_value(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) (p + 1); + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_error_21; + return s_error; + } + p++; + goto s_n_llhttp__internal__n_error_21; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_pause_9: { + state->error = 0x15; + state->reason = "on_chunk_extension_value pause"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_chunk_size_otherwise; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_22: { + state->error = 0x23; + state->reason = "`on_chunk_extension_value` callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_chunk_extension_value_3: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_chunk_extension_value(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) (p + 1); + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_value_complete_2; + return s_error; + } + p++; + goto s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_value_complete_2; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_chunk_extension_value_4: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_chunk_extension_value(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) (p + 1); + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_error_23; + return s_error; + } + p++; + goto s_n_llhttp__internal__n_error_23; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_pause_10: { + state->error = 0x15; + state->reason = "on_chunk_extension_name pause"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_chunk_extension_value; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_17: { + state->error = 0x22; + state->reason = "`on_chunk_extension_name` callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_name_complete_2: { + switch (llhttp__on_chunk_extension_name_complete(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_chunk_extension_value; + case 21: + goto s_n_llhttp__internal__n_pause_10; + default: + goto s_n_llhttp__internal__n_error_17; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_chunk_extension_name_2: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_chunk_extension_name(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) (p + 1); + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_span_start_llhttp__on_chunk_extension_value; + return s_error; + } + p++; + goto s_n_llhttp__internal__n_span_start_llhttp__on_chunk_extension_value; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_chunk_extension_name_3: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_chunk_extension_name(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) (p + 1); + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_error_24; + return s_error; + } + p++; + goto s_n_llhttp__internal__n_error_24; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_25: { + state->error = 0xc; + state->reason = "Invalid character in chunk size"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_mul_add_content_length: { + switch (llhttp__internal__c_mul_add_content_length(state, p, endp, match)) { + case 1: + goto s_n_llhttp__internal__n_error_26; + default: + goto s_n_llhttp__internal__n_chunk_size; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_27: { + state->error = 0xc; + state->reason = "Invalid character in chunk size"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_body_1: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_body(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_llhttp__on_message_complete_2; + return s_error; + } + goto s_n_llhttp__internal__n_invoke_llhttp__on_message_complete_2; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_update_finish_3: { + switch (llhttp__internal__c_update_finish_3(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_span_start_llhttp__on_body_2; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_29: { + state->error = 0xf; + state->reason = "Request has invalid `Transfer-Encoding`"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_pause: { + state->error = 0x15; + state->reason = "on_message_complete pause"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_llhttp__after_message_complete; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_6: { + state->error = 0x12; + state->reason = "`on_message_complete` callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_llhttp__on_message_complete: { + switch (llhttp__on_message_complete(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_invoke_llhttp__after_message_complete; + case 21: + goto s_n_llhttp__internal__n_pause; + default: + goto s_n_llhttp__internal__n_error_6; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_or_flags_1: { + switch (llhttp__internal__c_or_flags_1(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_invoke_llhttp__after_headers_complete; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_or_flags_2: { + switch (llhttp__internal__c_or_flags_1(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_invoke_llhttp__after_headers_complete; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_update_upgrade: { + switch (llhttp__internal__c_update_upgrade(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_invoke_or_flags_2; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_pause_12: { + state->error = 0x15; + state->reason = "Paused by on_headers_complete"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_llhttp__after_headers_complete; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_5: { + state->error = 0x11; + state->reason = "User callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_llhttp__on_headers_complete: { + switch (llhttp__on_headers_complete(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_invoke_llhttp__after_headers_complete; + case 1: + goto s_n_llhttp__internal__n_invoke_or_flags_1; + case 2: + goto s_n_llhttp__internal__n_invoke_update_upgrade; + case 21: + goto s_n_llhttp__internal__n_pause_12; + default: + goto s_n_llhttp__internal__n_error_5; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_llhttp__before_headers_complete: { + switch (llhttp__before_headers_complete(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_invoke_llhttp__on_headers_complete; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_test_lenient_flags_2: { + switch (llhttp__internal__c_test_lenient_flags_2(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_error_30; + default: + goto s_n_llhttp__internal__n_invoke_llhttp__before_headers_complete; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_test_flags_1: { + switch (llhttp__internal__c_test_flags_1(state, p, endp)) { + case 1: + goto s_n_llhttp__internal__n_invoke_test_lenient_flags_2; + default: + goto s_n_llhttp__internal__n_invoke_llhttp__before_headers_complete; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_test_flags: { + switch (llhttp__internal__c_test_flags(state, p, endp)) { + case 1: + goto s_n_llhttp__internal__n_invoke_llhttp__on_chunk_complete_1; + default: + goto s_n_llhttp__internal__n_invoke_test_flags_1; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_32: { + state->error = 0x2; + state->reason = "Expected LF after headers"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_header_field: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_header_field(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) (p + 1); + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_error_33; + return s_error; + } + p++; + goto s_n_llhttp__internal__n_error_33; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_test_lenient_flags_3: { + switch (llhttp__internal__c_test_lenient_flags(state, p, endp)) { + case 1: + goto s_n_llhttp__internal__n_header_field_colon_discard_ws; + default: + goto s_n_llhttp__internal__n_span_end_llhttp__on_header_field; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_37: { + state->error = 0xb; + state->reason = "Empty Content-Length"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_pause_14: { + state->error = 0x15; + state->reason = "on_header_value_complete pause"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_header_field_start; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_36: { + state->error = 0x1d; + state->reason = "`on_header_value_complete` callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_header_value: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_header_value(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_llhttp__on_header_value_complete; + return s_error; + } + goto s_n_llhttp__internal__n_invoke_llhttp__on_header_value_complete; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_update_header_state: { + switch (llhttp__internal__c_update_header_state(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_span_start_llhttp__on_header_value; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_or_flags_3: { + switch (llhttp__internal__c_or_flags_3(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_invoke_update_header_state; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_or_flags_4: { + switch (llhttp__internal__c_or_flags_4(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_invoke_update_header_state; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_or_flags_5: { + switch (llhttp__internal__c_or_flags_5(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_invoke_update_header_state; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_or_flags_6: { + switch (llhttp__internal__c_or_flags_6(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_span_start_llhttp__on_header_value; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_load_header_state_1: { + switch (llhttp__internal__c_load_header_state(state, p, endp)) { + case 5: + goto s_n_llhttp__internal__n_invoke_or_flags_3; + case 6: + goto s_n_llhttp__internal__n_invoke_or_flags_4; + case 7: + goto s_n_llhttp__internal__n_invoke_or_flags_5; + case 8: + goto s_n_llhttp__internal__n_invoke_or_flags_6; + default: + goto s_n_llhttp__internal__n_span_start_llhttp__on_header_value; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_load_header_state: { + switch (llhttp__internal__c_load_header_state(state, p, endp)) { + case 2: + goto s_n_llhttp__internal__n_error_37; + default: + goto s_n_llhttp__internal__n_invoke_load_header_state_1; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_35: { + state->error = 0xa; + state->reason = "Invalid header value char"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_test_lenient_flags_4: { + switch (llhttp__internal__c_test_lenient_flags(state, p, endp)) { + case 1: + goto s_n_llhttp__internal__n_header_value_discard_lws; + default: + goto s_n_llhttp__internal__n_error_35; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_38: { + state->error = 0x2; + state->reason = "Expected LF after CR"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_update_header_state_1: { + switch (llhttp__internal__c_update_header_state_1(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_span_start_llhttp__on_header_value_1; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_load_header_state_3: { + switch (llhttp__internal__c_load_header_state(state, p, endp)) { + case 8: + goto s_n_llhttp__internal__n_invoke_update_header_state_1; + default: + goto s_n_llhttp__internal__n_span_start_llhttp__on_header_value_1; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_update_header_state_2: { + switch (llhttp__internal__c_update_header_state(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_invoke_llhttp__on_header_value_complete; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_or_flags_7: { + switch (llhttp__internal__c_or_flags_3(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_invoke_update_header_state_2; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_or_flags_8: { + switch (llhttp__internal__c_or_flags_4(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_invoke_update_header_state_2; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_or_flags_9: { + switch (llhttp__internal__c_or_flags_5(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_invoke_update_header_state_2; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_or_flags_10: { + switch (llhttp__internal__c_or_flags_6(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_invoke_llhttp__on_header_value_complete; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_load_header_state_4: { + switch (llhttp__internal__c_load_header_state(state, p, endp)) { + case 5: + goto s_n_llhttp__internal__n_invoke_or_flags_7; + case 6: + goto s_n_llhttp__internal__n_invoke_or_flags_8; + case 7: + goto s_n_llhttp__internal__n_invoke_or_flags_9; + case 8: + goto s_n_llhttp__internal__n_invoke_or_flags_10; + default: + goto s_n_llhttp__internal__n_invoke_llhttp__on_header_value_complete; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_39: { + state->error = 0x3; + state->reason = "Missing expected LF after header value"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_header_value_1: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_header_value(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) (p + 1); + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_header_value_almost_done; + return s_error; + } + p++; + goto s_n_llhttp__internal__n_header_value_almost_done; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_header_value_3: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_header_value(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_header_value_almost_done; + return s_error; + } + goto s_n_llhttp__internal__n_header_value_almost_done; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_header_value_4: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_header_value(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) (p + 1); + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_header_value_almost_done; + return s_error; + } + p++; + goto s_n_llhttp__internal__n_header_value_almost_done; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_header_value_2: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_header_value(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_error_40; + return s_error; + } + goto s_n_llhttp__internal__n_error_40; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_test_lenient_flags_5: { + switch (llhttp__internal__c_test_lenient_flags(state, p, endp)) { + case 1: + goto s_n_llhttp__internal__n_header_value_lenient; + default: + goto s_n_llhttp__internal__n_span_end_llhttp__on_header_value_2; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_update_header_state_4: { + switch (llhttp__internal__c_update_header_state(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_header_value_connection; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_or_flags_11: { + switch (llhttp__internal__c_or_flags_3(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_invoke_update_header_state_4; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_or_flags_12: { + switch (llhttp__internal__c_or_flags_4(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_invoke_update_header_state_4; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_or_flags_13: { + switch (llhttp__internal__c_or_flags_5(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_invoke_update_header_state_4; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_or_flags_14: { + switch (llhttp__internal__c_or_flags_6(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_header_value_connection; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_load_header_state_5: { + switch (llhttp__internal__c_load_header_state(state, p, endp)) { + case 5: + goto s_n_llhttp__internal__n_invoke_or_flags_11; + case 6: + goto s_n_llhttp__internal__n_invoke_or_flags_12; + case 7: + goto s_n_llhttp__internal__n_invoke_or_flags_13; + case 8: + goto s_n_llhttp__internal__n_invoke_or_flags_14; + default: + goto s_n_llhttp__internal__n_header_value_connection; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_update_header_state_5: { + switch (llhttp__internal__c_update_header_state_1(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_header_value_connection_token; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_update_header_state_3: { + switch (llhttp__internal__c_update_header_state_3(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_header_value_connection_ws; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_update_header_state_6: { + switch (llhttp__internal__c_update_header_state_6(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_header_value_connection_ws; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_update_header_state_7: { + switch (llhttp__internal__c_update_header_state_7(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_header_value_connection_ws; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_header_value_5: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_header_value(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_error_42; + return s_error; + } + goto s_n_llhttp__internal__n_error_42; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_mul_add_content_length_1: { + switch (llhttp__internal__c_mul_add_content_length_1(state, p, endp, match)) { + case 1: + goto s_n_llhttp__internal__n_span_end_llhttp__on_header_value_5; + default: + goto s_n_llhttp__internal__n_header_value_content_length; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_or_flags_15: { + switch (llhttp__internal__c_or_flags_15(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_header_value_otherwise; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_header_value_6: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_header_value(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_error_43; + return s_error; + } + goto s_n_llhttp__internal__n_error_43; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_41: { + state->error = 0x4; + state->reason = "Duplicate Content-Length"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_test_flags_2: { + switch (llhttp__internal__c_test_flags_2(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_header_value_content_length; + default: + goto s_n_llhttp__internal__n_error_41; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_header_value_8: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_header_value(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) (p + 1); + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_error_45; + return s_error; + } + p++; + goto s_n_llhttp__internal__n_error_45; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_update_header_state_8: { + switch (llhttp__internal__c_update_header_state_8(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_header_value_otherwise; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_header_value_7: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_header_value(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) (p + 1); + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_error_44; + return s_error; + } + p++; + goto s_n_llhttp__internal__n_error_44; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_test_lenient_flags_6: { + switch (llhttp__internal__c_test_lenient_flags_6(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_span_end_llhttp__on_header_value_7; + default: + goto s_n_llhttp__internal__n_header_value_te_chunked; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_load_type_1: { + switch (llhttp__internal__c_load_type(state, p, endp)) { + case 1: + goto s_n_llhttp__internal__n_invoke_test_lenient_flags_6; + default: + goto s_n_llhttp__internal__n_header_value_te_chunked; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_update_header_state_9: { + switch (llhttp__internal__c_update_header_state_1(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_header_value; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_and_flags: { + switch (llhttp__internal__c_and_flags(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_header_value_te_chunked; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_or_flags_17: { + switch (llhttp__internal__c_or_flags_16(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_invoke_and_flags; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_test_lenient_flags_7: { + switch (llhttp__internal__c_test_lenient_flags_6(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_span_end_llhttp__on_header_value_8; + default: + goto s_n_llhttp__internal__n_invoke_or_flags_17; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_load_type_2: { + switch (llhttp__internal__c_load_type(state, p, endp)) { + case 1: + goto s_n_llhttp__internal__n_invoke_test_lenient_flags_7; + default: + goto s_n_llhttp__internal__n_invoke_or_flags_17; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_or_flags_16: { + switch (llhttp__internal__c_or_flags_16(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_invoke_and_flags; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_test_flags_3: { + switch (llhttp__internal__c_test_flags_3(state, p, endp)) { + case 1: + goto s_n_llhttp__internal__n_invoke_load_type_2; + default: + goto s_n_llhttp__internal__n_invoke_or_flags_16; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_or_flags_18: { + switch (llhttp__internal__c_or_flags_18(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_invoke_update_header_state_9; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_load_header_state_2: { + switch (llhttp__internal__c_load_header_state(state, p, endp)) { + case 1: + goto s_n_llhttp__internal__n_header_value_connection; + case 2: + goto s_n_llhttp__internal__n_invoke_test_flags_2; + case 3: + goto s_n_llhttp__internal__n_invoke_test_flags_3; + case 4: + goto s_n_llhttp__internal__n_invoke_or_flags_18; + default: + goto s_n_llhttp__internal__n_header_value; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_pause_15: { + state->error = 0x15; + state->reason = "on_header_field_complete pause"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_header_value_discard_ws; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_34: { + state->error = 0x1c; + state->reason = "`on_header_field_complete` callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_header_field_1: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_header_field(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) (p + 1); + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_llhttp__on_header_field_complete; + return s_error; + } + p++; + goto s_n_llhttp__internal__n_invoke_llhttp__on_header_field_complete; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_header_field_2: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_header_field(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) (p + 1); + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_llhttp__on_header_field_complete; + return s_error; + } + p++; + goto s_n_llhttp__internal__n_invoke_llhttp__on_header_field_complete; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_46: { + state->error = 0xa; + state->reason = "Invalid header token"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_update_header_state_10: { + switch (llhttp__internal__c_update_header_state_1(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_header_field_general; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_store_header_state: { + switch (llhttp__internal__c_store_header_state(state, p, endp, match)) { + default: + goto s_n_llhttp__internal__n_header_field_colon; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_update_header_state_11: { + switch (llhttp__internal__c_update_header_state_1(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_header_field_general; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_4: { + state->error = 0x1e; + state->reason = "Unexpected space after start line"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_test_lenient_flags: { + switch (llhttp__internal__c_test_lenient_flags(state, p, endp)) { + case 1: + goto s_n_llhttp__internal__n_header_field_start; + default: + goto s_n_llhttp__internal__n_error_4; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_pause_16: { + state->error = 0x15; + state->reason = "on_url_complete pause"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_headers_start; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_3: { + state->error = 0x1a; + state->reason = "`on_url_complete` callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_llhttp__on_url_complete: { + switch (llhttp__on_url_complete(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_headers_start; + case 21: + goto s_n_llhttp__internal__n_pause_16; + default: + goto s_n_llhttp__internal__n_error_3; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_update_http_minor: { + switch (llhttp__internal__c_update_http_minor(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_invoke_llhttp__on_url_complete; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_update_http_major: { + switch (llhttp__internal__c_update_http_major(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_invoke_update_http_minor; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_url_3: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_url(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_url_skip_to_http09; + return s_error; + } + goto s_n_llhttp__internal__n_url_skip_to_http09; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_47: { + state->error = 0x7; + state->reason = "Expected CRLF"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_url_4: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_url(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_url_skip_lf_to_http09; + return s_error; + } + goto s_n_llhttp__internal__n_url_skip_lf_to_http09; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_53: { + state->error = 0x17; + state->reason = "Pause on PRI/Upgrade"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_54: { + state->error = 0x9; + state->reason = "Expected HTTP/2 Connection Preface"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_52: { + state->error = 0x9; + state->reason = "Expected CRLF after version"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_pause_17: { + state->error = 0x15; + state->reason = "on_version_complete pause"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_load_method_1; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_51: { + state->error = 0x21; + state->reason = "`on_version_complete` callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_version_1: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_version(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_llhttp__on_version_complete; + return s_error; + } + goto s_n_llhttp__internal__n_invoke_llhttp__on_version_complete; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_version: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_version(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_error_50; + return s_error; + } + goto s_n_llhttp__internal__n_error_50; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_load_http_minor: { + switch (llhttp__internal__c_load_http_minor(state, p, endp)) { + case 9: + goto s_n_llhttp__internal__n_span_end_llhttp__on_version_1; + default: + goto s_n_llhttp__internal__n_span_end_llhttp__on_version; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_load_http_minor_1: { + switch (llhttp__internal__c_load_http_minor(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_span_end_llhttp__on_version_1; + case 1: + goto s_n_llhttp__internal__n_span_end_llhttp__on_version_1; + default: + goto s_n_llhttp__internal__n_span_end_llhttp__on_version; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_load_http_minor_2: { + switch (llhttp__internal__c_load_http_minor(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_span_end_llhttp__on_version_1; + default: + goto s_n_llhttp__internal__n_span_end_llhttp__on_version; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_load_http_major: { + switch (llhttp__internal__c_load_http_major(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_invoke_load_http_minor; + case 1: + goto s_n_llhttp__internal__n_invoke_load_http_minor_1; + case 2: + goto s_n_llhttp__internal__n_invoke_load_http_minor_2; + default: + goto s_n_llhttp__internal__n_span_end_llhttp__on_version; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_test_lenient_flags_8: { + switch (llhttp__internal__c_test_lenient_flags_8(state, p, endp)) { + case 1: + goto s_n_llhttp__internal__n_span_end_llhttp__on_version_1; + default: + goto s_n_llhttp__internal__n_invoke_load_http_major; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_store_http_minor: { + switch (llhttp__internal__c_store_http_minor(state, p, endp, match)) { + default: + goto s_n_llhttp__internal__n_invoke_test_lenient_flags_8; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_version_2: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_version(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_error_55; + return s_error; + } + goto s_n_llhttp__internal__n_error_55; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_version_3: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_version(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_error_56; + return s_error; + } + goto s_n_llhttp__internal__n_error_56; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_store_http_major: { + switch (llhttp__internal__c_store_http_major(state, p, endp, match)) { + default: + goto s_n_llhttp__internal__n_req_http_dot; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_version_4: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_version(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_error_57; + return s_error; + } + goto s_n_llhttp__internal__n_error_57; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_49: { + state->error = 0x8; + state->reason = "Invalid method for HTTP/x.x request"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_load_method: { + switch (llhttp__internal__c_load_method(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 1: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 2: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 3: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 4: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 5: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 6: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 7: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 8: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 9: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 10: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 11: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 12: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 13: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 14: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 15: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 16: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 17: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 18: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 19: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 20: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 21: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 22: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 23: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 24: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 25: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 26: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 27: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 28: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 29: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 30: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 31: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 32: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 33: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 34: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + default: + goto s_n_llhttp__internal__n_error_49; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_60: { + state->error = 0x8; + state->reason = "Expected HTTP/"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_58: { + state->error = 0x8; + state->reason = "Expected SOURCE method for ICE/x.x request"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_load_method_2: { + switch (llhttp__internal__c_load_method(state, p, endp)) { + case 33: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + default: + goto s_n_llhttp__internal__n_error_58; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_59: { + state->error = 0x8; + state->reason = "Invalid method for RTSP/x.x request"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_load_method_3: { + switch (llhttp__internal__c_load_method(state, p, endp)) { + case 1: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 3: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 6: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 35: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 36: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 37: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 38: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 39: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 40: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 41: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 42: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 43: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 44: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 45: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + default: + goto s_n_llhttp__internal__n_error_59; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_pause_18: { + state->error = 0x15; + state->reason = "on_url_complete pause"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_req_http_start; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_48: { + state->error = 0x1a; + state->reason = "`on_url_complete` callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_llhttp__on_url_complete_1: { + switch (llhttp__on_url_complete(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_req_http_start; + case 21: + goto s_n_llhttp__internal__n_pause_18; + default: + goto s_n_llhttp__internal__n_error_48; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_url_5: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_url(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_url_skip_to_http; + return s_error; + } + goto s_n_llhttp__internal__n_url_skip_to_http; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_url_6: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_url(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_url_skip_to_http09; + return s_error; + } + goto s_n_llhttp__internal__n_url_skip_to_http09; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_url_7: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_url(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_url_skip_lf_to_http09; + return s_error; + } + goto s_n_llhttp__internal__n_url_skip_lf_to_http09; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_url_8: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_url(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_url_skip_to_http; + return s_error; + } + goto s_n_llhttp__internal__n_url_skip_to_http; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_61: { + state->error = 0x7; + state->reason = "Invalid char in url fragment start"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_url_9: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_url(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_url_skip_to_http09; + return s_error; + } + goto s_n_llhttp__internal__n_url_skip_to_http09; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_url_10: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_url(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_url_skip_lf_to_http09; + return s_error; + } + goto s_n_llhttp__internal__n_url_skip_lf_to_http09; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_url_11: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_url(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_url_skip_to_http; + return s_error; + } + goto s_n_llhttp__internal__n_url_skip_to_http; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_62: { + state->error = 0x7; + state->reason = "Invalid char in url query"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_63: { + state->error = 0x7; + state->reason = "Invalid char in url path"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_url: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_url(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_url_skip_to_http09; + return s_error; + } + goto s_n_llhttp__internal__n_url_skip_to_http09; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_url_1: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_url(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_url_skip_lf_to_http09; + return s_error; + } + goto s_n_llhttp__internal__n_url_skip_lf_to_http09; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_url_2: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_url(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_url_skip_to_http; + return s_error; + } + goto s_n_llhttp__internal__n_url_skip_to_http; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_url_12: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_url(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_url_skip_to_http09; + return s_error; + } + goto s_n_llhttp__internal__n_url_skip_to_http09; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_url_13: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_url(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_url_skip_lf_to_http09; + return s_error; + } + goto s_n_llhttp__internal__n_url_skip_lf_to_http09; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_url_14: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_url(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_url_skip_to_http; + return s_error; + } + goto s_n_llhttp__internal__n_url_skip_to_http; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_64: { + state->error = 0x7; + state->reason = "Double @ in url"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_65: { + state->error = 0x7; + state->reason = "Unexpected char in url server"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_66: { + state->error = 0x7; + state->reason = "Unexpected char in url server"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_68: { + state->error = 0x7; + state->reason = "Unexpected char in url schema"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_69: { + state->error = 0x7; + state->reason = "Unexpected char in url schema"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_70: { + state->error = 0x7; + state->reason = "Unexpected start char in url"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_is_equal_method: { + switch (llhttp__internal__c_is_equal_method(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_url_entry_normal; + default: + goto s_n_llhttp__internal__n_url_entry_connect; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_71: { + state->error = 0x6; + state->reason = "Expected space after method"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_pause_22: { + state->error = 0x15; + state->reason = "on_method_complete pause"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_req_first_space_before_url; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_83: { + state->error = 0x20; + state->reason = "`on_method_complete` callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_method_2: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_method(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_llhttp__on_method_complete_1; + return s_error; + } + goto s_n_llhttp__internal__n_invoke_llhttp__on_method_complete_1; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_store_method_1: { + switch (llhttp__internal__c_store_method(state, p, endp, match)) { + default: + goto s_n_llhttp__internal__n_span_end_llhttp__on_method_2; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_84: { + state->error = 0x6; + state->reason = "Invalid method encountered"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_74: { + state->error = 0xd; + state->reason = "Response overflow"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_mul_add_status_code: { + switch (llhttp__internal__c_mul_add_status_code(state, p, endp, match)) { + case 1: + goto s_n_llhttp__internal__n_error_74; + default: + goto s_n_llhttp__internal__n_res_status_code; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_pause_20: { + state->error = 0x15; + state->reason = "on_status_complete pause"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_headers_start; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_75: { + state->error = 0x1b; + state->reason = "`on_status_complete` callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_76: { + state->error = 0x2; + state->reason = "Expected LF after CR"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_status: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_status(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) (p + 1); + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_llhttp__on_status_complete; + return s_error; + } + p++; + goto s_n_llhttp__internal__n_invoke_llhttp__on_status_complete; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_status_1: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_status(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) (p + 1); + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_res_line_almost_done; + return s_error; + } + p++; + goto s_n_llhttp__internal__n_res_line_almost_done; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_77: { + state->error = 0xd; + state->reason = "Invalid response status"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_update_status_code: { + switch (llhttp__internal__c_update_status_code(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_res_status_code; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_78: { + state->error = 0x9; + state->reason = "Expected space after version"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_pause_21: { + state->error = 0x15; + state->reason = "on_version_complete pause"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_res_after_version; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_73: { + state->error = 0x21; + state->reason = "`on_version_complete` callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_version_6: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_version(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_llhttp__on_version_complete_1; + return s_error; + } + goto s_n_llhttp__internal__n_invoke_llhttp__on_version_complete_1; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_version_5: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_version(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_error_72; + return s_error; + } + goto s_n_llhttp__internal__n_error_72; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_load_http_minor_3: { + switch (llhttp__internal__c_load_http_minor(state, p, endp)) { + case 9: + goto s_n_llhttp__internal__n_span_end_llhttp__on_version_6; + default: + goto s_n_llhttp__internal__n_span_end_llhttp__on_version_5; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_load_http_minor_4: { + switch (llhttp__internal__c_load_http_minor(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_span_end_llhttp__on_version_6; + case 1: + goto s_n_llhttp__internal__n_span_end_llhttp__on_version_6; + default: + goto s_n_llhttp__internal__n_span_end_llhttp__on_version_5; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_load_http_minor_5: { + switch (llhttp__internal__c_load_http_minor(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_span_end_llhttp__on_version_6; + default: + goto s_n_llhttp__internal__n_span_end_llhttp__on_version_5; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_load_http_major_1: { + switch (llhttp__internal__c_load_http_major(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_invoke_load_http_minor_3; + case 1: + goto s_n_llhttp__internal__n_invoke_load_http_minor_4; + case 2: + goto s_n_llhttp__internal__n_invoke_load_http_minor_5; + default: + goto s_n_llhttp__internal__n_span_end_llhttp__on_version_5; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_test_lenient_flags_9: { + switch (llhttp__internal__c_test_lenient_flags_8(state, p, endp)) { + case 1: + goto s_n_llhttp__internal__n_span_end_llhttp__on_version_6; + default: + goto s_n_llhttp__internal__n_invoke_load_http_major_1; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_store_http_minor_1: { + switch (llhttp__internal__c_store_http_minor(state, p, endp, match)) { + default: + goto s_n_llhttp__internal__n_invoke_test_lenient_flags_9; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_version_7: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_version(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_error_79; + return s_error; + } + goto s_n_llhttp__internal__n_error_79; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_version_8: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_version(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_error_80; + return s_error; + } + goto s_n_llhttp__internal__n_error_80; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_store_http_major_1: { + switch (llhttp__internal__c_store_http_major(state, p, endp, match)) { + default: + goto s_n_llhttp__internal__n_res_http_dot; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_version_9: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_version(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_error_81; + return s_error; + } + goto s_n_llhttp__internal__n_error_81; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_85: { + state->error = 0x8; + state->reason = "Expected HTTP/"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_pause_19: { + state->error = 0x15; + state->reason = "on_method_complete pause"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_req_first_space_before_url; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_1: { + state->error = 0x20; + state->reason = "`on_method_complete` callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_method: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_method(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_llhttp__on_method_complete; + return s_error; + } + goto s_n_llhttp__internal__n_invoke_llhttp__on_method_complete; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_update_type: { + switch (llhttp__internal__c_update_type(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_span_end_llhttp__on_method; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_store_method: { + switch (llhttp__internal__c_store_method(state, p, endp, match)) { + default: + goto s_n_llhttp__internal__n_invoke_update_type; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_82: { + state->error = 0x8; + state->reason = "Invalid word encountered"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_method_1: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_method(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_update_type_1; + return s_error; + } + goto s_n_llhttp__internal__n_invoke_update_type_1; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_update_type_2: { + switch (llhttp__internal__c_update_type(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_span_start_llhttp__on_method_1; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_pause_23: { + state->error = 0x15; + state->reason = "on_message_begin pause"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_load_type; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error: { + state->error = 0x10; + state->reason = "`on_message_begin` callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_llhttp__on_message_begin: { + switch (llhttp__on_message_begin(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_invoke_load_type; + case 21: + goto s_n_llhttp__internal__n_pause_23; + default: + goto s_n_llhttp__internal__n_error; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_pause_24: { + state->error = 0x15; + state->reason = "on_reset pause"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_update_finish; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_86: { + state->error = 0x1f; + state->reason = "`on_reset` callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_llhttp__on_reset: { + switch (llhttp__on_reset(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_invoke_update_finish; + case 21: + goto s_n_llhttp__internal__n_pause_24; + default: + goto s_n_llhttp__internal__n_error_86; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_load_initial_message_completed: { + switch (llhttp__internal__c_load_initial_message_completed(state, p, endp)) { + case 1: + goto s_n_llhttp__internal__n_invoke_llhttp__on_reset; + default: + goto s_n_llhttp__internal__n_invoke_update_finish; + } + /* UNREACHABLE */; + abort(); + } +} + +int llhttp__internal_execute(llhttp__internal_t* state, const char* p, const char* endp) { + llparse_state_t next; + + /* check lingering errors */ + if (state->error != 0) { + return state->error; + } + + /* restart spans */ + if (state->_span_pos0 != NULL) { + state->_span_pos0 = (void*) p; + } + + next = llhttp__internal__run(state, (const unsigned char*) p, (const unsigned char*) endp); + if (next == s_error) { + return state->error; + } + state->_current = (void*) (intptr_t) next; + + /* execute spans */ + if (state->_span_pos0 != NULL) { + int error; + + error = ((llhttp__internal__span_cb) state->_span_cb0)(state, state->_span_pos0, (const char*) endp); + if (error != 0) { + state->error = error; + state->error_pos = endp; + return error; + } + } + + return 0; +} + +#else /* !LLHTTP_STRICT_MODE */ + +#include +#include +#include + +#ifdef __SSE4_2__ + #ifdef _MSC_VER + #include + #else /* !_MSC_VER */ + #include + #endif /* _MSC_VER */ +#endif /* __SSE4_2__ */ + +#ifdef _MSC_VER + #define ALIGN(n) _declspec(align(n)) +#else /* !_MSC_VER */ + #define ALIGN(n) __attribute__((aligned(n))) +#endif /* _MSC_VER */ + +#include "llhttp.h" + +typedef int (*llhttp__internal__span_cb)( + llhttp__internal_t*, const char*, const char*); + +#ifdef __SSE4_2__ +static const unsigned char ALIGN(16) llparse_blob0[] = { + 0x9, 0x9, 0xc, 0xc, '!', '"', '$', '>', '@', '~', 0x80, + 0xff, 0x0, 0x0, 0x0, 0x0 +}; +#endif /* __SSE4_2__ */ +static const unsigned char llparse_blob1[] = { + 'o', 'n' +}; +static const unsigned char llparse_blob2[] = { + 'e', 'c', 't', 'i', 'o', 'n' +}; +static const unsigned char llparse_blob3[] = { + 'l', 'o', 's', 'e' +}; +static const unsigned char llparse_blob4[] = { + 'e', 'e', 'p', '-', 'a', 'l', 'i', 'v', 'e' +}; +static const unsigned char llparse_blob5[] = { + 'p', 'g', 'r', 'a', 'd', 'e' +}; +static const unsigned char llparse_blob6[] = { + 'c', 'h', 'u', 'n', 'k', 'e', 'd' +}; +#ifdef __SSE4_2__ +static const unsigned char ALIGN(16) llparse_blob7[] = { + 0x9, 0x9, ' ', '~', 0x80, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0 +}; +#endif /* __SSE4_2__ */ +#ifdef __SSE4_2__ +static const unsigned char ALIGN(16) llparse_blob8[] = { + ' ', '!', '#', '\'', '*', '+', '-', '.', '0', '9', 'A', + 'Z', '^', 'z', '|', '|' +}; +#endif /* __SSE4_2__ */ +#ifdef __SSE4_2__ +static const unsigned char ALIGN(16) llparse_blob9[] = { + '~', '~', 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0 +}; +#endif /* __SSE4_2__ */ +static const unsigned char llparse_blob10[] = { + 'e', 'n', 't', '-', 'l', 'e', 'n', 'g', 't', 'h' +}; +static const unsigned char llparse_blob11[] = { + 'r', 'o', 'x', 'y', '-', 'c', 'o', 'n', 'n', 'e', 'c', + 't', 'i', 'o', 'n' +}; +static const unsigned char llparse_blob12[] = { + 'r', 'a', 'n', 's', 'f', 'e', 'r', '-', 'e', 'n', 'c', + 'o', 'd', 'i', 'n', 'g' +}; +static const unsigned char llparse_blob13[] = { + 'p', 'g', 'r', 'a', 'd', 'e' +}; +static const unsigned char llparse_blob14[] = { + 0xd, 0xa +}; +static const unsigned char llparse_blob15[] = { + 'T', 'T', 'P', '/' +}; +static const unsigned char llparse_blob16[] = { + 0xd, 0xa, 0xd, 0xa, 'S', 'M', 0xd, 0xa, 0xd, 0xa +}; +static const unsigned char llparse_blob17[] = { + 'C', 'E', '/' +}; +static const unsigned char llparse_blob18[] = { + 'T', 'S', 'P', '/' +}; +static const unsigned char llparse_blob19[] = { + 'N', 'O', 'U', 'N', 'C', 'E' +}; +static const unsigned char llparse_blob20[] = { + 'I', 'N', 'D' +}; +static const unsigned char llparse_blob21[] = { + 'E', 'C', 'K', 'O', 'U', 'T' +}; +static const unsigned char llparse_blob22[] = { + 'N', 'E', 'C', 'T' +}; +static const unsigned char llparse_blob23[] = { + 'E', 'T', 'E' +}; +static const unsigned char llparse_blob24[] = { + 'C', 'R', 'I', 'B', 'E' +}; +static const unsigned char llparse_blob25[] = { + 'L', 'U', 'S', 'H' +}; +static const unsigned char llparse_blob26[] = { + 'E', 'T' +}; +static const unsigned char llparse_blob27[] = { + 'P', 'A', 'R', 'A', 'M', 'E', 'T', 'E', 'R' +}; +static const unsigned char llparse_blob28[] = { + 'E', 'A', 'D' +}; +static const unsigned char llparse_blob29[] = { + 'N', 'K' +}; +static const unsigned char llparse_blob30[] = { + 'C', 'K' +}; +static const unsigned char llparse_blob31[] = { + 'S', 'E', 'A', 'R', 'C', 'H' +}; +static const unsigned char llparse_blob32[] = { + 'R', 'G', 'E' +}; +static const unsigned char llparse_blob33[] = { + 'C', 'T', 'I', 'V', 'I', 'T', 'Y' +}; +static const unsigned char llparse_blob34[] = { + 'L', 'E', 'N', 'D', 'A', 'R' +}; +static const unsigned char llparse_blob35[] = { + 'V', 'E' +}; +static const unsigned char llparse_blob36[] = { + 'O', 'T', 'I', 'F', 'Y' +}; +static const unsigned char llparse_blob37[] = { + 'P', 'T', 'I', 'O', 'N', 'S' +}; +static const unsigned char llparse_blob38[] = { + 'C', 'H' +}; +static const unsigned char llparse_blob39[] = { + 'S', 'E' +}; +static const unsigned char llparse_blob40[] = { + 'A', 'Y' +}; +static const unsigned char llparse_blob41[] = { + 'S', 'T' +}; +static const unsigned char llparse_blob42[] = { + 'I', 'N', 'D' +}; +static const unsigned char llparse_blob43[] = { + 'A', 'T', 'C', 'H' +}; +static const unsigned char llparse_blob44[] = { + 'G', 'E' +}; +static const unsigned char llparse_blob45[] = { + 'I', 'N', 'D' +}; +static const unsigned char llparse_blob46[] = { + 'O', 'R', 'D' +}; +static const unsigned char llparse_blob47[] = { + 'I', 'R', 'E', 'C', 'T' +}; +static const unsigned char llparse_blob48[] = { + 'O', 'R', 'T' +}; +static const unsigned char llparse_blob49[] = { + 'R', 'C', 'H' +}; +static const unsigned char llparse_blob50[] = { + 'P', 'A', 'R', 'A', 'M', 'E', 'T', 'E', 'R' +}; +static const unsigned char llparse_blob51[] = { + 'U', 'R', 'C', 'E' +}; +static const unsigned char llparse_blob52[] = { + 'B', 'S', 'C', 'R', 'I', 'B', 'E' +}; +static const unsigned char llparse_blob53[] = { + 'A', 'R', 'D', 'O', 'W', 'N' +}; +static const unsigned char llparse_blob54[] = { + 'A', 'C', 'E' +}; +static const unsigned char llparse_blob55[] = { + 'I', 'N', 'D' +}; +static const unsigned char llparse_blob56[] = { + 'N', 'K' +}; +static const unsigned char llparse_blob57[] = { + 'C', 'K' +}; +static const unsigned char llparse_blob58[] = { + 'U', 'B', 'S', 'C', 'R', 'I', 'B', 'E' +}; +static const unsigned char llparse_blob59[] = { + 'H', 'T', 'T', 'P', '/' +}; +static const unsigned char llparse_blob60[] = { + 'A', 'D' +}; +static const unsigned char llparse_blob61[] = { + 'T', 'P', '/' +}; + +enum llparse_match_status_e { + kMatchComplete, + kMatchPause, + kMatchMismatch +}; +typedef enum llparse_match_status_e llparse_match_status_t; + +struct llparse_match_s { + llparse_match_status_t status; + const unsigned char* current; +}; +typedef struct llparse_match_s llparse_match_t; + +static llparse_match_t llparse__match_sequence_to_lower( + llhttp__internal_t* s, const unsigned char* p, + const unsigned char* endp, + const unsigned char* seq, uint32_t seq_len) { + uint32_t index; + llparse_match_t res; + + index = s->_index; + for (; p != endp; p++) { + unsigned char current; + + current = ((*p) >= 'A' && (*p) <= 'Z' ? (*p | 0x20) : (*p)); + if (current == seq[index]) { + if (++index == seq_len) { + res.status = kMatchComplete; + goto reset; + } + } else { + res.status = kMatchMismatch; + goto reset; + } + } + s->_index = index; + res.status = kMatchPause; + res.current = p; + return res; +reset: + s->_index = 0; + res.current = p; + return res; +} + +static llparse_match_t llparse__match_sequence_to_lower_unsafe( + llhttp__internal_t* s, const unsigned char* p, + const unsigned char* endp, + const unsigned char* seq, uint32_t seq_len) { + uint32_t index; + llparse_match_t res; + + index = s->_index; + for (; p != endp; p++) { + unsigned char current; + + current = ((*p) | 0x20); + if (current == seq[index]) { + if (++index == seq_len) { + res.status = kMatchComplete; + goto reset; + } + } else { + res.status = kMatchMismatch; + goto reset; + } + } + s->_index = index; + res.status = kMatchPause; + res.current = p; + return res; +reset: + s->_index = 0; + res.current = p; + return res; +} + +static llparse_match_t llparse__match_sequence_id( + llhttp__internal_t* s, const unsigned char* p, + const unsigned char* endp, + const unsigned char* seq, uint32_t seq_len) { + uint32_t index; + llparse_match_t res; + + index = s->_index; + for (; p != endp; p++) { + unsigned char current; + + current = *p; + if (current == seq[index]) { + if (++index == seq_len) { + res.status = kMatchComplete; + goto reset; + } + } else { + res.status = kMatchMismatch; + goto reset; + } + } + s->_index = index; + res.status = kMatchPause; + res.current = p; + return res; +reset: + s->_index = 0; + res.current = p; + return res; +} + +enum llparse_state_e { + s_error, + s_n_llhttp__internal__n_closed, + s_n_llhttp__internal__n_invoke_llhttp__after_message_complete, + s_n_llhttp__internal__n_pause_1, + s_n_llhttp__internal__n_invoke_is_equal_upgrade, + s_n_llhttp__internal__n_invoke_llhttp__on_message_complete_2, + s_n_llhttp__internal__n_chunk_data_almost_done_skip, + s_n_llhttp__internal__n_chunk_data_almost_done, + s_n_llhttp__internal__n_consume_content_length, + s_n_llhttp__internal__n_span_start_llhttp__on_body, + s_n_llhttp__internal__n_invoke_is_equal_content_length, + s_n_llhttp__internal__n_chunk_size_almost_done, + s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_name_complete, + s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_name_complete_1, + s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_value_complete, + s_n_llhttp__internal__n_chunk_extension_quoted_value_done, + s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_value_complete_1, + s_n_llhttp__internal__n_error_17, + s_n_llhttp__internal__n_chunk_extension_quoted_value, + s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_value_complete_2, + s_n_llhttp__internal__n_error_19, + s_n_llhttp__internal__n_chunk_extension_value, + s_n_llhttp__internal__n_span_start_llhttp__on_chunk_extension_value, + s_n_llhttp__internal__n_error_20, + s_n_llhttp__internal__n_chunk_extension_name, + s_n_llhttp__internal__n_span_start_llhttp__on_chunk_extension_name, + s_n_llhttp__internal__n_chunk_extensions, + s_n_llhttp__internal__n_chunk_size_otherwise, + s_n_llhttp__internal__n_chunk_size, + s_n_llhttp__internal__n_chunk_size_digit, + s_n_llhttp__internal__n_invoke_update_content_length_1, + s_n_llhttp__internal__n_consume_content_length_1, + s_n_llhttp__internal__n_span_start_llhttp__on_body_1, + s_n_llhttp__internal__n_eof, + s_n_llhttp__internal__n_span_start_llhttp__on_body_2, + s_n_llhttp__internal__n_invoke_llhttp__after_headers_complete, + s_n_llhttp__internal__n_headers_almost_done, + s_n_llhttp__internal__n_header_field_colon_discard_ws, + s_n_llhttp__internal__n_error_28, + s_n_llhttp__internal__n_invoke_llhttp__on_header_value_complete, + s_n_llhttp__internal__n_span_start_llhttp__on_header_value, + s_n_llhttp__internal__n_header_value_discard_lws, + s_n_llhttp__internal__n_header_value_discard_ws_almost_done, + s_n_llhttp__internal__n_header_value_lws, + s_n_llhttp__internal__n_header_value_almost_done, + s_n_llhttp__internal__n_header_value_lenient, + s_n_llhttp__internal__n_error_34, + s_n_llhttp__internal__n_header_value_otherwise, + s_n_llhttp__internal__n_header_value_connection_token, + s_n_llhttp__internal__n_header_value_connection_ws, + s_n_llhttp__internal__n_header_value_connection_1, + s_n_llhttp__internal__n_header_value_connection_2, + s_n_llhttp__internal__n_header_value_connection_3, + s_n_llhttp__internal__n_header_value_connection, + s_n_llhttp__internal__n_error_36, + s_n_llhttp__internal__n_error_37, + s_n_llhttp__internal__n_header_value_content_length_ws, + s_n_llhttp__internal__n_header_value_content_length, + s_n_llhttp__internal__n_error_39, + s_n_llhttp__internal__n_error_38, + s_n_llhttp__internal__n_header_value_te_token_ows, + s_n_llhttp__internal__n_header_value, + s_n_llhttp__internal__n_header_value_te_token, + s_n_llhttp__internal__n_header_value_te_chunked_last, + s_n_llhttp__internal__n_header_value_te_chunked, + s_n_llhttp__internal__n_span_start_llhttp__on_header_value_1, + s_n_llhttp__internal__n_header_value_discard_ws, + s_n_llhttp__internal__n_invoke_llhttp__on_header_field_complete, + s_n_llhttp__internal__n_header_field_general_otherwise, + s_n_llhttp__internal__n_header_field_general, + s_n_llhttp__internal__n_header_field_colon, + s_n_llhttp__internal__n_header_field_3, + s_n_llhttp__internal__n_header_field_4, + s_n_llhttp__internal__n_header_field_2, + s_n_llhttp__internal__n_header_field_1, + s_n_llhttp__internal__n_header_field_5, + s_n_llhttp__internal__n_header_field_6, + s_n_llhttp__internal__n_header_field_7, + s_n_llhttp__internal__n_header_field, + s_n_llhttp__internal__n_span_start_llhttp__on_header_field, + s_n_llhttp__internal__n_header_field_start, + s_n_llhttp__internal__n_headers_start, + s_n_llhttp__internal__n_url_skip_to_http09, + s_n_llhttp__internal__n_url_skip_lf_to_http09, + s_n_llhttp__internal__n_req_pri_upgrade, + s_n_llhttp__internal__n_req_http_complete_1, + s_n_llhttp__internal__n_req_http_complete, + s_n_llhttp__internal__n_invoke_load_method_1, + s_n_llhttp__internal__n_invoke_llhttp__on_version_complete, + s_n_llhttp__internal__n_error_44, + s_n_llhttp__internal__n_error_49, + s_n_llhttp__internal__n_req_http_minor, + s_n_llhttp__internal__n_error_50, + s_n_llhttp__internal__n_req_http_dot, + s_n_llhttp__internal__n_error_51, + s_n_llhttp__internal__n_req_http_major, + s_n_llhttp__internal__n_span_start_llhttp__on_version, + s_n_llhttp__internal__n_req_http_start_1, + s_n_llhttp__internal__n_req_http_start_2, + s_n_llhttp__internal__n_req_http_start_3, + s_n_llhttp__internal__n_req_http_start, + s_n_llhttp__internal__n_url_skip_to_http, + s_n_llhttp__internal__n_url_fragment, + s_n_llhttp__internal__n_span_end_stub_query_3, + s_n_llhttp__internal__n_url_query, + s_n_llhttp__internal__n_url_query_or_fragment, + s_n_llhttp__internal__n_url_path, + s_n_llhttp__internal__n_span_start_stub_path_2, + s_n_llhttp__internal__n_span_start_stub_path, + s_n_llhttp__internal__n_span_start_stub_path_1, + s_n_llhttp__internal__n_url_server_with_at, + s_n_llhttp__internal__n_url_server, + s_n_llhttp__internal__n_url_schema_delim_1, + s_n_llhttp__internal__n_url_schema_delim, + s_n_llhttp__internal__n_span_end_stub_schema, + s_n_llhttp__internal__n_url_schema, + s_n_llhttp__internal__n_url_start, + s_n_llhttp__internal__n_span_start_llhttp__on_url_1, + s_n_llhttp__internal__n_span_start_llhttp__on_url, + s_n_llhttp__internal__n_req_spaces_before_url, + s_n_llhttp__internal__n_req_first_space_before_url, + s_n_llhttp__internal__n_invoke_llhttp__on_method_complete_1, + s_n_llhttp__internal__n_after_start_req_2, + s_n_llhttp__internal__n_after_start_req_3, + s_n_llhttp__internal__n_after_start_req_1, + s_n_llhttp__internal__n_after_start_req_4, + s_n_llhttp__internal__n_after_start_req_6, + s_n_llhttp__internal__n_after_start_req_8, + s_n_llhttp__internal__n_after_start_req_9, + s_n_llhttp__internal__n_after_start_req_7, + s_n_llhttp__internal__n_after_start_req_5, + s_n_llhttp__internal__n_after_start_req_12, + s_n_llhttp__internal__n_after_start_req_13, + s_n_llhttp__internal__n_after_start_req_11, + s_n_llhttp__internal__n_after_start_req_10, + s_n_llhttp__internal__n_after_start_req_14, + s_n_llhttp__internal__n_after_start_req_17, + s_n_llhttp__internal__n_after_start_req_16, + s_n_llhttp__internal__n_after_start_req_15, + s_n_llhttp__internal__n_after_start_req_18, + s_n_llhttp__internal__n_after_start_req_20, + s_n_llhttp__internal__n_after_start_req_21, + s_n_llhttp__internal__n_after_start_req_19, + s_n_llhttp__internal__n_after_start_req_23, + s_n_llhttp__internal__n_after_start_req_24, + s_n_llhttp__internal__n_after_start_req_26, + s_n_llhttp__internal__n_after_start_req_28, + s_n_llhttp__internal__n_after_start_req_29, + s_n_llhttp__internal__n_after_start_req_27, + s_n_llhttp__internal__n_after_start_req_25, + s_n_llhttp__internal__n_after_start_req_30, + s_n_llhttp__internal__n_after_start_req_22, + s_n_llhttp__internal__n_after_start_req_31, + s_n_llhttp__internal__n_after_start_req_32, + s_n_llhttp__internal__n_after_start_req_35, + s_n_llhttp__internal__n_after_start_req_36, + s_n_llhttp__internal__n_after_start_req_34, + s_n_llhttp__internal__n_after_start_req_37, + s_n_llhttp__internal__n_after_start_req_38, + s_n_llhttp__internal__n_after_start_req_42, + s_n_llhttp__internal__n_after_start_req_43, + s_n_llhttp__internal__n_after_start_req_41, + s_n_llhttp__internal__n_after_start_req_40, + s_n_llhttp__internal__n_after_start_req_39, + s_n_llhttp__internal__n_after_start_req_45, + s_n_llhttp__internal__n_after_start_req_44, + s_n_llhttp__internal__n_after_start_req_33, + s_n_llhttp__internal__n_after_start_req_48, + s_n_llhttp__internal__n_after_start_req_49, + s_n_llhttp__internal__n_after_start_req_50, + s_n_llhttp__internal__n_after_start_req_51, + s_n_llhttp__internal__n_after_start_req_47, + s_n_llhttp__internal__n_after_start_req_46, + s_n_llhttp__internal__n_after_start_req_54, + s_n_llhttp__internal__n_after_start_req_56, + s_n_llhttp__internal__n_after_start_req_57, + s_n_llhttp__internal__n_after_start_req_55, + s_n_llhttp__internal__n_after_start_req_53, + s_n_llhttp__internal__n_after_start_req_58, + s_n_llhttp__internal__n_after_start_req_59, + s_n_llhttp__internal__n_after_start_req_52, + s_n_llhttp__internal__n_after_start_req_61, + s_n_llhttp__internal__n_after_start_req_62, + s_n_llhttp__internal__n_after_start_req_60, + s_n_llhttp__internal__n_after_start_req_65, + s_n_llhttp__internal__n_after_start_req_67, + s_n_llhttp__internal__n_after_start_req_68, + s_n_llhttp__internal__n_after_start_req_66, + s_n_llhttp__internal__n_after_start_req_69, + s_n_llhttp__internal__n_after_start_req_64, + s_n_llhttp__internal__n_after_start_req_63, + s_n_llhttp__internal__n_after_start_req, + s_n_llhttp__internal__n_span_start_llhttp__on_method_1, + s_n_llhttp__internal__n_invoke_llhttp__on_status_complete, + s_n_llhttp__internal__n_res_line_almost_done, + s_n_llhttp__internal__n_res_status, + s_n_llhttp__internal__n_span_start_llhttp__on_status, + s_n_llhttp__internal__n_res_status_start, + s_n_llhttp__internal__n_res_status_code_otherwise, + s_n_llhttp__internal__n_res_status_code, + s_n_llhttp__internal__n_res_after_version, + s_n_llhttp__internal__n_invoke_llhttp__on_version_complete_1, + s_n_llhttp__internal__n_error_66, + s_n_llhttp__internal__n_error_72, + s_n_llhttp__internal__n_res_http_minor, + s_n_llhttp__internal__n_error_73, + s_n_llhttp__internal__n_res_http_dot, + s_n_llhttp__internal__n_error_74, + s_n_llhttp__internal__n_res_http_major, + s_n_llhttp__internal__n_span_start_llhttp__on_version_1, + s_n_llhttp__internal__n_start_res, + s_n_llhttp__internal__n_invoke_llhttp__on_method_complete, + s_n_llhttp__internal__n_req_or_res_method_2, + s_n_llhttp__internal__n_invoke_update_type_1, + s_n_llhttp__internal__n_req_or_res_method_3, + s_n_llhttp__internal__n_req_or_res_method_1, + s_n_llhttp__internal__n_req_or_res_method, + s_n_llhttp__internal__n_span_start_llhttp__on_method, + s_n_llhttp__internal__n_start_req_or_res, + s_n_llhttp__internal__n_invoke_load_type, + s_n_llhttp__internal__n_invoke_update_finish, + s_n_llhttp__internal__n_start, +}; +typedef enum llparse_state_e llparse_state_t; + +int llhttp__on_method( + llhttp__internal_t* s, const unsigned char* p, + const unsigned char* endp); + +int llhttp__on_url( + llhttp__internal_t* s, const unsigned char* p, + const unsigned char* endp); + +int llhttp__on_version( + llhttp__internal_t* s, const unsigned char* p, + const unsigned char* endp); + +int llhttp__on_header_field( + llhttp__internal_t* s, const unsigned char* p, + const unsigned char* endp); + +int llhttp__on_header_value( + llhttp__internal_t* s, const unsigned char* p, + const unsigned char* endp); + +int llhttp__on_body( + llhttp__internal_t* s, const unsigned char* p, + const unsigned char* endp); + +int llhttp__on_chunk_extension_name( + llhttp__internal_t* s, const unsigned char* p, + const unsigned char* endp); + +int llhttp__on_chunk_extension_value( + llhttp__internal_t* s, const unsigned char* p, + const unsigned char* endp); + +int llhttp__on_status( + llhttp__internal_t* s, const unsigned char* p, + const unsigned char* endp); + +int llhttp__internal__c_load_initial_message_completed( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + return state->initial_message_completed; +} + +int llhttp__on_reset( + llhttp__internal_t* s, const unsigned char* p, + const unsigned char* endp); + +int llhttp__internal__c_update_finish( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + state->finish = 2; + return 0; +} + +int llhttp__on_message_begin( + llhttp__internal_t* s, const unsigned char* p, + const unsigned char* endp); + +int llhttp__internal__c_load_type( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + return state->type; +} + +int llhttp__internal__c_store_method( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp, + int match) { + state->method = match; + return 0; +} + +int llhttp__on_method_complete( + llhttp__internal_t* s, const unsigned char* p, + const unsigned char* endp); + +int llhttp__internal__c_is_equal_method( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + return state->method == 5; +} + +int llhttp__internal__c_update_http_major( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + state->http_major = 0; + return 0; +} + +int llhttp__internal__c_update_http_minor( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + state->http_minor = 9; + return 0; +} + +int llhttp__on_url_complete( + llhttp__internal_t* s, const unsigned char* p, + const unsigned char* endp); + +int llhttp__internal__c_test_lenient_flags( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + return (state->lenient_flags & 1) == 1; +} + +int llhttp__internal__c_test_flags( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + return (state->flags & 128) == 128; +} + +int llhttp__on_chunk_complete( + llhttp__internal_t* s, const unsigned char* p, + const unsigned char* endp); + +int llhttp__on_message_complete( + llhttp__internal_t* s, const unsigned char* p, + const unsigned char* endp); + +int llhttp__internal__c_is_equal_upgrade( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + return state->upgrade == 1; +} + +int llhttp__after_message_complete( + llhttp__internal_t* s, const unsigned char* p, + const unsigned char* endp); + +int llhttp__internal__c_update_content_length( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + state->content_length = 0; + return 0; +} + +int llhttp__internal__c_update_initial_message_completed( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + state->initial_message_completed = 1; + return 0; +} + +int llhttp__internal__c_update_finish_1( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + state->finish = 0; + return 0; +} + +int llhttp__internal__c_test_lenient_flags_1( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + return (state->lenient_flags & 4) == 4; +} + +int llhttp__internal__c_test_flags_1( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + return (state->flags & 544) == 544; +} + +int llhttp__internal__c_test_lenient_flags_2( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + return (state->lenient_flags & 2) == 2; +} + +int llhttp__before_headers_complete( + llhttp__internal_t* s, const unsigned char* p, + const unsigned char* endp); + +int llhttp__on_headers_complete( + llhttp__internal_t* s, const unsigned char* p, + const unsigned char* endp); + +int llhttp__after_headers_complete( + llhttp__internal_t* s, const unsigned char* p, + const unsigned char* endp); + +int llhttp__internal__c_mul_add_content_length( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp, + int match) { + /* Multiplication overflow */ + if (state->content_length > 0xffffffffffffffffULL / 16) { + return 1; + } + + state->content_length *= 16; + + /* Addition overflow */ + if (match >= 0) { + if (state->content_length > 0xffffffffffffffffULL - match) { + return 1; + } + } else { + if (state->content_length < 0ULL - match) { + return 1; + } + } + state->content_length += match; + return 0; +} + +int llhttp__on_chunk_header( + llhttp__internal_t* s, const unsigned char* p, + const unsigned char* endp); + +int llhttp__internal__c_is_equal_content_length( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + return state->content_length == 0; +} + +int llhttp__internal__c_or_flags( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + state->flags |= 128; + return 0; +} + +int llhttp__on_chunk_extension_name_complete( + llhttp__internal_t* s, const unsigned char* p, + const unsigned char* endp); + +int llhttp__on_chunk_extension_value_complete( + llhttp__internal_t* s, const unsigned char* p, + const unsigned char* endp); + +int llhttp__internal__c_update_finish_3( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + state->finish = 1; + return 0; +} + +int llhttp__internal__c_or_flags_1( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + state->flags |= 64; + return 0; +} + +int llhttp__internal__c_update_upgrade( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + state->upgrade = 1; + return 0; +} + +int llhttp__internal__c_store_header_state( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp, + int match) { + state->header_state = match; + return 0; +} + +int llhttp__on_header_field_complete( + llhttp__internal_t* s, const unsigned char* p, + const unsigned char* endp); + +int llhttp__internal__c_load_header_state( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + return state->header_state; +} + +int llhttp__internal__c_or_flags_3( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + state->flags |= 1; + return 0; +} + +int llhttp__internal__c_update_header_state( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + state->header_state = 1; + return 0; +} + +int llhttp__on_header_value_complete( + llhttp__internal_t* s, const unsigned char* p, + const unsigned char* endp); + +int llhttp__internal__c_or_flags_4( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + state->flags |= 2; + return 0; +} + +int llhttp__internal__c_or_flags_5( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + state->flags |= 4; + return 0; +} + +int llhttp__internal__c_or_flags_6( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + state->flags |= 8; + return 0; +} + +int llhttp__internal__c_update_header_state_3( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + state->header_state = 6; + return 0; +} + +int llhttp__internal__c_update_header_state_1( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + state->header_state = 0; + return 0; +} + +int llhttp__internal__c_update_header_state_6( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + state->header_state = 5; + return 0; +} + +int llhttp__internal__c_update_header_state_7( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + state->header_state = 7; + return 0; +} + +int llhttp__internal__c_test_flags_2( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + return (state->flags & 32) == 32; +} + +int llhttp__internal__c_mul_add_content_length_1( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp, + int match) { + /* Multiplication overflow */ + if (state->content_length > 0xffffffffffffffffULL / 10) { + return 1; + } + + state->content_length *= 10; + + /* Addition overflow */ + if (match >= 0) { + if (state->content_length > 0xffffffffffffffffULL - match) { + return 1; + } + } else { + if (state->content_length < 0ULL - match) { + return 1; + } + } + state->content_length += match; + return 0; +} + +int llhttp__internal__c_or_flags_15( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + state->flags |= 32; + return 0; +} + +int llhttp__internal__c_test_flags_3( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + return (state->flags & 8) == 8; +} + +int llhttp__internal__c_test_lenient_flags_6( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + return (state->lenient_flags & 8) == 8; +} + +int llhttp__internal__c_or_flags_16( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + state->flags |= 512; + return 0; +} + +int llhttp__internal__c_and_flags( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + state->flags &= -9; + return 0; +} + +int llhttp__internal__c_update_header_state_8( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + state->header_state = 8; + return 0; +} + +int llhttp__internal__c_or_flags_18( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + state->flags |= 16; + return 0; +} + +int llhttp__internal__c_load_method( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + return state->method; +} + +int llhttp__internal__c_store_http_major( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp, + int match) { + state->http_major = match; + return 0; +} + +int llhttp__internal__c_store_http_minor( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp, + int match) { + state->http_minor = match; + return 0; +} + +int llhttp__internal__c_test_lenient_flags_8( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + return (state->lenient_flags & 16) == 16; +} + +int llhttp__on_version_complete( + llhttp__internal_t* s, const unsigned char* p, + const unsigned char* endp); + +int llhttp__internal__c_load_http_major( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + return state->http_major; +} + +int llhttp__internal__c_load_http_minor( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + return state->http_minor; +} + +int llhttp__internal__c_update_status_code( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + state->status_code = 0; + return 0; +} + +int llhttp__internal__c_mul_add_status_code( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp, + int match) { + /* Multiplication overflow */ + if (state->status_code > 0xffff / 10) { + return 1; + } + + state->status_code *= 10; + + /* Addition overflow */ + if (match >= 0) { + if (state->status_code > 0xffff - match) { + return 1; + } + } else { + if (state->status_code < 0 - match) { + return 1; + } + } + state->status_code += match; + + /* Enforce maximum */ + if (state->status_code > 999) { + return 1; + } + return 0; +} + +int llhttp__on_status_complete( + llhttp__internal_t* s, const unsigned char* p, + const unsigned char* endp); + +int llhttp__internal__c_update_type( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + state->type = 1; + return 0; +} + +int llhttp__internal__c_update_type_1( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + state->type = 2; + return 0; +} + +int llhttp__internal_init(llhttp__internal_t* state) { + memset(state, 0, sizeof(*state)); + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_start; + return 0; +} + +static llparse_state_t llhttp__internal__run( + llhttp__internal_t* state, + const unsigned char* p, + const unsigned char* endp) { + int match; + switch ((llparse_state_t) (intptr_t) state->_current) { + case s_n_llhttp__internal__n_closed: + s_n_llhttp__internal__n_closed: { + if (p == endp) { + return s_n_llhttp__internal__n_closed; + } + p++; + goto s_n_llhttp__internal__n_closed; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_invoke_llhttp__after_message_complete: + s_n_llhttp__internal__n_invoke_llhttp__after_message_complete: { + switch (llhttp__after_message_complete(state, p, endp)) { + case 1: + goto s_n_llhttp__internal__n_invoke_update_content_length; + default: + goto s_n_llhttp__internal__n_invoke_update_finish_1; + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_pause_1: + s_n_llhttp__internal__n_pause_1: { + state->error = 0x16; + state->reason = "Pause on CONNECT/Upgrade"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_llhttp__after_message_complete; + return s_error; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_invoke_is_equal_upgrade: + s_n_llhttp__internal__n_invoke_is_equal_upgrade: { + switch (llhttp__internal__c_is_equal_upgrade(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_invoke_llhttp__after_message_complete; + default: + goto s_n_llhttp__internal__n_pause_1; + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_invoke_llhttp__on_message_complete_2: + s_n_llhttp__internal__n_invoke_llhttp__on_message_complete_2: { + switch (llhttp__on_message_complete(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_invoke_is_equal_upgrade; + case 21: + goto s_n_llhttp__internal__n_pause_11; + default: + goto s_n_llhttp__internal__n_error_24; + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_chunk_data_almost_done_skip: + s_n_llhttp__internal__n_chunk_data_almost_done_skip: { + if (p == endp) { + return s_n_llhttp__internal__n_chunk_data_almost_done_skip; + } + p++; + goto s_n_llhttp__internal__n_invoke_llhttp__on_chunk_complete; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_chunk_data_almost_done: + s_n_llhttp__internal__n_chunk_data_almost_done: { + if (p == endp) { + return s_n_llhttp__internal__n_chunk_data_almost_done; + } + p++; + goto s_n_llhttp__internal__n_chunk_data_almost_done_skip; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_consume_content_length: + s_n_llhttp__internal__n_consume_content_length: { + size_t avail; + uint64_t need; + + avail = endp - p; + need = state->content_length; + if (avail >= need) { + p += need; + state->content_length = 0; + goto s_n_llhttp__internal__n_span_end_llhttp__on_body; + } + + state->content_length -= avail; + return s_n_llhttp__internal__n_consume_content_length; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_span_start_llhttp__on_body: + s_n_llhttp__internal__n_span_start_llhttp__on_body: { + if (p == endp) { + return s_n_llhttp__internal__n_span_start_llhttp__on_body; + } + state->_span_pos0 = (void*) p; + state->_span_cb0 = llhttp__on_body; + goto s_n_llhttp__internal__n_consume_content_length; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_invoke_is_equal_content_length: + s_n_llhttp__internal__n_invoke_is_equal_content_length: { + switch (llhttp__internal__c_is_equal_content_length(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_span_start_llhttp__on_body; + default: + goto s_n_llhttp__internal__n_invoke_or_flags; + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_chunk_size_almost_done: + s_n_llhttp__internal__n_chunk_size_almost_done: { + if (p == endp) { + return s_n_llhttp__internal__n_chunk_size_almost_done; + } + p++; + goto s_n_llhttp__internal__n_invoke_llhttp__on_chunk_header; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_name_complete: + s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_name_complete: { + switch (llhttp__on_chunk_extension_name_complete(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_chunk_size_almost_done; + case 21: + goto s_n_llhttp__internal__n_pause_5; + default: + goto s_n_llhttp__internal__n_error_11; + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_name_complete_1: + s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_name_complete_1: { + switch (llhttp__on_chunk_extension_name_complete(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_chunk_extensions; + case 21: + goto s_n_llhttp__internal__n_pause_6; + default: + goto s_n_llhttp__internal__n_error_12; + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_value_complete: + s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_value_complete: { + switch (llhttp__on_chunk_extension_value_complete(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_chunk_size_almost_done; + case 21: + goto s_n_llhttp__internal__n_pause_7; + default: + goto s_n_llhttp__internal__n_error_14; + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_chunk_extension_quoted_value_done: + s_n_llhttp__internal__n_chunk_extension_quoted_value_done: { + if (p == endp) { + return s_n_llhttp__internal__n_chunk_extension_quoted_value_done; + } + switch (*p) { + case 13: { + p++; + goto s_n_llhttp__internal__n_chunk_size_almost_done; + } + case ';': { + p++; + goto s_n_llhttp__internal__n_chunk_extensions; + } + default: { + goto s_n_llhttp__internal__n_error_16; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_value_complete_1: + s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_value_complete_1: { + switch (llhttp__on_chunk_extension_value_complete(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_chunk_extension_quoted_value_done; + case 21: + goto s_n_llhttp__internal__n_pause_8; + default: + goto s_n_llhttp__internal__n_error_15; + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_error_17: + s_n_llhttp__internal__n_error_17: { + state->error = 0x2; + state->reason = "Invalid character in chunk extensions quoted value"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_chunk_extension_quoted_value: + s_n_llhttp__internal__n_chunk_extension_quoted_value: { + static uint8_t lookup_table[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 + }; + if (p == endp) { + return s_n_llhttp__internal__n_chunk_extension_quoted_value; + } + switch (lookup_table[(uint8_t) *p]) { + case 1: { + p++; + goto s_n_llhttp__internal__n_chunk_extension_quoted_value; + } + case 2: { + p++; + goto s_n_llhttp__internal__n_span_end_llhttp__on_chunk_extension_value_1; + } + default: { + goto s_n_llhttp__internal__n_span_end_llhttp__on_chunk_extension_value_2; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_value_complete_2: + s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_value_complete_2: { + switch (llhttp__on_chunk_extension_value_complete(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_chunk_size_otherwise; + case 21: + goto s_n_llhttp__internal__n_pause_9; + default: + goto s_n_llhttp__internal__n_error_18; + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_error_19: + s_n_llhttp__internal__n_error_19: { + state->error = 0x2; + state->reason = "Invalid character in chunk extensions value"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_chunk_extension_value: + s_n_llhttp__internal__n_chunk_extension_value: { + static uint8_t lookup_table[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2, 3, 2, 2, 2, 2, 2, 0, 0, 2, 2, 0, 2, 2, 0, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 4, 0, 0, 0, 0, + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 2, 0, 2, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + if (p == endp) { + return s_n_llhttp__internal__n_chunk_extension_value; + } + switch (lookup_table[(uint8_t) *p]) { + case 1: { + goto s_n_llhttp__internal__n_span_end_llhttp__on_chunk_extension_value; + } + case 2: { + p++; + goto s_n_llhttp__internal__n_chunk_extension_value; + } + case 3: { + p++; + goto s_n_llhttp__internal__n_chunk_extension_quoted_value; + } + case 4: { + goto s_n_llhttp__internal__n_span_end_llhttp__on_chunk_extension_value_3; + } + default: { + goto s_n_llhttp__internal__n_span_end_llhttp__on_chunk_extension_value_4; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_span_start_llhttp__on_chunk_extension_value: + s_n_llhttp__internal__n_span_start_llhttp__on_chunk_extension_value: { + if (p == endp) { + return s_n_llhttp__internal__n_span_start_llhttp__on_chunk_extension_value; + } + state->_span_pos0 = (void*) p; + state->_span_cb0 = llhttp__on_chunk_extension_value; + goto s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_name_complete_2; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_error_20: + s_n_llhttp__internal__n_error_20: { + state->error = 0x2; + state->reason = "Invalid character in chunk extensions name"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_chunk_extension_name: + s_n_llhttp__internal__n_chunk_extension_name: { + static uint8_t lookup_table[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2, 0, 2, 2, 2, 2, 2, 0, 0, 2, 2, 0, 2, 2, 0, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 3, 0, 4, 0, 0, + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 2, 0, 2, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + if (p == endp) { + return s_n_llhttp__internal__n_chunk_extension_name; + } + switch (lookup_table[(uint8_t) *p]) { + case 1: { + goto s_n_llhttp__internal__n_span_end_llhttp__on_chunk_extension_name; + } + case 2: { + p++; + goto s_n_llhttp__internal__n_chunk_extension_name; + } + case 3: { + goto s_n_llhttp__internal__n_span_end_llhttp__on_chunk_extension_name_1; + } + case 4: { + goto s_n_llhttp__internal__n_span_end_llhttp__on_chunk_extension_name_2; + } + default: { + goto s_n_llhttp__internal__n_span_end_llhttp__on_chunk_extension_name_3; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_span_start_llhttp__on_chunk_extension_name: + s_n_llhttp__internal__n_span_start_llhttp__on_chunk_extension_name: { + if (p == endp) { + return s_n_llhttp__internal__n_span_start_llhttp__on_chunk_extension_name; + } + state->_span_pos0 = (void*) p; + state->_span_cb0 = llhttp__on_chunk_extension_name; + goto s_n_llhttp__internal__n_chunk_extension_name; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_chunk_extensions: + s_n_llhttp__internal__n_chunk_extensions: { + if (p == endp) { + return s_n_llhttp__internal__n_chunk_extensions; + } + switch (*p) { + case 13: { + p++; + goto s_n_llhttp__internal__n_error_9; + } + case ' ': { + p++; + goto s_n_llhttp__internal__n_error_10; + } + default: { + goto s_n_llhttp__internal__n_span_start_llhttp__on_chunk_extension_name; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_chunk_size_otherwise: + s_n_llhttp__internal__n_chunk_size_otherwise: { + if (p == endp) { + return s_n_llhttp__internal__n_chunk_size_otherwise; + } + switch (*p) { + case 13: { + p++; + goto s_n_llhttp__internal__n_chunk_size_almost_done; + } + case ';': { + p++; + goto s_n_llhttp__internal__n_chunk_extensions; + } + default: { + goto s_n_llhttp__internal__n_error_21; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_chunk_size: + s_n_llhttp__internal__n_chunk_size: { + if (p == endp) { + return s_n_llhttp__internal__n_chunk_size; + } + switch (*p) { + case '0': { + p++; + match = 0; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case '1': { + p++; + match = 1; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case '2': { + p++; + match = 2; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case '3': { + p++; + match = 3; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case '4': { + p++; + match = 4; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case '5': { + p++; + match = 5; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case '6': { + p++; + match = 6; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case '7': { + p++; + match = 7; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case '8': { + p++; + match = 8; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case '9': { + p++; + match = 9; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case 'A': { + p++; + match = 10; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case 'B': { + p++; + match = 11; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case 'C': { + p++; + match = 12; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case 'D': { + p++; + match = 13; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case 'E': { + p++; + match = 14; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case 'F': { + p++; + match = 15; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case 'a': { + p++; + match = 10; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case 'b': { + p++; + match = 11; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case 'c': { + p++; + match = 12; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case 'd': { + p++; + match = 13; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case 'e': { + p++; + match = 14; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case 'f': { + p++; + match = 15; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + default: { + goto s_n_llhttp__internal__n_chunk_size_otherwise; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_chunk_size_digit: + s_n_llhttp__internal__n_chunk_size_digit: { + if (p == endp) { + return s_n_llhttp__internal__n_chunk_size_digit; + } + switch (*p) { + case '0': { + p++; + match = 0; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case '1': { + p++; + match = 1; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case '2': { + p++; + match = 2; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case '3': { + p++; + match = 3; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case '4': { + p++; + match = 4; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case '5': { + p++; + match = 5; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case '6': { + p++; + match = 6; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case '7': { + p++; + match = 7; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case '8': { + p++; + match = 8; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case '9': { + p++; + match = 9; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case 'A': { + p++; + match = 10; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case 'B': { + p++; + match = 11; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case 'C': { + p++; + match = 12; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case 'D': { + p++; + match = 13; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case 'E': { + p++; + match = 14; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case 'F': { + p++; + match = 15; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case 'a': { + p++; + match = 10; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case 'b': { + p++; + match = 11; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case 'c': { + p++; + match = 12; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case 'd': { + p++; + match = 13; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case 'e': { + p++; + match = 14; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + case 'f': { + p++; + match = 15; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length; + } + default: { + goto s_n_llhttp__internal__n_error_23; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_invoke_update_content_length_1: + s_n_llhttp__internal__n_invoke_update_content_length_1: { + switch (llhttp__internal__c_update_content_length(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_chunk_size_digit; + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_consume_content_length_1: + s_n_llhttp__internal__n_consume_content_length_1: { + size_t avail; + uint64_t need; + + avail = endp - p; + need = state->content_length; + if (avail >= need) { + p += need; + state->content_length = 0; + goto s_n_llhttp__internal__n_span_end_llhttp__on_body_1; + } + + state->content_length -= avail; + return s_n_llhttp__internal__n_consume_content_length_1; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_span_start_llhttp__on_body_1: + s_n_llhttp__internal__n_span_start_llhttp__on_body_1: { + if (p == endp) { + return s_n_llhttp__internal__n_span_start_llhttp__on_body_1; + } + state->_span_pos0 = (void*) p; + state->_span_cb0 = llhttp__on_body; + goto s_n_llhttp__internal__n_consume_content_length_1; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_eof: + s_n_llhttp__internal__n_eof: { + if (p == endp) { + return s_n_llhttp__internal__n_eof; + } + p++; + goto s_n_llhttp__internal__n_eof; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_span_start_llhttp__on_body_2: + s_n_llhttp__internal__n_span_start_llhttp__on_body_2: { + if (p == endp) { + return s_n_llhttp__internal__n_span_start_llhttp__on_body_2; + } + state->_span_pos0 = (void*) p; + state->_span_cb0 = llhttp__on_body; + goto s_n_llhttp__internal__n_eof; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_invoke_llhttp__after_headers_complete: + s_n_llhttp__internal__n_invoke_llhttp__after_headers_complete: { + switch (llhttp__after_headers_complete(state, p, endp)) { + case 1: + goto s_n_llhttp__internal__n_invoke_llhttp__on_message_complete_1; + case 2: + goto s_n_llhttp__internal__n_invoke_update_content_length_1; + case 3: + goto s_n_llhttp__internal__n_span_start_llhttp__on_body_1; + case 4: + goto s_n_llhttp__internal__n_invoke_update_finish_3; + case 5: + goto s_n_llhttp__internal__n_error_25; + default: + goto s_n_llhttp__internal__n_invoke_llhttp__on_message_complete; + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_headers_almost_done: + s_n_llhttp__internal__n_headers_almost_done: { + if (p == endp) { + return s_n_llhttp__internal__n_headers_almost_done; + } + p++; + goto s_n_llhttp__internal__n_invoke_test_flags; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_header_field_colon_discard_ws: + s_n_llhttp__internal__n_header_field_colon_discard_ws: { + if (p == endp) { + return s_n_llhttp__internal__n_header_field_colon_discard_ws; + } + switch (*p) { + case ' ': { + p++; + goto s_n_llhttp__internal__n_header_field_colon_discard_ws; + } + default: { + goto s_n_llhttp__internal__n_header_field_colon; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_error_28: + s_n_llhttp__internal__n_error_28: { + state->error = 0xa; + state->reason = "Invalid header field char"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_invoke_llhttp__on_header_value_complete: + s_n_llhttp__internal__n_invoke_llhttp__on_header_value_complete: { + switch (llhttp__on_header_value_complete(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_header_field_start; + case 21: + goto s_n_llhttp__internal__n_pause_14; + default: + goto s_n_llhttp__internal__n_error_31; + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_span_start_llhttp__on_header_value: + s_n_llhttp__internal__n_span_start_llhttp__on_header_value: { + if (p == endp) { + return s_n_llhttp__internal__n_span_start_llhttp__on_header_value; + } + state->_span_pos0 = (void*) p; + state->_span_cb0 = llhttp__on_header_value; + goto s_n_llhttp__internal__n_span_end_llhttp__on_header_value; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_header_value_discard_lws: + s_n_llhttp__internal__n_header_value_discard_lws: { + if (p == endp) { + return s_n_llhttp__internal__n_header_value_discard_lws; + } + switch (*p) { + case 9: { + p++; + goto s_n_llhttp__internal__n_header_value_discard_ws; + } + case ' ': { + p++; + goto s_n_llhttp__internal__n_header_value_discard_ws; + } + default: { + goto s_n_llhttp__internal__n_invoke_load_header_state; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_header_value_discard_ws_almost_done: + s_n_llhttp__internal__n_header_value_discard_ws_almost_done: { + if (p == endp) { + return s_n_llhttp__internal__n_header_value_discard_ws_almost_done; + } + p++; + goto s_n_llhttp__internal__n_header_value_discard_lws; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_header_value_lws: + s_n_llhttp__internal__n_header_value_lws: { + if (p == endp) { + return s_n_llhttp__internal__n_header_value_lws; + } + switch (*p) { + case 9: { + goto s_n_llhttp__internal__n_invoke_load_header_state_3; + } + case ' ': { + goto s_n_llhttp__internal__n_invoke_load_header_state_3; + } + default: { + goto s_n_llhttp__internal__n_invoke_load_header_state_4; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_header_value_almost_done: + s_n_llhttp__internal__n_header_value_almost_done: { + if (p == endp) { + return s_n_llhttp__internal__n_header_value_almost_done; + } + switch (*p) { + case 10: { + p++; + goto s_n_llhttp__internal__n_header_value_lws; + } + default: { + goto s_n_llhttp__internal__n_error_33; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_header_value_lenient: + s_n_llhttp__internal__n_header_value_lenient: { + if (p == endp) { + return s_n_llhttp__internal__n_header_value_lenient; + } + switch (*p) { + case 10: { + goto s_n_llhttp__internal__n_span_end_llhttp__on_header_value_3; + } + case 13: { + goto s_n_llhttp__internal__n_span_end_llhttp__on_header_value_4; + } + default: { + p++; + goto s_n_llhttp__internal__n_header_value_lenient; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_error_34: + s_n_llhttp__internal__n_error_34: { + state->error = 0xa; + state->reason = "Invalid header value char"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_header_value_otherwise: + s_n_llhttp__internal__n_header_value_otherwise: { + if (p == endp) { + return s_n_llhttp__internal__n_header_value_otherwise; + } + switch (*p) { + case 13: { + goto s_n_llhttp__internal__n_span_end_llhttp__on_header_value_1; + } + default: { + goto s_n_llhttp__internal__n_invoke_test_lenient_flags_5; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_header_value_connection_token: + s_n_llhttp__internal__n_header_value_connection_token: { + static uint8_t lookup_table[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 + }; + if (p == endp) { + return s_n_llhttp__internal__n_header_value_connection_token; + } + switch (lookup_table[(uint8_t) *p]) { + case 1: { + p++; + goto s_n_llhttp__internal__n_header_value_connection_token; + } + case 2: { + p++; + goto s_n_llhttp__internal__n_header_value_connection; + } + default: { + goto s_n_llhttp__internal__n_header_value_otherwise; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_header_value_connection_ws: + s_n_llhttp__internal__n_header_value_connection_ws: { + if (p == endp) { + return s_n_llhttp__internal__n_header_value_connection_ws; + } + switch (*p) { + case 10: { + goto s_n_llhttp__internal__n_header_value_otherwise; + } + case 13: { + goto s_n_llhttp__internal__n_header_value_otherwise; + } + case ' ': { + p++; + goto s_n_llhttp__internal__n_header_value_connection_ws; + } + case ',': { + p++; + goto s_n_llhttp__internal__n_invoke_load_header_state_5; + } + default: { + goto s_n_llhttp__internal__n_invoke_update_header_state_5; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_header_value_connection_1: + s_n_llhttp__internal__n_header_value_connection_1: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_header_value_connection_1; + } + match_seq = llparse__match_sequence_to_lower(state, p, endp, llparse_blob3, 4); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + goto s_n_llhttp__internal__n_invoke_update_header_state_3; + } + case kMatchPause: { + return s_n_llhttp__internal__n_header_value_connection_1; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_header_value_connection_token; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_header_value_connection_2: + s_n_llhttp__internal__n_header_value_connection_2: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_header_value_connection_2; + } + match_seq = llparse__match_sequence_to_lower(state, p, endp, llparse_blob4, 9); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + goto s_n_llhttp__internal__n_invoke_update_header_state_6; + } + case kMatchPause: { + return s_n_llhttp__internal__n_header_value_connection_2; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_header_value_connection_token; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_header_value_connection_3: + s_n_llhttp__internal__n_header_value_connection_3: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_header_value_connection_3; + } + match_seq = llparse__match_sequence_to_lower(state, p, endp, llparse_blob5, 6); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + goto s_n_llhttp__internal__n_invoke_update_header_state_7; + } + case kMatchPause: { + return s_n_llhttp__internal__n_header_value_connection_3; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_header_value_connection_token; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_header_value_connection: + s_n_llhttp__internal__n_header_value_connection: { + if (p == endp) { + return s_n_llhttp__internal__n_header_value_connection; + } + switch (((*p) >= 'A' && (*p) <= 'Z' ? (*p | 0x20) : (*p))) { + case 9: { + p++; + goto s_n_llhttp__internal__n_header_value_connection; + } + case ' ': { + p++; + goto s_n_llhttp__internal__n_header_value_connection; + } + case 'c': { + p++; + goto s_n_llhttp__internal__n_header_value_connection_1; + } + case 'k': { + p++; + goto s_n_llhttp__internal__n_header_value_connection_2; + } + case 'u': { + p++; + goto s_n_llhttp__internal__n_header_value_connection_3; + } + default: { + goto s_n_llhttp__internal__n_header_value_connection_token; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_error_36: + s_n_llhttp__internal__n_error_36: { + state->error = 0xb; + state->reason = "Content-Length overflow"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_error_37: + s_n_llhttp__internal__n_error_37: { + state->error = 0xb; + state->reason = "Invalid character in Content-Length"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_header_value_content_length_ws: + s_n_llhttp__internal__n_header_value_content_length_ws: { + if (p == endp) { + return s_n_llhttp__internal__n_header_value_content_length_ws; + } + switch (*p) { + case 10: { + goto s_n_llhttp__internal__n_invoke_or_flags_15; + } + case 13: { + goto s_n_llhttp__internal__n_invoke_or_flags_15; + } + case ' ': { + p++; + goto s_n_llhttp__internal__n_header_value_content_length_ws; + } + default: { + goto s_n_llhttp__internal__n_span_end_llhttp__on_header_value_6; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_header_value_content_length: + s_n_llhttp__internal__n_header_value_content_length: { + if (p == endp) { + return s_n_llhttp__internal__n_header_value_content_length; + } + switch (*p) { + case '0': { + p++; + match = 0; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length_1; + } + case '1': { + p++; + match = 1; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length_1; + } + case '2': { + p++; + match = 2; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length_1; + } + case '3': { + p++; + match = 3; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length_1; + } + case '4': { + p++; + match = 4; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length_1; + } + case '5': { + p++; + match = 5; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length_1; + } + case '6': { + p++; + match = 6; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length_1; + } + case '7': { + p++; + match = 7; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length_1; + } + case '8': { + p++; + match = 8; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length_1; + } + case '9': { + p++; + match = 9; + goto s_n_llhttp__internal__n_invoke_mul_add_content_length_1; + } + default: { + goto s_n_llhttp__internal__n_header_value_content_length_ws; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_error_39: + s_n_llhttp__internal__n_error_39: { + state->error = 0xf; + state->reason = "Invalid `Transfer-Encoding` header value"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_error_38: + s_n_llhttp__internal__n_error_38: { + state->error = 0xf; + state->reason = "Invalid `Transfer-Encoding` header value"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_header_value_te_token_ows: + s_n_llhttp__internal__n_header_value_te_token_ows: { + if (p == endp) { + return s_n_llhttp__internal__n_header_value_te_token_ows; + } + switch (*p) { + case 9: { + p++; + goto s_n_llhttp__internal__n_header_value_te_token_ows; + } + case ' ': { + p++; + goto s_n_llhttp__internal__n_header_value_te_token_ows; + } + default: { + goto s_n_llhttp__internal__n_header_value_te_chunked; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_header_value: + s_n_llhttp__internal__n_header_value: { + static uint8_t lookup_table[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 + }; + if (p == endp) { + return s_n_llhttp__internal__n_header_value; + } + #ifdef __SSE4_2__ + if (endp - p >= 16) { + __m128i ranges; + __m128i input; + int avail; + int match_len; + + /* Load input */ + input = _mm_loadu_si128((__m128i const*) p); + ranges = _mm_loadu_si128((__m128i const*) llparse_blob7); + + /* Find first character that does not match `ranges` */ + match_len = _mm_cmpestri(ranges, 6, + input, 16, + _SIDD_UBYTE_OPS | _SIDD_CMP_RANGES | + _SIDD_NEGATIVE_POLARITY); + + if (match_len != 0) { + p += match_len; + goto s_n_llhttp__internal__n_header_value; + } + goto s_n_llhttp__internal__n_header_value_otherwise; + } + #endif /* __SSE4_2__ */ + switch (lookup_table[(uint8_t) *p]) { + case 1: { + p++; + goto s_n_llhttp__internal__n_header_value; + } + default: { + goto s_n_llhttp__internal__n_header_value_otherwise; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_header_value_te_token: + s_n_llhttp__internal__n_header_value_te_token: { + static uint8_t lookup_table[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 + }; + if (p == endp) { + return s_n_llhttp__internal__n_header_value_te_token; + } + switch (lookup_table[(uint8_t) *p]) { + case 1: { + p++; + goto s_n_llhttp__internal__n_header_value_te_token; + } + case 2: { + p++; + goto s_n_llhttp__internal__n_header_value_te_token_ows; + } + default: { + goto s_n_llhttp__internal__n_invoke_update_header_state_9; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_header_value_te_chunked_last: + s_n_llhttp__internal__n_header_value_te_chunked_last: { + if (p == endp) { + return s_n_llhttp__internal__n_header_value_te_chunked_last; + } + switch (*p) { + case 10: { + goto s_n_llhttp__internal__n_invoke_update_header_state_8; + } + case 13: { + goto s_n_llhttp__internal__n_invoke_update_header_state_8; + } + case ' ': { + p++; + goto s_n_llhttp__internal__n_header_value_te_chunked_last; + } + case ',': { + goto s_n_llhttp__internal__n_invoke_load_type_1; + } + default: { + goto s_n_llhttp__internal__n_header_value_te_token; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_header_value_te_chunked: + s_n_llhttp__internal__n_header_value_te_chunked: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_header_value_te_chunked; + } + match_seq = llparse__match_sequence_to_lower_unsafe(state, p, endp, llparse_blob6, 7); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + goto s_n_llhttp__internal__n_header_value_te_chunked_last; + } + case kMatchPause: { + return s_n_llhttp__internal__n_header_value_te_chunked; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_header_value_te_token; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_span_start_llhttp__on_header_value_1: + s_n_llhttp__internal__n_span_start_llhttp__on_header_value_1: { + if (p == endp) { + return s_n_llhttp__internal__n_span_start_llhttp__on_header_value_1; + } + state->_span_pos0 = (void*) p; + state->_span_cb0 = llhttp__on_header_value; + goto s_n_llhttp__internal__n_invoke_load_header_state_2; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_header_value_discard_ws: + s_n_llhttp__internal__n_header_value_discard_ws: { + if (p == endp) { + return s_n_llhttp__internal__n_header_value_discard_ws; + } + switch (*p) { + case 9: { + p++; + goto s_n_llhttp__internal__n_header_value_discard_ws; + } + case 10: { + p++; + goto s_n_llhttp__internal__n_invoke_test_lenient_flags_4; + } + case 13: { + p++; + goto s_n_llhttp__internal__n_header_value_discard_ws_almost_done; + } + case ' ': { + p++; + goto s_n_llhttp__internal__n_header_value_discard_ws; + } + default: { + goto s_n_llhttp__internal__n_span_start_llhttp__on_header_value_1; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_invoke_llhttp__on_header_field_complete: + s_n_llhttp__internal__n_invoke_llhttp__on_header_field_complete: { + switch (llhttp__on_header_field_complete(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_header_value_discard_ws; + case 21: + goto s_n_llhttp__internal__n_pause_15; + default: + goto s_n_llhttp__internal__n_error_29; + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_header_field_general_otherwise: + s_n_llhttp__internal__n_header_field_general_otherwise: { + if (p == endp) { + return s_n_llhttp__internal__n_header_field_general_otherwise; + } + switch (*p) { + case ':': { + goto s_n_llhttp__internal__n_span_end_llhttp__on_header_field_2; + } + default: { + goto s_n_llhttp__internal__n_error_40; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_header_field_general: + s_n_llhttp__internal__n_header_field_general: { + static uint8_t lookup_table[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + if (p == endp) { + return s_n_llhttp__internal__n_header_field_general; + } + #ifdef __SSE4_2__ + if (endp - p >= 16) { + __m128i ranges; + __m128i input; + int avail; + int match_len; + + /* Load input */ + input = _mm_loadu_si128((__m128i const*) p); + ranges = _mm_loadu_si128((__m128i const*) llparse_blob8); + + /* Find first character that does not match `ranges` */ + match_len = _mm_cmpestri(ranges, 16, + input, 16, + _SIDD_UBYTE_OPS | _SIDD_CMP_RANGES | + _SIDD_NEGATIVE_POLARITY); + + if (match_len != 0) { + p += match_len; + goto s_n_llhttp__internal__n_header_field_general; + } + ranges = _mm_loadu_si128((__m128i const*) llparse_blob9); + + /* Find first character that does not match `ranges` */ + match_len = _mm_cmpestri(ranges, 2, + input, 16, + _SIDD_UBYTE_OPS | _SIDD_CMP_RANGES | + _SIDD_NEGATIVE_POLARITY); + + if (match_len != 0) { + p += match_len; + goto s_n_llhttp__internal__n_header_field_general; + } + goto s_n_llhttp__internal__n_header_field_general_otherwise; + } + #endif /* __SSE4_2__ */ + switch (lookup_table[(uint8_t) *p]) { + case 1: { + p++; + goto s_n_llhttp__internal__n_header_field_general; + } + default: { + goto s_n_llhttp__internal__n_header_field_general_otherwise; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_header_field_colon: + s_n_llhttp__internal__n_header_field_colon: { + if (p == endp) { + return s_n_llhttp__internal__n_header_field_colon; + } + switch (*p) { + case ' ': { + goto s_n_llhttp__internal__n_invoke_test_lenient_flags_3; + } + case ':': { + goto s_n_llhttp__internal__n_span_end_llhttp__on_header_field_1; + } + default: { + goto s_n_llhttp__internal__n_invoke_update_header_state_10; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_header_field_3: + s_n_llhttp__internal__n_header_field_3: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_header_field_3; + } + match_seq = llparse__match_sequence_to_lower(state, p, endp, llparse_blob2, 6); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 1; + goto s_n_llhttp__internal__n_invoke_store_header_state; + } + case kMatchPause: { + return s_n_llhttp__internal__n_header_field_3; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_invoke_update_header_state_11; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_header_field_4: + s_n_llhttp__internal__n_header_field_4: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_header_field_4; + } + match_seq = llparse__match_sequence_to_lower(state, p, endp, llparse_blob10, 10); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 2; + goto s_n_llhttp__internal__n_invoke_store_header_state; + } + case kMatchPause: { + return s_n_llhttp__internal__n_header_field_4; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_invoke_update_header_state_11; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_header_field_2: + s_n_llhttp__internal__n_header_field_2: { + if (p == endp) { + return s_n_llhttp__internal__n_header_field_2; + } + switch (((*p) >= 'A' && (*p) <= 'Z' ? (*p | 0x20) : (*p))) { + case 'n': { + p++; + goto s_n_llhttp__internal__n_header_field_3; + } + case 't': { + p++; + goto s_n_llhttp__internal__n_header_field_4; + } + default: { + goto s_n_llhttp__internal__n_invoke_update_header_state_11; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_header_field_1: + s_n_llhttp__internal__n_header_field_1: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_header_field_1; + } + match_seq = llparse__match_sequence_to_lower(state, p, endp, llparse_blob1, 2); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + goto s_n_llhttp__internal__n_header_field_2; + } + case kMatchPause: { + return s_n_llhttp__internal__n_header_field_1; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_invoke_update_header_state_11; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_header_field_5: + s_n_llhttp__internal__n_header_field_5: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_header_field_5; + } + match_seq = llparse__match_sequence_to_lower(state, p, endp, llparse_blob11, 15); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 1; + goto s_n_llhttp__internal__n_invoke_store_header_state; + } + case kMatchPause: { + return s_n_llhttp__internal__n_header_field_5; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_invoke_update_header_state_11; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_header_field_6: + s_n_llhttp__internal__n_header_field_6: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_header_field_6; + } + match_seq = llparse__match_sequence_to_lower(state, p, endp, llparse_blob12, 16); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 3; + goto s_n_llhttp__internal__n_invoke_store_header_state; + } + case kMatchPause: { + return s_n_llhttp__internal__n_header_field_6; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_invoke_update_header_state_11; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_header_field_7: + s_n_llhttp__internal__n_header_field_7: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_header_field_7; + } + match_seq = llparse__match_sequence_to_lower(state, p, endp, llparse_blob13, 6); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 4; + goto s_n_llhttp__internal__n_invoke_store_header_state; + } + case kMatchPause: { + return s_n_llhttp__internal__n_header_field_7; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_invoke_update_header_state_11; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_header_field: + s_n_llhttp__internal__n_header_field: { + if (p == endp) { + return s_n_llhttp__internal__n_header_field; + } + switch (((*p) >= 'A' && (*p) <= 'Z' ? (*p | 0x20) : (*p))) { + case 'c': { + p++; + goto s_n_llhttp__internal__n_header_field_1; + } + case 'p': { + p++; + goto s_n_llhttp__internal__n_header_field_5; + } + case 't': { + p++; + goto s_n_llhttp__internal__n_header_field_6; + } + case 'u': { + p++; + goto s_n_llhttp__internal__n_header_field_7; + } + default: { + goto s_n_llhttp__internal__n_invoke_update_header_state_11; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_span_start_llhttp__on_header_field: + s_n_llhttp__internal__n_span_start_llhttp__on_header_field: { + if (p == endp) { + return s_n_llhttp__internal__n_span_start_llhttp__on_header_field; + } + state->_span_pos0 = (void*) p; + state->_span_cb0 = llhttp__on_header_field; + goto s_n_llhttp__internal__n_header_field; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_header_field_start: + s_n_llhttp__internal__n_header_field_start: { + if (p == endp) { + return s_n_llhttp__internal__n_header_field_start; + } + switch (*p) { + case 10: { + goto s_n_llhttp__internal__n_headers_almost_done; + } + case 13: { + p++; + goto s_n_llhttp__internal__n_headers_almost_done; + } + default: { + goto s_n_llhttp__internal__n_span_start_llhttp__on_header_field; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_headers_start: + s_n_llhttp__internal__n_headers_start: { + if (p == endp) { + return s_n_llhttp__internal__n_headers_start; + } + switch (*p) { + case ' ': { + p++; + goto s_n_llhttp__internal__n_invoke_test_lenient_flags; + } + default: { + goto s_n_llhttp__internal__n_header_field_start; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_url_skip_to_http09: + s_n_llhttp__internal__n_url_skip_to_http09: { + if (p == endp) { + return s_n_llhttp__internal__n_url_skip_to_http09; + } + p++; + goto s_n_llhttp__internal__n_invoke_update_http_major; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_url_skip_lf_to_http09: + s_n_llhttp__internal__n_url_skip_lf_to_http09: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_url_skip_lf_to_http09; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob14, 2); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + goto s_n_llhttp__internal__n_invoke_update_http_major; + } + case kMatchPause: { + return s_n_llhttp__internal__n_url_skip_lf_to_http09; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_41; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_req_pri_upgrade: + s_n_llhttp__internal__n_req_pri_upgrade: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_req_pri_upgrade; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob16, 10); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + goto s_n_llhttp__internal__n_error_47; + } + case kMatchPause: { + return s_n_llhttp__internal__n_req_pri_upgrade; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_48; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_req_http_complete_1: + s_n_llhttp__internal__n_req_http_complete_1: { + if (p == endp) { + return s_n_llhttp__internal__n_req_http_complete_1; + } + switch (*p) { + case 10: { + p++; + goto s_n_llhttp__internal__n_headers_start; + } + default: { + goto s_n_llhttp__internal__n_error_46; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_req_http_complete: + s_n_llhttp__internal__n_req_http_complete: { + if (p == endp) { + return s_n_llhttp__internal__n_req_http_complete; + } + switch (*p) { + case 10: { + p++; + goto s_n_llhttp__internal__n_headers_start; + } + case 13: { + p++; + goto s_n_llhttp__internal__n_req_http_complete_1; + } + default: { + goto s_n_llhttp__internal__n_error_46; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_invoke_load_method_1: + s_n_llhttp__internal__n_invoke_load_method_1: { + switch (llhttp__internal__c_load_method(state, p, endp)) { + case 34: + goto s_n_llhttp__internal__n_req_pri_upgrade; + default: + goto s_n_llhttp__internal__n_req_http_complete; + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_invoke_llhttp__on_version_complete: + s_n_llhttp__internal__n_invoke_llhttp__on_version_complete: { + switch (llhttp__on_version_complete(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_invoke_load_method_1; + case 21: + goto s_n_llhttp__internal__n_pause_17; + default: + goto s_n_llhttp__internal__n_error_45; + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_error_44: + s_n_llhttp__internal__n_error_44: { + state->error = 0x9; + state->reason = "Invalid HTTP version"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_error_49: + s_n_llhttp__internal__n_error_49: { + state->error = 0x9; + state->reason = "Invalid minor version"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_req_http_minor: + s_n_llhttp__internal__n_req_http_minor: { + if (p == endp) { + return s_n_llhttp__internal__n_req_http_minor; + } + switch (*p) { + case '0': { + p++; + match = 0; + goto s_n_llhttp__internal__n_invoke_store_http_minor; + } + case '1': { + p++; + match = 1; + goto s_n_llhttp__internal__n_invoke_store_http_minor; + } + case '2': { + p++; + match = 2; + goto s_n_llhttp__internal__n_invoke_store_http_minor; + } + case '3': { + p++; + match = 3; + goto s_n_llhttp__internal__n_invoke_store_http_minor; + } + case '4': { + p++; + match = 4; + goto s_n_llhttp__internal__n_invoke_store_http_minor; + } + case '5': { + p++; + match = 5; + goto s_n_llhttp__internal__n_invoke_store_http_minor; + } + case '6': { + p++; + match = 6; + goto s_n_llhttp__internal__n_invoke_store_http_minor; + } + case '7': { + p++; + match = 7; + goto s_n_llhttp__internal__n_invoke_store_http_minor; + } + case '8': { + p++; + match = 8; + goto s_n_llhttp__internal__n_invoke_store_http_minor; + } + case '9': { + p++; + match = 9; + goto s_n_llhttp__internal__n_invoke_store_http_minor; + } + default: { + goto s_n_llhttp__internal__n_span_end_llhttp__on_version_2; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_error_50: + s_n_llhttp__internal__n_error_50: { + state->error = 0x9; + state->reason = "Expected dot"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_req_http_dot: + s_n_llhttp__internal__n_req_http_dot: { + if (p == endp) { + return s_n_llhttp__internal__n_req_http_dot; + } + switch (*p) { + case '.': { + p++; + goto s_n_llhttp__internal__n_req_http_minor; + } + default: { + goto s_n_llhttp__internal__n_span_end_llhttp__on_version_3; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_error_51: + s_n_llhttp__internal__n_error_51: { + state->error = 0x9; + state->reason = "Invalid major version"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_req_http_major: + s_n_llhttp__internal__n_req_http_major: { + if (p == endp) { + return s_n_llhttp__internal__n_req_http_major; + } + switch (*p) { + case '0': { + p++; + match = 0; + goto s_n_llhttp__internal__n_invoke_store_http_major; + } + case '1': { + p++; + match = 1; + goto s_n_llhttp__internal__n_invoke_store_http_major; + } + case '2': { + p++; + match = 2; + goto s_n_llhttp__internal__n_invoke_store_http_major; + } + case '3': { + p++; + match = 3; + goto s_n_llhttp__internal__n_invoke_store_http_major; + } + case '4': { + p++; + match = 4; + goto s_n_llhttp__internal__n_invoke_store_http_major; + } + case '5': { + p++; + match = 5; + goto s_n_llhttp__internal__n_invoke_store_http_major; + } + case '6': { + p++; + match = 6; + goto s_n_llhttp__internal__n_invoke_store_http_major; + } + case '7': { + p++; + match = 7; + goto s_n_llhttp__internal__n_invoke_store_http_major; + } + case '8': { + p++; + match = 8; + goto s_n_llhttp__internal__n_invoke_store_http_major; + } + case '9': { + p++; + match = 9; + goto s_n_llhttp__internal__n_invoke_store_http_major; + } + default: { + goto s_n_llhttp__internal__n_span_end_llhttp__on_version_4; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_span_start_llhttp__on_version: + s_n_llhttp__internal__n_span_start_llhttp__on_version: { + if (p == endp) { + return s_n_llhttp__internal__n_span_start_llhttp__on_version; + } + state->_span_pos0 = (void*) p; + state->_span_cb0 = llhttp__on_version; + goto s_n_llhttp__internal__n_req_http_major; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_req_http_start_1: + s_n_llhttp__internal__n_req_http_start_1: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_req_http_start_1; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob15, 4); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + goto s_n_llhttp__internal__n_invoke_load_method; + } + case kMatchPause: { + return s_n_llhttp__internal__n_req_http_start_1; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_54; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_req_http_start_2: + s_n_llhttp__internal__n_req_http_start_2: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_req_http_start_2; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob17, 3); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + goto s_n_llhttp__internal__n_invoke_load_method_2; + } + case kMatchPause: { + return s_n_llhttp__internal__n_req_http_start_2; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_54; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_req_http_start_3: + s_n_llhttp__internal__n_req_http_start_3: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_req_http_start_3; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob18, 4); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + goto s_n_llhttp__internal__n_invoke_load_method_3; + } + case kMatchPause: { + return s_n_llhttp__internal__n_req_http_start_3; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_54; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_req_http_start: + s_n_llhttp__internal__n_req_http_start: { + if (p == endp) { + return s_n_llhttp__internal__n_req_http_start; + } + switch (*p) { + case ' ': { + p++; + goto s_n_llhttp__internal__n_req_http_start; + } + case 'H': { + p++; + goto s_n_llhttp__internal__n_req_http_start_1; + } + case 'I': { + p++; + goto s_n_llhttp__internal__n_req_http_start_2; + } + case 'R': { + p++; + goto s_n_llhttp__internal__n_req_http_start_3; + } + default: { + goto s_n_llhttp__internal__n_error_54; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_url_skip_to_http: + s_n_llhttp__internal__n_url_skip_to_http: { + if (p == endp) { + return s_n_llhttp__internal__n_url_skip_to_http; + } + p++; + goto s_n_llhttp__internal__n_invoke_llhttp__on_url_complete_1; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_url_fragment: + s_n_llhttp__internal__n_url_fragment: { + static uint8_t lookup_table[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 1, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 + }; + if (p == endp) { + return s_n_llhttp__internal__n_url_fragment; + } + switch (lookup_table[(uint8_t) *p]) { + case 1: { + p++; + goto s_n_llhttp__internal__n_url_fragment; + } + case 2: { + goto s_n_llhttp__internal__n_span_end_llhttp__on_url_6; + } + case 3: { + goto s_n_llhttp__internal__n_span_end_llhttp__on_url_7; + } + case 4: { + goto s_n_llhttp__internal__n_span_end_llhttp__on_url_8; + } + default: { + goto s_n_llhttp__internal__n_error_55; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_span_end_stub_query_3: + s_n_llhttp__internal__n_span_end_stub_query_3: { + if (p == endp) { + return s_n_llhttp__internal__n_span_end_stub_query_3; + } + p++; + goto s_n_llhttp__internal__n_url_fragment; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_url_query: + s_n_llhttp__internal__n_url_query: { + static uint8_t lookup_table[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 1, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 4, 1, 1, 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 + }; + if (p == endp) { + return s_n_llhttp__internal__n_url_query; + } + switch (lookup_table[(uint8_t) *p]) { + case 1: { + p++; + goto s_n_llhttp__internal__n_url_query; + } + case 2: { + goto s_n_llhttp__internal__n_span_end_llhttp__on_url_9; + } + case 3: { + goto s_n_llhttp__internal__n_span_end_llhttp__on_url_10; + } + case 4: { + goto s_n_llhttp__internal__n_span_end_llhttp__on_url_11; + } + case 5: { + goto s_n_llhttp__internal__n_span_end_stub_query_3; + } + default: { + goto s_n_llhttp__internal__n_error_56; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_url_query_or_fragment: + s_n_llhttp__internal__n_url_query_or_fragment: { + if (p == endp) { + return s_n_llhttp__internal__n_url_query_or_fragment; + } + switch (*p) { + case 10: { + goto s_n_llhttp__internal__n_span_end_llhttp__on_url_3; + } + case 13: { + goto s_n_llhttp__internal__n_span_end_llhttp__on_url_4; + } + case ' ': { + goto s_n_llhttp__internal__n_span_end_llhttp__on_url_5; + } + case '#': { + p++; + goto s_n_llhttp__internal__n_url_fragment; + } + case '?': { + p++; + goto s_n_llhttp__internal__n_url_query; + } + default: { + goto s_n_llhttp__internal__n_error_57; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_url_path: + s_n_llhttp__internal__n_url_path: { + static uint8_t lookup_table[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 + }; + if (p == endp) { + return s_n_llhttp__internal__n_url_path; + } + #ifdef __SSE4_2__ + if (endp - p >= 16) { + __m128i ranges; + __m128i input; + int avail; + int match_len; + + /* Load input */ + input = _mm_loadu_si128((__m128i const*) p); + ranges = _mm_loadu_si128((__m128i const*) llparse_blob0); + + /* Find first character that does not match `ranges` */ + match_len = _mm_cmpestri(ranges, 12, + input, 16, + _SIDD_UBYTE_OPS | _SIDD_CMP_RANGES | + _SIDD_NEGATIVE_POLARITY); + + if (match_len != 0) { + p += match_len; + goto s_n_llhttp__internal__n_url_path; + } + goto s_n_llhttp__internal__n_url_query_or_fragment; + } + #endif /* __SSE4_2__ */ + switch (lookup_table[(uint8_t) *p]) { + case 1: { + p++; + goto s_n_llhttp__internal__n_url_path; + } + default: { + goto s_n_llhttp__internal__n_url_query_or_fragment; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_span_start_stub_path_2: + s_n_llhttp__internal__n_span_start_stub_path_2: { + if (p == endp) { + return s_n_llhttp__internal__n_span_start_stub_path_2; + } + p++; + goto s_n_llhttp__internal__n_url_path; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_span_start_stub_path: + s_n_llhttp__internal__n_span_start_stub_path: { + if (p == endp) { + return s_n_llhttp__internal__n_span_start_stub_path; + } + p++; + goto s_n_llhttp__internal__n_url_path; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_span_start_stub_path_1: + s_n_llhttp__internal__n_span_start_stub_path_1: { + if (p == endp) { + return s_n_llhttp__internal__n_span_start_stub_path_1; + } + p++; + goto s_n_llhttp__internal__n_url_path; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_url_server_with_at: + s_n_llhttp__internal__n_url_server_with_at: { + static uint8_t lookup_table[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 3, 4, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 4, 0, 6, + 7, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 4, 0, 4, + 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + if (p == endp) { + return s_n_llhttp__internal__n_url_server_with_at; + } + switch (lookup_table[(uint8_t) *p]) { + case 1: { + goto s_n_llhttp__internal__n_span_end_llhttp__on_url_12; + } + case 2: { + goto s_n_llhttp__internal__n_span_end_llhttp__on_url_13; + } + case 3: { + goto s_n_llhttp__internal__n_span_end_llhttp__on_url_14; + } + case 4: { + p++; + goto s_n_llhttp__internal__n_url_server; + } + case 5: { + goto s_n_llhttp__internal__n_span_start_stub_path_1; + } + case 6: { + p++; + goto s_n_llhttp__internal__n_url_query; + } + case 7: { + p++; + goto s_n_llhttp__internal__n_error_58; + } + default: { + goto s_n_llhttp__internal__n_error_59; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_url_server: + s_n_llhttp__internal__n_url_server: { + static uint8_t lookup_table[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 3, 4, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 4, 0, 6, + 7, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 4, 0, 4, + 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + if (p == endp) { + return s_n_llhttp__internal__n_url_server; + } + switch (lookup_table[(uint8_t) *p]) { + case 1: { + goto s_n_llhttp__internal__n_span_end_llhttp__on_url; + } + case 2: { + goto s_n_llhttp__internal__n_span_end_llhttp__on_url_1; + } + case 3: { + goto s_n_llhttp__internal__n_span_end_llhttp__on_url_2; + } + case 4: { + p++; + goto s_n_llhttp__internal__n_url_server; + } + case 5: { + goto s_n_llhttp__internal__n_span_start_stub_path; + } + case 6: { + p++; + goto s_n_llhttp__internal__n_url_query; + } + case 7: { + p++; + goto s_n_llhttp__internal__n_url_server_with_at; + } + default: { + goto s_n_llhttp__internal__n_error_60; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_url_schema_delim_1: + s_n_llhttp__internal__n_url_schema_delim_1: { + if (p == endp) { + return s_n_llhttp__internal__n_url_schema_delim_1; + } + switch (*p) { + case '/': { + p++; + goto s_n_llhttp__internal__n_url_server; + } + default: { + goto s_n_llhttp__internal__n_error_62; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_url_schema_delim: + s_n_llhttp__internal__n_url_schema_delim: { + if (p == endp) { + return s_n_llhttp__internal__n_url_schema_delim; + } + switch (*p) { + case 10: { + p++; + goto s_n_llhttp__internal__n_error_61; + } + case 13: { + p++; + goto s_n_llhttp__internal__n_error_61; + } + case ' ': { + p++; + goto s_n_llhttp__internal__n_error_61; + } + case '/': { + p++; + goto s_n_llhttp__internal__n_url_schema_delim_1; + } + default: { + goto s_n_llhttp__internal__n_error_62; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_span_end_stub_schema: + s_n_llhttp__internal__n_span_end_stub_schema: { + if (p == endp) { + return s_n_llhttp__internal__n_span_end_stub_schema; + } + p++; + goto s_n_llhttp__internal__n_url_schema_delim; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_url_schema: + s_n_llhttp__internal__n_url_schema: { + static uint8_t lookup_table[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, + 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + if (p == endp) { + return s_n_llhttp__internal__n_url_schema; + } + switch (lookup_table[(uint8_t) *p]) { + case 1: { + p++; + goto s_n_llhttp__internal__n_error_61; + } + case 2: { + goto s_n_llhttp__internal__n_span_end_stub_schema; + } + case 3: { + p++; + goto s_n_llhttp__internal__n_url_schema; + } + default: { + goto s_n_llhttp__internal__n_error_63; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_url_start: + s_n_llhttp__internal__n_url_start: { + static uint8_t lookup_table[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, + 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + if (p == endp) { + return s_n_llhttp__internal__n_url_start; + } + switch (lookup_table[(uint8_t) *p]) { + case 1: { + p++; + goto s_n_llhttp__internal__n_error_61; + } + case 2: { + goto s_n_llhttp__internal__n_span_start_stub_path_2; + } + case 3: { + goto s_n_llhttp__internal__n_url_schema; + } + default: { + goto s_n_llhttp__internal__n_error_64; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_span_start_llhttp__on_url_1: + s_n_llhttp__internal__n_span_start_llhttp__on_url_1: { + if (p == endp) { + return s_n_llhttp__internal__n_span_start_llhttp__on_url_1; + } + state->_span_pos0 = (void*) p; + state->_span_cb0 = llhttp__on_url; + goto s_n_llhttp__internal__n_url_start; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_span_start_llhttp__on_url: + s_n_llhttp__internal__n_span_start_llhttp__on_url: { + if (p == endp) { + return s_n_llhttp__internal__n_span_start_llhttp__on_url; + } + state->_span_pos0 = (void*) p; + state->_span_cb0 = llhttp__on_url; + goto s_n_llhttp__internal__n_url_server; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_req_spaces_before_url: + s_n_llhttp__internal__n_req_spaces_before_url: { + if (p == endp) { + return s_n_llhttp__internal__n_req_spaces_before_url; + } + switch (*p) { + case ' ': { + p++; + goto s_n_llhttp__internal__n_req_spaces_before_url; + } + default: { + goto s_n_llhttp__internal__n_invoke_is_equal_method; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_req_first_space_before_url: + s_n_llhttp__internal__n_req_first_space_before_url: { + if (p == endp) { + return s_n_llhttp__internal__n_req_first_space_before_url; + } + switch (*p) { + case ' ': { + p++; + goto s_n_llhttp__internal__n_req_spaces_before_url; + } + default: { + goto s_n_llhttp__internal__n_error_65; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_invoke_llhttp__on_method_complete_1: + s_n_llhttp__internal__n_invoke_llhttp__on_method_complete_1: { + switch (llhttp__on_method_complete(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_req_first_space_before_url; + case 21: + goto s_n_llhttp__internal__n_pause_22; + default: + goto s_n_llhttp__internal__n_error_76; + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_2: + s_n_llhttp__internal__n_after_start_req_2: { + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_2; + } + switch (*p) { + case 'L': { + p++; + match = 19; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + default: { + goto s_n_llhttp__internal__n_error_77; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_3: + s_n_llhttp__internal__n_after_start_req_3: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_3; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob19, 6); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 36; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_3; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_77; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_1: + s_n_llhttp__internal__n_after_start_req_1: { + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_1; + } + switch (*p) { + case 'C': { + p++; + goto s_n_llhttp__internal__n_after_start_req_2; + } + case 'N': { + p++; + goto s_n_llhttp__internal__n_after_start_req_3; + } + default: { + goto s_n_llhttp__internal__n_error_77; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_4: + s_n_llhttp__internal__n_after_start_req_4: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_4; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob20, 3); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 16; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_4; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_77; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_6: + s_n_llhttp__internal__n_after_start_req_6: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_6; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob21, 6); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 22; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_6; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_77; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_8: + s_n_llhttp__internal__n_after_start_req_8: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_8; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob22, 4); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 5; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_8; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_77; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_9: + s_n_llhttp__internal__n_after_start_req_9: { + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_9; + } + switch (*p) { + case 'Y': { + p++; + match = 8; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + default: { + goto s_n_llhttp__internal__n_error_77; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_7: + s_n_llhttp__internal__n_after_start_req_7: { + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_7; + } + switch (*p) { + case 'N': { + p++; + goto s_n_llhttp__internal__n_after_start_req_8; + } + case 'P': { + p++; + goto s_n_llhttp__internal__n_after_start_req_9; + } + default: { + goto s_n_llhttp__internal__n_error_77; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_5: + s_n_llhttp__internal__n_after_start_req_5: { + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_5; + } + switch (*p) { + case 'H': { + p++; + goto s_n_llhttp__internal__n_after_start_req_6; + } + case 'O': { + p++; + goto s_n_llhttp__internal__n_after_start_req_7; + } + default: { + goto s_n_llhttp__internal__n_error_77; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_12: + s_n_llhttp__internal__n_after_start_req_12: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_12; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob23, 3); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 0; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_12; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_77; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_13: + s_n_llhttp__internal__n_after_start_req_13: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_13; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob24, 5); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 35; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_13; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_77; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_11: + s_n_llhttp__internal__n_after_start_req_11: { + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_11; + } + switch (*p) { + case 'L': { + p++; + goto s_n_llhttp__internal__n_after_start_req_12; + } + case 'S': { + p++; + goto s_n_llhttp__internal__n_after_start_req_13; + } + default: { + goto s_n_llhttp__internal__n_error_77; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_10: + s_n_llhttp__internal__n_after_start_req_10: { + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_10; + } + switch (*p) { + case 'E': { + p++; + goto s_n_llhttp__internal__n_after_start_req_11; + } + default: { + goto s_n_llhttp__internal__n_error_77; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_14: + s_n_llhttp__internal__n_after_start_req_14: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_14; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob25, 4); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 45; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_14; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_77; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_17: + s_n_llhttp__internal__n_after_start_req_17: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_17; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob27, 9); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 41; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_17; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_77; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_16: + s_n_llhttp__internal__n_after_start_req_16: { + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_16; + } + switch (*p) { + case '_': { + p++; + goto s_n_llhttp__internal__n_after_start_req_17; + } + default: { + match = 1; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_15: + s_n_llhttp__internal__n_after_start_req_15: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_15; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob26, 2); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + goto s_n_llhttp__internal__n_after_start_req_16; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_15; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_77; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_18: + s_n_llhttp__internal__n_after_start_req_18: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_18; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob28, 3); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 2; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_18; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_77; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_20: + s_n_llhttp__internal__n_after_start_req_20: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_20; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob29, 2); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 31; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_20; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_77; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_21: + s_n_llhttp__internal__n_after_start_req_21: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_21; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob30, 2); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 9; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_21; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_77; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_19: + s_n_llhttp__internal__n_after_start_req_19: { + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_19; + } + switch (*p) { + case 'I': { + p++; + goto s_n_llhttp__internal__n_after_start_req_20; + } + case 'O': { + p++; + goto s_n_llhttp__internal__n_after_start_req_21; + } + default: { + goto s_n_llhttp__internal__n_error_77; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_23: + s_n_llhttp__internal__n_after_start_req_23: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_23; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob31, 6); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 24; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_23; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_77; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_24: + s_n_llhttp__internal__n_after_start_req_24: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_24; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob32, 3); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 23; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_24; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_77; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_26: + s_n_llhttp__internal__n_after_start_req_26: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_26; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob33, 7); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 21; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_26; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_77; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_28: + s_n_llhttp__internal__n_after_start_req_28: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_28; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob34, 6); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 30; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_28; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_77; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_29: + s_n_llhttp__internal__n_after_start_req_29: { + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_29; + } + switch (*p) { + case 'L': { + p++; + match = 10; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + default: { + goto s_n_llhttp__internal__n_error_77; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_27: + s_n_llhttp__internal__n_after_start_req_27: { + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_27; + } + switch (*p) { + case 'A': { + p++; + goto s_n_llhttp__internal__n_after_start_req_28; + } + case 'O': { + p++; + goto s_n_llhttp__internal__n_after_start_req_29; + } + default: { + goto s_n_llhttp__internal__n_error_77; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_25: + s_n_llhttp__internal__n_after_start_req_25: { + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_25; + } + switch (*p) { + case 'A': { + p++; + goto s_n_llhttp__internal__n_after_start_req_26; + } + case 'C': { + p++; + goto s_n_llhttp__internal__n_after_start_req_27; + } + default: { + goto s_n_llhttp__internal__n_error_77; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_30: + s_n_llhttp__internal__n_after_start_req_30: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_30; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob35, 2); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 11; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_30; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_77; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_22: + s_n_llhttp__internal__n_after_start_req_22: { + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_22; + } + switch (*p) { + case '-': { + p++; + goto s_n_llhttp__internal__n_after_start_req_23; + } + case 'E': { + p++; + goto s_n_llhttp__internal__n_after_start_req_24; + } + case 'K': { + p++; + goto s_n_llhttp__internal__n_after_start_req_25; + } + case 'O': { + p++; + goto s_n_llhttp__internal__n_after_start_req_30; + } + default: { + goto s_n_llhttp__internal__n_error_77; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_31: + s_n_llhttp__internal__n_after_start_req_31: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_31; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob36, 5); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 25; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_31; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_77; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_32: + s_n_llhttp__internal__n_after_start_req_32: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_32; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob37, 6); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 6; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_32; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_77; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_35: + s_n_llhttp__internal__n_after_start_req_35: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_35; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob38, 2); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 28; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_35; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_77; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_36: + s_n_llhttp__internal__n_after_start_req_36: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_36; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob39, 2); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 39; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_36; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_77; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_34: + s_n_llhttp__internal__n_after_start_req_34: { + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_34; + } + switch (*p) { + case 'T': { + p++; + goto s_n_llhttp__internal__n_after_start_req_35; + } + case 'U': { + p++; + goto s_n_llhttp__internal__n_after_start_req_36; + } + default: { + goto s_n_llhttp__internal__n_error_77; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_37: + s_n_llhttp__internal__n_after_start_req_37: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_37; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob40, 2); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 38; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_37; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_77; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_38: + s_n_llhttp__internal__n_after_start_req_38: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_38; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob41, 2); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 3; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_38; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_77; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_42: + s_n_llhttp__internal__n_after_start_req_42: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_42; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob42, 3); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 12; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_42; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_77; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_43: + s_n_llhttp__internal__n_after_start_req_43: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_43; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob43, 4); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 13; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_43; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_77; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_41: + s_n_llhttp__internal__n_after_start_req_41: { + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_41; + } + switch (*p) { + case 'F': { + p++; + goto s_n_llhttp__internal__n_after_start_req_42; + } + case 'P': { + p++; + goto s_n_llhttp__internal__n_after_start_req_43; + } + default: { + goto s_n_llhttp__internal__n_error_77; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_40: + s_n_llhttp__internal__n_after_start_req_40: { + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_40; + } + switch (*p) { + case 'P': { + p++; + goto s_n_llhttp__internal__n_after_start_req_41; + } + default: { + goto s_n_llhttp__internal__n_error_77; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_39: + s_n_llhttp__internal__n_after_start_req_39: { + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_39; + } + switch (*p) { + case 'I': { + p++; + match = 34; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case 'O': { + p++; + goto s_n_llhttp__internal__n_after_start_req_40; + } + default: { + goto s_n_llhttp__internal__n_error_77; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_45: + s_n_llhttp__internal__n_after_start_req_45: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_45; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob44, 2); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 29; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_45; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_77; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_44: + s_n_llhttp__internal__n_after_start_req_44: { + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_44; + } + switch (*p) { + case 'R': { + p++; + goto s_n_llhttp__internal__n_after_start_req_45; + } + case 'T': { + p++; + match = 4; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + default: { + goto s_n_llhttp__internal__n_error_77; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_33: + s_n_llhttp__internal__n_after_start_req_33: { + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_33; + } + switch (*p) { + case 'A': { + p++; + goto s_n_llhttp__internal__n_after_start_req_34; + } + case 'L': { + p++; + goto s_n_llhttp__internal__n_after_start_req_37; + } + case 'O': { + p++; + goto s_n_llhttp__internal__n_after_start_req_38; + } + case 'R': { + p++; + goto s_n_llhttp__internal__n_after_start_req_39; + } + case 'U': { + p++; + goto s_n_llhttp__internal__n_after_start_req_44; + } + default: { + goto s_n_llhttp__internal__n_error_77; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_48: + s_n_llhttp__internal__n_after_start_req_48: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_48; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob45, 3); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 17; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_48; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_77; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_49: + s_n_llhttp__internal__n_after_start_req_49: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_49; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob46, 3); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 44; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_49; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_77; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_50: + s_n_llhttp__internal__n_after_start_req_50: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_50; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob47, 5); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 43; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_50; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_77; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_51: + s_n_llhttp__internal__n_after_start_req_51: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_51; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob48, 3); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 20; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_51; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_77; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_47: + s_n_llhttp__internal__n_after_start_req_47: { + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_47; + } + switch (*p) { + case 'B': { + p++; + goto s_n_llhttp__internal__n_after_start_req_48; + } + case 'C': { + p++; + goto s_n_llhttp__internal__n_after_start_req_49; + } + case 'D': { + p++; + goto s_n_llhttp__internal__n_after_start_req_50; + } + case 'P': { + p++; + goto s_n_llhttp__internal__n_after_start_req_51; + } + default: { + goto s_n_llhttp__internal__n_error_77; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_46: + s_n_llhttp__internal__n_after_start_req_46: { + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_46; + } + switch (*p) { + case 'E': { + p++; + goto s_n_llhttp__internal__n_after_start_req_47; + } + default: { + goto s_n_llhttp__internal__n_error_77; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_54: + s_n_llhttp__internal__n_after_start_req_54: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_54; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob49, 3); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 14; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_54; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_77; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_56: + s_n_llhttp__internal__n_after_start_req_56: { + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_56; + } + switch (*p) { + case 'P': { + p++; + match = 37; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + default: { + goto s_n_llhttp__internal__n_error_77; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_57: + s_n_llhttp__internal__n_after_start_req_57: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_57; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob50, 9); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 42; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_57; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_77; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_55: + s_n_llhttp__internal__n_after_start_req_55: { + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_55; + } + switch (*p) { + case 'U': { + p++; + goto s_n_llhttp__internal__n_after_start_req_56; + } + case '_': { + p++; + goto s_n_llhttp__internal__n_after_start_req_57; + } + default: { + goto s_n_llhttp__internal__n_error_77; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_53: + s_n_llhttp__internal__n_after_start_req_53: { + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_53; + } + switch (*p) { + case 'A': { + p++; + goto s_n_llhttp__internal__n_after_start_req_54; + } + case 'T': { + p++; + goto s_n_llhttp__internal__n_after_start_req_55; + } + default: { + goto s_n_llhttp__internal__n_error_77; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_58: + s_n_llhttp__internal__n_after_start_req_58: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_58; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob51, 4); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 33; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_58; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_77; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_59: + s_n_llhttp__internal__n_after_start_req_59: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_59; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob52, 7); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 26; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_59; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_77; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_52: + s_n_llhttp__internal__n_after_start_req_52: { + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_52; + } + switch (*p) { + case 'E': { + p++; + goto s_n_llhttp__internal__n_after_start_req_53; + } + case 'O': { + p++; + goto s_n_llhttp__internal__n_after_start_req_58; + } + case 'U': { + p++; + goto s_n_llhttp__internal__n_after_start_req_59; + } + default: { + goto s_n_llhttp__internal__n_error_77; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_61: + s_n_llhttp__internal__n_after_start_req_61: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_61; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob53, 6); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 40; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_61; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_77; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_62: + s_n_llhttp__internal__n_after_start_req_62: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_62; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob54, 3); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 7; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_62; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_77; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_60: + s_n_llhttp__internal__n_after_start_req_60: { + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_60; + } + switch (*p) { + case 'E': { + p++; + goto s_n_llhttp__internal__n_after_start_req_61; + } + case 'R': { + p++; + goto s_n_llhttp__internal__n_after_start_req_62; + } + default: { + goto s_n_llhttp__internal__n_error_77; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_65: + s_n_llhttp__internal__n_after_start_req_65: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_65; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob55, 3); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 18; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_65; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_77; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_67: + s_n_llhttp__internal__n_after_start_req_67: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_67; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob56, 2); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 32; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_67; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_77; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_68: + s_n_llhttp__internal__n_after_start_req_68: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_68; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob57, 2); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 15; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_68; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_77; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_66: + s_n_llhttp__internal__n_after_start_req_66: { + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_66; + } + switch (*p) { + case 'I': { + p++; + goto s_n_llhttp__internal__n_after_start_req_67; + } + case 'O': { + p++; + goto s_n_llhttp__internal__n_after_start_req_68; + } + default: { + goto s_n_llhttp__internal__n_error_77; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_69: + s_n_llhttp__internal__n_after_start_req_69: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_69; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob58, 8); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 27; + goto s_n_llhttp__internal__n_invoke_store_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_after_start_req_69; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_77; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_64: + s_n_llhttp__internal__n_after_start_req_64: { + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_64; + } + switch (*p) { + case 'B': { + p++; + goto s_n_llhttp__internal__n_after_start_req_65; + } + case 'L': { + p++; + goto s_n_llhttp__internal__n_after_start_req_66; + } + case 'S': { + p++; + goto s_n_llhttp__internal__n_after_start_req_69; + } + default: { + goto s_n_llhttp__internal__n_error_77; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req_63: + s_n_llhttp__internal__n_after_start_req_63: { + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req_63; + } + switch (*p) { + case 'N': { + p++; + goto s_n_llhttp__internal__n_after_start_req_64; + } + default: { + goto s_n_llhttp__internal__n_error_77; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_after_start_req: + s_n_llhttp__internal__n_after_start_req: { + if (p == endp) { + return s_n_llhttp__internal__n_after_start_req; + } + switch (*p) { + case 'A': { + p++; + goto s_n_llhttp__internal__n_after_start_req_1; + } + case 'B': { + p++; + goto s_n_llhttp__internal__n_after_start_req_4; + } + case 'C': { + p++; + goto s_n_llhttp__internal__n_after_start_req_5; + } + case 'D': { + p++; + goto s_n_llhttp__internal__n_after_start_req_10; + } + case 'F': { + p++; + goto s_n_llhttp__internal__n_after_start_req_14; + } + case 'G': { + p++; + goto s_n_llhttp__internal__n_after_start_req_15; + } + case 'H': { + p++; + goto s_n_llhttp__internal__n_after_start_req_18; + } + case 'L': { + p++; + goto s_n_llhttp__internal__n_after_start_req_19; + } + case 'M': { + p++; + goto s_n_llhttp__internal__n_after_start_req_22; + } + case 'N': { + p++; + goto s_n_llhttp__internal__n_after_start_req_31; + } + case 'O': { + p++; + goto s_n_llhttp__internal__n_after_start_req_32; + } + case 'P': { + p++; + goto s_n_llhttp__internal__n_after_start_req_33; + } + case 'R': { + p++; + goto s_n_llhttp__internal__n_after_start_req_46; + } + case 'S': { + p++; + goto s_n_llhttp__internal__n_after_start_req_52; + } + case 'T': { + p++; + goto s_n_llhttp__internal__n_after_start_req_60; + } + case 'U': { + p++; + goto s_n_llhttp__internal__n_after_start_req_63; + } + default: { + goto s_n_llhttp__internal__n_error_77; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_span_start_llhttp__on_method_1: + s_n_llhttp__internal__n_span_start_llhttp__on_method_1: { + if (p == endp) { + return s_n_llhttp__internal__n_span_start_llhttp__on_method_1; + } + state->_span_pos0 = (void*) p; + state->_span_cb0 = llhttp__on_method; + goto s_n_llhttp__internal__n_after_start_req; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_invoke_llhttp__on_status_complete: + s_n_llhttp__internal__n_invoke_llhttp__on_status_complete: { + switch (llhttp__on_status_complete(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_headers_start; + case 21: + goto s_n_llhttp__internal__n_pause_20; + default: + goto s_n_llhttp__internal__n_error_69; + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_res_line_almost_done: + s_n_llhttp__internal__n_res_line_almost_done: { + if (p == endp) { + return s_n_llhttp__internal__n_res_line_almost_done; + } + p++; + goto s_n_llhttp__internal__n_invoke_llhttp__on_status_complete; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_res_status: + s_n_llhttp__internal__n_res_status: { + if (p == endp) { + return s_n_llhttp__internal__n_res_status; + } + switch (*p) { + case 10: { + goto s_n_llhttp__internal__n_span_end_llhttp__on_status; + } + case 13: { + goto s_n_llhttp__internal__n_span_end_llhttp__on_status_1; + } + default: { + p++; + goto s_n_llhttp__internal__n_res_status; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_span_start_llhttp__on_status: + s_n_llhttp__internal__n_span_start_llhttp__on_status: { + if (p == endp) { + return s_n_llhttp__internal__n_span_start_llhttp__on_status; + } + state->_span_pos0 = (void*) p; + state->_span_cb0 = llhttp__on_status; + goto s_n_llhttp__internal__n_res_status; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_res_status_start: + s_n_llhttp__internal__n_res_status_start: { + if (p == endp) { + return s_n_llhttp__internal__n_res_status_start; + } + switch (*p) { + case 10: { + p++; + goto s_n_llhttp__internal__n_invoke_llhttp__on_status_complete; + } + case 13: { + p++; + goto s_n_llhttp__internal__n_res_line_almost_done; + } + default: { + goto s_n_llhttp__internal__n_span_start_llhttp__on_status; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_res_status_code_otherwise: + s_n_llhttp__internal__n_res_status_code_otherwise: { + if (p == endp) { + return s_n_llhttp__internal__n_res_status_code_otherwise; + } + switch (*p) { + case 10: { + goto s_n_llhttp__internal__n_res_status_start; + } + case 13: { + goto s_n_llhttp__internal__n_res_status_start; + } + case ' ': { + p++; + goto s_n_llhttp__internal__n_res_status_start; + } + default: { + goto s_n_llhttp__internal__n_error_70; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_res_status_code: + s_n_llhttp__internal__n_res_status_code: { + if (p == endp) { + return s_n_llhttp__internal__n_res_status_code; + } + switch (*p) { + case '0': { + p++; + match = 0; + goto s_n_llhttp__internal__n_invoke_mul_add_status_code; + } + case '1': { + p++; + match = 1; + goto s_n_llhttp__internal__n_invoke_mul_add_status_code; + } + case '2': { + p++; + match = 2; + goto s_n_llhttp__internal__n_invoke_mul_add_status_code; + } + case '3': { + p++; + match = 3; + goto s_n_llhttp__internal__n_invoke_mul_add_status_code; + } + case '4': { + p++; + match = 4; + goto s_n_llhttp__internal__n_invoke_mul_add_status_code; + } + case '5': { + p++; + match = 5; + goto s_n_llhttp__internal__n_invoke_mul_add_status_code; + } + case '6': { + p++; + match = 6; + goto s_n_llhttp__internal__n_invoke_mul_add_status_code; + } + case '7': { + p++; + match = 7; + goto s_n_llhttp__internal__n_invoke_mul_add_status_code; + } + case '8': { + p++; + match = 8; + goto s_n_llhttp__internal__n_invoke_mul_add_status_code; + } + case '9': { + p++; + match = 9; + goto s_n_llhttp__internal__n_invoke_mul_add_status_code; + } + default: { + goto s_n_llhttp__internal__n_res_status_code_otherwise; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_res_after_version: + s_n_llhttp__internal__n_res_after_version: { + if (p == endp) { + return s_n_llhttp__internal__n_res_after_version; + } + switch (*p) { + case ' ': { + p++; + goto s_n_llhttp__internal__n_invoke_update_status_code; + } + default: { + goto s_n_llhttp__internal__n_error_71; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_invoke_llhttp__on_version_complete_1: + s_n_llhttp__internal__n_invoke_llhttp__on_version_complete_1: { + switch (llhttp__on_version_complete(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_res_after_version; + case 21: + goto s_n_llhttp__internal__n_pause_21; + default: + goto s_n_llhttp__internal__n_error_67; + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_error_66: + s_n_llhttp__internal__n_error_66: { + state->error = 0x9; + state->reason = "Invalid HTTP version"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_error_72: + s_n_llhttp__internal__n_error_72: { + state->error = 0x9; + state->reason = "Invalid minor version"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_res_http_minor: + s_n_llhttp__internal__n_res_http_minor: { + if (p == endp) { + return s_n_llhttp__internal__n_res_http_minor; + } + switch (*p) { + case '0': { + p++; + match = 0; + goto s_n_llhttp__internal__n_invoke_store_http_minor_1; + } + case '1': { + p++; + match = 1; + goto s_n_llhttp__internal__n_invoke_store_http_minor_1; + } + case '2': { + p++; + match = 2; + goto s_n_llhttp__internal__n_invoke_store_http_minor_1; + } + case '3': { + p++; + match = 3; + goto s_n_llhttp__internal__n_invoke_store_http_minor_1; + } + case '4': { + p++; + match = 4; + goto s_n_llhttp__internal__n_invoke_store_http_minor_1; + } + case '5': { + p++; + match = 5; + goto s_n_llhttp__internal__n_invoke_store_http_minor_1; + } + case '6': { + p++; + match = 6; + goto s_n_llhttp__internal__n_invoke_store_http_minor_1; + } + case '7': { + p++; + match = 7; + goto s_n_llhttp__internal__n_invoke_store_http_minor_1; + } + case '8': { + p++; + match = 8; + goto s_n_llhttp__internal__n_invoke_store_http_minor_1; + } + case '9': { + p++; + match = 9; + goto s_n_llhttp__internal__n_invoke_store_http_minor_1; + } + default: { + goto s_n_llhttp__internal__n_span_end_llhttp__on_version_7; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_error_73: + s_n_llhttp__internal__n_error_73: { + state->error = 0x9; + state->reason = "Expected dot"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_res_http_dot: + s_n_llhttp__internal__n_res_http_dot: { + if (p == endp) { + return s_n_llhttp__internal__n_res_http_dot; + } + switch (*p) { + case '.': { + p++; + goto s_n_llhttp__internal__n_res_http_minor; + } + default: { + goto s_n_llhttp__internal__n_span_end_llhttp__on_version_8; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_error_74: + s_n_llhttp__internal__n_error_74: { + state->error = 0x9; + state->reason = "Invalid major version"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_res_http_major: + s_n_llhttp__internal__n_res_http_major: { + if (p == endp) { + return s_n_llhttp__internal__n_res_http_major; + } + switch (*p) { + case '0': { + p++; + match = 0; + goto s_n_llhttp__internal__n_invoke_store_http_major_1; + } + case '1': { + p++; + match = 1; + goto s_n_llhttp__internal__n_invoke_store_http_major_1; + } + case '2': { + p++; + match = 2; + goto s_n_llhttp__internal__n_invoke_store_http_major_1; + } + case '3': { + p++; + match = 3; + goto s_n_llhttp__internal__n_invoke_store_http_major_1; + } + case '4': { + p++; + match = 4; + goto s_n_llhttp__internal__n_invoke_store_http_major_1; + } + case '5': { + p++; + match = 5; + goto s_n_llhttp__internal__n_invoke_store_http_major_1; + } + case '6': { + p++; + match = 6; + goto s_n_llhttp__internal__n_invoke_store_http_major_1; + } + case '7': { + p++; + match = 7; + goto s_n_llhttp__internal__n_invoke_store_http_major_1; + } + case '8': { + p++; + match = 8; + goto s_n_llhttp__internal__n_invoke_store_http_major_1; + } + case '9': { + p++; + match = 9; + goto s_n_llhttp__internal__n_invoke_store_http_major_1; + } + default: { + goto s_n_llhttp__internal__n_span_end_llhttp__on_version_9; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_span_start_llhttp__on_version_1: + s_n_llhttp__internal__n_span_start_llhttp__on_version_1: { + if (p == endp) { + return s_n_llhttp__internal__n_span_start_llhttp__on_version_1; + } + state->_span_pos0 = (void*) p; + state->_span_cb0 = llhttp__on_version; + goto s_n_llhttp__internal__n_res_http_major; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_start_res: + s_n_llhttp__internal__n_start_res: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_start_res; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob59, 5); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + goto s_n_llhttp__internal__n_span_start_llhttp__on_version_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_start_res; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_78; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_invoke_llhttp__on_method_complete: + s_n_llhttp__internal__n_invoke_llhttp__on_method_complete: { + switch (llhttp__on_method_complete(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_req_first_space_before_url; + case 21: + goto s_n_llhttp__internal__n_pause_19; + default: + goto s_n_llhttp__internal__n_error_1; + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_req_or_res_method_2: + s_n_llhttp__internal__n_req_or_res_method_2: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_req_or_res_method_2; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob60, 2); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + match = 2; + goto s_n_llhttp__internal__n_invoke_store_method; + } + case kMatchPause: { + return s_n_llhttp__internal__n_req_or_res_method_2; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_75; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_invoke_update_type_1: + s_n_llhttp__internal__n_invoke_update_type_1: { + switch (llhttp__internal__c_update_type_1(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version_1; + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_req_or_res_method_3: + s_n_llhttp__internal__n_req_or_res_method_3: { + llparse_match_t match_seq; + + if (p == endp) { + return s_n_llhttp__internal__n_req_or_res_method_3; + } + match_seq = llparse__match_sequence_id(state, p, endp, llparse_blob61, 3); + p = match_seq.current; + switch (match_seq.status) { + case kMatchComplete: { + p++; + goto s_n_llhttp__internal__n_span_end_llhttp__on_method_1; + } + case kMatchPause: { + return s_n_llhttp__internal__n_req_or_res_method_3; + } + case kMatchMismatch: { + goto s_n_llhttp__internal__n_error_75; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_req_or_res_method_1: + s_n_llhttp__internal__n_req_or_res_method_1: { + if (p == endp) { + return s_n_llhttp__internal__n_req_or_res_method_1; + } + switch (*p) { + case 'E': { + p++; + goto s_n_llhttp__internal__n_req_or_res_method_2; + } + case 'T': { + p++; + goto s_n_llhttp__internal__n_req_or_res_method_3; + } + default: { + goto s_n_llhttp__internal__n_error_75; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_req_or_res_method: + s_n_llhttp__internal__n_req_or_res_method: { + if (p == endp) { + return s_n_llhttp__internal__n_req_or_res_method; + } + switch (*p) { + case 'H': { + p++; + goto s_n_llhttp__internal__n_req_or_res_method_1; + } + default: { + goto s_n_llhttp__internal__n_error_75; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_span_start_llhttp__on_method: + s_n_llhttp__internal__n_span_start_llhttp__on_method: { + if (p == endp) { + return s_n_llhttp__internal__n_span_start_llhttp__on_method; + } + state->_span_pos0 = (void*) p; + state->_span_cb0 = llhttp__on_method; + goto s_n_llhttp__internal__n_req_or_res_method; + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_start_req_or_res: + s_n_llhttp__internal__n_start_req_or_res: { + if (p == endp) { + return s_n_llhttp__internal__n_start_req_or_res; + } + switch (*p) { + case 'H': { + goto s_n_llhttp__internal__n_span_start_llhttp__on_method; + } + default: { + goto s_n_llhttp__internal__n_invoke_update_type_2; + } + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_invoke_load_type: + s_n_llhttp__internal__n_invoke_load_type: { + switch (llhttp__internal__c_load_type(state, p, endp)) { + case 1: + goto s_n_llhttp__internal__n_span_start_llhttp__on_method_1; + case 2: + goto s_n_llhttp__internal__n_start_res; + default: + goto s_n_llhttp__internal__n_start_req_or_res; + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_invoke_update_finish: + s_n_llhttp__internal__n_invoke_update_finish: { + switch (llhttp__internal__c_update_finish(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_invoke_llhttp__on_message_begin; + } + /* UNREACHABLE */; + abort(); + } + case s_n_llhttp__internal__n_start: + s_n_llhttp__internal__n_start: { + if (p == endp) { + return s_n_llhttp__internal__n_start; + } + switch (*p) { + case 10: { + p++; + goto s_n_llhttp__internal__n_start; + } + case 13: { + p++; + goto s_n_llhttp__internal__n_start; + } + default: { + goto s_n_llhttp__internal__n_invoke_load_initial_message_completed; + } + } + /* UNREACHABLE */; + abort(); + } + default: + /* UNREACHABLE */ + abort(); + } + s_n_llhttp__internal__n_error_61: { + state->error = 0x7; + state->reason = "Invalid characters in url"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_update_finish_2: { + switch (llhttp__internal__c_update_finish_1(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_start; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_update_initial_message_completed: { + switch (llhttp__internal__c_update_initial_message_completed(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_invoke_update_finish_2; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_update_content_length: { + switch (llhttp__internal__c_update_content_length(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_invoke_update_initial_message_completed; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_test_lenient_flags_1: { + switch (llhttp__internal__c_test_lenient_flags_1(state, p, endp)) { + case 1: + goto s_n_llhttp__internal__n_invoke_update_initial_message_completed; + default: + goto s_n_llhttp__internal__n_closed; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_update_finish_1: { + switch (llhttp__internal__c_update_finish_1(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_invoke_test_lenient_flags_1; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_pause_11: { + state->error = 0x15; + state->reason = "on_message_complete pause"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_is_equal_upgrade; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_24: { + state->error = 0x12; + state->reason = "`on_message_complete` callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_pause_13: { + state->error = 0x15; + state->reason = "on_chunk_complete pause"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_llhttp__on_message_complete_2; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_27: { + state->error = 0x14; + state->reason = "`on_chunk_complete` callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_llhttp__on_chunk_complete_1: { + switch (llhttp__on_chunk_complete(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_invoke_llhttp__on_message_complete_2; + case 21: + goto s_n_llhttp__internal__n_pause_13; + default: + goto s_n_llhttp__internal__n_error_27; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_26: { + state->error = 0x4; + state->reason = "Content-Length can't be present with Transfer-Encoding"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_pause_2: { + state->error = 0x15; + state->reason = "on_message_complete pause"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_pause_1; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_6: { + state->error = 0x12; + state->reason = "`on_message_complete` callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_llhttp__on_message_complete_1: { + switch (llhttp__on_message_complete(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_pause_1; + case 21: + goto s_n_llhttp__internal__n_pause_2; + default: + goto s_n_llhttp__internal__n_error_6; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_22: { + state->error = 0xc; + state->reason = "Chunk size overflow"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_pause_3: { + state->error = 0x15; + state->reason = "on_chunk_complete pause"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_update_content_length_1; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_8: { + state->error = 0x14; + state->reason = "`on_chunk_complete` callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_llhttp__on_chunk_complete: { + switch (llhttp__on_chunk_complete(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_invoke_update_content_length_1; + case 21: + goto s_n_llhttp__internal__n_pause_3; + default: + goto s_n_llhttp__internal__n_error_8; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_body: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_body(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_chunk_data_almost_done; + return s_error; + } + goto s_n_llhttp__internal__n_chunk_data_almost_done; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_or_flags: { + switch (llhttp__internal__c_or_flags(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_header_field_start; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_pause_4: { + state->error = 0x15; + state->reason = "on_chunk_header pause"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_is_equal_content_length; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_7: { + state->error = 0x13; + state->reason = "`on_chunk_header` callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_llhttp__on_chunk_header: { + switch (llhttp__on_chunk_header(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_invoke_is_equal_content_length; + case 21: + goto s_n_llhttp__internal__n_pause_4; + default: + goto s_n_llhttp__internal__n_error_7; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_9: { + state->error = 0x2; + state->reason = "Invalid character in chunk extensions"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_10: { + state->error = 0x2; + state->reason = "Invalid character in chunk extensions"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_pause_5: { + state->error = 0x15; + state->reason = "on_chunk_extension_name pause"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_chunk_size_almost_done; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_11: { + state->error = 0x22; + state->reason = "`on_chunk_extension_name` callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_chunk_extension_name: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_chunk_extension_name(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) (p + 1); + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_name_complete; + return s_error; + } + p++; + goto s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_name_complete; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_pause_6: { + state->error = 0x15; + state->reason = "on_chunk_extension_name pause"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_chunk_extensions; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_12: { + state->error = 0x22; + state->reason = "`on_chunk_extension_name` callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_chunk_extension_name_1: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_chunk_extension_name(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) (p + 1); + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_name_complete_1; + return s_error; + } + p++; + goto s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_name_complete_1; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_pause_7: { + state->error = 0x15; + state->reason = "on_chunk_extension_value pause"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_chunk_size_almost_done; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_14: { + state->error = 0x23; + state->reason = "`on_chunk_extension_value` callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_chunk_extension_value: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_chunk_extension_value(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) (p + 1); + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_value_complete; + return s_error; + } + p++; + goto s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_value_complete; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_16: { + state->error = 0x2; + state->reason = "Invalid character in chunk extensions quote value"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_pause_8: { + state->error = 0x15; + state->reason = "on_chunk_extension_value pause"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_chunk_extension_quoted_value_done; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_15: { + state->error = 0x23; + state->reason = "`on_chunk_extension_value` callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_chunk_extension_value_1: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_chunk_extension_value(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_value_complete_1; + return s_error; + } + goto s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_value_complete_1; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_chunk_extension_value_2: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_chunk_extension_value(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) (p + 1); + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_error_17; + return s_error; + } + p++; + goto s_n_llhttp__internal__n_error_17; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_pause_9: { + state->error = 0x15; + state->reason = "on_chunk_extension_value pause"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_chunk_size_otherwise; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_18: { + state->error = 0x23; + state->reason = "`on_chunk_extension_value` callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_chunk_extension_value_3: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_chunk_extension_value(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) (p + 1); + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_value_complete_2; + return s_error; + } + p++; + goto s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_value_complete_2; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_chunk_extension_value_4: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_chunk_extension_value(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) (p + 1); + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_error_19; + return s_error; + } + p++; + goto s_n_llhttp__internal__n_error_19; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_pause_10: { + state->error = 0x15; + state->reason = "on_chunk_extension_name pause"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_chunk_extension_value; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_13: { + state->error = 0x22; + state->reason = "`on_chunk_extension_name` callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_llhttp__on_chunk_extension_name_complete_2: { + switch (llhttp__on_chunk_extension_name_complete(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_chunk_extension_value; + case 21: + goto s_n_llhttp__internal__n_pause_10; + default: + goto s_n_llhttp__internal__n_error_13; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_chunk_extension_name_2: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_chunk_extension_name(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) (p + 1); + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_span_start_llhttp__on_chunk_extension_value; + return s_error; + } + p++; + goto s_n_llhttp__internal__n_span_start_llhttp__on_chunk_extension_value; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_chunk_extension_name_3: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_chunk_extension_name(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) (p + 1); + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_error_20; + return s_error; + } + p++; + goto s_n_llhttp__internal__n_error_20; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_21: { + state->error = 0xc; + state->reason = "Invalid character in chunk size"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_mul_add_content_length: { + switch (llhttp__internal__c_mul_add_content_length(state, p, endp, match)) { + case 1: + goto s_n_llhttp__internal__n_error_22; + default: + goto s_n_llhttp__internal__n_chunk_size; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_23: { + state->error = 0xc; + state->reason = "Invalid character in chunk size"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_body_1: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_body(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_llhttp__on_message_complete_2; + return s_error; + } + goto s_n_llhttp__internal__n_invoke_llhttp__on_message_complete_2; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_update_finish_3: { + switch (llhttp__internal__c_update_finish_3(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_span_start_llhttp__on_body_2; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_25: { + state->error = 0xf; + state->reason = "Request has invalid `Transfer-Encoding`"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_pause: { + state->error = 0x15; + state->reason = "on_message_complete pause"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_llhttp__after_message_complete; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_5: { + state->error = 0x12; + state->reason = "`on_message_complete` callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_llhttp__on_message_complete: { + switch (llhttp__on_message_complete(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_invoke_llhttp__after_message_complete; + case 21: + goto s_n_llhttp__internal__n_pause; + default: + goto s_n_llhttp__internal__n_error_5; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_or_flags_1: { + switch (llhttp__internal__c_or_flags_1(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_invoke_llhttp__after_headers_complete; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_or_flags_2: { + switch (llhttp__internal__c_or_flags_1(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_invoke_llhttp__after_headers_complete; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_update_upgrade: { + switch (llhttp__internal__c_update_upgrade(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_invoke_or_flags_2; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_pause_12: { + state->error = 0x15; + state->reason = "Paused by on_headers_complete"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_llhttp__after_headers_complete; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_4: { + state->error = 0x11; + state->reason = "User callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_llhttp__on_headers_complete: { + switch (llhttp__on_headers_complete(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_invoke_llhttp__after_headers_complete; + case 1: + goto s_n_llhttp__internal__n_invoke_or_flags_1; + case 2: + goto s_n_llhttp__internal__n_invoke_update_upgrade; + case 21: + goto s_n_llhttp__internal__n_pause_12; + default: + goto s_n_llhttp__internal__n_error_4; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_llhttp__before_headers_complete: { + switch (llhttp__before_headers_complete(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_invoke_llhttp__on_headers_complete; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_test_lenient_flags_2: { + switch (llhttp__internal__c_test_lenient_flags_2(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_error_26; + default: + goto s_n_llhttp__internal__n_invoke_llhttp__before_headers_complete; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_test_flags_1: { + switch (llhttp__internal__c_test_flags_1(state, p, endp)) { + case 1: + goto s_n_llhttp__internal__n_invoke_test_lenient_flags_2; + default: + goto s_n_llhttp__internal__n_invoke_llhttp__before_headers_complete; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_test_flags: { + switch (llhttp__internal__c_test_flags(state, p, endp)) { + case 1: + goto s_n_llhttp__internal__n_invoke_llhttp__on_chunk_complete_1; + default: + goto s_n_llhttp__internal__n_invoke_test_flags_1; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_header_field: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_header_field(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) (p + 1); + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_error_28; + return s_error; + } + p++; + goto s_n_llhttp__internal__n_error_28; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_test_lenient_flags_3: { + switch (llhttp__internal__c_test_lenient_flags(state, p, endp)) { + case 1: + goto s_n_llhttp__internal__n_header_field_colon_discard_ws; + default: + goto s_n_llhttp__internal__n_span_end_llhttp__on_header_field; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_32: { + state->error = 0xb; + state->reason = "Empty Content-Length"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_pause_14: { + state->error = 0x15; + state->reason = "on_header_value_complete pause"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_header_field_start; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_31: { + state->error = 0x1d; + state->reason = "`on_header_value_complete` callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_header_value: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_header_value(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_llhttp__on_header_value_complete; + return s_error; + } + goto s_n_llhttp__internal__n_invoke_llhttp__on_header_value_complete; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_update_header_state: { + switch (llhttp__internal__c_update_header_state(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_span_start_llhttp__on_header_value; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_or_flags_3: { + switch (llhttp__internal__c_or_flags_3(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_invoke_update_header_state; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_or_flags_4: { + switch (llhttp__internal__c_or_flags_4(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_invoke_update_header_state; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_or_flags_5: { + switch (llhttp__internal__c_or_flags_5(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_invoke_update_header_state; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_or_flags_6: { + switch (llhttp__internal__c_or_flags_6(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_span_start_llhttp__on_header_value; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_load_header_state_1: { + switch (llhttp__internal__c_load_header_state(state, p, endp)) { + case 5: + goto s_n_llhttp__internal__n_invoke_or_flags_3; + case 6: + goto s_n_llhttp__internal__n_invoke_or_flags_4; + case 7: + goto s_n_llhttp__internal__n_invoke_or_flags_5; + case 8: + goto s_n_llhttp__internal__n_invoke_or_flags_6; + default: + goto s_n_llhttp__internal__n_span_start_llhttp__on_header_value; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_load_header_state: { + switch (llhttp__internal__c_load_header_state(state, p, endp)) { + case 2: + goto s_n_llhttp__internal__n_error_32; + default: + goto s_n_llhttp__internal__n_invoke_load_header_state_1; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_30: { + state->error = 0xa; + state->reason = "Invalid header value char"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_test_lenient_flags_4: { + switch (llhttp__internal__c_test_lenient_flags(state, p, endp)) { + case 1: + goto s_n_llhttp__internal__n_header_value_discard_lws; + default: + goto s_n_llhttp__internal__n_error_30; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_update_header_state_1: { + switch (llhttp__internal__c_update_header_state_1(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_span_start_llhttp__on_header_value_1; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_load_header_state_3: { + switch (llhttp__internal__c_load_header_state(state, p, endp)) { + case 8: + goto s_n_llhttp__internal__n_invoke_update_header_state_1; + default: + goto s_n_llhttp__internal__n_span_start_llhttp__on_header_value_1; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_update_header_state_2: { + switch (llhttp__internal__c_update_header_state(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_invoke_llhttp__on_header_value_complete; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_or_flags_7: { + switch (llhttp__internal__c_or_flags_3(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_invoke_update_header_state_2; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_or_flags_8: { + switch (llhttp__internal__c_or_flags_4(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_invoke_update_header_state_2; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_or_flags_9: { + switch (llhttp__internal__c_or_flags_5(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_invoke_update_header_state_2; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_or_flags_10: { + switch (llhttp__internal__c_or_flags_6(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_invoke_llhttp__on_header_value_complete; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_load_header_state_4: { + switch (llhttp__internal__c_load_header_state(state, p, endp)) { + case 5: + goto s_n_llhttp__internal__n_invoke_or_flags_7; + case 6: + goto s_n_llhttp__internal__n_invoke_or_flags_8; + case 7: + goto s_n_llhttp__internal__n_invoke_or_flags_9; + case 8: + goto s_n_llhttp__internal__n_invoke_or_flags_10; + default: + goto s_n_llhttp__internal__n_invoke_llhttp__on_header_value_complete; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_33: { + state->error = 0x3; + state->reason = "Missing expected LF after header value"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_header_value_1: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_header_value(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) (p + 1); + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_header_value_almost_done; + return s_error; + } + p++; + goto s_n_llhttp__internal__n_header_value_almost_done; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_header_value_3: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_header_value(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_header_value_almost_done; + return s_error; + } + goto s_n_llhttp__internal__n_header_value_almost_done; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_header_value_4: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_header_value(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) (p + 1); + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_header_value_almost_done; + return s_error; + } + p++; + goto s_n_llhttp__internal__n_header_value_almost_done; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_header_value_2: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_header_value(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_error_34; + return s_error; + } + goto s_n_llhttp__internal__n_error_34; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_test_lenient_flags_5: { + switch (llhttp__internal__c_test_lenient_flags(state, p, endp)) { + case 1: + goto s_n_llhttp__internal__n_header_value_lenient; + default: + goto s_n_llhttp__internal__n_span_end_llhttp__on_header_value_2; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_update_header_state_4: { + switch (llhttp__internal__c_update_header_state(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_header_value_connection; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_or_flags_11: { + switch (llhttp__internal__c_or_flags_3(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_invoke_update_header_state_4; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_or_flags_12: { + switch (llhttp__internal__c_or_flags_4(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_invoke_update_header_state_4; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_or_flags_13: { + switch (llhttp__internal__c_or_flags_5(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_invoke_update_header_state_4; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_or_flags_14: { + switch (llhttp__internal__c_or_flags_6(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_header_value_connection; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_load_header_state_5: { + switch (llhttp__internal__c_load_header_state(state, p, endp)) { + case 5: + goto s_n_llhttp__internal__n_invoke_or_flags_11; + case 6: + goto s_n_llhttp__internal__n_invoke_or_flags_12; + case 7: + goto s_n_llhttp__internal__n_invoke_or_flags_13; + case 8: + goto s_n_llhttp__internal__n_invoke_or_flags_14; + default: + goto s_n_llhttp__internal__n_header_value_connection; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_update_header_state_5: { + switch (llhttp__internal__c_update_header_state_1(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_header_value_connection_token; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_update_header_state_3: { + switch (llhttp__internal__c_update_header_state_3(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_header_value_connection_ws; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_update_header_state_6: { + switch (llhttp__internal__c_update_header_state_6(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_header_value_connection_ws; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_update_header_state_7: { + switch (llhttp__internal__c_update_header_state_7(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_header_value_connection_ws; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_header_value_5: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_header_value(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_error_36; + return s_error; + } + goto s_n_llhttp__internal__n_error_36; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_mul_add_content_length_1: { + switch (llhttp__internal__c_mul_add_content_length_1(state, p, endp, match)) { + case 1: + goto s_n_llhttp__internal__n_span_end_llhttp__on_header_value_5; + default: + goto s_n_llhttp__internal__n_header_value_content_length; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_or_flags_15: { + switch (llhttp__internal__c_or_flags_15(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_header_value_otherwise; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_header_value_6: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_header_value(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_error_37; + return s_error; + } + goto s_n_llhttp__internal__n_error_37; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_35: { + state->error = 0x4; + state->reason = "Duplicate Content-Length"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_test_flags_2: { + switch (llhttp__internal__c_test_flags_2(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_header_value_content_length; + default: + goto s_n_llhttp__internal__n_error_35; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_header_value_8: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_header_value(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) (p + 1); + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_error_39; + return s_error; + } + p++; + goto s_n_llhttp__internal__n_error_39; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_update_header_state_8: { + switch (llhttp__internal__c_update_header_state_8(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_header_value_otherwise; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_header_value_7: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_header_value(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) (p + 1); + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_error_38; + return s_error; + } + p++; + goto s_n_llhttp__internal__n_error_38; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_test_lenient_flags_6: { + switch (llhttp__internal__c_test_lenient_flags_6(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_span_end_llhttp__on_header_value_7; + default: + goto s_n_llhttp__internal__n_header_value_te_chunked; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_load_type_1: { + switch (llhttp__internal__c_load_type(state, p, endp)) { + case 1: + goto s_n_llhttp__internal__n_invoke_test_lenient_flags_6; + default: + goto s_n_llhttp__internal__n_header_value_te_chunked; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_update_header_state_9: { + switch (llhttp__internal__c_update_header_state_1(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_header_value; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_and_flags: { + switch (llhttp__internal__c_and_flags(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_header_value_te_chunked; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_or_flags_17: { + switch (llhttp__internal__c_or_flags_16(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_invoke_and_flags; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_test_lenient_flags_7: { + switch (llhttp__internal__c_test_lenient_flags_6(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_span_end_llhttp__on_header_value_8; + default: + goto s_n_llhttp__internal__n_invoke_or_flags_17; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_load_type_2: { + switch (llhttp__internal__c_load_type(state, p, endp)) { + case 1: + goto s_n_llhttp__internal__n_invoke_test_lenient_flags_7; + default: + goto s_n_llhttp__internal__n_invoke_or_flags_17; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_or_flags_16: { + switch (llhttp__internal__c_or_flags_16(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_invoke_and_flags; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_test_flags_3: { + switch (llhttp__internal__c_test_flags_3(state, p, endp)) { + case 1: + goto s_n_llhttp__internal__n_invoke_load_type_2; + default: + goto s_n_llhttp__internal__n_invoke_or_flags_16; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_or_flags_18: { + switch (llhttp__internal__c_or_flags_18(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_invoke_update_header_state_9; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_load_header_state_2: { + switch (llhttp__internal__c_load_header_state(state, p, endp)) { + case 1: + goto s_n_llhttp__internal__n_header_value_connection; + case 2: + goto s_n_llhttp__internal__n_invoke_test_flags_2; + case 3: + goto s_n_llhttp__internal__n_invoke_test_flags_3; + case 4: + goto s_n_llhttp__internal__n_invoke_or_flags_18; + default: + goto s_n_llhttp__internal__n_header_value; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_pause_15: { + state->error = 0x15; + state->reason = "on_header_field_complete pause"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_header_value_discard_ws; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_29: { + state->error = 0x1c; + state->reason = "`on_header_field_complete` callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_header_field_1: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_header_field(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) (p + 1); + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_llhttp__on_header_field_complete; + return s_error; + } + p++; + goto s_n_llhttp__internal__n_invoke_llhttp__on_header_field_complete; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_header_field_2: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_header_field(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) (p + 1); + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_llhttp__on_header_field_complete; + return s_error; + } + p++; + goto s_n_llhttp__internal__n_invoke_llhttp__on_header_field_complete; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_40: { + state->error = 0xa; + state->reason = "Invalid header token"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_update_header_state_10: { + switch (llhttp__internal__c_update_header_state_1(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_header_field_general; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_store_header_state: { + switch (llhttp__internal__c_store_header_state(state, p, endp, match)) { + default: + goto s_n_llhttp__internal__n_header_field_colon; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_update_header_state_11: { + switch (llhttp__internal__c_update_header_state_1(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_header_field_general; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_3: { + state->error = 0x1e; + state->reason = "Unexpected space after start line"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_test_lenient_flags: { + switch (llhttp__internal__c_test_lenient_flags(state, p, endp)) { + case 1: + goto s_n_llhttp__internal__n_header_field_start; + default: + goto s_n_llhttp__internal__n_error_3; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_pause_16: { + state->error = 0x15; + state->reason = "on_url_complete pause"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_headers_start; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_2: { + state->error = 0x1a; + state->reason = "`on_url_complete` callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_llhttp__on_url_complete: { + switch (llhttp__on_url_complete(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_headers_start; + case 21: + goto s_n_llhttp__internal__n_pause_16; + default: + goto s_n_llhttp__internal__n_error_2; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_update_http_minor: { + switch (llhttp__internal__c_update_http_minor(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_invoke_llhttp__on_url_complete; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_update_http_major: { + switch (llhttp__internal__c_update_http_major(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_invoke_update_http_minor; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_url_3: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_url(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_url_skip_to_http09; + return s_error; + } + goto s_n_llhttp__internal__n_url_skip_to_http09; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_41: { + state->error = 0x7; + state->reason = "Expected CRLF"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_url_4: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_url(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_url_skip_lf_to_http09; + return s_error; + } + goto s_n_llhttp__internal__n_url_skip_lf_to_http09; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_47: { + state->error = 0x17; + state->reason = "Pause on PRI/Upgrade"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_48: { + state->error = 0x9; + state->reason = "Expected HTTP/2 Connection Preface"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_46: { + state->error = 0x9; + state->reason = "Expected CRLF after version"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_pause_17: { + state->error = 0x15; + state->reason = "on_version_complete pause"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_load_method_1; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_45: { + state->error = 0x21; + state->reason = "`on_version_complete` callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_version_1: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_version(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_llhttp__on_version_complete; + return s_error; + } + goto s_n_llhttp__internal__n_invoke_llhttp__on_version_complete; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_version: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_version(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_error_44; + return s_error; + } + goto s_n_llhttp__internal__n_error_44; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_load_http_minor: { + switch (llhttp__internal__c_load_http_minor(state, p, endp)) { + case 9: + goto s_n_llhttp__internal__n_span_end_llhttp__on_version_1; + default: + goto s_n_llhttp__internal__n_span_end_llhttp__on_version; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_load_http_minor_1: { + switch (llhttp__internal__c_load_http_minor(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_span_end_llhttp__on_version_1; + case 1: + goto s_n_llhttp__internal__n_span_end_llhttp__on_version_1; + default: + goto s_n_llhttp__internal__n_span_end_llhttp__on_version; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_load_http_minor_2: { + switch (llhttp__internal__c_load_http_minor(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_span_end_llhttp__on_version_1; + default: + goto s_n_llhttp__internal__n_span_end_llhttp__on_version; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_load_http_major: { + switch (llhttp__internal__c_load_http_major(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_invoke_load_http_minor; + case 1: + goto s_n_llhttp__internal__n_invoke_load_http_minor_1; + case 2: + goto s_n_llhttp__internal__n_invoke_load_http_minor_2; + default: + goto s_n_llhttp__internal__n_span_end_llhttp__on_version; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_test_lenient_flags_8: { + switch (llhttp__internal__c_test_lenient_flags_8(state, p, endp)) { + case 1: + goto s_n_llhttp__internal__n_span_end_llhttp__on_version_1; + default: + goto s_n_llhttp__internal__n_invoke_load_http_major; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_store_http_minor: { + switch (llhttp__internal__c_store_http_minor(state, p, endp, match)) { + default: + goto s_n_llhttp__internal__n_invoke_test_lenient_flags_8; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_version_2: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_version(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_error_49; + return s_error; + } + goto s_n_llhttp__internal__n_error_49; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_version_3: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_version(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_error_50; + return s_error; + } + goto s_n_llhttp__internal__n_error_50; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_store_http_major: { + switch (llhttp__internal__c_store_http_major(state, p, endp, match)) { + default: + goto s_n_llhttp__internal__n_req_http_dot; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_version_4: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_version(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_error_51; + return s_error; + } + goto s_n_llhttp__internal__n_error_51; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_43: { + state->error = 0x8; + state->reason = "Invalid method for HTTP/x.x request"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_load_method: { + switch (llhttp__internal__c_load_method(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 1: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 2: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 3: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 4: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 5: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 6: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 7: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 8: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 9: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 10: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 11: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 12: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 13: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 14: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 15: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 16: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 17: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 18: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 19: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 20: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 21: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 22: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 23: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 24: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 25: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 26: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 27: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 28: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 29: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 30: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 31: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 32: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 33: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 34: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + default: + goto s_n_llhttp__internal__n_error_43; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_54: { + state->error = 0x8; + state->reason = "Expected HTTP/"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_52: { + state->error = 0x8; + state->reason = "Expected SOURCE method for ICE/x.x request"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_load_method_2: { + switch (llhttp__internal__c_load_method(state, p, endp)) { + case 33: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + default: + goto s_n_llhttp__internal__n_error_52; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_53: { + state->error = 0x8; + state->reason = "Invalid method for RTSP/x.x request"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_load_method_3: { + switch (llhttp__internal__c_load_method(state, p, endp)) { + case 1: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 3: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 6: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 35: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 36: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 37: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 38: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 39: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 40: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 41: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 42: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 43: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 44: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + case 45: + goto s_n_llhttp__internal__n_span_start_llhttp__on_version; + default: + goto s_n_llhttp__internal__n_error_53; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_pause_18: { + state->error = 0x15; + state->reason = "on_url_complete pause"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_req_http_start; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_42: { + state->error = 0x1a; + state->reason = "`on_url_complete` callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_llhttp__on_url_complete_1: { + switch (llhttp__on_url_complete(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_req_http_start; + case 21: + goto s_n_llhttp__internal__n_pause_18; + default: + goto s_n_llhttp__internal__n_error_42; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_url_5: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_url(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_url_skip_to_http; + return s_error; + } + goto s_n_llhttp__internal__n_url_skip_to_http; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_url_6: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_url(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_url_skip_to_http09; + return s_error; + } + goto s_n_llhttp__internal__n_url_skip_to_http09; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_url_7: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_url(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_url_skip_lf_to_http09; + return s_error; + } + goto s_n_llhttp__internal__n_url_skip_lf_to_http09; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_url_8: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_url(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_url_skip_to_http; + return s_error; + } + goto s_n_llhttp__internal__n_url_skip_to_http; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_55: { + state->error = 0x7; + state->reason = "Invalid char in url fragment start"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_url_9: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_url(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_url_skip_to_http09; + return s_error; + } + goto s_n_llhttp__internal__n_url_skip_to_http09; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_url_10: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_url(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_url_skip_lf_to_http09; + return s_error; + } + goto s_n_llhttp__internal__n_url_skip_lf_to_http09; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_url_11: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_url(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_url_skip_to_http; + return s_error; + } + goto s_n_llhttp__internal__n_url_skip_to_http; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_56: { + state->error = 0x7; + state->reason = "Invalid char in url query"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_57: { + state->error = 0x7; + state->reason = "Invalid char in url path"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_url: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_url(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_url_skip_to_http09; + return s_error; + } + goto s_n_llhttp__internal__n_url_skip_to_http09; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_url_1: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_url(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_url_skip_lf_to_http09; + return s_error; + } + goto s_n_llhttp__internal__n_url_skip_lf_to_http09; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_url_2: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_url(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_url_skip_to_http; + return s_error; + } + goto s_n_llhttp__internal__n_url_skip_to_http; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_url_12: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_url(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_url_skip_to_http09; + return s_error; + } + goto s_n_llhttp__internal__n_url_skip_to_http09; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_url_13: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_url(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_url_skip_lf_to_http09; + return s_error; + } + goto s_n_llhttp__internal__n_url_skip_lf_to_http09; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_url_14: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_url(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_url_skip_to_http; + return s_error; + } + goto s_n_llhttp__internal__n_url_skip_to_http; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_58: { + state->error = 0x7; + state->reason = "Double @ in url"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_59: { + state->error = 0x7; + state->reason = "Unexpected char in url server"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_60: { + state->error = 0x7; + state->reason = "Unexpected char in url server"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_62: { + state->error = 0x7; + state->reason = "Unexpected char in url schema"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_63: { + state->error = 0x7; + state->reason = "Unexpected char in url schema"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_64: { + state->error = 0x7; + state->reason = "Unexpected start char in url"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_is_equal_method: { + switch (llhttp__internal__c_is_equal_method(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_span_start_llhttp__on_url_1; + default: + goto s_n_llhttp__internal__n_span_start_llhttp__on_url; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_65: { + state->error = 0x6; + state->reason = "Expected space after method"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_pause_22: { + state->error = 0x15; + state->reason = "on_method_complete pause"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_req_first_space_before_url; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_76: { + state->error = 0x20; + state->reason = "`on_method_complete` callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_method_2: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_method(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_llhttp__on_method_complete_1; + return s_error; + } + goto s_n_llhttp__internal__n_invoke_llhttp__on_method_complete_1; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_store_method_1: { + switch (llhttp__internal__c_store_method(state, p, endp, match)) { + default: + goto s_n_llhttp__internal__n_span_end_llhttp__on_method_2; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_77: { + state->error = 0x6; + state->reason = "Invalid method encountered"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_68: { + state->error = 0xd; + state->reason = "Response overflow"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_mul_add_status_code: { + switch (llhttp__internal__c_mul_add_status_code(state, p, endp, match)) { + case 1: + goto s_n_llhttp__internal__n_error_68; + default: + goto s_n_llhttp__internal__n_res_status_code; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_pause_20: { + state->error = 0x15; + state->reason = "on_status_complete pause"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_headers_start; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_69: { + state->error = 0x1b; + state->reason = "`on_status_complete` callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_status: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_status(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) (p + 1); + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_llhttp__on_status_complete; + return s_error; + } + p++; + goto s_n_llhttp__internal__n_invoke_llhttp__on_status_complete; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_status_1: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_status(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) (p + 1); + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_res_line_almost_done; + return s_error; + } + p++; + goto s_n_llhttp__internal__n_res_line_almost_done; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_70: { + state->error = 0xd; + state->reason = "Invalid response status"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_update_status_code: { + switch (llhttp__internal__c_update_status_code(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_res_status_code; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_71: { + state->error = 0x9; + state->reason = "Expected space after version"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_pause_21: { + state->error = 0x15; + state->reason = "on_version_complete pause"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_res_after_version; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_67: { + state->error = 0x21; + state->reason = "`on_version_complete` callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_version_6: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_version(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_llhttp__on_version_complete_1; + return s_error; + } + goto s_n_llhttp__internal__n_invoke_llhttp__on_version_complete_1; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_version_5: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_version(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_error_66; + return s_error; + } + goto s_n_llhttp__internal__n_error_66; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_load_http_minor_3: { + switch (llhttp__internal__c_load_http_minor(state, p, endp)) { + case 9: + goto s_n_llhttp__internal__n_span_end_llhttp__on_version_6; + default: + goto s_n_llhttp__internal__n_span_end_llhttp__on_version_5; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_load_http_minor_4: { + switch (llhttp__internal__c_load_http_minor(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_span_end_llhttp__on_version_6; + case 1: + goto s_n_llhttp__internal__n_span_end_llhttp__on_version_6; + default: + goto s_n_llhttp__internal__n_span_end_llhttp__on_version_5; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_load_http_minor_5: { + switch (llhttp__internal__c_load_http_minor(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_span_end_llhttp__on_version_6; + default: + goto s_n_llhttp__internal__n_span_end_llhttp__on_version_5; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_load_http_major_1: { + switch (llhttp__internal__c_load_http_major(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_invoke_load_http_minor_3; + case 1: + goto s_n_llhttp__internal__n_invoke_load_http_minor_4; + case 2: + goto s_n_llhttp__internal__n_invoke_load_http_minor_5; + default: + goto s_n_llhttp__internal__n_span_end_llhttp__on_version_5; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_test_lenient_flags_9: { + switch (llhttp__internal__c_test_lenient_flags_8(state, p, endp)) { + case 1: + goto s_n_llhttp__internal__n_span_end_llhttp__on_version_6; + default: + goto s_n_llhttp__internal__n_invoke_load_http_major_1; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_store_http_minor_1: { + switch (llhttp__internal__c_store_http_minor(state, p, endp, match)) { + default: + goto s_n_llhttp__internal__n_invoke_test_lenient_flags_9; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_version_7: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_version(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_error_72; + return s_error; + } + goto s_n_llhttp__internal__n_error_72; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_version_8: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_version(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_error_73; + return s_error; + } + goto s_n_llhttp__internal__n_error_73; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_store_http_major_1: { + switch (llhttp__internal__c_store_http_major(state, p, endp, match)) { + default: + goto s_n_llhttp__internal__n_res_http_dot; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_version_9: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_version(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_error_74; + return s_error; + } + goto s_n_llhttp__internal__n_error_74; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_78: { + state->error = 0x8; + state->reason = "Expected HTTP/"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_pause_19: { + state->error = 0x15; + state->reason = "on_method_complete pause"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_req_first_space_before_url; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_1: { + state->error = 0x20; + state->reason = "`on_method_complete` callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_method: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_method(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_llhttp__on_method_complete; + return s_error; + } + goto s_n_llhttp__internal__n_invoke_llhttp__on_method_complete; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_update_type: { + switch (llhttp__internal__c_update_type(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_span_end_llhttp__on_method; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_store_method: { + switch (llhttp__internal__c_store_method(state, p, endp, match)) { + default: + goto s_n_llhttp__internal__n_invoke_update_type; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_75: { + state->error = 0x8; + state->reason = "Invalid word encountered"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_span_end_llhttp__on_method_1: { + const unsigned char* start; + int err; + + start = state->_span_pos0; + state->_span_pos0 = NULL; + err = llhttp__on_method(state, start, p); + if (err != 0) { + state->error = err; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_update_type_1; + return s_error; + } + goto s_n_llhttp__internal__n_invoke_update_type_1; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_update_type_2: { + switch (llhttp__internal__c_update_type(state, p, endp)) { + default: + goto s_n_llhttp__internal__n_span_start_llhttp__on_method_1; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_pause_23: { + state->error = 0x15; + state->reason = "on_message_begin pause"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_load_type; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error: { + state->error = 0x10; + state->reason = "`on_message_begin` callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_llhttp__on_message_begin: { + switch (llhttp__on_message_begin(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_invoke_load_type; + case 21: + goto s_n_llhttp__internal__n_pause_23; + default: + goto s_n_llhttp__internal__n_error; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_pause_24: { + state->error = 0x15; + state->reason = "on_reset pause"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_n_llhttp__internal__n_invoke_update_finish; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_error_79: { + state->error = 0x1f; + state->reason = "`on_reset` callback error"; + state->error_pos = (const char*) p; + state->_current = (void*) (intptr_t) s_error; + return s_error; + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_llhttp__on_reset: { + switch (llhttp__on_reset(state, p, endp)) { + case 0: + goto s_n_llhttp__internal__n_invoke_update_finish; + case 21: + goto s_n_llhttp__internal__n_pause_24; + default: + goto s_n_llhttp__internal__n_error_79; + } + /* UNREACHABLE */; + abort(); + } + s_n_llhttp__internal__n_invoke_load_initial_message_completed: { + switch (llhttp__internal__c_load_initial_message_completed(state, p, endp)) { + case 1: + goto s_n_llhttp__internal__n_invoke_llhttp__on_reset; + default: + goto s_n_llhttp__internal__n_invoke_update_finish; + } + /* UNREACHABLE */; + abort(); + } +} + +int llhttp__internal_execute(llhttp__internal_t* state, const char* p, const char* endp) { + llparse_state_t next; + + /* check lingering errors */ + if (state->error != 0) { + return state->error; + } + + /* restart spans */ + if (state->_span_pos0 != NULL) { + state->_span_pos0 = (void*) p; + } + + next = llhttp__internal__run(state, (const unsigned char*) p, (const unsigned char*) endp); + if (next == s_error) { + return state->error; + } + state->_current = (void*) (intptr_t) next; + + /* execute spans */ + if (state->_span_pos0 != NULL) { + int error; + + error = ((llhttp__internal__span_cb) state->_span_cb0)(state, state->_span_pos0, (const char*) endp); + if (error != 0) { + state->error = error; + state->error_pos = endp; + return error; + } + } + + return 0; +} + +#endif /* LLHTTP_STRICT_MODE */ diff --git a/deps/undici/src/lib/dispatcher/balanced-pool.js b/deps/undici/src/lib/dispatcher/balanced-pool.js index 15a7e7b5879..1e2de289cb7 100644 --- a/deps/undici/src/lib/dispatcher/balanced-pool.js +++ b/deps/undici/src/lib/dispatcher/balanced-pool.js @@ -25,9 +25,23 @@ const kWeight = Symbol('kWeight') const kMaxWeightPerServer = Symbol('kMaxWeightPerServer') const kErrorPenalty = Symbol('kErrorPenalty') +/** + * Calculate the greatest common divisor of two numbers by + * using the Euclidean algorithm. + * + * @param {number} a + * @param {number} b + * @returns {number} + */ function getGreatestCommonDivisor (a, b) { - if (b === 0) return a - return getGreatestCommonDivisor(b, a % b) + if (a === 0) return b + + while (b !== 0) { + const t = b + b = a % b + a = t + } + return a } function defaultFactory (origin, opts) { @@ -105,7 +119,12 @@ class BalancedPool extends PoolBase { } _updateBalancedPoolStats () { - this[kGreatestCommonDivisor] = this[kClients].map(p => p[kWeight]).reduce(getGreatestCommonDivisor, 0) + let result = 0 + for (let i = 0; i < this[kClients].length; i++) { + result = getGreatestCommonDivisor(this[kClients][i][kWeight], result) + } + + this[kGreatestCommonDivisor] = result } removeUpstream (upstream) { diff --git a/deps/undici/src/lib/llhttp/llhttp.wasm b/deps/undici/src/lib/llhttp/llhttp.wasm new file mode 100755 index 00000000000..582dbad4243 Binary files /dev/null and b/deps/undici/src/lib/llhttp/llhttp.wasm differ diff --git a/deps/undici/src/lib/llhttp/llhttp_simd.wasm b/deps/undici/src/lib/llhttp/llhttp_simd.wasm new file mode 100755 index 00000000000..b26d8319e39 Binary files /dev/null and b/deps/undici/src/lib/llhttp/llhttp_simd.wasm differ diff --git a/deps/undici/src/lib/llhttp/wasm_build_env.txt b/deps/undici/src/lib/llhttp/wasm_build_env.txt new file mode 100644 index 00000000000..88676cd7cd0 --- /dev/null +++ b/deps/undici/src/lib/llhttp/wasm_build_env.txt @@ -0,0 +1,60 @@ + +> undici@6.19.8 prebuild:wasm +> node build/wasm.js --prebuild + +> docker build --platform=linux/x86_64 -t llhttp_wasm_builder -f /home/runner/work/node/node/deps/undici/src/build/Dockerfile /home/runner/work/node/node/deps/undici/src + + + +> undici@6.19.8 build:wasm +> node build/wasm.js --docker + +> docker run --rm -t --platform=linux/x86_64 --user 1001:127 --mount type=bind,source=/home/runner/work/node/node/deps/undici/src/lib/llhttp,target=/home/node/undici/lib/llhttp llhttp_wasm_builder node build/wasm.js + + +alpine-baselayout-3.4.3-r2 +alpine-baselayout-data-3.4.3-r2 +alpine-keys-2.4-r1 +apk-tools-2.14.0-r5 +binutils-2.41-r0 +busybox-1.36.1-r15 +busybox-binsh-1.36.1-r15 +ca-certificates-bundle-20230506-r0 +clang17-17.0.5-r0 +clang17-headers-17.0.5-r0 +clang17-libs-17.0.5-r0 +fortify-headers-1.1-r3 +gcc-13.2.1_git20231014-r0 +gmp-6.3.0-r0 +isl26-0.26-r1 +jansson-2.14-r4 +libatomic-13.2.1_git20231014-r0 +libc-utils-0.7.2-r5 +libcrypto3-3.1.4-r5 +libffi-3.4.4-r3 +libgcc-13.2.1_git20231014-r0 +libgomp-13.2.1_git20231014-r0 +libssl3-3.1.4-r5 +libstdc++-13.2.1_git20231014-r0 +libstdc++-dev-13.2.1_git20231014-r0 +libxml2-2.11.8-r0 +lld-17.0.5-r0 +lld-libs-17.0.5-r0 +llvm17-libs-17.0.5-r0 +llvm17-linker-tools-17.0.5-r0 +mpc1-1.3.1-r1 +mpfr4-4.2.1-r0 +musl-1.2.4_git20230717-r4 +musl-dev-1.2.4_git20230717-r4 +musl-utils-1.2.4_git20230717-r4 +scanelf-1.3.7-r2 +scudo-malloc-17.0.5-r0 +ssl_client-1.36.1-r15 +wasi-compiler-rt-17.0.5-r1 +wasi-libc-0.20231012-r0 +wasi-libcxx-17.0.5-r0 +wasi-sdk-20-r3 +xz-libs-5.4.5-r0 +zlib-1.3.1-r0 +zstd-libs-1.5.5-r8 + diff --git a/deps/undici/src/lib/web/fetch/body.js b/deps/undici/src/lib/web/fetch/body.js index 55718ac7c81..464e7b50e5c 100644 --- a/deps/undici/src/lib/web/fetch/body.js +++ b/deps/undici/src/lib/web/fetch/body.js @@ -16,12 +16,25 @@ const { kState } = require('./symbols') const { webidl } = require('./webidl') const { Blob } = require('node:buffer') const assert = require('node:assert') -const { isErrored } = require('../../core/util') +const { isErrored, isDisturbed } = require('node:stream') const { isArrayBuffer } = require('node:util/types') const { serializeAMimeType } = require('./data-url') const { multipartFormDataParser } = require('./formdata-parser') const textEncoder = new TextEncoder() +function noop () {} + +const hasFinalizationRegistry = globalThis.FinalizationRegistry && process.version.indexOf('v18') !== 0 +let streamRegistry + +if (hasFinalizationRegistry) { + streamRegistry = new FinalizationRegistry((weakRef) => { + const stream = weakRef.deref() + if (stream && !stream.locked && !isDisturbed(stream) && !isErrored(stream)) { + stream.cancel('Response object has been garbage collected').catch(noop) + } + }) +} // https://fetch.spec.whatwg.org/#concept-bodyinit-extract function extractBody (object, keepalive = false) { @@ -264,7 +277,7 @@ function safelyExtractBody (object, keepalive = false) { return extractBody(object, keepalive) } -function cloneBody (body) { +function cloneBody (instance, body) { // To clone a body body, run these steps: // https://fetch.spec.whatwg.org/#concept-body-clone @@ -272,6 +285,10 @@ function cloneBody (body) { // 1. Let « out1, out2 » be the result of teeing body’s stream. const [out1, out2] = body.stream.tee() + if (hasFinalizationRegistry) { + streamRegistry.register(instance, new WeakRef(out1)) + } + // 2. Set body’s stream to out1. body.stream = out1 @@ -414,7 +431,7 @@ async function consumeBody (object, convertBytesToJSValue, instance) { // 1. If object is unusable, then return a promise rejected // with a TypeError. - if (bodyUnusable(object[kState].body)) { + if (bodyUnusable(object)) { throw new TypeError('Body is unusable: Body has already been read') } @@ -454,7 +471,9 @@ async function consumeBody (object, convertBytesToJSValue, instance) { } // https://fetch.spec.whatwg.org/#body-unusable -function bodyUnusable (body) { +function bodyUnusable (object) { + const body = object[kState].body + // An object including the Body interface mixin is // said to be unusable if its body is non-null and // its body’s stream is disturbed or locked. @@ -496,5 +515,8 @@ module.exports = { extractBody, safelyExtractBody, cloneBody, - mixinBody + mixinBody, + streamRegistry, + hasFinalizationRegistry, + bodyUnusable } diff --git a/deps/undici/src/lib/web/fetch/request.js b/deps/undici/src/lib/web/fetch/request.js index bc436aa9705..542ea7fb28a 100644 --- a/deps/undici/src/lib/web/fetch/request.js +++ b/deps/undici/src/lib/web/fetch/request.js @@ -2,7 +2,7 @@ 'use strict' -const { extractBody, mixinBody, cloneBody } = require('./body') +const { extractBody, mixinBody, cloneBody, bodyUnusable } = require('./body') const { Headers, fill: fillHeaders, HeadersList, setHeadersGuard, getHeadersGuard, setHeadersList, getHeadersList } = require('./headers') const { FinalizationRegistry } = require('./dispatcher-weakref')() const util = require('../../core/util') @@ -557,7 +557,7 @@ class Request { // 40. If initBody is null and inputBody is non-null, then: if (initBody == null && inputBody != null) { // 1. If input is unusable, then throw a TypeError. - if (util.isDisturbed(inputBody.stream) || inputBody.stream.locked) { + if (bodyUnusable(input)) { throw new TypeError( 'Cannot construct a Request with a Request object that has already been used.' ) @@ -759,7 +759,7 @@ class Request { webidl.brandCheck(this, Request) // 1. If this is unusable, then throw a TypeError. - if (this.bodyUsed || this.body?.locked) { + if (bodyUnusable(this)) { throw new TypeError('unusable') } @@ -877,7 +877,7 @@ function cloneRequest (request) { // 2. If request’s body is non-null, set newRequest’s body to the // result of cloning request’s body. if (request.body != null) { - newRequest.body = cloneBody(request.body) + newRequest.body = cloneBody(newRequest, request.body) } // 3. Return newRequest. diff --git a/deps/undici/src/lib/web/fetch/response.js b/deps/undici/src/lib/web/fetch/response.js index 8c00835698e..155dbadd1ad 100644 --- a/deps/undici/src/lib/web/fetch/response.js +++ b/deps/undici/src/lib/web/fetch/response.js @@ -1,7 +1,7 @@ 'use strict' const { Headers, HeadersList, fill, getHeadersGuard, setHeadersGuard, setHeadersList } = require('./headers') -const { extractBody, cloneBody, mixinBody } = require('./body') +const { extractBody, cloneBody, mixinBody, hasFinalizationRegistry, streamRegistry, bodyUnusable } = require('./body') const util = require('../../core/util') const nodeUtil = require('node:util') const { kEnumerableProperty } = util @@ -26,23 +26,9 @@ const { URLSerializer } = require('./data-url') const { kConstruct } = require('../../core/symbols') const assert = require('node:assert') const { types } = require('node:util') -const { isDisturbed, isErrored } = require('node:stream') const textEncoder = new TextEncoder('utf-8') -const hasFinalizationRegistry = globalThis.FinalizationRegistry && process.version.indexOf('v18') !== 0 -let registry - -if (hasFinalizationRegistry) { - registry = new FinalizationRegistry((stream) => { - if (!stream.locked && !isDisturbed(stream) && !isErrored(stream)) { - stream.cancel('Response object has been garbage collected').catch(noop) - } - }) -} - -function noop () {} - // https://fetch.spec.whatwg.org/#response-class class Response { // Creates network error Response. @@ -243,7 +229,7 @@ class Response { webidl.brandCheck(this, Response) // 1. If this is unusable, then throw a TypeError. - if (this.bodyUsed || this.body?.locked) { + if (bodyUnusable(this)) { throw webidl.errors.exception({ header: 'Response.clone', message: 'Body has already been consumed.' @@ -326,7 +312,7 @@ function cloneResponse (response) { // 3. If response’s body is non-null, then set newResponse’s body to the // result of cloning response’s body. if (response.body != null) { - newResponse.body = cloneBody(response.body) + newResponse.body = cloneBody(newResponse, response.body) } // 4. Return newResponse. @@ -526,7 +512,12 @@ function fromInnerResponse (innerResponse, guard) { setHeadersGuard(response[kHeaders], guard) if (hasFinalizationRegistry && innerResponse.body?.stream) { - registry.register(response, innerResponse.body.stream) + // If the target (response) is reclaimed, the cleanup callback may be called at some point with + // the held value provided for it (innerResponse.body.stream). The held value can be any value: + // a primitive or an object, even undefined. If the held value is an object, the registry keeps + // a strong reference to it (so it can pass it to the cleanup callback later). Reworded from + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/FinalizationRegistry + streamRegistry.register(response, new WeakRef(innerResponse.body.stream)) } return response diff --git a/deps/undici/src/package-lock.json b/deps/undici/src/package-lock.json index 91ada55a0d9..67e74b4e445 100644 --- a/deps/undici/src/package-lock.json +++ b/deps/undici/src/package-lock.json @@ -1,12 +1,12 @@ { "name": "undici", - "version": "6.19.2", + "version": "6.19.8", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "undici", - "version": "6.19.2", + "version": "6.19.8", "license": "MIT", "devDependencies": { "@fastify/busboy": "2.1.1", @@ -50,9 +50,9 @@ } }, "node_modules/@actions/http-client": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.2.1.tgz", - "integrity": "sha512-KhC/cZsq7f8I4LfZSJKgCvEwfkE8o1538VoBeoGzokVLLnbFDEAdFD3UhoMklxo2un9NJVBdANOresx7vTHlHw==", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.2.2.tgz", + "integrity": "sha512-2TvX5LskKQzDDQI+bobIDGAjkn0NJiQlg4MTrKnZ8HfQ7nDEUbtJ1ytxPDb2bfk3Hr2XD99X8oAJISAmIoiSAQ==", "dev": true, "license": "MIT", "dependencies": { @@ -89,9 +89,9 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.7.tgz", - "integrity": "sha512-qJzAIcv03PyaWqxRgO4mSU3lihncDT296vnyuE2O8uA4w3UHWI4S3hgeZd1L8W1Bft40w9JxJ2b412iDUFFRhw==", + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.2.tgz", + "integrity": "sha512-bYcppcpKBvX4znYaPEeFau03bp89ShqNMLs+rmdptMw+heSZh9+z84d2YG+K7cYLbWwzdjtDoW/uqZmPjulClQ==", "dev": true, "license": "MIT", "engines": { @@ -99,22 +99,22 @@ } }, "node_modules/@babel/core": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.7.tgz", - "integrity": "sha512-nykK+LEK86ahTkX/3TgauT0ikKoNCfKHEaZYTUVupJdTLzGNvrblu4u6fa7DhZONAltdf8e662t/abY8idrd/g==", + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.25.2.tgz", + "integrity": "sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==", "dev": true, "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.24.7", - "@babel/helper-compilation-targets": "^7.24.7", - "@babel/helper-module-transforms": "^7.24.7", - "@babel/helpers": "^7.24.7", - "@babel/parser": "^7.24.7", - "@babel/template": "^7.24.7", - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7", + "@babel/generator": "^7.25.0", + "@babel/helper-compilation-targets": "^7.25.2", + "@babel/helper-module-transforms": "^7.25.2", + "@babel/helpers": "^7.25.0", + "@babel/parser": "^7.25.0", + "@babel/template": "^7.25.0", + "@babel/traverse": "^7.25.2", + "@babel/types": "^7.25.2", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -130,13 +130,13 @@ } }, "node_modules/@babel/generator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.7.tgz", - "integrity": "sha512-oipXieGC3i45Y1A41t4tAqpnEZWgB/lC6Ehh6+rOviR5XWpTtMmLN+fGjz9vOiNRt0p6RtO6DtD0pdU3vpqdSA==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.0.tgz", + "integrity": "sha512-3LEEcj3PVW8pW2R1SR1M89g/qrYk/m/mB/tLqn7dn4sbBUQyTqnlod+II2U4dqiGtUmkcnAmkMDralTFZttRiw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.24.7", + "@babel/types": "^7.25.0", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^2.5.1" @@ -146,15 +146,15 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.7.tgz", - "integrity": "sha512-ctSdRHBi20qWOfy27RUb4Fhp07KSJ3sXcuSvTrXrc4aG8NSYDo1ici3Vhg9bg69y5bj0Mr1lh0aeEgTvc12rMg==", + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.2.tgz", + "integrity": "sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.24.7", - "@babel/helper-validator-option": "^7.24.7", - "browserslist": "^4.22.2", + "@babel/compat-data": "^7.25.2", + "@babel/helper-validator-option": "^7.24.8", + "browserslist": "^4.23.1", "lru-cache": "^5.1.1", "semver": "^6.3.1" }, @@ -162,46 +162,6 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/helper-environment-visitor": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz", - "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-function-name": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz", - "integrity": "sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/template": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.7.tgz", - "integrity": "sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-module-imports": { "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", @@ -217,17 +177,16 @@ } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.7.tgz", - "integrity": "sha512-1fuJEwIrp+97rM4RWdO+qrRsZlAeL1lQJoPqtCYWv0NL115XM93hIH4CSRln2w52SqvmY5hqdtauB6QFCDiZNQ==", + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.25.2.tgz", + "integrity": "sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-environment-visitor": "^7.24.7", "@babel/helper-module-imports": "^7.24.7", "@babel/helper-simple-access": "^7.24.7", - "@babel/helper-split-export-declaration": "^7.24.7", - "@babel/helper-validator-identifier": "^7.24.7" + "@babel/helper-validator-identifier": "^7.24.7", + "@babel/traverse": "^7.25.2" }, "engines": { "node": ">=6.9.0" @@ -237,9 +196,9 @@ } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", - "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz", + "integrity": "sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==", "dev": true, "license": "MIT", "engines": { @@ -260,23 +219,10 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", - "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-string-parser": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz", - "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz", + "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==", "dev": true, "license": "MIT", "engines": { @@ -294,9 +240,9 @@ } }, "node_modules/@babel/helper-validator-option": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.7.tgz", - "integrity": "sha512-yy1/KvjhV/ZCL+SM7hBrvnZJ3ZuT9OuZgIJAGpPEToANvc3iM6iDvBnRjtElWibHU6n8/LPR/EjX9EtIEYO3pw==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz", + "integrity": "sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==", "dev": true, "license": "MIT", "engines": { @@ -304,14 +250,14 @@ } }, "node_modules/@babel/helpers": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.7.tgz", - "integrity": "sha512-NlmJJtvcw72yRJRcnCmGvSi+3jDEg8qFu3z0AFoymmzLx5ERVWyzd9kVXr7Th9/8yIJi2Zc6av4Tqz3wFs8QWg==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.0.tgz", + "integrity": "sha512-MjgLZ42aCm0oGjJj8CtSM3DB8NOOf8h2l7DCTePJs29u+v7yO/RBX9nShlKMgFnRks/Q4tBAe7Hxnov9VkGwLw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/template": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/template": "^7.25.0", + "@babel/types": "^7.25.0" }, "engines": { "node": ">=6.9.0" @@ -412,11 +358,14 @@ } }, "node_modules/@babel/parser": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.7.tgz", - "integrity": "sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==", + "version": "7.25.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.3.tgz", + "integrity": "sha512-iLTJKDbJ4hMvFPgQwwsVoxtHyWpKKPBrxkANrSYewDPaPpT5py5yeVkgPIJ7XYXhndxJpaA3PyALSXQ7u8e/Dw==", "dev": true, "license": "MIT", + "dependencies": { + "@babel/types": "^7.25.2" + }, "bin": { "parser": "bin/babel-parser.js" }, @@ -463,6 +412,38 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.24.7.tgz", + "integrity": "sha512-hbX+lKKeUMGihnK8nvKqmXBInriT3GVjzXKFriV3YC6APGxMbP8RZNFwy91+hocLXq90Mta+HshoB31802bb8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/plugin-syntax-import-meta": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", @@ -583,6 +564,22 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/plugin-syntax-top-level-await": { "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", @@ -616,35 +613,32 @@ } }, "node_modules/@babel/template": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz", - "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.0.tgz", + "integrity": "sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==", "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.24.7", - "@babel/parser": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/parser": "^7.25.0", + "@babel/types": "^7.25.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.7.tgz", - "integrity": "sha512-yb65Ed5S/QAcewNPh0nZczy9JdYXkkAbIsEo+P7BE7yO3txAY30Y/oPa3QkQ5It3xVG2kpKMg9MsdxZaO31uKA==", + "version": "7.25.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.3.tgz", + "integrity": "sha512-HefgyP1x754oGCsKmV5reSmtV7IXj/kpaE1XYY+D9G5PvKKoFfSbiS4M77MdjuwlZKDIKFCffq9rPU+H/s3ZdQ==", "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.24.7", - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-function-name": "^7.24.7", - "@babel/helper-hoist-variables": "^7.24.7", - "@babel/helper-split-export-declaration": "^7.24.7", - "@babel/parser": "^7.24.7", - "@babel/types": "^7.24.7", + "@babel/generator": "^7.25.0", + "@babel/parser": "^7.25.3", + "@babel/template": "^7.25.0", + "@babel/types": "^7.25.2", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -653,13 +647,13 @@ } }, "node_modules/@babel/types": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", - "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.2.tgz", + "integrity": "sha512-YTnYtra7W9e6/oAZEHj0bJehPRUlLH9/fbpT5LfB0NhQXyALCRkRs3zH9v07IYhkgpqX6Z78FnuccZr/l4Fs4Q==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.24.7", + "@babel/helper-string-parser": "^7.24.8", "@babel/helper-validator-identifier": "^7.24.7", "to-fast-properties": "^2.0.0" }, @@ -691,9 +685,9 @@ } }, "node_modules/@eslint-community/regexpp": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.1.tgz", - "integrity": "sha512-Zm2NGpWELsQAD1xsJzGQpYfvICSsFkEpU0jxBjfdC6uNEWXcHnfs9hScFWtXVDVl+rBQJGrl4g1vcKIejpH9dA==", + "version": "4.11.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz", + "integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==", "dev": true, "license": "MIT", "engines": { @@ -1420,9 +1414,9 @@ } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", "dev": true, "license": "MIT" }, @@ -1670,9 +1664,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "18.19.36", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.36.tgz", - "integrity": "sha512-tX1BNmYSWEvViftB26VLNxT6mEr37M7+ldUtq7rlKnv4/2fKYsJIOmqJAjT6h1DNuwQjIKgw3VJ/Dtw3yiTIQw==", + "version": "18.19.45", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.45.tgz", + "integrity": "sha512-VZxPKNNhjKmaC1SUYowuXSRSMGyQGmQjvvA1xE4QZ0xce2kLtEhPDS+kqpCPBZYgqblCLQ2DAjSzmgCM5auvhA==", "dev": true, "license": "MIT", "dependencies": { @@ -1704,9 +1698,9 @@ "license": "MIT" }, "node_modules/@types/yargs": { - "version": "17.0.32", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", - "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", + "version": "17.0.33", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz", + "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==", "dev": true, "license": "MIT", "dependencies": { @@ -1741,9 +1735,9 @@ } }, "node_modules/acorn": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.0.tgz", - "integrity": "sha512-RTvkC4w+KNXrM39/lWCUaG0IbRkWdCv7W/IOW9oU6SawyxulvkQy5HQPVTKxEjczcUvapcrw3cFx/60VN/NRNw==", + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", "dev": true, "license": "MIT", "bin": { @@ -2104,19 +2098,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/array.prototype.toreversed": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/array.prototype.toreversed/-/array.prototype.toreversed-1.1.2.tgz", - "integrity": "sha512-wwDCoT4Ck4Cz7sLtgUmzR5UV3YF5mFHUlbChCzZBQZ+0m2cl/DH3tKgvphv1nKgFsJ48oCSg6p91q2Vm0I/ZMA==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" - } - }, "node_modules/array.prototype.tosorted": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz", @@ -2324,24 +2305,27 @@ } }, "node_modules/babel-preset-current-node-syntax": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", - "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.1.0.tgz", + "integrity": "sha512-ldYss8SbBlWva1bs28q78Ju5Zq1F+8BrqBZZ0VFhLBvhh6lCpC2o3gDJi/5DRLs9FgYZCnmPYIVFU4lRXCkyUw==", "dev": true, "license": "MIT", "dependencies": { "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.8.3", - "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-import-attributes": "^7.24.7", + "@babel/plugin-syntax-import-meta": "^7.10.4", "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-top-level-await": "^7.8.3" + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5" }, "peerDependencies": { "@babel/core": "^7.0.0" @@ -2418,9 +2402,9 @@ } }, "node_modules/browserslist": { - "version": "4.23.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.1.tgz", - "integrity": "sha512-TUfofFo/KsK/bWZ9TWQ5O26tsWW4Uhmt8IYklbnUa70udB6P2wA7w7o4PY4muaEPBQaAX+CEnmmIA41NVHtPVw==", + "version": "4.23.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.3.tgz", + "integrity": "sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==", "dev": true, "funding": [ { @@ -2438,10 +2422,10 @@ ], "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001629", - "electron-to-chromium": "^1.4.796", - "node-releases": "^2.0.14", - "update-browserslist-db": "^1.0.16" + "caniuse-lite": "^1.0.30001646", + "electron-to-chromium": "^1.5.4", + "node-releases": "^2.0.18", + "update-browserslist-db": "^1.1.0" }, "bin": { "browserslist": "cli.js" @@ -2478,9 +2462,9 @@ } }, "node_modules/builtins/node_modules/semver": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "dev": true, "license": "ISC", "bin": { @@ -2642,9 +2626,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001636", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001636.tgz", - "integrity": "sha512-bMg2vmr8XBsbL6Lr0UHXy/21m84FTxDLWn2FSqMd5PrlbMxwJlQnC2YWYxVgp66PZE+BBNF2jYQUBKCo1FDeZg==", + "version": "1.0.30001651", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001651.tgz", + "integrity": "sha512-9Cf+Xv1jJNe1xPZLGuUXLNkE1BoDkqRqYyFJ9TDYSqhduqA4hu4oR9HluGoWYQC/aj8WHjsGVV+bwkh0+tegRg==", "dev": true, "funding": [ { @@ -3063,9 +3047,9 @@ } }, "node_modules/debug": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", - "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", + "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==", "dev": true, "license": "MIT", "dependencies": { @@ -3269,9 +3253,9 @@ "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.4.805", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.805.tgz", - "integrity": "sha512-8W4UJwX/w9T0QSzINJckTKG6CYpAUTqsaWcWIsdud3I1FYJcMgW9QqT1/4CBff/pP/TihWh13OmiyY8neto6vw==", + "version": "1.5.11", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.11.tgz", + "integrity": "sha512-R1CccCDYqndR25CaXFd6hp/u9RaaMcftMkphmvuepXr5b1vfLkRml6aWVeBhXJ7rbevHkKEMJtz8XqPf7ffmew==", "dev": true, "license": "ISC" }, @@ -3909,9 +3893,9 @@ } }, "node_modules/eslint-plugin-n/node_modules/semver": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "dev": true, "license": "ISC", "bin": { @@ -3922,9 +3906,9 @@ } }, "node_modules/eslint-plugin-promise": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-6.2.0.tgz", - "integrity": "sha512-QmAqwizauvnKOlifxyDj2ObfULpHQawlg/zQdgEixur9vl0CvZGv/LCJV2rtj3210QCoeGBzVMfMXqGAOr/4fA==", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-6.6.0.tgz", + "integrity": "sha512-57Zzfw8G6+Gq7axm2Pdo3gW/Rx3h9Yywgn61uE/3elTCOePEHVrn2i5CdfBwA1BLK0Q0WqctICIUSqXZW/VprQ==", "dev": true, "license": "ISC", "engines": { @@ -3938,36 +3922,36 @@ } }, "node_modules/eslint-plugin-react": { - "version": "7.34.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.34.2.tgz", - "integrity": "sha512-2HCmrU+/JNigDN6tg55cRDKCQWicYAPB38JGSFDQt95jDm8rrvSUo7YPkOIm5l6ts1j1zCvysNcasvfTMQzUOw==", + "version": "7.35.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.35.0.tgz", + "integrity": "sha512-v501SSMOWv8gerHkk+IIQBkcGRGrO2nfybfj5pLxuJNFTPxxA3PSryhXTK+9pNbtkggheDdsC0E9Q8CuPk6JKA==", "dev": true, "license": "MIT", "dependencies": { "array-includes": "^3.1.8", "array.prototype.findlast": "^1.2.5", "array.prototype.flatmap": "^1.3.2", - "array.prototype.toreversed": "^1.1.2", - "array.prototype.tosorted": "^1.1.3", + "array.prototype.tosorted": "^1.1.4", "doctrine": "^2.1.0", "es-iterator-helpers": "^1.0.19", "estraverse": "^5.3.0", + "hasown": "^2.0.2", "jsx-ast-utils": "^2.4.1 || ^3.0.0", "minimatch": "^3.1.2", "object.entries": "^1.1.8", "object.fromentries": "^2.0.8", - "object.hasown": "^1.1.4", "object.values": "^1.2.0", "prop-types": "^15.8.1", "resolve": "^2.0.0-next.5", "semver": "^6.3.1", - "string.prototype.matchall": "^4.0.11" + "string.prototype.matchall": "^4.0.11", + "string.prototype.repeat": "^1.0.0" }, "engines": { "node": ">=4" }, "peerDependencies": { - "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" } }, "node_modules/eslint-plugin-react/node_modules/brace-expansion": { @@ -4292,9 +4276,9 @@ } }, "node_modules/esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -4398,9 +4382,9 @@ } }, "node_modules/fast-check": { - "version": "3.19.0", - "resolved": "https://registry.npmjs.org/fast-check/-/fast-check-3.19.0.tgz", - "integrity": "sha512-CO2JX/8/PT9bDGO1iXa5h5ey1skaKI1dvecERyhH4pp3PGjwd3KIjMAXEg79Ps9nclsdt4oPbfqiAnLU0EwrAQ==", + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/fast-check/-/fast-check-3.21.0.tgz", + "integrity": "sha512-QpmbiqRFRZ+SIlBJh6xi5d/PgXciUc/xWKc4Vi2RWEHHIRx6oM3f0fWNna++zP9VB5HUBTObUK9gTKQP3vVcrQ==", "dev": true, "funding": [ { @@ -4568,9 +4552,9 @@ } }, "node_modules/foreground-child": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.2.1.tgz", - "integrity": "sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", + "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", "dev": true, "license": "ISC", "dependencies": { @@ -4765,9 +4749,9 @@ } }, "node_modules/glob": { - "version": "10.4.1", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.1.tgz", - "integrity": "sha512-2jelhlq3E4ho74ZyVLN03oKdAZVUa6UDZzFLVH1H7dnoax+y9qyaq8zBkfDIggjniU19z0wU18y16jMB2eyVIw==", + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", "dev": true, "license": "ISC", "dependencies": { @@ -4775,14 +4759,12 @@ "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": { "glob": "dist/esm/bin.mjs" }, - "engines": { - "node": ">=16 || 14 >=14.18" - }, "funding": { "url": "https://github.com/sponsors/isaacs" } @@ -5052,9 +5034,9 @@ } }, "node_modules/https-proxy-agent": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.4.tgz", - "integrity": "sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==", + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", + "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", "dev": true, "license": "MIT", "dependencies": { @@ -5076,13 +5058,13 @@ } }, "node_modules/husky": { - "version": "9.0.11", - "resolved": "https://registry.npmjs.org/husky/-/husky-9.0.11.tgz", - "integrity": "sha512-AB6lFlbwwyIqMdHYhwPe+kjOC3Oc5P3nThEoW/AaO2BX3vJDjWPFxYLxokUZOo6RNX20He3AaT8sESs9NJcmEw==", + "version": "9.1.4", + "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.4.tgz", + "integrity": "sha512-bho94YyReb4JV7LYWRWxZ/xr6TtOTt8cMfmQ39MQYJ7f/YE268s3GdghGwi+y4zAeqewE5zYLvuhV0M0ijsDEA==", "dev": true, "license": "MIT", "bin": { - "husky": "bin.mjs" + "husky": "bin.js" }, "engines": { "node": ">=18" @@ -5105,9 +5087,9 @@ } }, "node_modules/ignore": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", - "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true, "license": "MIT", "engines": { @@ -5142,9 +5124,9 @@ } }, "node_modules/import-local": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", - "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", + "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==", "dev": true, "license": "MIT", "dependencies": { @@ -5309,13 +5291,16 @@ } }, "node_modules/is-core-module": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", - "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.0.tgz", + "integrity": "sha512-Dd+Lb2/zvk9SKy1TGCt1wFJFo/MWBPMX5x7KcvLajWTGuomczdQX61PvY5yK6SVACwpoexWo81IfFyoKY2QnTA==", "dev": true, "license": "MIT", "dependencies": { - "hasown": "^2.0.0" + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -5692,9 +5677,9 @@ } }, "node_modules/istanbul-lib-instrument": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.2.tgz", - "integrity": "sha512-1WUsZ9R1lA0HtBSohTkm39WTPlNKSJ5iFk7UwqXkBLoHQT+hfqPsfsTDVuZdKGaBwn7din9bS7SsnoAr943hvw==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", + "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -5709,9 +5694,9 @@ } }, "node_modules/istanbul-lib-instrument/node_modules/semver": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "dev": true, "license": "ISC", "bin": { @@ -5780,17 +5765,14 @@ } }, "node_modules/jackspeak": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.0.tgz", - "integrity": "sha512-JVYhQnN59LVPFCEcVa2C3CrEKYacvjRfqIQl+h8oi91aLYQVWRYbxjPcv1bUiUy/kLmQaANrYfNMCO3kuEDHfw==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { "@isaacs/cliui": "^8.0.2" }, - "engines": { - "node": ">=14" - }, "funding": { "url": "https://github.com/sponsors/isaacs" }, @@ -6489,9 +6471,9 @@ } }, "node_modules/jest-snapshot/node_modules/semver": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "dev": true, "license": "ISC", "bin": { @@ -6624,9 +6606,9 @@ } }, "node_modules/jsdom": { - "version": "24.1.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-24.1.0.tgz", - "integrity": "sha512-6gpM7pRXCwIOKxX47cgOyvyQDN/Eh0f1MeKySBV2xGdKtqJBLj8P25eY3EVCWo2mglDDzozR2r2MW4T+JiNUZA==", + "version": "24.1.1", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-24.1.1.tgz", + "integrity": "sha512-5O1wWV99Jhq4DV7rCLIoZ/UIhyQeDR7wHVyZAHAshbrvZsLs+Xzz7gtwnlJTJDjleiTKh54F4dXrX70vJQTyJQ==", "dev": true, "license": "MIT", "dependencies": { @@ -6636,11 +6618,11 @@ "form-data": "^4.0.0", "html-encoding-sniffer": "^4.0.0", "http-proxy-agent": "^7.0.2", - "https-proxy-agent": "^7.0.4", + "https-proxy-agent": "^7.0.5", "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.10", + "nwsapi": "^2.2.12", "parse5": "^7.1.2", - "rrweb-cssom": "^0.7.0", + "rrweb-cssom": "^0.7.1", "saxes": "^6.0.0", "symbol-tree": "^3.2.4", "tough-cookie": "^4.1.4", @@ -6649,7 +6631,7 @@ "whatwg-encoding": "^3.1.1", "whatwg-mimetype": "^4.0.0", "whatwg-url": "^14.0.0", - "ws": "^8.17.0", + "ws": "^8.18.0", "xml-name-validator": "^5.0.0" }, "engines": { @@ -6933,9 +6915,9 @@ } }, "node_modules/make-dir/node_modules/semver": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "dev": true, "license": "ISC", "bin": { @@ -7096,9 +7078,9 @@ } }, "node_modules/minimatch": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", - "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, "license": "ISC", "dependencies": { @@ -7188,9 +7170,9 @@ "license": "MIT" }, "node_modules/node-releases": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", - "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", "dev": true, "license": "MIT" }, @@ -7211,9 +7193,9 @@ } }, "node_modules/normalize-package-data/node_modules/semver": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "dev": true, "license": "ISC", "bin": { @@ -7263,9 +7245,9 @@ } }, "node_modules/nwsapi": { - "version": "2.2.10", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.10.tgz", - "integrity": "sha512-QK0sRs7MKv0tKe1+5uZIQk/C8XGza4DAnztJG8iD+TpJIORARrCxczA738awHrZoHeTjSSoHqao2teO0dC/gFQ==", + "version": "2.2.12", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.12.tgz", + "integrity": "sha512-qXDmcVlZV4XRtKFzddidpfVP4oMSGhga+xdMc25mv8kaLUHtgzCDhUxkrN8exkGdTlLNaXj7CV3GtON7zuGZ+w==", "dev": true, "license": "MIT" }, @@ -7280,11 +7262,14 @@ } }, "node_modules/object-inspect": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", - "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", + "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", "dev": true, "license": "MIT", + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -7367,24 +7352,6 @@ "node": ">= 0.4" } }, - "node_modules/object.hasown": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.4.tgz", - "integrity": "sha512-FZ9LZt9/RHzGySlBARE3VF+gE26TxR38SdmqOqliuTnl9wrKulaQs+4dee1V+Io8VfxqzAfHu6YuRgUy8OHoTg==", - "dev": true, - "license": "MIT", - "dependencies": { - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/object.values": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", @@ -7505,9 +7472,9 @@ } }, "node_modules/p-locate/node_modules/yocto-queue": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", - "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.1.1.tgz", + "integrity": "sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==", "dev": true, "license": "MIT", "engines": { @@ -7527,6 +7494,13 @@ "node": ">=6" } }, + "node_modules/package-json-from-dist": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz", + "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -7627,14 +7601,11 @@ } }, "node_modules/path-scurry/node_modules/lru-cache": { - "version": "10.2.2", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.2.tgz", - "integrity": "sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==", + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", "dev": true, - "license": "ISC", - "engines": { - "node": "14 || >=16.14" - } + "license": "ISC" }, "node_modules/path-type": { "version": "4.0.0", @@ -8029,9 +8000,9 @@ "license": "MIT" }, "node_modules/proxy": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/proxy/-/proxy-2.1.1.tgz", - "integrity": "sha512-nLgd7zdUAOpB3ZO/xCkU8gy74UER7P0aihU8DkUsDS5ZoFwVCX7u8dy+cv5tVK8UaB/yminU1GiLWE26TKPYpg==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/proxy/-/proxy-2.2.0.tgz", + "integrity": "sha512-nYclNIWj9UpXbVJ3W5EXIYiGR88AKZoGt90kyh3zoOBY5QW+7bbtPvMFgKGD4VJmpS3UXQXtlGXSg3lRNLOFLg==", "dev": true, "license": "MIT", "dependencies": { @@ -8039,6 +8010,9 @@ "basic-auth-parser": "0.0.2-1", "debug": "^4.3.4" }, + "bin": { + "proxy": "dist/bin/proxy.js" + }, "engines": { "node": ">= 14" } @@ -9123,6 +9097,17 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/string.prototype.repeat": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz", + "integrity": "sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, "node_modules/string.prototype.trim": { "version": "1.2.9", "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", @@ -9601,9 +9586,9 @@ "license": "MIT" }, "node_modules/typescript": { - "version": "5.4.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", - "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", + "version": "5.5.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", + "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", "dev": true, "license": "Apache-2.0", "bin": { @@ -9674,9 +9659,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.0.16", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.16.tgz", - "integrity": "sha512-KVbTxlBYlckhF5wgfyZXTWnMn7MMZjMu9XG8bPlliUOP9ThaF4QnhP8qrjrH7DRzHfSk0oQv1wToW+iA5GajEQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", + "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", "dev": true, "funding": [ { @@ -9743,9 +9728,9 @@ } }, "node_modules/v8-to-istanbul": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz", - "integrity": "sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==", + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", + "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==", "dev": true, "license": "ISC", "dependencies": { @@ -9882,14 +9867,14 @@ } }, "node_modules/which-builtin-type": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.1.3.tgz", - "integrity": "sha512-YmjsSMDBYsM1CaFiayOVT06+KJeXf0o5M/CAd4o1lTadFAtacTUM49zoYxr/oroopFDfhvN6iEcBxUyc3gvKmw==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.1.4.tgz", + "integrity": "sha512-bppkmBSsHFmIMSl8BO9TbsyzsvGjVoppt8xUiGzwiu/bhDCGxnpOKCxgqj6GuyHE0mINMDecBFPlOm2hzY084w==", "dev": true, "license": "MIT", "dependencies": { - "function.prototype.name": "^1.1.5", - "has-tostringtag": "^1.0.0", + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", "is-async-function": "^2.0.0", "is-date-object": "^1.0.5", "is-finalizationregistry": "^1.0.2", @@ -9898,8 +9883,8 @@ "is-weakref": "^1.0.2", "isarray": "^2.0.5", "which-boxed-primitive": "^1.0.2", - "which-collection": "^1.0.1", - "which-typed-array": "^1.1.9" + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.15" }, "engines": { "node": ">= 0.4" @@ -10081,9 +10066,9 @@ "license": "ISC" }, "node_modules/ws": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", - "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", "dev": true, "license": "MIT", "engines": { diff --git a/deps/undici/src/package.json b/deps/undici/src/package.json index 008f2cc145d..2763f5f2d1e 100644 --- a/deps/undici/src/package.json +++ b/deps/undici/src/package.json @@ -1,6 +1,6 @@ { "name": "undici", - "version": "6.19.2", + "version": "6.19.8", "description": "An HTTP/1.1 client, written from scratch for Node.js", "homepage": "https://undici.nodejs.org", "bugs": { @@ -62,7 +62,7 @@ "main": "index.js", "types": "index.d.ts", "scripts": { - "build:node": "npx esbuild@0.19.4 index-fetch.js --bundle --platform=node --outfile=undici-fetch.js --define:esbuildDetection=1 --keep-names && node scripts/strip-comments.js", + "build:node": "npx esbuild@0.19.10 index-fetch.js --bundle --platform=node --outfile=undici-fetch.js --define:esbuildDetection=1 --keep-names && node scripts/strip-comments.js", "prebuild:wasm": "node build/wasm.js --prebuild", "build:wasm": "node build/wasm.js --docker", "lint": "standard | snazzy", diff --git a/deps/undici/src/scripts/clean-coverage.js b/deps/undici/src/scripts/clean-coverage.js new file mode 100644 index 00000000000..0be16871d03 --- /dev/null +++ b/deps/undici/src/scripts/clean-coverage.js @@ -0,0 +1,15 @@ +'use strict' + +const { rmSync } = require('node:fs') +const { resolve } = require('node:path') + +if (process.env.NODE_V8_COVERAGE) { + if (process.env.NODE_V8_COVERAGE.endsWith('/tmp')) { + rmSync(resolve(__dirname, process.env.NODE_V8_COVERAGE, '..'), { recursive: true, force: true }) + } else { + rmSync(resolve(__dirname, process.env.NODE_V8_COVERAGE), { recursive: true, force: true }) + } +} else { + console.log(resolve(__dirname, 'coverage')) + rmSync(resolve(__dirname, '../coverage'), { recursive: true, force: true }) +} diff --git a/deps/undici/src/scripts/generate-pem.js b/deps/undici/src/scripts/generate-pem.js new file mode 100644 index 00000000000..0d7e628e209 --- /dev/null +++ b/deps/undici/src/scripts/generate-pem.js @@ -0,0 +1,3 @@ +/* istanbul ignore file */ + +require('https-pem/install') diff --git a/deps/undici/src/scripts/generate-undici-types-package-json.js b/deps/undici/src/scripts/generate-undici-types-package-json.js new file mode 100644 index 00000000000..78095ae6d5e --- /dev/null +++ b/deps/undici/src/scripts/generate-undici-types-package-json.js @@ -0,0 +1,28 @@ +const fs = require('node:fs') +const path = require('node:path') + +const packageJSONPath = path.join(__dirname, '..', 'package.json') +const packageJSONRaw = fs.readFileSync(packageJSONPath, 'utf-8') +const packageJSON = JSON.parse(packageJSONRaw) + +const licensePath = path.join(__dirname, '..', 'LICENSE') +const licenseRaw = fs.readFileSync(licensePath, 'utf-8') + +const packageTypesJSON = { + name: 'undici-types', + version: packageJSON.version, + description: 'A stand-alone types package for Undici', + homepage: packageJSON.homepage, + bugs: packageJSON.bugs, + repository: packageJSON.repository, + license: packageJSON.license, + types: 'index.d.ts', + files: ['*.d.ts'], + contributors: packageJSON.contributors +} + +const packageTypesPath = path.join(__dirname, '..', 'types', 'package.json') +const licenseTypesPath = path.join(__dirname, '..', 'types', 'LICENSE') + +fs.writeFileSync(packageTypesPath, JSON.stringify(packageTypesJSON, null, 2)) +fs.writeFileSync(licenseTypesPath, licenseRaw) diff --git a/deps/undici/src/scripts/platform-shell.js b/deps/undici/src/scripts/platform-shell.js new file mode 100644 index 00000000000..093ce536a77 --- /dev/null +++ b/deps/undici/src/scripts/platform-shell.js @@ -0,0 +1,12 @@ +'use strict' + +const { platform } = require('node:os') +const { writeFileSync } = require('node:fs') +const { resolve } = require('node:path') + +if (platform() === 'win32') { + writeFileSync( + resolve(__dirname, '.npmrc'), + 'script-shell = "C:\\windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe"\n' + ) +} diff --git a/deps/undici/src/scripts/release.js b/deps/undici/src/scripts/release.js new file mode 100644 index 00000000000..ad8e8468669 --- /dev/null +++ b/deps/undici/src/scripts/release.js @@ -0,0 +1,73 @@ +'use strict' + +// Called from .github/workflows + +const generateReleaseNotes = async ({ github, owner, repo, versionTag, defaultBranch }) => { + const { data: releases } = await github.rest.repos.listReleases({ + owner, + repo + }) + + const previousRelease = releases.find((r) => r.tag_name.startsWith('v6')) + + const { data: { body } } = await github.rest.repos.generateReleaseNotes({ + owner, + repo, + tag_name: versionTag, + target_commitish: defaultBranch, + previous_tag_name: previousRelease?.tag_name + }) + + const bodyWithoutReleasePr = body.split('\n') + .filter((line) => !line.includes('[Release] v')) + .join('\n') + + return bodyWithoutReleasePr +} + +const generatePr = async ({ github, context, defaultBranch, versionTag }) => { + const { owner, repo } = context.repo + const releaseNotes = await generateReleaseNotes({ github, owner, repo, versionTag, defaultBranch }) + + await github.rest.pulls.create({ + owner, + repo, + head: `release/${versionTag}`, + base: defaultBranch, + title: `[Release] ${versionTag}`, + body: releaseNotes + }) +} + +const release = async ({ github, context, defaultBranch, versionTag }) => { + const { owner, repo } = context.repo + const releaseNotes = await generateReleaseNotes({ github, owner, repo, versionTag, defaultBranch }) + + await github.rest.repos.createRelease({ + owner, + repo, + tag_name: versionTag, + target_commitish: defaultBranch, + name: versionTag, + body: releaseNotes, + draft: false, + prerelease: false, + generate_release_notes: false + }) + + try { + await github.rest.git.deleteRef({ + owner, + repo, + ref: `heads/release/${versionTag}` + }) + } catch (err) { + console.log("Couldn't delete release PR ref") + console.log(err) + } +} + +module.exports = { + generatePr, + release +} diff --git a/deps/undici/src/scripts/verifyVersion.js b/deps/undici/src/scripts/verifyVersion.js new file mode 100644 index 00000000000..8ad2d192a66 --- /dev/null +++ b/deps/undici/src/scripts/verifyVersion.js @@ -0,0 +1,15 @@ +/* istanbul ignore file */ + +const [major, minor, patch] = process.versions.node.split('.').map(v => Number(v)) +const required = process.argv.pop().split('.').map(v => Number(v)) + +const badMajor = major < required[0] +const badMinor = major === required[0] && minor < required[1] +const badPatch = major === required[0] && minor === required[1] && patch < required[2] + +if (badMajor || badMinor || badPatch) { + console.log(`Required Node.js >=${required.join('.')}, got ${process.versions.node}`) + console.log('Skipping') +} else { + process.exit(1) +} diff --git a/deps/undici/undici.js b/deps/undici/undici.js index 6db2e4ce249..acbece91687 100644 --- a/deps/undici/undici.js +++ b/deps/undici/undici.js @@ -5210,11 +5210,24 @@ var require_body = __commonJS({ var { webidl } = require_webidl(); var { Blob: Blob2 } = require("node:buffer"); var assert = require("node:assert"); - var { isErrored } = require_util(); + var { isErrored, isDisturbed } = require("node:stream"); var { isArrayBuffer } = require("node:util/types"); var { serializeAMimeType } = require_data_url(); var { multipartFormDataParser } = require_formdata_parser(); var textEncoder = new TextEncoder(); + function noop() { + } + __name(noop, "noop"); + var hasFinalizationRegistry = globalThis.FinalizationRegistry && process.version.indexOf("v18") !== 0; + var streamRegistry; + if (hasFinalizationRegistry) { + streamRegistry = new FinalizationRegistry((weakRef) => { + const stream = weakRef.deref(); + if (stream && !stream.locked && !isDisturbed(stream) && !isErrored(stream)) { + stream.cancel("Response object has been garbage collected").catch(noop); + } + }); + } function extractBody(object, keepalive = false) { let stream = null; if (object instanceof ReadableStream) { @@ -5359,8 +5372,11 @@ Content-Type: ${value.type || "application/octet-stream"}\r return extractBody(object, keepalive); } __name(safelyExtractBody, "safelyExtractBody"); - function cloneBody(body) { + function cloneBody(instance, body) { const [out1, out2] = body.stream.tee(); + if (hasFinalizationRegistry) { + streamRegistry.register(instance, new WeakRef(out1)); + } body.stream = out1; return { stream: out2, @@ -5443,7 +5459,7 @@ Content-Type: ${value.type || "application/octet-stream"}\r __name(mixinBody, "mixinBody"); async function consumeBody(object, convertBytesToJSValue, instance) { webidl.brandCheck(object, instance); - if (bodyUnusable(object[kState].body)) { + if (bodyUnusable(object)) { throw new TypeError("Body is unusable: Body has already been read"); } throwIfAborted(object[kState]); @@ -5464,7 +5480,8 @@ Content-Type: ${value.type || "application/octet-stream"}\r return promise.promise; } __name(consumeBody, "consumeBody"); - function bodyUnusable(body) { + function bodyUnusable(object) { + const body = object[kState].body; return body != null && (body.stream.locked || util.isDisturbed(body.stream)); } __name(bodyUnusable, "bodyUnusable"); @@ -5485,7 +5502,10 @@ Content-Type: ${value.type || "application/octet-stream"}\r extractBody, safelyExtractBody, cloneBody, - mixinBody + mixinBody, + streamRegistry, + hasFinalizationRegistry, + bodyUnusable }; } }); @@ -8719,7 +8739,7 @@ var require_response = __commonJS({ "lib/web/fetch/response.js"(exports2, module2) { "use strict"; var { Headers, HeadersList, fill, getHeadersGuard, setHeadersGuard, setHeadersList } = require_headers(); - var { extractBody, cloneBody, mixinBody } = require_body(); + var { extractBody, cloneBody, mixinBody, hasFinalizationRegistry, streamRegistry, bodyUnusable } = require_body(); var util = require_util(); var nodeUtil = require("node:util"); var { kEnumerableProperty } = util; @@ -8744,20 +8764,7 @@ var require_response = __commonJS({ var { kConstruct } = require_symbols(); var assert = require("node:assert"); var { types } = require("node:util"); - var { isDisturbed, isErrored } = require("node:stream"); var textEncoder = new TextEncoder("utf-8"); - var hasFinalizationRegistry = globalThis.FinalizationRegistry && process.version.indexOf("v18") !== 0; - var registry; - if (hasFinalizationRegistry) { - registry = new FinalizationRegistry((stream) => { - if (!stream.locked && !isDisturbed(stream) && !isErrored(stream)) { - stream.cancel("Response object has been garbage collected").catch(noop); - } - }); - } - function noop() { - } - __name(noop, "noop"); var Response = class _Response { static { __name(this, "Response"); @@ -8872,7 +8879,7 @@ var require_response = __commonJS({ // Returns a clone of response. clone() { webidl.brandCheck(this, _Response); - if (this.bodyUsed || this.body?.locked) { + if (bodyUnusable(this)) { throw webidl.errors.exception({ header: "Response.clone", message: "Body has already been consumed." @@ -8931,7 +8938,7 @@ var require_response = __commonJS({ } const newResponse = makeResponse({ ...response, body: null }); if (response.body != null) { - newResponse.body = cloneBody(response.body); + newResponse.body = cloneBody(newResponse, response.body); } return newResponse; } @@ -9064,7 +9071,7 @@ var require_response = __commonJS({ setHeadersList(response[kHeaders], innerResponse.headersList); setHeadersGuard(response[kHeaders], guard); if (hasFinalizationRegistry && innerResponse.body?.stream) { - registry.register(response, innerResponse.body.stream); + streamRegistry.register(response, new WeakRef(innerResponse.body.stream)); } return response; } @@ -9186,7 +9193,7 @@ var require_dispatcher_weakref = __commonJS({ var require_request2 = __commonJS({ "lib/web/fetch/request.js"(exports2, module2) { "use strict"; - var { extractBody, mixinBody, cloneBody } = require_body(); + var { extractBody, mixinBody, cloneBody, bodyUnusable } = require_body(); var { Headers, fill: fillHeaders, HeadersList, setHeadersGuard, getHeadersGuard, setHeadersList, getHeadersList } = require_headers(); var { FinalizationRegistry: FinalizationRegistry2 } = require_dispatcher_weakref()(); var util = require_util(); @@ -9512,7 +9519,7 @@ var require_request2 = __commonJS({ } let finalBody = inputOrInitBody; if (initBody == null && inputBody != null) { - if (util.isDisturbed(inputBody.stream) || inputBody.stream.locked) { + if (bodyUnusable(input)) { throw new TypeError( "Cannot construct a Request with a Request object that has already been used." ); @@ -9647,7 +9654,7 @@ var require_request2 = __commonJS({ // Returns a clone of request. clone() { webidl.brandCheck(this, _Request); - if (this.bodyUsed || this.body?.locked) { + if (bodyUnusable(this)) { throw new TypeError("unusable"); } const clonedRequest = cloneRequest(this[kState]); @@ -9741,7 +9748,7 @@ var require_request2 = __commonJS({ function cloneRequest(request) { const newRequest = makeRequest({ ...request, body: null }); if (request.body != null) { - newRequest.body = cloneBody(request.body); + newRequest.body = cloneBody(newRequest, request.body); } return newRequest; } @@ -13194,11 +13201,5 @@ module.exports.EventSource = require_eventsource().EventSource; module.exports.EnvHttpProxyAgent = EnvHttpProxyAgent; module.exports.getGlobalDispatcher = getGlobalDispatcher; module.exports.setGlobalDispatcher = setGlobalDispatcher; -/*! Bundled license information: - -undici/lib/web/fetch/body.js: - (*! formdata-polyfill. MIT License. Jimmy Wärting *) - -undici/lib/web/websocket/frame.js: - (*! ws. MIT License. Einar Otto Stangvik *) -*/ +/*! formdata-polyfill. MIT License. Jimmy Wärting */ +/*! ws. MIT License. Einar Otto Stangvik */ diff --git a/deps/v8/src/base/macros.h b/deps/v8/src/base/macros.h index c267b8f1e9f..953e7b4da93 100644 --- a/deps/v8/src/base/macros.h +++ b/deps/v8/src/base/macros.h @@ -198,7 +198,8 @@ namespace base { // base::is_trivially_copyable will differ for these cases. template struct is_trivially_copyable { -#if V8_CC_MSVC +#if V8_CC_MSVC || (__GNUC__ == 12 && __GNUC_MINOR__ <= 2) || \ + (defined(__clang__) && __clang_major__ <= 17) // Unfortunately, MSVC 2015 is broken in that std::is_trivially_copyable can // be false even though it should be true according to the standard. // (status at 2018-02-26, observed on the msvc waterfall bot). @@ -206,6 +207,8 @@ struct is_trivially_copyable { // intended, so we reimplement this according to the standard. // See also https://developercommunity.visualstudio.com/content/problem/ // 170883/msvc-type-traits-stdis-trivial-is-bugged.html. + // + // Also observed with an eclectic range of clang++ releases. static constexpr bool value = // Copy constructor is trivial or deleted. (std::is_trivially_copy_constructible::value || diff --git a/deps/zlib/CMakeLists.txt b/deps/zlib/CMakeLists.txt index 66f7d04966a..59d77c3a413 100644 --- a/deps/zlib/CMakeLists.txt +++ b/deps/zlib/CMakeLists.txt @@ -24,6 +24,7 @@ check_include_file(stddef.h HAVE_STDDEF_H) option(ENABLE_SIMD_OPTIMIZATIONS "Enable all SIMD optimizations" OFF) option(ENABLE_SIMD_AVX512 "Enable SIMD AXV512 optimizations" OFF) option(USE_ZLIB_RABIN_KARP_HASH "Enable bitstream compatibility with canonical zlib" OFF) +option(ENABLE_INTEL_QAT_COMPRESSION "Enable Intel Quick Assist Technology use for compression" OFF) option(BUILD_UNITTESTS "Enable standalone unit tests build" OFF) option(BUILD_MINIZIP_BIN "Enable building minzip_bin tool" OFF) option(BUILD_ZPIPE "Enable building zpipe tool" OFF) @@ -228,6 +229,22 @@ if (ENABLE_SIMD_OPTIMIZATIONS) endif() endif() +if (ENABLE_INTEL_QAT_COMPRESSION) + list(APPEND ZLIB_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/contrib/qat/deflate_qat.cpp) + list(APPEND ZLIB_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/contrib/qat/qatzpp/io_buffers.cpp) + list(APPEND ZLIB_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/contrib/qat/qatzpp/memory.cpp) + list(APPEND ZLIB_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/contrib/qat/qatzpp/qat_buffer_list.cpp) + list(APPEND ZLIB_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/contrib/qat/qatzpp/qat.cpp) + list(APPEND ZLIB_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/contrib/qat/qatzpp/qat_instance.cpp) + list(APPEND ZLIB_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/contrib/qat/qatzpp/session.cpp) + list(APPEND ZLIB_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/contrib/qat/qatzpp/qat_task.cpp) + + # TODO(gustavoa): Find a way to include the qatzpp headers without having the + # presubmit check throw errors. + include_directories(${CMAKE_CURRENT_SOURCE_DIR}/contrib/qat/qatzpp) + add_compile_definitions(QAT_COMPRESSION_ENABLED) +endif() + # parse the full version number from zlib.h and include in ZLIB_FULL_VERSION file(READ ${CMAKE_CURRENT_SOURCE_DIR}/zlib.h _zlib_h_contents) string(REGEX REPLACE ".*#define[ \t]+ZLIB_VERSION[ \t]+\"([-0-9A-Za-z.]+)\".*" @@ -254,6 +271,15 @@ add_library(zlibstatic STATIC ${ZLIB_SRCS} ${ZLIB_PUBLIC_HDRS} ${ZLIB_PRIVATE_HD set_target_properties(zlib PROPERTIES DEFINE_SYMBOL ZLIB_DLL) set_target_properties(zlib PROPERTIES SOVERSION 1) +if (ENABLE_INTEL_QAT_COMPRESSION) + target_include_directories(zlib PUBLIC ${QATZPP_INCLUDE_DIRS}) + target_link_libraries(zlib ${QATZPP_LIBRARY}) + target_link_libraries(zlib qat) + target_include_directories(zlibstatic PUBLIC ${QATZPP_INCLUDE_DIRS}) + target_link_libraries(zlibstatic ${QATZPP_LIBRARY}) + target_link_libraries(zlibstatic qat) +endif() + if(NOT CYGWIN) # This property causes shared libraries on Linux to have the full version # encoded into their final filename. We disable this on Cygwin because diff --git a/deps/zlib/contrib/bench/zlib_bench.cc b/deps/zlib/contrib/bench/zlib_bench.cc index b65f9291bff..6df296c8721 100644 --- a/deps/zlib/contrib/bench/zlib_bench.cc +++ b/deps/zlib/contrib/bench/zlib_bench.cc @@ -71,10 +71,6 @@ Data read_file_data_or_exit(const char* name) { return data; } -size_t zlib_estimate_compressed_size(size_t input_size) { - return compressBound(input_size); -} - enum zlib_wrapper { kWrapperNONE, kWrapperZLIB, @@ -128,10 +124,6 @@ void zlib_compress( std::string* output, bool resize_output = false) { - if (resize_output) - output->resize(zlib_estimate_compressed_size(input_size)); - size_t output_size = output->size(); - z_stream stream; memset(&stream, 0, sizeof(stream)); @@ -140,6 +132,11 @@ void zlib_compress( if (result != Z_OK) error_exit("deflateInit2 failed", result); + if (resize_output) { + output->resize(deflateBound(&stream, input_size)); + } + size_t output_size = output->size(); + stream.next_out = (Bytef*)string_data(output); stream.avail_out = (uInt)output_size; stream.next_in = (z_const Bytef*)input; @@ -299,7 +296,7 @@ void zlib_file(const char* name, // Pre-grow the output buffer so we don't measure string resize time. for (int b = 0; b < blocks; ++b) - compressed[b].resize(zlib_estimate_compressed_size(block_size)); + zlib_compress(type, input[b], input_length[b], &compressed[b], true); auto start = now(); for (int b = 0; b < blocks; ++b) @@ -307,11 +304,6 @@ void zlib_file(const char* name, zlib_compress(type, input[b], input_length[b], &compressed[b]); ctime[run] = std::chrono::duration(now() - start).count(); - // Compress again, resizing compressed, so we don't leave junk at the - // end of the compressed string that could confuse zlib_uncompress(). - for (int b = 0; b < blocks; ++b) - zlib_compress(type, input[b], input_length[b], &compressed[b], true); - for (int b = 0; b < blocks; ++b) output[b].resize(input_length[b]); diff --git a/deps/zlib/contrib/minizip/README.chromium b/deps/zlib/contrib/minizip/README.chromium index b5895f2a518..ceaff34f0f3 100644 --- a/deps/zlib/contrib/minizip/README.chromium +++ b/deps/zlib/contrib/minizip/README.chromium @@ -2,10 +2,11 @@ Name: ZIP file API for reading file entries in a ZIP archive Short Name: minizip URL: https://github.com/madler/zlib/tree/master/contrib/minizip Version: 1.3.0.1 +Revision: 643e17b7498d12ab8d15565662880579692f769d License: Zlib License File: //third_party/zlib/LICENSE -Security Critical: yes Shipped: yes +Security Critical: yes CPEPrefix: cpe:/a:minizip_project:minizip Description: diff --git a/deps/zlib/contrib/qat/deflate_qat.cpp b/deps/zlib/contrib/qat/deflate_qat.cpp new file mode 100644 index 00000000000..bfe45472bb5 --- /dev/null +++ b/deps/zlib/contrib/qat/deflate_qat.cpp @@ -0,0 +1,312 @@ +/* + * Copyright (C) 2024 Intel Corporation. All rights reserved. + * Authors: + * Gustavo A Espinoza + * + * + * For conditions of distribution and use, see copyright notice in zlib.h + */ +#include "deflate_qat.h" +#include "deflate.h" + +#include "session.hpp" +#include "qat_instance.hpp" +#include "qat_buffer_list.hpp" +#include "qat.hpp" + +#include + +/* +* TODO(gustavoa): Make the input size adjustable from the memlevel +* attribute on deflateInit. +*/ +static constexpr size_t kInputSize = 1024 * 1024; + +/* QAT Instances obtained available from the library. */ +static std::vector> qat_instances; + +/* +* TODO(gustavoa): Verify if the ordering of the struct fields won't create +* unnecessary holes in the structure that requires extraneous padding. +*/ +struct qat_deflate { + std::unique_ptr qat_session; + + /* QAT requires contiguous physical pages. Cannot be allocated using + * malloc/new. + */ + uint8_t *input_buffer; + uint8_t *output_buffer; + + /* Pointer to the next byte in the output buffer. */ + uint8_t *pending_out; + + unsigned input_buffer_size; + unsigned output_buffer_size; + + unsigned pending_in_count; + unsigned pending_out_count; +}; + +static std::unique_ptr qat_create_session(int level, int wrap) +{ + CpaDcChecksum checksum = CPA_DC_NONE; + + switch(wrap) { + case 1: + checksum = CPA_DC_ADLER32; + break; + case 2: + checksum = CPA_DC_CRC32; + break; + } + + return std::make_unique( + qat_instances[0], + (CpaDcCompLvl)level, + checksum, + 0 + ); +} + + +int qat_deflate_init() +{ + return (qat::Initialize()) ? Z_ERRNO : Z_OK; +} + +struct qat_deflate* qat_deflate_state_init(int level, int wrap) +{ + if (qat_instances.empty()) { + qat_instances = qat::Instance::Create(); + } + if (qat_instances.empty()) { + return nullptr; + } + + struct qat_deflate *qat_deflate = new struct qat_deflate; + if (!qat_deflate) { + return nullptr; + } + + /* TODO(gustavoa): Find a way to utilize all the available instances for the same + * process. + */ + qat_instances[0]->Start(); + + qat_deflate->qat_session = qat_create_session(level, wrap); + + qat_deflate->input_buffer_size = kInputSize; + qat_deflate->input_buffer = qat::AllocBlockArray(kInputSize, 0); + qat_deflate->output_buffer_size = + qat_deflate->qat_session->GetDeflateBound(qat_deflate->input_buffer_size); + qat_deflate->pending_out = qat_deflate->output_buffer = + qat::AllocBlockArray(qat_deflate->output_buffer_size, 0); + + qat_deflate->pending_in_count = qat_deflate->pending_out_count = 0; + + if (!qat_deflate->input_buffer || !qat_deflate->output_buffer) { + return nullptr; + } + + return qat_deflate; +} + +static unsigned qat_read_buf(z_streamp strm, struct qat_deflate* qat, unsigned size) +{ + unsigned len = strm->avail_in; + + if (len > size) { + len = size; + } + if (len == 0) return 0; + + strm->avail_in -= len; + strm->total_in += len; + + zmemcpy( + qat->input_buffer + qat->pending_in_count, + strm->next_in, + len + ); + + strm->next_in += len; + qat->pending_in_count += len; + + return len; +} + +void qat_flush_pending(deflate_state* s) +{ + unsigned len; + z_streamp strm = s->strm; + struct qat_deflate* qat = s->qat_s; + + len = qat->pending_out_count; + if (len > strm->avail_out) len = strm->avail_out; + if (len == 0) return; + + zmemcpy(strm->next_out, qat->pending_out, len); + + qat->pending_out += len; + qat->pending_out_count -= len; + strm->next_out += len; + strm->avail_out -= len; + strm->total_out += len; + if (qat->pending_out_count == 0) { + qat->pending_out = qat->output_buffer; + } +} + +static int qat_compress_pending(deflate_state*s, int flush) +{ + struct qat_deflate* qat = s->qat_s; + uint32_t metadata_size; + + /* TODO(gustavoa): find a way to make qatzpp setup this number internally. */ + cpaDcBufferListGetMetaSize(qat->qat_session->getInstance()->GetHandle(), 1, &metadata_size); + + auto job = qat->qat_session->Deflate( + std::make_unique( + std::make_unique( + qat->input_buffer, + qat->pending_in_count, + metadata_size + ), + std::make_unique( + qat->output_buffer, + qat->output_buffer_size, + metadata_size + ) + ), (flush == Z_FINISH && s->strm->avail_in == 0) + ); + + job->WaitCompletion(); + + /* + * TODO(gustavoa): make QAT perform the checksum combine. + */ + if (s->wrap == 2) { + s->strm->adler = crc32_combine( + s->strm->adler, + job->GetResults()->checksum, + job->GetResults()->consumed + ); + } else if (s->wrap == 1) { + s->strm->adler = adler32( + s->strm->adler, + qat->input_buffer, + job->GetResults()->consumed + ); + } + + qat->pending_out_count = job->GetResults()->produced; + qat->pending_in_count -= job->GetResults()->consumed; + + if(qat->pending_in_count != 0) { + /* Copy any remaining bytes to the beginning of the buffer. */ + zmemcpy( + qat->input_buffer, + qat->input_buffer + job->GetResults()->consumed, + qat->pending_in_count + ); + } + + return 0; +} + +qat_block_state qat_deflate_step(deflate_state* s, int flush) +{ + z_streamp strm = s->strm; + struct qat_deflate* qat_state = s->qat_s; + + for (;;) { + if (qat_state->pending_in_count < qat_state->input_buffer_size) { + qat_read_buf( + strm, + qat_state, + qat_state->input_buffer_size - qat_state->pending_in_count + ); + if (qat_state->pending_in_count < qat_state->input_buffer_size && flush == Z_NO_FLUSH) { + return qat_block_need_more; + } else { + qat_compress_pending(s, flush); + } + if (strm->avail_in == 0) { + break; + } + } else { + qat_compress_pending(s, flush); + } + + qat_flush_pending(s); + if (strm->avail_out == 0) { + return (flush == Z_FINISH) ? qat_block_finish_started : qat_block_need_more; + } + } + + if (flush == Z_FINISH) { + qat_flush_pending(s); + if (strm->avail_out == 0) { + return qat_block_finish_started; + } else { + return qat_block_finish_done; + } + } + + qat_flush_pending(s); + if (strm->avail_out == 0) { + return qat_block_done; + } + + return qat_block_need_more; +} + +int qat_deflate_state_free(deflate_state* s) +{ + struct qat_deflate* qat_state = s->qat_s; + if (qat_state->input_buffer) { + qat::Free(qat_state->input_buffer); + } + if (qat_state->output_buffer) { + qat::Free(qat_state->output_buffer); + } + + qat_state->qat_session.reset(); + delete qat_state; + s->qat_s = nullptr; + + return Z_OK; +} + +struct qat_deflate *qat_deflate_copy(deflate_state *ss) +{ + struct qat_deflate *sqat = ss->qat_s; + struct qat_deflate *dqat = nullptr; + + if (!sqat) { + return nullptr; + } + + dqat = new struct qat_deflate; + + dqat->qat_session = qat_create_session(ss->level, ss->wrap); + + dqat->input_buffer_size = sqat->input_buffer_size; + dqat->input_buffer = qat::AllocBlockArray(dqat->input_buffer_size, 0); + + dqat->output_buffer_size = sqat->output_buffer_size; + dqat->output_buffer = qat::AllocBlockArray(dqat->output_buffer_size, 0); + + dqat->pending_in_count = sqat->pending_in_count; + dqat->pending_out_count = sqat->pending_out_count; + + dqat->pending_out = + dqat->output_buffer + (sqat->pending_out - sqat->output_buffer); + + zmemcpy(dqat->input_buffer, sqat->input_buffer, dqat->input_buffer_size); + zmemcpy(dqat->output_buffer, sqat->output_buffer, dqat->output_buffer_size); + + return dqat; +} + diff --git a/deps/zlib/contrib/qat/deflate_qat.h b/deps/zlib/contrib/qat/deflate_qat.h new file mode 100644 index 00000000000..3c7aa116b7d --- /dev/null +++ b/deps/zlib/contrib/qat/deflate_qat.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2024 Intel Corporation. All rights reserved. + * Authors: + * Gustavo A Espinoza + * + * + * For conditions of distribution and use, see copyright notice in zlib.h + */ +#ifndef DEFLATE_QAT_H +#define DEFLATE_QAT_H + +#include "deflate.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* This is a 1:1 mapping of the block states that deflate_fast, deflate_slow, + * deflate_rle, etc.. return. + * The added 'qat_failure' value is used for signaling the caller to revert + * back into software mode. + */ +typedef enum { + qat_block_need_more, + qat_block_done, + qat_block_finish_started, + qat_block_finish_done, + qat_failure +} qat_block_state; + +/* Initialize QAT for the calling process if it has not been yet initialized. */ +int qat_deflate_init(); + +/* Initialize a QAT stream state for a deflate_state object. */ +struct qat_deflate *qat_deflate_state_init(int level, int wra); + +/* Flush QAT output buffer into the zstream.next_out pointer. */ +void qat_flush_pending(deflate_state*); + +/* Compresses/copies/flushes any data in the internal QAT state + * input/output buffers. +*/ +qat_block_state qat_deflate_step(deflate_state*, int flush); + +/* Frees all the QAT-related buffers and objects for a given deflate_state. */ +int qat_deflate_state_free(deflate_state*); + +struct qat_deflate *qat_deflate_copy(deflate_state *ss); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/deps/zlib/contrib/qat/qatzpp/io_buffers.cpp b/deps/zlib/contrib/qat/qatzpp/io_buffers.cpp new file mode 100644 index 00000000000..2870292be17 --- /dev/null +++ b/deps/zlib/contrib/qat/qatzpp/io_buffers.cpp @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2024 Intel Corporation. All rights reserved. + * Authors: + * Gustavo A Espinoza + * + * + * For conditions of distribution and use, see copyright notice in zlib.h + */ +#include +#include + +#include "io_buffers.h" +#include "qat_instance.hpp" + +namespace qat +{ + +IOBuffers::IOBuffers() +{ +} + +IOBuffers::IOBuffers(std::unique_ptr&& src_list, std::unique_ptr&& dst_list): + src_buffer_list_(std::move(src_list)), dst_buffer_list_(std::move(dst_list)) +{ +} + +IOBuffers::~IOBuffers() +{ +} + +} diff --git a/deps/zlib/contrib/qat/qatzpp/io_buffers.h b/deps/zlib/contrib/qat/qatzpp/io_buffers.h new file mode 100644 index 00000000000..9fe8bfdbc33 --- /dev/null +++ b/deps/zlib/contrib/qat/qatzpp/io_buffers.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2024 Intel Corporation. All rights reserved. + * Authors: + * Gustavo A Espinoza + * + * + * For conditions of distribution and use, see copyright notice in zlib.h + */ +#ifndef QATZPP_IO_BUFFERS_H +#define QATZPP_IO_BUFFERS_H + +#include + +#include +#include +#include +#include +#include + +#include "memory.hpp" +#include "qat_instance.hpp" + +namespace qat +{ + +struct BaseBufferList +{ + virtual ~BaseBufferList() {} + + CpaBufferList list; + std::vector flat_buffers; + +protected: + BaseBufferList() {} +}; + +class IOBuffers +{ +public: + IOBuffers( + std::unique_ptr &&src_list, + std::unique_ptr &&dst_list + ); + virtual ~IOBuffers(); + + BaseBufferList *GetSrc() const { + return src_buffer_list_.get(); + } + + BaseBufferList *GetDst() const { + return dst_buffer_list_.get(); + } +protected: + IOBuffers(); + + std::unique_ptr src_buffer_list_; + std::unique_ptr dst_buffer_list_; +}; + +} + +#endif \ No newline at end of file diff --git a/deps/zlib/contrib/qat/qatzpp/memory.cpp b/deps/zlib/contrib/qat/qatzpp/memory.cpp new file mode 100644 index 00000000000..6a97ffe2fdf --- /dev/null +++ b/deps/zlib/contrib/qat/qatzpp/memory.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2024 Intel Corporation. All rights reserved. + * Authors: + * Gustavo A Espinoza + * + * + * For conditions of distribution and use, see copyright notice in zlib.h + */ +#include + +#include +#include + +#include "memory.hpp" +#include "qat.hpp" + +namespace qat +{ + +void *Alloc(size_t size_bytes, uint32_t numa_node) +{ + return qaeMemAllocNUMA(size_bytes, numa_node, 1); +} + +void Free(void *ptr) +{ + qaeMemFreeNUMA(&ptr); +} + +} \ No newline at end of file diff --git a/deps/zlib/contrib/qat/qatzpp/memory.hpp b/deps/zlib/contrib/qat/qatzpp/memory.hpp new file mode 100644 index 00000000000..191516ca75d --- /dev/null +++ b/deps/zlib/contrib/qat/qatzpp/memory.hpp @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2024 Intel Corporation. All rights reserved. + * Authors: + * Gustavo A Espinoza + * + * + * For conditions of distribution and use, see copyright notice in zlib.h + */ +#ifndef QATZPP_MEMORY_HPP +#define QATZPP_MEMORY_HPP + +#include +#include + +namespace qat +{ + +void *Alloc(size_t sizeBytes, uint32_t numa_node); + +template +T *AllocBlock(int32_t numa_node) +{ + return static_cast(Alloc(sizeof(T), numa_node)); +} + +template +T *AllocBlockArray(size_t count, int32_t numa_node) +{ + if (count <= 0) { + return nullptr; + } + + return static_cast(Alloc(sizeof(T) * count, numa_node)); +} + +void Free(void *ptr); + +} + +#endif \ No newline at end of file diff --git a/deps/zlib/contrib/qat/qatzpp/qat.cpp b/deps/zlib/contrib/qat/qatzpp/qat.cpp new file mode 100644 index 00000000000..80468d39515 --- /dev/null +++ b/deps/zlib/contrib/qat/qatzpp/qat.cpp @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2024 Intel Corporation. All rights reserved. + * Authors: + * Gustavo A Espinoza + * + * + * For conditions of distribution and use, see copyright notice in zlib.h + */ +#include "qat.hpp" + +#include +#include +#include + +#include +#include +#include +#include + +namespace qat +{ + +static bool g_qat_not_available = false; +static bool g_qat_initialized = false; +static std::mutex g_qat_initialization_mutex; + +class QATContext +{ +public: + explicit QATContext() {} + + QATContext(const QATContext &) = delete; + QATContext &operator=(const QATContext &) = delete; + + QATContext(QATContext &&) = delete; + QATContext &operator=(QATContext &&) = delete; + + ~QATContext() + { + std::lock_guard lock(g_qat_initialization_mutex); + + if (g_qat_not_available) return; + + if (g_qat_initialized) { + icp_sal_userStop(); + g_qat_initialized = false; + } + } +}; + +static std::unique_ptr qat_context; + +int Initialize() +{ + std::lock_guard lock(g_qat_initialization_mutex); + uint32_t cpa_state; + if (g_qat_not_available) { + return CPA_STATUS_FAIL; + } + if (g_qat_initialized) { + return CPA_STATUS_SUCCESS; + } + + cpa_state = icp_sal_userStartMultiProcess("SSL", CPA_FALSE); + + g_qat_not_available = (cpa_state != CPA_STATUS_SUCCESS); + g_qat_initialized = (cpa_state == CPA_STATUS_SUCCESS); + + qat_context = std::make_unique(); + return cpa_state; +} + +} diff --git a/deps/zlib/contrib/qat/qatzpp/qat.hpp b/deps/zlib/contrib/qat/qatzpp/qat.hpp new file mode 100644 index 00000000000..8ee7746b5ef --- /dev/null +++ b/deps/zlib/contrib/qat/qatzpp/qat.hpp @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2024 Intel Corporation. All rights reserved. + * Authors: + * Gustavo A Espinoza + * + * + * For conditions of distribution and use, see copyright notice in zlib.h + */ +#ifndef QATZPP_QAT_HPP +#define QATZPP_QAT_HPP + +namespace qat +{ + +int Initialize(); + +} + +#endif \ No newline at end of file diff --git a/deps/zlib/contrib/qat/qatzpp/qat_buffer_list.cpp b/deps/zlib/contrib/qat/qatzpp/qat_buffer_list.cpp new file mode 100644 index 00000000000..f0eea4908a5 --- /dev/null +++ b/deps/zlib/contrib/qat/qatzpp/qat_buffer_list.cpp @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2024 Intel Corporation. All rights reserved. + * Authors: + * Gustavo A Espinoza + * + * + * For conditions of distribution and use, see copyright notice in zlib.h + */ +#include "qat_buffer_list.hpp" + +namespace qat +{ + +BufferListUser::BufferListUser( + uint8_t *data, + size_t size, + size_t metadata_size) +{ + flat_buffers = std::vector(1); + flat_buffers[0].pData = data; + flat_buffers[0].dataLenInBytes = size; + list.pPrivateMetaData = AllocBlockArray(metadata_size, 0); + list.numBuffers = 1; + list.pBuffers = flat_buffers.data(); +} + +BufferListUser::~BufferListUser() +{ + if (list.pPrivateMetaData) { + Free(list.pPrivateMetaData); + } +} + +} diff --git a/deps/zlib/contrib/qat/qatzpp/qat_buffer_list.hpp b/deps/zlib/contrib/qat/qatzpp/qat_buffer_list.hpp new file mode 100644 index 00000000000..2a28175e18d --- /dev/null +++ b/deps/zlib/contrib/qat/qatzpp/qat_buffer_list.hpp @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2024 Intel Corporation. All rights reserved. + * Authors: + * Gustavo A Espinoza + * + * + * For conditions of distribution and use, see copyright notice in zlib.h + */ +#ifndef QATZPP_QAT_BUFFER_LIST_HPP +#define QATZPP_QAT_BUFFER_LIST_HPP + +#include + +#include "io_buffers.h" + +namespace qat +{ + +struct BufferListUser final : public BaseBufferList +{ + BufferListUser( + uint8_t *data, + size_t size, + size_t metadata_size + ); + + ~BufferListUser() override; +}; + +} + +#endif \ No newline at end of file diff --git a/deps/zlib/contrib/qat/qatzpp/qat_instance.cpp b/deps/zlib/contrib/qat/qatzpp/qat_instance.cpp new file mode 100644 index 00000000000..5b833c2ce7e --- /dev/null +++ b/deps/zlib/contrib/qat/qatzpp/qat_instance.cpp @@ -0,0 +1,135 @@ +/* + * Copyright (C) 2024 Intel Corporation. All rights reserved. + * Authors: + * Gustavo A Espinoza + * + * + * For conditions of distribution and use, see copyright notice in zlib.h + */ +#include + +#include +#include + +#include "memory.hpp" +#include "qat_instance.hpp" +#include "session.hpp" + +#define MAX_SAMPLE_BUFFER_SIZE (4*1024*1024) + +namespace qat +{ + +static std::mutex g_instance_mutex; +static std::vector> instances; + +static CpaPhysicalAddr virt2Phys(void *virt_addr) +{ + return (CpaPhysicalAddr)qaeVirtToPhysNUMA(virt_addr); +} + +Instance::Instance(CpaInstanceHandle instance): + instance_(instance), + num_intermediate_buffer_lists_(0), + intermediate_buffer_array_(nullptr), + started_(false) +{ + CpaDcInstanceCapabilities caps{}; + cpaDcQueryCapabilities(instance_, &caps); + + if (!caps.statelessDeflateCompression || !caps.statelessDeflateDecompression || + !caps.checksumAdler32 || !caps.dynamicHuffman) + { + return; + } + + if (caps.dynamicHuffmanBufferReq) { + uint32_t buffer_metadata_size; + cpaDcBufferListGetMetaSize(instance_, 1, &buffer_metadata_size); + cpaDcGetNumIntermediateBuffers(instance_, &num_intermediate_buffer_lists_); + + if(num_intermediate_buffer_lists_) { + intermediate_buffer_array_ = AllocBlockArray(num_intermediate_buffer_lists_, 0); + } + for (int i = 0; i < num_intermediate_buffer_lists_; ++i) { + intermediate_buffer_array_[i] = AllocBlock(0); + intermediate_buffer_array_[i]->pPrivateMetaData = + AllocBlockArray(buffer_metadata_size, 0); + intermediate_buffer_array_[i]->pBuffers = AllocBlock(0); + intermediate_buffer_array_[i]->pBuffers->pData = + AllocBlockArray(MAX_SAMPLE_BUFFER_SIZE, 0); + intermediate_buffer_array_[i]->pBuffers->dataLenInBytes = MAX_SAMPLE_BUFFER_SIZE; + } + } + + cpaDcSetAddressTranslation(instance_, virt2Phys); +} + +Instance::~Instance() +{ +} + +CpaDcInstanceCapabilities Instance::GetCapabilities() +{ + CpaDcInstanceCapabilities caps{}; + cpaDcQueryCapabilities(instance_, &caps); + + return caps; +} + +CpaInstanceInfo2 Instance::GetInfo() +{ + CpaInstanceInfo2 info{}; + cpaDcInstanceGetInfo2(instance_, &info); + + return info; +} + +int Instance::Start() +{ + std::lock_guard lock(mutex_); + + if (started_) { + return 0; + } + + int ret = cpaDcStartInstance + ( + instance_, + num_intermediate_buffer_lists_, + intermediate_buffer_array_ + ); + if (ret) { + return -1; + } + started_ = true; + return 0; +} + +std::vector> Instance::Create() +{ + std::lock_guard lock(g_instance_mutex); + uint16_t num_instances = 0; + + if (!instances.empty()) { + return instances; + } + + cpaDcGetNumInstances(&num_instances); + + if (!num_instances) { + std::cerr << "No instances found\n"; + return {}; + } + + std::vector handles(num_instances); + cpaDcGetInstances(num_instances, handles.data()); + + for(auto& handle: handles) { + instances.emplace_back(std::make_shared(handle)); + } + + return instances; +} + +} diff --git a/deps/zlib/contrib/qat/qatzpp/qat_instance.hpp b/deps/zlib/contrib/qat/qatzpp/qat_instance.hpp new file mode 100644 index 00000000000..1a2b4afcab1 --- /dev/null +++ b/deps/zlib/contrib/qat/qatzpp/qat_instance.hpp @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2024 Intel Corporation. All rights reserved. + * Authors: + * Gustavo A Espinoza + * + * + * For conditions of distribution and use, see copyright notice in zlib.h + */ +#ifndef QATZPP_QAT_INSTANCE_HPP +#define QATZPP_QAT_INSTANCE_HPP + +#include + +#include +#include +#include + +namespace qat +{ + +class Instance +{ +public: + Instance(CpaInstanceHandle); + ~Instance(); + + CpaInstanceHandle GetHandle() { return instance_; } + CpaDcInstanceCapabilities GetCapabilities(); + CpaInstanceInfo2 GetInfo(); + + int Start(void); + static std::vector> Create(); +private: + + CpaInstanceHandle instance_; + uint16_t num_intermediate_buffer_lists_; + CpaBufferList **intermediate_buffer_array_; + bool started_; + + std::mutex mutex_; +}; + +} + +#endif \ No newline at end of file diff --git a/deps/zlib/contrib/qat/qatzpp/qat_task.cpp b/deps/zlib/contrib/qat/qatzpp/qat_task.cpp new file mode 100644 index 00000000000..a53ea94ac95 --- /dev/null +++ b/deps/zlib/contrib/qat/qatzpp/qat_task.cpp @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2024 Intel Corporation. All rights reserved. + * Authors: + * Gustavo A Espinoza + * + * + * For conditions of distribution and use, see copyright notice in zlib.h + */ +#include +#include + +#include "qat_task.hpp" + +namespace qat +{ + +QATTask::QATTask(std::shared_ptr &qat_instance, + std::unique_ptr &&buffers, + std::unique_ptr &&dc_results): + qat_instance_(qat_instance), + io_buffers_(std::move(buffers)), + dc_results_(std::move(dc_results)), + completed_(false) +{ +} + +void QATTask::WaitCompletion() +{ + if (completed_) { + return; + } + + while (!completed_) { + icp_sal_DcPollInstance(qat_instance_->GetHandle(), 0); + } +} + +IOBuffers *QATTask::GetBuffers() +{ + return io_buffers_.get(); +} + +CpaDcRqResults *QATTask::GetResults() +{ + return dc_results_.get(); +} + +void dc_callback(void *callback_tag, CpaStatus status) +{ + if (!callback_tag) { + return; + } + // Ugly and dangerous + QATTask* task = static_cast(callback_tag); + task->completed_ = true; +} + +} \ No newline at end of file diff --git a/deps/zlib/contrib/qat/qatzpp/qat_task.hpp b/deps/zlib/contrib/qat/qatzpp/qat_task.hpp new file mode 100644 index 00000000000..3950502f50d --- /dev/null +++ b/deps/zlib/contrib/qat/qatzpp/qat_task.hpp @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2024 Intel Corporation. All rights reserved. + * Authors: + * Gustavo A Espinoza + * + * + * For conditions of distribution and use, see copyright notice in zlib.h + */ +#ifndef QATZPP_WORK_HPP +#define QATZPP_WORK_HPP + +#include + +#include + +#include "io_buffers.h" + +namespace qat +{ + +class QATTask +{ +public: + explicit QATTask(std::shared_ptr &qat_instance, + std::unique_ptr &&, + std::unique_ptr &&dc_results); + + QATTask(QATTask &&) = delete; + QATTask& operator=(QATTask &&) = delete; + + QATTask(const QATTask &) = delete; + QATTask &operator=(const QATTask &) = delete; + + void WaitCompletion(); + + IOBuffers *GetBuffers(); + CpaDcRqResults *GetResults(); + +private: + bool completed_; + + std::shared_ptr qat_instance_; + + std::unique_ptr dc_results_; + std::unique_ptr io_buffers_; + + friend void dc_callback(void *, CpaStatus); +}; + +void dc_callback(void*, CpaStatus); + +} + +#endif \ No newline at end of file diff --git a/deps/zlib/contrib/qat/qatzpp/session.cpp b/deps/zlib/contrib/qat/qatzpp/session.cpp new file mode 100644 index 00000000000..b4cefb31e85 --- /dev/null +++ b/deps/zlib/contrib/qat/qatzpp/session.cpp @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2024 Intel Corporation. All rights reserved. + * Authors: + * Gustavo A Espinoza + * + * + * For conditions of distribution and use, see copyright notice in zlib.h + */ +#include +#include + +#include "memory.hpp" +#include "session.hpp" + +namespace qat +{ + +constexpr CpaDcHuffType kHuffType = CPA_DC_HT_FULL_DYNAMIC; + +DeflateSession::DeflateSession( + std::shared_ptr &qat_instance, + CpaDcCompLvl comp_level, CpaDcChecksum checksum, + uint32_t numa_node): + qat_instance_(qat_instance) +{ + uint32_t session_size = 0; + uint32_t ctx_size = 0; + + CpaDcSessionSetupData sd{}; + sd.compLevel = comp_level; + sd.compType = CPA_DC_DEFLATE; + sd.huffType = kHuffType; + sd.autoSelectBestHuffmanTree = CPA_DC_ASB_UNCOMP_STATIC_DYNAMIC_WITH_STORED_HDRS; + sd.sessDirection = CPA_DC_DIR_COMBINED; + sd.sessState = CPA_DC_STATELESS; + sd.checksum = checksum; + + cpaDcGetSessionSize(qat_instance_->GetHandle(), &sd, &session_size, &ctx_size); + session_ = AllocBlockArray(session_size, numa_node); + + cpaDcInitSession( + qat_instance_->GetHandle(), + session_, + &sd, + nullptr, // No context for stateless operations + &dc_callback + ); + +} + +DeflateSession::~DeflateSession() +{ + if (session_) { + cpaDcRemoveSession(qat_instance_->GetHandle(), session_); + Free(session_); + } + + session_ = nullptr; +} + +std::unique_ptr DeflateSession::Deflate( + std::unique_ptr &&buffers, + bool flush_final) +{ + CpaDcOpData op_data{}; + op_data.flushFlag = (flush_final) ? + CPA_DC_FLUSH_FINAL : CPA_DC_FLUSH_FULL; + op_data.compressAndVerify = CPA_TRUE; + op_data.inputSkipData.skipMode = CPA_DC_SKIP_DISABLED; + op_data.outputSkipData.skipMode = CPA_DC_SKIP_DISABLED; + + auto task = std::make_unique( + qat_instance_, std::move(buffers), + std::make_unique() + ); + + cpaDcCompressData2( + qat_instance_->GetHandle(), + session_, + &task->GetBuffers()->GetSrc()->list, + &task->GetBuffers()->GetDst()->list, + &op_data, + task->GetResults(), + static_cast(task.get()) + ); + + return std::move(task); +} + +std::unique_ptr DeflateSession::Inflate(std::unique_ptr &&buffers) +{ + CpaDcOpData op_data = {}; + op_data.flushFlag = CPA_DC_FLUSH_FINAL; + op_data.compressAndVerify = CPA_TRUE; + op_data.inputSkipData.skipMode = CPA_DC_SKIP_DISABLED; + op_data.outputSkipData.skipMode = CPA_DC_SKIP_DISABLED; + + auto task = std::make_unique( + qat_instance_, std::move(buffers), + std::make_unique() + ); + + cpaDcDecompressData2( + qat_instance_->GetHandle(), + session_, + &task->GetBuffers()->GetSrc()->list, + &task->GetBuffers()->GetDst()->list, + &op_data, + task->GetResults(), + static_cast(task.get()) + ); + + return std::move(task); +} + +uint32_t DeflateSession::GetDeflateBound(uint32_t input_size) +{ + uint32_t output_size = 0; + + cpaDcDeflateCompressBound( + qat_instance_->GetHandle(), + kHuffType, + input_size, &output_size + ); + + return output_size; +} + +} diff --git a/deps/zlib/contrib/qat/qatzpp/session.hpp b/deps/zlib/contrib/qat/qatzpp/session.hpp new file mode 100644 index 00000000000..c8af47c27c2 --- /dev/null +++ b/deps/zlib/contrib/qat/qatzpp/session.hpp @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2024 Intel Corporation. All rights reserved. + * Authors: + * Gustavo A Espinoza + * + * + * For conditions of distribution and use, see copyright notice in zlib.h + */ +#ifndef QATZPP_SESSION_HPP +#define QATZPP_SESSION_HPP + +#include +#include + +#include + +#include "io_buffers.h" +#include "qat_task.hpp" + +namespace qat +{ + +class DeflateSession +{ +public: + DeflateSession( + std::shared_ptr &, CpaDcCompLvl, + CpaDcChecksum, uint32_t numa_node); + ~DeflateSession(); + + std::unique_ptr Deflate(std::unique_ptr &&buffers, bool flush_final); + std::unique_ptr Inflate(std::unique_ptr &&buffers); + + uint32_t GetDeflateBound(uint32_t input_size); + + std::shared_ptr getInstance() { return qat_instance_; } + +private: + std::shared_ptr qat_instance_; + CpaDcSessionHandle session_; +}; + +} + +#endif \ No newline at end of file diff --git a/deps/zlib/contrib/tests/fuzzers/BUILD.gn b/deps/zlib/contrib/tests/fuzzers/BUILD.gn index 16e918a720e..d7db4b3459b 100644 --- a/deps/zlib/contrib/tests/fuzzers/BUILD.gn +++ b/deps/zlib/contrib/tests/fuzzers/BUILD.gn @@ -34,6 +34,11 @@ fuzzer_test("zlib_deflate_set_dictionary_fuzzer") { deps = [ "../../../:zlib" ] } +fuzzer_test("zlib_compress_fuzzer") { + sources = [ "compress_fuzzer.cc" ] + deps = [ "../../../:zlib" ] +} + fuzzer_test("zlib_deflate_fuzzer") { sources = [ "deflate_fuzzer.cc" ] deps = [ "../../../:zlib" ] diff --git a/deps/zlib/contrib/tests/fuzzers/compress_fuzzer.cc b/deps/zlib/contrib/tests/fuzzers/compress_fuzzer.cc new file mode 100644 index 00000000000..3afc78122be --- /dev/null +++ b/deps/zlib/contrib/tests/fuzzers/compress_fuzzer.cc @@ -0,0 +1,46 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include + +#include + +#include "zlib.h" + +// Fuzzer builds often have NDEBUG set, so roll our own assert macro. +#define ASSERT(cond) \ + do { \ + if (!(cond)) { \ + fprintf(stderr, "%s:%d Assert failed: %s\n", __FILE__, __LINE__, #cond); \ + exit(1); \ + } \ + } while (0) + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + FuzzedDataProvider fdp(data, size); + const int level = fdp.PickValueInArray({-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}); + const std::vector src = fdp.ConsumeRemainingBytes(); + + const unsigned long compress_bound = compressBound(src.size()); + std::vector compressed; + compressed.resize(compress_bound); + + unsigned long compressed_size = compress_bound; + int ret = compress2(compressed.data(), &compressed_size, src.data(), + src.size(), level); + ASSERT(ret == Z_OK); + ASSERT(compressed_size <= compress_bound); + compressed.resize(compressed_size); + + std::vector uncompressed; + uncompressed.resize(src.size()); + unsigned long uncompressed_size = uncompressed.size(); + ret = uncompress(uncompressed.data(), &uncompressed_size, compressed.data(), + compressed.size()); + ASSERT(ret == Z_OK); + ASSERT(uncompressed_size == src.size()); + ASSERT(uncompressed == src); + + return 0; +} diff --git a/deps/zlib/crc32.c b/deps/zlib/crc32.c index 4177e920a47..204aa1ad0c4 100644 --- a/deps/zlib/crc32.c +++ b/deps/zlib/crc32.c @@ -1168,6 +1168,11 @@ ZLIB_INTERNAL void crc_reset(deflate_state *const s) ZLIB_INTERNAL void crc_finalize(deflate_state *const s) { +#ifdef QAT_COMPRESSION_ENABLED + if (s->qat_s) { + return; + } +#endif #ifdef CRC32_SIMD_SSE42_PCLMUL if (x86_cpu_enable_simd) s->strm->adler = crc_fold_512to32(s); diff --git a/deps/zlib/crc32_simd.c b/deps/zlib/crc32_simd.c index 1ee7742015d..1c60ae9bd3c 100644 --- a/deps/zlib/crc32_simd.c +++ b/deps/zlib/crc32_simd.c @@ -387,9 +387,9 @@ uint32_t ZLIB_INTERNAL crc32_sse42_simd_( /* SSE4.2+PCLMUL */ #endif #if defined(__aarch64__) -#define TARGET_ARMV8_WITH_CRC __attribute__((target("aes,crc"))) +#define TARGET_ARMV8_WITH_CRC __attribute__((target("arch=armv8-a+aes+crc"))) #else // !defined(__aarch64__) -#define TARGET_ARMV8_WITH_CRC __attribute__((target("armv8-a,crc"))) +#define TARGET_ARMV8_WITH_CRC __attribute__((target("crc"))) #endif // defined(__aarch64__) #elif defined(__GNUC__) @@ -398,7 +398,7 @@ uint32_t ZLIB_INTERNAL crc32_sse42_simd_( /* SSE4.2+PCLMUL */ */ #include #include -#define TARGET_ARMV8_WITH_CRC +#define TARGET_ARMV8_WITH_CRC __attribute__((target("arch=armv8-a+crc+crypto"))) #else // !defined(__GNUC__) && !defined(_aarch64__) #error ARM CRC32 SIMD extensions only supported for Clang and GCC #endif diff --git a/deps/zlib/deflate.c b/deps/zlib/deflate.c index b9a31203046..8a5281c2b6c 100644 --- a/deps/zlib/deflate.c +++ b/deps/zlib/deflate.c @@ -57,6 +57,10 @@ #include "slide_hash_simd.h" #endif +#if defined(QAT_COMPRESSION_ENABLED) +#include "contrib/qat/deflate_qat.h" +#endif + #include "contrib/optimizations/insert_string.h" #ifdef FASTEST @@ -564,6 +568,13 @@ int ZEXPORT deflateInit2_(z_streamp strm, int level, int method, s->strategy = strategy; s->method = (Byte)method; +#if defined(QAT_COMPRESSION_ENABLED) + s->qat_s = NULL; + if (s->level && qat_deflate_init() == Z_OK) { + s->qat_s = qat_deflate_state_init(s->level, s->wrap); + } +#endif + return deflateReset(strm); } @@ -962,6 +973,12 @@ local void flush_pending(z_streamp strm) { unsigned len; deflate_state *s = strm->state; +#if defined(QAT_COMPRESSION_ENABLED) + if (s->qat_s) { + qat_flush_pending(s); + } +#endif + _tr_flush_bits(s); len = s->pending; if (len > strm->avail_out) len = strm->avail_out; @@ -1315,6 +1332,12 @@ int ZEXPORT deflateEnd(z_streamp strm) { TRY_FREE(strm, strm->state->prev); TRY_FREE(strm, strm->state->window); +#if defined(QAT_COMPRESSION_ENABLED) + if (strm->state->qat_s) { + qat_deflate_state_free(strm->state); + } +#endif + ZFREE(strm, strm->state); strm->state = Z_NULL; @@ -1389,6 +1412,14 @@ int ZEXPORT deflateCopy(z_streamp dest, z_streamp source) { ds->d_desc.dyn_tree = ds->dyn_dtree; ds->bl_desc.dyn_tree = ds->bl_tree; +#if defined(QAT_COMPRESSION_ENABLED) + if(ss->qat_s) { + ds->qat_s = qat_deflate_copy(ss); + if (!ds->qat_s) + return Z_MEM_ERROR; + } +#endif + return Z_OK; #endif /* MAXSEG_64K */ } @@ -1880,6 +1911,24 @@ local block_state deflate_fast(deflate_state *s, int flush) { IPos hash_head; /* head of the hash chain */ int bflush; /* set if current block must be flushed */ +#if defined(QAT_COMPRESSION_ENABLED) + if (s->qat_s) { + qat_block_state qat_block = qat_deflate_step(s, flush); + switch (qat_block) { + case qat_block_need_more: + return need_more; + case qat_block_done: + return block_done; + case qat_block_finish_started: + return finish_started; + case qat_block_finish_done: + return finish_done; + case qat_failure: + break; + } + } +#endif + for (;;) { /* Make sure that we always have enough lookahead, except * at the end of the input file. We need MAX_MATCH bytes @@ -1982,6 +2031,24 @@ local block_state deflate_slow(deflate_state *s, int flush) { IPos hash_head; /* head of hash chain */ int bflush; /* set if current block must be flushed */ +#if defined(QAT_COMPRESSION_ENABLED) + if (s->qat_s) { + qat_block_state qat_block = qat_deflate_step(s, flush); + switch (qat_block) { + case qat_block_need_more: + return need_more; + case qat_block_done: + return block_done; + case qat_block_finish_started: + return finish_started; + case qat_block_finish_done: + return finish_done; + case qat_failure: + break; + } + } +#endif + /* Process the input block. */ for (;;) { /* Make sure that we always have enough lookahead, except diff --git a/deps/zlib/deflate.h b/deps/zlib/deflate.h index eb7f0724015..099d3594319 100644 --- a/deps/zlib/deflate.h +++ b/deps/zlib/deflate.h @@ -282,6 +282,13 @@ typedef struct internal_state { * hash is enabled. */ +#if defined(QAT_COMPRESSION_ENABLED) + /* Pointer to a struct that contains the current state of the QAT + * stream. + */ + struct qat_deflate *qat_s; +#endif + } FAR deflate_state; /* Output a byte on the stream. diff --git a/deps/zlib/google/zip_internal.cc b/deps/zlib/google/zip_internal.cc index d15c6cfe4f5..aa49f4546ca 100644 --- a/deps/zlib/google/zip_internal.cc +++ b/deps/zlib/google/zip_internal.cc @@ -8,12 +8,12 @@ #include #include +#include #include "base/containers/fixed_flat_set.h" #include "base/files/file_path.h" #include "base/logging.h" #include "base/notreached.h" -#include "base/strings/string_piece.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" @@ -398,64 +398,64 @@ Compression GetCompressionMethod(const base::FilePath& path) { if (ext.empty()) return kDeflated; - using StringPiece = base::FilePath::StringPieceType; // Skip the leading dot. - StringPiece ext_without_dot = ext; + base::FilePath::StringPieceType ext_without_dot = ext; DCHECK_EQ(ext_without_dot.front(), FILE_PATH_LITERAL('.')); ext_without_dot.remove_prefix(1); // Well known filename extensions of files that a likely to be already // compressed. The extensions are in lower case without the leading dot. - static constexpr auto kExts = base::MakeFixedFlatSet({ - FILE_PATH_LITERAL("3g2"), // - FILE_PATH_LITERAL("3gp"), // - FILE_PATH_LITERAL("7z"), // - FILE_PATH_LITERAL("7zip"), // - FILE_PATH_LITERAL("aac"), // - FILE_PATH_LITERAL("avi"), // - FILE_PATH_LITERAL("bz"), // - FILE_PATH_LITERAL("bz2"), // - FILE_PATH_LITERAL("crx"), // - FILE_PATH_LITERAL("gif"), // - FILE_PATH_LITERAL("gz"), // - FILE_PATH_LITERAL("jar"), // - FILE_PATH_LITERAL("jpeg"), // - FILE_PATH_LITERAL("jpg"), // - FILE_PATH_LITERAL("lz"), // - FILE_PATH_LITERAL("m2v"), // - FILE_PATH_LITERAL("m4p"), // - FILE_PATH_LITERAL("m4v"), // - FILE_PATH_LITERAL("mng"), // - FILE_PATH_LITERAL("mov"), // - FILE_PATH_LITERAL("mp2"), // - FILE_PATH_LITERAL("mp3"), // - FILE_PATH_LITERAL("mp4"), // - FILE_PATH_LITERAL("mpe"), // - FILE_PATH_LITERAL("mpeg"), // - FILE_PATH_LITERAL("mpg"), // - FILE_PATH_LITERAL("mpv"), // - FILE_PATH_LITERAL("ogg"), // - FILE_PATH_LITERAL("ogv"), // - FILE_PATH_LITERAL("png"), // - FILE_PATH_LITERAL("qt"), // - FILE_PATH_LITERAL("rar"), // - FILE_PATH_LITERAL("taz"), // - FILE_PATH_LITERAL("tb2"), // - FILE_PATH_LITERAL("tbz"), // - FILE_PATH_LITERAL("tbz2"), // - FILE_PATH_LITERAL("tgz"), // - FILE_PATH_LITERAL("tlz"), // - FILE_PATH_LITERAL("tz"), // - FILE_PATH_LITERAL("tz2"), // - FILE_PATH_LITERAL("vob"), // - FILE_PATH_LITERAL("webm"), // - FILE_PATH_LITERAL("wma"), // - FILE_PATH_LITERAL("wmv"), // - FILE_PATH_LITERAL("xz"), // - FILE_PATH_LITERAL("z"), // - FILE_PATH_LITERAL("zip"), // - }); + static constexpr auto kExts = + base::MakeFixedFlatSet({ + FILE_PATH_LITERAL("3g2"), // + FILE_PATH_LITERAL("3gp"), // + FILE_PATH_LITERAL("7z"), // + FILE_PATH_LITERAL("7zip"), // + FILE_PATH_LITERAL("aac"), // + FILE_PATH_LITERAL("avi"), // + FILE_PATH_LITERAL("bz"), // + FILE_PATH_LITERAL("bz2"), // + FILE_PATH_LITERAL("crx"), // + FILE_PATH_LITERAL("gif"), // + FILE_PATH_LITERAL("gz"), // + FILE_PATH_LITERAL("jar"), // + FILE_PATH_LITERAL("jpeg"), // + FILE_PATH_LITERAL("jpg"), // + FILE_PATH_LITERAL("lz"), // + FILE_PATH_LITERAL("m2v"), // + FILE_PATH_LITERAL("m4p"), // + FILE_PATH_LITERAL("m4v"), // + FILE_PATH_LITERAL("mng"), // + FILE_PATH_LITERAL("mov"), // + FILE_PATH_LITERAL("mp2"), // + FILE_PATH_LITERAL("mp3"), // + FILE_PATH_LITERAL("mp4"), // + FILE_PATH_LITERAL("mpe"), // + FILE_PATH_LITERAL("mpeg"), // + FILE_PATH_LITERAL("mpg"), // + FILE_PATH_LITERAL("mpv"), // + FILE_PATH_LITERAL("ogg"), // + FILE_PATH_LITERAL("ogv"), // + FILE_PATH_LITERAL("png"), // + FILE_PATH_LITERAL("qt"), // + FILE_PATH_LITERAL("rar"), // + FILE_PATH_LITERAL("taz"), // + FILE_PATH_LITERAL("tb2"), // + FILE_PATH_LITERAL("tbz"), // + FILE_PATH_LITERAL("tbz2"), // + FILE_PATH_LITERAL("tgz"), // + FILE_PATH_LITERAL("tlz"), // + FILE_PATH_LITERAL("tz"), // + FILE_PATH_LITERAL("tz2"), // + FILE_PATH_LITERAL("vob"), // + FILE_PATH_LITERAL("webm"), // + FILE_PATH_LITERAL("wma"), // + FILE_PATH_LITERAL("wmv"), // + FILE_PATH_LITERAL("xz"), // + FILE_PATH_LITERAL("z"), // + FILE_PATH_LITERAL("zip"), // + }); if (kExts.count(ext_without_dot)) { return kStored; diff --git a/deps/zlib/google/zip_reader.cc b/deps/zlib/google/zip_reader.cc index 34a815e5f52..182a802ad84 100644 --- a/deps/zlib/google/zip_reader.cc +++ b/deps/zlib/google/zip_reader.cc @@ -5,6 +5,7 @@ #include "third_party/zlib/google/zip_reader.h" #include +#include #include #include "base/check.h" @@ -15,7 +16,6 @@ #include "base/logging.h" #include "base/numerics/safe_conversions.h" #include "base/strings/strcat.h" -#include "base/strings/string_piece.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "base/task/sequenced_task_runner.h" @@ -267,7 +267,7 @@ bool ZipReader::OpenEntry() { return true; } -void ZipReader::Normalize(base::StringPiece16 in) { +void ZipReader::Normalize(std::u16string_view in) { entry_.is_unsafe = true; // Directory entries in ZIP have a path ending with "/". @@ -281,15 +281,16 @@ void ZipReader::Normalize(base::StringPiece16 in) { for (;;) { // Consume initial path separators. - const base::StringPiece16::size_type i = in.find_first_not_of(u'/'); - if (i == base::StringPiece16::npos) + const std::u16string_view::size_type i = in.find_first_not_of(u'/'); + if (i == std::u16string_view::npos) { break; + } in.remove_prefix(i); DCHECK(!in.empty()); // Isolate next path component. - const base::StringPiece16 part = in.substr(0, in.find_first_of(u'/')); + const std::u16string_view part = in.substr(0, in.find_first_of(u'/')); DCHECK(!part.empty()); in.remove_prefix(part.size()); diff --git a/deps/zlib/google/zip_reader.h b/deps/zlib/google/zip_reader.h index b7680cc8393..0dbf50b87b6 100644 --- a/deps/zlib/google/zip_reader.h +++ b/deps/zlib/google/zip_reader.h @@ -10,6 +10,7 @@ #include #include #include +#include #include "base/files/file.h" #include "base/files/file_path.h" @@ -281,7 +282,7 @@ class ZipReader { // Normalizes the given path passed as UTF-16 string piece. Sets entry_.path, // entry_.is_directory and entry_.is_unsafe. - void Normalize(base::StringPiece16 in); + void Normalize(std::u16string_view in); // Runs the ListenerCallback at a throttled rate. void ReportProgress(ListenerCallback listener_callback, uint64_t bytes) const; diff --git a/deps/zlib/google/zip_reader_unittest.cc b/deps/zlib/google/zip_reader_unittest.cc index 9eb7d7d2b10..9d1406feff9 100644 --- a/deps/zlib/google/zip_reader_unittest.cc +++ b/deps/zlib/google/zip_reader_unittest.cc @@ -10,6 +10,7 @@ #include #include +#include #include #include "base/check.h" @@ -22,7 +23,6 @@ #include "base/i18n/time_formatting.h" #include "base/path_service.h" #include "base/run_loop.h" -#include "base/strings/string_piece.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #include "base/test/bind.h" @@ -172,7 +172,7 @@ class ZipReaderTest : public PlatformTest { } static Paths GetPaths(const base::FilePath& zip_path, - base::StringPiece encoding = {}) { + std::string_view encoding = {}) { Paths paths; if (ZipReader reader; reader.Open(zip_path)) { @@ -422,7 +422,7 @@ TEST_F(ZipReaderTest, EncryptedFile_WrongPassword) { EXPECT_EQ("This is not encrypted.\n", contents); } - for (const base::StringPiece path : { + for (const std::string_view path : { "Encrypted AES-128.txt", "Encrypted AES-192.txt", "Encrypted AES-256.txt", @@ -458,7 +458,7 @@ TEST_F(ZipReaderTest, EncryptedFile_RightPassword) { } // TODO(crbug.com/1296838) Support AES encryption. - for (const base::StringPiece path : { + for (const std::string_view path : { "Encrypted AES-128.txt", "Encrypted AES-192.txt", "Encrypted AES-256.txt", @@ -713,12 +713,12 @@ TEST_F(ZipReaderTest, ExtractCurrentEntryToString) { if (i > 0) { // Exact byte read limit: must pass. EXPECT_TRUE(reader.ExtractCurrentEntryToString(i, &contents)); - EXPECT_EQ(std::string(base::StringPiece("0123456", i)), contents); + EXPECT_EQ(std::string(std::string_view("0123456", i)), contents); } // More than necessary byte read limit: must pass. EXPECT_TRUE(reader.ExtractCurrentEntryToString(&contents)); - EXPECT_EQ(std::string(base::StringPiece("0123456", i)), contents); + EXPECT_EQ(std::string(std::string_view("0123456", i)), contents); } reader.Close(); } diff --git a/deps/zlib/google/zip_unittest.cc b/deps/zlib/google/zip_unittest.cc index 922d38303ce..58bafb809d6 100644 --- a/deps/zlib/google/zip_unittest.cc +++ b/deps/zlib/google/zip_unittest.cc @@ -2,12 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "third_party/zlib/google/zip.h" + #include #include #include #include #include +#include #include #include #include @@ -29,7 +32,6 @@ #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "testing/platform_test.h" -#include "third_party/zlib/google/zip.h" #include "third_party/zlib/google/zip_internal.h" #include "third_party/zlib/google/zip_reader.h" @@ -1290,7 +1292,7 @@ TEST_F(ZipTest, Compressed) { EXPECT_TRUE(base::CreateDirectory(src_dir)); // Create some dummy source files. - for (const base::StringPiece s : {"foo", "bar.txt", ".hidden"}) { + for (const std::string_view s : {"foo", "bar.txt", ".hidden"}) { base::File f(src_dir.AppendASCII(s), base::File::FLAG_CREATE | base::File::FLAG_WRITE); ASSERT_TRUE(f.SetLength(5000)); diff --git a/deps/zlib/zlib.gyp b/deps/zlib/zlib.gyp index 26ceed9fbe6..25f570fbe7b 100644 --- a/deps/zlib/zlib.gyp +++ b/deps/zlib/zlib.gyp @@ -7,7 +7,6 @@ 'ZLIB_ROOT': '.', 'use_system_zlib%': 0, 'arm_fpu%': '', - 'llvm_version%': '0.0', }, 'conditions': [ ['use_system_zlib==0', { @@ -24,7 +23,7 @@ },{ 'defines': [ 'X86_NOT_WINDOWS' ], }], - ['OS!="win" or llvm_version!="0.0"', { + ['OS!="win" or clang==1', { 'cflags': [ '-mssse3' ], 'xcode_settings': { 'OTHER_CFLAGS': [ '-mssse3' ], @@ -65,7 +64,7 @@ 'conditions': [ ['OS!="ios"', { 'conditions': [ - ['OS!="win" and llvm_version=="0.0"', { + ['OS!="win" and clang==0', { 'cflags': [ '-march=armv8-a+aes+crc' ], }], ['OS=="android"', { @@ -111,7 +110,7 @@ # 'target_name': 'zlib_crc32_simd', # 'type': 'static_library', # 'conditions': [ - # ['OS!="win" or llvm_version!="0.0"', { + # ['OS!="win" or clang==1', { # 'cflags': [ # '-msse4.2', # '-mpclmul', diff --git a/doc/api/addons.md b/doc/api/addons.md index 08172a9ae9c..446a63b1a2f 100644 --- a/doc/api/addons.md +++ b/doc/api/addons.md @@ -923,7 +923,7 @@ void MyObject::New(const FunctionCallbackInfo& args) { void MyObject::PlusOne(const FunctionCallbackInfo& args) { Isolate* isolate = args.GetIsolate(); - MyObject* obj = ObjectWrap::Unwrap(args.Holder()); + MyObject* obj = ObjectWrap::Unwrap(args.This()); obj->value_ += 1; args.GetReturnValue().Set(Number::New(isolate, obj->value_)); @@ -1138,7 +1138,7 @@ void MyObject::NewInstance(const FunctionCallbackInfo& args) { void MyObject::PlusOne(const FunctionCallbackInfo& args) { Isolate* isolate = args.GetIsolate(); - MyObject* obj = ObjectWrap::Unwrap(args.Holder()); + MyObject* obj = ObjectWrap::Unwrap(args.This()); obj->value_ += 1; args.GetReturnValue().Set(Number::New(isolate, obj->value_)); diff --git a/doc/api/async_hooks.md b/doc/api/async_hooks.md index a5571c30be5..07793fca90e 100644 --- a/doc/api/async_hooks.md +++ b/doc/api/async_hooks.md @@ -704,7 +704,7 @@ import { executionAsyncId, executionAsyncResource, createHook, -} from 'async_hooks'; +} from 'node:async_hooks'; const sym = Symbol('state'); // Private symbol to avoid pollution createHook({ diff --git a/doc/api/buffer.md b/doc/api/buffer.md index be7998b5b7d..65a2548d98b 100644 --- a/doc/api/buffer.md +++ b/doc/api/buffer.md @@ -513,6 +513,23 @@ added: Returns a promise that fulfills with an {ArrayBuffer} containing a copy of the `Blob` data. +#### `blob.bytes()` + + + +The `blob.bytes()` method returns the byte of the `Blob` object as a `Promise`. + +```js +const blob = new Blob(['hello']); +blob.bytes().then((bytes) => { + console.log(bytes); // Outputs: Uint8Array(5) [ 104, 101, 108, 108, 111 ] +}); +``` + ### `blob.size` -> Stability: 1 - Experimental +> Stability: 2 - Stable -Enable experimental support for custom [conditional exports][] resolution -conditions. +Provide custom [conditional exports][] resolution conditions. Any number of custom string condition names are permitted. @@ -687,6 +691,23 @@ Make built-in language features like `eval` and `new Function` that generate code from strings throw an exception instead. This does not affect the Node.js `node:vm` module. +### `--expose-gc` + + + +> Stability: 1 - Experimental. This flag is inherited from V8 and is subject to +> change upstream. + +This flag will expose the gc extension from V8. + +```js +if (globalThis.gc) { + globalThis.gc(); +} +``` + ### `--dns-result-order=order` + +Enable exposition of [EventSource Web API][] on the global scope. + ### `--experimental-import-meta-resolve` + +> Stability: 1 - Experimental + +Enable experimental support for the network inspection with Chrome DevTools. + ### `--experimental-permission` + +> Stability: 1.0 - Early development + +Enable module mocking in the test runner. + ### `--experimental-vm-modules` + Disable the clearing of the console when watch mode restarts the process. ```bash @@ -2697,6 +2753,7 @@ one is included in the list below. * `--experimental-abortcontroller` * `--experimental-default-type` * `--experimental-detect-module` +* `--experimental-eventsource` * `--experimental-import-meta-resolve` * `--experimental-json-modules` * `--experimental-loader` @@ -2810,6 +2867,7 @@ V8 options that are allowed are: * `--abort-on-uncaught-exception` * `--disallow-code-generation-from-strings` * `--enable-etw-stack-walking` +* `--expose-gc` * `--huge-max-old-generation-size` * `--interpreted-frames-native-stack` * `--jitless` @@ -2823,11 +2881,15 @@ V8 options that are allowed are: + + `--perf-basic-prof-only-functions`, `--perf-basic-prof`, `--perf-prof-unwinding-info`, and `--perf-prof` are only available on Linux. `--enable-etw-stack-walking` is only available on Windows. + + ### `NODE_PATH=path[:…]` + +### `--abort-on-uncaught-exception` + +### `--disallow-code-generation-from-strings` + +### `--enable-etw-stack-walking` + +### `--expose-gc` + +### `--harmony-shadow-realm` + +### `--huge-max-old-generation-size` + +### `--jitless` + +### `--interpreted-frames-native-stack` + +### `--prof` + +### `--perf-basic-prof` + +### `--perf-basic-prof-only-functions` + +### `--perf-prof` + +### `--perf-prof-unwinding-info` + + + + + +### `--max-old-space-size=SIZE` (in MiB) Sets the max memory size of V8's old memory section. As memory consumption approaches the limit, V8 will spend more time on @@ -3140,10 +3234,14 @@ On a machine with 2 GiB of memory, consider setting this to node --max-old-space-size=1536 index.js ``` -### `--max-semi-space-size=SIZE` (in megabytes) + + + + +### `--max-semi-space-size=SIZE` (in MiB) Sets the maximum [semi-space][] size for V8's [scavenge garbage collector][] in -MiB (megabytes). +MiB (mebibytes). Increasing the max size of a semi-space may improve throughput for Node.js at the cost of more memory consumption. @@ -3165,6 +3263,19 @@ for MiB in 16 32 64 128; do done ``` +### `--security-revert` + +### `--stack-trace-limit=limit` + +The maximum number of stack frames to collect in an error's stack trace. +Setting it to 0 disables stack trace collection. The default value is 10. + +```bash +node --stack-trace-limit=12 -p -e "Error.stackTraceLimit" # prints 12 +``` + + + [#42511]: https://github.com/nodejs/node/issues/42511 [Chrome DevTools Protocol]: https://chromedevtools.github.io/devtools-protocol/ [CommonJS]: modules.md @@ -3172,6 +3283,7 @@ done [CustomEvent Web API]: https://dom.spec.whatwg.org/#customevent [DEP0025 warning]: deprecations.md#dep0025-requirenodesys [ECMAScript module]: esm.md#modules-ecmascript-modules +[EventSource Web API]: https://html.spec.whatwg.org/multipage/server-sent-events.html#server-sent-events [ExperimentalWarning: `vm.measureMemory` is an experimental feature]: vm.md#vmmeasurememoryoptions [Fetch API]: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API [File System Permissions]: permissions.md#file-system-permissions diff --git a/doc/api/console.md b/doc/api/console.md index c9812f05597..147a45eadb1 100644 --- a/doc/api/console.md +++ b/doc/api/console.md @@ -80,7 +80,11 @@ The `Console` class can be used to create a simple logger with configurable output streams and can be accessed using either `require('node:console').Console` or `console.Console` (or their destructured counterparts): -```js +```mjs +import { Console } from 'node:console'; +``` + +```cjs const { Console } = require('node:console'); ``` @@ -132,7 +136,28 @@ Creates a new `Console` with one or two writable stream instances. `stdout` is a writable stream to print log or info output. `stderr` is used for warning or error output. If `stderr` is not provided, `stdout` is used for `stderr`. -```js +```mjs +import { createWriteStream } from 'node:fs'; +import { Console } from 'node:console'; +// Alternatively +// const { Console } = console; + +const output = createWriteStream('./stdout.log'); +const errorOutput = createWriteStream('./stderr.log'); +// Custom simple logger +const logger = new Console({ stdout: output, stderr: errorOutput }); +// use it like console +const count = 5; +logger.log('count: %d', count); +// In stdout.log: count 5 +``` + +```cjs +const fs = require('node:fs'); +const { Console } = require('node:console'); +// Alternatively +// const { Console } = console; + const output = fs.createWriteStream('./stdout.log'); const errorOutput = fs.createWriteStream('./stderr.log'); // Custom simple logger diff --git a/doc/api/deprecations.md b/doc/api/deprecations.md index d302c4b14c6..c04c15e013e 100644 --- a/doc/api/deprecations.md +++ b/doc/api/deprecations.md @@ -3543,6 +3543,36 @@ switch to its new provider model. The `clientCertEngine` option for the `privateKeyEngine` and `privateKeyIdentifier` for [`tls.createSecureContext()`][]; and [`crypto.setEngine()`][] all depend on this functionality from OpenSSL. +### DEP0184: Instantiating `node:zlib` classes without `new` + + + +Type: Documentation-only + +Instantiating classes without the `new` qualifier exported by the `node:zlib` module is deprecated. +It is recommended to use the `new` qualifier instead. This applies to all Zlib classes, such as `Deflate`, +`DeflateRaw`, `Gunzip`, `Inflate`, `InflateRaw`, `Unzip`, and `Zlib`. + +### DEP0185: Instantiating `node:repl` classes without `new` + + + +Type: Documentation-only + +Instantiating classes without the `new` qualifier exported by the `node:repl` module is deprecated. +It is recommended to use the `new` qualifier instead. This applies to all REPL classes, including +`REPLServer` and `Recoverable`. + [NIST SP 800-38D]: https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf [RFC 6066]: https://tools.ietf.org/html/rfc6066#section-3 [RFC 8247 Section 2.4]: https://www.rfc-editor.org/rfc/rfc8247#section-2.4 diff --git a/doc/api/diagnostics_channel.md b/doc/api/diagnostics_channel.md index 39be4115bb4..eb59fa932af 100644 --- a/doc/api/diagnostics_channel.md +++ b/doc/api/diagnostics_channel.md @@ -863,7 +863,7 @@ channels.tracePromise(async () => { }); ``` -#### `tracingChannel.traceCallback(fn, position, context, thisArg, ...args)` +#### `tracingChannel.traceCallback(fn[, position[, context[, thisArg[, ...args]]]])` Too much HTTP header data was received. In order to protect against malicious or -malconfigured clients, if more than 8 KiB of HTTP header data is received then +malconfigured clients, if more than `maxHeaderSize` of HTTP header data is received then HTTP parsing will abort without a request or response object being created, and an `Error` with this code will be emitted. diff --git a/doc/api/globals.md b/doc/api/globals.md index 9d3d1e23bd6..d25b50d2b12 100644 --- a/doc/api/globals.md +++ b/doc/api/globals.md @@ -451,6 +451,17 @@ changes: A browser-compatible implementation of the `Event` class. See [`EventTarget` and `Event` API][] for more details. +## `EventSource` + + + +> Stability: 1 - Experimental. Enable this API with the [`--experimental-eventsource`][] +> CLI flag. + +A browser-compatible implementation of the [`EventSource`][] class. + ## `EventTarget` + +> Stability: 1 - Experimental + +* `params` {Object} + +This feature is only available with the `--experimental-network-inspection` flag enabled. + +Broadcasts the `Network.requestWillBeSent` event to connected frontends. This event indicates that +the application is about to send an HTTP request. + +### `inspector.Network.responseReceived([params])` + + + +> Stability: 1 - Experimental + +* `params` {Object} + +This feature is only available with the `--experimental-network-inspection` flag enabled. + +Broadcasts the `Network.responseReceived` event to connected frontends. This event indicates that +HTTP response is available. + +### `inspector.Network.loadingFinished([params])` + + + +> Stability: 1 - Experimental + +* `params` {Object} + +This feature is only available with the `--experimental-network-inspection` flag enabled. + +Broadcasts the `Network.loadingFinished` event to connected frontends. This event indicates that +HTTP request has finished loading. + +### `inspector.Network.loadingFailed([params])` + + + +> Stability: 1 - Experimental + +* `params` {Object} + +This feature is only available with the `--experimental-network-inspection` flag enabled. + +Broadcasts the `Network.loadingFailed` event to connected frontends. This event indicates that +HTTP request has failed to load. + ## Support of breakpoints The Chrome DevTools Protocol [`Debugger` domain][] allows an diff --git a/doc/api/modules.md b/doc/api/modules.md index 9207d97410b..16f93992f74 100644 --- a/doc/api/modules.md +++ b/doc/api/modules.md @@ -387,7 +387,7 @@ described in greater detail elsewhere in this documentation. The built-in modules are defined within the Node.js source and are located in the `lib/` folder. -built-in modules can be identified using the `node:` prefix, in which case +Built-in modules can be identified using the `node:` prefix, in which case it bypasses the `require` cache. For instance, `require('node:http')` will always return the built in HTTP module, even if there is `require.cache` entry by that name. diff --git a/doc/api/n-api.md b/doc/api/n-api.md index ac38710303f..8de55d8c709 100644 --- a/doc/api/n-api.md +++ b/doc/api/n-api.md @@ -3081,6 +3081,54 @@ The native string is copied. The JavaScript `string` type is described in [Section 6.1.4][] of the ECMAScript Language Specification. +### Functions to create optimized property keys + +Many JavaScript engines including V8 use internalized strings as keys +to set and get property values. They typically use a hash table to create +and lookup such strings. While it adds some cost per key creation, it improves +the performance after that by enabling comparison of string pointers instead +of the whole strings. + +If a new JavaScript string is intended to be used as a property key, then for +some JavaScript engines it will be more efficient to use the functions in this +section. Otherwise, use the `napi_create_string_utf8` or +`node_api_create_external_string_utf8` series functions as there may be +additional overhead in creating/storing strings with the property key +creation methods. + +#### `node_api_create_property_key_latin1` + + + +> Stability: 1 - Experimental + +```c +napi_status NAPI_CDECL node_api_create_property_key_latin1(napi_env env, + const char* str, + size_t length, + napi_value* result); +``` + +* `[in] env`: The environment that the API is invoked under. +* `[in] str`: Character buffer representing an ISO-8859-1-encoded string. +* `[in] length`: The length of the string in bytes, or `NAPI_AUTO_LENGTH` if it + is null-terminated. +* `[out] result`: A `napi_value` representing an optimized JavaScript `string` + to be used as a property key for objects. + +Returns `napi_ok` if the API succeeded. + +This API creates an optimized JavaScript `string` value from +an ISO-8859-1-encoded C string to be used as a property key for objects. +The native string is copied. In contrast with `napi_create_string_latin1`, +subsequent calls to this function with the same `str` pointer may benefit from a speedup +in the creation of the requested `napi_value`, depending on the engine. + +The JavaScript `string` type is described in +[Section 6.1.4][] of the ECMAScript Language Specification. + #### `node_api_create_property_key_utf16` + +> Stability: 1 - Experimental + +```c +napi_status NAPI_CDECL node_api_create_property_key_utf8(napi_env env, + const char* str, + size_t length, + napi_value* result); +``` + +* `[in] env`: The environment that the API is invoked under. +* `[in] str`: Character buffer representing a UTF8-encoded string. +* `[in] length`: The length of the string in two-byte code units, or + `NAPI_AUTO_LENGTH` if it is null-terminated. +* `[out] result`: A `napi_value` representing an optimized JavaScript `string` + to be used as a property key for objects. + +Returns `napi_ok` if the API succeeded. + +This API creates an optimized JavaScript `string` value from +a UTF8-encoded C string to be used as a property key for objects. +The native string is copied. The JavaScript `string` type is described in [Section 6.1.4][] of the ECMAScript Language Specification. diff --git a/doc/api/net.md b/doc/api/net.md index a1c8f624a50..1b02978cfa1 100644 --- a/doc/api/net.md +++ b/doc/api/net.md @@ -660,6 +660,19 @@ changes: `false`. * `fd` {number} If specified, wrap around an existing socket with the given file descriptor, otherwise a new socket will be created. + * `onread` {Object} If specified, incoming data is stored in a single `buffer` + and passed to the supplied `callback` when data arrives on the socket. + This will cause the streaming functionality to not provide any data. + The socket will emit events like `'error'`, `'end'`, and `'close'` + as usual. Methods like `pause()` and `resume()` will also behave as + expected. + * `buffer` {Buffer|Uint8Array|Function} Either a reusable chunk of memory to + use for storing incoming data or a function that returns such. + * `callback` {Function} This function is called for every chunk of incoming + data. Two arguments are passed to it: the number of bytes written to + `buffer` and a reference to `buffer`. Return `false` from this function to + implicitly `pause()` the socket. This function will be executed in the + global context. * `readable` {boolean} Allow reads on the socket when an `fd` is passed, otherwise ignored. **Default:** `false`. * `signal` {AbortSignal} An Abort signal that may be used to destroy the @@ -1021,39 +1034,6 @@ For [IPC][] connections, available `options` are: See [Identifying paths for IPC connections][]. If provided, the TCP-specific options above are ignored. -For both types, available `options` include: - -* `onread` {Object} If specified, incoming data is stored in a single `buffer` - and passed to the supplied `callback` when data arrives on the socket. - This will cause the streaming functionality to not provide any data. - The socket will emit events like `'error'`, `'end'`, and `'close'` - as usual. Methods like `pause()` and `resume()` will also behave as - expected. - * `buffer` {Buffer|Uint8Array|Function} Either a reusable chunk of memory to - use for storing incoming data or a function that returns such. - * `callback` {Function} This function is called for every chunk of incoming - data. Two arguments are passed to it: the number of bytes written to - `buffer` and a reference to `buffer`. Return `false` from this function to - implicitly `pause()` the socket. This function will be executed in the - global context. - -Following is an example of a client using the `onread` option: - -```js -const net = require('node:net'); -net.connect({ - port: 80, - onread: { - // Reuses a 4KiB Buffer for every read from the socket. - buffer: Buffer.alloc(4 * 1024), - callback: function(nread, buf) { - // Received data is available in `buf` from 0 to `nread`. - console.log(buf.toString('utf8', 0, nread)); - }, - }, -}); -``` - #### `socket.connect(path[, connectListener])` * `path` {string} Path the client should connect to. See @@ -1556,6 +1536,26 @@ To connect on the socket `/tmp/echo.sock`: const client = net.createConnection({ path: '/tmp/echo.sock' }); ``` +Following is an example of a client using the `port` and `onread` +option. In this case, the `onread` option will be only used to call +`new net.Socket([options])` and the `port` option will be used to +call `socket.connect(options[, connectListener])`. + +```js +const net = require('node:net'); +net.createConnection({ + port: 80, + onread: { + // Reuses a 4KiB Buffer for every read from the socket. + buffer: Buffer.alloc(4 * 1024), + callback: function(nread, buf) { + // Received data is available in `buf` from 0 to `nread`. + console.log(buf.toString('utf8', 0, nread)); + }, + }, +}); +``` + ### `net.createConnection(path[, connectListener])` + +* Returns: {Object} + * `loopCount` {number} Number of event loop iterations. + * `events` {number} Number of events that have been processed by the event handler. + * `eventsWaiting` {number} Number of events that were waiting to be processed when the event provider was called. + +This is a wrapper to the `uv_metrics_info` function. +It returns the current set of event loop metrics. + +It is recommended to use this property inside a function whose execution was +scheduled using `setImmediate` to avoid collecting metrics before finishing all +operations scheduled during the current loop iteration. + +```cjs +const { performance } = require('node:perf_hooks'); + +setImmediate(() => { + console.log(performance.nodeTiming.uvMetricsInfo); +}); +``` + +```mjs +import { performance } from 'node:perf_hooks'; + +setImmediate(() => { + console.log(performance.nodeTiming.uvMetricsInfo); +}); +``` + ### `performanceNodeTiming.v8Start` +> Stability: 3 - Legacy: Use [`queueMicrotask()`][] instead. + * `callback` {Function} * `...args` {any} Additional arguments to pass when invoking the `callback` @@ -4024,7 +4029,7 @@ cases: code will be `128` + `6`, or `134`. [Advanced serialization for `child_process`]: child_process.md#advanced-serialization -[Android building]: https://github.com/nodejs/node/blob/HEAD/BUILDING.md#androidandroid-based-devices-eg-firefox-os +[Android building]: https://github.com/nodejs/node/blob/HEAD/BUILDING.md#android [Child Process]: child_process.md [Cluster]: cluster.md [Duplex]: stream.md#duplex-and-transform-streams diff --git a/doc/api/repl.md b/doc/api/repl.md index 16378cca8ab..89d02ff7eeb 100644 --- a/doc/api/repl.md +++ b/doc/api/repl.md @@ -774,6 +774,14 @@ a `net.Server` and `net.Socket` instance, see: For an example of running a REPL instance over [`curl(1)`][], see: . +This example is intended purely for educational purposes to demonstrate how +Node.js REPLs can be started using different I/O streams. +It should **not** be used in production environments or any context where security +is a concern without additional protective measures. +If you need to implement REPLs in a real-world application, consider alternative +approaches that mitigate these risks, such as using secure input mechanisms and +avoiding open network interfaces. + [TTY keybindings]: readline.md#tty-keybindings [ZSH]: https://en.wikipedia.org/wiki/Z_shell [`'uncaughtException'`]: process.md#event-uncaughtexception diff --git a/doc/api/single-executable-applications.md b/doc/api/single-executable-applications.md index 61dd7fcedbd..c282446fa52 100644 --- a/doc/api/single-executable-applications.md +++ b/doc/api/single-executable-applications.md @@ -190,6 +190,13 @@ If the paths are not absolute, Node.js will use the path relative to the current working directory. The version of the Node.js binary used to produce the blob must be the same as the one to which the blob will be injected. +Note: When generating cross-platform SEAs (e.g., generating a SEA +for `linux-x64` on `darwin-arm64`), `useCodeCache` and `useSnapshot` +must be set to false to avoid generating incompatible executables. +Since code cache and snapshots can only be loaded on the same platform +where they are compiled, the generated executable might crash on startup when +trying to load code cache or snapshots built on a different platform. + ### Assets Users can include assets by adding a key-path dictionary to the configuration @@ -212,7 +219,7 @@ executable, users can retrieve the assets using the [`sea.getAsset()`][] and The single-executable application can access the assets as follows: ```cjs -const { getAsset } = require('node:sea'); +const { getAsset, getAssetAsBlob, getRawAsset } = require('node:sea'); // Returns a copy of the data in an ArrayBuffer. const image = getAsset('a.jpg'); // Returns a string decoded from the asset as UTF8. @@ -223,7 +230,7 @@ const blob = getAssetAsBlob('a.jpg'); const raw = getRawAsset('a.jpg'); ``` -See documentation of the [`sea.getAsset()`][] and [`sea.getAssetAsBlob()`][] +See documentation of the [`sea.getAsset()`][], [`sea.getAssetAsBlob()`][] and [`sea.getRawAsset()`][] APIs for more information. ### Startup snapshot support @@ -328,7 +335,7 @@ This method can be used to retrieve the assets configured to be bundled into the single-executable application at build time. An error is thrown when no matching asset can be found. -Unlike `sea.getRawAsset()` or `sea.getAssetAsBlob()`, this method does not +Unlike `sea.getAsset()` or `sea.getAssetAsBlob()`, this method does not return a copy. Instead, it returns the raw asset bundled inside the executable. For now, users should avoid writing to the returned array buffer. If the @@ -414,6 +421,7 @@ to help us document them. [`require.main`]: modules.md#accessing-the-main-module [`sea.getAsset()`]: #seagetassetkey-encoding [`sea.getAssetAsBlob()`]: #seagetassetasblobkey-options +[`sea.getRawAsset()`]: #seagetrawassetkey [`v8.startupSnapshot.setDeserializeMainFunction()`]: v8.md#v8startupsnapshotsetdeserializemainfunctioncallback-data [`v8.startupSnapshot` API]: v8.md#startup-snapshot-api [documentation about startup snapshot support in Node.js]: cli.md#--build-snapshot diff --git a/doc/api/test.md b/doc/api/test.md index d50d40d4bfc..9824b72647e 100644 --- a/doc/api/test.md +++ b/doc/api/test.md @@ -431,7 +431,8 @@ command-line flag, code coverage is collected and statistics are reported once all tests have completed. If the [`NODE_V8_COVERAGE`][] environment variable is used to specify a code coverage directory, the generated V8 coverage files are written to that directory. Node.js core modules and files within -`node_modules/` directories are not included in the coverage report. If +`node_modules/` directories are, by default, not included in the coverage report. +However, they can be explicity included via the [`--test-coverage-include`][] flag. If coverage is enabled, the coverage report is sent to any [test reporters][] via the `'test:coverage'` event. @@ -1047,13 +1048,13 @@ export default async function * customReporter(source) { for await (const event of source) { switch (event.type) { case 'test:dequeue': - yield `test ${event.data.name} dequeued`; + yield `test ${event.data.name} dequeued\n`; break; case 'test:enqueue': - yield `test ${event.data.name} enqueued`; + yield `test ${event.data.name} enqueued\n`; break; case 'test:watch:drained': - yield 'test watch queue drained'; + yield 'test watch queue drained\n'; break; case 'test:start': yield `test ${event.data.name} started\n`; @@ -1065,7 +1066,7 @@ export default async function * customReporter(source) { yield `test ${event.data.name} failed\n`; break; case 'test:plan': - yield 'test plan'; + yield 'test plan\n'; break; case 'test:diagnostic': case 'test:stderr': @@ -1087,13 +1088,13 @@ module.exports = async function * customReporter(source) { for await (const event of source) { switch (event.type) { case 'test:dequeue': - yield `test ${event.data.name} dequeued`; + yield `test ${event.data.name} dequeued\n`; break; case 'test:enqueue': - yield `test ${event.data.name} enqueued`; + yield `test ${event.data.name} enqueued\n`; break; case 'test:watch:drained': - yield 'test watch queue drained'; + yield 'test watch queue drained\n'; break; case 'test:start': yield `test ${event.data.name} started\n`; @@ -1735,6 +1736,25 @@ added: Resets the implementation of the mock function to its original behavior. The mock can still be used after calling this function. +## Class: `MockModuleContext` + + + +> Stability: 1.0 - Early development + +The `MockModuleContext` class is used to manipulate the behavior of module mocks +created via the [`MockTracker`][] APIs. + +### `ctx.restore()` + + + +Resets the implementation of the mock module. + ## Class: `MockTracker` + +> Stability: 1.0 - Early development + +* `specifier` {string} A string identifying the module to mock. +* `options` {Object} Optional configuration options for the mock module. The + following properties are supported: + * `cache` {boolean} If `false`, each call to `require()` or `import()` + generates a new mock module. If `true`, subsequent calls will return the same + module mock, and the mock module is inserted into the CommonJS cache. + **Default:** false. + * `defaultExport` {any} An optional value used as the mocked module's default + export. If this value is not provided, ESM mocks do not include a default + export. If the mock is a CommonJS or builtin module, this setting is used as + the value of `module.exports`. If this value is not provided, CJS and builtin + mocks use an empty object as the value of `module.exports`. + * `namedExports` {Object} An optional object whose keys and values are used to + create the named exports of the mock module. If the mock is a CommonJS or + builtin module, these values are copied onto `module.exports`. Therefore, if a + mock is created with both named exports and a non-object default export, the + mock will throw an exception when used as a CJS or builtin module. +* Returns: {MockModuleContext} An object that can be used to manipulate the mock. + +This function is used to mock the exports of ECMAScript modules, CommonJS +modules, and Node.js builtin modules. Any references to the original module +prior to mocking are not impacted. The following example demonstrates how a mock +is created for a module. + +```js +test('mocks a builtin module in both module systems', async (t) => { + // Create a mock of 'node:readline' with a named export named 'fn', which + // does not exist in the original 'node:readline' module. + const mock = t.mock.module('node:readline', { + namedExports: { fn() { return 42; } }, + }); + + let esmImpl = await import('node:readline'); + let cjsImpl = require('node:readline'); + + // cursorTo() is an export of the original 'node:readline' module. + assert.strictEqual(esmImpl.cursorTo, undefined); + assert.strictEqual(cjsImpl.cursorTo, undefined); + assert.strictEqual(esmImpl.fn(), 42); + assert.strictEqual(cjsImpl.fn(), 42); + + mock.restore(); + + // The mock is restored, so the original builtin module is returned. + esmImpl = await import('node:readline'); + cjsImpl = require('node:readline'); + + assert.strictEqual(typeof esmImpl.cursorTo, 'function'); + assert.strictEqual(typeof cjsImpl.cursorTo, 'function'); + assert.strictEqual(esmImpl.fn, undefined); + assert.strictEqual(cjsImpl.fn, undefined); +}); +``` + ### `mock.reset()` * `options` {Object} + * `allowPartialTrustChain` {boolean} Treat intermediate (non-self-signed) + certificates in the trust CA certificate list as trusted. * `ca` {string|string\[]|Buffer|Buffer\[]} Optionally override the trusted CA certificates. Default is to trust the well-known CAs curated by Mozilla. Mozilla's CAs are completely replaced when CAs are explicitly specified diff --git a/doc/api/util.md b/doc/api/util.md index 729c27121c0..5db0680265b 100644 --- a/doc/api/util.md +++ b/doc/api/util.md @@ -1798,30 +1798,61 @@ console.log(util.stripVTControlCharacters('\u001B[4mvalue\u001B[0m')); // Prints "value" ``` -## `util.styleText(format, text)` +## `util.styleText(format, text[, options])` > Stability: 1.1 - Active development * `format` {string | Array} A text format or an Array of text formats defined in `util.inspect.colors`. * `text` {string} The text to to be formatted. +* `options` {Object} + * `validateStream` {boolean} When true, `stream` is checked to see if it can handle colors. **Default:** `true`. + * `stream` {Stream} A stream that will be validated if it can be colored. **Default:** `process.stdout`. -This function returns a formatted text considering the `format` passed. +This function returns a formatted text considering the `format` passed +for printing in a terminal. It is aware of the terminal's capabilities +and acts according to the configuration set via `NO_COLORS`, +`NODE_DISABLE_COLORS` and `FORCE_COLOR` environment variables. ```mjs import { styleText } from 'node:util'; -const errorMessage = styleText('red', 'Error! Error!'); -console.log(errorMessage); +import { stderr } from 'node:process'; + +const successMessage = styleText('green', 'Success!'); +console.log(successMessage); + +const errorMessage = styleText( + 'red', + 'Error! Error!', + // Validate if process.stderr has TTY + { stream: stderr }, +); +console.error(successMessage); ``` ```cjs const { styleText } = require('node:util'); -const errorMessage = styleText('red', 'Error! Error!'); -console.log(errorMessage); +const { stderr } = require('node:process'); + +const successMessage = styleText('green', 'Success!'); +console.log(successMessage); + +const errorMessage = styleText( + 'red', + 'Error! Error!', + // Validate if process.stderr has TTY + { stream: stderr }, +); +console.error(successMessage); ``` `util.inspect.colors` also provides text formats such as `italic`, and diff --git a/doc/api/v8.md b/doc/api/v8.md index 3b71e33cd32..bfd475afdda 100644 --- a/doc/api/v8.md +++ b/doc/api/v8.md @@ -198,6 +198,35 @@ Returns an object with the following properties: * `used_global_handles_size` {number} * `external_memory` {number} +`total_heap_size` The value of total\_heap\_size is the number of bytes V8 has +allocated for the heap. This can grow if used\_heap needs more memory. + +`total_heap_size_executable` The value of total\_heap\_size\_executable is the +portion of the heap that can contain executable code, in bytes. This includes +memory used by JIT-compiled code and any memory that must be kept executable. + +`total_physical_size` The value of total\_physical\_size is the actual physical memory +used by the V8 heap, in bytes. This is the amount of memory that is committed +(or in use) rather than reserved. + +`total_available_size` The value of total\_available\_size is the number of +bytes of memory available to the V8 heap. This value represents how much +more memory V8 can use before it exceeds the heap limit. + +`used_heap_size` The value of used\_heap\_size is number of bytes currently +being used by V8’s JavaScript objects. This is the actual memory in use and +does not include memory that has been allocated but not yet used. + +`heap_size_limit` The value of heap\_size\_limit is the maximum size of the V8 +heap, in bytes (either the default limit, determined by system resources, or +the value passed to the `--max_old_space_size` option). + +`malloced_memory` The value of malloced\_memory is the number of bytes allocated +through `malloc` by V8. + +`peak_malloced_memory` The value of peak\_malloced\_memory is the peak number of +bytes allocated through `malloc` by V8 during the lifetime of the process. + `does_zap_garbage` is a 0/1 boolean, which signifies whether the `--zap_code_space` option is enabled or not. This makes V8 overwrite heap garbage with a bit pattern. The RSS footprint (resident set size) gets bigger diff --git a/doc/api/vm.md b/doc/api/vm.md index 07f913e9b14..a82df8a95ac 100644 --- a/doc/api/vm.md +++ b/doc/api/vm.md @@ -228,6 +228,9 @@ overhead. -* `contextObject` {Object} An object that will be [contextified][]. If - `undefined`, a new object will be created. +* `contextObject` {Object|vm.constants.DONT\_CONTEXTIFY|undefined} + Either [`vm.constants.DONT_CONTEXTIFY`][] or an object that will be [contextified][]. + If `undefined`, an empty contextified object will be created for backwards compatibility. * `options` {Object} * `displayErrors` {boolean} When `true`, if an [`Error`][] occurs while compiling the `code`, the line of code causing the error is attached @@ -274,9 +278,16 @@ changes: `breakOnSigint` scopes in that case. * Returns: {any} the result of the very last statement executed in the script. -First contextifies the given `contextObject`, runs the compiled code contained -by the `vm.Script` object within the created context, and returns the result. -Running code does not have access to local scope. +This method is a shortcut to `script.runInContext(vm.createContext(options), options)`. +It does several things at once: + +1. Creates a new context. +2. If `contextObject` is an object, [contextifies][contextified] it with the new context. + If `contextObject` is undefined, creates a new object and [contextifies][contextified] it. + If `contextObject` is [`vm.constants.DONT_CONTEXTIFY`][], don't [contextify][contextified] anything. +3. Runs the compiled code contained by the `vm.Script` object within the created context. The code + does not have access to the scope in which this method is called. +4. Returns the result. The following example compiles code that sets a global variable, then executes the code multiple times in different contexts. The globals are set on and @@ -294,6 +305,12 @@ contexts.forEach((context) => { console.log(contexts); // Prints: [{ globalVar: 'set' }, { globalVar: 'set' }, { globalVar: 'set' }] + +// This would throw if the context is created from a contextified object. +// vm.constants.DONT_CONTEXTIFY allows creating contexts with ordinary +// global objects that can be frozen. +const freezeScript = new vm.Script('Object.freeze(globalThis); globalThis;'); +const frozenContext = freezeScript.runInNewContext(vm.constants.DONT_CONTEXTIFY); ``` ### `script.runInThisContext([options])` @@ -1063,6 +1080,10 @@ For detailed information, see -* `contextObject` {Object} +* `contextObject` {Object|vm.constants.DONT\_CONTEXTIFY|undefined} + Either [`vm.constants.DONT_CONTEXTIFY`][] or an object that will be [contextified][]. + If `undefined`, an empty contextified object will be created for backwards compatibility. * `options` {Object} * `name` {string} Human-readable name of the newly created context. **Default:** `'VM Context i'`, where `i` is an ascending numerical index of @@ -1113,10 +1136,10 @@ changes: [Support of dynamic `import()` in compilation APIs][]. * Returns: {Object} contextified object. -If given a `contextObject`, the `vm.createContext()` method will [prepare that +If the given `contextObject` is an object, the `vm.createContext()` method will [prepare that object][contextified] and return a reference to it so that it can be used in calls to [`vm.runInContext()`][] or [`script.runInContext()`][]. Inside such -scripts, the `contextObject` will be the global object, retaining all of its +scripts, the global object will be wrapped by the `contextObject`, retaining all of its existing properties but also having the built-in objects and functions any standard [global object][] has. Outside of scripts run by the vm module, global variables will remain unchanged. @@ -1141,6 +1164,11 @@ console.log(global.globalVar); If `contextObject` is omitted (or passed explicitly as `undefined`), a new, empty [contextified][] object will be returned. +When the global object in the newly created context is [contextified][], it has some quirks +compared to ordinary global objects. For example, it cannot be frozen. To create a context +without the contextifying quirks, pass [`vm.constants.DONT_CONTEXTIFY`][] as the `contextObject` +argument. See the documentation of [`vm.constants.DONT_CONTEXTIFY`][] for details. + The `vm.createContext()` method is primarily useful for creating a single context that can be used to run multiple scripts. For instance, if emulating a web browser, the method can be used to create a single context representing a @@ -1160,7 +1188,8 @@ added: v0.11.7 * Returns: {boolean} Returns `true` if the given `object` object has been [contextified][] using -[`vm.createContext()`][]. +[`vm.createContext()`][], or if it's the global object of a context created +using [`vm.constants.DONT_CONTEXTIFY`][]. ## `vm.measureMemory([options])` @@ -1320,6 +1349,10 @@ console.log(contextObject); * `code` {string} The JavaScript code to compile and run. -* `contextObject` {Object} An object that will be [contextified][]. If - `undefined`, a new object will be created. +* `contextObject` {Object|vm.constants.DONT\_CONTEXTIFY|undefined} + Either [`vm.constants.DONT_CONTEXTIFY`][] or an object that will be [contextified][]. + If `undefined`, an empty contextified object will be created for backwards compatibility. * `options` {Object|string} * `filename` {string} Specifies the filename used in stack traces produced by this script. **Default:** `'evalmachine.'`. @@ -1394,13 +1428,21 @@ changes: `breakOnSigint` scopes in that case. * Returns: {any} the result of the very last statement executed in the script. -The `vm.runInNewContext()` first contextifies the given `contextObject` (or -creates a new `contextObject` if passed as `undefined`), compiles the `code`, -runs it within the created context, then returns the result. Running code -does not have access to the local scope. - +This method is a shortcut to +`(new vm.Script(code, options)).runInContext(vm.createContext(options), options)`. If `options` is a string, then it specifies the filename. +It does several things at once: + +1. Creates a new context. +2. If `contextObject` is an object, [contextifies][contextified] it with the new context. + If `contextObject` is undefined, creates a new object and [contextifies][contextified] it. + If `contextObject` is [`vm.constants.DONT_CONTEXTIFY`][], don't [contextify][contextified] anything. +3. Compiles the code as a`vm.Script` +4. Runs the compield code within the created context. The code does not have access to the scope in + which this method is called. +5. Returns the result. + The following example compiles and executes code that increments a global variable and sets a new one. These globals are contained in the `contextObject`. @@ -1415,6 +1457,11 @@ const contextObject = { vm.runInNewContext('count += 1; name = "kitty"', contextObject); console.log(contextObject); // Prints: { animal: 'cat', count: 3, name: 'kitty' } + +// This would throw if the context is created from a contextified object. +// vm.constants.DONT_CONTEXTIFY allows creating contexts with ordinary global objects that +// can be frozen. +const frozenContext = vm.runInNewContext('Object.freeze(globalThis); globalThis;', vm.constants.DONT_CONTEXTIFY); ``` ## `vm.runInThisContext(code[, options])` @@ -1541,13 +1588,85 @@ According to the [V8 Embedder's Guide][]: > JavaScript applications to run in a single instance of V8. You must explicitly > specify the context in which you want any JavaScript code to be run. -When the method `vm.createContext()` is called, the `contextObject` argument -(or a newly-created object if `contextObject` is `undefined`) is associated -internally with a new instance of a V8 Context. This V8 Context provides the -`code` run using the `node:vm` module's methods with an isolated global -environment within which it can operate. The process of creating the V8 Context -and associating it with the `contextObject` is what this document refers to as -"contextifying" the object. +When the method `vm.createContext()` is called with an object, the `contextObject` argument +will be used to wrap the global object of a new instance of a V8 Context +(if `contextObject` is `undefined`, a new object will be created from the current context +before its contextified). This V8 Context provides the `code` run using the `node:vm` +module's methods with an isolated global environment within which it can operate. +The process of creating the V8 Context and associating it with the `contextObject` +in the outer context is what this document refers to as "contextifying" the object. + +The contextifying would introduce some quirks to the `globalThis` value in the context. +For example, it cannot be frozen, and it is not reference equal to the `contextObject` +in the outer context. + +```js +const vm = require('node:vm'); + +// An undefined `contextObject` option makes the global object contextified. +const context = vm.createContext(); +console.log(vm.runInContext('globalThis', context) === context); // false +// A contextified global object cannot be frozen. +try { + vm.runInContext('Object.freeze(globalThis);', context); +} catch (e) { + console.log(e); // TypeError: Cannot freeze +} +console.log(vm.runInContext('globalThis.foo = 1; foo;', context)); // 1 +``` + +To create a context with an ordinary global object and get access to a global proxy in +the outer context with fewer quirks, specify `vm.constants.DONT_CONTEXTIFY` as the +`contextObject` argument. + +### `vm.constants.DONT_CONTEXTIFY` + +This constant, when used as the `contextObject` argument in vm APIs, instructs Node.js to create +a context without wrapping its global object with another object in a Node.js-specific manner. +As a result, the `globalThis` value inside the new context would behave more closely to an ordinary +one. + +```js +const vm = require('node:vm'); + +// Use vm.constants.DONT_CONTEXTIFY to freeze the global object. +const context = vm.createContext(vm.constants.DONT_CONTEXTIFY); +vm.runInContext('Object.freeze(globalThis);', context); +try { + vm.runInContext('bar = 1; bar;', context); +} catch (e) { + console.log(e); // Uncaught ReferenceError: bar is not defined +} +``` + +When `vm.constants.DONT_CONTEXTIFY` is used as the `contextObject` argument to [`vm.createContext()`][], +the returned object is a proxy-like object to the global object in the newly created context with +fewer Node.js-specific quirks. It is reference equal to the `globalThis` value in the new context, +can be modified from outside the context, and can be used to access built-ins in the new context directly. + +```js +const vm = require('node:vm'); + +const context = vm.createContext(vm.constants.DONT_CONTEXTIFY); + +// Returned object is reference equal to globalThis in the new context. +console.log(vm.runInContext('globalThis', context) === context); // true + +// Can be used to access globals in the new context directly. +console.log(context.Array); // [Function: Array] +vm.runInContext('foo = 1;', context); +console.log(context.foo); // 1 +context.bar = 1; +console.log(vm.runInContext('bar;', context)); // 1 + +// Can be frozen and it affects the inner context. +Object.freeze(context); +try { + vm.runInContext('baz = 1; baz;', context); +} catch (e) { + console.log(e); // Uncaught ReferenceError: baz is not defined +} +``` ## Timeout interactions with asynchronous tasks and Promises @@ -1837,6 +1956,7 @@ const { Script, SyntheticModule } = require('node:vm'); [`script.runInThisContext()`]: #scriptruninthiscontextoptions [`url.origin`]: url.md#urlorigin [`vm.compileFunction()`]: #vmcompilefunctioncode-params-options +[`vm.constants.DONT_CONTEXTIFY`]: #vmconstantsdont_contextify [`vm.createContext()`]: #vmcreatecontextcontextobject-options [`vm.runInContext()`]: #vmrunincontextcode-contextifiedobject-options [`vm.runInThisContext()`]: #vmruninthiscontextcode-options diff --git a/doc/api/wasi.md b/doc/api/wasi.md index 6c2fcf0efe2..bb1fda39e7c 100644 --- a/doc/api/wasi.md +++ b/doc/api/wasi.md @@ -17,7 +17,7 @@ operating system via a collection of POSIX-like functions. ```mjs import { readFile } from 'node:fs/promises'; -import { WASI } from 'wasi'; +import { WASI } from 'node:wasi'; import { argv, env } from 'node:process'; const wasi = new WASI({ @@ -40,7 +40,7 @@ wasi.start(instance); ```cjs 'use strict'; const { readFile } = require('node:fs/promises'); -const { WASI } = require('wasi'); +const { WASI } = require('node:wasi'); const { argv, env } = require('node:process'); const { join } = require('node:path'); diff --git a/doc/api/webcrypto.md b/doc/api/webcrypto.md index 86aa16b10fe..fa7e248c982 100644 --- a/doc/api/webcrypto.md +++ b/doc/api/webcrypto.md @@ -565,7 +565,7 @@ The algorithms currently supported include: * `'RSA-OAEP'` * `'AES-CTR'` * `'AES-CBC'` -* `'AES-GCM`' +* `'AES-GCM'` ### `subtle.deriveBits(algorithm, baseKey[, length])` @@ -699,7 +699,7 @@ The algorithms currently supported include: * `'RSA-OAEP'` * `'AES-CTR'` * `'AES-CBC'` -* `'AES-GCM`' +* `'AES-GCM'` ### `subtle.exportKey(format, key)` diff --git a/doc/api/worker_threads.md b/doc/api/worker_threads.md index 9a82f9a3097..4f2482e1b82 100644 --- a/doc/api/worker_threads.md +++ b/doc/api/worker_threads.md @@ -1305,7 +1305,7 @@ Node.js event loop. import { Worker, isMainThread, -} from 'worker_threads'; +} from 'node:worker_threads'; if (isMainThread) { new Worker(new URL(import.meta.url)); @@ -1354,8 +1354,8 @@ thread spawned will spawn another until the application crashes. [`'close'` event]: #event-close [`'exit'` event]: #event-exit [`'online'` event]: #event-online -[`--max-old-space-size`]: cli.md#--max-old-space-sizesize-in-megabytes -[`--max-semi-space-size`]: cli.md#--max-semi-space-sizesize-in-megabytes +[`--max-old-space-size`]: cli.md#--max-old-space-sizesize-in-mib +[`--max-semi-space-size`]: cli.md#--max-semi-space-sizesize-in-mib [`ArrayBuffer`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer [`AsyncResource`]: async_hooks.md#class-asyncresource [`Buffer.allocUnsafe()`]: buffer.md#static-method-bufferallocunsafesize diff --git a/doc/changelogs/CHANGELOG_V20.md b/doc/changelogs/CHANGELOG_V20.md index cfa881f9bfe..efe25bfafb4 100644 --- a/doc/changelogs/CHANGELOG_V20.md +++ b/doc/changelogs/CHANGELOG_V20.md @@ -9,6 +9,7 @@ +20.18.0
20.17.0
20.16.0
20.15.1
@@ -64,6 +65,347 @@ * [io.js](CHANGELOG_IOJS.md) * [Archive](CHANGELOG_ARCHIVE.md) + + +## 2024-10-03, Version 20.18.0 'Iron' (LTS), @targos + +### Notable Changes + +### Experimental Network Inspection Support in Node.js + +This update introduces the initial support for network inspection in Node.js. +Currently, this is an experimental feature, so you need to enable it using the `--experimental-network-inspection` flag. +With this feature enabled, you can inspect network activities occurring within a JavaScript application. + +To use network inspection, start your Node.js application with the following command: + +```console +$ node --inspect-wait --experimental-network-inspection index.js +``` + +Please note that the network inspection capabilities are in active development. +We are actively working on enhancing this feature and will continue to expand its functionality in future updates. + +* Network inspection is limited to the `http` and `https` modules only. +* The Network tab in Chrome DevTools will not be available until the + [feature request on the Chrome DevTools side](https://issues.chromium.org/issues/353924015) is addressed. + +Contributed by Kohei Ueno in [#53593](https://github.com/nodejs/node/pull/53593) and [#54246](https://github.com/nodejs/node/pull/54246) + +#### Exposes X509\_V\_FLAG\_PARTIAL\_CHAIN to tls.createSecureContext + +This releases introduces a new option to the API `tls.createSecureContext`. From +now on, `tls.createSecureContext({ allowPartialTrustChain: true })` can be used +to treat intermediate (non-self-signed) certificates in the trust CA certificate +list as trusted. + +Contributed by Anna Henningsen in [#54790](https://github.com/nodejs/node/pull/54790) + +#### New option for vm.createContext() to create a context with a freezable globalThis + +Node.js implements a flavor of `vm.createContext()` and friends that creates a context without contextifying its global +object when vm.constants.DONT\_CONTEXTIFY is used. This is suitable when users want to freeze the context +(impossible when the global is contextified i.e. has interceptors installed) or speed up the global access if they +don't need the interceptor behavior. + +Contributed by Joyee Cheung in [#54394](https://github.com/nodejs/node/pull/54394) + +#### Deprecations + +* \[[`64aa31f6e5`](https://github.com/nodejs/node/commit/64aa31f6e5)] - **repl**: doc-deprecate instantiating `node:repl` classes without `new` (Aviv Keller) [#54842](https://github.com/nodejs/node/pull/54842) +* \[[`4c52ee3d7f`](https://github.com/nodejs/node/commit/4c52ee3d7f)] - **zlib**: deprecate instantiating classes without new (Yagiz Nizipli) [#54708](https://github.com/nodejs/node/pull/54708) + +#### Other Notable Changes + +* \[[`b80da2f964`](https://github.com/nodejs/node/commit/b80da2f964)] - **buffer**: optimize createFromString (Robert Nagy) [#54324](https://github.com/nodejs/node/pull/54324) +* \[[`02b36cbd2d`](https://github.com/nodejs/node/commit/02b36cbd2d)] - **(SEMVER-MINOR)** **lib**: add EventSource Client (Aras Abbasi) [#51575](https://github.com/nodejs/node/pull/51575) +* \[[`879546a9bf`](https://github.com/nodejs/node/commit/879546a9bf)] - **(SEMVER-MINOR)** **src,lib**: add performance.uvMetricsInfo (Rafael Gonzaga) [#54413](https://github.com/nodejs/node/pull/54413) +* \[[`f789f4c92d`](https://github.com/nodejs/node/commit/f789f4c92d)] - **(SEMVER-MINOR)** **test\_runner**: support module mocking (Colin Ihrig) [#52848](https://github.com/nodejs/node/pull/52848) +* \[[`4eb0749b6c`](https://github.com/nodejs/node/commit/4eb0749b6c)] - **(SEMVER-MINOR)** **url**: implement parse method for safer URL parsing (Ali Hassan) [#52280](https://github.com/nodejs/node/pull/52280) + +### Commits + +* \[[`013c48f0e9`](https://github.com/nodejs/node/commit/013c48f0e9)] - **benchmark**: --no-warnings to avoid DEP/ExpWarn log (Rafael Gonzaga) [#54928](https://github.com/nodejs/node/pull/54928) +* \[[`194fc113ac`](https://github.com/nodejs/node/commit/194fc113ac)] - **benchmark**: add buffer.isAscii benchmark (RafaelGSS) [#54740](https://github.com/nodejs/node/pull/54740) +* \[[`7410d51cb9`](https://github.com/nodejs/node/commit/7410d51cb9)] - **benchmark**: add buffer.isUtf8 bench (RafaelGSS) [#54740](https://github.com/nodejs/node/pull/54740) +* \[[`2393f21e8a`](https://github.com/nodejs/node/commit/2393f21e8a)] - **benchmark**: add access async version to bench (Rafael Gonzaga) [#54747](https://github.com/nodejs/node/pull/54747) +* \[[`b8779721f0`](https://github.com/nodejs/node/commit/b8779721f0)] - **benchmark**: enhance dc publish benchmark (Rafael Gonzaga) [#54745](https://github.com/nodejs/node/pull/54745) +* \[[`4078aa83ff`](https://github.com/nodejs/node/commit/4078aa83ff)] - **benchmark**: add match and doesNotMatch bench (RafaelGSS) [#54734](https://github.com/nodejs/node/pull/54734) +* \[[`66acab9976`](https://github.com/nodejs/node/commit/66acab9976)] - **benchmark**: add rejects and doesNotReject bench (RafaelGSS) [#54734](https://github.com/nodejs/node/pull/54734) +* \[[`6db777fb3a`](https://github.com/nodejs/node/commit/6db777fb3a)] - **benchmark**: add throws and doesNotThrow bench (RafaelGSS) [#54734](https://github.com/nodejs/node/pull/54734) +* \[[`8f101560ce`](https://github.com/nodejs/node/commit/8f101560ce)] - **benchmark**: add strictEqual and notStrictEqual bench (RafaelGSS) [#54734](https://github.com/nodejs/node/pull/54734) +* \[[`2c9e4c936e`](https://github.com/nodejs/node/commit/2c9e4c936e)] - **benchmark**: adds groups to better separate benchmarks (Giovanni Bucci) [#54393](https://github.com/nodejs/node/pull/54393) +* \[[`671c3ac633`](https://github.com/nodejs/node/commit/671c3ac633)] - **benchmark**: fix benchmark for file path and URL conversion (Early Riser) [#54190](https://github.com/nodejs/node/pull/54190) +* \[[`8c8708cb5b`](https://github.com/nodejs/node/commit/8c8708cb5b)] - **benchmark**: use assert.ok searchparams (Rafael Gonzaga) [#54334](https://github.com/nodejs/node/pull/54334) +* \[[`8b71fa79e2`](https://github.com/nodejs/node/commit/8b71fa79e2)] - **benchmark**: add stream.compose benchmark (jakecastelli) [#54308](https://github.com/nodejs/node/pull/54308) +* \[[`93ee36e3a0`](https://github.com/nodejs/node/commit/93ee36e3a0)] - **benchmark**: rename count to n (Rafael Gonzaga) [#54271](https://github.com/nodejs/node/pull/54271) +* \[[`f2971b6f0b`](https://github.com/nodejs/node/commit/f2971b6f0b)] - **benchmark**: change assert() to assert.ok() (Rafael Gonzaga) [#54254](https://github.com/nodejs/node/pull/54254) +* \[[`f48f2c212c`](https://github.com/nodejs/node/commit/f48f2c212c)] - **benchmark**: support --help in CLI (Aviv Keller) [#53358](https://github.com/nodejs/node/pull/53358) +* \[[`0309b0520b`](https://github.com/nodejs/node/commit/0309b0520b)] - **benchmark**: remove force option as force defaults to true (Yelim Koo) [#54203](https://github.com/nodejs/node/pull/54203) +* \[[`b6e8305b2d`](https://github.com/nodejs/node/commit/b6e8305b2d)] - **benchmark**: use assert.ok instead of assert (Rafael Gonzaga) [#54176](https://github.com/nodejs/node/pull/54176) +* \[[`90c660d26a`](https://github.com/nodejs/node/commit/90c660d26a)] - **benchmark**: add require-esm benchmark (Joyee Cheung) [#52166](https://github.com/nodejs/node/pull/52166) +* \[[`1b8584b52e`](https://github.com/nodejs/node/commit/1b8584b52e)] - **benchmark,doc**: add CPU scaling governor to perf (Rafael Gonzaga) [#54723](https://github.com/nodejs/node/pull/54723) +* \[[`0b9161b330`](https://github.com/nodejs/node/commit/0b9161b330)] - **benchmark,doc**: mention bar.R to the list of scripts (Rafael Gonzaga) [#54722](https://github.com/nodejs/node/pull/54722) +* \[[`84bf93b7ea`](https://github.com/nodejs/node/commit/84bf93b7ea)] - **buffer**: allow invalid encoding in from (Robert Nagy) [#54533](https://github.com/nodejs/node/pull/54533) +* \[[`d04246a0d7`](https://github.com/nodejs/node/commit/d04246a0d7)] - **buffer**: optimize byteLength for common encodings (Robert Nagy) [#54342](https://github.com/nodejs/node/pull/54342) +* \[[`f36831f694`](https://github.com/nodejs/node/commit/f36831f694)] - **buffer**: optimize createFromString (Robert Nagy) [#54324](https://github.com/nodejs/node/pull/54324) +* \[[`f5f40c8088`](https://github.com/nodejs/node/commit/f5f40c8088)] - **buffer**: optimize for common encodings (Robert Nagy) [#54319](https://github.com/nodejs/node/pull/54319) +* \[[`76c37703be`](https://github.com/nodejs/node/commit/76c37703be)] - **buffer**: add JSDoc to blob bytes method (Roberto Simonini) [#54117](https://github.com/nodejs/node/pull/54117) +* \[[`3012d31404`](https://github.com/nodejs/node/commit/3012d31404)] - **buffer**: use faster integer argument check (Robert Nagy) [#54089](https://github.com/nodejs/node/pull/54089) +* \[[`3505782801`](https://github.com/nodejs/node/commit/3505782801)] - **buffer**: make indexOf(byte) faster (Tobias Nießen) [#53455](https://github.com/nodejs/node/pull/53455) +* \[[`d285fc1f68`](https://github.com/nodejs/node/commit/d285fc1f68)] - **build**: upgrade clang-format to v18 (Aviv Keller) [#53957](https://github.com/nodejs/node/pull/53957) +* \[[`d288ec3b0a`](https://github.com/nodejs/node/commit/d288ec3b0a)] - **build**: fix conflicting V8 object print flags (Daeyeon Jeong) [#54785](https://github.com/nodejs/node/pull/54785) +* \[[`e862eecac9`](https://github.com/nodejs/node/commit/e862eecac9)] - **build**: do not build with code cache for core coverage collection (Joyee Cheung) [#54633](https://github.com/nodejs/node/pull/54633) +* \[[`f7a606eb96`](https://github.com/nodejs/node/commit/f7a606eb96)] - **build**: turn off `-Wrestrict` (Richard Lau) [#54737](https://github.com/nodejs/node/pull/54737) +* \[[`71ca2665e4`](https://github.com/nodejs/node/commit/71ca2665e4)] - **build**: reclaim disk space on macOS GHA runner (jakecastelli) [#54658](https://github.com/nodejs/node/pull/54658) +* \[[`82d8051c39`](https://github.com/nodejs/node/commit/82d8051c39)] - **build**: don't clean obj.target directory if it doesn't exist (Joyee Cheung) [#54337](https://github.com/nodejs/node/pull/54337) +* \[[`6e550b1f26`](https://github.com/nodejs/node/commit/6e550b1f26)] - **build**: update `ruff` to `0.5.2` (Aviv Keller) [#53909](https://github.com/nodejs/node/pull/53909) +* \[[`e2ea7b26d7`](https://github.com/nodejs/node/commit/e2ea7b26d7)] - **build**: fix ./configure --help format error (Zhenwei Jin) [#53066](https://github.com/nodejs/node/pull/53066) +* \[[`eb2402d569`](https://github.com/nodejs/node/commit/eb2402d569)] - **build**: enable building with shared uvwasi lib (Pooja D P) [#43987](https://github.com/nodejs/node/pull/43987) +* \[[`45732314d4`](https://github.com/nodejs/node/commit/45732314d4)] - **build**: sync V8 warning cflags with BUILD.gn (Michaël Zasso) [#52873](https://github.com/nodejs/node/pull/52873) +* \[[`6e0a2bb54c`](https://github.com/nodejs/node/commit/6e0a2bb54c)] - **build**: harmonize Clang checks (Michaël Zasso) [#52873](https://github.com/nodejs/node/pull/52873) +* \[[`3f78d4eb28`](https://github.com/nodejs/node/commit/3f78d4eb28)] - **cli**: add `--expose-gc` flag available to `NODE_OPTIONS` (Juan José) [#53078](https://github.com/nodejs/node/pull/53078) +* \[[`a110409b2a`](https://github.com/nodejs/node/commit/a110409b2a)] - **console**: use validateOneOf for colorMode validation (HEESEUNG) [#54245](https://github.com/nodejs/node/pull/54245) +* \[[`231ab788ea`](https://github.com/nodejs/node/commit/231ab788ea)] - **crypto**: reject dh,x25519,x448 in {Sign,Verify}Final (Huáng Jùnliàng) [#53774](https://github.com/nodejs/node/pull/53774) +* \[[`a5984e4570`](https://github.com/nodejs/node/commit/a5984e4570)] - **crypto**: return a clearer error when loading an unsupported pkcs12 (Tim Perry) [#54485](https://github.com/nodejs/node/pull/54485) +* \[[`f287cd77bd`](https://github.com/nodejs/node/commit/f287cd77bd)] - **crypto**: remove unused `kHashTypes` internal (Antoine du Hamel) [#54627](https://github.com/nodejs/node/pull/54627) +* \[[`1fc904f8c4`](https://github.com/nodejs/node/commit/1fc904f8c4)] - **deps**: update cjs-module-lexer to 1.4.1 (Node.js GitHub Bot) [#54846](https://github.com/nodejs/node/pull/54846) +* \[[`95b55c39b1`](https://github.com/nodejs/node/commit/95b55c39b1)] - **deps**: update simdutf to 5.5.0 (Node.js GitHub Bot) [#54434](https://github.com/nodejs/node/pull/54434) +* \[[`cf6ded5dd3`](https://github.com/nodejs/node/commit/cf6ded5dd3)] - **deps**: update cjs-module-lexer to 1.4.0 (Node.js GitHub Bot) [#54713](https://github.com/nodejs/node/pull/54713) +* \[[`7f8edce3f1`](https://github.com/nodejs/node/commit/7f8edce3f1)] - **deps**: update c-ares to v1.33.1 (Node.js GitHub Bot) [#54549](https://github.com/nodejs/node/pull/54549) +* \[[`9a4a7b7ecc`](https://github.com/nodejs/node/commit/9a4a7b7ecc)] - **deps**: update undici to 6.19.8 (Node.js GitHub Bot) [#54456](https://github.com/nodejs/node/pull/54456) +* \[[`87ca1d7fee`](https://github.com/nodejs/node/commit/87ca1d7fee)] - **deps**: update simdutf to 5.3.4 (Node.js GitHub Bot) [#54312](https://github.com/nodejs/node/pull/54312) +* \[[`d3a743f182`](https://github.com/nodejs/node/commit/d3a743f182)] - **deps**: update zlib to 1.3.0.1-motley-71660e1 (Node.js GitHub Bot) [#53464](https://github.com/nodejs/node/pull/53464) +* \[[`926981aa9f`](https://github.com/nodejs/node/commit/926981aa9f)] - **deps**: update zlib to 1.3.0.1-motley-c2469fd (Node.js GitHub Bot) [#53464](https://github.com/nodejs/node/pull/53464) +* \[[`654c8d1fdc`](https://github.com/nodejs/node/commit/654c8d1fdc)] - **deps**: update zlib to 1.3.0.1-motley-68e57e6 (Node.js GitHub Bot) [#53464](https://github.com/nodejs/node/pull/53464) +* \[[`2477e79172`](https://github.com/nodejs/node/commit/2477e79172)] - **deps**: update zlib to 1.3.0.1-motley-8b7eff8 (Node.js GitHub Bot) [#53464](https://github.com/nodejs/node/pull/53464) +* \[[`3d8113faf5`](https://github.com/nodejs/node/commit/3d8113faf5)] - **deps**: update zlib to 1.3.0.1-motley-e432200 (Node.js GitHub Bot) [#53464](https://github.com/nodejs/node/pull/53464) +* \[[`ac294e3db4`](https://github.com/nodejs/node/commit/ac294e3db4)] - **deps**: update zlib to 1.3.0.1-motley-887bb57 (Node.js GitHub Bot) [#53464](https://github.com/nodejs/node/pull/53464) +* \[[`239588b968`](https://github.com/nodejs/node/commit/239588b968)] - **deps**: update c-ares to v1.33.0 (Node.js GitHub Bot) [#54198](https://github.com/nodejs/node/pull/54198) +* \[[`6e7de37ed3`](https://github.com/nodejs/node/commit/6e7de37ed3)] - **deps**: update undici to 6.19.7 (Node.js GitHub Bot) [#54286](https://github.com/nodejs/node/pull/54286) +* \[[`38aa9d6ea9`](https://github.com/nodejs/node/commit/38aa9d6ea9)] - **deps**: update acorn to 8.12.1 (Node.js GitHub Bot) [#53465](https://github.com/nodejs/node/pull/53465) +* \[[`d30145f663`](https://github.com/nodejs/node/commit/d30145f663)] - **deps**: update undici to 6.19.5 (Node.js GitHub Bot) [#54076](https://github.com/nodejs/node/pull/54076) +* \[[`c169d9c12b`](https://github.com/nodejs/node/commit/c169d9c12b)] - **deps**: update simdutf to 5.3.1 (Node.js GitHub Bot) [#54196](https://github.com/nodejs/node/pull/54196) +* \[[`92f3447957`](https://github.com/nodejs/node/commit/92f3447957)] - **doc**: add missing EventSource docs to globals (Matthew Aitken) [#55022](https://github.com/nodejs/node/pull/55022) +* \[[`2879ce9681`](https://github.com/nodejs/node/commit/2879ce9681)] - **doc**: fix broken Android building link (Niklas Wenzel) [#54922](https://github.com/nodejs/node/pull/54922) +* \[[`096623b59a`](https://github.com/nodejs/node/commit/096623b59a)] - **doc**: add support link for aduh95 (Antoine du Hamel) [#54866](https://github.com/nodejs/node/pull/54866) +* \[[`1dfd238781`](https://github.com/nodejs/node/commit/1dfd238781)] - **doc**: run license-builder (github-actions\[bot]) [#54854](https://github.com/nodejs/node/pull/54854) +* \[[`a6c748fffb`](https://github.com/nodejs/node/commit/a6c748fffb)] - **doc**: experimental flag for global accessible APIs (Chengzhong Wu) [#54330](https://github.com/nodejs/node/pull/54330) +* \[[`d48a22fa14`](https://github.com/nodejs/node/commit/d48a22fa14)] - **doc**: add `ERR_INVALID_ADDRESS` to `errors.md` (Aviv Keller) [#54661](https://github.com/nodejs/node/pull/54661) +* \[[`4a840cecfa`](https://github.com/nodejs/node/commit/4a840cecfa)] - **doc**: add support link for mcollina (Matteo Collina) [#54786](https://github.com/nodejs/node/pull/54786) +* \[[`ec22d86512`](https://github.com/nodejs/node/commit/ec22d86512)] - **doc**: mark `--conditions` CLI flag as stable (Guy Bedford) [#54209](https://github.com/nodejs/node/pull/54209) +* \[[`77c702ca07`](https://github.com/nodejs/node/commit/77c702ca07)] - **doc**: fix typo in recognizing-contributors (Tobias Nießen) [#54822](https://github.com/nodejs/node/pull/54822) +* \[[`62953ef9fb`](https://github.com/nodejs/node/commit/62953ef9fb)] - **doc**: clarify `--max-old-space-size` and `--max-semi-space-size` units (Alexandre ABRIOUX) [#54477](https://github.com/nodejs/node/pull/54477) +* \[[`e2bab0f2b2`](https://github.com/nodejs/node/commit/e2bab0f2b2)] - **doc**: replace --allow-fs-read by --allow-fs-write in related section (M1CK431) [#54427](https://github.com/nodejs/node/pull/54427) +* \[[`9cbfd5b33a`](https://github.com/nodejs/node/commit/9cbfd5b33a)] - **doc**: add support link for marco-ippolito (Marco Ippolito) [#54789](https://github.com/nodejs/node/pull/54789) +* \[[`53167b29ef`](https://github.com/nodejs/node/commit/53167b29ef)] - **doc**: fix typo (Michael Dawson) [#54640](https://github.com/nodejs/node/pull/54640) +* \[[`87f78a35f7`](https://github.com/nodejs/node/commit/87f78a35f7)] - **doc**: fix webcrypto.md AES-GCM backticks (Filip Skokan) [#54621](https://github.com/nodejs/node/pull/54621) +* \[[`7c83c15221`](https://github.com/nodejs/node/commit/7c83c15221)] - **doc**: add documentation about os.tmpdir() overrides (Joyee Cheung) [#54613](https://github.com/nodejs/node/pull/54613) +* \[[`4bfd832d70`](https://github.com/nodejs/node/commit/4bfd832d70)] - **doc**: add support me link for anonrig (Yagiz Nizipli) [#54611](https://github.com/nodejs/node/pull/54611) +* \[[`22a103e5ec`](https://github.com/nodejs/node/commit/22a103e5ec)] - **doc**: add alert on REPL from TCP socket (Rafael Gonzaga) [#54594](https://github.com/nodejs/node/pull/54594) +* \[[`b6374c24e1`](https://github.com/nodejs/node/commit/b6374c24e1)] - **doc**: fix typo in styleText description (Rafael Gonzaga) [#54616](https://github.com/nodejs/node/pull/54616) +* \[[`2f5b98ee1f`](https://github.com/nodejs/node/commit/2f5b98ee1f)] - **doc**: add getHeapStatistics() property descriptions (Benji Marinacci) [#54584](https://github.com/nodejs/node/pull/54584) +* \[[`482302b99b`](https://github.com/nodejs/node/commit/482302b99b)] - **doc**: fix information about including coverage files (Aviv Keller) [#54527](https://github.com/nodejs/node/pull/54527) +* \[[`b3708e7df4`](https://github.com/nodejs/node/commit/b3708e7df4)] - **doc**: support collaborators - talk amplification (Michael Dawson) [#54508](https://github.com/nodejs/node/pull/54508) +* \[[`c86fe23012`](https://github.com/nodejs/node/commit/c86fe23012)] - **doc**: add note about shasum generation failure (Marco Ippolito) [#54487](https://github.com/nodejs/node/pull/54487) +* \[[`d53e6cf755`](https://github.com/nodejs/node/commit/d53e6cf755)] - **doc**: fix capitalization in module.md (shallow-beach) [#54488](https://github.com/nodejs/node/pull/54488) +* \[[`cdc6713f18`](https://github.com/nodejs/node/commit/cdc6713f18)] - **doc**: add esm examples to node:https (Alfredo González) [#54399](https://github.com/nodejs/node/pull/54399) +* \[[`1ac1fe4e65`](https://github.com/nodejs/node/commit/1ac1fe4e65)] - **doc**: fix error description of the max header size (Egawa Ryo) [#54125](https://github.com/nodejs/node/pull/54125) +* \[[`244542b720`](https://github.com/nodejs/node/commit/244542b720)] - **doc**: add git node security --cleanup (Rafael Gonzaga) [#54381](https://github.com/nodejs/node/pull/54381) +* \[[`69fb71f54c`](https://github.com/nodejs/node/commit/69fb71f54c)] - **doc**: add note on weakness of permission model (Tobias Nießen) [#54268](https://github.com/nodejs/node/pull/54268) +* \[[`83b2cb908b`](https://github.com/nodejs/node/commit/83b2cb908b)] - **doc**: add versions when `--watch-preserve-output` was added (Théo LUDWIG) [#54328](https://github.com/nodejs/node/pull/54328) +* \[[`460fb49483`](https://github.com/nodejs/node/commit/460fb49483)] - **doc**: replace v19 mention in Current release (Rafael Gonzaga) [#54361](https://github.com/nodejs/node/pull/54361) +* \[[`994b46a160`](https://github.com/nodejs/node/commit/994b46a160)] - **doc**: correct peformance entry types (Jason Zhang) [#54263](https://github.com/nodejs/node/pull/54263) +* \[[`f142e668cb`](https://github.com/nodejs/node/commit/f142e668cb)] - **doc**: fix typo in method name in the sea doc (Eliyah Sundström) [#54027](https://github.com/nodejs/node/pull/54027) +* \[[`9529a30dba`](https://github.com/nodejs/node/commit/9529a30dba)] - **doc**: mark process.nextTick legacy (Marco Ippolito) [#51280](https://github.com/nodejs/node/pull/51280) +* \[[`7e25fabb91`](https://github.com/nodejs/node/commit/7e25fabb91)] - **doc**: add esm examples to node:http2 (Alfredo González) [#54292](https://github.com/nodejs/node/pull/54292) +* \[[`6a4f05e384`](https://github.com/nodejs/node/commit/6a4f05e384)] - **doc**: explicitly mention node:fs module restriction (Rafael Gonzaga) [#54269](https://github.com/nodejs/node/pull/54269) +* \[[`53f5c54997`](https://github.com/nodejs/node/commit/53f5c54997)] - **doc**: warn for windows build bug (Jason Zhang) [#54217](https://github.com/nodejs/node/pull/54217) +* \[[`07bde054f3`](https://github.com/nodejs/node/commit/07bde054f3)] - **doc**: make some parameters optional in `tracingChannel.traceCallback` (Deokjin Kim) [#54068](https://github.com/nodejs/node/pull/54068) +* \[[`62bf03b5f1`](https://github.com/nodejs/node/commit/62bf03b5f1)] - **doc**: add esm examples to node:dns (Alfredo González) [#54172](https://github.com/nodejs/node/pull/54172) +* \[[`fb2b19184b`](https://github.com/nodejs/node/commit/fb2b19184b)] - **doc**: add KevinEady as a triager (Chengzhong Wu) [#54179](https://github.com/nodejs/node/pull/54179) +* \[[`24976bfba0`](https://github.com/nodejs/node/commit/24976bfba0)] - **doc**: add esm examples to node:console (Alfredo González) [#54108](https://github.com/nodejs/node/pull/54108) +* \[[`4e7edc40f7`](https://github.com/nodejs/node/commit/4e7edc40f7)] - **doc**: fix sea assets example (Sadzurami) [#54192](https://github.com/nodejs/node/pull/54192) +* \[[`322b5d91e1`](https://github.com/nodejs/node/commit/322b5d91e1)] - **doc**: add links to security steward companies (Aviv Keller) [#52981](https://github.com/nodejs/node/pull/52981) +* \[[`6ab271510e`](https://github.com/nodejs/node/commit/6ab271510e)] - **doc**: move `onread` option from `socket.connect()` to `new net.socket()` (sendoru) [#54194](https://github.com/nodejs/node/pull/54194) +* \[[`39c30ea08f`](https://github.com/nodejs/node/commit/39c30ea08f)] - **doc**: move release key for Myles Borins (Richard Lau) [#54059](https://github.com/nodejs/node/pull/54059) +* \[[`e9fc54804a`](https://github.com/nodejs/node/commit/e9fc54804a)] - **doc**: refresh instructions for building node from source (Liran Tal) [#53768](https://github.com/nodejs/node/pull/53768) +* \[[`f131dc625a`](https://github.com/nodejs/node/commit/f131dc625a)] - **doc**: add documentation for blob.bytes() method (jaexxin) [#54114](https://github.com/nodejs/node/pull/54114) +* \[[`8d41bb900b`](https://github.com/nodejs/node/commit/8d41bb900b)] - **doc**: add missing new lines to custom test reporter examples (Eddie Abbondanzio) [#54152](https://github.com/nodejs/node/pull/54152) +* \[[`2acaeaba77`](https://github.com/nodejs/node/commit/2acaeaba77)] - **doc**: update list of Triagers on the `README.md` (Antoine du Hamel) [#54138](https://github.com/nodejs/node/pull/54138) +* \[[`fff8eb2792`](https://github.com/nodejs/node/commit/fff8eb2792)] - **doc**: expand troubleshooting section (Liran Tal) [#53808](https://github.com/nodejs/node/pull/53808) +* \[[`402121520f`](https://github.com/nodejs/node/commit/402121520f)] - **doc**: clarify `useCodeCache` setting for cross-platform SEA generation (Yelim Koo) [#53994](https://github.com/nodejs/node/pull/53994) +* \[[`272484b8b2`](https://github.com/nodejs/node/commit/272484b8b2)] - **doc**: test for cli options (Aras Abbasi) [#51623](https://github.com/nodejs/node/pull/51623) +* \[[`c4d0ca4710`](https://github.com/nodejs/node/commit/c4d0ca4710)] - **doc, build**: fixup build docs (Aviv Keller) [#54899](https://github.com/nodejs/node/pull/54899) +* \[[`2e3e17748b`](https://github.com/nodejs/node/commit/2e3e17748b)] - **doc, child\_process**: add esm snippets (Aviv Keller) [#53616](https://github.com/nodejs/node/pull/53616) +* \[[`c40b4b4f27`](https://github.com/nodejs/node/commit/c40b4b4f27)] - **doc, meta**: fix broken link in `onboarding.md` (Aviv Keller) [#54886](https://github.com/nodejs/node/pull/54886) +* \[[`beff587b94`](https://github.com/nodejs/node/commit/beff587b94)] - **doc, meta**: add missing `,` to `BUILDING.md` (Aviv Keller) [#54409](https://github.com/nodejs/node/pull/54409) +* \[[`c114585430`](https://github.com/nodejs/node/commit/c114585430)] - **doc, meta**: replace command with link to keys (Aviv Keller) [#53745](https://github.com/nodejs/node/pull/53745) +* \[[`0843077a99`](https://github.com/nodejs/node/commit/0843077a99)] - **doc, test**: simplify test README table (Aviv Keller) [#53971](https://github.com/nodejs/node/pull/53971) +* \[[`2df7bc0e32`](https://github.com/nodejs/node/commit/2df7bc0e32)] - **doc,tools**: enforce use of `node:` prefix (Antoine du Hamel) [#53950](https://github.com/nodejs/node/pull/53950) +* \[[`0dd4639391`](https://github.com/nodejs/node/commit/0dd4639391)] - **esm**: fix support for `URL` instances in `import.meta.resolve` (Antoine du Hamel) [#54690](https://github.com/nodejs/node/pull/54690) +* \[[`f0c55e206d`](https://github.com/nodejs/node/commit/f0c55e206d)] - **fs**: refactor rimraf to avoid using primordials (Yagiz Nizipli) [#54834](https://github.com/nodejs/node/pull/54834) +* \[[`f568384bbd`](https://github.com/nodejs/node/commit/f568384bbd)] - **fs**: refactor handleTimestampsAndMode to remove redundant call (HEESEUNG) [#54369](https://github.com/nodejs/node/pull/54369) +* \[[`2fb7cc9715`](https://github.com/nodejs/node/commit/2fb7cc9715)] - **fs**: fix typings (Yagiz Nizipli) [#53626](https://github.com/nodejs/node/pull/53626) +* \[[`596940cfa0`](https://github.com/nodejs/node/commit/596940cfa0)] - **http**: reduce likelihood of race conditions on keep-alive timeout (jazelly) [#54863](https://github.com/nodejs/node/pull/54863) +* \[[`6e13a7ba02`](https://github.com/nodejs/node/commit/6e13a7ba02)] - **http**: remove prototype primordials (Antoine du Hamel) [#53698](https://github.com/nodejs/node/pull/53698) +* \[[`99f96eb3f7`](https://github.com/nodejs/node/commit/99f96eb3f7)] - **http2**: remove prototype primordials (Antoine du Hamel) [#53696](https://github.com/nodejs/node/pull/53696) +* \[[`41f5eacc1a`](https://github.com/nodejs/node/commit/41f5eacc1a)] - **https**: only use default ALPNProtocols when appropriate (Brian White) [#54411](https://github.com/nodejs/node/pull/54411) +* \[[`59a39520e1`](https://github.com/nodejs/node/commit/59a39520e1)] - **(SEMVER-MINOR)** **inspector**: support `Network.loadingFailed` event (Kohei Ueno) [#54246](https://github.com/nodejs/node/pull/54246) +* \[[`d1007fb1a9`](https://github.com/nodejs/node/commit/d1007fb1a9)] - **inspector**: provide detailed info to fix DevTools frontend errors (Kohei Ueno) [#54156](https://github.com/nodejs/node/pull/54156) +* \[[`3b93507949`](https://github.com/nodejs/node/commit/3b93507949)] - **(SEMVER-MINOR)** **inspector**: add initial support for network inspection (Kohei Ueno) [#53593](https://github.com/nodejs/node/pull/53593) +* \[[`fc37b801c8`](https://github.com/nodejs/node/commit/fc37b801c8)] - **lib**: remove unnecessary async (jakecastelli) [#54829](https://github.com/nodejs/node/pull/54829) +* \[[`d86f24787b`](https://github.com/nodejs/node/commit/d86f24787b)] - **lib**: make WeakRef safe in abort\_controller (jazelly) [#54791](https://github.com/nodejs/node/pull/54791) +* \[[`77c59224e5`](https://github.com/nodejs/node/commit/77c59224e5)] - **lib**: add note about removing `node:sys` module (Rafael Gonzaga) [#54743](https://github.com/nodejs/node/pull/54743) +* \[[`b8c06dce02`](https://github.com/nodejs/node/commit/b8c06dce02)] - **lib**: ensure no holey array in fixed\_queue (Jason Zhang) [#54537](https://github.com/nodejs/node/pull/54537) +* \[[`b85c8ce1fc`](https://github.com/nodejs/node/commit/b85c8ce1fc)] - **lib**: refactor SubtleCrypto experimental warnings (Filip Skokan) [#54620](https://github.com/nodejs/node/pull/54620) +* \[[`e84812c1b5`](https://github.com/nodejs/node/commit/e84812c1b5)] - **lib**: respect terminal capabilities on styleText (Rafael Gonzaga) [#54389](https://github.com/nodejs/node/pull/54389) +* \[[`c004abaf17`](https://github.com/nodejs/node/commit/c004abaf17)] - **lib**: replace spread operator with primordials function (YoonSoo\_Shin) [#54053](https://github.com/nodejs/node/pull/54053) +* \[[`b79aeabc4d`](https://github.com/nodejs/node/commit/b79aeabc4d)] - **lib**: avoid for of loop and remove unnecessary variable in zlib (YoonSoo\_Shin) [#54258](https://github.com/nodejs/node/pull/54258) +* \[[`f4085363c6`](https://github.com/nodejs/node/commit/f4085363c6)] - **lib**: fix unhandled errors in webstream adapters (Fedor Indutny) [#54206](https://github.com/nodejs/node/pull/54206) +* \[[`1ad857e748`](https://github.com/nodejs/node/commit/1ad857e748)] - **lib**: fix typos in comments within internal/streams (YoonSoo\_Shin) [#54093](https://github.com/nodejs/node/pull/54093) +* \[[`02b36cbd2d`](https://github.com/nodejs/node/commit/02b36cbd2d)] - **(SEMVER-MINOR)** **lib**: add EventSource Client (Aras Abbasi) [#51575](https://github.com/nodejs/node/pull/51575) +* \[[`afbf2c0530`](https://github.com/nodejs/node/commit/afbf2c0530)] - **lib,permission**: support Buffer to permission.has (Rafael Gonzaga) [#54104](https://github.com/nodejs/node/pull/54104) +* \[[`54af47395d`](https://github.com/nodejs/node/commit/54af47395d)] - **meta**: bump peter-evans/create-pull-request from 6.1.0 to 7.0.1 (dependabot\[bot]) [#54820](https://github.com/nodejs/node/pull/54820) +* \[[`a0c10f2ed9`](https://github.com/nodejs/node/commit/a0c10f2ed9)] - **meta**: add `Windows ARM64` to flaky-tests list (Aviv Keller) [#54693](https://github.com/nodejs/node/pull/54693) +* \[[`27b06880e1`](https://github.com/nodejs/node/commit/27b06880e1)] - **meta**: bump actions/setup-python from 5.1.1 to 5.2.0 (Rich Trott) [#54691](https://github.com/nodejs/node/pull/54691) +* \[[`8747af1037`](https://github.com/nodejs/node/commit/8747af1037)] - **meta**: update sccache to v0.8.1 (Aviv Keller) [#54720](https://github.com/nodejs/node/pull/54720) +* \[[`3f753d87a6`](https://github.com/nodejs/node/commit/3f753d87a6)] - **meta**: bump step-security/harden-runner from 2.9.0 to 2.9.1 (dependabot\[bot]) [#54704](https://github.com/nodejs/node/pull/54704) +* \[[`6f103ae25d`](https://github.com/nodejs/node/commit/6f103ae25d)] - **meta**: bump actions/upload-artifact from 4.3.4 to 4.4.0 (dependabot\[bot]) [#54703](https://github.com/nodejs/node/pull/54703) +* \[[`3e6a9bb04e`](https://github.com/nodejs/node/commit/3e6a9bb04e)] - **meta**: bump github/codeql-action from 3.25.15 to 3.26.6 (dependabot\[bot]) [#54702](https://github.com/nodejs/node/pull/54702) +* \[[`c666ebc4e4`](https://github.com/nodejs/node/commit/c666ebc4e4)] - **meta**: fix links in `SECURITY.md` (Aviv Keller) [#54696](https://github.com/nodejs/node/pull/54696) +* \[[`4d361b3bed`](https://github.com/nodejs/node/commit/4d361b3bed)] - **meta**: fix `contributing` codeowners (Aviv Keller) [#54641](https://github.com/nodejs/node/pull/54641) +* \[[`36931aa183`](https://github.com/nodejs/node/commit/36931aa183)] - **meta**: remind users to use a supported version in bug reports (Aviv Keller) [#54481](https://github.com/nodejs/node/pull/54481) +* \[[`cf283d9ca7`](https://github.com/nodejs/node/commit/cf283d9ca7)] - **meta**: run coverage-windows when `vcbuild.bat` updated (Aviv Keller) [#54412](https://github.com/nodejs/node/pull/54412) +* \[[`67ca397c9f`](https://github.com/nodejs/node/commit/67ca397c9f)] - **meta**: add test-permission-\* CODEOWNERS (Rafael Gonzaga) [#54267](https://github.com/nodejs/node/pull/54267) +* \[[`b61a2f5b79`](https://github.com/nodejs/node/commit/b61a2f5b79)] - **meta**: move one or more collaborators to emeritus (Node.js GitHub Bot) [#54210](https://github.com/nodejs/node/pull/54210) +* \[[`dd8ab83667`](https://github.com/nodejs/node/commit/dd8ab83667)] - **meta**: add module label for the lib/internal/modules folder (Aviv Keller) [#52858](https://github.com/nodejs/node/pull/52858) +* \[[`db78978d17`](https://github.com/nodejs/node/commit/db78978d17)] - **meta**: bump `actions/upload-artifact` from 4.3.3 to 4.3.4 (dependabot\[bot]) [#54166](https://github.com/nodejs/node/pull/54166) +* \[[`ca808dd9e5`](https://github.com/nodejs/node/commit/ca808dd9e5)] - **meta**: bump `actions/download-artifact` from 4.1.7 to 4.1.8 (dependabot\[bot]) [#54167](https://github.com/nodejs/node/pull/54167) +* \[[`a35d980146`](https://github.com/nodejs/node/commit/a35d980146)] - **meta**: bump actions/setup-python from 5.1.0 to 5.1.1 (dependabot\[bot]) [#54165](https://github.com/nodejs/node/pull/54165) +* \[[`3a103c3a17`](https://github.com/nodejs/node/commit/3a103c3a17)] - **meta**: bump `step-security/harden-runner` from 2.8.1 to 2.9.0 (dependabot\[bot]) [#54169](https://github.com/nodejs/node/pull/54169) +* \[[`775ebbe0e8`](https://github.com/nodejs/node/commit/775ebbe0e8)] - **meta**: bump `actions/setup-node` from 4.0.2 to 4.0.3 (dependabot\[bot]) [#54170](https://github.com/nodejs/node/pull/54170) +* \[[`7d5dd6f1d1`](https://github.com/nodejs/node/commit/7d5dd6f1d1)] - **meta**: bump `github/codeql-action` from 3.25.11 to 3.25.15 (dependabot\[bot]) [#54168](https://github.com/nodejs/node/pull/54168) +* \[[`80dd38dde3`](https://github.com/nodejs/node/commit/80dd38dde3)] - **meta**: bump `ossf/scorecard-action` from 2.3.3 to 2.4.0 (dependabot\[bot]) [#54171](https://github.com/nodejs/node/pull/54171) +* \[[`90b632ee02`](https://github.com/nodejs/node/commit/90b632ee02)] - **module**: warn on detection in typeless package (Geoffrey Booth) [#52168](https://github.com/nodejs/node/pull/52168) +* \[[`3011927aab`](https://github.com/nodejs/node/commit/3011927aab)] - **node-api**: add external buffer creation benchmark (Chengzhong Wu) [#54877](https://github.com/nodejs/node/pull/54877) +* \[[`7611093e11`](https://github.com/nodejs/node/commit/7611093e11)] - **node-api**: add support for UTF-8 and Latin-1 property keys (Mert Can Altin) [#52984](https://github.com/nodejs/node/pull/52984) +* \[[`d65a8f377c`](https://github.com/nodejs/node/commit/d65a8f377c)] - **node-api**: remove RefBase and CallbackWrapper (Vladimir Morozov) [#53590](https://github.com/nodejs/node/pull/53590) +* \[[`309cb1cbd2`](https://github.com/nodejs/node/commit/309cb1cbd2)] - **path**: remove `StringPrototypeCharCodeAt` from `posix.extname` (Aviv Keller) [#54546](https://github.com/nodejs/node/pull/54546) +* \[[`2859b4ba9a`](https://github.com/nodejs/node/commit/2859b4ba9a)] - **path**: change `posix.join` to use array (Wiyeong Seo) [#54331](https://github.com/nodejs/node/pull/54331) +* \[[`c61cee2138`](https://github.com/nodejs/node/commit/c61cee2138)] - **path**: fix relative on Windows (Hüseyin Açacak) [#53991](https://github.com/nodejs/node/pull/53991) +* \[[`329be5cc35`](https://github.com/nodejs/node/commit/329be5cc35)] - **path**: use the correct name in `validateString` (Benjamin Pasero) [#53669](https://github.com/nodejs/node/pull/53669) +* \[[`a9837267cb`](https://github.com/nodejs/node/commit/a9837267cb)] - **repl**: avoid interpreting 'npm' as a command when errors are recoverable (Shima Ryuhei) [#54848](https://github.com/nodejs/node/pull/54848) +* \[[`d6a2317961`](https://github.com/nodejs/node/commit/d6a2317961)] - **repl**: doc-deprecate instantiating `node:repl` classes without `new` (Aviv Keller) [#54842](https://github.com/nodejs/node/pull/54842) +* \[[`7f09d983f3`](https://github.com/nodejs/node/commit/7f09d983f3)] - **sea**: don't set code cache flags when snapshot is used (Joyee Cheung) [#54120](https://github.com/nodejs/node/pull/54120) +* \[[`85542b094c`](https://github.com/nodejs/node/commit/85542b094c)] - **src**: add Cleanable class to Environment (Gabriel Schulhof) [#54880](https://github.com/nodejs/node/pull/54880) +* \[[`8422064127`](https://github.com/nodejs/node/commit/8422064127)] - **src**: remove redundant AESCipherMode (Tobias Nießen) [#54438](https://github.com/nodejs/node/pull/54438) +* \[[`342c32483a`](https://github.com/nodejs/node/commit/342c32483a)] - **src**: handle errors correctly in `permission.cc` (Michaël Zasso) [#54541](https://github.com/nodejs/node/pull/54541) +* \[[`90ff714699`](https://github.com/nodejs/node/commit/90ff714699)] - **src**: return `v8::Object` from error constructors (Michaël Zasso) [#54541](https://github.com/nodejs/node/pull/54541) +* \[[`872856cfcb`](https://github.com/nodejs/node/commit/872856cfcb)] - **src**: improve `buffer.transcode` performance (Yagiz Nizipli) [#54153](https://github.com/nodejs/node/pull/54153) +* \[[`91936ebd12`](https://github.com/nodejs/node/commit/91936ebd12)] - **src**: skip inspector wait in internal workers (Chengzhong Wu) [#54219](https://github.com/nodejs/node/pull/54219) +* \[[`9759049427`](https://github.com/nodejs/node/commit/9759049427)] - **src**: account for OpenSSL unexpected version (Shelley Vohr) [#54038](https://github.com/nodejs/node/pull/54038) +* \[[`87167fa248`](https://github.com/nodejs/node/commit/87167fa248)] - **src**: use `args.This()` instead of `Holder` (Michaël Zasso) [#53474](https://github.com/nodejs/node/pull/53474) +* \[[`b05c56e4be`](https://github.com/nodejs/node/commit/b05c56e4be)] - **src**: simplify `size() == 0` checks (Yagiz Nizipli) [#53440](https://github.com/nodejs/node/pull/53440) +* \[[`d53e53699c`](https://github.com/nodejs/node/commit/d53e53699c)] - **src**: fix execArgv in worker (theanarkh) [#53029](https://github.com/nodejs/node/pull/53029) +* \[[`21776a34b5`](https://github.com/nodejs/node/commit/21776a34b5)] - **src**: make sure pass the `argv` to worker threads (theanarkh) [#52827](https://github.com/nodejs/node/pull/52827) +* \[[`3aaae68ec8`](https://github.com/nodejs/node/commit/3aaae68ec8)] - **(SEMVER-MINOR)** **src,lib**: add performance.uvMetricsInfo (Rafael Gonzaga) [#54413](https://github.com/nodejs/node/pull/54413) +* \[[`ef1c0d7def`](https://github.com/nodejs/node/commit/ef1c0d7def)] - **src,permission**: handle process.chdir on pm (Rafael Gonzaga) [#53175](https://github.com/nodejs/node/pull/53175) +* \[[`0c32918eef`](https://github.com/nodejs/node/commit/0c32918eef)] - **stream**: change stream to use index instead of `for...of` (Wiyeong Seo) [#54474](https://github.com/nodejs/node/pull/54474) +* \[[`337cd412b5`](https://github.com/nodejs/node/commit/337cd412b5)] - **stream**: make checking pendingcb on WritableStream backward compatible (jakecastelli) [#54142](https://github.com/nodejs/node/pull/54142) +* \[[`713fc0c9eb`](https://github.com/nodejs/node/commit/713fc0c9eb)] - **stream**: throw TypeError when criteria fulfilled in getIterator (jakecastelli) [#53825](https://github.com/nodejs/node/pull/53825) +* \[[`9686153616`](https://github.com/nodejs/node/commit/9686153616)] - **stream**: fix util.inspect for compression/decompressionStream (Mert Can Altin) [#52283](https://github.com/nodejs/node/pull/52283) +* \[[`76110b0b43`](https://github.com/nodejs/node/commit/76110b0b43)] - **test**: adjust test-tls-junk-server for OpenSSL32 (Michael Dawson) [#54926](https://github.com/nodejs/node/pull/54926) +* \[[`4092889371`](https://github.com/nodejs/node/commit/4092889371)] - **test**: adjust tls test for OpenSSL32 (Michael Dawson) [#54909](https://github.com/nodejs/node/pull/54909) +* \[[`5d48543a16`](https://github.com/nodejs/node/commit/5d48543a16)] - **test**: fix test-http2-socket-close.js (Hüseyin Açacak) [#54900](https://github.com/nodejs/node/pull/54900) +* \[[`8048c2eaed`](https://github.com/nodejs/node/commit/8048c2eaed)] - **test**: improve test-internal-fs-syncwritestream (Sunghoon) [#54671](https://github.com/nodejs/node/pull/54671) +* \[[`597bc14c90`](https://github.com/nodejs/node/commit/597bc14c90)] - **test**: deflake test-dns (Luigi Pinca) [#54902](https://github.com/nodejs/node/pull/54902) +* \[[`a9fc8d9cfa`](https://github.com/nodejs/node/commit/a9fc8d9cfa)] - **test**: fix test test-tls-dhe for OpenSSL32 (Michael Dawson) [#54903](https://github.com/nodejs/node/pull/54903) +* \[[`1b3b4f4a9f`](https://github.com/nodejs/node/commit/1b3b4f4a9f)] - **test**: use correct file naming syntax for `util-parse-env` (Aviv Keller) [#53705](https://github.com/nodejs/node/pull/53705) +* \[[`9db46b5ea3`](https://github.com/nodejs/node/commit/9db46b5ea3)] - **test**: add missing await (Luigi Pinca) [#54828](https://github.com/nodejs/node/pull/54828) +* \[[`124f715679`](https://github.com/nodejs/node/commit/124f715679)] - **test**: move more url tests to `node:test` (Yagiz Nizipli) [#54636](https://github.com/nodejs/node/pull/54636) +* \[[`d2ec96150a`](https://github.com/nodejs/node/commit/d2ec96150a)] - **test**: strip color chars in `test-runner-run` (Giovanni Bucci) [#54552](https://github.com/nodejs/node/pull/54552) +* \[[`747d9ae72e`](https://github.com/nodejs/node/commit/747d9ae72e)] - **test**: deflake test-http2-misbehaving-multiplex (Luigi Pinca) [#54872](https://github.com/nodejs/node/pull/54872) +* \[[`7b7687eadc`](https://github.com/nodejs/node/commit/7b7687eadc)] - **test**: remove dead code in test-http2-misbehaving-multiplex (Luigi Pinca) [#54860](https://github.com/nodejs/node/pull/54860) +* \[[`60f5f5426d`](https://github.com/nodejs/node/commit/60f5f5426d)] - **test**: reduce test-esm-loader-hooks-inspect-wait flakiness (Luigi Pinca) [#54827](https://github.com/nodejs/node/pull/54827) +* \[[`f5e77385c5`](https://github.com/nodejs/node/commit/f5e77385c5)] - **test**: reduce the allocation size in test-worker-arraybuffer-zerofill (James M Snell) [#54839](https://github.com/nodejs/node/pull/54839) +* \[[`f26cf09d6b`](https://github.com/nodejs/node/commit/f26cf09d6b)] - **test**: fix test-tls-client-mindhsize for OpenSSL32 (Michael Dawson) [#54739](https://github.com/nodejs/node/pull/54739) +* \[[`c6f9afec94`](https://github.com/nodejs/node/commit/c6f9afec94)] - **test**: use platform timeout (jakecastelli) [#54591](https://github.com/nodejs/node/pull/54591) +* \[[`8f49b7c3ee`](https://github.com/nodejs/node/commit/8f49b7c3ee)] - **test**: reduce fs calls in test-fs-existssync-false (Yagiz Nizipli) [#54815](https://github.com/nodejs/node/pull/54815) +* \[[`e2c69c9844`](https://github.com/nodejs/node/commit/e2c69c9844)] - **test**: move test-http-server-request-timeouts-mixed (James M Snell) [#54841](https://github.com/nodejs/node/pull/54841) +* \[[`f7af8ca021`](https://github.com/nodejs/node/commit/f7af8ca021)] - **test**: fix volatile for CauseSegfault with clang (Ivan Trubach) [#54325](https://github.com/nodejs/node/pull/54325) +* \[[`d1bae5ede5`](https://github.com/nodejs/node/commit/d1bae5ede5)] - **test**: set `test-worker-arraybuffer-zerofill` as flaky (Yagiz Nizipli) [#54802](https://github.com/nodejs/node/pull/54802) +* \[[`b5b5cc811f`](https://github.com/nodejs/node/commit/b5b5cc811f)] - **test**: set `test-http-server-request-timeouts-mixed` as flaky (Yagiz Nizipli) [#54802](https://github.com/nodejs/node/pull/54802) +* \[[`9808feecac`](https://github.com/nodejs/node/commit/9808feecac)] - **test**: set `test-single-executable-application-empty` as flaky (Yagiz Nizipli) [#54802](https://github.com/nodejs/node/pull/54802) +* \[[`97d41c62e3`](https://github.com/nodejs/node/commit/97d41c62e3)] - **test**: set `test-macos-app-sandbox` as flaky (Yagiz Nizipli) [#54802](https://github.com/nodejs/node/pull/54802) +* \[[`57ae68001c`](https://github.com/nodejs/node/commit/57ae68001c)] - **test**: set `test-fs-utimes` as flaky (Yagiz Nizipli) [#54802](https://github.com/nodejs/node/pull/54802) +* \[[`38afc4da03`](https://github.com/nodejs/node/commit/38afc4da03)] - **test**: set `test-runner-run-watch` as flaky (Yagiz Nizipli) [#54802](https://github.com/nodejs/node/pull/54802) +* \[[`68e19748a6`](https://github.com/nodejs/node/commit/68e19748a6)] - **test**: set `test-writewrap` as flaky (Yagiz Nizipli) [#54802](https://github.com/nodejs/node/pull/54802) +* \[[`e8cb03d530`](https://github.com/nodejs/node/commit/e8cb03d530)] - **test**: set `test-async-context-frame` as flaky (Yagiz Nizipli) [#54802](https://github.com/nodejs/node/pull/54802) +* \[[`3a56517220`](https://github.com/nodejs/node/commit/3a56517220)] - **test**: set `test-esm-loader-hooks-inspect-wait` as flaky (Yagiz Nizipli) [#54802](https://github.com/nodejs/node/pull/54802) +* \[[`c98cd1227d`](https://github.com/nodejs/node/commit/c98cd1227d)] - **test**: set `test-http2-large-file` as flaky (Yagiz Nizipli) [#54802](https://github.com/nodejs/node/pull/54802) +* \[[`16176a6323`](https://github.com/nodejs/node/commit/16176a6323)] - **test**: set `test-runner-watch-mode-complex` as flaky (Yagiz Nizipli) [#54802](https://github.com/nodejs/node/pull/54802) +* \[[`eed0537533`](https://github.com/nodejs/node/commit/eed0537533)] - **test**: set `test-performance-function` as flaky (Yagiz Nizipli) [#54802](https://github.com/nodejs/node/pull/54802) +* \[[`d0f208d2e9`](https://github.com/nodejs/node/commit/d0f208d2e9)] - **test**: set `test-debugger-heap-profiler` as flaky (Yagiz Nizipli) [#54802](https://github.com/nodejs/node/pull/54802) +* \[[`68891a6363`](https://github.com/nodejs/node/commit/68891a6363)] - **test**: fix `test-process-load-env-file` when path contains `'` (Antoine du Hamel) [#54511](https://github.com/nodejs/node/pull/54511) +* \[[`4f82673139`](https://github.com/nodejs/node/commit/4f82673139)] - **test**: refactor fs-watch tests due to macOS issue (Santiago Gimeno) [#54498](https://github.com/nodejs/node/pull/54498) +* \[[`3606c53fdc`](https://github.com/nodejs/node/commit/3606c53fdc)] - **test**: refactor `test-esm-type-field-errors` (Giovanni Bucci) [#54368](https://github.com/nodejs/node/pull/54368) +* \[[`99566aea97`](https://github.com/nodejs/node/commit/99566aea97)] - **test**: improve output of child process utilities (Joyee Cheung) [#54622](https://github.com/nodejs/node/pull/54622) +* \[[`ed2377c1a1`](https://github.com/nodejs/node/commit/ed2377c1a1)] - **test**: fix test-tls-client-auth test for OpenSSL32 (Michael Dawson) [#54610](https://github.com/nodejs/node/pull/54610) +* \[[`d2a7e45946`](https://github.com/nodejs/node/commit/d2a7e45946)] - **test**: update TLS test for OpenSSL 3.2 (Richard Lau) [#54612](https://github.com/nodejs/node/pull/54612) +* \[[`a50bbca78a`](https://github.com/nodejs/node/commit/a50bbca78a)] - **test**: increase key size for ca2-cert.pem (Michael Dawson) [#54599](https://github.com/nodejs/node/pull/54599) +* \[[`d7ac3262de`](https://github.com/nodejs/node/commit/d7ac3262de)] - **test**: update test-assert-typedarray-deepequal to use node:test (James M Snell) [#54585](https://github.com/nodejs/node/pull/54585) +* \[[`916a73cd8f`](https://github.com/nodejs/node/commit/916a73cd8f)] - **test**: update test-assert to use node:test (James M Snell) [#54585](https://github.com/nodejs/node/pull/54585) +* \[[`10bea1cef5`](https://github.com/nodejs/node/commit/10bea1cef5)] - **test**: merge ongc and gcutil into gc.js (tannal) [#54355](https://github.com/nodejs/node/pull/54355) +* \[[`f145982436`](https://github.com/nodejs/node/commit/f145982436)] - **test**: move a couple of tests over to using node:test (James M Snell) [#54582](https://github.com/nodejs/node/pull/54582) +* \[[`229e102d20`](https://github.com/nodejs/node/commit/229e102d20)] - **test**: fix embedding test for Windows (Vladimir Morozov) [#53659](https://github.com/nodejs/node/pull/53659) +* \[[`fcf82adef0`](https://github.com/nodejs/node/commit/fcf82adef0)] - **test**: use relative paths in test-cli-permission tests (sendoru) [#54188](https://github.com/nodejs/node/pull/54188) +* \[[`4c219b0235`](https://github.com/nodejs/node/commit/4c219b0235)] - **test**: fix timeout not being cleared (Isaac-yz-Liu) [#54242](https://github.com/nodejs/node/pull/54242) +* \[[`e446517a41`](https://github.com/nodejs/node/commit/e446517a41)] - **test**: refactor `test-runner-module-mocking` (Antoine du Hamel) [#54233](https://github.com/nodejs/node/pull/54233) +* \[[`782a6a05ef`](https://github.com/nodejs/node/commit/782a6a05ef)] - **test**: use assert.{s,deepS}trictEqual() (Luigi Pinca) [#54208](https://github.com/nodejs/node/pull/54208) +* \[[`d478db7adc`](https://github.com/nodejs/node/commit/d478db7adc)] - **test**: set test-structuredclone-jstransferable non-flaky (Stefan Stojanovic) [#54115](https://github.com/nodejs/node/pull/54115) +* \[[`c8587ec90d`](https://github.com/nodejs/node/commit/c8587ec90d)] - **test**: update wpt test for streams (devstone) [#54129](https://github.com/nodejs/node/pull/54129) +* \[[`dbc26c2971`](https://github.com/nodejs/node/commit/dbc26c2971)] - **test**: fix typo in test (Sonny) [#54137](https://github.com/nodejs/node/pull/54137) +* \[[`17b7ec4df3`](https://github.com/nodejs/node/commit/17b7ec4df3)] - **test**: add initial pull delay and prototype pollution prevention tests (Sonny) [#54061](https://github.com/nodejs/node/pull/54061) +* \[[`931ff4367a`](https://github.com/nodejs/node/commit/931ff4367a)] - **test**: update wpt test (Mert Can Altin) [#53814](https://github.com/nodejs/node/pull/53814) +* \[[`1c1bd7ce52`](https://github.com/nodejs/node/commit/1c1bd7ce52)] - **test**: update `url` web-platform tests (Yagiz Nizipli) [#53472](https://github.com/nodejs/node/pull/53472) +* \[[`b048eaea5c`](https://github.com/nodejs/node/commit/b048eaea5c)] - **test\_runner**: reimplement `assert.ok` to allow stack parsing (Aviv Keller) [#54776](https://github.com/nodejs/node/pull/54776) +* \[[`c981e61155`](https://github.com/nodejs/node/commit/c981e61155)] - **test\_runner**: improve code coverage cleanup (Colin Ihrig) [#54856](https://github.com/nodejs/node/pull/54856) +* \[[`4f421b37da`](https://github.com/nodejs/node/commit/4f421b37da)] - **test\_runner**: use validateStringArray for `timers.enable()` (Deokjin Kim) [#49534](https://github.com/nodejs/node/pull/49534) +* \[[`27da75ae22`](https://github.com/nodejs/node/commit/27da75ae22)] - **test\_runner**: do not expose internal loader (Antoine du Hamel) [#54106](https://github.com/nodejs/node/pull/54106) +* \[[`56cbc80d28`](https://github.com/nodejs/node/commit/56cbc80d28)] - **test\_runner**: make mock\_loader not confuse CJS and ESM resolution (Sung Ye In) [#53846](https://github.com/nodejs/node/pull/53846) +* \[[`8fd951f7c7`](https://github.com/nodejs/node/commit/8fd951f7c7)] - **test\_runner**: remove outdated comment (Colin Ihrig) [#54146](https://github.com/nodejs/node/pull/54146) +* \[[`65b6fec3ba`](https://github.com/nodejs/node/commit/65b6fec3ba)] - **test\_runner**: run after hooks even if test is aborted (Colin Ihrig) [#54151](https://github.com/nodejs/node/pull/54151) +* \[[`c0b4c8284c`](https://github.com/nodejs/node/commit/c0b4c8284c)] - **test\_runner**: added colors to dot reporter (Giovanni) [#53450](https://github.com/nodejs/node/pull/53450) +* \[[`3000e5df91`](https://github.com/nodejs/node/commit/3000e5df91)] - **test\_runner**: support module detection in module mocks (Geoffrey Booth) [#53642](https://github.com/nodejs/node/pull/53642) +* \[[`f789f4c92d`](https://github.com/nodejs/node/commit/f789f4c92d)] - **(SEMVER-MINOR)** **test\_runner**: support module mocking (Colin Ihrig) [#52848](https://github.com/nodejs/node/pull/52848) +* \[[`82d1c36f51`](https://github.com/nodejs/node/commit/82d1c36f51)] - **test\_runner**: display failed test stack trace with dot reporter (Mihir Bhansali) [#52655](https://github.com/nodejs/node/pull/52655) +* \[[`5358601e31`](https://github.com/nodejs/node/commit/5358601e31)] - **timers**: avoid generating holey internal arrays (Gürgün Dayıoğlu) [#54771](https://github.com/nodejs/node/pull/54771) +* \[[`b6ed97c66d`](https://github.com/nodejs/node/commit/b6ed97c66d)] - **timers**: document ref option for scheduler.wait (Paolo Insogna) [#54605](https://github.com/nodejs/node/pull/54605) +* \[[`f524b8a28b`](https://github.com/nodejs/node/commit/f524b8a28b)] - **timers**: fix validation (Paolo Insogna) [#54404](https://github.com/nodejs/node/pull/54404) +* \[[`bc020f7cb3`](https://github.com/nodejs/node/commit/bc020f7cb3)] - **(SEMVER-MINOR)** **tls**: add `allowPartialTrustChain` flag (Anna Henningsen) [#54790](https://github.com/nodejs/node/pull/54790) +* \[[`d0e6f9168e`](https://github.com/nodejs/node/commit/d0e6f9168e)] - **tls**: remove prototype primordials (Antoine du Hamel) [#53699](https://github.com/nodejs/node/pull/53699) +* \[[`f5c65d0be6`](https://github.com/nodejs/node/commit/f5c65d0be6)] - **tools**: add readability/fn\_size to filter (Rafael Gonzaga) [#54744](https://github.com/nodejs/node/pull/54744) +* \[[`a47bb9b2c2`](https://github.com/nodejs/node/commit/a47bb9b2c2)] - **tools**: add util scripts to land and rebase PRs (Antoine du Hamel) [#54656](https://github.com/nodejs/node/pull/54656) +* \[[`fe3155cefa`](https://github.com/nodejs/node/commit/fe3155cefa)] - **tools**: remove readability/fn\_size rule (Rafael Gonzaga) [#54663](https://github.com/nodejs/node/pull/54663) +* \[[`d6b9cc3acd`](https://github.com/nodejs/node/commit/d6b9cc3acd)] - **tools**: remove unused python files (Aviv Keller) [#53928](https://github.com/nodejs/node/pull/53928) +* \[[`b5fbe9609c`](https://github.com/nodejs/node/commit/b5fbe9609c)] - **tools**: remove header from c-ares license (Aviv Keller) [#54335](https://github.com/nodejs/node/pull/54335) +* \[[`a7fdc608c6`](https://github.com/nodejs/node/commit/a7fdc608c6)] - **tools**: add find pyenv path on windows (Marco Ippolito) [#54314](https://github.com/nodejs/node/pull/54314) +* \[[`f90688cd5b`](https://github.com/nodejs/node/commit/f90688cd5b)] - **tools**: make undici updater build wasm from src (Michael Dawson) [#54128](https://github.com/nodejs/node/pull/54128) +* \[[`a033dff2f2`](https://github.com/nodejs/node/commit/a033dff2f2)] - **tty**: initialize winSize array with values (Michaël Zasso) [#54281](https://github.com/nodejs/node/pull/54281) +* \[[`e635e0956c`](https://github.com/nodejs/node/commit/e635e0956c)] - **typings**: fix TypedArray to a global type (1ilsang) [#54063](https://github.com/nodejs/node/pull/54063) +* \[[`b5bf08f31e`](https://github.com/nodejs/node/commit/b5bf08f31e)] - **typings**: correct param type of `SafePromisePrototypeFinally` (Wuli) [#54727](https://github.com/nodejs/node/pull/54727) +* \[[`628ae4bde5`](https://github.com/nodejs/node/commit/628ae4bde5)] - **typings**: add util.styleText type definition (Rafael Gonzaga) [#54252](https://github.com/nodejs/node/pull/54252) +* \[[`cc37401ea5`](https://github.com/nodejs/node/commit/cc37401ea5)] - **typings**: add missing binding function `writeFileUtf8()` (Jungku Lee) [#54110](https://github.com/nodejs/node/pull/54110) +* \[[`728c3fd6f1`](https://github.com/nodejs/node/commit/728c3fd6f1)] - **url**: modify pathToFileURL to handle extended UNC path (Early Riser) [#54262](https://github.com/nodejs/node/pull/54262) +* \[[`b25563dfcb`](https://github.com/nodejs/node/commit/b25563dfcb)] - **url**: improve resolveObject with ObjectAssign (Early Riser) [#54092](https://github.com/nodejs/node/pull/54092) +* \[[`eededd1ca8`](https://github.com/nodejs/node/commit/eededd1ca8)] - **url**: make URL.parse enumerable (Filip Skokan) [#53720](https://github.com/nodejs/node/pull/53720) +* \[[`4eb0749b6c`](https://github.com/nodejs/node/commit/4eb0749b6c)] - **(SEMVER-MINOR)** **url**: implement parse method for safer URL parsing (Ali Hassan) [#52280](https://github.com/nodejs/node/pull/52280) +* \[[`9e1c2293bf`](https://github.com/nodejs/node/commit/9e1c2293bf)] - **vm**: harden module type checks (Chengzhong Wu) [#52162](https://github.com/nodejs/node/pull/52162) +* \[[`2d90340cb3`](https://github.com/nodejs/node/commit/2d90340cb3)] - **(SEMVER-MINOR)** **vm**: introduce vanilla contexts via vm.constants.DONT\_CONTEXTIFY (Joyee Cheung) [#54394](https://github.com/nodejs/node/pull/54394) +* \[[`4644d05ab5`](https://github.com/nodejs/node/commit/4644d05ab5)] - **zlib**: deprecate instantiating classes without new (Yagiz Nizipli) [#54708](https://github.com/nodejs/node/pull/54708) +* \[[`ecdf6dd444`](https://github.com/nodejs/node/commit/ecdf6dd444)] - **zlib**: simplify validators (Yagiz Nizipli) [#54442](https://github.com/nodejs/node/pull/54442) + ## 2024-08-21, Version 20.17.0 'Iron' (LTS), @marco-ippolito diff --git a/doc/contributing/collaborator-guide.md b/doc/contributing/collaborator-guide.md index 73f5164c008..755b84c7505 100644 --- a/doc/contributing/collaborator-guide.md +++ b/doc/contributing/collaborator-guide.md @@ -441,6 +441,23 @@ For pull requests introducing new core modules: * Land with a [Stability Index][] of Experimental. The module must remain Experimental until a semver-major release. +### Introducing new APIs on the global scope + +Exposing new APIs to the global scope that are available without +an `import` or `require` call, including introducing new interfaces on +`globalThis` like `globalThis.navigator`, and adding new properties on +interfaces on `globalThis` like well known symbols, could break feature +detection and Node.js environment detection. + +Exposing new APIs to the global scope unconditionally without any CLI +flags must always be labeled as `semver-major`. The `semver-major` label may +be waived through the regular TSC consensus process. + +It is recommended to start with exposing APIs to the global scope with an +experimental CLI flag `--experimental-`, without being labeled as +`semver-major`. When the new APIs are feature complete, turn the flag on by +default with a CLI flag `--no-experimental-` to opt-out. + ### Additions to Node-API Node-API provides an ABI-stable API guaranteed for future Node.js versions. diff --git a/doc/contributing/internal-api.md b/doc/contributing/internal-api.md index 2631978e1af..e4120f44fc6 100644 --- a/doc/contributing/internal-api.md +++ b/doc/contributing/internal-api.md @@ -8,6 +8,12 @@ rules. The core developers may remove these flags in any version of Node.js. ### Flags +#### `--debug-arraybuffer-allocations` + +#### `--expose-internals` + +Allows to require the `internal/*` modules. + #### `--inspect-brk-node[=[host:]port]` | item | // | item | | item | | item | // | ... | | ... | | ... | // | item | | item | | item | // | item | | item | | item | -// | [empty] | <-- top | item | | item | -// | [empty] | | item | | item | -// | [empty] | | [empty] | <-- top top --> | [empty] | +// | undefined | <-- top | item | | item | +// | undefined | | item | | item | +// | undefined | | undefined | <-- top top --> | undefined | // +-----------+ +-----------+ +-----------+ // // Or, if there is only one circular buffer, it looks something @@ -40,12 +41,12 @@ const kMask = kSize - 1; // +-----------+ +-----------+ // | [null] | | [null] | // +-----------+ +-----------+ -// | [empty] | | item | -// | [empty] | | item | -// | item | <-- bottom top --> | [empty] | -// | item | | [empty] | -// | [empty] | <-- top bottom --> | item | -// | [empty] | | item | +// | undefined | | item | +// | undefined | | item | +// | item | <-- bottom top --> | undefined | +// | item | | undefined | +// | undefined | <-- top bottom --> | item | +// | undefined | | item | // +-----------+ +-----------+ // // Adding a value means moving `top` forward by one, removing means @@ -60,7 +61,7 @@ class FixedCircularBuffer { constructor() { this.bottom = 0; this.top = 0; - this.list = new Array(kSize); + this.list = ArrayPrototypeFill(new Array(kSize), undefined); this.next = null; } diff --git a/lib/internal/fs/cp/cp.js b/lib/internal/fs/cp/cp.js index f59bbdb1e59..0724eb730db 100644 --- a/lib/internal/fs/cp/cp.js +++ b/lib/internal/fs/cp/cp.js @@ -270,7 +270,6 @@ async function handleTimestampsAndMode(srcMode, src, dest) { // (through utimes call) if (fileIsNotWritable(srcMode)) { await makeFileWritable(dest, srcMode); - return setDestTimestampsAndMode(srcMode, src, dest); } return setDestTimestampsAndMode(srcMode, src, dest); } diff --git a/lib/internal/fs/rimraf.js b/lib/internal/fs/rimraf.js index 877f238011c..d5732ef3dbd 100644 --- a/lib/internal/fs/rimraf.js +++ b/lib/internal/fs/rimraf.js @@ -140,8 +140,10 @@ function _rmchildren(path, options, callback) { let done = false; - ArrayPrototypeForEach(files, (child) => { - const childPath = Buffer.concat([pathBuf, separator, child]); + const childPathPrefix = Buffer.concat([pathBuf, separator]); + + for (let i = 0; i < files.length; i++) { + const childPath = Buffer.concat([childPathPrefix, files[i]]); rimraf(childPath, options, (err) => { if (done) @@ -156,7 +158,7 @@ function _rmchildren(path, options, callback) { if (numFiles === 0) rmdir(path, callback); }); - }); + } }); } diff --git a/lib/internal/http.js b/lib/internal/http.js index c26c322aafc..251f51ec454 100644 --- a/lib/internal/http.js +++ b/lib/internal/http.js @@ -1,10 +1,8 @@ 'use strict'; const { - Symbol, Date, - DatePrototypeGetMilliseconds, - DatePrototypeToUTCString, + Symbol, } = primordials; const { setUnrefTimeout } = require('internal/timers'); @@ -23,8 +21,8 @@ function utcDate() { function cache() { const d = new Date(); - utcCache = DatePrototypeToUTCString(d); - setUnrefTimeout(resetCache, 1000 - DatePrototypeGetMilliseconds(d)); + utcCache = d.toUTCString(); + setUnrefTimeout(resetCache, 1000 - d.getMilliseconds()); } function resetCache() { diff --git a/lib/internal/http2/compat.js b/lib/internal/http2/compat.js index f0dd26de0d6..24370094866 100644 --- a/lib/internal/http2/compat.js +++ b/lib/internal/http2/compat.js @@ -2,19 +2,13 @@ const { ArrayIsArray, - ArrayPrototypePush, Boolean, - FunctionPrototypeBind, ObjectAssign, + ObjectHasOwn, ObjectKeys, - ObjectPrototypeHasOwnProperty, Proxy, ReflectApply, ReflectGetPrototypeOf, - StringPrototypeIncludes, - SafeArrayIterator, - StringPrototypeToLowerCase, - StringPrototypeTrim, Symbol, } = primordials; @@ -89,7 +83,7 @@ let statusConnectionHeaderWarned = false; const assertValidHeader = hideStackFrames((name, value) => { if (name === '' || typeof name !== 'string' || - StringPrototypeIncludes(name, ' ')) { + name.includes(' ')) { throw new ERR_INVALID_HTTP_TOKEN.HideStackFramesError('Header name', name); } if (isPseudoHeader(name)) { @@ -153,8 +147,7 @@ function onStreamTrailers(trailers, flags, rawTrailers) { const request = this[kRequest]; if (request !== undefined) { ObjectAssign(request[kTrailers], trailers); - ArrayPrototypePush(request[kRawTrailers], - ...new SafeArrayIterator(rawTrailers)); + request[kRawTrailers].push(...rawTrailers); } } @@ -216,7 +209,7 @@ const proxySocketHandler = { case 'end': case 'emit': case 'destroy': - return FunctionPrototypeBind(stream[prop], stream); + return stream[prop].bind(stream); case 'writable': case 'destroyed': return stream[prop]; @@ -229,8 +222,8 @@ const proxySocketHandler = { case 'setTimeout': { const session = stream.session; if (session !== undefined) - return FunctionPrototypeBind(session.setTimeout, session); - return FunctionPrototypeBind(stream.setTimeout, stream); + return session.setTimeout.bind(session); + return stream.setTimeout.bind(stream); } case 'write': case 'read': @@ -242,7 +235,7 @@ const proxySocketHandler = { stream.session[kSocket] : stream; const value = ref[prop]; return typeof value === 'function' ? - FunctionPrototypeBind(value, ref) : + value.bind(ref) : value; } } @@ -417,7 +410,7 @@ class Http2ServerRequest extends Readable { set method(method) { validateString(method, 'method'); - if (StringPrototypeTrim(method) === '') + if (method.trim() === '') throw new ERR_INVALID_ARG_VALUE('method', method); this[kHeaders][HTTP2_HEADER_METHOD] = method; @@ -578,7 +571,7 @@ class Http2ServerResponse extends Stream { setTrailer(name, value) { validateString(name, 'name'); - name = StringPrototypeToLowerCase(StringPrototypeTrim(name)); + name = name.trim().toLowerCase(); assertValidHeader(name, value); this[kTrailers][name] = value; } @@ -594,7 +587,7 @@ class Http2ServerResponse extends Stream { getHeader(name) { validateString(name, 'name'); - name = StringPrototypeToLowerCase(StringPrototypeTrim(name)); + name = name.trim().toLowerCase(); return this[kHeaders][name]; } @@ -609,8 +602,8 @@ class Http2ServerResponse extends Stream { hasHeader(name) { validateString(name, 'name'); - name = StringPrototypeToLowerCase(StringPrototypeTrim(name)); - return ObjectPrototypeHasOwnProperty(this[kHeaders], name); + name = name.trim().toLowerCase(); + return ObjectHasOwn(this[kHeaders], name); } removeHeader(name) { @@ -618,7 +611,7 @@ class Http2ServerResponse extends Stream { if (this[kStream].headersSent) throw new ERR_HTTP2_HEADERS_SENT(); - name = StringPrototypeToLowerCase(StringPrototypeTrim(name)); + name = name.trim().toLowerCase(); if (name === 'date') { this[kState].sendDate = false; @@ -638,7 +631,7 @@ class Http2ServerResponse extends Stream { } [kSetHeader](name, value) { - name = StringPrototypeToLowerCase(StringPrototypeTrim(name)); + name = name.trim().toLowerCase(); assertValidHeader(name, value); if (!isConnectionHeaderAllowed(name, value)) { @@ -662,7 +655,7 @@ class Http2ServerResponse extends Stream { } [kAppendHeader](name, value) { - name = StringPrototypeToLowerCase(StringPrototypeTrim(name)); + name = name.trim().toLowerCase(); assertValidHeader(name, value); if (!isConnectionHeaderAllowed(name, value)) { diff --git a/lib/internal/http2/core.js b/lib/internal/http2/core.js index 49ec8b0691f..4b3ae479e90 100644 --- a/lib/internal/http2/core.js +++ b/lib/internal/http2/core.js @@ -3,34 +3,24 @@ const { ArrayFrom, ArrayIsArray, - ArrayPrototypeForEach, - ArrayPrototypePush, - ArrayPrototypeUnshift, - FunctionPrototypeBind, - FunctionPrototypeCall, MathMin, Number, ObjectAssign, - ObjectKeys, ObjectDefineProperty, ObjectEntries, - ObjectPrototypeHasOwnProperty, + ObjectHasOwn, + ObjectKeys, Promise, - PromisePrototypeThen, Proxy, ReflectApply, ReflectGet, ReflectGetPrototypeOf, ReflectSet, - RegExpPrototypeExec, - SafeArrayIterator, SafeMap, SafeSet, - StringPrototypeSlice, Symbol, SymbolAsyncDispose, SymbolDispose, - TypedArrayPrototypeGetLength, Uint32Array, Uint8Array, } = primordials; @@ -205,22 +195,22 @@ function debugStream(id, sessionType, message, ...args) { return; } debug('Http2Stream %s [Http2Session %s]: ' + message, - id, sessionName(sessionType), ...new SafeArrayIterator(args)); + id, sessionName(sessionType), ...args); } function debugStreamObj(stream, message, ...args) { const session = stream[kSession]; const type = session ? session[kType] : undefined; - debugStream(stream[kID], type, message, ...new SafeArrayIterator(args)); + debugStream(stream[kID], type, message, ...args); } function debugSession(sessionType, message, ...args) { debug('Http2Session %s: ' + message, sessionName(sessionType), - ...new SafeArrayIterator(args)); + ...args); } function debugSessionObj(session, message, ...args) { - debugSession(session[kType], message, ...new SafeArrayIterator(args)); + debugSession(session[kType], message, ...args); } const kMaxFrameSize = (2 ** 24) - 1; @@ -826,8 +816,7 @@ function submitSettings(settings, callback) { debugSessionObj(this, 'submitting settings'); this[kUpdateTimer](); updateSettingsBuffer(settings); - if (!this[kHandle].settings(FunctionPrototypeBind(settingsCallback, - this, callback))) { + if (!this[kHandle].settings(settingsCallback.bind(this, callback))) { this.destroy(new ERR_HTTP2_MAX_PENDING_SETTINGS_ACK()); } } @@ -869,7 +858,7 @@ const proxySocketHandler = { case 'setTimeout': case 'ref': case 'unref': - return FunctionPrototypeBind(session[prop], session); + return session[prop].bind(session); case 'destroy': case 'emit': case 'end': @@ -887,7 +876,7 @@ const proxySocketHandler = { throw new ERR_HTTP2_SOCKET_UNBOUND(); const value = socket[prop]; return typeof value === 'function' ? - FunctionPrototypeBind(value, socket) : + value.bind(socket) : value; } } @@ -998,7 +987,7 @@ const validateSettings = hideStackFrames((settings) => { // Wrap a typed array in a proxy, and allow selectively copying the entries // that have explicitly been set to another typed array. function trackAssignmentsTypedArray(typedArray) { - const typedArrayLength = TypedArrayPrototypeGetLength(typedArray); + const typedArrayLength = typedArray.length; const modifiedEntries = new Uint8Array(typedArrayLength); function copyAssigned(target) { @@ -1183,8 +1172,7 @@ function closeSession(session, code, error) { // Destroy the handle if it exists at this point. if (handle !== undefined) { - handle.ondone = FunctionPrototypeBind(finishSessionClose, - null, session, error); + handle.ondone = finishSessionClose.bind(null, session, error); handle.destroy(code, socket.destroyed); } else { finishSessionClose(session, error); @@ -1276,8 +1264,7 @@ class Http2Session extends EventEmitter { if (typeof socket.disableRenegotiation === 'function') socket.disableRenegotiation(); - const setupFn = FunctionPrototypeBind(setupHandle, this, - socket, type, options); + const setupFn = setupHandle.bind(this, socket, type, options); if (socket.connecting || socket.secureConnecting) { const connectEvent = socket instanceof tls.TLSSocket ? 'secureConnect' : 'connect'; @@ -1512,8 +1499,7 @@ class Http2Session extends EventEmitter { this[kState].pendingAck++; - const settingsFn = FunctionPrototypeBind(submitSettings, this, - { ...settings }, callback); + const settingsFn = submitSettings.bind(this, { ...settings }, callback); if (this.connecting) { this.once('connect', settingsFn); return; @@ -1535,9 +1521,7 @@ class Http2Session extends EventEmitter { validateNumber(code, 'code'); validateNumber(lastStreamID, 'lastStreamID'); - const goawayFn = FunctionPrototypeBind(submitGoaway, - this, - code, lastStreamID, opaqueData); + const goawayFn = submitGoaway.bind(this, code, lastStreamID, opaqueData); if (this.connecting) { this.once('connect', goawayFn); return; @@ -1693,7 +1677,7 @@ class ServerHttp2Session extends Http2Session { } validateString(alt, 'alt'); - if (RegExpPrototypeExec(kQuotedString, alt) === null) + if (!kQuotedString.test(alt)) throw new ERR_INVALID_CHAR('alt'); // Max length permitted for ALTSVC @@ -1786,8 +1770,7 @@ class ClientHttp2Session extends Http2Session { if (getAuthority(headers) === undefined) headers[HTTP2_HEADER_AUTHORITY] = this[kAuthority]; if (headers[HTTP2_HEADER_SCHEME] === undefined) - headers[HTTP2_HEADER_SCHEME] = StringPrototypeSlice(this[kProtocol], - 0, -1); + headers[HTTP2_HEADER_SCHEME] = this[kProtocol].slice(0, -1); if (headers[HTTP2_HEADER_PATH] === undefined) headers[HTTP2_HEADER_PATH] = '/'; } else { @@ -1839,15 +1822,14 @@ class ClientHttp2Session extends Http2Session { } } - const onConnect = FunctionPrototypeBind(requestOnConnect, - stream, headersList, options); + const onConnect = requestOnConnect.bind(stream, headersList, options); if (this.connecting) { if (this[kPendingRequestCalls] !== null) { - ArrayPrototypePush(this[kPendingRequestCalls], onConnect); + this[kPendingRequestCalls].push(onConnect); } else { this[kPendingRequestCalls] = [onConnect]; this.once('connect', () => { - ArrayPrototypeForEach(this[kPendingRequestCalls], (f) => f()); + this[kPendingRequestCalls].forEach((f) => f()); this[kPendingRequestCalls] = null; }); } @@ -1951,7 +1933,7 @@ function closeStream(stream, code, rstStreamStatus = kSubmitRstStream) { } if (rstStreamStatus !== kNoRstStream) { - const finishFn = FunctionPrototypeBind(finishCloseStream, stream, code); + const finishFn = finishCloseStream.bind(stream, code); if (!ending || stream.writableFinished || code !== NGHTTP2_NO_ERROR || rstStreamStatus === kForceRstStream) finishFn(); @@ -1961,7 +1943,7 @@ function closeStream(stream, code, rstStreamStatus = kSubmitRstStream) { } function finishCloseStream(code) { - const rstStreamFn = FunctionPrototypeBind(submitRstStream, this, code); + const rstStreamFn = submitRstStream.bind(this, code); // If the handle has not yet been assigned, queue up the request to // ensure that the RST_STREAM frame is sent after the stream ID has // been determined. @@ -2145,8 +2127,7 @@ class Http2Stream extends Duplex { if (this.pending) { this.once( 'ready', - FunctionPrototypeBind(this[kWriteGeneric], - this, writev, data, encoding, cb), + this[kWriteGeneric].bind(this, writev, data, encoding, cb), ); return; } @@ -2238,7 +2219,7 @@ class Http2Stream extends Duplex { this[kState].didRead = true; } if (!this.pending) { - FunctionPrototypeCall(streamOnResume, this); + streamOnResume.call(this); } else { this.once('ready', streamOnResume); } @@ -2252,7 +2233,7 @@ class Http2Stream extends Duplex { options = { ...options }; setAndValidatePriorityOptions(options); - const priorityFn = FunctionPrototypeBind(submitPriority, this, options); + const priorityFn = submitPriority.bind(this, options); // If the handle has not yet been assigned, queue up the priority // frame to be sent as soon as the ready event is emitted. @@ -2455,7 +2436,7 @@ function processHeaders(oldHeaders, options) { if (oldHeaders !== null && oldHeaders !== undefined) { // This loop is here for performance reason. Do not change. for (const key in oldHeaders) { - if (ObjectPrototypeHasOwnProperty(oldHeaders, key)) { + if (ObjectHasOwn(oldHeaders, key)) { headers[key] = oldHeaders[key]; } } @@ -2493,8 +2474,7 @@ function processHeaders(oldHeaders, options) { function onFileUnpipe() { const stream = this.sink[kOwner]; if (stream.ownsFd) - PromisePrototypeThen(this.source.close(), undefined, - FunctionPrototypeBind(stream.destroy, stream)); + this.source.close().catch(stream.destroy.bind(stream)); else this.source.releaseFD(); } @@ -2677,9 +2657,7 @@ function afterOpen(session, options, headers, streamOptions, err, fd) { state.fd = fd; fs.fstat(fd, - FunctionPrototypeBind(doSendFileFD, this, - session, options, fd, - headers, streamOptions)); + doSendFileFD.bind(this, session, options, fd, headers, streamOptions)); } class ServerHttp2Stream extends Http2Stream { @@ -2882,9 +2860,7 @@ class ServerHttp2Stream extends Http2Stream { if (options.statCheck !== undefined) { fs.fstat(fd, - FunctionPrototypeBind(doSendFD, this, - session, options, fd, - headers, streamOptions)); + doSendFD.bind(this, session, options, fd, headers, streamOptions)); return; } @@ -2943,8 +2919,7 @@ class ServerHttp2Stream extends Http2Stream { } fs.open(path, 'r', - FunctionPrototypeBind(afterOpen, this, - session, options, headers, streamOptions)); + afterOpen.bind(this, session, options, headers, streamOptions)); } // Sends a block of informational headers. In theory, the HTTP/2 spec @@ -2980,7 +2955,7 @@ class ServerHttp2Stream extends Http2Stream { if (!this[kInfoHeaders]) this[kInfoHeaders] = [headers]; else - ArrayPrototypePush(this[kInfoHeaders], headers); + this[kInfoHeaders].push(headers); const ret = this[kHandle].info(headersList); if (ret < 0) @@ -3066,7 +3041,7 @@ function connectionListener(socket) { if (options.allowHTTP1 === true) { socket.server[kIncomingMessage] = options.Http1IncomingMessage; socket.server[kServerResponse] = options.Http1ServerResponse; - return FunctionPrototypeCall(httpConnectionListener, this, socket); + return httpConnectionListener.call(this, socket); } // Let event handler deal with the socket debug('Unknown protocol from %s:%s', @@ -3164,7 +3139,7 @@ function initializeTLSOptions(options, servername) { options = initializeOptions(options); options.ALPNProtocols = ['h2']; if (options.allowHTTP1 === true) - ArrayPrototypePush(options.ALPNProtocols, 'http/1.1'); + options.ALPNProtocols.push('http/1.1'); if (servername !== undefined && !options.servername) options.servername = servername; return options; @@ -3249,7 +3224,7 @@ class Http2Server extends NETServer { } async [SymbolAsyncDispose]() { - return FunctionPrototypeCall(promisify(super.close), this); + return promisify(super.close).call(this); } } @@ -3284,7 +3259,7 @@ Http2Server.prototype[EventEmitter.captureRejectionSymbol] = function( break; } default: - ArrayPrototypeUnshift(args, err, event); + args.unshift(err, event); ReflectApply(net.Server.prototype[EventEmitter.captureRejectionSymbol], this, args); } @@ -3293,11 +3268,8 @@ Http2Server.prototype[EventEmitter.captureRejectionSymbol] = function( function setupCompat(ev) { if (ev === 'request') { this.removeListener('newListener', setupCompat); - this.on('stream', FunctionPrototypeBind(onServerStream, - this, - this[kOptions].Http2ServerRequest, - this[kOptions].Http2ServerResponse), - ); + this.on('stream', onServerStream.bind(this, this[kOptions].Http2ServerRequest, + this[kOptions].Http2ServerResponse)); } } @@ -3344,7 +3316,7 @@ function connect(authority, options, listener) { host = authority.hostname; if (host[0] === '[') - host = StringPrototypeSlice(host, 1, -1); + host = host.slice(1, -1); } else if (authority.host) { host = authority.host; } diff --git a/lib/internal/http2/util.js b/lib/internal/http2/util.js index 46e0218ac64..77267a52fdc 100644 --- a/lib/internal/http2/util.js +++ b/lib/internal/http2/util.js @@ -2,9 +2,6 @@ const { ArrayIsArray, - ArrayPrototypeIncludes, - ArrayPrototypeMap, - ArrayPrototypePush, Error, MathMax, Number, @@ -13,8 +10,6 @@ const { SafeSet, String, StringFromCharCode, - StringPrototypeIncludes, - StringPrototypeToLowerCase, Symbol, } = primordials; @@ -602,15 +597,13 @@ function mapToHeaders(map, let value; let isSingleValueHeader; let err; - const neverIndex = - ArrayPrototypeMap(map[kSensitiveHeaders] || emptyArray, - StringPrototypeToLowerCase); + const neverIndex = (map[kSensitiveHeaders] || emptyArray).map((v) => v.toLowerCase()); for (i = 0; i < keys.length; ++i) { key = keys[i]; value = map[key]; if (value === undefined || key === '') continue; - key = StringPrototypeToLowerCase(key); + key = key.toLowerCase(); isSingleValueHeader = kSingleValueHeaders.has(key); isArray = ArrayIsArray(value); if (isArray) { @@ -633,7 +626,7 @@ function mapToHeaders(map, throw new ERR_HTTP2_HEADER_SINGLE_VALUE(key); singles.add(key); } - const flags = ArrayPrototypeIncludes(neverIndex, key) ? + const flags = neverIndex.includes(key) ? kNeverIndexFlag : kNoHeaderFlags; if (key[0] === ':') { @@ -644,7 +637,7 @@ function mapToHeaders(map, count++; continue; } - if (StringPrototypeIncludes(key, ' ')) { + if (key.includes(' ')) { throw new ERR_INVALID_HTTP_TOKEN('Header name', key); } if (isIllegalConnectionSpecificHeader(key, value)) { @@ -738,7 +731,7 @@ function toHeaderObject(headers, sensitiveHeaders) { // fields with the same name. Since it cannot be combined into a // single field-value, recipients ought to handle "Set-Cookie" as a // special case while processing header fields." - ArrayPrototypePush(existing, value); + existing.push(value); break; default: // https://tools.ietf.org/html/rfc7230#section-3.2.2 diff --git a/lib/internal/inspector_network_tracking.js b/lib/internal/inspector_network_tracking.js new file mode 100644 index 00000000000..df3d2e5bf8e --- /dev/null +++ b/lib/internal/inspector_network_tracking.js @@ -0,0 +1,109 @@ +'use strict'; + +const { + ArrayIsArray, + DateNow, + ObjectEntries, + String, +} = primordials; + +let dc; +let Network; + +let requestId = 0; +const getNextRequestId = () => `node-network-event-${++requestId}`; + +// Convert a Headers object (Map) to a plain object (Map) +const headerObjectToDictionary = (headers = {}) => { + const dict = {}; + for (const { 0: key, 1: value } of ObjectEntries(headers)) { + if (typeof value === 'string') { + dict[key] = value; + } else if (ArrayIsArray(value)) { + if (key.toLowerCase() === 'cookie') dict[key] = value.join('; '); + // ChromeDevTools frontend treats 'set-cookie' as a special case + // https://github.com/ChromeDevTools/devtools-frontend/blob/4275917f84266ef40613db3c1784a25f902ea74e/front_end/core/sdk/NetworkRequest.ts#L1368 + else if (key.toLowerCase() === 'set-cookie') dict[key] = value.join('\n'); + else dict[key] = value.join(', '); + } else { + dict[key] = String(value); + } + } + return dict; +}; + +function onClientRequestStart({ request }) { + const url = `${request.protocol}//${request.host}${request.path}`; + const wallTime = DateNow(); + const timestamp = wallTime / 1000; + request._inspectorRequestId = getNextRequestId(); + Network.requestWillBeSent({ + requestId: request._inspectorRequestId, + timestamp, + wallTime, + request: { + url, + method: request.method, + headers: headerObjectToDictionary(request.getHeaders()), + }, + }); +} + +function onClientRequestError({ request, error }) { + if (typeof request._inspectorRequestId !== 'string') { + return; + } + const timestamp = DateNow() / 1000; + Network.loadingFailed({ + requestId: request._inspectorRequestId, + timestamp, + type: 'Other', + errorText: error.message, + }); +} + +function onClientResponseFinish({ request, response }) { + if (typeof request._inspectorRequestId !== 'string') { + return; + } + const url = `${request.protocol}//${request.host}${request.path}`; + const timestamp = DateNow() / 1000; + Network.responseReceived({ + requestId: request._inspectorRequestId, + timestamp, + type: 'Other', + response: { + url, + status: response.statusCode, + statusText: response.statusMessage ?? '', + headers: headerObjectToDictionary(response.headers), + }, + }); + Network.loadingFinished({ + requestId: request._inspectorRequestId, + timestamp, + }); +} + +function enable() { + if (!dc) { + dc = require('diagnostics_channel'); + } + if (!Network) { + Network = require('inspector').Network; + } + dc.subscribe('http.client.request.start', onClientRequestStart); + dc.subscribe('http.client.request.error', onClientRequestError); + dc.subscribe('http.client.response.finish', onClientResponseFinish); +} + +function disable() { + dc.unsubscribe('http.client.request.start', onClientRequestStart); + dc.unsubscribe('http.client.request.error', onClientRequestError); + dc.unsubscribe('http.client.response.finish', onClientResponseFinish); +} + +module.exports = { + enable, + disable, +}; diff --git a/lib/internal/modules/esm/get_format.js b/lib/internal/modules/esm/get_format.js index 1931688e85d..1fe5564545d 100644 --- a/lib/internal/modules/esm/get_format.js +++ b/lib/internal/modules/esm/get_format.js @@ -5,6 +5,7 @@ const { ObjectPrototypeHasOwnProperty, PromisePrototypeThen, PromiseResolve, + SafeSet, StringPrototypeIncludes, StringPrototypeCharCodeAt, StringPrototypeSlice, @@ -19,7 +20,7 @@ const { const experimentalNetworkImports = getOptionValue('--experimental-network-imports'); const { containsModuleSyntax } = internalBinding('contextify'); -const { getPackageType } = require('internal/modules/esm/resolve'); +const { getPackageScopeConfig, getPackageType } = require('internal/modules/esm/resolve'); const { fileURLToPath } = require('internal/url'); const { ERR_UNKNOWN_FILE_EXTENSION } = require('internal/errors').codes; @@ -81,6 +82,7 @@ function underNodeModules(url) { return StringPrototypeIncludes(url.pathname, '/node_modules/'); } +let typelessPackageJsonFilesWarnedAbout; /** * @param {URL} url * @param {{parentURL: string; source?: Buffer}} context @@ -92,7 +94,7 @@ function getFileProtocolModuleFormat(url, context = { __proto__: null }, ignoreE const ext = extname(url); if (ext === '.js') { - const packageType = getPackageType(url); + const { type: packageType, pjsonPath } = getPackageScopeConfig(url); if (packageType !== 'none') { return packageType; } @@ -111,9 +113,23 @@ function getFileProtocolModuleFormat(url, context = { __proto__: null }, ignoreE // `source` is undefined when this is called from `defaultResolve`; // but this gets called again from `defaultLoad`/`defaultLoadSync`. if (getOptionValue('--experimental-detect-module')) { - return source ? + const format = source ? (containsModuleSyntax(`${source}`, fileURLToPath(url)) ? 'module' : 'commonjs') : null; + if (format === 'module') { + // This module has a .js extension, a package.json with no `type` field, and ESM syntax. + // Warn about the missing `type` field so that the user can avoid the performance penalty of detection. + typelessPackageJsonFilesWarnedAbout ??= new SafeSet(); + if (!typelessPackageJsonFilesWarnedAbout.has(pjsonPath)) { + const warning = `${url} parsed as an ES module because module syntax was detected;` + + ` to avoid the performance penalty of syntax detection, add "type": "module" to ${pjsonPath}`; + process.emitWarning(warning, { + code: 'MODULE_TYPELESS_PACKAGE_JSON', + }); + typelessPackageJsonFilesWarnedAbout.add(pjsonPath); + } + } + return format; } return 'commonjs'; } diff --git a/lib/internal/modules/esm/hooks.js b/lib/internal/modules/esm/hooks.js index a4ff342e645..aca37333581 100644 --- a/lib/internal/modules/esm/hooks.js +++ b/lib/internal/modules/esm/hooks.js @@ -160,13 +160,15 @@ class Hooks { * @param {any} [data] Arbitrary data to be passed from the custom * loader (user-land) to the worker. */ - async register(urlOrSpecifier, parentURL, data) { + async register(urlOrSpecifier, parentURL, data, isInternal) { const cascadedLoader = require('internal/modules/esm/loader').getOrInitializeCascadedLoader(); - const keyedExports = await cascadedLoader.import( - urlOrSpecifier, - parentURL, - kEmptyObject, - ); + const keyedExports = isInternal ? + require(urlOrSpecifier) : + await cascadedLoader.import( + urlOrSpecifier, + parentURL, + kEmptyObject, + ); await this.addCustomLoader(urlOrSpecifier, keyedExports, data); } diff --git a/lib/internal/modules/esm/loader.js b/lib/internal/modules/esm/loader.js index 4b88ed67703..9c7a52019ce 100644 --- a/lib/internal/modules/esm/loader.js +++ b/lib/internal/modules/esm/loader.js @@ -477,7 +477,7 @@ class ModuleLoader { /** * @see {@link CustomizedModuleLoader.register} */ - register(specifier, parentURL, data, transferList) { + register(specifier, parentURL, data, transferList, isInternal) { if (!this.#customizations) { // `CustomizedModuleLoader` is defined at the bottom of this file and // available well before this line is ever invoked. This is here in @@ -485,7 +485,7 @@ class ModuleLoader { // eslint-disable-next-line no-use-before-define this.setCustomizations(new CustomizedModuleLoader()); } - return this.#customizations.register(`${specifier}`, `${parentURL}`, data, transferList); + return this.#customizations.register(`${specifier}`, `${parentURL}`, data, transferList, isInternal); } /** @@ -498,6 +498,7 @@ class ModuleLoader { * @returns {{ format: string, url: URL['href'] }} */ resolve(originalSpecifier, parentURL, importAttributes) { + originalSpecifier = `${originalSpecifier}`; if (this.#customizations) { return this.#customizations.resolve(originalSpecifier, parentURL, importAttributes); } @@ -516,6 +517,7 @@ class ModuleLoader { * `import.meta.resolve` which must happen synchronously. */ resolveSync(originalSpecifier, parentURL, importAttributes) { + originalSpecifier = `${originalSpecifier}`; if (this.#customizations) { return this.#customizations.resolveSync(originalSpecifier, parentURL, importAttributes); } @@ -617,10 +619,11 @@ class CustomizedModuleLoader { * @param {any} [data] Arbitrary data to be passed from the custom loader * (user-land) to the worker. * @param {any[]} [transferList] Objects in `data` that are changing ownership + * @param {boolean} [isInternal] For internal loaders that should not be publicly exposed. * @returns {{ format: string, url: URL['href'] }} */ - register(originalSpecifier, parentURL, data, transferList) { - return hooksProxy.makeSyncRequest('register', transferList, originalSpecifier, parentURL, data); + register(originalSpecifier, parentURL, data, transferList, isInternal) { + return hooksProxy.makeSyncRequest('register', transferList, originalSpecifier, parentURL, data, isInternal); } /** diff --git a/lib/internal/per_context/primordials.js b/lib/internal/per_context/primordials.js index 551094d3219..bba0343b064 100644 --- a/lib/internal/per_context/primordials.js +++ b/lib/internal/per_context/primordials.js @@ -461,7 +461,7 @@ const SafePromise = makeSafe( * rejected). The resolved value cannot be modified from the callback. * Prefer using async functions when possible. * @param {Promise} thisPromise - * @param {() => void) | undefined | null} onFinally The callback to execute + * @param {(() => void) | undefined | null} onFinally The callback to execute * when the Promise is settled (fulfilled or rejected). * @returns {Promise} A Promise for the completion of the callback. */ diff --git a/lib/internal/perf/nodetiming.js b/lib/internal/perf/nodetiming.js index 11f877e5d81..d19bc021263 100644 --- a/lib/internal/perf/nodetiming.js +++ b/lib/internal/perf/nodetiming.js @@ -28,6 +28,7 @@ const { NODE_PERFORMANCE_MILESTONE_ENVIRONMENT, }, loopIdleTime, + uvMetricsInfo, } = internalBinding('performance'); class PerformanceNodeTiming { @@ -122,6 +123,13 @@ class PerformanceNodeTiming { configurable: true, get: loopIdleTime, }, + + uvMetricsInfo: { + __proto__: null, + enumerable: true, + configurable: true, + get: uvMetricsInfo, + }, }); } diff --git a/lib/internal/process/permission.js b/lib/internal/process/permission.js index f0d5f2b180b..7a6dd80d1d0 100644 --- a/lib/internal/process/permission.js +++ b/lib/internal/process/permission.js @@ -5,7 +5,9 @@ const { } = primordials; const permission = internalBinding('permission'); -const { validateString } = require('internal/validators'); +const { validateString, validateBuffer } = require('internal/validators'); +const { Buffer } = require('buffer'); +const { isBuffer } = Buffer; let experimentalPermission; @@ -22,7 +24,11 @@ module.exports = ObjectFreeze({ validateString(scope, 'scope'); if (reference != null) { // TODO: add support for WHATWG URLs and Uint8Arrays. - validateString(reference, 'reference'); + if (isBuffer(reference)) { + validateBuffer(reference, 'reference'); + } else { + validateString(reference, 'reference'); + } } return permission.has(scope, reference); diff --git a/lib/internal/process/pre_execution.js b/lib/internal/process/pre_execution.js index 7c6f696d471..6aff996e771 100644 --- a/lib/internal/process/pre_execution.js +++ b/lib/internal/process/pre_execution.js @@ -113,10 +113,12 @@ function prepareExecution(options) { const mainEntry = patchProcessObject(expandArgv1); setupTraceCategoryState(); setupInspectorHooks(); + setupNetworkInspection(); setupWarningHandler(); setupUndici(); setupWebCrypto(); setupCustomEvent(); + setupEventsource(); setupCodeCoverage(); setupDebugEnv(); // Process initial diagnostic reporting configuration, if present. @@ -341,6 +343,13 @@ function setupUndici() { } } +// https://html.spec.whatwg.org/multipage/server-sent-events.html +function setupEventsource() { + if (!getOptionValue('--experimental-eventsource')) { + delete globalThis.EventSource; + } +} + // TODO(aduh95): move this to internal/bootstrap/web/* when the CLI flag is // removed. function setupWebCrypto() { @@ -483,6 +492,16 @@ function setupInspectorHooks() { } } +function setupNetworkInspection() { + if (internalBinding('config').hasInspector && getOptionValue('--experimental-network-inspection')) { + const { + enable, + disable, + } = require('internal/inspector_network_tracking'); + internalBinding('inspector').setupNetworkTracking(enable, disable); + } +} + // In general deprecations are initialized wherever the APIs are implemented, // this is used to deprecate APIs implemented in C++ where the deprecation // utilities are not easily accessible. diff --git a/lib/internal/streams/compose.js b/lib/internal/streams/compose.js index 1b04a0f70a1..276ae627607 100644 --- a/lib/internal/streams/compose.js +++ b/lib/internal/streams/compose.js @@ -1,5 +1,9 @@ 'use strict'; +const { + ArrayPrototypeSlice, +} = primordials; + const { pipeline } = require('internal/streams/pipeline'); const Duplex = require('internal/streams/duplex'); const { destroyer } = require('internal/streams/destroy'); @@ -30,7 +34,7 @@ module.exports = function compose(...streams) { return Duplex.from(streams[0]); } - const orgStreams = [...streams]; + const orgStreams = ArrayPrototypeSlice(streams); if (typeof streams[0] === 'function') { streams[0] = Duplex.from(streams[0]); diff --git a/lib/internal/streams/end-of-stream.js b/lib/internal/streams/end-of-stream.js index 31b8dfca58c..c1403f419c5 100644 --- a/lib/internal/streams/end-of-stream.js +++ b/lib/internal/streams/end-of-stream.js @@ -215,7 +215,7 @@ function eos(stream, options, callback) { !readable && (!willEmitClose || isReadable(stream)) && (writableFinished || isWritable(stream) === false) && - (wState == null || wState.pendingcb === 0) + (wState == null || wState.pendingcb === undefined || wState.pendingcb === 0) ) { process.nextTick(onclosed); } else if ( diff --git a/lib/internal/streams/readable.js b/lib/internal/streams/readable.js index ff07a2fd89a..b97c54bee3e 100644 --- a/lib/internal/streams/readable.js +++ b/lib/internal/streams/readable.js @@ -258,7 +258,7 @@ ObjectDefineProperties(ReadableState.prototype, { function ReadableState(options, stream, isDuplex) { - // Bit map field to store ReadableState more effciently with 1 bit per field + // Bit map field to store ReadableState more efficiently with 1 bit per field // instead of a V8 slot per field. this[kState] = kEmitClose | kAutoDestroy | kConstructed | kSync; diff --git a/lib/internal/streams/transform.js b/lib/internal/streams/transform.js index 42e1adda618..2f4d498bc78 100644 --- a/lib/internal/streams/transform.js +++ b/lib/internal/streams/transform.js @@ -180,7 +180,7 @@ Transform.prototype._write = function(chunk, encoding, callback) { if (rState.ended) { // If user has called this.push(null) we have to - // delay the callback to properly progate the new + // delay the callback to properly propagate the new // state. process.nextTick(callback); } else if ( diff --git a/lib/internal/streams/utils.js b/lib/internal/streams/utils.js index 2c6b841a89e..88c0ca87bc6 100644 --- a/lib/internal/streams/utils.js +++ b/lib/internal/streams/utils.js @@ -8,7 +8,7 @@ const { } = primordials; // We need to use SymbolFor to make these globally available -// for interopt with readable-stream, i.e. readable-stream +// for interoperability with readable-stream, i.e. readable-stream // and node core needs to be able to read/write private state // from each other for proper interoperability. const kIsDestroyed = SymbolFor('nodejs.stream.destroyed'); diff --git a/lib/internal/streams/writable.js b/lib/internal/streams/writable.js index 16e49cb5951..103b9eaa72f 100644 --- a/lib/internal/streams/writable.js +++ b/lib/internal/streams/writable.js @@ -300,7 +300,7 @@ ObjectDefineProperties(WritableState.prototype, { }); function WritableState(options, stream, isDuplex) { - // Bit map field to store WritableState more effciently with 1 bit per field + // Bit map field to store WritableState more efficiently with 1 bit per field // instead of a V8 slot per field. this[kState] = kSync | kConstructed | kEmitClose | kAutoDestroy; diff --git a/lib/internal/test_runner/coverage.js b/lib/internal/test_runner/coverage.js index 81a06182929..385a52fb34f 100644 --- a/lib/internal/test_runner/coverage.js +++ b/lib/internal/test_runner/coverage.js @@ -23,6 +23,7 @@ const { mkdtempSync, opendirSync, readFileSync, + rmSync, } = require('fs'); const { setupCoverageHooks } = require('internal/util'); const { tmpdir } = require('os'); @@ -270,28 +271,35 @@ class TestCoverage { cleanup() { // Restore the original value of process.env.NODE_V8_COVERAGE. Then, copy // all of the created coverage files to the original coverage directory. + internalBinding('profiler').endCoverage(); + if (this.originalCoverageDirectory === undefined) { delete process.env.NODE_V8_COVERAGE; - return; - } - - process.env.NODE_V8_COVERAGE = this.originalCoverageDirectory; - let dir; + } else { + process.env.NODE_V8_COVERAGE = this.originalCoverageDirectory; + let dir; - try { - mkdirSync(this.originalCoverageDirectory, { __proto__: null, recursive: true }); - dir = opendirSync(this.coverageDirectory); + try { + mkdirSync(this.originalCoverageDirectory, { __proto__: null, recursive: true }); + dir = opendirSync(this.coverageDirectory); - for (let entry; (entry = dir.readSync()) !== null;) { - const src = join(this.coverageDirectory, entry.name); - const dst = join(this.originalCoverageDirectory, entry.name); - copyFileSync(src, dst); - } - } finally { - if (dir) { - dir.closeSync(); + for (let entry; (entry = dir.readSync()) !== null;) { + const src = join(this.coverageDirectory, entry.name); + const dst = join(this.originalCoverageDirectory, entry.name); + copyFileSync(src, dst); + } + } finally { + if (dir) { + dir.closeSync(); + } } } + + try { + rmSync(this.coverageDirectory, { __proto__: null, recursive: true }); + } catch { + // Ignore cleanup errors. + } } getCoverageFromDirectory() { diff --git a/lib/internal/test_runner/harness.js b/lib/internal/test_runner/harness.js index c7d951d6b48..d67bcf7cd2b 100644 --- a/lib/internal/test_runner/harness.js +++ b/lib/internal/test_runner/harness.js @@ -113,12 +113,15 @@ function collectCoverage(rootTest, coverage) { try { summary = coverage.summary(); - coverage.cleanup(); } catch (err) { - const op = summary ? 'clean up' : 'report'; - const msg = `Warning: Could not ${op} code coverage. ${err}`; + rootTest.diagnostic(`Warning: Could not report code coverage. ${err}`); + process.exitCode = kGenericUserError; + } - rootTest.diagnostic(msg); + try { + coverage.cleanup(); + } catch (err) { + rootTest.diagnostic(`Warning: Could not clean up code coverage. ${err}`); process.exitCode = kGenericUserError; } diff --git a/lib/internal/test_runner/mock/loader.js b/lib/internal/test_runner/mock/loader.js new file mode 100644 index 00000000000..a434248bcce --- /dev/null +++ b/lib/internal/test_runner/mock/loader.js @@ -0,0 +1,233 @@ +'use strict'; +const { + JSONStringify, + SafeMap, + globalThis: { + Atomics: { + notify: AtomicsNotify, + store: AtomicsStore, + }, + }, +} = primordials; +const { + ensureNodeScheme, + kBadExportsMessage, + kMockSearchParam, + kMockSuccess, + kMockExists, + kMockUnknownMessage, +} = require('internal/test_runner/mock/mock'); +const { pathToFileURL, URL } = require('internal/url'); +const { normalizeReferrerURL } = require('internal/modules/helpers'); +let debug = require('internal/util/debuglog').debuglog('test_runner', (fn) => { + debug = fn; +}); +const { createRequire, isBuiltin } = require('module'); +const { defaultGetFormatWithoutErrors } = require('internal/modules/esm/get_format'); +const { defaultResolve } = require('internal/modules/esm/resolve'); + +// TODO(cjihrig): The mocks need to be thread aware because the exports are +// evaluated on the thread that creates the mock. Before marking this API as +// stable, one of the following issues needs to be implemented: +// https://github.com/nodejs/node/issues/49472 +// or https://github.com/nodejs/node/issues/52219 + +const mocks = new SafeMap(); + +async function initialize(data) { + data?.port.on('message', ({ type, payload }) => { + debug('mock loader received message type "%s" with payload %o', type, payload); + + if (type === 'node:test:register') { + const { baseURL } = payload; + const mock = mocks.get(baseURL); + + if (mock?.active) { + debug('already mocking "%s"', baseURL); + sendAck(payload.ack, kMockExists); + return; + } + + const localVersion = mock?.localVersion ?? 0; + + debug('new mock version %d for "%s"', localVersion, baseURL); + mocks.set(baseURL, { + __proto__: null, + active: true, + cache: payload.cache, + exportNames: payload.exportNames, + format: payload.format, + hasDefaultExport: payload.hasDefaultExport, + localVersion, + url: baseURL, + }); + sendAck(payload.ack); + } else if (type === 'node:test:unregister') { + const mock = mocks.get(payload.baseURL); + + if (mock !== undefined) { + mock.active = false; + mock.localVersion++; + } + + sendAck(payload.ack); + } else { + sendAck(payload.ack, kMockUnknownMessage); + } + }); +} + +async function resolve(specifier, context, nextResolve) { + debug('resolve hook entry, specifier = "%s", context = %o', specifier, context); + let mockSpecifier; + + if (isBuiltin(specifier)) { + mockSpecifier = ensureNodeScheme(specifier); + } else { + let format; + + if (context.parentURL) { + format = defaultGetFormatWithoutErrors(pathToFileURL(context.parentURL)); + } + + try { + if (format === 'module') { + specifier = defaultResolve(specifier, context).url; + } else { + specifier = pathToFileURL( + createRequire(context.parentURL).resolve(specifier), + ).href; + } + } catch { + const parentURL = normalizeReferrerURL(context.parentURL); + const parsedURL = URL.parse(specifier, parentURL)?.href; + + if (parsedURL) { + specifier = parsedURL; + } + } + + mockSpecifier = specifier; + } + + const mock = mocks.get(mockSpecifier); + debug('resolve hook, specifier = "%s", mock = %o', specifier, mock); + + if (mock?.active !== true) { + return nextResolve(specifier, context); + } + + const url = new URL(mockSpecifier); + + url.searchParams.set(kMockSearchParam, mock.localVersion); + + if (!mock.cache) { + // With ESM, we can't remove modules from the cache. Bump the module's + // version instead so that the next import will be uncached. + mock.localVersion++; + } + + debug('resolve hook finished, url = "%s"', url.href); + return nextResolve(url.href, context); +} + +async function load(url, context, nextLoad) { + debug('load hook entry, url = "%s", context = %o', url, context); + const parsedURL = URL.parse(url); + if (parsedURL) { + parsedURL.searchParams.delete(kMockSearchParam); + } + + const baseURL = parsedURL ? parsedURL.href : url; + const mock = mocks.get(baseURL); + + const original = await nextLoad(url, context); + debug('load hook, mock = %o', mock); + if (mock?.active !== true) { + return original; + } + + // Treat builtins as commonjs because customization hooks do not allow a + // core module to be replaced. + // Also collapse 'commonjs-sync' and 'require-commonjs' to 'commonjs'. + const format = ( + original.format === 'builtin' || + original.format === 'commonjs-sync' || + original.format === 'require-commonjs') ? 'commonjs' : original.format; + + const result = { + __proto__: null, + format, + shortCircuit: true, + source: await createSourceFromMock(mock, format), + }; + + debug('load hook finished, result = %o', result); + return result; +} + +async function createSourceFromMock(mock, format) { + // Create mock implementation from provided exports. + const { exportNames, hasDefaultExport, url } = mock; + const useESM = format === 'module'; + const source = `${testImportSource(useESM)} +if (!$__test.mock._mockExports.has('${url}')) { + throw new Error(${JSONStringify(`mock exports not found for "${url}"`)}); +} + +const $__exports = $__test.mock._mockExports.get(${JSONStringify(url)}); +${defaultExportSource(useESM, hasDefaultExport)} +${namedExportsSource(useESM, exportNames)} +`; + + return source; +} + +function testImportSource(useESM) { + if (useESM) { + return "import $__test from 'node:test';"; + } + + return "const $__test = require('node:test');"; +} + +function defaultExportSource(useESM, hasDefaultExport) { + if (!hasDefaultExport) { + return ''; + } else if (useESM) { + return 'export default $__exports.defaultExport;'; + } + + return 'module.exports = $__exports.defaultExport;'; +} + +function namedExportsSource(useESM, exportNames) { + let source = ''; + + if (!useESM && exportNames.length > 0) { + source += ` +if (module.exports === null || typeof module.exports !== 'object') { + throw new Error('${JSONStringify(kBadExportsMessage)}'); +} +`; + } + + for (let i = 0; i < exportNames.length; ++i) { + const name = exportNames[i]; + + if (useESM) { + source += `export let ${name} = $__exports.namedExports[${JSONStringify(name)}];\n`; + } else { + source += `module.exports[${JSONStringify(name)}] = $__exports.namedExports[${JSONStringify(name)}];\n`; + } + } + + return source; +} + +function sendAck(buf, status = kMockSuccess) { + AtomicsStore(buf, 0, status); + AtomicsNotify(buf, 0); +} + +module.exports = { initialize, load, resolve }; diff --git a/lib/internal/test_runner/mock/mock.js b/lib/internal/test_runner/mock/mock.js index 838a530ddd4..828f3e513f8 100644 --- a/lib/internal/test_runner/mock/mock.js +++ b/lib/internal/test_runner/mock/mock.js @@ -3,32 +3,70 @@ const { ArrayPrototypePush, ArrayPrototypeSlice, Error, + FunctionPrototypeBind, FunctionPrototypeCall, + Int32Array, ObjectDefineProperty, ObjectGetOwnPropertyDescriptor, ObjectGetPrototypeOf, + ObjectKeys, Proxy, ReflectApply, ReflectConstruct, ReflectGet, SafeMap, + StringPrototypeSlice, + StringPrototypeStartsWith, + globalThis: { + Atomics: { + store: AtomicsStore, + wait: AtomicsWait, + }, + SharedArrayBuffer, + }, } = primordials; const { codes: { ERR_INVALID_ARG_TYPE, ERR_INVALID_ARG_VALUE, + ERR_INVALID_STATE, }, } = require('internal/errors'); -const { kEmptyObject } = require('internal/util'); +const esmLoader = require('internal/modules/esm/loader'); +const { getOptionValue } = require('internal/options'); +const { fileURLToPath, toPathIfFileURL, URL } = require('internal/url'); +const { + emitExperimentalWarning, + getStructuredStack, + kEmptyObject, +} = require('internal/util'); +let debug = require('internal/util/debuglog').debuglog('test_runner', (fn) => { + debug = fn; +}); const { validateBoolean, validateFunction, validateInteger, validateObject, + validateOneOf, + validateString, } = require('internal/validators'); const { MockTimers } = require('internal/test_runner/mock/mock_timers'); - +const { strictEqual, notStrictEqual } = require('assert'); +const { Module } = require('internal/modules/cjs/loader'); +const { MessageChannel } = require('worker_threads'); +const { _load, _nodeModulePaths, _resolveFilename, isBuiltin } = Module; function kDefaultFunction() {} +const enableModuleMocking = getOptionValue('--experimental-test-module-mocks'); +const kMockSearchParam = 'node-test-mock'; +const kMockSuccess = 1; +const kMockExists = 2; +const kMockUnknownMessage = 3; +const kWaitTimeout = 5_000; +const kBadExportsMessage = 'Cannot create mock because named exports ' + + 'cannot be applied to the provided default export.'; +const kSupportedFormats = ['builtin', 'commonjs', 'module']; +let sharedModuleState; class MockFunctionContext { #calls; @@ -132,10 +170,108 @@ class MockFunctionContext { } } -const { nextImpl, restore, trackCall } = MockFunctionContext.prototype; +const { + nextImpl, + restore: restoreFn, + trackCall, +} = MockFunctionContext.prototype; delete MockFunctionContext.prototype.trackCall; delete MockFunctionContext.prototype.nextImpl; +class MockModuleContext { + #restore; + #sharedState; + + constructor({ + baseURL, + cache, + caller, + defaultExport, + format, + fullPath, + hasDefaultExport, + namedExports, + sharedState, + }) { + const ack = new Int32Array(new SharedArrayBuffer(4)); + const config = { + __proto__: null, + cache, + defaultExport, + hasDefaultExport, + namedExports, + caller: toPathIfFileURL(caller), + }; + + sharedState.mockMap.set(baseURL, config); + sharedState.mockMap.set(fullPath, config); + + this.#sharedState = sharedState; + this.#restore = { + __proto__: null, + ack, + baseURL, + cached: fullPath in Module._cache, + format, + fullPath, + value: Module._cache[fullPath], + }; + + sharedState.loaderPort.postMessage({ + __proto__: null, + type: 'node:test:register', + payload: { + __proto__: null, + ack, + baseURL, + cache, + exportNames: ObjectKeys(namedExports), + hasDefaultExport, + format, + }, + }); + waitForAck(ack); + delete Module._cache[fullPath]; + sharedState.mockExports.set(baseURL, { + __proto__: null, + defaultExport, + namedExports, + }); + } + + restore() { + if (this.#restore === undefined) { + return; + } + + // Delete the mock CJS cache entry. If the module was previously in the + // cache then restore the old value. + delete Module._cache[this.#restore.fullPath]; + + if (this.#restore.cached) { + Module._cache[this.#restore.fullPath] = this.#restore.value; + } + + AtomicsStore(this.#restore.ack, 0, 0); + this.#sharedState.loaderPort.postMessage({ + __proto__: null, + type: 'node:test:unregister', + payload: { + __proto__: null, + ack: this.#restore.ack, + baseURL: this.#restore.baseURL, + }, + }); + waitForAck(this.#restore.ack); + + this.#sharedState.mockMap.delete(this.#restore.baseURL); + this.#sharedState.mockMap.delete(this.#restore.fullPath); + this.#restore = undefined; + } +} + +const { restore: restoreModule } = MockModuleContext.prototype; + class MockTracker { #mocks = []; #timers; @@ -350,6 +486,74 @@ class MockTracker { }); } + module(specifier, options = kEmptyObject) { + emitExperimentalWarning('Module mocking'); + validateString(specifier, 'specifier'); + validateObject(options, 'options'); + debug('module mock entry, specifier = "%s", options = %o', specifier, options); + + const { + cache = false, + namedExports = kEmptyObject, + defaultExport, + } = options; + const hasDefaultExport = 'defaultExport' in options; + + validateBoolean(cache, 'options.cache'); + validateObject(namedExports, 'options.namedExports'); + + const sharedState = setupSharedModuleState(); + const mockSpecifier = StringPrototypeStartsWith(specifier, 'node:') ? + StringPrototypeSlice(specifier, 5) : specifier; + + // Get the file that called this function. We need four stack frames: + // vm context -> getStructuredStack() -> this function -> actual caller. + const caller = getStructuredStack()[3]?.getFileName(); + const { format, url } = sharedState.moduleLoader.resolveSync( + mockSpecifier, caller, null, + ); + debug('module mock, url = "%s", format = "%s", caller = "%s"', url, format, caller); + if (format) { // Format is not yet known for ambiguous files when detection is enabled. + validateOneOf(format, 'format', kSupportedFormats); + } + const baseURL = URL.parse(url); + + if (!baseURL) { + throw new ERR_INVALID_ARG_VALUE( + 'specifier', specifier, 'cannot compute URL', + ); + } + + if (baseURL.searchParams.has(kMockSearchParam)) { + throw new ERR_INVALID_STATE( + `Cannot mock '${specifier}.' The module is already mocked.`, + ); + } + + const fullPath = StringPrototypeStartsWith(url, 'file://') ? + fileURLToPath(url) : null; + const ctx = new MockModuleContext({ + __proto__: null, + baseURL: baseURL.href, + cache, + caller, + defaultExport, + format, + fullPath, + hasDefaultExport, + namedExports, + sharedState, + specifier: mockSpecifier, + }); + + ArrayPrototypePush(this.#mocks, { + __proto__: null, + ctx, + restore: restoreModule, + }); + return ctx; + } + /** * Resets the mock tracker, restoring all mocks and clearing timers. */ @@ -364,7 +568,9 @@ class MockTracker { */ restoreAll() { for (let i = 0; i < this.#mocks.length; i++) { - FunctionPrototypeCall(restore, this.#mocks[i]); + const { ctx, restore } = this.#mocks[i]; + + FunctionPrototypeCall(restore, ctx); } } @@ -430,11 +636,101 @@ class MockTracker { }, }); - ArrayPrototypePush(this.#mocks, ctx); + ArrayPrototypePush(this.#mocks, { + __proto__: null, + ctx, + restore: restoreFn, + }); return mock; } } +function setupSharedModuleState() { + if (sharedModuleState === undefined) { + const { mock } = require('test'); + const mockExports = new SafeMap(); + const { port1, port2 } = new MessageChannel(); + const moduleLoader = esmLoader.getOrInitializeCascadedLoader(); + + moduleLoader.register( + 'internal/test_runner/mock/loader', + 'node:', + { __proto__: null, port: port2 }, + [port2], + true, + ); + + sharedModuleState = { + __proto__: null, + loaderPort: port1, + mockExports, + mockMap: new SafeMap(), + moduleLoader, + }; + mock._mockExports = mockExports; + Module._load = FunctionPrototypeBind(cjsMockModuleLoad, sharedModuleState); + } + + return sharedModuleState; +} + +function cjsMockModuleLoad(request, parent, isMain) { + let resolved; + + if (isBuiltin(request)) { + resolved = ensureNodeScheme(request); + } else { + resolved = _resolveFilename(request, parent, isMain); + } + + const config = this.mockMap.get(resolved); + if (config === undefined) { + return _load(request, parent, isMain); + } + + const { + cache, + caller, + defaultExport, + hasDefaultExport, + namedExports, + } = config; + + if (cache && Module._cache[resolved]) { + // The CJS cache entry is deleted when the mock is configured. If it has + // been repopulated, return the exports from that entry. + return Module._cache[resolved].exports; + } + + // eslint-disable-next-line node-core/set-proto-to-null-in-object + const modExports = hasDefaultExport ? defaultExport : {}; + const exportNames = ObjectKeys(namedExports); + + if ((typeof modExports !== 'object' || modExports === null) && + exportNames.length > 0) { + // eslint-disable-next-line no-restricted-syntax + throw new Error(kBadExportsMessage); + } + + for (let i = 0; i < exportNames.length; ++i) { + const name = exportNames[i]; + const descriptor = ObjectGetOwnPropertyDescriptor(namedExports, name); + ObjectDefineProperty(modExports, name, descriptor); + } + + if (cache) { + const entry = new Module(resolved, caller); + + entry.exports = modExports; + entry.filename = resolved; + entry.loaded = true; + entry.paths = _nodeModulePaths(entry.path); + Module._cache[resolved] = entry; + } + + return modExports; +} + function validateStringOrSymbol(value, name) { if (typeof value !== 'string' && typeof value !== 'symbol') { throw new ERR_INVALID_ARG_TYPE(name, ['string', 'symbol'], value); @@ -466,4 +762,31 @@ function findMethodOnPrototypeChain(instance, methodName) { return descriptor; } -module.exports = { MockTracker }; +function waitForAck(buf) { + const result = AtomicsWait(buf, 0, 0, kWaitTimeout); + + notStrictEqual(result, 'timed-out', 'test mocking synchronization failed'); + strictEqual(buf[0], kMockSuccess); +} + +function ensureNodeScheme(specifier) { + if (!StringPrototypeStartsWith(specifier, 'node:')) { + return `node:${specifier}`; + } + + return specifier; +} + +if (!enableModuleMocking) { + delete MockTracker.prototype.module; +} + +module.exports = { + ensureNodeScheme, + kBadExportsMessage, + kMockSearchParam, + kMockSuccess, + kMockExists, + kMockUnknownMessage, + MockTracker, +}; diff --git a/lib/internal/test_runner/mock/mock_timers.js b/lib/internal/test_runner/mock/mock_timers.js index 2250d76ca5d..1edef54bf3d 100644 --- a/lib/internal/test_runner/mock/mock_timers.js +++ b/lib/internal/test_runner/mock/mock_timers.js @@ -26,8 +26,8 @@ const { } = primordials; const { validateAbortSignal, - validateArray, validateNumber, + validateStringArray, } = require('internal/validators'); const { @@ -673,7 +673,7 @@ class MockTimers { */ /** * Enables the MockTimers replacing the native timers with the fake ones. - * @param {EnableOptions} options + * @param {EnableOptions} [options] */ enable(options = { __proto__: null, apis: SUPPORTED_APIS, now: 0 }) { const internalOptions = { __proto__: null, ...options }; @@ -693,7 +693,7 @@ class MockTimers { internalOptions.apis = SUPPORTED_APIS; } - validateArray(internalOptions.apis, 'options.apis'); + validateStringArray(internalOptions.apis, 'options.apis'); // Check that the timers passed are supported ArrayPrototypeForEach(internalOptions.apis, (timer) => { if (!ArrayPrototypeIncludes(SUPPORTED_APIS, timer)) { diff --git a/lib/internal/test_runner/reporter/dot.js b/lib/internal/test_runner/reporter/dot.js index 496c819d69e..1e581f7a337 100644 --- a/lib/internal/test_runner/reporter/dot.js +++ b/lib/internal/test_runner/reporter/dot.js @@ -1,15 +1,22 @@ 'use strict'; -const { MathMax } = primordials; +const { + ArrayPrototypePush, + MathMax, +} = primordials; +const colors = require('internal/util/colors'); +const { formatTestReport } = require('internal/test_runner/reporter/utils'); module.exports = async function* dot(source) { let count = 0; let columns = getLineLength(); - for await (const { type } of source) { + const failedTests = []; + for await (const { type, data } of source) { if (type === 'test:pass') { - yield '.'; + yield `${colors.green}.${colors.clear}`; } if (type === 'test:fail') { - yield 'X'; + yield `${colors.red}X${colors.clear}`; + ArrayPrototypePush(failedTests, data); } if ((type === 'test:fail' || type === 'test:pass') && ++count === columns) { yield '\n'; @@ -20,6 +27,12 @@ module.exports = async function* dot(source) { } } yield '\n'; + if (failedTests.length > 0) { + yield `\n${colors.red}Failed tests:${colors.white}\n\n`; + for (const test of failedTests) { + yield formatTestReport('test:fail', test); + } + } }; function getLineLength() { diff --git a/lib/internal/test_runner/reporter/spec.js b/lib/internal/test_runner/reporter/spec.js index fd4313ae19b..2092d22e3fe 100644 --- a/lib/internal/test_runner/reporter/spec.js +++ b/lib/internal/test_runner/reporter/spec.js @@ -1,97 +1,35 @@ 'use strict'; - const { ArrayPrototypeJoin, ArrayPrototypePop, ArrayPrototypePush, ArrayPrototypeShift, ArrayPrototypeUnshift, - hardenRegExp, - RegExpPrototypeSymbolSplit, - SafeMap, - StringPrototypeRepeat, } = primordials; const assert = require('assert'); const Transform = require('internal/streams/transform'); -const { inspectWithNoCustomRetry } = require('internal/errors'); const colors = require('internal/util/colors'); const { kSubtestsFailed } = require('internal/test_runner/test'); const { getCoverageReport } = require('internal/test_runner/utils'); const { relative } = require('path'); +const { + formatTestReport, + indent, + reporterColorMap, + reporterUnicodeSymbolMap, +} = require('internal/test_runner/reporter/utils'); -const symbols = { - '__proto__': null, - 'test:fail': '\u2716 ', - 'test:pass': '\u2714 ', - 'test:diagnostic': '\u2139 ', - 'test:coverage': '\u2139 ', - 'arrow:right': '\u25B6 ', - 'hyphen:minus': '\uFE63 ', -}; class SpecReporter extends Transform { #stack = []; #reported = []; - #indentMemo = new SafeMap(); #failedTests = []; #cwd = process.cwd(); - #inspectOptions; - #colors; constructor() { super({ __proto__: null, writableObjectMode: true }); colors.refresh(); - this.#inspectOptions = { __proto__: null, colors: colors.shouldColorize(process.stdout), breakLength: Infinity }; - this.#colors = { - '__proto__': null, - 'test:fail': colors.red, - 'test:pass': colors.green, - 'test:diagnostic': colors.blue, - }; } - #indent(nesting) { - let value = this.#indentMemo.get(nesting); - if (value === undefined) { - value = StringPrototypeRepeat(' ', nesting); - this.#indentMemo.set(nesting, value); - } - - return value; - } - #formatError(error, indent) { - if (!error) return ''; - const err = error.code === 'ERR_TEST_FAILURE' ? error.cause : error; - const message = ArrayPrototypeJoin( - RegExpPrototypeSymbolSplit( - hardenRegExp(/\r?\n/), - inspectWithNoCustomRetry(err, this.#inspectOptions), - ), `\n${indent} `); - return `\n${indent} ${message}\n`; - } - #formatTestReport(type, data, prefix = '', indent = '', hasChildren = false) { - let color = this.#colors[type] ?? colors.white; - let symbol = symbols[type] ?? ' '; - const { skip, todo } = data; - const duration_ms = data.details?.duration_ms ? ` ${colors.gray}(${data.details.duration_ms}ms)${colors.white}` : ''; - let title = `${data.name}${duration_ms}`; - - if (skip !== undefined) { - title += ` # ${typeof skip === 'string' && skip.length ? skip : 'SKIP'}`; - } else if (todo !== undefined) { - title += ` # ${typeof todo === 'string' && todo.length ? todo : 'TODO'}`; - } - const error = this.#formatError(data.details?.error, indent); - if (hasChildren) { - // If this test has had children - it was already reported, so slightly modify the output - const err = !error || data.details?.error?.failureType === 'subtestsFailed' ? '' : `\n${error}`; - return `${prefix}${indent}${color}${symbols['arrow:right']}${colors.white}${title}${err}`; - } - if (skip !== undefined) { - color = colors.gray; - symbol = symbols['hyphen:minus']; - } - return `${prefix}${indent}${color}${symbol}${title}${colors.white}${error}`; - } #handleTestReportEvent(type, data) { const subtest = ArrayPrototypeShift(this.#stack); // This is the matching `test:start` event if (subtest) { @@ -106,15 +44,15 @@ class SpecReporter extends Transform { assert(parent.type === 'test:start'); const msg = parent.data; ArrayPrototypeUnshift(this.#reported, msg); - prefix += `${this.#indent(msg.nesting)}${symbols['arrow:right']}${msg.name}\n`; + prefix += `${indent(msg.nesting)}${reporterUnicodeSymbolMap['arrow:right']}${msg.name}\n`; } let hasChildren = false; if (this.#reported[0] && this.#reported[0].nesting === data.nesting && this.#reported[0].name === data.name) { ArrayPrototypeShift(this.#reported); hasChildren = true; } - const indent = this.#indent(data.nesting); - return `${this.#formatTestReport(type, data, prefix, indent, hasChildren)}\n`; + const indentation = indent(data.nesting); + return `${formatTestReport(type, data, prefix, indentation, hasChildren)}\n`; } #handleEvent({ type, data }) { switch (type) { @@ -132,9 +70,10 @@ class SpecReporter extends Transform { case 'test:stdout': return data.message; case 'test:diagnostic': - return `${this.#colors[type]}${this.#indent(data.nesting)}${symbols[type]}${data.message}${colors.white}\n`; + return `${reporterColorMap[type]}${indent(data.nesting)}${reporterUnicodeSymbolMap[type]}${data.message}${colors.white}\n`; case 'test:coverage': - return getCoverageReport(this.#indent(data.nesting), data.summary, symbols['test:coverage'], colors.blue, true); + return getCoverageReport(indent(data.nesting), data.summary, + reporterUnicodeSymbolMap['test:coverage'], colors.blue, true); } } _transform({ type, data }, encoding, callback) { @@ -145,10 +84,10 @@ class SpecReporter extends Transform { callback(null, ''); return; } - const results = [`\n${this.#colors['test:fail']}${symbols['test:fail']}failing tests:${colors.white}\n`]; + const results = [`\n${reporterColorMap['test:fail']}${reporterUnicodeSymbolMap['test:fail']}failing tests:${colors.white}\n`]; for (let i = 0; i < this.#failedTests.length; i++) { const test = this.#failedTests[i]; - const formattedErr = this.#formatTestReport('test:fail', test); + const formattedErr = formatTestReport('test:fail', test); if (test.file) { const relPath = relative(this.#cwd, test.file); diff --git a/lib/internal/test_runner/reporter/utils.js b/lib/internal/test_runner/reporter/utils.js new file mode 100644 index 00000000000..42c4ffa3cda --- /dev/null +++ b/lib/internal/test_runner/reporter/utils.js @@ -0,0 +1,93 @@ +'use strict'; +const { + ArrayPrototypeJoin, + RegExpPrototypeSymbolSplit, + SafeMap, + StringPrototypeRepeat, + hardenRegExp, +} = primordials; +const colors = require('internal/util/colors'); +const { inspectWithNoCustomRetry } = require('internal/errors'); +const indentMemo = new SafeMap(); + +const inspectOptions = { + __proto__: null, + colors: colors.shouldColorize(process.stdout), + breakLength: Infinity, +}; + +const reporterUnicodeSymbolMap = { + '__proto__': null, + 'test:fail': '\u2716 ', + 'test:pass': '\u2714 ', + 'test:diagnostic': '\u2139 ', + 'test:coverage': '\u2139 ', + 'arrow:right': '\u25B6 ', + 'hyphen:minus': '\uFE63 ', +}; + +const reporterColorMap = { + '__proto__': null, + get 'test:fail'() { + return colors.red; + }, + get 'test:pass'() { + return colors.green; + }, + get 'test:diagnostic'() { + return colors.blue; + }, +}; + +function indent(nesting) { + let value = indentMemo.get(nesting); + if (value === undefined) { + value = StringPrototypeRepeat(' ', nesting); + indentMemo.set(nesting, value); + } + return value; +} + +function formatError(error, indent) { + if (!error) return ''; + const err = error.code === 'ERR_TEST_FAILURE' ? error.cause : error; + const message = ArrayPrototypeJoin( + RegExpPrototypeSymbolSplit( + hardenRegExp(/\r?\n/), + inspectWithNoCustomRetry(err, inspectOptions), + ), `\n${indent} `); + return `\n${indent} ${message}\n`; +} + +function formatTestReport(type, data, prefix = '', indent = '', hasChildren = false) { + let color = reporterColorMap[type] ?? colors.white; + let symbol = reporterUnicodeSymbolMap[type] ?? ' '; + const { skip, todo } = data; + const duration_ms = data.details?.duration_ms ? ` ${colors.gray}(${data.details.duration_ms}ms)${colors.white}` : ''; + let title = `${data.name}${duration_ms}`; + + if (skip !== undefined) { + title += ` # ${typeof skip === 'string' && skip.length ? skip : 'SKIP'}`; + } else if (todo !== undefined) { + title += ` # ${typeof todo === 'string' && todo.length ? todo : 'TODO'}`; + } + const error = formatError(data.details?.error, indent); + if (hasChildren) { + // If this test has had children - it was already reported, so slightly modify the output + const err = !error || data.details?.error?.failureType === 'subtestsFailed' ? '' : `\n${error}`; + return `${prefix}${indent}${color}${reporterUnicodeSymbolMap['arrow:right']}${colors.white}${title}${err}`; + } + if (skip !== undefined) { + color = colors.gray; + symbol = reporterUnicodeSymbolMap['hyphen:minus']; + } + return `${prefix}${indent}${color}${symbol}${title}${colors.white}${error}`; +} + +module.exports = { + __proto__: null, + reporterUnicodeSymbolMap, + reporterColorMap, + formatTestReport, + indent, +}; diff --git a/lib/internal/test_runner/test.js b/lib/internal/test_runner/test.js index 58490ecac84..8a171d099ee 100644 --- a/lib/internal/test_runner/test.js +++ b/lib/internal/test_runner/test.js @@ -61,6 +61,7 @@ const { setTimeout } = require('timers'); const { TIMEOUT_MAX } = require('internal/timers'); const { fileURLToPath } = require('internal/url'); const { availableParallelism } = require('os'); +const { innerOk } = require('internal/assert/utils'); const { bigint: hrtime } = process.hrtime; const kCallbackAndPromisePresent = 'callbackAndPromisePresent'; const kCancelledByParent = 'cancelledByParent'; @@ -117,7 +118,6 @@ function lazyAssertObject() { 'notDeepStrictEqual', 'notEqual', 'notStrictEqual', - 'ok', 'rejects', 'strictEqual', 'throws', @@ -243,6 +243,16 @@ class TestContext { return ReflectApply(method, assert, args); }; }); + + // This is a hack. It allows the innerOk function to collect the stacktrace from the correct starting point. + function ok(...args) { + if (plan !== null) { + plan.actual++; + } + innerOk(ok, args.length, ...args); + } + + assert.ok = ok; } return this.#assert; } @@ -694,10 +704,7 @@ class Test extends AsyncResource { } [kShouldAbort]() { - if (this.signal.aborted) { - return true; - } - if (this.outerSignal?.aborted) { + if (this.signal.aborted || this.outerSignal?.aborted) { this.#abortHandler(); return true; } @@ -790,10 +797,7 @@ class Test extends AsyncResource { await SafePromiseRace([PromiseResolve(promise), stopPromise]); } - if (this[kShouldAbort]()) { - this.postRun(); - return; - } + this[kShouldAbort](); this.plan?.check(); this.pass(); await afterEach(); diff --git a/lib/internal/tls/secure-context.js b/lib/internal/tls/secure-context.js index b0f971e4eef..84e74105fdb 100644 --- a/lib/internal/tls/secure-context.js +++ b/lib/internal/tls/secure-context.js @@ -130,6 +130,7 @@ function configSecureContext(context, options = kEmptyObject, name = 'options') validateObject(options, name); const { + allowPartialTrustChain, ca, cert, ciphers = getDefaultCiphers(), @@ -182,6 +183,10 @@ function configSecureContext(context, options = kEmptyObject, name = 'options') context.addRootCerts(); } + if (allowPartialTrustChain) { + context.setAllowPartialTrustChain(); + } + if (cert) { setCerts(context, ArrayIsArray(cert) ? cert : [cert], `${name}.cert`); } diff --git a/lib/internal/url.js b/lib/internal/url.js index 41037755606..e6ed5466b88 100644 --- a/lib/internal/url.js +++ b/lib/internal/url.js @@ -764,6 +764,14 @@ function isURL(self) { return Boolean(self?.href && self.protocol && self.auth === undefined && self.path === undefined); } +/** + * A unique symbol used as a private identifier to safely invoke the URL constructor + * with a special parsing behavior. When passed as the third argument to the URL + * constructor, it signals that the constructor should not throw an exception + * for invalid URL inputs. + */ +const kParseURLSymbol = Symbol('kParseURL'); + class URL { #context = new URLContext(); #searchParams; @@ -782,7 +790,7 @@ class URL { }; } - constructor(input, base = undefined) { + constructor(input, base = undefined, parseSymbol = undefined) { if (arguments.length === 0) { throw new ERR_MISSING_ARGS('url'); } @@ -794,7 +802,19 @@ class URL { base = `${base}`; } - this.#updateContext(bindingUrl.parse(input, base)); + const raiseException = parseSymbol !== kParseURLSymbol; + const href = bindingUrl.parse(input, base, raiseException); + if (href) { + this.#updateContext(href); + } + } + + static parse(input, base = undefined) { + if (arguments.length === 0) { + throw new ERR_MISSING_ARGS('url'); + } + const parsedURLObject = new URL(input, base, kParseURLSymbol); + return parsedURLObject.href ? parsedURLObject : null; } [inspect.custom](depth, opts) { @@ -1139,6 +1159,12 @@ ObjectDefineProperties(URL, { writable: true, enumerable: true, }, + parse: { + __proto__: null, + configurable: true, + writable: true, + enumerable: true, + }, }); function installObjectURLMethods() { @@ -1504,7 +1530,12 @@ function pathToFileURL(filepath, options = kEmptyObject) { if ((windows ?? isWindows) && StringPrototypeStartsWith(filepath, '\\\\')) { const outURL = new URL('file://'); // UNC path format: \\server\share\resource - const hostnameEndIndex = StringPrototypeIndexOf(filepath, '\\', 2); + // Handle extended UNC path and standard UNC path + // "\\?\UNC\" path prefix should be ignored. + // Ref: https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation + const isExtendedUNC = StringPrototypeStartsWith(filepath, '\\\\?\\UNC\\'); + const prefixLength = isExtendedUNC ? 8 : 2; + const hostnameEndIndex = StringPrototypeIndexOf(filepath, '\\', prefixLength); if (hostnameEndIndex === -1) { throw new ERR_INVALID_ARG_VALUE( 'path', @@ -1519,7 +1550,7 @@ function pathToFileURL(filepath, options = kEmptyObject) { 'Empty UNC servername', ); } - const hostname = StringPrototypeSlice(filepath, 2, hostnameEndIndex); + const hostname = StringPrototypeSlice(filepath, prefixLength, hostnameEndIndex); outURL.hostname = domainToASCII(hostname); outURL.pathname = encodePathChars( RegExpPrototypeSymbolReplace(backslashRegEx, StringPrototypeSlice(filepath, hostnameEndIndex), '/'), diff --git a/lib/internal/util.js b/lib/internal/util.js index de3e3d56195..fdb3e926811 100644 --- a/lib/internal/util.js +++ b/lib/internal/util.js @@ -477,16 +477,16 @@ function spliceOne(list, index) { const kNodeModulesRE = /^(?:.*)[\\/]node_modules[\\/]/; -let getStructuredStack; +let getStructuredStackImpl; -function isInsideNodeModules() { - if (getStructuredStack === undefined) { +function lazyGetStructuredStack() { + if (getStructuredStackImpl === undefined) { // Lazy-load to avoid a circular dependency. const { runInNewContext } = require('vm'); // Use `runInNewContext()` to get something tamper-proof and - // side-effect-free. Since this is currently only used for a deprecated API, - // the perf implications should be okay. - getStructuredStack = runInNewContext(`(function() { + // side-effect-free. Since this is currently only used for a deprecated API + // and module mocking, the perf implications should be okay. + getStructuredStackImpl = runInNewContext(`(function() { try { Error.stackTraceLimit = Infinity; } catch {} return function structuredStack() { const e = new Error(); @@ -496,6 +496,16 @@ function isInsideNodeModules() { })()`, { overrideStackTrace }, { filename: 'structured-stack' }); } + return getStructuredStackImpl; +} + +function getStructuredStack() { + const getStructuredStackImpl = lazyGetStructuredStack(); + + return getStructuredStackImpl(); +} + +function isInsideNodeModules() { const stack = getStructuredStack(); // Iterate over all stack frames and look for the first one not coming @@ -896,6 +906,7 @@ module.exports = { getConstructorOf, getCWDURL, getInternalGlobal, + getStructuredStack, getSystemErrorMap, getSystemErrorName, guessHandleType, diff --git a/lib/internal/validators.js b/lib/internal/validators.js index 68ba56cf6a5..56f56121264 100644 --- a/lib/internal/validators.js +++ b/lib/internal/validators.js @@ -7,6 +7,7 @@ const { ArrayPrototypeIncludes, ArrayPrototypeJoin, ArrayPrototypeMap, + NumberIsFinite, NumberIsInteger, NumberIsNaN, NumberMAX_SAFE_INTEGER, @@ -567,6 +568,46 @@ const validateLinkHeaderValue = hideStackFrames((hints) => { ); }); +// 1. Returns false for undefined and NaN +// 2. Returns true for finite numbers +// 3. Throws ERR_INVALID_ARG_TYPE for non-numbers +// 4. Throws ERR_OUT_OF_RANGE for infinite numbers +const validateFiniteNumber = hideStackFrames((number, name) => { + // Common case + if (number === undefined) { + return false; + } + + if (NumberIsFinite(number)) { + return true; // Is a valid number + } + + if (NumberIsNaN(number)) { + return false; + } + + validateNumber(number, name); + + // Infinite numbers + throw new ERR_OUT_OF_RANGE(name, 'a finite number', number); +}); + +// 1. Returns def for number when it's undefined or NaN +// 2. Returns number for finite numbers >= lower and <= upper +// 3. Throws ERR_INVALID_ARG_TYPE for non-numbers +// 4. Throws ERR_OUT_OF_RANGE for infinite numbers or numbers > upper or < lower +const checkRangesOrGetDefault = hideStackFrames( + (number, name, lower, upper, def) => { + if (!validateFiniteNumber(number, name)) { + return def; + } + if (number < lower || number > upper) { + throw new ERR_OUT_OF_RANGE(name, `>= ${lower} and <= ${upper}`, number); + } + return number; + }, +); + module.exports = { isInt32, isUint32, @@ -601,4 +642,6 @@ module.exports = { validateAbortSignal, validateLinkHeaderValue, validateInternalField, + validateFiniteNumber, + checkRangesOrGetDefault, }; diff --git a/lib/internal/vm/module.js b/lib/internal/vm/module.js index 74c1870337f..0a8419f8ca4 100644 --- a/lib/internal/vm/module.js +++ b/lib/internal/vm/module.js @@ -8,6 +8,7 @@ const { ArrayPrototypeSome, ObjectDefineProperty, ObjectGetPrototypeOf, + ObjectPrototypeHasOwnProperty, ObjectSetPrototypeOf, ReflectApply, SafePromiseAllReturnVoid, @@ -43,6 +44,7 @@ const { validateObject, validateUint32, validateString, + validateInternalField, } = require('internal/validators'); const binding = internalBinding('module_wrap'); @@ -75,6 +77,13 @@ const kLink = Symbol('kLink'); const { isContext } = require('internal/vm'); +function isModule(object) { + if (typeof object !== 'object' || object === null || !ObjectPrototypeHasOwnProperty(object, kWrap)) { + return false; + } + return true; +} + class Module { constructor(options) { emitExperimentalWarning('VM Modules'); @@ -147,23 +156,17 @@ class Module { } get identifier() { - if (this[kWrap] === undefined) { - throw new ERR_VM_MODULE_NOT_MODULE(); - } + validateInternalField(this, kWrap, 'Module'); return this[kWrap].url; } get context() { - if (this[kWrap] === undefined) { - throw new ERR_VM_MODULE_NOT_MODULE(); - } + validateInternalField(this, kWrap, 'Module'); return this[kContext]; } get namespace() { - if (this[kWrap] === undefined) { - throw new ERR_VM_MODULE_NOT_MODULE(); - } + validateInternalField(this, kWrap, 'Module'); if (this[kWrap].getStatus() < kInstantiated) { throw new ERR_VM_MODULE_STATUS('must not be unlinked or linking'); } @@ -171,16 +174,12 @@ class Module { } get status() { - if (this[kWrap] === undefined) { - throw new ERR_VM_MODULE_NOT_MODULE(); - } + validateInternalField(this, kWrap, 'Module'); return STATUS_MAP[this[kWrap].getStatus()]; } get error() { - if (this[kWrap] === undefined) { - throw new ERR_VM_MODULE_NOT_MODULE(); - } + validateInternalField(this, kWrap, 'Module'); if (this[kWrap].getStatus() !== kErrored) { throw new ERR_VM_MODULE_STATUS('must be errored'); } @@ -188,9 +187,7 @@ class Module { } async link(linker) { - if (this[kWrap] === undefined) { - throw new ERR_VM_MODULE_NOT_MODULE(); - } + validateInternalField(this, kWrap, 'Module'); validateFunction(linker, 'linker'); if (this.status === 'linked') { throw new ERR_VM_MODULE_ALREADY_LINKED(); @@ -203,10 +200,7 @@ class Module { } async evaluate(options = kEmptyObject) { - if (this[kWrap] === undefined) { - throw new ERR_VM_MODULE_NOT_MODULE(); - } - + validateInternalField(this, kWrap, 'Module'); validateObject(options, 'options'); let timeout = options.timeout; @@ -229,9 +223,7 @@ class Module { } [customInspectSymbol](depth, options) { - if (this[kWrap] === undefined) { - throw new ERR_VM_MODULE_NOT_MODULE(); - } + validateInternalField(this, kWrap, 'Module'); if (typeof depth === 'number' && depth < 0) return this; @@ -306,7 +298,7 @@ class SourceTextModule extends Module { const promises = this[kWrap].link(async (identifier, attributes) => { const module = await linker(identifier, this, { attributes, assert: attributes }); - if (module[kWrap] === undefined) { + if (!isModule(module)) { throw new ERR_VM_MODULE_NOT_MODULE(); } if (module.context !== this.context) { @@ -337,19 +329,13 @@ class SourceTextModule extends Module { } get dependencySpecifiers() { - if (this[kWrap] === undefined) { - throw new ERR_VM_MODULE_NOT_MODULE(); - } - if (this[kDependencySpecifiers] === undefined) { - this[kDependencySpecifiers] = this[kWrap].getStaticDependencySpecifiers(); - } + validateInternalField(this, kDependencySpecifiers, 'SourceTextModule'); + this[kDependencySpecifiers] ??= this[kWrap].getStaticDependencySpecifiers(); return this[kDependencySpecifiers]; } get status() { - if (this[kWrap] === undefined) { - throw new ERR_VM_MODULE_NOT_MODULE(); - } + validateInternalField(this, kDependencySpecifiers, 'SourceTextModule'); if (this.#error !== kNoError) { return 'errored'; } @@ -360,9 +346,7 @@ class SourceTextModule extends Module { } get error() { - if (this[kWrap] === undefined) { - throw new ERR_VM_MODULE_NOT_MODULE(); - } + validateInternalField(this, kDependencySpecifiers, 'SourceTextModule'); if (this.#error !== kNoError) { return this.#error; } @@ -415,9 +399,7 @@ class SyntheticModule extends Module { } setExport(name, value) { - if (this[kWrap] === undefined) { - throw new ERR_VM_MODULE_NOT_MODULE(); - } + validateInternalField(this, kWrap, 'SyntheticModule'); validateString(name, 'name'); if (this[kWrap].getStatus() < kInstantiated) { throw new ERR_VM_MODULE_STATUS('must be linked'); @@ -432,7 +414,7 @@ function importModuleDynamicallyWrap(importModuleDynamically) { if (isModuleNamespaceObject(m)) { return m; } - if (!m || m[kWrap] === undefined) { + if (!isModule(m)) { throw new ERR_VM_MODULE_NOT_MODULE(); } if (m.status === 'errored') { diff --git a/lib/internal/webstreams/adapters.js b/lib/internal/webstreams/adapters.js index 8993ced806d..d09150c1590 100644 --- a/lib/internal/webstreams/adapters.js +++ b/lib/internal/webstreams/adapters.js @@ -176,7 +176,7 @@ function newWritableStreamFromStreamWritable(streamWritable) { return new WritableStream({ start(c) { controller = c; }, - async write(chunk) { + write(chunk) { if (streamWritable.writableNeedDrain || !streamWritable.write(chunk)) { backpressurePromise = createDeferredPromise(); return SafePromisePrototypeFinally( @@ -424,6 +424,7 @@ function newReadableStreamFromStreamReadable(streamReadable, options = kEmptyObj const strategy = evaluateStrategyOrFallback(options?.strategy); let controller; + let wasCanceled = false; function onData(chunk) { // Copy the Buffer to detach it from the pool. @@ -448,6 +449,10 @@ function newReadableStreamFromStreamReadable(streamReadable, options = kEmptyObj streamReadable.on('error', () => {}); if (error) return controller.error(error); + // Was already canceled + if (wasCanceled) { + return; + } controller.close(); }); @@ -459,6 +464,7 @@ function newReadableStreamFromStreamReadable(streamReadable, options = kEmptyObj pull() { streamReadable.resume(); }, cancel(reason) { + wasCanceled = true; destroy(streamReadable, reason); }, }, strategy); diff --git a/lib/internal/webstreams/compression.js b/lib/internal/webstreams/compression.js index 28b6dc8f7a4..92933aae4d3 100644 --- a/lib/internal/webstreams/compression.js +++ b/lib/internal/webstreams/compression.js @@ -94,7 +94,7 @@ class CompressionStream { [kInspect](depth, options) { if (!isCompressionStream(this)) throw new ERR_INVALID_THIS('CompressionStream'); - customInspect(depth, options, 'CompressionStream', { + return customInspect(depth, options, 'CompressionStream', { readable: this[kTransform].readable, writable: this[kTransform].writable, }); @@ -146,7 +146,7 @@ class DecompressionStream { [kInspect](depth, options) { if (!isDecompressionStream(this)) throw new ERR_INVALID_THIS('DecompressionStream'); - customInspect(depth, options, 'DecompressionStream', { + return customInspect(depth, options, 'DecompressionStream', { readable: this[kTransform].readable, writable: this[kTransform].writable, }); diff --git a/lib/internal/webstreams/util.js b/lib/internal/webstreams/util.js index e862b3ffe25..47b557c69cf 100644 --- a/lib/internal/webstreams/util.js +++ b/lib/internal/webstreams/util.js @@ -18,6 +18,7 @@ const { const { codes: { + ERR_ARG_NOT_ITERABLE, ERR_INVALID_ARG_VALUE, ERR_OPERATION_FAILED, ERR_INVALID_STATE, @@ -235,6 +236,11 @@ function getIterator(obj, kind = 'sync', method) { method = obj[SymbolAsyncIterator]; if (method === undefined) { const syncMethod = obj[SymbolIterator]; + + if (syncMethod === undefined) { + throw new ERR_ARG_NOT_ITERABLE(obj); + } + const syncIteratorRecord = getIterator(obj, 'sync', syncMethod); return createAsyncFromSyncIterator(syncIteratorRecord); } @@ -243,6 +249,10 @@ function getIterator(obj, kind = 'sync', method) { } } + if (method === undefined) { + throw new ERR_ARG_NOT_ITERABLE(obj); + } + const iterator = FunctionPrototypeCall(method, obj); if (typeof iterator !== 'object' || iterator === null) { throw new ERR_INVALID_STATE.TypeError('The iterator method must return an object'); diff --git a/lib/path.js b/lib/path.js index e9dec3f7d36..05989794958 100644 --- a/lib/path.js +++ b/lib/path.js @@ -22,12 +22,16 @@ 'use strict'; const { + ArrayPrototypeJoin, + ArrayPrototypeSlice, FunctionPrototypeBind, StringPrototypeCharCodeAt, StringPrototypeIndexOf, StringPrototypeLastIndexOf, + StringPrototypeRepeat, StringPrototypeReplace, StringPrototypeSlice, + StringPrototypeSplit, StringPrototypeToLowerCase, } = primordials; @@ -540,6 +544,42 @@ const win32 = { if (from === to) return ''; + if (fromOrig.length !== from.length || toOrig.length !== to.length) { + const fromSplit = StringPrototypeSplit(fromOrig, '\\'); + const toSplit = StringPrototypeSplit(toOrig, '\\'); + if (fromSplit[fromSplit.length - 1] === '') { + fromSplit.pop(); + } + if (toSplit[toSplit.length - 1] === '') { + toSplit.pop(); + } + + const fromLen = fromSplit.length; + const toLen = toSplit.length; + const length = fromLen < toLen ? fromLen : toLen; + + let i; + for (i = 0; i < length; i++) { + if (StringPrototypeToLowerCase(fromSplit[i]) !== StringPrototypeToLowerCase(toSplit[i])) { + break; + } + } + + if (i === 0) { + return toOrig; + } else if (i === length) { + if (toLen > length) { + return ArrayPrototypeJoin(ArrayPrototypeSlice(toSplit, i), '\\'); + } + if (fromLen > length) { + return StringPrototypeRepeat('..\\', fromLen - 1 - i) + '..'; + } + return ''; + } + + return StringPrototypeRepeat('..\\', fromLen - i) + ArrayPrototypeJoin(ArrayPrototypeSlice(toSplit, i), '\\'); + } + // Trim any leading backslashes let fromStart = 0; while (fromStart < from.length && @@ -776,7 +816,7 @@ const win32 = { */ basename(path, suffix) { if (suffix !== undefined) - validateString(suffix, 'ext'); + validateString(suffix, 'suffix'); validateString(path, 'path'); let start = 0; let end = -1; @@ -1197,20 +1237,20 @@ const posix = { join(...args) { if (args.length === 0) return '.'; - let joined; + + const path = []; for (let i = 0; i < args.length; ++i) { const arg = args[i]; validateString(arg, 'path'); if (arg.length > 0) { - if (joined === undefined) - joined = arg; - else - joined += `/${arg}`; + path.push(arg); } } - if (joined === undefined) + + if (path.length === 0) return '.'; - return posix.normalize(joined); + + return posix.normalize(ArrayPrototypeJoin(path, '/')); }, /** @@ -1336,7 +1376,7 @@ const posix = { */ basename(path, suffix) { if (suffix !== undefined) - validateString(suffix, 'ext'); + validateString(suffix, 'suffix'); validateString(path, 'path'); let start = 0; @@ -1423,8 +1463,8 @@ const posix = { // after any path separator we find let preDotState = 0; for (let i = path.length - 1; i >= 0; --i) { - const code = StringPrototypeCharCodeAt(path, i); - if (code === CHAR_FORWARD_SLASH) { + const char = path[i]; + if (char === '/') { // If we reached a path separator that was not part of a set of path // separators at the end of the string, stop now if (!matchedSlash) { @@ -1439,7 +1479,7 @@ const posix = { matchedSlash = false; end = i + 1; } - if (code === CHAR_DOT) { + if (char === '.') { // If this is our first dot, mark it as the start of our extension if (startDot === -1) startDot = i; diff --git a/lib/repl.js b/lib/repl.js index a06ca0dd990..8796b4a0cea 100644 --- a/lib/repl.js +++ b/lib/repl.js @@ -931,7 +931,9 @@ function REPLServer(prompt, ReflectApply(_memory, self, [cmd]); if (e && !self[kBufferedCommandSymbol] && - StringPrototypeStartsWith(StringPrototypeTrim(cmd), 'npm ')) { + StringPrototypeStartsWith(StringPrototypeTrim(cmd), 'npm ') && + !(e instanceof Recoverable) + ) { self.output.write('npm should be run outside of the ' + 'Node.js REPL, in your normal shell.\n' + '(Press Ctrl+D to exit.)\n'); diff --git a/lib/stream.js b/lib/stream.js index 420415a2259..a26cc0b81c5 100644 --- a/lib/stream.js +++ b/lib/stream.js @@ -61,7 +61,9 @@ Stream.isReadable = utils.isReadable; Stream.isWritable = utils.isWritable; Stream.Readable = require('internal/streams/readable'); -for (const key of ObjectKeys(streamReturningOperators)) { +const streamKeys = ObjectKeys(streamReturningOperators); +for (let i = 0; i < streamKeys.length; i++) { + const key = streamKeys[i]; const op = streamReturningOperators[key]; function fn(...args) { if (new.target) { @@ -79,7 +81,9 @@ for (const key of ObjectKeys(streamReturningOperators)) { writable: true, }); } -for (const key of ObjectKeys(promiseReturningOperators)) { +const promiseKeys = ObjectKeys(promiseReturningOperators); +for (let i = 0; i < promiseKeys.length; i++) { + const key = promiseKeys[i]; const op = promiseReturningOperators[key]; function fn(...args) { if (new.target) { diff --git a/lib/sys.js b/lib/sys.js index 1292a38e9ce..4606412dabc 100644 --- a/lib/sys.js +++ b/lib/sys.js @@ -24,6 +24,8 @@ // The sys module was renamed to 'util'. This shim remains to keep old programs // working. `sys` is deprecated and shouldn't be used. +// Note to maintainers: Although this module has been deprecated for a while +// we do not plan to remove it. See: https://github.com/nodejs/node/pull/35407#issuecomment-700693439 module.exports = require('util'); process.emitWarning('sys is deprecated. Use util instead.', 'DeprecationWarning', 'DEP0025'); diff --git a/lib/timers.js b/lib/timers.js index 9e40f8ce0b2..d7bd32cc73c 100644 --- a/lib/timers.js +++ b/lib/timers.js @@ -22,6 +22,7 @@ 'use strict'; const { + ArrayPrototypePush, MathTrunc, ObjectDefineProperty, ObjectDefineProperties, @@ -154,7 +155,7 @@ function setTimeout(callback, after, arg1, arg2, arg3) { args = [arg1, arg2, arg3]; for (i = 5; i < arguments.length; i++) { // Extend array dynamically, makes .apply run much faster in v6.0.0 - args[i - 2] = arguments[i]; + ArrayPrototypePush(args, arguments[i]); } break; } @@ -224,7 +225,7 @@ function setInterval(callback, repeat, arg1, arg2, arg3) { args = [arg1, arg2, arg3]; for (i = 5; i < arguments.length; i++) { // Extend array dynamically, makes .apply run much faster in v6.0.0 - args[i - 2] = arguments[i]; + ArrayPrototypePush(args, arguments[i]); } break; } @@ -296,7 +297,7 @@ function setImmediate(callback, arg1, arg2, arg3) { args = [arg1, arg2, arg3]; for (i = 4; i < arguments.length; i++) { // Extend array dynamically, makes .apply run much faster in v6.0.0 - args[i - 1] = arguments[i]; + ArrayPrototypePush(args, arguments[i]); } break; } diff --git a/lib/timers/promises.js b/lib/timers/promises.js index 2bf36d6cc51..7343a39615a 100644 --- a/lib/timers/promises.js +++ b/lib/timers/promises.js @@ -24,7 +24,6 @@ const { AbortError, codes: { ERR_ILLEGAL_CONSTRUCTOR, - ERR_INVALID_ARG_TYPE, ERR_INVALID_THIS, }, } = require('internal/errors'); @@ -33,6 +32,7 @@ const { validateAbortSignal, validateBoolean, validateObject, + validateNumber, } = require('internal/validators'); const { @@ -50,34 +50,33 @@ function cancelListenerHandler(clear, reject, signal) { } function setTimeout(after, value, options = kEmptyObject) { - const args = value !== undefined ? [value] : value; - if (options == null || typeof options !== 'object') { - return PromiseReject( - new ERR_INVALID_ARG_TYPE( - 'options', - 'Object', - options)); - } - const { signal, ref = true } = options; try { - validateAbortSignal(signal, 'options.signal'); + if (typeof after !== 'undefined') { + validateNumber(after, 'delay'); + } + + validateObject(options, 'options'); + + if (typeof options?.signal !== 'undefined') { + validateAbortSignal(options.signal, 'options.signal'); + } + + if (typeof options?.ref !== 'undefined') { + validateBoolean(options.ref, 'options.ref'); + } } catch (err) { return PromiseReject(err); } - if (typeof ref !== 'boolean') { - return PromiseReject( - new ERR_INVALID_ARG_TYPE( - 'options.ref', - 'boolean', - ref)); - } + + const { signal, ref = true } = options; if (signal?.aborted) { return PromiseReject(new AbortError(undefined, { cause: signal.reason })); } + let oncancel; const ret = new Promise((resolve, reject) => { - const timeout = new Timeout(resolve, after, args, false, ref); + const timeout = new Timeout(resolve, after, [value], false, ref); insert(timeout, timeout._idleTimeout); if (signal) { oncancel = FunctionPrototypeBind(cancelListenerHandler, @@ -93,30 +92,26 @@ function setTimeout(after, value, options = kEmptyObject) { } function setImmediate(value, options = kEmptyObject) { - if (options == null || typeof options !== 'object') { - return PromiseReject( - new ERR_INVALID_ARG_TYPE( - 'options', - 'Object', - options)); - } - const { signal, ref = true } = options; try { - validateAbortSignal(signal, 'options.signal'); + validateObject(options, 'options'); + + if (typeof options?.signal !== 'undefined') { + validateAbortSignal(options.signal, 'options.signal'); + } + + if (typeof options?.ref !== 'undefined') { + validateBoolean(options.ref, 'options.ref'); + } } catch (err) { return PromiseReject(err); } - if (typeof ref !== 'boolean') { - return PromiseReject( - new ERR_INVALID_ARG_TYPE( - 'options.ref', - 'boolean', - ref)); - } + + const { signal, ref = true } = options; if (signal?.aborted) { return PromiseReject(new AbortError(undefined, { cause: signal.reason })); } + let oncancel; const ret = new Promise((resolve, reject) => { const immediate = new Immediate(resolve, [value]); @@ -136,13 +131,25 @@ function setImmediate(value, options = kEmptyObject) { } async function* setInterval(after, value, options = kEmptyObject) { + if (typeof after !== 'undefined') { + validateNumber(after, 'delay'); + } + validateObject(options, 'options'); + + if (typeof options?.signal !== 'undefined') { + validateAbortSignal(options.signal, 'options.signal'); + } + + if (typeof options?.ref !== 'undefined') { + validateBoolean(options.ref, 'options.ref'); + } + const { signal, ref = true } = options; - validateAbortSignal(signal, 'options.signal'); - validateBoolean(ref, 'options.ref'); - if (signal?.aborted) + if (signal?.aborted) { throw new AbortError(undefined, { cause: signal?.reason }); + } let onCancel; let interval; @@ -216,7 +223,7 @@ class Scheduler { wait(delay, options) { if (!this[kScheduler]) throw new ERR_INVALID_THIS('Scheduler'); - return setTimeout(delay, undefined, { signal: options?.signal }); + return setTimeout(delay, undefined, options); } } diff --git a/lib/tls.js b/lib/tls.js index b78f56d49a1..0c1b3350618 100644 --- a/lib/tls.js +++ b/lib/tls.js @@ -24,26 +24,10 @@ const { Array, ArrayIsArray, - ArrayPrototypeForEach, - ArrayPrototypeIncludes, - ArrayPrototypeJoin, - ArrayPrototypePush, - ArrayPrototypeReduce, - ArrayPrototypeSome, JSONParse, ObjectDefineProperty, ObjectFreeze, - RegExpPrototypeExec, - RegExpPrototypeSymbolReplace, StringFromCharCode, - StringPrototypeCharCodeAt, - StringPrototypeEndsWith, - StringPrototypeIncludes, - StringPrototypeIndexOf, - StringPrototypeSlice, - StringPrototypeSplit, - StringPrototypeStartsWith, - StringPrototypeSubstring, } = primordials; const { @@ -122,7 +106,7 @@ ObjectDefineProperty(exports, 'rootCertificates', { // ("\x06spdy/2\x08http/1.1\x08http/1.0") function convertProtocols(protocols) { const lens = new Array(protocols.length); - const buff = Buffer.allocUnsafe(ArrayPrototypeReduce(protocols, (p, c, i) => { + const buff = Buffer.allocUnsafe(protocols.reduce((p, c, i) => { const len = Buffer.byteLength(c); if (len > 255) { throw new ERR_OUT_OF_RANGE('The byte length of the protocol at index ' + @@ -158,20 +142,17 @@ exports.convertALPNProtocols = function convertALPNProtocols(protocols, out) { }; function unfqdn(host) { - return RegExpPrototypeSymbolReplace(/[.]$/, host, ''); + return host.replace(/[.]$/, ''); } // String#toLowerCase() is locale-sensitive so we use // a conservative version that only lowercases A-Z. function toLowerCase(c) { - return StringFromCharCode(32 + StringPrototypeCharCodeAt(c, 0)); + return StringFromCharCode(32 + c.charCodeAt(0)); } function splitHost(host) { - return StringPrototypeSplit( - RegExpPrototypeSymbolReplace(/[A-Z]/g, unfqdn(host), toLowerCase), - '.', - ); + return unfqdn(host).replace(/[A-Z]/g, toLowerCase).split('.'); } function check(hostParts, pattern, wildcards) { @@ -185,15 +166,15 @@ function check(hostParts, pattern, wildcards) { return false; // Pattern has empty components, e.g. "bad..example.com". - if (ArrayPrototypeIncludes(patternParts, '')) + if (patternParts.includes('')) return false; // RFC 6125 allows IDNA U-labels (Unicode) in names but we have no // good way to detect their encoding or normalize them so we simply // reject them. Control characters and blanks are rejected as well // because nothing good can come from accepting them. - const isBad = (s) => RegExpPrototypeExec(/[^\u0021-\u007F]/u, s) !== null; - if (ArrayPrototypeSome(patternParts, isBad)) + const isBad = (s) => /[^\u0021-\u007F]/u.test(s); + if (patternParts.some(isBad)) return false; // Check host parts from right to left first. @@ -204,13 +185,13 @@ function check(hostParts, pattern, wildcards) { const hostSubdomain = hostParts[0]; const patternSubdomain = patternParts[0]; - const patternSubdomainParts = StringPrototypeSplit(patternSubdomain, '*'); + const patternSubdomainParts = patternSubdomain.split('*'); // Short-circuit when the subdomain does not contain a wildcard. // RFC 6125 does not allow wildcard substitution for components // containing IDNA A-labels (Punycode) so match those verbatim. if (patternSubdomainParts.length === 1 || - StringPrototypeIncludes(patternSubdomain, 'xn--')) + patternSubdomain.includes('xn--')) return hostSubdomain === patternSubdomain; if (!wildcards) @@ -229,10 +210,10 @@ function check(hostParts, pattern, wildcards) { if (prefix.length + suffix.length > hostSubdomain.length) return false; - if (!StringPrototypeStartsWith(hostSubdomain, prefix)) + if (!hostSubdomain.startsWith(prefix)) return false; - if (!StringPrototypeEndsWith(hostSubdomain, suffix)) + if (!hostSubdomain.endsWith(suffix)) return false; return true; @@ -250,13 +231,12 @@ function splitEscapedAltNames(altNames) { let currentToken = ''; let offset = 0; while (offset !== altNames.length) { - const nextSep = StringPrototypeIndexOf(altNames, ', ', offset); - const nextQuote = StringPrototypeIndexOf(altNames, '"', offset); + const nextSep = altNames.indexOf(',', offset); + const nextQuote = altNames.indexOf('"', offset); if (nextQuote !== -1 && (nextSep === -1 || nextQuote < nextSep)) { // There is a quote character and there is no separator before the quote. - currentToken += StringPrototypeSubstring(altNames, offset, nextQuote); - const match = RegExpPrototypeExec( - jsonStringPattern, StringPrototypeSubstring(altNames, nextQuote)); + currentToken += altNames.substring(offset, nextQuote); + const match = jsonStringPattern.exec(altNames.substring(nextQuote)); if (!match) { throw new ERR_TLS_CERT_ALTNAME_FORMAT(); } @@ -264,16 +244,16 @@ function splitEscapedAltNames(altNames) { offset = nextQuote + match[0].length; } else if (nextSep !== -1) { // There is a separator and no quote before it. - currentToken += StringPrototypeSubstring(altNames, offset, nextSep); - ArrayPrototypePush(result, currentToken); + currentToken += altNames.substring(offset, nextSep); + result.push(currentToken); currentToken = ''; offset = nextSep + 2; } else { - currentToken += StringPrototypeSubstring(altNames, offset); + currentToken += altNames.substring(offset); offset = altNames.length; } } - ArrayPrototypePush(result, currentToken); + result.push(currentToken); return result; } @@ -286,14 +266,14 @@ exports.checkServerIdentity = function checkServerIdentity(hostname, cert) { hostname = '' + hostname; if (altNames) { - const splitAltNames = StringPrototypeIncludes(altNames, '"') ? + const splitAltNames = altNames.includes('"') ? splitEscapedAltNames(altNames) : - StringPrototypeSplit(altNames, ', '); - ArrayPrototypeForEach(splitAltNames, (name) => { - if (StringPrototypeStartsWith(name, 'DNS:')) { - ArrayPrototypePush(dnsNames, StringPrototypeSlice(name, 4)); - } else if (StringPrototypeStartsWith(name, 'IP Address:')) { - ArrayPrototypePush(ips, canonicalizeIP(StringPrototypeSlice(name, 11))); + altNames.split(', '); + splitAltNames.forEach((name) => { + if (name.startsWith('DNS:')) { + dnsNames.push(name.slice(4)); + } else if (name.startsWith('IP Address:')) { + ips.push(canonicalizeIP(name.slice(11))); } }); } @@ -304,16 +284,15 @@ exports.checkServerIdentity = function checkServerIdentity(hostname, cert) { hostname = unfqdn(hostname); // Remove trailing dot for error messages. if (net.isIP(hostname)) { - valid = ArrayPrototypeIncludes(ips, canonicalizeIP(hostname)); + valid = ips.includes(canonicalizeIP(hostname)); if (!valid) - reason = `IP: ${hostname} is not in the cert's list: ` + - ArrayPrototypeJoin(ips, ', '); + reason = `IP: ${hostname} is not in the cert's list: ` + ips.join(', '); } else if (dnsNames.length > 0 || subject?.CN) { const hostParts = splitHost(hostname); const wildcard = (pattern) => check(hostParts, pattern, true); if (dnsNames.length > 0) { - valid = ArrayPrototypeSome(dnsNames, wildcard); + valid = dnsNames.some(wildcard); if (!valid) reason = `Host: ${hostname}. is not in the cert's altnames: ${altNames}`; @@ -322,7 +301,7 @@ exports.checkServerIdentity = function checkServerIdentity(hostname, cert) { const cn = subject.CN; if (ArrayIsArray(cn)) - valid = ArrayPrototypeSome(cn, wildcard); + valid = cn.some(wildcard); else if (cn) valid = wildcard(cn); diff --git a/lib/tty.js b/lib/tty.js index aa929cd9ba0..7dfa552c23b 100644 --- a/lib/tty.js +++ b/lib/tty.js @@ -22,7 +22,6 @@ 'use strict'; const { - Array, NumberIsInteger, ObjectSetPrototypeOf, } = primordials; @@ -106,7 +105,7 @@ function WriteStream(fd) { // Ref: https://github.com/nodejs/node/pull/1771#issuecomment-119351671 this._handle.setBlocking(true); - const winSize = new Array(2); + const winSize = [0, 0]; const err = this._handle.getWindowSize(winSize); if (!err) { this.columns = winSize[0]; @@ -126,7 +125,7 @@ WriteStream.prototype.hasColors = hasColors; WriteStream.prototype._refreshSize = function() { const oldCols = this.columns; const oldRows = this.rows; - const winSize = new Array(2); + const winSize = [0, 0]; const err = this._handle.getWindowSize(winSize); if (err) { this.emit('error', new errors.ErrnoException(err, 'getWindowSize')); diff --git a/lib/url.js b/lib/url.js index 312750e86d6..8fa8553c2b3 100644 --- a/lib/url.js +++ b/lib/url.js @@ -24,6 +24,7 @@ const { Boolean, Int8Array, + ObjectAssign, ObjectKeys, StringPrototypeCharCodeAt, decodeURIComponent, @@ -735,11 +736,7 @@ Url.prototype.resolveObject = function resolveObject(relative) { } const result = new Url(); - const tkeys = ObjectKeys(this); - for (let tk = 0; tk < tkeys.length; tk++) { - const tkey = tkeys[tk]; - result[tkey] = this[tkey]; - } + ObjectAssign(result, this); // Hash is always overridden, no matter what. // even href="" will remove it. @@ -754,12 +751,13 @@ Url.prototype.resolveObject = function resolveObject(relative) { // Hrefs like //foo/bar always cut to the protocol. if (relative.slashes && !relative.protocol) { // Take everything except the protocol from relative - const rkeys = ObjectKeys(relative); - for (let rk = 0; rk < rkeys.length; rk++) { - const rkey = rkeys[rk]; - if (rkey !== 'protocol') - result[rkey] = relative[rkey]; - } + const relativeWithoutProtocol = ObjectKeys(relative).reduce((acc, key) => { + if (key !== 'protocol') { + acc[key] = relative[key]; + } + return acc; + }, {}); + ObjectAssign(result, relativeWithoutProtocol); // urlParse appends trailing / to urls like http://www.example.com if (slashedProtocol.has(result.protocol) && @@ -781,11 +779,7 @@ Url.prototype.resolveObject = function resolveObject(relative) { // because that's known to be hostless. // anything else is assumed to be absolute. if (!slashedProtocol.has(relative.protocol)) { - const keys = ObjectKeys(relative); - for (let v = 0; v < keys.length; v++) { - const k = keys[v]; - result[k] = relative[k]; - } + ObjectAssign(result, relative); result.href = result.format(); return result; } diff --git a/lib/util.js b/lib/util.js index b6c60419436..4dcdfcdf3be 100644 --- a/lib/util.js +++ b/lib/util.js @@ -65,13 +65,26 @@ const { } = require('internal/util/inspect'); const { debuglog } = require('internal/util/debuglog'); const { + validateBoolean, validateFunction, validateNumber, validateString, validateOneOf, } = require('internal/validators'); const { isBuffer } = require('buffer').Buffer; +const { + isReadableStream, + isWritableStream, + isNodeStream, +} = require('internal/streams/utils'); const types = require('internal/util/types'); + +let utilColors; +function lazyUtilColors() { + utilColors ??= require('internal/util/colors'); + return utilColors; +} + const binding = internalBinding('util'); const { @@ -209,10 +222,25 @@ function escapeStyleCode(code) { /** * @param {string | string[]} format * @param {string} text + * @param {object} [options={}] + * @param {boolean} [options.validateStream=true] - Whether to validate the stream. + * @param {Stream} [options.stream=process.stdout] - The stream used for validation. * @returns {string} */ -function styleText(format, text) { +function styleText(format, text, { validateStream = true, stream = process.stdout } = {}) { validateString(text, 'text'); + validateBoolean(validateStream, 'options.validateStream'); + + if (validateStream) { + if ( + !isReadableStream(stream) && + !isWritableStream(stream) && + !isNodeStream(stream) + ) { + throw new ERR_INVALID_ARG_TYPE('stream', ['ReadableStream', 'WritableStream', 'Stream'], stream); + } + } + if (ArrayIsArray(format)) { let left = ''; let right = ''; @@ -232,6 +260,18 @@ function styleText(format, text) { if (formatCodes == null) { validateOneOf(format, 'format', ObjectKeys(inspect.colors)); } + + // Check colorize only after validating arg type and value + if ( + validateStream && + ( + !stream || + !lazyUtilColors().shouldColorize(stream) + ) + ) { + return text; + } + return `${escapeStyleCode(formatCodes[0])}${text}${escapeStyleCode(formatCodes[1])}`; } diff --git a/lib/vm.js b/lib/vm.js index 34814c430d3..cb64404ef0b 100644 --- a/lib/vm.js +++ b/lib/vm.js @@ -65,6 +65,7 @@ const { } = require('internal/vm'); const { vm_dynamic_import_main_context_default, + vm_context_no_contextify, } = internalBinding('symbols'); const kParsingContext = Symbol('script parsing context'); @@ -222,7 +223,7 @@ function getContextOptions(options) { let defaultContextNameIndex = 1; function createContext(contextObject = {}, options = kEmptyObject) { - if (isContext(contextObject)) { + if (contextObject !== vm_context_no_contextify && isContext(contextObject)) { return contextObject; } @@ -258,10 +259,10 @@ function createContext(contextObject = {}, options = kEmptyObject) { const hostDefinedOptionId = getHostDefinedOptionId(importModuleDynamically, name); - makeContext(contextObject, name, origin, strings, wasm, microtaskQueue, hostDefinedOptionId); + const result = makeContext(contextObject, name, origin, strings, wasm, microtaskQueue, hostDefinedOptionId); // Register the context scope callback after the context was initialized. - registerImportModuleDynamically(contextObject, importModuleDynamically); - return contextObject; + registerImportModuleDynamically(result, importModuleDynamically); + return result; } function createScript(code, options) { @@ -394,6 +395,7 @@ function measureMemory(options = kEmptyObject) { const vmConstants = { __proto__: null, USE_MAIN_CONTEXT_DEFAULT_LOADER: vm_dynamic_import_main_context_default, + DONT_CONTEXTIFY: vm_context_no_contextify, }; ObjectFreeze(vmConstants); diff --git a/lib/zlib.js b/lib/zlib.js index 509f83731e9..a2c092f1037 100644 --- a/lib/zlib.js +++ b/lib/zlib.js @@ -28,7 +28,6 @@ const { ArrayPrototypePush, FunctionPrototypeBind, MathMaxApply, - NumberIsFinite, NumberIsNaN, ObjectDefineProperties, ObjectDefineProperty, @@ -51,7 +50,6 @@ const { ERR_ZLIB_INITIALIZATION_FAILED, }, genericNodeError, - hideStackFrames, } = require('internal/errors'); const { Transform, finished } = require('stream'); const { @@ -71,9 +69,10 @@ const { } = require('buffer'); const { owner_symbol } = require('internal/async_hooks').symbols; const { + checkRangesOrGetDefault, validateFunction, - validateNumber, validateUint32, + validateFiniteNumber, } = require('internal/validators'); const kFlushFlag = Symbol('kFlushFlag'); @@ -195,47 +194,6 @@ function zlibOnError(message, errno, code) { self[kError] = error; } -// 1. Returns false for undefined and NaN -// 2. Returns true for finite numbers -// 3. Throws ERR_INVALID_ARG_TYPE for non-numbers -// 4. Throws ERR_OUT_OF_RANGE for infinite numbers -const checkFiniteNumber = hideStackFrames((number, name) => { - // Common case - if (number === undefined) { - return false; - } - - if (NumberIsFinite(number)) { - return true; // Is a valid number - } - - if (NumberIsNaN(number)) { - return false; - } - - validateNumber.withoutStackTrace(number, name); - - // Infinite numbers - throw new ERR_OUT_OF_RANGE.HideStackFramesError(name, 'a finite number', number); -}); - -// 1. Returns def for number when it's undefined or NaN -// 2. Returns number for finite numbers >= lower and <= upper -// 3. Throws ERR_INVALID_ARG_TYPE for non-numbers -// 4. Throws ERR_OUT_OF_RANGE for infinite numbers or numbers > upper or < lower -const checkRangesOrGetDefault = hideStackFrames( - (number, name, lower, upper, def) => { - if (!checkFiniteNumber.withoutStackTrace(number, name)) { - return def; - } - if (number < lower || number > upper) { - throw new ERR_OUT_OF_RANGE.HideStackFramesError(name, - `>= ${lower} and <= ${upper}`, number); - } - return number; - }, -); - const FLUSH_BOUND = [ [ Z_NO_FLUSH, Z_BLOCK ], [ BROTLI_OPERATION_PROCESS, BROTLI_OPERATION_EMIT_METADATA ], @@ -261,7 +219,7 @@ function ZlibBase(opts, mode, handle, { flush, finishFlush, fullFlush }) { if (opts) { chunkSize = opts.chunkSize; - if (!checkFiniteNumber(chunkSize, 'options.chunkSize')) { + if (!validateFiniteNumber(chunkSize, 'options.chunkSize')) { chunkSize = Z_DEFAULT_CHUNK; } else if (chunkSize < Z_MIN_CHUNK) { throw new ERR_OUT_OF_RANGE('options.chunkSize', @@ -361,11 +319,10 @@ ZlibBase.prototype._final = function(callback) { // Z_NO_FLUSH (< Z_TREES) < Z_BLOCK < Z_PARTIAL_FLUSH < // Z_SYNC_FLUSH < Z_FULL_FLUSH < Z_FINISH const flushiness = []; -let i = 0; const kFlushFlagList = [Z_NO_FLUSH, Z_BLOCK, Z_PARTIAL_FLUSH, Z_SYNC_FLUSH, Z_FULL_FLUSH, Z_FINISH]; -for (const flushFlag of kFlushFlagList) { - flushiness[flushFlag] = i++; +for (let i = 0; i < kFlushFlagList.length; i++) { + flushiness[kFlushFlagList[i]] = i; } function maxFlush(a, b) { diff --git a/node.gyp b/node.gyp index d8bc84e2696..3f21bb15338 100644 --- a/node.gyp +++ b/node.gyp @@ -19,6 +19,7 @@ 'node_shared_http_parser%': 'false', 'node_shared_cares%': 'false', 'node_shared_libuv%': 'false', + 'node_shared_uvwasi%': 'false', 'node_shared_nghttp2%': 'false', 'node_shared_sodium%': 'false', 'node_shared_zmq%': 'false', @@ -513,7 +514,7 @@ # Putting these explicitly here so not to depend on `common.gypi`. # `common.gypi` need to be more general because it is used to build userland native addons. # Refs: https://github.com/nodejs/node-gyp/issues/1118 - 'cflags': [ '-Wall', '-Wextra', '-Wno-unused-parameter', ], + 'cflags': [ '-Wall', '-Wextra', '-Wno-unused-parameter', '-Wno-c++98-compat-extra-semi', ], 'xcode_settings': { 'WARNING_CFLAGS': [ '-Wall', @@ -521,7 +522,6 @@ '-W', '-Wno-unused-parameter', '-Werror=undefined-inline', - '-Werror=extra-semi', '-Wno-c++98-compat-extra-semi', ], }, @@ -536,6 +536,9 @@ }, 'conditions': [ + ['clang==0 and OS!="win"', { + 'cflags': [ '-Wno-restrict', '-Wno-c++98-compat-extra-semi', ], + }], # Pointer authentication for ARM64. ['target_arch=="arm64"', { 'target_conditions': [ @@ -556,7 +559,8 @@ '-Wl,-bnoerrmsg', ], }], - ['OS == "linux" and llvm_version != "0.0"', { + ['OS=="linux" and clang==1', { + 'cflags': [ '-Wno-c++98-compat-extra-semi', ], 'libraries': ['-latomic'], }], ], @@ -603,7 +607,6 @@ 'dependencies': [ 'deps/histogram/histogram.gyp:histogram', - 'deps/uvwasi/uvwasi.gyp:uvwasi', ], 'msvs_settings': { @@ -628,7 +631,7 @@ 'conditions': [ [ 'error_on_warn=="true"', { - 'cflags': ['-Werror'], + 'cflags': ['-Werror', '-Wno-c++98-compat-extra-semi'], 'xcode_settings': { 'WARNING_CFLAGS': [ '-Werror' ], }, @@ -1089,8 +1092,8 @@ 'dependencies': [ '<(node_lib_target_name)', 'deps/histogram/histogram.gyp:histogram', - 'deps/uvwasi/uvwasi.gyp:uvwasi', ], + 'includes': [ 'node.gypi' ], @@ -1100,9 +1103,9 @@ 'deps/v8/include', 'deps/cares/include', 'deps/uv/include', - 'deps/uvwasi/include', 'test/cctest', ], + 'defines': [ 'NODE_ARCH="<(target_arch)"', 'NODE_PLATFORM="<(OS)"', @@ -1239,7 +1242,6 @@ 'deps/v8/include', 'deps/cares/include', 'deps/uv/include', - 'deps/uvwasi/include', 'test/cctest', 'agents', 'deps/nsuv/include', @@ -1303,7 +1305,6 @@ 'dependencies': [ '<(node_lib_target_name)', 'deps/histogram/histogram.gyp:histogram', - 'deps/uvwasi/uvwasi.gyp:uvwasi', 'deps/ada/ada.gyp:ada', ], @@ -1318,7 +1319,6 @@ 'deps/v8/include', 'deps/cares/include', 'deps/uv/include', - 'deps/uvwasi/include', 'test/embedding', ], @@ -1418,7 +1418,6 @@ 'dependencies': [ '<(node_lib_target_name)', 'deps/histogram/histogram.gyp:histogram', - 'deps/uvwasi/uvwasi.gyp:uvwasi', 'deps/ada/ada.gyp:ada', ], @@ -1433,7 +1432,6 @@ 'deps/cares/include', 'deps/uv/include', 'deps/nsuv/include', - 'deps/uvwasi/include', ], 'defines': [ 'NODE_WANT_INTERNALS=1' ], diff --git a/node.gypi b/node.gypi index 6884dd34110..832f3f39485 100644 --- a/node.gypi +++ b/node.gypi @@ -27,7 +27,7 @@ 'conditions': [ [ 'clang==1', { - 'cflags': [ '-Werror=undefined-inline', '-Werror=extra-semi'] + 'cflags': [ '-Werror=undefined-inline', '-Wno-c++98-compat-extra-semi'] }], [ '"<(_type)"=="executable"', { 'msvs_settings': { @@ -208,6 +208,10 @@ ], }], + [ 'node_shared_uvwasi=="false"', { + 'dependencies': [ 'deps/uvwasi/uvwasi.gyp:uvwasi' ], + }], + [ 'node_shared_nghttp2=="false"', { 'dependencies': [ 'deps/nghttp2/nghttp2.gyp:nghttp2' ], }], @@ -334,6 +338,11 @@ [ 'node_shared_otlp_http_exporter=="false"', { 'dependencies': [ 'deps/opentelemetry-cpp/otlp-http-exporter.gyp:otlp-http-exporter' ], + 'direct_dependent_settings': { + 'cflags': [ + '-Wno-c++98-compat-extra-semi', + ], + }, 'conditions': [ [ 'force_load=="true"', { 'xcode_settings': { diff --git a/onboarding.md b/onboarding.md index 1696b047ea3..e213dd03da0 100644 --- a/onboarding.md +++ b/onboarding.md @@ -121,7 +121,7 @@ The project has a venue for real-time discussion: * You can always refer to the [full moderation policy](https://github.com/nodejs/admin/blob/main/Moderation-Policy.md). * You can contact someone in the - [full list of moderation team members](https://github.com/nodejs/moderation#moderation-team-members). + [full list of moderation team members](https://github.com/nodejs/admin/blob/main/Moderation-Policy.md#current-members-of-moderation-team). ## Reviewing pull requests diff --git a/src/README.md b/src/README.md index 5853e1efa23..01d6d5fd4bc 100644 --- a/src/README.md +++ b/src/README.md @@ -418,8 +418,6 @@ Node.js source code.) `args[n]` is a `Local` that represents the n-th argument passed to the function. `args.This()` is the `this` value inside this function call. -`args.Holder()` is equivalent to `args.This()` in all use cases inside of -Node.js. `args.GetReturnValue()` is a placeholder for the return value of the function, and provides a `.Set()` method that can be called with a boolean, integer, @@ -829,7 +827,7 @@ The JavaScript object can be accessed as a `v8::Local` by using `self->object()`, given a `BaseObject` named `self`. Accessing a `BaseObject` from a `v8::Local` (frequently that is -`args.This()` or `args.Holder()` in a [binding function][]) can be done using +`args.This()` in a [binding function][]) can be done using the `Unwrap(obj)` function, where `T` is a subclass of `BaseObject`. A helper for this is the `ASSIGN_OR_RETURN_UNWRAP` macro that returns from the current function if unwrapping fails (typically that means that the `BaseObject` @@ -838,7 +836,7 @@ has been deleted earlier). ```cpp void Http2Session::Request(const FunctionCallbackInfo& args) { Http2Session* session; - ASSIGN_OR_RETURN_UNWRAP(&session, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&session, args.This()); Environment* env = session->env(); Local context = env->context(); Isolate* isolate = env->isolate(); diff --git a/src/acorn_version.h b/src/acorn_version.h index 1dfc3532ce0..b625cceb704 100644 --- a/src/acorn_version.h +++ b/src/acorn_version.h @@ -2,5 +2,5 @@ // Refer to tools/dep_updaters/update-acorn.sh #ifndef SRC_ACORN_VERSION_H_ #define SRC_ACORN_VERSION_H_ -#define ACORN_VERSION "8.11.3" +#define ACORN_VERSION "8.12.1" #endif // SRC_ACORN_VERSION_H_ diff --git a/src/api/environment.cc b/src/api/environment.cc index 2c3da74f88d..57d0834ffbe 100644 --- a/src/api/environment.cc +++ b/src/api/environment.cc @@ -373,9 +373,8 @@ IsolateData* CreateIsolateData( MultiIsolatePlatform* platform, ArrayBufferAllocator* allocator, const EmbedderSnapshotData* embedder_snapshot_data) { - const SnapshotData* snapshot_data = - SnapshotData::FromEmbedderWrapper(embedder_snapshot_data); - return new IsolateData(isolate, loop, platform, allocator, snapshot_data); + return IsolateData::CreateIsolateData( + isolate, loop, platform, allocator, embedder_snapshot_data); } void FreeIsolateData(IsolateData* isolate_data) { diff --git a/src/async_wrap.cc b/src/async_wrap.cc index 4b96331c187..65829a31a36 100644 --- a/src/async_wrap.cc +++ b/src/async_wrap.cc @@ -254,7 +254,7 @@ static void RegisterDestroyHook(const FunctionCallbackInfo& args) { void AsyncWrap::GetAsyncId(const FunctionCallbackInfo& args) { AsyncWrap* wrap; args.GetReturnValue().Set(kInvalidAsyncId); - ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&wrap, args.This()); args.GetReturnValue().Set(wrap->get_async_id()); } @@ -296,7 +296,7 @@ void AsyncWrap::AsyncReset(const FunctionCallbackInfo& args) { CHECK(args[0]->IsObject()); AsyncWrap* wrap; - ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&wrap, args.This()); Local resource = args[0].As(); double execution_async_id = @@ -308,7 +308,7 @@ void AsyncWrap::AsyncReset(const FunctionCallbackInfo& args) { void AsyncWrap::GetProviderType(const FunctionCallbackInfo& args) { AsyncWrap* wrap; args.GetReturnValue().Set(AsyncWrap::PROVIDER_NONE); - ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&wrap, args.This()); args.GetReturnValue().Set(wrap->provider_type()); } diff --git a/src/blob_serializer_deserializer-inl.h b/src/blob_serializer_deserializer-inl.h index f47a1e0cdf8..fc6b8c0c33d 100644 --- a/src/blob_serializer_deserializer-inl.h +++ b/src/blob_serializer_deserializer-inl.h @@ -246,7 +246,7 @@ size_t BlobSerializer::WriteVector(const std::vector& data) { } size_t written_total = WriteArithmetic(data.size()); - if (data.size() == 0) { + if (data.empty()) { return written_total; } diff --git a/src/cares_wrap.cc b/src/cares_wrap.cc index e129cc57b57..29980223873 100644 --- a/src/cares_wrap.cc +++ b/src/cares_wrap.cc @@ -1404,7 +1404,7 @@ template static void Query(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); ChannelWrap* channel; - ASSIGN_OR_RETURN_UNWRAP(&channel, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&channel, args.This()); CHECK_EQ(false, args.IsConstructCall()); CHECK(args[0]->IsObject()); @@ -1664,7 +1664,7 @@ void GetNameInfo(const FunctionCallbackInfo& args) { void GetServers(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); ChannelWrap* channel; - ASSIGN_OR_RETURN_UNWRAP(&channel, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&channel, args.This()); Local server_array = Array::New(env->isolate()); @@ -1702,7 +1702,7 @@ void GetServers(const FunctionCallbackInfo& args) { void SetServers(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); ChannelWrap* channel; - ASSIGN_OR_RETURN_UNWRAP(&channel, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&channel, args.This()); if (channel->active_query_count()) { return args.GetReturnValue().Set(DNS_ESETSRVPENDING); @@ -1783,7 +1783,7 @@ void SetServers(const FunctionCallbackInfo& args) { void SetLocalAddress(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); ChannelWrap* channel; - ASSIGN_OR_RETURN_UNWRAP(&channel, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&channel, args.This()); CHECK_EQ(args.Length(), 2); CHECK(args[0]->IsString()); @@ -1846,7 +1846,7 @@ void SetLocalAddress(const FunctionCallbackInfo& args) { void Cancel(const FunctionCallbackInfo& args) { ChannelWrap* channel; - ASSIGN_OR_RETURN_UNWRAP(&channel, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&channel, args.This()); TRACE_EVENT_INSTANT0(TRACING_CATEGORY_NODE2(dns, native), "cancel", TRACE_EVENT_SCOPE_THREAD); diff --git a/src/cjs_module_lexer_version.h b/src/cjs_module_lexer_version.h index 3e120e55032..72a66ba9e90 100644 --- a/src/cjs_module_lexer_version.h +++ b/src/cjs_module_lexer_version.h @@ -2,5 +2,5 @@ // Refer to tools/dep_updaters/update-cjs-module-lexer.sh #ifndef SRC_CJS_MODULE_LEXER_VERSION_H_ #define SRC_CJS_MODULE_LEXER_VERSION_H_ -#define CJS_MODULE_LEXER_VERSION "1.2.2" +#define CJS_MODULE_LEXER_VERSION "1.4.1" #endif // SRC_CJS_MODULE_LEXER_VERSION_H_ diff --git a/src/crypto/crypto_aes.cc b/src/crypto/crypto_aes.cc index c3f088024a9..c56d435a991 100644 --- a/src/crypto/crypto_aes.cc +++ b/src/crypto/crypto_aes.cc @@ -134,7 +134,7 @@ WebCryptoCipherStatus AES_Cipher( // // Refs: https://github.com/openssl/openssl/commit/420cb707b880e4fb649094241371701013eeb15f // Refs: https://github.com/nodejs/node/pull/38913#issuecomment-866505244 - if (in.size() == 0) { + if (in.empty()) { out_len = 0; } else if (!EVP_CipherUpdate(ctx.get(), buf.data(), @@ -476,12 +476,9 @@ Maybe AESCipherTraits::AdditionalConfig( params->variant = static_cast(args[offset].As()->Value()); - AESCipherMode cipher_op_mode; int cipher_nid; - -#define V(name, _, mode, nid) \ +#define V(name, _, nid) \ case kKeyVariantAES_##name: { \ - cipher_op_mode = mode; \ cipher_nid = nid; \ break; \ } @@ -492,15 +489,22 @@ Maybe AESCipherTraits::AdditionalConfig( } #undef V - if (cipher_op_mode != AESCipherMode::KW) { + params->cipher = EVP_get_cipherbynid(cipher_nid); + if (params->cipher == nullptr) { + THROW_ERR_CRYPTO_UNKNOWN_CIPHER(env); + return Nothing(); + } + + int cipher_op_mode = EVP_CIPHER_mode(params->cipher); + if (cipher_op_mode != EVP_CIPH_WRAP_MODE) { if (!ValidateIV(env, mode, args[offset + 1], params)) { return Nothing(); } - if (cipher_op_mode == AESCipherMode::CTR) { + if (cipher_op_mode == EVP_CIPH_CTR_MODE) { if (!ValidateCounter(env, args[offset + 2], params)) { return Nothing(); } - } else if (cipher_op_mode == AESCipherMode::GCM) { + } else if (cipher_op_mode == EVP_CIPH_GCM_MODE) { if (!ValidateAuthTag(env, mode, cipher_mode, args[offset + 2], params) || !ValidateAdditionalData(env, mode, args[offset + 3], params)) { return Nothing(); @@ -510,12 +514,6 @@ Maybe AESCipherTraits::AdditionalConfig( UseDefaultIV(params); } - params->cipher = EVP_get_cipherbynid(cipher_nid); - if (params->cipher == nullptr) { - THROW_ERR_CRYPTO_UNKNOWN_CIPHER(env); - return Nothing(); - } - if (params->iv.size() < static_cast(EVP_CIPHER_iv_length(params->cipher))) { THROW_ERR_CRYPTO_INVALID_IV(env); @@ -532,7 +530,7 @@ WebCryptoCipherStatus AESCipherTraits::DoCipher( const AESCipherConfig& params, const ByteSource& in, ByteSource* out) { -#define V(name, fn, _, __) \ +#define V(name, fn, _) \ case kKeyVariantAES_##name: \ return fn(env, key_data.get(), cipher_mode, params, in, out); switch (params.variant) { @@ -546,7 +544,7 @@ WebCryptoCipherStatus AESCipherTraits::DoCipher( void AES::Initialize(Environment* env, Local target) { AESCryptoJob::Initialize(env, target); -#define V(name, _, __, ___) NODE_DEFINE_CONSTANT(target, kKeyVariantAES_##name); +#define V(name, _, __) NODE_DEFINE_CONSTANT(target, kKeyVariantAES_##name); VARIANTS(V) #undef V } diff --git a/src/crypto/crypto_aes.h b/src/crypto/crypto_aes.h index 2ddbc14b8e6..a9ec45c2660 100644 --- a/src/crypto/crypto_aes.h +++ b/src/crypto/crypto_aes.h @@ -15,29 +15,22 @@ constexpr size_t kAesBlockSize = 16; constexpr unsigned kNoAuthTagLength = static_cast(-1); constexpr const char* kDefaultWrapIV = "\xa6\xa6\xa6\xa6\xa6\xa6\xa6\xa6"; -enum class AESCipherMode { - CTR, - CBC, - GCM, - KW, -}; - #define VARIANTS(V) \ - V(CTR_128, AES_CTR_Cipher, AESCipherMode::CTR, NID_aes_128_ctr) \ - V(CTR_192, AES_CTR_Cipher, AESCipherMode::CTR, NID_aes_192_ctr) \ - V(CTR_256, AES_CTR_Cipher, AESCipherMode::CTR, NID_aes_256_ctr) \ - V(CBC_128, AES_Cipher, AESCipherMode::CBC, NID_aes_128_cbc) \ - V(CBC_192, AES_Cipher, AESCipherMode::CBC, NID_aes_192_cbc) \ - V(CBC_256, AES_Cipher, AESCipherMode::CBC, NID_aes_256_cbc) \ - V(GCM_128, AES_Cipher, AESCipherMode::GCM, NID_aes_128_gcm) \ - V(GCM_192, AES_Cipher, AESCipherMode::GCM, NID_aes_192_gcm) \ - V(GCM_256, AES_Cipher, AESCipherMode::GCM, NID_aes_256_gcm) \ - V(KW_128, AES_Cipher, AESCipherMode::KW, NID_id_aes128_wrap) \ - V(KW_192, AES_Cipher, AESCipherMode::KW, NID_id_aes192_wrap) \ - V(KW_256, AES_Cipher, AESCipherMode::KW, NID_id_aes256_wrap) + V(CTR_128, AES_CTR_Cipher, NID_aes_128_ctr) \ + V(CTR_192, AES_CTR_Cipher, NID_aes_192_ctr) \ + V(CTR_256, AES_CTR_Cipher, NID_aes_256_ctr) \ + V(CBC_128, AES_Cipher, NID_aes_128_cbc) \ + V(CBC_192, AES_Cipher, NID_aes_192_cbc) \ + V(CBC_256, AES_Cipher, NID_aes_256_cbc) \ + V(GCM_128, AES_Cipher, NID_aes_128_gcm) \ + V(GCM_192, AES_Cipher, NID_aes_192_gcm) \ + V(GCM_256, AES_Cipher, NID_aes_256_gcm) \ + V(KW_128, AES_Cipher, NID_id_aes128_wrap) \ + V(KW_192, AES_Cipher, NID_id_aes192_wrap) \ + V(KW_256, AES_Cipher, NID_id_aes256_wrap) enum AESKeyVariant { -#define V(name, _, __, ___) kKeyVariantAES_##name, +#define V(name, _, __) kKeyVariantAES_##name, VARIANTS(V) #undef V }; diff --git a/src/crypto/crypto_cipher.cc b/src/crypto/crypto_cipher.cc index 67cd4f2adf1..4f0637f9511 100644 --- a/src/crypto/crypto_cipher.cc +++ b/src/crypto/crypto_cipher.cc @@ -448,7 +448,7 @@ void CipherBase::Init(const char* cipher_type, void CipherBase::Init(const FunctionCallbackInfo& args) { CipherBase* cipher; - ASSIGN_OR_RETURN_UNWRAP(&cipher, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&cipher, args.This()); Environment* env = Environment::GetCurrent(args); CHECK_GE(args.Length(), 3); @@ -520,7 +520,7 @@ void CipherBase::InitIv(const char* cipher_type, void CipherBase::InitIv(const FunctionCallbackInfo& args) { CipherBase* cipher; - ASSIGN_OR_RETURN_UNWRAP(&cipher, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&cipher, args.This()); Environment* env = cipher->env(); CHECK_GE(args.Length(), 4); @@ -655,7 +655,7 @@ bool CipherBase::IsAuthenticatedMode() const { void CipherBase::GetAuthTag(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); CipherBase* cipher; - ASSIGN_OR_RETURN_UNWRAP(&cipher, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&cipher, args.This()); // Only callable after Final and if encrypting. if (cipher->ctx_ || @@ -671,7 +671,7 @@ void CipherBase::GetAuthTag(const FunctionCallbackInfo& args) { void CipherBase::SetAuthTag(const FunctionCallbackInfo& args) { CipherBase* cipher; - ASSIGN_OR_RETURN_UNWRAP(&cipher, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&cipher, args.This()); Environment* env = Environment::GetCurrent(args); if (!cipher->ctx_ || @@ -784,7 +784,7 @@ bool CipherBase::SetAAD( void CipherBase::SetAAD(const FunctionCallbackInfo& args) { CipherBase* cipher; - ASSIGN_OR_RETURN_UNWRAP(&cipher, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&cipher, args.This()); Environment* env = Environment::GetCurrent(args); CHECK_EQ(args.Length(), 2); @@ -897,7 +897,7 @@ bool CipherBase::SetAutoPadding(bool auto_padding) { void CipherBase::SetAutoPadding(const FunctionCallbackInfo& args) { CipherBase* cipher; - ASSIGN_OR_RETURN_UNWRAP(&cipher, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&cipher, args.This()); bool b = cipher->SetAutoPadding(args.Length() < 1 || args[0]->IsTrue()); args.GetReturnValue().Set(b); // Possibly report invalid state failure @@ -972,7 +972,7 @@ void CipherBase::Final(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); CipherBase* cipher; - ASSIGN_OR_RETURN_UNWRAP(&cipher, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&cipher, args.This()); if (cipher->ctx_ == nullptr) return THROW_ERR_CRYPTO_INVALID_STATE(env); diff --git a/src/crypto/crypto_context.cc b/src/crypto/crypto_context.cc index e26e64834be..cef0c877c67 100644 --- a/src/crypto/crypto_context.cc +++ b/src/crypto/crypto_context.cc @@ -273,6 +273,8 @@ Local SecureContext::GetConstructorTemplate( SetProtoMethod(isolate, tmpl, "setKey", SetKey); SetProtoMethod(isolate, tmpl, "setCert", SetCert); SetProtoMethod(isolate, tmpl, "addCACert", AddCACert); + SetProtoMethod( + isolate, tmpl, "setAllowPartialTrustChain", SetAllowPartialTrustChain); SetProtoMethod(isolate, tmpl, "addCRL", AddCRL); SetProtoMethod(isolate, tmpl, "addRootCerts", AddRootCerts); SetProtoMethod(isolate, tmpl, "setCipherSuites", SetCipherSuites); @@ -354,6 +356,7 @@ void SecureContext::RegisterExternalReferences( registry->Register(AddCACert); registry->Register(AddCRL); registry->Register(AddRootCerts); + registry->Register(SetAllowPartialTrustChain); registry->Register(SetCipherSuites); registry->Register(SetCiphers); registry->Register(SetSigalgs); @@ -422,7 +425,7 @@ void SecureContext::New(const FunctionCallbackInfo& args) { void SecureContext::Init(const FunctionCallbackInfo& args) { SecureContext* sc; - ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&sc, args.This()); Environment* env = sc->env(); CHECK_EQ(args.Length(), 3); @@ -595,7 +598,7 @@ void SecureContext::SetKey(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); SecureContext* sc; - ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&sc, args.This()); CHECK_GE(args.Length(), 1); // Private key argument is mandatory @@ -626,7 +629,7 @@ void SecureContext::SetKey(const FunctionCallbackInfo& args) { void SecureContext::SetSigalgs(const FunctionCallbackInfo& args) { SecureContext* sc; - ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&sc, args.This()); Environment* env = sc->env(); ClearErrorOnReturn clear_error_on_return; @@ -644,7 +647,7 @@ void SecureContext::SetEngineKey(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); SecureContext* sc; - ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&sc, args.This()); CHECK_EQ(args.Length(), 2); @@ -707,7 +710,7 @@ void SecureContext::SetCert(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); SecureContext* sc; - ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&sc, args.This()); CHECK_GE(args.Length(), 1); // Certificate argument is mandatory @@ -715,17 +718,39 @@ void SecureContext::SetCert(const FunctionCallbackInfo& args) { USE(sc->AddCert(env, std::move(bio))); } +// NOLINTNEXTLINE(runtime/int) +void SecureContext::SetX509StoreFlag(unsigned long flags) { + X509_STORE* cert_store = GetCertStoreOwnedByThisSecureContext(); + CHECK_EQ(1, X509_STORE_set_flags(cert_store, flags)); +} + +X509_STORE* SecureContext::GetCertStoreOwnedByThisSecureContext() { + if (own_cert_store_cache_ != nullptr) return own_cert_store_cache_; + + X509_STORE* cert_store = SSL_CTX_get_cert_store(ctx_.get()); + if (cert_store == GetOrCreateRootCertStore()) { + cert_store = NewRootCertStore(); + SSL_CTX_set_cert_store(ctx_.get(), cert_store); + } + + return own_cert_store_cache_ = cert_store; +} + +void SecureContext::SetAllowPartialTrustChain( + const FunctionCallbackInfo& args) { + SecureContext* sc; + ASSIGN_OR_RETURN_UNWRAP(&sc, args.This()); + sc->SetX509StoreFlag(X509_V_FLAG_PARTIAL_CHAIN); +} + void SecureContext::SetCACert(const BIOPointer& bio) { ClearErrorOnReturn clear_error_on_return; if (!bio) return; - X509_STORE* cert_store = SSL_CTX_get_cert_store(ctx_.get()); while (X509Pointer x509 = X509Pointer(PEM_read_bio_X509_AUX( bio.get(), nullptr, NoPasswordCallback, nullptr))) { - if (cert_store == GetOrCreateRootCertStore()) { - cert_store = NewRootCertStore(); - SSL_CTX_set_cert_store(ctx_.get(), cert_store); - } - CHECK_EQ(1, X509_STORE_add_cert(cert_store, x509.get())); + CHECK_EQ(1, + X509_STORE_add_cert(GetCertStoreOwnedByThisSecureContext(), + x509.get())); CHECK_EQ(1, SSL_CTX_add_client_CA(ctx_.get(), x509.get())); } } @@ -734,7 +759,7 @@ void SecureContext::AddCACert(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); SecureContext* sc; - ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&sc, args.This()); CHECK_GE(args.Length(), 1); // CA certificate argument is mandatory @@ -754,11 +779,7 @@ Maybe SecureContext::SetCRL(Environment* env, const BIOPointer& bio) { return Nothing(); } - X509_STORE* cert_store = SSL_CTX_get_cert_store(ctx_.get()); - if (cert_store == GetOrCreateRootCertStore()) { - cert_store = NewRootCertStore(); - SSL_CTX_set_cert_store(ctx_.get(), cert_store); - } + X509_STORE* cert_store = GetCertStoreOwnedByThisSecureContext(); CHECK_EQ(1, X509_STORE_add_crl(cert_store, crl.get())); CHECK_EQ(1, @@ -771,7 +792,7 @@ void SecureContext::AddCRL(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); SecureContext* sc; - ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&sc, args.This()); CHECK_GE(args.Length(), 1); // CRL argument is mandatory @@ -790,7 +811,7 @@ void SecureContext::SetRootCerts() { void SecureContext::AddRootCerts(const FunctionCallbackInfo& args) { SecureContext* sc; - ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&sc, args.This()); sc->SetRootCerts(); } @@ -798,7 +819,7 @@ void SecureContext::SetCipherSuites(const FunctionCallbackInfo& args) { // BoringSSL doesn't allow API config of TLS1.3 cipher suites. #ifndef OPENSSL_IS_BORINGSSL SecureContext* sc; - ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&sc, args.This()); Environment* env = sc->env(); ClearErrorOnReturn clear_error_on_return; @@ -813,7 +834,7 @@ void SecureContext::SetCipherSuites(const FunctionCallbackInfo& args) { void SecureContext::SetCiphers(const FunctionCallbackInfo& args) { SecureContext* sc; - ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&sc, args.This()); Environment* env = sc->env(); ClearErrorOnReturn clear_error_on_return; @@ -837,7 +858,7 @@ void SecureContext::SetCiphers(const FunctionCallbackInfo& args) { void SecureContext::SetECDHCurve(const FunctionCallbackInfo& args) { SecureContext* sc; - ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&sc, args.This()); Environment* env = sc->env(); CHECK_GE(args.Length(), 1); // ECDH curve name argument is mandatory @@ -899,7 +920,7 @@ void SecureContext::SetDHParam(const FunctionCallbackInfo& args) { void SecureContext::SetMinProto(const FunctionCallbackInfo& args) { SecureContext* sc; - ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&sc, args.This()); CHECK_EQ(args.Length(), 1); CHECK(args[0]->IsInt32()); @@ -911,7 +932,7 @@ void SecureContext::SetMinProto(const FunctionCallbackInfo& args) { void SecureContext::SetMaxProto(const FunctionCallbackInfo& args) { SecureContext* sc; - ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&sc, args.This()); CHECK_EQ(args.Length(), 1); CHECK(args[0]->IsInt32()); @@ -923,7 +944,7 @@ void SecureContext::SetMaxProto(const FunctionCallbackInfo& args) { void SecureContext::GetMinProto(const FunctionCallbackInfo& args) { SecureContext* sc; - ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&sc, args.This()); CHECK_EQ(args.Length(), 0); @@ -934,7 +955,7 @@ void SecureContext::GetMinProto(const FunctionCallbackInfo& args) { void SecureContext::GetMaxProto(const FunctionCallbackInfo& args) { SecureContext* sc; - ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&sc, args.This()); CHECK_EQ(args.Length(), 0); @@ -946,7 +967,7 @@ void SecureContext::GetMaxProto(const FunctionCallbackInfo& args) { void SecureContext::SetOptions(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); SecureContext* sc; - ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&sc, args.This()); CHECK_GE(args.Length(), 1); CHECK(args[0]->IsNumber()); @@ -960,7 +981,7 @@ void SecureContext::SetOptions(const FunctionCallbackInfo& args) { void SecureContext::SetSessionIdContext( const FunctionCallbackInfo& args) { SecureContext* sc; - ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&sc, args.This()); Environment* env = sc->env(); CHECK_GE(args.Length(), 1); @@ -992,7 +1013,7 @@ void SecureContext::SetSessionIdContext( void SecureContext::SetSessionTimeout(const FunctionCallbackInfo& args) { SecureContext* sc; - ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&sc, args.This()); CHECK_GE(args.Length(), 1); CHECK(args[0]->IsInt32()); @@ -1004,7 +1025,7 @@ void SecureContext::SetSessionTimeout(const FunctionCallbackInfo& args) { void SecureContext::Close(const FunctionCallbackInfo& args) { SecureContext* sc; - ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&sc, args.This()); sc->Reset(); } @@ -1016,7 +1037,7 @@ void SecureContext::LoadPKCS12(const FunctionCallbackInfo& args) { bool ret = false; SecureContext* sc; - ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&sc, args.This()); ClearErrorOnReturn clear_error_on_return; if (args.Length() < 1) { @@ -1042,8 +1063,6 @@ void SecureContext::LoadPKCS12(const FunctionCallbackInfo& args) { sc->issuer_.reset(); sc->cert_.reset(); - X509_STORE* cert_store = SSL_CTX_get_cert_store(sc->ctx_.get()); - DeleteFnPtr p12; EVPKeyPointer pkey; X509Pointer cert; @@ -1097,11 +1116,7 @@ void SecureContext::LoadPKCS12(const FunctionCallbackInfo& args) { for (int i = 0; i < sk_X509_num(extra_certs.get()); i++) { X509* ca = sk_X509_value(extra_certs.get(), i); - if (cert_store == GetOrCreateRootCertStore()) { - cert_store = NewRootCertStore(); - SSL_CTX_set_cert_store(sc->ctx_.get(), cert_store); - } - X509_STORE_add_cert(cert_store, ca); + X509_STORE_add_cert(sc->GetCertStoreOwnedByThisSecureContext(), ca); SSL_CTX_add_client_CA(sc->ctx_.get(), ca); } ret = true; @@ -1110,6 +1125,16 @@ void SecureContext::LoadPKCS12(const FunctionCallbackInfo& args) { if (!ret) { // TODO(@jasnell): Should this use ThrowCryptoError? unsigned long err = ERR_get_error(); // NOLINT(runtime/int) + +#if OPENSSL_VERSION_MAJOR >= 3 + if (ERR_GET_REASON(err) == ERR_R_UNSUPPORTED) { + // OpenSSL's "unsupported" error without any context is very + // common and not very helpful, so we override it: + return THROW_ERR_CRYPTO_UNSUPPORTED_OPERATION( + env, "Unsupported PKCS12 PFX data"); + } +#endif + const char* str = ERR_reason_error_string(err); str = str != nullptr ? str : "Unknown error"; @@ -1125,7 +1150,7 @@ void SecureContext::SetClientCertEngine( CHECK(args[0]->IsString()); SecureContext* sc; - ASSIGN_OR_RETURN_UNWRAP(&sc, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&sc, args.This()); MarkPopErrorOnReturn mark_pop_error_on_return; @@ -1162,7 +1187,7 @@ void SecureContext::SetClientCertEngine( void SecureContext::GetTicketKeys(const FunctionCallbackInfo& args) { SecureContext* wrap; - ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&wrap, args.This()); Local buff; if (!Buffer::New(wrap->env(), 48).ToLocal(&buff)) @@ -1177,7 +1202,7 @@ void SecureContext::GetTicketKeys(const FunctionCallbackInfo& args) { void SecureContext::SetTicketKeys(const FunctionCallbackInfo& args) { SecureContext* wrap; - ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&wrap, args.This()); CHECK_GE(args.Length(), 1); // Ticket keys argument is mandatory CHECK(args[0]->IsArrayBufferView()); @@ -1197,7 +1222,7 @@ void SecureContext::SetTicketKeys(const FunctionCallbackInfo& args) { void SecureContext::EnableTicketKeyCallback( const FunctionCallbackInfo& args) { SecureContext* wrap; - ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&wrap, args.This()); SSL_CTX_set_tlsext_ticket_key_cb(wrap->ctx_.get(), TicketKeyCallback); } @@ -1351,7 +1376,7 @@ void SecureContext::CtxGetter(const FunctionCallbackInfo& info) { template void SecureContext::GetCertificate(const FunctionCallbackInfo& args) { SecureContext* wrap; - ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&wrap, args.This()); Environment* env = wrap->env(); X509* cert; diff --git a/src/crypto/crypto_context.h b/src/crypto/crypto_context.h index 607b0984ba6..4c76bdc5ec1 100644 --- a/src/crypto/crypto_context.h +++ b/src/crypto/crypto_context.h @@ -65,6 +65,9 @@ class SecureContext final : public BaseObject { void SetCACert(const BIOPointer& bio); void SetRootCerts(); + void SetX509StoreFlag(unsigned long flags); // NOLINT(runtime/int) + X509_STORE* GetCertStoreOwnedByThisSecureContext(); + // TODO(joyeecheung): track the memory used by OpenSSL types SET_NO_MEMORY_INFO() SET_MEMORY_INFO_NAME(SecureContext) @@ -91,6 +94,8 @@ class SecureContext final : public BaseObject { #endif // !OPENSSL_NO_ENGINE static void SetCert(const v8::FunctionCallbackInfo& args); static void AddCACert(const v8::FunctionCallbackInfo& args); + static void SetAllowPartialTrustChain( + const v8::FunctionCallbackInfo& args); static void AddCRL(const v8::FunctionCallbackInfo& args); static void AddRootCerts(const v8::FunctionCallbackInfo& args); static void SetCipherSuites(const v8::FunctionCallbackInfo& args); @@ -143,6 +148,8 @@ class SecureContext final : public BaseObject { SSLCtxPointer ctx_; X509Pointer cert_; X509Pointer issuer_; + // Non-owning cache for SSL_CTX_get_cert_store(ctx_.get()) + X509_STORE* own_cert_store_cache_ = nullptr; #ifndef OPENSSL_NO_ENGINE bool client_cert_engine_provided_ = false; EnginePointer private_key_engine_; diff --git a/src/crypto/crypto_dh.cc b/src/crypto/crypto_dh.cc index b4447102a84..dac37f52b96 100644 --- a/src/crypto/crypto_dh.cc +++ b/src/crypto/crypto_dh.cc @@ -292,7 +292,7 @@ void DiffieHellman::GenerateKeys(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); DiffieHellman* diffieHellman; - ASSIGN_OR_RETURN_UNWRAP(&diffieHellman, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&diffieHellman, args.This()); if (!DH_generate_key(diffieHellman->dh_.get())) { return ThrowCryptoError(env, ERR_get_error(), "Key generation failed"); @@ -327,7 +327,7 @@ void DiffieHellman::GetField(const FunctionCallbackInfo& args, Environment* env = Environment::GetCurrent(args); DiffieHellman* dh; - ASSIGN_OR_RETURN_UNWRAP(&dh, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&dh, args.This()); const BIGNUM* num = get_field(dh->dh_.get()); if (num == nullptr) @@ -388,7 +388,7 @@ void DiffieHellman::ComputeSecret(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); DiffieHellman* diffieHellman; - ASSIGN_OR_RETURN_UNWRAP(&diffieHellman, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&diffieHellman, args.This()); ClearErrorOnReturn clear_error_on_return; @@ -447,7 +447,7 @@ void DiffieHellman::SetKey(const FunctionCallbackInfo& args, int (*set_field)(DH*, BIGNUM*), const char* what) { Environment* env = Environment::GetCurrent(args); DiffieHellman* dh; - ASSIGN_OR_RETURN_UNWRAP(&dh, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&dh, args.This()); CHECK_EQ(args.Length(), 1); ArrayBufferOrViewContents buf(args[0]); if (UNLIKELY(!buf.CheckSizeInt32())) @@ -473,7 +473,7 @@ void DiffieHellman::VerifyErrorGetter(const FunctionCallbackInfo& args) { HandleScope scope(args.GetIsolate()); DiffieHellman* diffieHellman; - ASSIGN_OR_RETURN_UNWRAP(&diffieHellman, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&diffieHellman, args.This()); args.GetReturnValue().Set(diffieHellman->verifyError_); } diff --git a/src/crypto/crypto_ec.cc b/src/crypto/crypto_ec.cc index 98273ac4eea..e8653c7db88 100644 --- a/src/crypto/crypto_ec.cc +++ b/src/crypto/crypto_ec.cc @@ -155,7 +155,7 @@ void ECDH::GenerateKeys(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); ECDH* ecdh; - ASSIGN_OR_RETURN_UNWRAP(&ecdh, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&ecdh, args.This()); if (!EC_KEY_generate_key(ecdh->key_.get())) return THROW_ERR_CRYPTO_OPERATION_FAILED(env, "Failed to generate key"); @@ -196,7 +196,7 @@ void ECDH::ComputeSecret(const FunctionCallbackInfo& args) { CHECK(IsAnyBufferSource(args[0])); ECDH* ecdh; - ASSIGN_OR_RETURN_UNWRAP(&ecdh, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&ecdh, args.This()); MarkPopErrorOnReturn mark_pop_error_on_return; @@ -240,7 +240,7 @@ void ECDH::GetPublicKey(const FunctionCallbackInfo& args) { CHECK_EQ(args.Length(), 1); ECDH* ecdh; - ASSIGN_OR_RETURN_UNWRAP(&ecdh, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&ecdh, args.This()); const EC_GROUP* group = EC_KEY_get0_group(ecdh->key_.get()); const EC_POINT* pub = EC_KEY_get0_public_key(ecdh->key_.get()); @@ -263,7 +263,7 @@ void ECDH::GetPrivateKey(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); ECDH* ecdh; - ASSIGN_OR_RETURN_UNWRAP(&ecdh, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&ecdh, args.This()); const BIGNUM* b = EC_KEY_get0_private_key(ecdh->key_.get()); if (b == nullptr) @@ -289,7 +289,7 @@ void ECDH::SetPrivateKey(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); ECDH* ecdh; - ASSIGN_OR_RETURN_UNWRAP(&ecdh, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&ecdh, args.This()); ArrayBufferOrViewContents priv_buffer(args[0]); if (UNLIKELY(!priv_buffer.CheckSizeInt32())) @@ -345,7 +345,7 @@ void ECDH::SetPublicKey(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); ECDH* ecdh; - ASSIGN_OR_RETURN_UNWRAP(&ecdh, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&ecdh, args.This()); CHECK(IsAnyBufferSource(args[0])); @@ -398,8 +398,7 @@ void ECDH::ConvertKey(const FunctionCallbackInfo& args) { ArrayBufferOrViewContents args0(args[0]); if (UNLIKELY(!args0.CheckSizeInt32())) return THROW_ERR_OUT_OF_RANGE(env, "key is too big"); - if (args0.size() == 0) - return args.GetReturnValue().SetEmptyString(); + if (args0.empty()) return args.GetReturnValue().SetEmptyString(); node::Utf8Value curve(env->isolate(), args[1]); diff --git a/src/crypto/crypto_hash.cc b/src/crypto/crypto_hash.cc index 46086018b60..09ed2002996 100644 --- a/src/crypto/crypto_hash.cc +++ b/src/crypto/crypto_hash.cc @@ -378,7 +378,7 @@ void Hash::HashDigest(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); Hash* hash; - ASSIGN_OR_RETURN_UNWRAP(&hash, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&hash, args.This()); enum encoding encoding = BUFFER; if (args.Length() >= 1) { diff --git a/src/crypto/crypto_hmac.cc b/src/crypto/crypto_hmac.cc index b101d5c7b08..86315374fdf 100644 --- a/src/crypto/crypto_hmac.cc +++ b/src/crypto/crypto_hmac.cc @@ -85,7 +85,7 @@ void Hmac::HmacInit(const char* hash_type, const char* key, int key_len) { void Hmac::HmacInit(const FunctionCallbackInfo& args) { Hmac* hmac; - ASSIGN_OR_RETURN_UNWRAP(&hmac, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&hmac, args.This()); Environment* env = hmac->env(); const node::Utf8Value hash_type(env->isolate(), args[0]); @@ -114,7 +114,7 @@ void Hmac::HmacDigest(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); Hmac* hmac; - ASSIGN_OR_RETURN_UNWRAP(&hmac, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&hmac, args.This()); enum encoding encoding = BUFFER; if (args.Length() >= 1) { diff --git a/src/crypto/crypto_keys.cc b/src/crypto/crypto_keys.cc index ce28ec8f37a..35474c31bfc 100644 --- a/src/crypto/crypto_keys.cc +++ b/src/crypto/crypto_keys.cc @@ -969,7 +969,7 @@ KeyObjectHandle::KeyObjectHandle(Environment* env, void KeyObjectHandle::Init(const FunctionCallbackInfo& args) { KeyObjectHandle* key; - ASSIGN_OR_RETURN_UNWRAP(&key, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&key, args.This()); MarkPopErrorOnReturn mark_pop_error_on_return; CHECK(args[0]->IsInt32()); @@ -1013,7 +1013,7 @@ void KeyObjectHandle::Init(const FunctionCallbackInfo& args) { void KeyObjectHandle::InitJWK(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); KeyObjectHandle* key; - ASSIGN_OR_RETURN_UNWRAP(&key, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&key, args.This()); MarkPopErrorOnReturn mark_pop_error_on_return; // The argument must be a JavaScript object that we will inspect @@ -1052,7 +1052,7 @@ void KeyObjectHandle::InitJWK(const FunctionCallbackInfo& args) { void KeyObjectHandle::InitECRaw(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); KeyObjectHandle* key; - ASSIGN_OR_RETURN_UNWRAP(&key, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&key, args.This()); CHECK(args[0]->IsString()); Utf8Value name(env->isolate(), args[0]); @@ -1090,7 +1090,7 @@ void KeyObjectHandle::InitECRaw(const FunctionCallbackInfo& args) { void KeyObjectHandle::InitEDRaw(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); KeyObjectHandle* key; - ASSIGN_OR_RETURN_UNWRAP(&key, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&key, args.This()); CHECK(args[0]->IsString()); Utf8Value name(env->isolate(), args[0]); @@ -1132,7 +1132,7 @@ void KeyObjectHandle::InitEDRaw(const FunctionCallbackInfo& args) { void KeyObjectHandle::Equals(const FunctionCallbackInfo& args) { KeyObjectHandle* self_handle; KeyObjectHandle* arg_handle; - ASSIGN_OR_RETURN_UNWRAP(&self_handle, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&self_handle, args.This()); ASSIGN_OR_RETURN_UNWRAP(&arg_handle, args[0].As()); std::shared_ptr key = self_handle->Data(); std::shared_ptr key2 = arg_handle->Data(); @@ -1180,7 +1180,7 @@ void KeyObjectHandle::Equals(const FunctionCallbackInfo& args) { void KeyObjectHandle::GetKeyDetail(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); KeyObjectHandle* key; - ASSIGN_OR_RETURN_UNWRAP(&key, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&key, args.This()); CHECK(args[0]->IsObject()); @@ -1233,7 +1233,7 @@ Local KeyObjectHandle::GetAsymmetricKeyType() const { void KeyObjectHandle::GetAsymmetricKeyType( const FunctionCallbackInfo& args) { KeyObjectHandle* key; - ASSIGN_OR_RETURN_UNWRAP(&key, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&key, args.This()); args.GetReturnValue().Set(key->GetAsymmetricKeyType()); } @@ -1261,7 +1261,7 @@ bool KeyObjectHandle::CheckEcKeyData() const { void KeyObjectHandle::CheckEcKeyData(const FunctionCallbackInfo& args) { KeyObjectHandle* key; - ASSIGN_OR_RETURN_UNWRAP(&key, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&key, args.This()); args.GetReturnValue().Set(key->CheckEcKeyData()); } @@ -1269,14 +1269,14 @@ void KeyObjectHandle::CheckEcKeyData(const FunctionCallbackInfo& args) { void KeyObjectHandle::GetSymmetricKeySize( const FunctionCallbackInfo& args) { KeyObjectHandle* key; - ASSIGN_OR_RETURN_UNWRAP(&key, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&key, args.This()); args.GetReturnValue().Set( static_cast(key->Data()->GetSymmetricKeySize())); } void KeyObjectHandle::Export(const FunctionCallbackInfo& args) { KeyObjectHandle* key; - ASSIGN_OR_RETURN_UNWRAP(&key, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&key, args.This()); KeyType type = key->Data()->GetKeyType(); @@ -1326,7 +1326,7 @@ void KeyObjectHandle::ExportJWK( const v8::FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); KeyObjectHandle* key; - ASSIGN_OR_RETURN_UNWRAP(&key, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&key, args.This()); CHECK(args[0]->IsObject()); CHECK(args[1]->IsBoolean()); diff --git a/src/crypto/crypto_sig.cc b/src/crypto/crypto_sig.cc index ab020efbaeb..fa4ba62f8f9 100644 --- a/src/crypto/crypto_sig.cc +++ b/src/crypto/crypto_sig.cc @@ -92,12 +92,15 @@ std::unique_ptr Node_SignFinal(Environment* env, sig = ArrayBuffer::NewBackingStore(env->isolate(), sig_len); } EVPKeyCtxPointer pkctx(EVP_PKEY_CTX_new(pkey.get(), nullptr)); - if (pkctx && - EVP_PKEY_sign_init(pkctx.get()) && + if (pkctx && EVP_PKEY_sign_init(pkctx.get()) > 0 && ApplyRSAOptions(pkey, pkctx.get(), padding, pss_salt_len) && - EVP_PKEY_CTX_set_signature_md(pkctx.get(), EVP_MD_CTX_md(mdctx.get())) && - EVP_PKEY_sign(pkctx.get(), static_cast(sig->Data()), - &sig_len, m, m_len)) { + EVP_PKEY_CTX_set_signature_md(pkctx.get(), EVP_MD_CTX_md(mdctx.get())) > + 0 && + EVP_PKEY_sign(pkctx.get(), + static_cast(sig->Data()), + &sig_len, + m, + m_len) > 0) { CHECK_LE(sig_len, sig->ByteLength()); if (sig_len == 0) { sig = ArrayBuffer::NewBackingStore(env->isolate(), 0); @@ -371,7 +374,7 @@ void Sign::New(const FunctionCallbackInfo& args) { void Sign::SignInit(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); Sign* sign; - ASSIGN_OR_RETURN_UNWRAP(&sign, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&sign, args.This()); const node::Utf8Value sign_type(args.GetIsolate(), args[0]); crypto::CheckThrow(env, sign->Init(*sign_type)); @@ -414,7 +417,7 @@ Sign::SignResult Sign::SignFinal( void Sign::SignFinal(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); Sign* sign; - ASSIGN_OR_RETURN_UNWRAP(&sign, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&sign, args.This()); ClearErrorOnReturn clear_error_on_return; @@ -492,7 +495,7 @@ void Verify::New(const FunctionCallbackInfo& args) { void Verify::VerifyInit(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); Verify* verify; - ASSIGN_OR_RETURN_UNWRAP(&verify, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&verify, args.This()); const node::Utf8Value verify_type(args.GetIsolate(), args[0]); crypto::CheckThrow(env, verify->Init(*verify_type)); @@ -527,14 +530,18 @@ SignBase::Error Verify::VerifyFinal(const ManagedEVPPKey& pkey, return kSignPublicKey; EVPKeyCtxPointer pkctx(EVP_PKEY_CTX_new(pkey.get(), nullptr)); - if (pkctx && - EVP_PKEY_verify_init(pkctx.get()) > 0 && - ApplyRSAOptions(pkey, pkctx.get(), padding, saltlen) && - EVP_PKEY_CTX_set_signature_md(pkctx.get(), - EVP_MD_CTX_md(mdctx.get())) > 0) { - const unsigned char* s = sig.data(); - const int r = EVP_PKEY_verify(pkctx.get(), s, sig.size(), m, m_len); - *verify_result = r == 1; + if (pkctx) { + const int init_ret = EVP_PKEY_verify_init(pkctx.get()); + if (init_ret == -2) { + return kSignPublicKey; + } + if (init_ret > 0 && ApplyRSAOptions(pkey, pkctx.get(), padding, saltlen) && + EVP_PKEY_CTX_set_signature_md(pkctx.get(), EVP_MD_CTX_md(mdctx.get())) > + 0) { + const unsigned char* s = sig.data(); + const int r = EVP_PKEY_verify(pkctx.get(), s, sig.size(), m, m_len); + *verify_result = r == 1; + } } return kSignOk; @@ -545,7 +552,7 @@ void Verify::VerifyFinal(const FunctionCallbackInfo& args) { ClearErrorOnReturn clear_error_on_return; Verify* verify; - ASSIGN_OR_RETURN_UNWRAP(&verify, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&verify, args.This()); unsigned int offset = 0; ManagedEVPPKey pkey = diff --git a/src/crypto/crypto_spkac.cc b/src/crypto/crypto_spkac.cc index 92484847afb..a09a09ddd2f 100644 --- a/src/crypto/crypto_spkac.cc +++ b/src/crypto/crypto_spkac.cc @@ -39,8 +39,7 @@ bool VerifySpkac(const ArrayBufferOrViewContents& input) { void VerifySpkac(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); ArrayBufferOrViewContents input(args[0]); - if (input.size() == 0) - return args.GetReturnValue().SetEmptyString(); + if (input.empty()) return args.GetReturnValue().SetEmptyString(); if (UNLIKELY(!input.CheckSizeInt32())) return THROW_ERR_OUT_OF_RANGE(env, "spkac is too large"); @@ -76,7 +75,7 @@ void ExportPublicKey(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); ArrayBufferOrViewContents input(args[0]); - if (input.size() == 0) return args.GetReturnValue().SetEmptyString(); + if (input.empty()) return args.GetReturnValue().SetEmptyString(); if (UNLIKELY(!input.CheckSizeInt32())) return THROW_ERR_OUT_OF_RANGE(env, "spkac is too large"); @@ -109,8 +108,7 @@ void ExportChallenge(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); ArrayBufferOrViewContents input(args[0]); - if (input.size() == 0) - return args.GetReturnValue().SetEmptyString(); + if (input.empty()) return args.GetReturnValue().SetEmptyString(); if (UNLIKELY(!input.CheckSizeInt32())) return THROW_ERR_OUT_OF_RANGE(env, "spkac is too large"); diff --git a/src/crypto/crypto_tls.cc b/src/crypto/crypto_tls.cc index 5fb66d4e493..9fb567f89c1 100644 --- a/src/crypto/crypto_tls.cc +++ b/src/crypto/crypto_tls.cc @@ -506,7 +506,7 @@ void TLSWrap::Wrap(const FunctionCallbackInfo& args) { void TLSWrap::Receive(const FunctionCallbackInfo& args) { TLSWrap* wrap; - ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&wrap, args.This()); ArrayBufferViewContents buffer(args[0]); const char* data = buffer.data(); @@ -528,7 +528,7 @@ void TLSWrap::Receive(const FunctionCallbackInfo& args) { void TLSWrap::Start(const FunctionCallbackInfo& args) { TLSWrap* wrap; - ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&wrap, args.This()); CHECK(!wrap->started_); wrap->started_ = true; @@ -1155,7 +1155,7 @@ int TLSWrap::DoShutdown(ShutdownWrap* req_wrap) { void TLSWrap::SetVerifyMode(const FunctionCallbackInfo& args) { TLSWrap* wrap; - ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&wrap, args.This()); CHECK_EQ(args.Length(), 2); CHECK(args[0]->IsBoolean()); @@ -1187,7 +1187,7 @@ void TLSWrap::SetVerifyMode(const FunctionCallbackInfo& args) { void TLSWrap::EnableSessionCallbacks(const FunctionCallbackInfo& args) { TLSWrap* wrap; - ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&wrap, args.This()); CHECK_NOT_NULL(wrap->ssl_); wrap->enable_session_callbacks(); @@ -1203,7 +1203,7 @@ void TLSWrap::EnableSessionCallbacks(const FunctionCallbackInfo& args) { void TLSWrap::EnableKeylogCallback(const FunctionCallbackInfo& args) { TLSWrap* wrap; - ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&wrap, args.This()); CHECK(wrap->sc_); wrap->sc_->SetKeylogCallback(KeylogCallback); } @@ -1220,7 +1220,7 @@ void TLSWrap::EnableKeylogCallback(const FunctionCallbackInfo& args) { void TLSWrap::EnableTrace(const FunctionCallbackInfo& args) { TLSWrap* wrap; - ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&wrap, args.This()); #if HAVE_SSL_TRACE if (wrap->ssl_) { @@ -1243,7 +1243,7 @@ void TLSWrap::EnableTrace(const FunctionCallbackInfo& args) { void TLSWrap::DestroySSL(const FunctionCallbackInfo& args) { TLSWrap* wrap; - ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&wrap, args.This()); wrap->Destroy(); Debug(wrap, "DestroySSL() finished"); } @@ -1272,7 +1272,7 @@ void TLSWrap::Destroy() { void TLSWrap::EnableCertCb(const FunctionCallbackInfo& args) { TLSWrap* wrap; - ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&wrap, args.This()); wrap->WaitForCertCb(OnClientHelloParseEnd, wrap); } @@ -1289,7 +1289,7 @@ void TLSWrap::OnClientHelloParseEnd(void* arg) { void TLSWrap::EnableALPNCb(const FunctionCallbackInfo& args) { TLSWrap* wrap; - ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&wrap, args.This()); wrap->alpn_callback_enabled_ = true; SSL* ssl = wrap->ssl_.get(); @@ -1301,7 +1301,7 @@ void TLSWrap::GetServername(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); TLSWrap* wrap; - ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&wrap, args.This()); CHECK_NOT_NULL(wrap->ssl_); @@ -1317,7 +1317,7 @@ void TLSWrap::SetServername(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); TLSWrap* wrap; - ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&wrap, args.This()); CHECK_EQ(args.Length(), 1); CHECK(args[0]->IsString()); @@ -1382,7 +1382,7 @@ int TLSWrap::SetCACerts(SecureContext* sc) { void TLSWrap::SetPskIdentityHint(const FunctionCallbackInfo& args) { TLSWrap* p; - ASSIGN_OR_RETURN_UNWRAP(&p, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&p, args.This()); CHECK_NOT_NULL(p->ssl_); Environment* env = p->env(); @@ -1399,7 +1399,7 @@ void TLSWrap::SetPskIdentityHint(const FunctionCallbackInfo& args) { void TLSWrap::EnablePskCallback(const FunctionCallbackInfo& args) { TLSWrap* wrap; - ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&wrap, args.This()); CHECK_NOT_NULL(wrap->ssl_); SSL_set_psk_server_callback(wrap->ssl_.get(), PskServerCallback); @@ -1533,7 +1533,7 @@ void TLSWrap::MemoryInfo(MemoryTracker* tracker) const { void TLSWrap::CertCbDone(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); TLSWrap* w; - ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&w, args.This()); CHECK(w->is_waiting_cert_cb() && w->cert_cb_running_); @@ -1578,7 +1578,7 @@ void TLSWrap::CertCbDone(const FunctionCallbackInfo& args) { void TLSWrap::SetALPNProtocols(const FunctionCallbackInfo& args) { TLSWrap* w; - ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&w, args.This()); Environment* env = w->env(); if (args.Length() < 1 || !Buffer::HasInstance(args[0])) return env->ThrowTypeError("Must give a Buffer as first argument"); @@ -1624,7 +1624,7 @@ void TLSWrap::SetKeyCert(const FunctionCallbackInfo& args) { void TLSWrap::GetPeerCertificate(const FunctionCallbackInfo& args) { TLSWrap* w; - ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&w, args.This()); Environment* env = w->env(); bool abbreviated = args.Length() < 1 || !args[0]->IsTrue(); @@ -1640,7 +1640,7 @@ void TLSWrap::GetPeerCertificate(const FunctionCallbackInfo& args) { void TLSWrap::GetPeerX509Certificate(const FunctionCallbackInfo& args) { TLSWrap* w; - ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&w, args.This()); Environment* env = w->env(); X509Certificate::GetPeerCertificateFlag flag = w->is_server() @@ -1654,7 +1654,7 @@ void TLSWrap::GetPeerX509Certificate(const FunctionCallbackInfo& args) { void TLSWrap::GetCertificate(const FunctionCallbackInfo& args) { TLSWrap* w; - ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&w, args.This()); Environment* env = w->env(); Local ret; @@ -1664,7 +1664,7 @@ void TLSWrap::GetCertificate(const FunctionCallbackInfo& args) { void TLSWrap::GetX509Certificate(const FunctionCallbackInfo& args) { TLSWrap* w; - ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&w, args.This()); Environment* env = w->env(); Local ret; if (X509Certificate::GetCert(env, w->ssl_).ToLocal(&ret)) @@ -1675,7 +1675,7 @@ void TLSWrap::GetFinished(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); TLSWrap* w; - ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&w, args.This()); // We cannot just pass nullptr to SSL_get_finished() // because it would further be propagated to memcpy(), @@ -1706,7 +1706,7 @@ void TLSWrap::GetPeerFinished(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); TLSWrap* w; - ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&w, args.This()); // We cannot just pass nullptr to SSL_get_peer_finished() // because it would further be propagated to memcpy(), @@ -1737,7 +1737,7 @@ void TLSWrap::GetSession(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); TLSWrap* w; - ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&w, args.This()); SSL_SESSION* sess = SSL_get_session(w->ssl_.get()); if (sess == nullptr) @@ -1766,7 +1766,7 @@ void TLSWrap::SetSession(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); TLSWrap* w; - ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&w, args.This()); if (args.Length() < 1) return THROW_ERR_MISSING_ARGS(env, "Session argument is mandatory"); @@ -1783,7 +1783,7 @@ void TLSWrap::SetSession(const FunctionCallbackInfo& args) { void TLSWrap::IsSessionReused(const FunctionCallbackInfo& args) { TLSWrap* w; - ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&w, args.This()); bool yes = SSL_session_reused(w->ssl_.get()); args.GetReturnValue().Set(yes); } @@ -1791,7 +1791,7 @@ void TLSWrap::IsSessionReused(const FunctionCallbackInfo& args) { void TLSWrap::VerifyError(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); TLSWrap* w; - ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&w, args.This()); // XXX(bnoordhuis) The UNABLE_TO_GET_ISSUER_CERT error when there is no // peer certificate is questionable but it's compatible with what was @@ -1819,14 +1819,14 @@ void TLSWrap::VerifyError(const FunctionCallbackInfo& args) { void TLSWrap::GetCipher(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); TLSWrap* w; - ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&w, args.This()); args.GetReturnValue().Set( GetCipherInfo(env, w->ssl_).FromMaybe(Local())); } void TLSWrap::LoadSession(const FunctionCallbackInfo& args) { TLSWrap* w; - ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&w, args.This()); // TODO(@sam-github) check arg length and types in js, and CHECK in c++ if (args.Length() >= 1 && Buffer::HasInstance(args[0])) { @@ -1843,7 +1843,7 @@ void TLSWrap::LoadSession(const FunctionCallbackInfo& args) { void TLSWrap::GetSharedSigalgs(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); TLSWrap* w; - ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&w, args.This()); SSL* ssl = w->ssl_.get(); int nsig = SSL_get_shared_sigalgs(ssl, 0, nullptr, nullptr, nullptr, nullptr, @@ -1925,7 +1925,7 @@ void TLSWrap::ExportKeyingMaterial(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); TLSWrap* w; - ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&w, args.This()); uint32_t olen = args[0].As()->Value(); Utf8Value label(env->isolate(), args[1]); @@ -1964,13 +1964,13 @@ void TLSWrap::ExportKeyingMaterial(const FunctionCallbackInfo& args) { void TLSWrap::EndParser(const FunctionCallbackInfo& args) { TLSWrap* w; - ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&w, args.This()); w->hello_parser_.End(); } void TLSWrap::Renegotiate(const FunctionCallbackInfo& args) { TLSWrap* w; - ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&w, args.This()); ClearErrorOnReturn clear_error_on_return; if (SSL_renegotiate(w->ssl_.get()) != 1) return ThrowCryptoError(w->env(), ERR_get_error()); @@ -1978,7 +1978,7 @@ void TLSWrap::Renegotiate(const FunctionCallbackInfo& args) { void TLSWrap::GetTLSTicket(const FunctionCallbackInfo& args) { TLSWrap* w; - ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&w, args.This()); Environment* env = w->env(); SSL_SESSION* sess = SSL_get_session(w->ssl_.get()); @@ -1998,14 +1998,14 @@ void TLSWrap::GetTLSTicket(const FunctionCallbackInfo& args) { void TLSWrap::NewSessionDone(const FunctionCallbackInfo& args) { TLSWrap* w; - ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&w, args.This()); w->awaiting_new_session_ = false; w->NewSessionDoneCb(); } void TLSWrap::SetOCSPResponse(const FunctionCallbackInfo& args) { TLSWrap* w; - ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&w, args.This()); Environment* env = w->env(); if (args.Length() < 1) @@ -2018,14 +2018,14 @@ void TLSWrap::SetOCSPResponse(const FunctionCallbackInfo& args) { void TLSWrap::RequestOCSP(const FunctionCallbackInfo& args) { TLSWrap* w; - ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&w, args.This()); SSL_set_tlsext_status_type(w->ssl_.get(), TLSEXT_STATUSTYPE_ocsp); } void TLSWrap::GetEphemeralKeyInfo(const FunctionCallbackInfo& args) { TLSWrap* w; - ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&w, args.This()); Environment* env = Environment::GetCurrent(args); CHECK(w->ssl_); @@ -2044,7 +2044,7 @@ void TLSWrap::GetEphemeralKeyInfo(const FunctionCallbackInfo& args) { void TLSWrap::GetProtocol(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); TLSWrap* w; - ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&w, args.This()); args.GetReturnValue().Set( OneByteString(env->isolate(), SSL_get_version(w->ssl_.get()))); } @@ -2052,7 +2052,7 @@ void TLSWrap::GetProtocol(const FunctionCallbackInfo& args) { void TLSWrap::GetALPNNegotiatedProto(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); TLSWrap* w; - ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&w, args.This()); const unsigned char* alpn_proto; unsigned int alpn_proto_len; @@ -2078,7 +2078,7 @@ void TLSWrap::GetALPNNegotiatedProto(const FunctionCallbackInfo& args) { void TLSWrap::WritesIssuedByPrevListenerDone( const FunctionCallbackInfo& args) { TLSWrap* w; - ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&w, args.This()); Debug(w, "WritesIssuedByPrevListenerDone is called"); w->has_active_write_issued_by_prev_listener_ = false; @@ -2103,7 +2103,7 @@ void TLSWrap::SetMaxSendFragment(const FunctionCallbackInfo& args) { CHECK(args.Length() >= 1 && args[0]->IsNumber()); Environment* env = Environment::GetCurrent(args); TLSWrap* w; - ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&w, args.This()); int rv = SSL_set_max_send_fragment( w->ssl_.get(), args[0]->Int32Value(env->context()).FromJust()); diff --git a/src/crypto/crypto_util.h b/src/crypto/crypto_util.h index 0ae2946e5e5..4ba26101469 100644 --- a/src/crypto/crypto_util.h +++ b/src/crypto/crypto_util.h @@ -136,7 +136,7 @@ void Decode(const v8::FunctionCallbackInfo& args, void (*callback)(T*, const v8::FunctionCallbackInfo&, const char*, size_t)) { T* ctx; - ASSIGN_OR_RETURN_UNWRAP(&ctx, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&ctx, args.This()); if (args[0]->IsString()) { StringBytes::InlineDecoder decoder; @@ -233,6 +233,9 @@ class ByteSource { // Returns the (allocated) size in bytes. size_t size() const { return size_; } + // Returns if (allocated) size is zero. + bool empty() const { return size_ == 0; } + // Finalizes the Builder and returns a read-only view that is optionally // truncated. ByteSource release(std::optional resize = std::nullopt) && { @@ -271,6 +274,8 @@ class ByteSource { size_t size() const { return size_; } + bool empty() const { return size_ == 0; } + operator bool() const { return data_ != nullptr; } BignumPointer ToBN() const { @@ -412,7 +417,7 @@ class CryptoJob : public AsyncWrap, public ThreadPoolWork { Environment* env = Environment::GetCurrent(args); CryptoJob* job; - ASSIGN_OR_RETURN_UNWRAP(&job, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&job, args.This()); if (job->mode() == kCryptoJobAsync) return job->ScheduleWork(); @@ -718,8 +723,7 @@ class ArrayBufferOrViewContents { // Ideally, these would return nullptr if IsEmpty() or length_ is zero, // but some of the openssl API react badly if given a nullptr even when // length is zero, so we have to return something. - if (size() == 0) - return &buf; + if (empty()) return &buf; return reinterpret_cast(data_) + offset_; } @@ -727,13 +731,14 @@ class ArrayBufferOrViewContents { // Ideally, these would return nullptr if IsEmpty() or length_ is zero, // but some of the openssl API react badly if given a nullptr even when // length is zero, so we have to return something. - if (size() == 0) - return &buf; + if (empty()) return &buf; return reinterpret_cast(data_) + offset_; } inline size_t size() const { return length_; } + inline bool empty() const { return length_ == 0; } + // In most cases, input buffer sizes passed in to openssl need to // be limited to <= INT_MAX. This utility method helps us check. inline bool CheckSizeInt32() { return size() <= INT_MAX; } @@ -743,14 +748,14 @@ class ArrayBufferOrViewContents { } inline ByteSource ToCopy() const { - if (size() == 0) return ByteSource(); + if (empty()) return ByteSource(); ByteSource::Builder buf(size()); memcpy(buf.data(), data(), size()); return std::move(buf).release(); } inline ByteSource ToNullTerminatedCopy() const { - if (size() == 0) return ByteSource(); + if (empty()) return ByteSource(); ByteSource::Builder buf(size() + 1); memcpy(buf.data(), data(), size()); buf.data()[size()] = 0; diff --git a/src/crypto/crypto_x509.cc b/src/crypto/crypto_x509.cc index 84f2528a28f..a2fc10f3b32 100644 --- a/src/crypto/crypto_x509.cc +++ b/src/crypto/crypto_x509.cc @@ -56,7 +56,7 @@ template void Fingerprint(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); X509Certificate* cert; - ASSIGN_OR_RETURN_UNWRAP(&cert, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&cert, args.This()); Local ret; if (GetFingerprintDigest(env, algo(), cert->get()).ToLocal(&ret)) args.GetReturnValue().Set(ret); @@ -208,7 +208,7 @@ template Property( static void ReturnPropertyThroughBIO(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); X509Certificate* cert; - ASSIGN_OR_RETURN_UNWRAP(&cert, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&cert, args.This()); BIOPointer bio(BIO_new(BIO_s_mem())); CHECK(bio); Local ret; @@ -244,7 +244,7 @@ template Property(Environment* env, X509* cert)> static void ReturnProperty(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); X509Certificate* cert; - ASSIGN_OR_RETURN_UNWRAP(&cert, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&cert, args.This()); Local ret; if (Property(env, cert->get()).ToLocal(&ret)) args.GetReturnValue().Set(ret); } @@ -264,7 +264,7 @@ void X509Certificate::Raw(const FunctionCallbackInfo& args) { void X509Certificate::PublicKey(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); X509Certificate* cert; - ASSIGN_OR_RETURN_UNWRAP(&cert, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&cert, args.This()); // TODO(tniessen): consider checking X509_get_pubkey() when the // X509Certificate object is being created. @@ -283,7 +283,7 @@ void X509Certificate::PublicKey(const FunctionCallbackInfo& args) { void X509Certificate::Pem(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); X509Certificate* cert; - ASSIGN_OR_RETURN_UNWRAP(&cert, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&cert, args.This()); BIOPointer bio(BIO_new(BIO_s_mem())); CHECK(bio); if (PEM_write_bio_X509(bio.get(), cert->get())) @@ -293,14 +293,14 @@ void X509Certificate::Pem(const FunctionCallbackInfo& args) { void X509Certificate::CheckCA(const FunctionCallbackInfo& args) { X509Certificate* cert; ClearErrorOnReturn clear_error_on_return; - ASSIGN_OR_RETURN_UNWRAP(&cert, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&cert, args.This()); args.GetReturnValue().Set(X509_check_ca(cert->get()) == 1); } void X509Certificate::CheckHost(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); X509Certificate* cert; - ASSIGN_OR_RETURN_UNWRAP(&cert, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&cert, args.This()); CHECK(args[0]->IsString()); // name CHECK(args[1]->IsUint32()); // flags @@ -335,7 +335,7 @@ void X509Certificate::CheckHost(const FunctionCallbackInfo& args) { void X509Certificate::CheckEmail(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); X509Certificate* cert; - ASSIGN_OR_RETURN_UNWRAP(&cert, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&cert, args.This()); CHECK(args[0]->IsString()); // name CHECK(args[1]->IsUint32()); // flags @@ -362,7 +362,7 @@ void X509Certificate::CheckEmail(const FunctionCallbackInfo& args) { void X509Certificate::CheckIP(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); X509Certificate* cert; - ASSIGN_OR_RETURN_UNWRAP(&cert, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&cert, args.This()); CHECK(args[0]->IsString()); // IP CHECK(args[1]->IsUint32()); // flags @@ -385,7 +385,7 @@ void X509Certificate::CheckIP(const FunctionCallbackInfo& args) { void X509Certificate::CheckIssued(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); X509Certificate* cert; - ASSIGN_OR_RETURN_UNWRAP(&cert, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&cert, args.This()); CHECK(args[0]->IsObject()); CHECK(X509Certificate::HasInstance(env, args[0].As())); @@ -401,7 +401,7 @@ void X509Certificate::CheckIssued(const FunctionCallbackInfo& args) { void X509Certificate::CheckPrivateKey(const FunctionCallbackInfo& args) { X509Certificate* cert; - ASSIGN_OR_RETURN_UNWRAP(&cert, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&cert, args.This()); CHECK(args[0]->IsObject()); KeyObjectHandle* key; @@ -418,7 +418,7 @@ void X509Certificate::CheckPrivateKey(const FunctionCallbackInfo& args) { void X509Certificate::Verify(const FunctionCallbackInfo& args) { X509Certificate* cert; - ASSIGN_OR_RETURN_UNWRAP(&cert, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&cert, args.This()); CHECK(args[0]->IsObject()); KeyObjectHandle* key; @@ -436,7 +436,7 @@ void X509Certificate::Verify(const FunctionCallbackInfo& args) { void X509Certificate::ToLegacy(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); X509Certificate* cert; - ASSIGN_OR_RETURN_UNWRAP(&cert, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&cert, args.This()); ClearErrorOnReturn clear_error_on_return; Local ret; if (X509ToObject(env, cert->get()).ToLocal(&ret)) @@ -445,7 +445,7 @@ void X509Certificate::ToLegacy(const FunctionCallbackInfo& args) { void X509Certificate::GetIssuerCert(const FunctionCallbackInfo& args) { X509Certificate* cert; - ASSIGN_OR_RETURN_UNWRAP(&cert, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&cert, args.This()); if (cert->issuer_cert_) args.GetReturnValue().Set(cert->issuer_cert_->object()); } diff --git a/src/env-inl.h b/src/env-inl.h index 18b1461e50e..d98a32d6ec3 100644 --- a/src/env-inl.h +++ b/src/env-inl.h @@ -576,11 +576,6 @@ inline std::shared_ptr IsolateData::options() { return options_; } -inline void IsolateData::set_options( - std::shared_ptr options) { - options_ = std::move(options); -} - template void Environment::SetImmediate(Fn&& cb, CallbackFlags::Flags flags) { auto callback = native_immediates_.CreateCallback(std::move(cb), flags); diff --git a/src/env.cc b/src/env.cc index 36c24677459..ae2eefbdebb 100644 --- a/src/env.cc +++ b/src/env.cc @@ -537,19 +537,35 @@ Mutex IsolateData::isolate_data_mutex_; std::unordered_map> IsolateData::wrapper_data_map_; +IsolateData* IsolateData::CreateIsolateData( + Isolate* isolate, + uv_loop_t* loop, + MultiIsolatePlatform* platform, + ArrayBufferAllocator* allocator, + const EmbedderSnapshotData* embedder_snapshot_data, + std::shared_ptr options) { + const SnapshotData* snapshot_data = + SnapshotData::FromEmbedderWrapper(embedder_snapshot_data); + if (options == nullptr) { + options = per_process::cli_options->per_isolate->Clone(); + } + return new IsolateData( + isolate, loop, platform, allocator, snapshot_data, options); +} + IsolateData::IsolateData(Isolate* isolate, uv_loop_t* event_loop, MultiIsolatePlatform* platform, ArrayBufferAllocator* node_allocator, - const SnapshotData* snapshot_data) + const SnapshotData* snapshot_data, + std::shared_ptr options) : isolate_(isolate), event_loop_(event_loop), node_allocator_(node_allocator == nullptr ? nullptr : node_allocator->GetImpl()), platform_(platform), - snapshot_data_(snapshot_data) { - options_.reset( - new PerIsolateOptions(*(per_process::cli_options->per_isolate))); + snapshot_data_(snapshot_data), + options_(std::move(options)) { v8::CppHeap* cpp_heap = isolate->GetCppHeap(); uint16_t cppgc_id = kDefaultCppGCEmbedderID; @@ -1228,6 +1244,11 @@ void Environment::RunCleanup() { // Defer the BaseObject cleanup after handles are cleaned up. CleanupHandles(); + while (!cleanable_queue_.IsEmpty()) { + Cleanable* cleanable = cleanable_queue_.PopFront(); + cleanable->Clean(); + } + while (!cleanup_queue_.empty() || principal_realm_->HasCleanupHooks() || native_immediates_.size() > 0 || native_immediates_threadsafe_.size() > 0 || diff --git a/src/env.h b/src/env.h index c71f2b0f750..31c10828f46 100644 --- a/src/env.h +++ b/src/env.h @@ -139,12 +139,22 @@ struct PerIsolateWrapperData { }; class NODE_EXTERN_PRIVATE IsolateData : public MemoryRetainer { - public: + private: IsolateData(v8::Isolate* isolate, uv_loop_t* event_loop, - MultiIsolatePlatform* platform = nullptr, - ArrayBufferAllocator* node_allocator = nullptr, - const SnapshotData* snapshot_data = nullptr); + MultiIsolatePlatform* platform, + ArrayBufferAllocator* node_allocator, + const SnapshotData* snapshot_data, + std::shared_ptr options); + + public: + static IsolateData* CreateIsolateData( + v8::Isolate* isolate, + uv_loop_t* event_loop, + MultiIsolatePlatform* platform = nullptr, + ArrayBufferAllocator* node_allocator = nullptr, + const EmbedderSnapshotData* embedder_snapshot_data = nullptr, + std::shared_ptr options = nullptr); ~IsolateData(); SET_MEMORY_INFO_NAME(IsolateData) @@ -173,7 +183,6 @@ class NODE_EXTERN_PRIVATE IsolateData : public MemoryRetainer { inline MultiIsolatePlatform* platform() const; inline const SnapshotData* snapshot_data() const; inline std::shared_ptr options(); - inline void set_options(std::shared_ptr options); inline NodeArrayBufferAllocator* node_allocator() const; @@ -591,6 +600,18 @@ void DefaultProcessExitHandlerInternal(Environment* env, ExitCode exit_code); v8::Maybe SpinEventLoopInternal(Environment* env); v8::Maybe EmitProcessExitInternal(Environment* env); +class Cleanable { + public: + virtual ~Cleanable() = default; + + protected: + ListNode cleanable_queue_; + + private: + virtual void Clean() = 0; + friend class Environment; +}; + /** * Environment is a per-isolate data structure that represents an execution * environment. Each environment has a principal realm. An environment can @@ -897,8 +918,12 @@ class Environment : public MemoryRetainer { typedef ListHead HandleWrapQueue; typedef ListHead ReqWrapQueue; + typedef ListHead CleanableQueue; inline HandleWrapQueue* handle_wrap_queue() { return &handle_wrap_queue_; } + inline CleanableQueue* cleanable_queue() { + return &cleanable_queue_; + } inline ReqWrapQueue* req_wrap_queue() { return &req_wrap_queue_; } // https://w3c.github.io/hr-time/#dfn-time-origin @@ -1176,6 +1201,7 @@ class Environment : public MemoryRetainer { // memory are predictable. For more information please refer to // `doc/contributing/node-postmortem-support.md` friend int GenDebugSymbols(); + CleanableQueue cleanable_queue_; HandleWrapQueue handle_wrap_queue_; ReqWrapQueue req_wrap_queue_; std::list handle_cleanup_queue_; diff --git a/src/env_properties.h b/src/env_properties.h index 96e02cfa0d1..d60e9c9bd2c 100644 --- a/src/env_properties.h +++ b/src/env_properties.h @@ -52,6 +52,7 @@ V(resource_symbol, "resource_symbol") \ V(trigger_async_id_symbol, "trigger_async_id_symbol") \ V(source_text_module_default_hdo, "source_text_module_default_hdo") \ + V(vm_context_no_contextify, "vm_context_no_contextify") \ V(vm_dynamic_import_default_internal, "vm_dynamic_import_default_internal") \ V(vm_dynamic_import_main_context_default, \ "vm_dynamic_import_main_context_default") \ @@ -133,6 +134,8 @@ V(env_var_settings_string, "envVarSettings") \ V(errno_string, "errno") \ V(error_string, "error") \ + V(events, "events") \ + V(events_waiting, "eventsWaiting") \ V(exchange_string, "exchange") \ V(expire_string, "expire") \ V(exponent_string, "exponent") \ @@ -202,6 +205,7 @@ V(kind_string, "kind") \ V(length_string, "length") \ V(library_string, "library") \ + V(loop_count, "loopCount") \ V(mac_string, "mac") \ V(max_buffer_string, "maxBuffer") \ V(max_concurrent_streams_string, "maxConcurrentStreams") \ @@ -426,7 +430,9 @@ V(immediate_callback_function, v8::Function) \ V(inspector_console_extension_installer, v8::Function) \ V(inspector_disable_async_hooks, v8::Function) \ + V(inspector_disable_network_tracking, v8::Function) \ V(inspector_enable_async_hooks, v8::Function) \ + V(inspector_enable_network_tracking, v8::Function) \ V(maybe_cache_generated_source_map, v8::Function) \ V(messaging_deserialize_create_object, v8::Function) \ V(message_port, v8::Object) \ diff --git a/src/handle_wrap.cc b/src/handle_wrap.cc index 0e8f2c97d26..5d602136856 100644 --- a/src/handle_wrap.cc +++ b/src/handle_wrap.cc @@ -41,7 +41,7 @@ using v8::Value; void HandleWrap::Ref(const FunctionCallbackInfo& args) { HandleWrap* wrap; - ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&wrap, args.This()); if (IsAlive(wrap)) uv_ref(wrap->GetHandle()); @@ -50,7 +50,7 @@ void HandleWrap::Ref(const FunctionCallbackInfo& args) { void HandleWrap::Unref(const FunctionCallbackInfo& args) { HandleWrap* wrap; - ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&wrap, args.This()); if (IsAlive(wrap)) uv_unref(wrap->GetHandle()); @@ -59,14 +59,14 @@ void HandleWrap::Unref(const FunctionCallbackInfo& args) { void HandleWrap::HasRef(const FunctionCallbackInfo& args) { HandleWrap* wrap; - ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&wrap, args.This()); args.GetReturnValue().Set(HasRef(wrap)); } void HandleWrap::Close(const FunctionCallbackInfo& args) { HandleWrap* wrap; - ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&wrap, args.This()); wrap->Close(args[0]); } diff --git a/src/histogram.cc b/src/histogram.cc index 4f58359fe58..4dbdea9be57 100644 --- a/src/histogram.cc +++ b/src/histogram.cc @@ -165,7 +165,7 @@ void HistogramBase::MemoryInfo(MemoryTracker* tracker) const { void HistogramBase::RecordDelta(const FunctionCallbackInfo& args) { HistogramBase* histogram; - ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&histogram, args.This()); (*histogram)->RecordDelta(); } @@ -185,7 +185,7 @@ void HistogramBase::Record(const FunctionCallbackInfo& args) { if (!lossless || value < 1) return THROW_ERR_OUT_OF_RANGE(env, "value is out of range"); HistogramBase* histogram; - ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&histogram, args.This()); (*histogram)->Record(value); } @@ -204,7 +204,7 @@ void HistogramBase::FastRecord(Local receiver, void HistogramBase::Add(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); HistogramBase* histogram; - ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&histogram, args.This()); CHECK(GetConstructorTemplate(env->isolate_data())->HasInstance(args[0])); HistogramBase* other; @@ -432,7 +432,7 @@ void IntervalHistogram::OnStop() { void IntervalHistogram::Start(const FunctionCallbackInfo& args) { IntervalHistogram* histogram; - ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&histogram, args.This()); histogram->OnStart(args[0]->IsTrue() ? StartFlags::RESET : StartFlags::NONE); } @@ -444,7 +444,7 @@ void IntervalHistogram::FastStart(Local receiver, bool reset) { void IntervalHistogram::Stop(const FunctionCallbackInfo& args) { IntervalHistogram* histogram; - ASSIGN_OR_RETURN_UNWRAP(&histogram, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&histogram, args.This()); histogram->OnStop(); } @@ -455,67 +455,67 @@ void IntervalHistogram::FastStop(Local receiver) { } void HistogramImpl::GetCount(const FunctionCallbackInfo& args) { - HistogramImpl* histogram = HistogramImpl::FromJSObject(args.Holder()); + HistogramImpl* histogram = HistogramImpl::FromJSObject(args.This()); double value = static_cast((*histogram)->Count()); args.GetReturnValue().Set(value); } void HistogramImpl::GetCountBigInt(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); - HistogramImpl* histogram = HistogramImpl::FromJSObject(args.Holder()); + HistogramImpl* histogram = HistogramImpl::FromJSObject(args.This()); args.GetReturnValue().Set( BigInt::NewFromUnsigned(env->isolate(), (*histogram)->Count())); } void HistogramImpl::GetMin(const FunctionCallbackInfo& args) { - HistogramImpl* histogram = HistogramImpl::FromJSObject(args.Holder()); + HistogramImpl* histogram = HistogramImpl::FromJSObject(args.This()); double value = static_cast((*histogram)->Min()); args.GetReturnValue().Set(value); } void HistogramImpl::GetMinBigInt(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); - HistogramImpl* histogram = HistogramImpl::FromJSObject(args.Holder()); + HistogramImpl* histogram = HistogramImpl::FromJSObject(args.This()); args.GetReturnValue().Set(BigInt::New(env->isolate(), (*histogram)->Min())); } void HistogramImpl::GetMax(const FunctionCallbackInfo& args) { - HistogramImpl* histogram = HistogramImpl::FromJSObject(args.Holder()); + HistogramImpl* histogram = HistogramImpl::FromJSObject(args.This()); double value = static_cast((*histogram)->Max()); args.GetReturnValue().Set(value); } void HistogramImpl::GetMaxBigInt(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); - HistogramImpl* histogram = HistogramImpl::FromJSObject(args.Holder()); + HistogramImpl* histogram = HistogramImpl::FromJSObject(args.This()); args.GetReturnValue().Set(BigInt::New(env->isolate(), (*histogram)->Max())); } void HistogramImpl::GetMean(const FunctionCallbackInfo& args) { - HistogramImpl* histogram = HistogramImpl::FromJSObject(args.Holder()); + HistogramImpl* histogram = HistogramImpl::FromJSObject(args.This()); args.GetReturnValue().Set((*histogram)->Mean()); } void HistogramImpl::GetExceeds(const FunctionCallbackInfo& args) { - HistogramImpl* histogram = HistogramImpl::FromJSObject(args.Holder()); + HistogramImpl* histogram = HistogramImpl::FromJSObject(args.This()); double value = static_cast((*histogram)->Exceeds()); args.GetReturnValue().Set(value); } void HistogramImpl::GetExceedsBigInt(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); - HistogramImpl* histogram = HistogramImpl::FromJSObject(args.Holder()); + HistogramImpl* histogram = HistogramImpl::FromJSObject(args.This()); args.GetReturnValue().Set( BigInt::New(env->isolate(), (*histogram)->Exceeds())); } void HistogramImpl::GetStddev(const FunctionCallbackInfo& args) { - HistogramImpl* histogram = HistogramImpl::FromJSObject(args.Holder()); + HistogramImpl* histogram = HistogramImpl::FromJSObject(args.This()); args.GetReturnValue().Set((*histogram)->Stddev()); } void HistogramImpl::GetPercentile(const FunctionCallbackInfo& args) { - HistogramImpl* histogram = HistogramImpl::FromJSObject(args.Holder()); + HistogramImpl* histogram = HistogramImpl::FromJSObject(args.This()); CHECK(args[0]->IsNumber()); double percentile = args[0].As()->Value(); double value = static_cast((*histogram)->Percentile(percentile)); @@ -525,7 +525,7 @@ void HistogramImpl::GetPercentile(const FunctionCallbackInfo& args) { void HistogramImpl::GetPercentileBigInt( const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); - HistogramImpl* histogram = HistogramImpl::FromJSObject(args.Holder()); + HistogramImpl* histogram = HistogramImpl::FromJSObject(args.This()); CHECK(args[0]->IsNumber()); double percentile = args[0].As()->Value(); int64_t value = (*histogram)->Percentile(percentile); @@ -534,7 +534,7 @@ void HistogramImpl::GetPercentileBigInt( void HistogramImpl::GetPercentiles(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); - HistogramImpl* histogram = HistogramImpl::FromJSObject(args.Holder()); + HistogramImpl* histogram = HistogramImpl::FromJSObject(args.This()); CHECK(args[0]->IsMap()); Local map = args[0].As(); (*histogram)->Percentiles([map, env](double key, int64_t value) { @@ -548,7 +548,7 @@ void HistogramImpl::GetPercentiles(const FunctionCallbackInfo& args) { void HistogramImpl::GetPercentilesBigInt( const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); - HistogramImpl* histogram = HistogramImpl::FromJSObject(args.Holder()); + HistogramImpl* histogram = HistogramImpl::FromJSObject(args.This()); CHECK(args[0]->IsMap()); Local map = args[0].As(); (*histogram)->Percentiles([map, env](double key, int64_t value) { @@ -560,7 +560,7 @@ void HistogramImpl::GetPercentilesBigInt( } void HistogramImpl::DoReset(const FunctionCallbackInfo& args) { - HistogramImpl* histogram = HistogramImpl::FromJSObject(args.Holder()); + HistogramImpl* histogram = HistogramImpl::FromJSObject(args.This()); (*histogram)->Reset(); } diff --git a/src/inspector/network_agent.cc b/src/inspector/network_agent.cc new file mode 100644 index 00000000000..f8b42b29158 --- /dev/null +++ b/src/inspector/network_agent.cc @@ -0,0 +1,147 @@ +#include "network_agent.h" +#include "network_inspector.h" + +namespace node { +namespace inspector { +namespace protocol { + +std::unique_ptr createRequest( + const String& url, + const String& method, + std::unique_ptr headers) { + return Network::Request::create() + .setUrl(url) + .setMethod(method) + .setHeaders(std::move(headers)) + .build(); +} + +std::unique_ptr createResponse( + const String& url, + int status, + const String& statusText, + std::unique_ptr headers) { + return Network::Response::create() + .setUrl(url) + .setStatus(status) + .setStatusText(statusText) + .setHeaders(std::move(headers)) + .build(); +} + +NetworkAgent::NetworkAgent(NetworkInspector* inspector) + : inspector_(inspector) { + event_notifier_map_["requestWillBeSent"] = &NetworkAgent::requestWillBeSent; + event_notifier_map_["responseReceived"] = &NetworkAgent::responseReceived; + event_notifier_map_["loadingFailed"] = &NetworkAgent::loadingFailed; + event_notifier_map_["loadingFinished"] = &NetworkAgent::loadingFinished; +} + +void NetworkAgent::emitNotification( + const String& event, std::unique_ptr params) { + if (!inspector_->IsEnabled()) return; + auto it = event_notifier_map_.find(event); + if (it != event_notifier_map_.end()) { + (this->*(it->second))(std::move(params)); + } +} + +void NetworkAgent::Wire(UberDispatcher* dispatcher) { + frontend_ = std::make_unique(dispatcher->channel()); + Network::Dispatcher::wire(dispatcher, this); +} + +DispatchResponse NetworkAgent::enable() { + inspector_->Enable(); + return DispatchResponse::OK(); +} + +DispatchResponse NetworkAgent::disable() { + inspector_->Disable(); + return DispatchResponse::OK(); +} + +void NetworkAgent::requestWillBeSent( + std::unique_ptr params) { + String request_id; + params->getString("requestId", &request_id); + double timestamp; + params->getDouble("timestamp", ×tamp); + double wall_time; + params->getDouble("wallTime", &wall_time); + auto request = params->getObject("request"); + String url; + request->getString("url", &url); + String method; + request->getString("method", &method); + + ErrorSupport errors; + auto headers = + Network::Headers::fromValue(request->getObject("headers"), &errors); + if (errors.hasErrors()) { + headers = std::make_unique(DictionaryValue::create()); + } + + frontend_->requestWillBeSent(request_id, + createRequest(url, method, std::move(headers)), + timestamp, + wall_time); +} + +void NetworkAgent::responseReceived( + std::unique_ptr params) { + String request_id; + params->getString("requestId", &request_id); + double timestamp; + params->getDouble("timestamp", ×tamp); + String type; + params->getString("type", &type); + auto response = params->getObject("response"); + String url; + response->getString("url", &url); + int status; + response->getInteger("status", &status); + String statusText; + response->getString("statusText", &statusText); + + ErrorSupport errors; + auto headers = + Network::Headers::fromValue(response->getObject("headers"), &errors); + if (errors.hasErrors()) { + headers = std::make_unique(DictionaryValue::create()); + } + + frontend_->responseReceived( + request_id, + timestamp, + type, + createResponse(url, status, statusText, std::move(headers))); +} + +void NetworkAgent::loadingFailed( + std::unique_ptr params) { + String request_id; + params->getString("requestId", &request_id); + double timestamp; + params->getDouble("timestamp", ×tamp); + String type; + params->getString("type", &type); + String error_text; + params->getString("errorText", &error_text); + + frontend_->loadingFailed(request_id, timestamp, type, error_text); +} + +void NetworkAgent::loadingFinished( + std::unique_ptr params) { + String request_id; + params->getString("requestId", &request_id); + double timestamp; + params->getDouble("timestamp", ×tamp); + + frontend_->loadingFinished(request_id, timestamp); +} + +} // namespace protocol +} // namespace inspector +} // namespace node diff --git a/src/inspector/network_agent.h b/src/inspector/network_agent.h new file mode 100644 index 00000000000..8d0e71c49b4 --- /dev/null +++ b/src/inspector/network_agent.h @@ -0,0 +1,48 @@ +#ifndef SRC_INSPECTOR_NETWORK_AGENT_H_ +#define SRC_INSPECTOR_NETWORK_AGENT_H_ + +#include "node/inspector/protocol/Network.h" + +#include + +namespace node { + +namespace inspector { +class NetworkInspector; + +namespace protocol { + +class NetworkAgent : public Network::Backend { + public: + explicit NetworkAgent(NetworkInspector* inspector); + + void Wire(UberDispatcher* dispatcher); + + DispatchResponse enable() override; + + DispatchResponse disable() override; + + void emitNotification(const String& event, + std::unique_ptr params); + + void requestWillBeSent(std::unique_ptr params); + + void responseReceived(std::unique_ptr params); + + void loadingFailed(std::unique_ptr params); + + void loadingFinished(std::unique_ptr params); + + private: + NetworkInspector* inspector_; + std::shared_ptr frontend_; + using EventNotifier = + void (NetworkAgent::*)(std::unique_ptr); + std::unordered_map event_notifier_map_; +}; + +} // namespace protocol +} // namespace inspector +} // namespace node + +#endif // SRC_INSPECTOR_NETWORK_AGENT_H_ diff --git a/src/inspector/network_inspector.cc b/src/inspector/network_inspector.cc new file mode 100644 index 00000000000..a03a66d461e --- /dev/null +++ b/src/inspector/network_inspector.cc @@ -0,0 +1,48 @@ +#include "network_inspector.h" + +namespace node { +namespace inspector { + +NetworkInspector::NetworkInspector(Environment* env) + : enabled_(false), env_(env) { + network_agent_ = std::make_unique(this); +} +NetworkInspector::~NetworkInspector() { + network_agent_.reset(); +} + +void NetworkInspector::Wire(protocol::UberDispatcher* dispatcher) { + network_agent_->Wire(dispatcher); +} + +bool NetworkInspector::canEmit(const std::string& domain) { + return domain == "Network"; +} + +void NetworkInspector::emitNotification( + const std::string& domain, + const std::string& method, + std::unique_ptr params) { + if (domain == "Network") { + network_agent_->emitNotification(method, std::move(params)); + } else { + UNREACHABLE("Unknown domain"); + } +} + +void NetworkInspector::Enable() { + if (auto agent = env_->inspector_agent()) { + agent->EnableNetworkTracking(); + } + enabled_ = true; +} + +void NetworkInspector::Disable() { + if (auto agent = env_->inspector_agent()) { + agent->DisableNetworkTracking(); + } + enabled_ = false; +} + +} // namespace inspector +} // namespace node diff --git a/src/inspector/network_inspector.h b/src/inspector/network_inspector.h new file mode 100644 index 00000000000..1a30997bad9 --- /dev/null +++ b/src/inspector/network_inspector.h @@ -0,0 +1,38 @@ +#ifndef SRC_INSPECTOR_NETWORK_INSPECTOR_H_ +#define SRC_INSPECTOR_NETWORK_INSPECTOR_H_ + +#include "env.h" +#include "network_agent.h" + +namespace node { +class Environment; + +namespace inspector { + +class NetworkInspector { + public: + explicit NetworkInspector(Environment* env); + ~NetworkInspector(); + + void Wire(protocol::UberDispatcher* dispatcher); + + bool canEmit(const std::string& domain); + + void emitNotification(const std::string& domain, + const std::string& method, + std::unique_ptr params); + + void Enable(); + void Disable(); + bool IsEnabled() const { return enabled_; } + + private: + bool enabled_; + Environment* env_; + std::unique_ptr network_agent_; +}; + +} // namespace inspector +} // namespace node + +#endif // SRC_INSPECTOR_NETWORK_INSPECTOR_H_ diff --git a/src/inspector/node_inspector.gypi b/src/inspector/node_inspector.gypi index a2dfdcb42db..d559004be80 100644 --- a/src/inspector/node_inspector.gypi +++ b/src/inspector/node_inspector.gypi @@ -23,6 +23,10 @@ 'src/inspector/tracing_agent.h', 'src/inspector/worker_agent.cc', 'src/inspector/worker_agent.h', + 'src/inspector/network_inspector.cc', + 'src/inspector/network_inspector.h', + 'src/inspector/network_agent.cc', + 'src/inspector/network_agent.h', 'src/inspector/worker_inspector.cc', 'src/inspector/worker_inspector.h', ], @@ -36,6 +40,8 @@ '<(SHARED_INTERMEDIATE_DIR)/src/node/inspector/protocol/NodeTracing.h', '<(SHARED_INTERMEDIATE_DIR)/src/node/inspector/protocol/NodeRuntime.cpp', '<(SHARED_INTERMEDIATE_DIR)/src/node/inspector/protocol/NodeRuntime.h', + '<(SHARED_INTERMEDIATE_DIR)/src/node/inspector/protocol/Network.cpp', + '<(SHARED_INTERMEDIATE_DIR)/src/node/inspector/protocol/Network.h', ], 'node_protocol_files': [ '<(protocol_tool_path)/lib/Allocator_h.template', diff --git a/src/inspector/node_protocol.pdl b/src/inspector/node_protocol.pdl index d8a873de263..d5b50dc81b4 100644 --- a/src/inspector/node_protocol.pdl +++ b/src/inspector/node_protocol.pdl @@ -98,6 +98,106 @@ experimental domain NodeWorker SessionID sessionId string message +# Partial support for Network domain of ChromeDevTools Protocol. +# https://chromedevtools.github.io/devtools-protocol/tot/Network +experimental domain Network + # Resource type as it was perceived by the rendering engine. + type ResourceType extends string + enum + Document + Stylesheet + Image + Media + Font + Script + TextTrack + XHR + Fetch + Prefetch + EventSource + WebSocket + Manifest + SignedExchange + Ping + CSPViolationReport + Preflight + Other + + # Unique request identifier. + type RequestId extends string + + # UTC time in seconds, counted from January 1, 1970. + type TimeSinceEpoch extends number + + # Monotonically increasing time in seconds since an arbitrary point in the past. + type MonotonicTime extends number + + # HTTP request data. + type Request extends object + properties + string url + string method + Headers headers + + # HTTP response data. + type Response extends object + properties + string url + integer status + string statusText + Headers headers + + # Request / response headers as keys / values of JSON object. + type Headers extends object + + # Disables network tracking, prevents network events from being sent to the client. + command disable + + # Enables network tracking, network events will now be delivered to the client. + command enable + + # Fired when page is about to send HTTP request. + event requestWillBeSent + parameters + # Request identifier. + RequestId requestId + # Request data. + Request request + # Timestamp. + MonotonicTime timestamp + # Timestamp. + TimeSinceEpoch wallTime + + # Fired when HTTP response is available. + event responseReceived + parameters + # Request identifier. + RequestId requestId + # Timestamp. + MonotonicTime timestamp + # Resource type. + ResourceType type + # Response data. + Response response + + event loadingFailed + parameters + # Request identifier. + RequestId requestId + # Timestamp. + MonotonicTime timestamp + # Resource type. + ResourceType type + # Error message. + string errorText + + event loadingFinished + parameters + # Request identifier. + RequestId requestId + # Timestamp. + MonotonicTime timestamp + # Support for inspecting node process state. experimental domain NodeRuntime # Enable the NodeRuntime events except by `NodeRuntime.waitingForDisconnect`. diff --git a/src/inspector/node_string.cc b/src/inspector/node_string.cc index 7960971a094..c62e7ed30c4 100644 --- a/src/inspector/node_string.cc +++ b/src/inspector/node_string.cc @@ -84,7 +84,7 @@ String StringViewToUtf8(v8_inspector::StringView view) { String fromDouble(double d) { std::ostringstream stream; stream.imbue(std::locale::classic()); // Ignore current locale - stream << d; + stream << std::fixed << d; return stream.str(); } diff --git a/src/inspector_agent.cc b/src/inspector_agent.cc index 4cab7dea043..bb39a0cb42a 100644 --- a/src/inspector_agent.cc +++ b/src/inspector_agent.cc @@ -2,6 +2,7 @@ #include "env-inl.h" #include "inspector/main_thread_interface.h" +#include "inspector/network_inspector.h" #include "inspector/node_string.h" #include "inspector/runtime_agent.h" #include "inspector/tracing_agent.h" @@ -231,6 +232,8 @@ class ChannelImpl final : public v8_inspector::V8Inspector::Channel, } runtime_agent_ = std::make_unique(); runtime_agent_->Wire(node_dispatcher_.get()); + network_inspector_ = std::make_unique(env); + network_inspector_->Wire(node_dispatcher_.get()); } ~ChannelImpl() override { @@ -242,6 +245,24 @@ class ChannelImpl final : public v8_inspector::V8Inspector::Channel, } runtime_agent_->disable(); runtime_agent_.reset(); // Dispose before the dispatchers + network_inspector_->Disable(); + network_inspector_.reset(); // Dispose before the dispatchers + } + + void emitNotificationFromBackend(const StringView& event, + const StringView& params) { + std::unique_ptr value = + protocol::DictionaryValue::cast( + protocol::StringUtil::parseJSON(params)); + std::string raw_event = protocol::StringUtil::StringViewToUtf8(event); + std::string domain_name = raw_event.substr(0, raw_event.find('.')); + std::string event_name = raw_event.substr(raw_event.find('.') + 1); + if (network_inspector_->canEmit(domain_name)) { + network_inspector_->emitNotification( + domain_name, event_name, std::move(value)); + } else { + UNREACHABLE("Unknown domain for emitNotificationFromBackend"); + } } void dispatchProtocolMessage(const StringView& message) { @@ -259,8 +280,8 @@ class ChannelImpl final : public v8_inspector::V8Inspector::Channel, Utf8ToStringView(method)->string())) { session_->dispatchProtocolMessage(message); } else { - node_dispatcher_->dispatch(call_id, method, std::move(value), - raw_message); + node_dispatcher_->dispatch( + call_id, method, std::move(value), raw_message); } } @@ -335,6 +356,7 @@ class ChannelImpl final : public v8_inspector::V8Inspector::Channel, std::unique_ptr runtime_agent_; std::unique_ptr tracing_agent_; std::unique_ptr worker_agent_; + std::unique_ptr network_inspector_; std::unique_ptr delegate_; std::unique_ptr session_; std::unique_ptr node_dispatcher_; @@ -631,6 +653,12 @@ class NodeInspectorClient : public V8InspectorClient { return retaining_context; } + void emitNotification(const StringView& event, const StringView& params) { + for (const auto& id_channel : channels_) { + id_channel.second->emitNotificationFromBackend(event, params); + } + } + std::shared_ptr getThreadHandle() { if (!interface_) { interface_ = std::make_shared( @@ -844,6 +872,66 @@ std::unique_ptr Agent::ConnectToMainThread( prevent_shutdown); } +void Agent::EmitProtocolEvent(const StringView& event, + const StringView& params) { + if (!env()->options()->experimental_network_inspection) return; + client_->emitNotification(event, params); +} + +void Agent::SetupNetworkTracking(Local enable_function, + Local disable_function) { + parent_env_->set_inspector_enable_network_tracking(enable_function); + parent_env_->set_inspector_disable_network_tracking(disable_function); + if (pending_enable_network_tracking) { + pending_enable_network_tracking = false; + EnableNetworkTracking(); + } else if (pending_disable_network_tracking) { + pending_disable_network_tracking = false; + DisableNetworkTracking(); + } +} + +void Agent::EnableNetworkTracking() { + if (network_tracking_enabled_) { + return; + } + HandleScope scope(parent_env_->isolate()); + Local enable = parent_env_->inspector_enable_network_tracking(); + if (enable.IsEmpty()) { + pending_enable_network_tracking = true; + } else { + ToggleNetworkTracking(parent_env_->isolate(), enable); + network_tracking_enabled_ = true; + } +} + +void Agent::DisableNetworkTracking() { + if (!network_tracking_enabled_) { + return; + } + HandleScope scope(parent_env_->isolate()); + Local disable = parent_env_->inspector_disable_network_tracking(); + if (disable.IsEmpty()) { + pending_disable_network_tracking = true; + } else if (!client_->hasConnectedSessions()) { + ToggleNetworkTracking(parent_env_->isolate(), disable); + network_tracking_enabled_ = false; + } +} + +void Agent::ToggleNetworkTracking(Isolate* isolate, Local fn) { + if (!parent_env_->can_call_into_js()) return; + auto context = parent_env_->context(); + HandleScope scope(isolate); + CHECK(!fn.IsEmpty()); + v8::TryCatch try_catch(isolate); + USE(fn->Call(context, Undefined(isolate), 0, nullptr)); + if (try_catch.HasCaught() && !try_catch.HasTerminated()) { + PrintCaughtException(isolate, context, try_catch); + UNREACHABLE("Cannot toggle network tracking, please report this."); + } +} + void Agent::WaitForDisconnect() { THROW_IF_INSUFFICIENT_PERMISSIONS(parent_env_, permission::PermissionScope::kInspector, diff --git a/src/inspector_agent.h b/src/inspector_agent.h index 725275e43c7..2ddffdb63ff 100644 --- a/src/inspector_agent.h +++ b/src/inspector_agent.h @@ -69,6 +69,14 @@ class Agent { void ReportUncaughtException(v8::Local error, v8::Local message); + void EmitProtocolEvent(const v8_inspector::StringView& event, + const v8_inspector::StringView& params); + + void SetupNetworkTracking(v8::Local enable_function, + v8::Local disable_function); + void EnableNetworkTracking(); + void DisableNetworkTracking(); + // Async stack traces instrumentation. void AsyncTaskScheduled(const v8_inspector::StringView& taskName, void* task, bool recurring); @@ -121,6 +129,7 @@ class Agent { private: void ToggleAsyncHook(v8::Isolate* isolate, v8::Local fn); + void ToggleNetworkTracking(v8::Isolate* isolate, v8::Local fn); node::Environment* parent_env_; // Encapsulates majority of the Inspector functionality @@ -139,6 +148,10 @@ class Agent { bool pending_enable_async_hook_ = false; bool pending_disable_async_hook_ = false; + + bool network_tracking_enabled_ = false; + bool pending_enable_network_tracking = false; + bool pending_disable_network_tracking = false; }; } // namespace inspector diff --git a/src/inspector_js_api.cc b/src/inspector_js_api.cc index fec9de840ef..28257560154 100644 --- a/src/inspector_js_api.cc +++ b/src/inspector_js_api.cc @@ -131,14 +131,14 @@ class JSBindingsConnection : public BaseObject { static void Disconnect(const FunctionCallbackInfo& info) { JSBindingsConnection* session; - ASSIGN_OR_RETURN_UNWRAP(&session, info.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&session, info.This()); session->Disconnect(); } static void Dispatch(const FunctionCallbackInfo& info) { Environment* env = Environment::GetCurrent(info); JSBindingsConnection* session; - ASSIGN_OR_RETURN_UNWRAP(&session, info.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&session, info.This()); CHECK(info[0]->IsString()); if (session->session_) { @@ -207,11 +207,8 @@ void InspectorConsoleCall(const FunctionCallbackInfo& info) { CHECK(inspector_method->IsFunction()); if (!env->is_in_inspector_console_call()) { env->set_is_in_inspector_console_call(true); - MaybeLocal ret = - inspector_method.As()->Call(context, - info.Holder(), - call_args.length(), - call_args.out()); + MaybeLocal ret = inspector_method.As()->Call( + context, info.This(), call_args.length(), call_args.out()); env->set_is_in_inspector_console_call(false); if (ret.IsEmpty()) return; @@ -220,10 +217,8 @@ void InspectorConsoleCall(const FunctionCallbackInfo& info) { Local node_method = info[1]; CHECK(node_method->IsFunction()); - USE(node_method.As()->Call(context, - info.Holder(), - call_args.length(), - call_args.out())); + USE(node_method.As()->Call( + context, info.This(), call_args.length(), call_args.out())); } static void* GetAsyncTask(int64_t asyncId) { @@ -275,6 +270,30 @@ static void RegisterAsyncHookWrapper(const FunctionCallbackInfo& args) { enable_function, disable_function); } +void EmitProtocolEvent(const FunctionCallbackInfo& args) { + Environment* env = Environment::GetCurrent(args); + CHECK(args[0]->IsString()); + Local eventName = args[0].As(); + CHECK(args[1]->IsString()); + Local params = args[1].As(); + + env->inspector_agent()->EmitProtocolEvent( + ToProtocolString(env->isolate(), eventName)->string(), + ToProtocolString(env->isolate(), params)->string()); +} + +void SetupNetworkTracking(const FunctionCallbackInfo& args) { + Environment* env = Environment::GetCurrent(args); + + CHECK(args[0]->IsFunction()); + Local enable_function = args[0].As(); + CHECK(args[1]->IsFunction()); + Local disable_function = args[1].As(); + + env->inspector_agent()->SetupNetworkTracking(enable_function, + disable_function); +} + void IsEnabled(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); args.GetReturnValue().Set(env->inspector_agent()->IsListening()); @@ -359,6 +378,8 @@ void Initialize(Local target, Local unused, SetMethod(context, target, "registerAsyncHook", RegisterAsyncHookWrapper); SetMethodNoSideEffect(context, target, "isEnabled", IsEnabled); + SetMethod(context, target, "emitProtocolEvent", EmitProtocolEvent); + SetMethod(context, target, "setupNetworkTracking", SetupNetworkTracking); Local console_string = FIXED_ONE_BYTE_STRING(isolate, "console"); @@ -392,6 +413,8 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) { registry->Register(RegisterAsyncHookWrapper); registry->Register(IsEnabled); + registry->Register(EmitProtocolEvent); + registry->Register(SetupNetworkTracking); registry->Register(JSBindingsConnection::New); registry->Register(JSBindingsConnection::Dispatch); diff --git a/src/inspector_profiler.cc b/src/inspector_profiler.cc index aeebc1f18a0..0ebd2ea61ad 100644 --- a/src/inspector_profiler.cc +++ b/src/inspector_profiler.cc @@ -503,6 +503,21 @@ static void StopCoverage(const FunctionCallbackInfo& args) { } } +static void EndCoverage(const FunctionCallbackInfo& args) { + Environment* env = Environment::GetCurrent(args); + V8CoverageConnection* connection = env->coverage_connection(); + + Debug(env, + DebugCategory::INSPECTOR_PROFILER, + "EndCoverage, connection %s nullptr\n", + connection == nullptr ? "==" : "!="); + + if (connection != nullptr) { + Debug(env, DebugCategory::INSPECTOR_PROFILER, "Ending coverage\n"); + connection->End(); + } +} + static void Initialize(Local target, Local unused, Local context, @@ -512,6 +527,7 @@ static void Initialize(Local target, context, target, "setSourceMapCacheGetter", SetSourceMapCacheGetter); SetMethod(context, target, "takeCoverage", TakeCoverage); SetMethod(context, target, "stopCoverage", StopCoverage); + SetMethod(context, target, "endCoverage", EndCoverage); } void RegisterExternalReferences(ExternalReferenceRegistry* registry) { @@ -519,6 +535,7 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) { registry->Register(SetSourceMapCacheGetter); registry->Register(TakeCoverage); registry->Register(StopCoverage); + registry->Register(EndCoverage); } } // namespace profiler diff --git a/src/js_native_api.h b/src/js_native_api.h index 1558a9f996a..07e3df13407 100644 --- a/src/js_native_api.h +++ b/src/js_native_api.h @@ -114,6 +114,10 @@ node_api_create_external_string_utf16(napi_env env, #ifdef NAPI_EXPERIMENTAL #define NODE_API_EXPERIMENTAL_HAS_PROPERTY_KEYS +NAPI_EXTERN napi_status NAPI_CDECL node_api_create_property_key_latin1( + napi_env env, const char* str, size_t length, napi_value* result); +NAPI_EXTERN napi_status NAPI_CDECL node_api_create_property_key_utf8( + napi_env env, const char* str, size_t length, napi_value* result); NAPI_EXTERN napi_status NAPI_CDECL node_api_create_property_key_utf16( napi_env env, const char16_t* str, size_t length, napi_value* result); #endif // NAPI_EXPERIMENTAL diff --git a/src/js_native_api_v8.cc b/src/js_native_api_v8.cc index e3529f5b84f..fe3c152e83b 100644 --- a/src/js_native_api_v8.cc +++ b/src/js_native_api_v8.cc @@ -134,43 +134,38 @@ napi_status NewExternalString(napi_env env, return status; } -class TrackedStringResource : public Finalizer, RefTracker { +class TrackedStringResource : private RefTracker { public: TrackedStringResource(napi_env env, napi_finalize finalize_callback, void* data, void* finalize_hint) - : Finalizer(env, finalize_callback, data, finalize_hint) { + : RefTracker(), finalizer_(env, finalize_callback, data, finalize_hint) { Link(finalize_callback == nullptr ? &env->reflist : &env->finalizing_reflist); } protected: - // The only time Finalize() gets called before Dispose() is if the + // The only time Finalize() gets called before destructor is if the // environment is dying. Finalize() expects that the item will be unlinked, - // so we do it here. V8 will still call Dispose() on us later, so we don't do - // any deleting here. We just null out env_ to avoid passing a stale pointer - // to the user's finalizer when V8 does finally call Dispose(). + // so we do it here. V8 will still call destructor on us later, so we don't do + // any deleting here. We just null out env to avoid passing a stale pointer + // to the user's finalizer when V8 does finally call destructor. void Finalize() override { Unlink(); - env_ = nullptr; + finalizer_.ResetEnv(); } - ~TrackedStringResource() { - if (finalize_callback_ == nullptr) return; - if (env_ == nullptr) { - // The environment is dead. Call the finalizer directly. - finalize_callback_(nullptr, finalize_data_, finalize_hint_); - } else { - // The environment is still alive. Let's remove ourselves from its list - // of references and call the user's finalizer. - Unlink(); - env_->CallFinalizer(finalize_callback_, finalize_data_, finalize_hint_); - } + ~TrackedStringResource() override { + Unlink(); + finalizer_.CallFinalizer(); } + + private: + Finalizer finalizer_; }; -class ExternalOneByteStringResource +class ExternalOneByteStringResource final : public v8::String::ExternalOneByteStringResource, TrackedStringResource { public: @@ -191,8 +186,8 @@ class ExternalOneByteStringResource const size_t length_; }; -class ExternalStringResource : public v8::String::ExternalStringResource, - TrackedStringResource { +class ExternalStringResource final : public v8::String::ExternalStringResource, + TrackedStringResource { public: ExternalStringResource(napi_env env, char16_t* string, @@ -368,7 +363,7 @@ inline napi_status Unwrap(napi_env env, if (action == RemoveWrap) { CHECK(obj->DeletePrivate(context, NAPI_PRIVATE_KEY(context, wrapper)) .FromJust()); - if (reference->ownership() == Ownership::kUserland) { + if (reference->ownership() == ReferenceOwnership::kUserland) { // When the wrap is been removed, the finalizer should be reset. reference->ResetFinalizer(); } else { @@ -400,10 +395,16 @@ class CallbackBundle { bundle->env = env; v8::Local cbdata = v8::External::New(env->isolate, bundle); - Reference::New( - env, cbdata, 0, Ownership::kRuntime, Delete, bundle, nullptr); + ReferenceWithFinalizer::New( + env, cbdata, 0, ReferenceOwnership::kRuntime, Delete, bundle, nullptr); return cbdata; } + + static CallbackBundle* FromCallbackData(v8::Local data) { + return reinterpret_cast(data.As()->Value()); + } + + public: napi_env env; // Necessary to invoke C++ NAPI callback void* cb_data; // The user provided callback data napi_callback cb; @@ -415,71 +416,9 @@ class CallbackBundle { } }; -// Base class extended by classes that wrap V8 function and property callback -// info. -class CallbackWrapper { - public: - inline CallbackWrapper(napi_value this_arg, size_t args_length, void* data) - : _this(this_arg), _args_length(args_length), _data(data) {} - - virtual napi_value GetNewTarget() = 0; - virtual void Args(napi_value* buffer, size_t bufferlength) = 0; - virtual void SetReturnValue(napi_value value) = 0; - - napi_value This() { return _this; } - - size_t ArgsLength() { return _args_length; } - - void* Data() { return _data; } - - protected: - const napi_value _this; - const size_t _args_length; - void* _data; -}; - -class CallbackWrapperBase : public CallbackWrapper { - public: - inline CallbackWrapperBase(const v8::FunctionCallbackInfo& cbinfo, - const size_t args_length) - : CallbackWrapper( - JsValueFromV8LocalValue(cbinfo.This()), args_length, nullptr), - _cbinfo(cbinfo) { - _bundle = reinterpret_cast( - cbinfo.Data().As()->Value()); - _data = _bundle->cb_data; - } - - protected: - inline void InvokeCallback() { - napi_callback_info cbinfo_wrapper = reinterpret_cast( - static_cast(this)); - - // All other pointers we need are stored in `_bundle` - napi_env env = _bundle->env; - napi_callback cb = _bundle->cb; - - napi_value result = nullptr; - bool exceptionOccurred = false; - env->CallIntoModule([&](napi_env env) { result = cb(env, cbinfo_wrapper); }, - [&](napi_env env, v8::Local value) { - exceptionOccurred = true; - if (env->terminatedOrTerminating()) { - return; - } - env->isolate->ThrowException(value); - }); - - if (!exceptionOccurred && (result != nullptr)) { - this->SetReturnValue(result); - } - } - - const v8::FunctionCallbackInfo& _cbinfo; - CallbackBundle* _bundle; -}; - -class FunctionCallbackWrapper : public CallbackWrapperBase { +// Wraps up v8::FunctionCallbackInfo. +// The class must be stack allocated. +class FunctionCallbackWrapper { public: static void Invoke(const v8::FunctionCallbackInfo& info) { FunctionCallbackWrapper cbwrapper(info); @@ -514,41 +453,70 @@ class FunctionCallbackWrapper : public CallbackWrapperBase { return napi_clear_last_error(env); } - explicit FunctionCallbackWrapper( - const v8::FunctionCallbackInfo& cbinfo) - : CallbackWrapperBase(cbinfo, cbinfo.Length()) {} - - napi_value GetNewTarget() override { - if (_cbinfo.IsConstructCall()) { - return v8impl::JsValueFromV8LocalValue(_cbinfo.NewTarget()); + napi_value GetNewTarget() { + if (cbinfo_.IsConstructCall()) { + return v8impl::JsValueFromV8LocalValue(cbinfo_.NewTarget()); } else { return nullptr; } } - /*virtual*/ - void Args(napi_value* buffer, size_t buffer_length) override { + void Args(napi_value* buffer, size_t buffer_length) { size_t i = 0; - size_t min = std::min(buffer_length, _args_length); + size_t min_arg_count = std::min(buffer_length, ArgsLength()); - for (; i < min; i += 1) { - buffer[i] = v8impl::JsValueFromV8LocalValue(_cbinfo[i]); + for (; i < min_arg_count; ++i) { + buffer[i] = JsValueFromV8LocalValue(cbinfo_[i]); } if (i < buffer_length) { napi_value undefined = - v8impl::JsValueFromV8LocalValue(v8::Undefined(_cbinfo.GetIsolate())); - for (; i < buffer_length; i += 1) { + JsValueFromV8LocalValue(v8::Undefined(cbinfo_.GetIsolate())); + for (; i < buffer_length; ++i) { buffer[i] = undefined; } } } - /*virtual*/ - void SetReturnValue(napi_value value) override { - v8::Local val = v8impl::V8LocalValueFromJsValue(value); - _cbinfo.GetReturnValue().Set(val); + napi_value This() { return JsValueFromV8LocalValue(cbinfo_.This()); } + + size_t ArgsLength() { return static_cast(cbinfo_.Length()); } + + void* Data() { return bundle_->cb_data; } + + private: + explicit FunctionCallbackWrapper( + const v8::FunctionCallbackInfo& cbinfo) + : cbinfo_(cbinfo), + bundle_(CallbackBundle::FromCallbackData(cbinfo.Data())) {} + + void InvokeCallback() { + napi_callback_info cbinfo_wrapper = + reinterpret_cast(this); + + // All other pointers we need are stored in `_bundle` + napi_env env = bundle_->env; + napi_callback cb = bundle_->cb; + + napi_value result = nullptr; + bool exceptionOccurred = false; + env->CallIntoModule([&](napi_env env) { result = cb(env, cbinfo_wrapper); }, + [&](napi_env env, v8::Local value) { + exceptionOccurred = true; + if (env->terminatedOrTerminating()) { + return; + } + env->isolate->ThrowException(value); + }); + + if (!exceptionOccurred && (result != nullptr)) { + cbinfo_.GetReturnValue().Set(V8LocalValueFromJsValue(result)); + } } + + private: + const v8::FunctionCallbackInfo& cbinfo_; + CallbackBundle* bundle_; }; inline napi_status Wrap(napi_env env, @@ -579,24 +547,29 @@ inline napi_status Wrap(napi_env env, // before then, then the finalize callback will never be invoked.) // Therefore a finalize callback is required when returning a reference. CHECK_ARG(env, finalize_cb); - reference = v8impl::Reference::New(env, - obj, - 0, - v8impl::Ownership::kUserland, - finalize_cb, - native_object, - finalize_hint); + reference = v8impl::ReferenceWithFinalizer::New( + env, + obj, + 0, + v8impl::ReferenceOwnership::kUserland, + finalize_cb, + native_object, + finalize_hint); *result = reinterpret_cast(reference); - } else { + } else if (finalize_cb != nullptr) { // Create a self-deleting reference. - reference = v8impl::Reference::New( + reference = v8impl::ReferenceWithFinalizer::New( env, obj, 0, - v8impl::Ownership::kRuntime, + v8impl::ReferenceOwnership::kRuntime, finalize_cb, native_object, - finalize_cb == nullptr ? nullptr : finalize_hint); + finalize_hint); + } else { + // Create a self-deleting reference. + reference = v8impl::ReferenceWithData::New( + env, obj, 0, v8impl::ReferenceOwnership::kRuntime, native_object); } CHECK(obj->SetPrivate(context, @@ -621,27 +594,46 @@ inline bool CanBeHeldWeakly(v8::Local value) { } // end of anonymous namespace +void Finalizer::ResetEnv() { + env_ = nullptr; +} + void Finalizer::ResetFinalizer() { finalize_callback_ = nullptr; finalize_data_ = nullptr; finalize_hint_ = nullptr; } +void Finalizer::CallFinalizer() { + napi_finalize finalize_callback = finalize_callback_; + void* finalize_data = finalize_data_; + void* finalize_hint = finalize_hint_; + ResetFinalizer(); + + if (finalize_callback == nullptr) return; + if (env_ == nullptr) { + // The environment is dead. Call the finalizer directly. + finalize_callback(nullptr, finalize_data, finalize_hint); + } else { + env_->CallFinalizer(finalize_callback, finalize_data, finalize_hint); + } +} + TrackedFinalizer::TrackedFinalizer(napi_env env, napi_finalize finalize_callback, void* finalize_data, void* finalize_hint) - : Finalizer(env, finalize_callback, finalize_data, finalize_hint), - RefTracker() { - Link(finalize_callback == nullptr ? &env->reflist : &env->finalizing_reflist); -} + : RefTracker(), + finalizer_(env, finalize_callback, finalize_data, finalize_hint) {} TrackedFinalizer* TrackedFinalizer::New(napi_env env, napi_finalize finalize_callback, void* finalize_data, void* finalize_hint) { - return new TrackedFinalizer( + TrackedFinalizer* finalizer = new TrackedFinalizer( env, finalize_callback, finalize_data, finalize_hint); + finalizer->Link(&env->finalizing_reflist); + return finalizer; } // When a TrackedFinalizer is being deleted, it may have been queued to call its @@ -650,92 +642,25 @@ TrackedFinalizer::~TrackedFinalizer() { // Remove from the env's tracked list. Unlink(); // Try to remove the finalizer from the scheduled second pass callback. - env_->DequeueFinalizer(this); + finalizer_.env()->DequeueFinalizer(this); } void TrackedFinalizer::Finalize() { - FinalizeCore(/*deleteMe:*/ true); -} - -void TrackedFinalizer::FinalizeCore(bool deleteMe) { - // Swap out the field finalize_callback so that it can not be accidentally - // called more than once. - napi_finalize finalize_callback = finalize_callback_; - void* finalize_data = finalize_data_; - void* finalize_hint = finalize_hint_; - ResetFinalizer(); - - // Either the RefBase is going to be deleted in the finalize_callback or not, - // it should be removed from the tracked list. Unlink(); - // If the finalize_callback is present, it should either delete the - // derived RefBase, or the RefBase ownership was set to Ownership::kRuntime - // and the deleteMe parameter is true. - if (finalize_callback != nullptr) { - env_->CallFinalizer(finalize_callback, finalize_data, finalize_hint); - } - - if (deleteMe) { - delete this; - } -} - -// Wrapper around v8impl::Persistent that implements reference counting. -RefBase::RefBase(napi_env env, - uint32_t initial_refcount, - Ownership ownership, - napi_finalize finalize_callback, - void* finalize_data, - void* finalize_hint) - : TrackedFinalizer(env, finalize_callback, finalize_data, finalize_hint), - refcount_(initial_refcount), - ownership_(ownership) {} - -RefBase* RefBase::New(napi_env env, - uint32_t initial_refcount, - Ownership ownership, - napi_finalize finalize_callback, - void* finalize_data, - void* finalize_hint) { - return new RefBase(env, - initial_refcount, - ownership, - finalize_callback, - finalize_data, - finalize_hint); -} - -void* RefBase::Data() { - return finalize_data_; -} - -uint32_t RefBase::Ref() { - return ++refcount_; -} - -uint32_t RefBase::Unref() { - if (refcount_ == 0) { - return 0; - } - return --refcount_; -} - -uint32_t RefBase::RefCount() { - return refcount_; + finalizer_.CallFinalizer(); + delete this; } -void RefBase::Finalize() { - // If the RefBase is not Ownership::kRuntime, userland code should delete it. - // Delete it if it is Ownership::kRuntime. - FinalizeCore(/*deleteMe:*/ ownership_ == Ownership::kRuntime); -} - -template -Reference::Reference(napi_env env, v8::Local value, Args&&... args) - : RefBase(env, std::forward(args)...), +Reference::Reference(napi_env env, + v8::Local value, + uint32_t initial_refcount, + ReferenceOwnership ownership) + : RefTracker(), persistent_(env->isolate, value), + refcount_(initial_refcount), + ownership_(ownership), can_be_weak_(CanBeHeldWeakly(value)) { - if (RefCount() == 0) { + if (refcount_ == 0) { SetWeak(); } } @@ -743,22 +668,18 @@ Reference::Reference(napi_env env, v8::Local value, Args&&... args) Reference::~Reference() { // Reset the handle. And no weak callback will be invoked. persistent_.Reset(); + + // Remove from the env's tracked list. + Unlink(); } Reference* Reference::New(napi_env env, v8::Local value, uint32_t initial_refcount, - Ownership ownership, - napi_finalize finalize_callback, - void* finalize_data, - void* finalize_hint) { - return new Reference(env, - value, - initial_refcount, - ownership, - finalize_callback, - finalize_data, - finalize_hint); + ReferenceOwnership ownership) { + Reference* reference = new Reference(env, value, initial_refcount, ownership); + reference->Link(&env->reflist); + return reference; } uint32_t Reference::Ref() { @@ -767,32 +688,29 @@ uint32_t Reference::Ref() { if (persistent_.IsEmpty()) { return 0; } - uint32_t refcount = RefBase::Ref(); - if (refcount == 1 && can_be_weak_) { + if (++refcount_ == 1 && can_be_weak_) { persistent_.ClearWeak(); } - return refcount; + return refcount_; } uint32_t Reference::Unref() { // When the persistent_ is cleared in the WeakCallback, and a second pass // callback is pending, return 0 unconditionally. - if (persistent_.IsEmpty()) { + if (persistent_.IsEmpty() || refcount_ == 0) { return 0; } - uint32_t old_refcount = RefCount(); - uint32_t refcount = RefBase::Unref(); - if (old_refcount == 1 && refcount == 0) { + if (--refcount_ == 0) { SetWeak(); } - return refcount; + return refcount_; } -v8::Local Reference::Get() { +v8::Local Reference::Get(napi_env env) { if (persistent_.IsEmpty()) { return v8::Local(); } else { - return v8::Local::New(env_->isolate, persistent_); + return v8::Local::New(env->isolate, persistent_); } } @@ -801,12 +719,30 @@ void Reference::Finalize() { // be invoked again. persistent_.Reset(); - // Chain up to perform the rest of the finalization. - RefBase::Finalize(); + // If the Reference is not ReferenceOwnership::kRuntime, userland code should + // delete it. Delete it if it is ReferenceOwnership::kRuntime. + bool deleteMe = ownership_ == ReferenceOwnership::kRuntime; + + // Whether the Reference is going to be deleted in the finalize_callback + // or not, it should be removed from the tracked list. + Unlink(); + + // If the finalize_callback is present, it should either delete the + // derived Reference, or the Reference ownership was set to + // ReferenceOwnership::kRuntime and the deleteMe parameter is true. + CallUserFinalizer(); + + if (deleteMe) { + delete this; + } +} + +// Call the Finalize immediately since there is no user finalizer to call. +void Reference::InvokeFinalizerFromGC() { + Finalize(); } -// Mark the reference as weak and eligible for collection -// by the gc. +// Mark the reference as weak and eligible for collection by the GC. void Reference::SetWeak() { if (can_be_weak_) { persistent_.SetWeak(this, WeakCallback, v8::WeakCallbackType::kParameter); @@ -815,14 +751,76 @@ void Reference::SetWeak() { } } -// The N-API finalizer callback may make calls into the engine. V8's heap is -// not in a consistent state during the weak callback, and therefore it does -// not support calls back into it. Enqueue the invocation of the finalizer. +// Static function called by GC. Delegate the call to the reference instance. void Reference::WeakCallback(const v8::WeakCallbackInfo& data) { Reference* reference = data.GetParameter(); - // The reference must be reset during the weak callback as the API protocol. + // The reference must be reset during the weak callback per V8 API protocol. reference->persistent_.Reset(); - reference->env_->InvokeFinalizerFromGC(reference); + reference->InvokeFinalizerFromGC(); +} + +ReferenceWithData* ReferenceWithData::New(napi_env env, + v8::Local value, + uint32_t initial_refcount, + ReferenceOwnership ownership, + void* data) { + ReferenceWithData* reference = + new ReferenceWithData(env, value, initial_refcount, ownership, data); + reference->Link(&env->reflist); + return reference; +} + +ReferenceWithData::ReferenceWithData(napi_env env, + v8::Local value, + uint32_t initial_refcount, + ReferenceOwnership ownership, + void* data) + : Reference(env, value, initial_refcount, ownership), data_(data) {} + +ReferenceWithFinalizer* ReferenceWithFinalizer::New( + napi_env env, + v8::Local value, + uint32_t initial_refcount, + ReferenceOwnership ownership, + napi_finalize finalize_callback, + void* finalize_data, + void* finalize_hint) { + ReferenceWithFinalizer* reference = + new ReferenceWithFinalizer(env, + value, + initial_refcount, + ownership, + finalize_callback, + finalize_data, + finalize_hint); + reference->Link(&env->finalizing_reflist); + return reference; +} + +ReferenceWithFinalizer::ReferenceWithFinalizer(napi_env env, + v8::Local value, + uint32_t initial_refcount, + ReferenceOwnership ownership, + napi_finalize finalize_callback, + void* finalize_data, + void* finalize_hint) + : Reference(env, value, initial_refcount, ownership), + finalizer_(env, finalize_callback, finalize_data, finalize_hint) {} + +ReferenceWithFinalizer::~ReferenceWithFinalizer() { + // Try to remove the finalizer from the scheduled second pass callback. + finalizer_.env()->DequeueFinalizer(this); +} + +void ReferenceWithFinalizer::CallUserFinalizer() { + finalizer_.CallFinalizer(); +} + +// The Node-API finalizer callback may make calls into the engine. V8's heap is +// not in a consistent state during the weak callback, and therefore it does +// not support calls back into it. Enqueue the invocation of the finalizer. +void ReferenceWithFinalizer::InvokeFinalizerFromGC() { + finalizer_.env()->InvokeFinalizerFromGC(this); } /** @@ -1709,6 +1707,30 @@ napi_status NAPI_CDECL node_api_create_external_string_utf16( }); } +napi_status node_api_create_property_key_latin1(napi_env env, + const char* str, + size_t length, + napi_value* result) { + return v8impl::NewString(env, str, length, result, [&](v8::Isolate* isolate) { + return v8::String::NewFromOneByte(isolate, + reinterpret_cast(str), + v8::NewStringType::kInternalized, + length); + }); +} + +napi_status node_api_create_property_key_utf8(napi_env env, + const char* str, + size_t length, + napi_value* result) { + return v8impl::NewString(env, str, length, result, [&](v8::Isolate* isolate) { + return v8::String::NewFromUtf8(isolate, + str, + v8::NewStringType::kInternalized, + static_cast(length)); + }); +} + napi_status NAPI_CDECL node_api_create_property_key_utf16(napi_env env, const char16_t* str, size_t length, @@ -2051,8 +2073,8 @@ napi_status NAPI_CDECL napi_get_cb_info( CHECK_ENV(env); CHECK_ARG(env, cbinfo); - v8impl::CallbackWrapper* info = - reinterpret_cast(cbinfo); + v8impl::FunctionCallbackWrapper* info = + reinterpret_cast(cbinfo); if (argv != nullptr) { CHECK_ARG(env, argc); @@ -2078,8 +2100,8 @@ napi_status NAPI_CDECL napi_get_new_target(napi_env env, CHECK_ARG(env, cbinfo); CHECK_ARG(env, result); - v8impl::CallbackWrapper* info = - reinterpret_cast(cbinfo); + v8impl::FunctionCallbackWrapper* info = + reinterpret_cast(cbinfo); *result = info->GetNewTarget(); return napi_clear_last_error(env); @@ -2605,13 +2627,13 @@ napi_create_external(napi_env env, if (finalize_cb) { // The Reference object will delete itself after invoking the finalizer // callback. - v8impl::Reference::New(env, - external_value, - 0, - v8impl::Ownership::kRuntime, - finalize_cb, - data, - finalize_hint); + v8impl::ReferenceWithFinalizer::New(env, + external_value, + 0, + v8impl::ReferenceOwnership::kRuntime, + finalize_cb, + data, + finalize_hint); } *result = v8impl::JsValueFromV8LocalValue(external_value); @@ -2746,7 +2768,7 @@ napi_status NAPI_CDECL napi_create_reference(napi_env env, } v8impl::Reference* reference = v8impl::Reference::New( - env, v8_value, initial_refcount, v8impl::Ownership::kUserland); + env, v8_value, initial_refcount, v8impl::ReferenceOwnership::kUserland); *result = reinterpret_cast(reference); return napi_clear_last_error(env); @@ -2802,7 +2824,7 @@ napi_status NAPI_CDECL napi_reference_unref(napi_env env, v8impl::Reference* reference = reinterpret_cast(ref); - if (reference->RefCount() == 0) { + if (reference->refcount() == 0) { return napi_set_last_error(env, napi_generic_failure); } @@ -2828,7 +2850,7 @@ napi_status NAPI_CDECL napi_get_reference_value(napi_env env, CHECK_ARG(env, result); v8impl::Reference* reference = reinterpret_cast(ref); - *result = v8impl::JsValueFromV8LocalValue(reference->Get()); + *result = v8impl::JsValueFromV8LocalValue(reference->Get(env)); return napi_clear_last_error(env); } @@ -3439,10 +3461,10 @@ napi_add_finalizer(napi_env env, // Create a self-deleting reference if the optional out-param result is not // set. - v8impl::Ownership ownership = result == nullptr - ? v8impl::Ownership::kRuntime - : v8impl::Ownership::kUserland; - v8impl::Reference* reference = v8impl::Reference::New( + v8impl::ReferenceOwnership ownership = + result == nullptr ? v8impl::ReferenceOwnership::kRuntime + : v8impl::ReferenceOwnership::kUserland; + v8impl::Reference* reference = v8impl::ReferenceWithFinalizer::New( env, v8_value, 0, ownership, finalize_cb, finalize_data, finalize_hint); if (result != nullptr) { @@ -3485,15 +3507,16 @@ napi_status NAPI_CDECL napi_set_instance_data(node_api_basic_env basic_env, napi_env env = const_cast(basic_env); CHECK_ENV(env); - v8impl::RefBase* old_data = static_cast(env->instance_data); + v8impl::TrackedFinalizer* old_data = + static_cast(env->instance_data); if (old_data != nullptr) { // Our contract so far has been to not finalize any old data there may be. // So we simply delete it. delete old_data; } - env->instance_data = v8impl::RefBase::New( - env, 0, v8impl::Ownership::kRuntime, finalize_cb, data, finalize_hint); + env->instance_data = + v8impl::TrackedFinalizer::New(env, finalize_cb, data, finalize_hint); return napi_clear_last_error(env); } @@ -3503,9 +3526,10 @@ napi_status NAPI_CDECL napi_get_instance_data(node_api_basic_env env, CHECK_ENV(env); CHECK_ARG(env, data); - v8impl::RefBase* idata = static_cast(env->instance_data); + v8impl::TrackedFinalizer* idata = + static_cast(env->instance_data); - *data = (idata == nullptr ? nullptr : idata->Data()); + *data = (idata == nullptr ? nullptr : idata->data()); return napi_clear_last_error(env); } diff --git a/src/js_native_api_v8.h b/src/js_native_api_v8.h index 1817226b2da..99bb30cfbe9 100644 --- a/src/js_native_api_v8.h +++ b/src/js_native_api_v8.h @@ -8,14 +8,15 @@ inline napi_status napi_clear_last_error(node_api_basic_env env); namespace v8impl { +// Base class to track references and finalizers in a doubly linked list. class RefTracker { public: + using RefList = RefTracker; + RefTracker() = default; virtual ~RefTracker() = default; virtual void Finalize() {} - typedef RefTracker RefList; - inline void Link(RefList* list) { prev_ = list; next_ = list->next_; @@ -47,7 +48,6 @@ class RefTracker { RefList* prev_ = nullptr; }; -class Finalizer; } // end of namespace v8impl struct napi_env__ { @@ -99,11 +99,7 @@ struct napi_env__ { } } - // Call finalizer immediately. - virtual void CallFinalizer(napi_finalize cb, void* data, void* hint) { - v8::HandleScope handle_scope(isolate); - CallIntoModule([&](napi_env env) { cb(env, data, hint); }); - } + virtual void CallFinalizer(napi_finalize cb, void* data, void* hint) = 0; // Invoke finalizer from V8 garbage collector. void InvokeFinalizerFromGC(v8impl::RefTracker* finalizer); @@ -323,7 +319,7 @@ inline v8::Local V8LocalValueFromJsValue(napi_value v) { // Adapter for napi_finalize callbacks. class Finalizer { - protected: + public: Finalizer(napi_env env, napi_finalize finalize_callback, void* finalize_data, @@ -333,23 +329,14 @@ class Finalizer { finalize_data_(finalize_data), finalize_hint_(finalize_hint) {} - virtual ~Finalizer() = default; - - public: - static Finalizer* New(napi_env env, - napi_finalize finalize_callback = nullptr, - void* finalize_data = nullptr, - void* finalize_hint = nullptr) { - return new Finalizer(env, finalize_callback, finalize_data, finalize_hint); - } - - napi_finalize callback() { return finalize_callback_; } + napi_env env() { return env_; } void* data() { return finalize_data_; } - void* hint() { return finalize_hint_; } + void ResetEnv(); void ResetFinalizer(); + void CallFinalizer(); - protected: + private: napi_env env_; napi_finalize finalize_callback_; void* finalize_data_; @@ -370,24 +357,8 @@ class TryCatch : public v8::TryCatch { napi_env _env; }; -// Ownership of a reference. -enum class Ownership { - // The reference is owned by the runtime. No userland call is needed to - // destruct the reference. - kRuntime, - // The reference is owned by the userland. User code is responsible to delete - // the reference with appropriate node-api calls. - kUserland, -}; - // Wrapper around Finalizer that can be tracked. -class TrackedFinalizer : public Finalizer, public RefTracker { - protected: - TrackedFinalizer(napi_env env, - napi_finalize finalize_callback, - void* finalize_data, - void* finalize_hint); - +class TrackedFinalizer final : public RefTracker { public: static TrackedFinalizer* New(napi_env env, napi_finalize finalize_callback, @@ -395,76 +366,120 @@ class TrackedFinalizer : public Finalizer, public RefTracker { void* finalize_hint); ~TrackedFinalizer() override; - protected: - void Finalize() override; - void FinalizeCore(bool deleteMe); -}; + void* data() { return finalizer_.data(); } -// Wrapper around TrackedFinalizer that implements reference counting. -class RefBase : public TrackedFinalizer { - protected: - RefBase(napi_env env, - uint32_t initial_refcount, - Ownership ownership, - napi_finalize finalize_callback, - void* finalize_data, - void* finalize_hint); - - public: - static RefBase* New(napi_env env, - uint32_t initial_refcount, - Ownership ownership, - napi_finalize finalize_callback, - void* finalize_data, - void* finalize_hint); - - void* Data(); - uint32_t Ref(); - uint32_t Unref(); - uint32_t RefCount(); - - Ownership ownership() { return ownership_; } - - protected: + private: + TrackedFinalizer(napi_env env, + napi_finalize finalize_callback, + void* finalize_data, + void* finalize_hint); void Finalize() override; private: - uint32_t refcount_; - Ownership ownership_; + Finalizer finalizer_; }; -// Wrapper around v8impl::Persistent. -class Reference : public RefBase { - protected: - template - Reference(napi_env env, v8::Local value, Args&&... args); +// Ownership of a reference. +enum class ReferenceOwnership : uint8_t { + // The reference is owned by the runtime. No userland call is needed to + // destruct the reference. + kRuntime, + // The reference is owned by the userland. User code is responsible to delete + // the reference with appropriate node-api calls. + kUserland, +}; +// Wrapper around v8impl::Persistent. +class Reference : public RefTracker { public: static Reference* New(napi_env env, v8::Local value, uint32_t initial_refcount, - Ownership ownership, - napi_finalize finalize_callback = nullptr, - void* finalize_data = nullptr, - void* finalize_hint = nullptr); + ReferenceOwnership ownership); + ~Reference() override; - virtual ~Reference(); uint32_t Ref(); uint32_t Unref(); - v8::Local Get(); + v8::Local Get(napi_env env); + + virtual void ResetFinalizer() {} + virtual void* Data() { return nullptr; } + + uint32_t refcount() const { return refcount_; } + ReferenceOwnership ownership() { return ownership_; } protected: - void Finalize() override; + Reference(napi_env env, + v8::Local value, + uint32_t initial_refcount, + ReferenceOwnership ownership); + virtual void CallUserFinalizer() {} + virtual void InvokeFinalizerFromGC(); private: static void WeakCallback(const v8::WeakCallbackInfo& data); - void SetWeak(); + void Finalize() override; + private: v8impl::Persistent persistent_; + uint32_t refcount_; + ReferenceOwnership ownership_; bool can_be_weak_; }; +// Reference that can store additional data. +class ReferenceWithData final : public Reference { + public: + static ReferenceWithData* New(napi_env env, + v8::Local value, + uint32_t initial_refcount, + ReferenceOwnership ownership, + void* data); + + void* Data() override { return data_; } + + private: + ReferenceWithData(napi_env env, + v8::Local value, + uint32_t initial_refcount, + ReferenceOwnership ownership, + void* data); + + private: + void* data_; +}; + +// Reference that has a user finalizer callback. +class ReferenceWithFinalizer final : public Reference { + public: + static ReferenceWithFinalizer* New(napi_env env, + v8::Local value, + uint32_t initial_refcount, + ReferenceOwnership ownership, + napi_finalize finalize_callback, + void* finalize_data, + void* finalize_hint); + ~ReferenceWithFinalizer() override; + + void ResetFinalizer() override { finalizer_.ResetFinalizer(); } + void* Data() override { return finalizer_.data(); } + + private: + ReferenceWithFinalizer(napi_env env, + v8::Local value, + uint32_t initial_refcount, + ReferenceOwnership ownership, + napi_finalize finalize_callback, + void* finalize_data, + void* finalize_hint); + void CallUserFinalizer() override; + void InvokeFinalizerFromGC() override; + + private: + Finalizer finalizer_; +}; + } // end of namespace v8impl #endif // SRC_JS_NATIVE_API_V8_H_ diff --git a/src/js_stream.cc b/src/js_stream.cc index af10fcac399..0d13066f54c 100644 --- a/src/js_stream.cc +++ b/src/js_stream.cc @@ -163,7 +163,7 @@ void JSStream::Finish(const FunctionCallbackInfo& args) { void JSStream::ReadBuffer(const FunctionCallbackInfo& args) { JSStream* wrap; - ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&wrap, args.This()); ArrayBufferViewContents buffer(args[0]); const char* data = buffer.data(); @@ -187,7 +187,7 @@ void JSStream::ReadBuffer(const FunctionCallbackInfo& args) { void JSStream::EmitEOF(const FunctionCallbackInfo& args) { JSStream* wrap; - ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&wrap, args.This()); wrap->EmitRead(UV_EOF); } diff --git a/src/js_udp_wrap.cc b/src/js_udp_wrap.cc index ed2238a3b5f..a4f183025df 100644 --- a/src/js_udp_wrap.cc +++ b/src/js_udp_wrap.cc @@ -137,12 +137,12 @@ SocketAddress JSUDPWrap::GetSockName() { void JSUDPWrap::New(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); CHECK(args.IsConstructCall()); - new JSUDPWrap(env, args.Holder()); + new JSUDPWrap(env, args.This()); } void JSUDPWrap::EmitReceived(const FunctionCallbackInfo& args) { JSUDPWrap* wrap; - ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&wrap, args.This()); Environment* env = wrap->env(); ArrayBufferViewContents buffer(args[0]); @@ -176,7 +176,7 @@ void JSUDPWrap::EmitReceived(const FunctionCallbackInfo& args) { void JSUDPWrap::OnSendDone(const FunctionCallbackInfo& args) { JSUDPWrap* wrap; - ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&wrap, args.This()); CHECK(args[0]->IsObject()); CHECK(args[1]->IsInt32()); @@ -189,7 +189,7 @@ void JSUDPWrap::OnSendDone(const FunctionCallbackInfo& args) { void JSUDPWrap::OnAfterBind(const FunctionCallbackInfo& args) { JSUDPWrap* wrap; - ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&wrap, args.This()); wrap->listener()->OnAfterBind(); } diff --git a/src/node_api.cc b/src/node_api.cc index 1bfb246ac75..d8a203ba420 100644 --- a/src/node_api.cc +++ b/src/node_api.cc @@ -121,9 +121,9 @@ namespace { class BufferFinalizer : private Finalizer { public: static BufferFinalizer* New(napi_env env, - napi_finalize finalize_callback = nullptr, - void* finalize_data = nullptr, - void* finalize_hint = nullptr) { + napi_finalize finalize_callback, + void* finalize_data, + void* finalize_hint) { return new BufferFinalizer( env, finalize_callback, finalize_data, finalize_hint); } @@ -131,13 +131,8 @@ class BufferFinalizer : private Finalizer { static void FinalizeBufferCallback(char* data, void* hint) { std::unique_ptr finalizer{ static_cast(hint)}; - finalizer->finalize_data_ = data; - // It is safe to call into JavaScript at this point. - if (finalizer->finalize_callback_ == nullptr) return; - finalizer->env_->CallFinalizer(finalizer->finalize_callback_, - finalizer->finalize_data_, - finalizer->finalize_hint_); + finalizer->CallFinalizer(); } struct Deleter { @@ -150,10 +145,10 @@ class BufferFinalizer : private Finalizer { void* finalize_data, void* finalize_hint) : Finalizer(env, finalize_callback, finalize_data, finalize_hint) { - env_->Ref(); + env->Ref(); } - ~BufferFinalizer() { env_->Unref(); } + ~BufferFinalizer() { env()->Unref(); } }; void ThrowNodeApiVersionError(node::Environment* node_env, @@ -1057,7 +1052,7 @@ napi_create_external_buffer(napi_env env, // The finalizer object will delete itself after invoking the callback. v8impl::BufferFinalizer* finalizer = - v8impl::BufferFinalizer::New(env, finalize_cb, nullptr, finalize_hint); + v8impl::BufferFinalizer::New(env, finalize_cb, data, finalize_hint); v8::MaybeLocal maybe = node::Buffer::New(isolate, diff --git a/src/node_blob.cc b/src/node_blob.cc index af6a443bbec..6c881344685 100644 --- a/src/node_blob.cc +++ b/src/node_blob.cc @@ -233,7 +233,7 @@ void Blob::New(const FunctionCallbackInfo& args) { void Blob::GetReader(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); Blob* blob; - ASSIGN_OR_RETURN_UNWRAP(&blob, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&blob, args.This()); BaseObjectPtr reader = Blob::Reader::Create(env, BaseObjectPtr(blob)); @@ -243,7 +243,7 @@ void Blob::GetReader(const FunctionCallbackInfo& args) { void Blob::ToSlice(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); Blob* blob; - ASSIGN_OR_RETURN_UNWRAP(&blob, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&blob, args.This()); CHECK(args[0]->IsUint32()); CHECK(args[1]->IsUint32()); size_t start = args[0].As()->Value(); @@ -312,7 +312,7 @@ BaseObjectPtr Blob::Reader::Create(Environment* env, void Blob::Reader::Pull(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); Blob::Reader* reader; - ASSIGN_OR_RETURN_UNWRAP(&reader, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&reader, args.This()); CHECK(args[0]->IsFunction()); Local fn = args[0].As(); diff --git a/src/node_buffer.cc b/src/node_buffer.cc index e7e3ead4416..d438b2bbdd8 100644 --- a/src/node_buffer.cc +++ b/src/node_buffer.cc @@ -57,6 +57,7 @@ using v8::ArrayBufferView; using v8::BackingStore; using v8::Context; using v8::EscapableHandleScope; +using v8::FastApiTypedArray; using v8::FunctionCallbackInfo; using v8::Global; using v8::HandleScope; @@ -80,7 +81,7 @@ using v8::Value; namespace { -class CallbackInfo { +class CallbackInfo : public Cleanable { public: static inline Local CreateTrackedArrayBuffer( Environment* env, @@ -93,7 +94,7 @@ class CallbackInfo { CallbackInfo& operator=(const CallbackInfo&) = delete; private: - static void CleanupHook(void* data); + void Clean(); inline void OnBackingStoreFree(); inline void CallAndResetCallback(); inline CallbackInfo(Environment* env, @@ -108,7 +109,6 @@ class CallbackInfo { Environment* const env_; }; - Local CallbackInfo::CreateTrackedArrayBuffer( Environment* env, char* data, @@ -148,25 +148,23 @@ CallbackInfo::CallbackInfo(Environment* env, data_(data), hint_(hint), env_(env) { - env->AddCleanupHook(CleanupHook, this); + env->cleanable_queue()->PushFront(this); env->isolate()->AdjustAmountOfExternalAllocatedMemory(sizeof(*this)); } -void CallbackInfo::CleanupHook(void* data) { - CallbackInfo* self = static_cast(data); - +void CallbackInfo::Clean() { { - HandleScope handle_scope(self->env_->isolate()); - Local ab = self->persistent_.Get(self->env_->isolate()); + HandleScope handle_scope(env_->isolate()); + Local ab = persistent_.Get(env_->isolate()); if (!ab.IsEmpty() && ab->IsDetachable()) { ab->Detach(Local()).Check(); - self->persistent_.Reset(); + persistent_.Reset(); } } // Call the callback in this case, but don't delete `this` yet because the // BackingStore deleter callback will do so later. - self->CallAndResetCallback(); + CallAndResetCallback(); } void CallbackInfo::CallAndResetCallback() { @@ -178,7 +176,7 @@ void CallbackInfo::CallAndResetCallback() { } if (callback != nullptr) { // Clean up all Environment-related state and run the callback. - env_->RemoveCleanupHook(CleanupHook, this); + cleanable_queue_.Remove(); int64_t change_in_bytes = -static_cast(sizeof(*this)); env_->isolate()->AdjustAmountOfExternalAllocatedMemory(change_in_bytes); @@ -528,17 +526,6 @@ MaybeLocal New(Environment* env, namespace { -void CreateFromString(const FunctionCallbackInfo& args) { - CHECK(args[0]->IsString()); - CHECK(args[1]->IsInt32()); - - enum encoding enc = static_cast(args[1].As()->Value()); - Local buf; - if (New(args.GetIsolate(), args[0].As(), enc).ToLocal(&buf)) - args.GetReturnValue().Set(buf); -} - - template void StringSlice(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); @@ -1071,37 +1058,57 @@ void IndexOfBuffer(const FunctionCallbackInfo& args) { result == haystack_length ? -1 : static_cast(result)); } -void IndexOfNumber(const FunctionCallbackInfo& args) { +int32_t IndexOfNumber(const uint8_t* buffer_data, + size_t buffer_length, + uint32_t needle, + int64_t offset_i64, + bool is_forward) { + int64_t opt_offset = IndexOfOffset(buffer_length, offset_i64, 1, is_forward); + if (opt_offset <= -1 || buffer_length == 0) { + return -1; + } + size_t offset = static_cast(opt_offset); + CHECK_LT(offset, buffer_length); + + const void* ptr; + if (is_forward) { + ptr = memchr(buffer_data + offset, needle, buffer_length - offset); + } else { + ptr = node::stringsearch::MemrchrFill(buffer_data, needle, offset + 1); + } + const uint8_t* ptr_uint8 = static_cast(ptr); + return ptr != nullptr ? static_cast(ptr_uint8 - buffer_data) : -1; +} + +void SlowIndexOfNumber(const FunctionCallbackInfo& args) { CHECK(args[1]->IsUint32()); CHECK(args[2]->IsNumber()); CHECK(args[3]->IsBoolean()); THROW_AND_RETURN_UNLESS_BUFFER(Environment::GetCurrent(args), args[0]); - ArrayBufferViewContents buffer(args[0]); + ArrayBufferViewContents buffer(args[0]); uint32_t needle = args[1].As()->Value(); int64_t offset_i64 = args[2].As()->Value(); bool is_forward = args[3]->IsTrue(); - int64_t opt_offset = - IndexOfOffset(buffer.length(), offset_i64, 1, is_forward); - if (opt_offset <= -1 || buffer.length() == 0) { - return args.GetReturnValue().Set(-1); - } - size_t offset = static_cast(opt_offset); - CHECK_LT(offset, buffer.length()); + args.GetReturnValue().Set(IndexOfNumber( + buffer.data(), buffer.length(), needle, offset_i64, is_forward)); +} - const void* ptr; - if (is_forward) { - ptr = memchr(buffer.data() + offset, needle, buffer.length() - offset); - } else { - ptr = node::stringsearch::MemrchrFill(buffer.data(), needle, offset + 1); - } - const char* ptr_char = static_cast(ptr); - args.GetReturnValue().Set(ptr ? static_cast(ptr_char - buffer.data()) - : -1); +int32_t FastIndexOfNumber(v8::Local, + const FastApiTypedArray& buffer, + uint32_t needle, + int64_t offset_i64, + bool is_forward) { + uint8_t* buffer_data; + CHECK(buffer.getStorageIfAligned(&buffer_data)); + return IndexOfNumber( + buffer_data, buffer.length(), needle, offset_i64, is_forward); } +static v8::CFunction fast_index_of_number( + v8::CFunction::Make(FastIndexOfNumber)); void Swap16(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); @@ -1401,7 +1408,6 @@ void Initialize(Local target, SetMethodNoSideEffect(context, target, "btoa", Btoa); SetMethod(context, target, "setBufferPrototype", SetBufferPrototype); - SetMethodNoSideEffect(context, target, "createFromString", CreateFromString); SetFastMethodNoSideEffect(context, target, @@ -1413,7 +1419,11 @@ void Initialize(Local target, SetMethodNoSideEffect(context, target, "compareOffset", CompareOffset); SetMethod(context, target, "fill", Fill); SetMethodNoSideEffect(context, target, "indexOfBuffer", IndexOfBuffer); - SetMethodNoSideEffect(context, target, "indexOfNumber", IndexOfNumber); + SetFastMethodNoSideEffect(context, + target, + "indexOfNumber", + SlowIndexOfNumber, + &fast_index_of_number); SetMethodNoSideEffect(context, target, "indexOfString", IndexOfString); SetMethod(context, target, "detachArrayBuffer", DetachArrayBuffer); @@ -1462,7 +1472,6 @@ void Initialize(Local target, void RegisterExternalReferences(ExternalReferenceRegistry* registry) { registry->Register(SetBufferPrototype); - registry->Register(CreateFromString); registry->Register(SlowByteLengthUtf8); registry->Register(fast_byte_length_utf8.GetTypeInfo()); @@ -1472,7 +1481,9 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) { registry->Register(CompareOffset); registry->Register(Fill); registry->Register(IndexOfBuffer); - registry->Register(IndexOfNumber); + registry->Register(SlowIndexOfNumber); + registry->Register(FastIndexOfNumber); + registry->Register(fast_index_of_number.GetTypeInfo()); registry->Register(IndexOfString); registry->Register(Swap16); diff --git a/src/node_contextify.cc b/src/node_contextify.cc index d873792ab95..8951cd378a9 100644 --- a/src/node_contextify.cc +++ b/src/node_contextify.cc @@ -111,9 +111,15 @@ Local Uint32ToName(Local context, uint32_t index) { BaseObjectPtr ContextifyContext::New( Environment* env, Local sandbox_obj, ContextOptions* options) { + Local object_template; HandleScope scope(env->isolate()); - Local object_template = env->contextify_global_template(); - DCHECK(!object_template.IsEmpty()); + CHECK_IMPLIES(sandbox_obj.IsEmpty(), options->vanilla); + if (!sandbox_obj.IsEmpty()) { + // Do not use the template with interceptors for vanilla contexts. + object_template = env->contextify_global_template(); + DCHECK(!object_template.IsEmpty()); + } + const SnapshotData* snapshot_data = env->isolate_data()->snapshot_data(); MicrotaskQueue* queue = @@ -208,7 +214,7 @@ MaybeLocal ContextifyContext::CreateV8Context( EscapableHandleScope scope(isolate); Local ctx; - if (snapshot_data == nullptr) { + if (object_template.IsEmpty() || snapshot_data == nullptr) { ctx = Context::New( isolate, nullptr, // extensions @@ -240,6 +246,7 @@ BaseObjectPtr ContextifyContext::New( Local sandbox_obj, ContextOptions* options) { HandleScope scope(env->isolate()); + CHECK_IMPLIES(sandbox_obj.IsEmpty(), options->vanilla); // This only initializes part of the context. The primordials are // only initialized when needed because even deserializing them slows // things down significantly and they are only needed in rare occasions @@ -258,8 +265,13 @@ BaseObjectPtr ContextifyContext::New( // embedder data field. The sandbox uses a private symbol to hold a reference // to the ContextifyContext wrapper which in turn internally references // the context from its constructor. - v8_context->SetEmbedderData(ContextEmbedderIndex::kSandboxObject, - sandbox_obj); + if (sandbox_obj.IsEmpty()) { + v8_context->SetEmbedderData(ContextEmbedderIndex::kSandboxObject, + v8::Undefined(env->isolate())); + } else { + v8_context->SetEmbedderData(ContextEmbedderIndex::kSandboxObject, + sandbox_obj); + } // Delegate the code generation validation to // node::ModifyCodeGenerationFromStrings. @@ -281,16 +293,19 @@ BaseObjectPtr ContextifyContext::New( Local wrapper; { Context::Scope context_scope(v8_context); - Local ctor_name = sandbox_obj->GetConstructorName(); - if (!ctor_name->Equals(v8_context, env->object_string()).FromMaybe(false) && - new_context_global - ->DefineOwnProperty( - v8_context, - v8::Symbol::GetToStringTag(env->isolate()), - ctor_name, - static_cast(v8::DontEnum)) - .IsNothing()) { - return BaseObjectPtr(); + if (!sandbox_obj.IsEmpty()) { + Local ctor_name = sandbox_obj->GetConstructorName(); + if (!ctor_name->Equals(v8_context, env->object_string()) + .FromMaybe(false) && + new_context_global + ->DefineOwnProperty( + v8_context, + v8::Symbol::GetToStringTag(env->isolate()), + ctor_name, + static_cast(v8::DontEnum)) + .IsNothing()) { + return BaseObjectPtr(); + } } // Assign host_defined_options_id to the global object so that in the @@ -319,23 +334,27 @@ BaseObjectPtr ContextifyContext::New( result->MakeWeak(); } - if (sandbox_obj + Local wrapper_holder = + sandbox_obj.IsEmpty() ? new_context_global : sandbox_obj; + if (!wrapper_holder.IsEmpty() && + wrapper_holder ->SetPrivate( v8_context, env->contextify_context_private_symbol(), wrapper) .IsNothing()) { return BaseObjectPtr(); } - // Assign host_defined_options_id to the sandbox object so that module - // callbacks like importModuleDynamically can be registered once back to the - // JS land. - if (sandbox_obj + + // Assign host_defined_options_id to the sandbox object or the global object + // (for vanilla contexts) so that module callbacks like + // importModuleDynamically can be registered once back to the JS land. + if (!sandbox_obj.IsEmpty() && + sandbox_obj ->SetPrivate(v8_context, env->host_defined_option_symbol(), options->host_defined_options_id) .IsNothing()) { return BaseObjectPtr(); } - return result; } @@ -368,18 +387,21 @@ void ContextifyContext::RegisterExternalReferences( // makeContext(sandbox, name, origin, strings, wasm); void ContextifyContext::MakeContext(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); + ContextOptions options; CHECK_EQ(args.Length(), 7); - CHECK(args[0]->IsObject()); - Local sandbox = args[0].As(); - - // Don't allow contextifying a sandbox multiple times. - CHECK( - !sandbox->HasPrivate( - env->context(), - env->contextify_context_private_symbol()).FromJust()); - - ContextOptions options; + Local sandbox; + if (args[0]->IsObject()) { + sandbox = args[0].As(); + // Don't allow contextifying a sandbox multiple times. + CHECK(!sandbox + ->HasPrivate(env->context(), + env->contextify_context_private_symbol()) + .FromJust()); + } else { + CHECK(args[0]->IsSymbol()); + options.vanilla = true; + } CHECK(args[1]->IsString()); options.name = args[1].As(); @@ -412,6 +434,12 @@ void ContextifyContext::MakeContext(const FunctionCallbackInfo& args) { try_catch.ReThrow(); return; } + + if (sandbox.IsEmpty()) { + args.GetReturnValue().Set(context_ptr->context()->Global()); + } else { + args.GetReturnValue().Set(sandbox); + } } void ContextifyContext::WeakCallback( @@ -422,14 +450,13 @@ void ContextifyContext::WeakCallback( // static ContextifyContext* ContextifyContext::ContextFromContextifiedSandbox( - Environment* env, - const Local& sandbox) { - Local context_global; - if (sandbox + Environment* env, const Local& wrapper_holder) { + Local contextify; + if (wrapper_holder ->GetPrivate(env->context(), env->contextify_context_private_symbol()) - .ToLocal(&context_global) && - context_global->IsObject()) { - return Unwrap(context_global.As()); + .ToLocal(&contextify) && + contextify->IsObject()) { + return Unwrap(contextify.As()); } return nullptr; } @@ -984,7 +1011,7 @@ void ContextifyScript::CreateCachedData( const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); ContextifyScript* wrapped_script; - ASSIGN_OR_RETURN_UNWRAP(&wrapped_script, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&wrapped_script, args.This()); Local unbound_script = PersistentToLocal::Default(env->isolate(), wrapped_script->script_); std::unique_ptr cached_data( @@ -1004,7 +1031,7 @@ void ContextifyScript::RunInContext(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); ContextifyScript* wrapped_script; - ASSIGN_OR_RETURN_UNWRAP(&wrapped_script, args.Holder()); + ASSIGN_OR_RETURN_UNWRAP(&wrapped_script, args.This()); CHECK_EQ(args.Length(), 5); CHECK(args[0]->IsObject() || args[0]->IsNull()); @@ -1065,7 +1092,7 @@ bool ContextifyScript::EvalMachine(Local context, if (!env->can_call_into_js()) return false; - if (!ContextifyScript::InstanceOf(env, args.Holder())) { + if (!ContextifyScript::InstanceOf(env, args.This())) { THROW_ERR_INVALID_THIS( env, "Script methods can only be called on script instances."); @@ -1075,7 +1102,7 @@ bool ContextifyScript::EvalMachine(Local context, TryCatchScope try_catch(env); Isolate::SafeForTerminationScope safe_for_termination(env->isolate()); ContextifyScript* wrapped_script; - ASSIGN_OR_RETURN_UNWRAP(&wrapped_script, args.Holder(), false); + ASSIGN_OR_RETURN_UNWRAP(&wrapped_script, args.This(), false); Local unbound_script = PersistentToLocal::Default(env->isolate(), wrapped_script->script_); Local - diff --git a/test/fixtures/wpt/streams/readable-streams/cancel.any.js b/test/fixtures/wpt/streams/readable-streams/cancel.any.js index 9915c1fb633..d44222f1497 100644 --- a/test/fixtures/wpt/streams/readable-streams/cancel.any.js +++ b/test/fixtures/wpt/streams/readable-streams/cancel.any.js @@ -234,3 +234,28 @@ promise_test(() => { return Promise.all([rs.cancel(), rs.getReader().closed]); }, 'ReadableStream cancellation: cancelling before start finishes should prevent pull() from being called'); + +promise_test(async () => { + + const events = []; + + const pendingPromise = new Promise(() => {}); + + const rs = new ReadableStream({ + pull() { + events.push('pull'); + return pendingPromise; + }, + cancel() { + events.push('cancel'); + } + }); + + const reader = rs.getReader(); + reader.read().catch(() => {}); // No await. + await delay(0); + await Promise.all([reader.cancel(), reader.closed]); + + assert_array_equals(events, ['pull', 'cancel'], 'cancel should have been called'); + +}, 'ReadableStream cancellation: underlyingSource.cancel() should called, even with pending pull'); diff --git a/test/fixtures/wpt/streams/readable-streams/from.any.js b/test/fixtures/wpt/streams/readable-streams/from.any.js index 58ad4d4add1..2a4212ab890 100644 --- a/test/fixtures/wpt/streams/readable-streams/from.any.js +++ b/test/fixtures/wpt/streams/readable-streams/from.any.js @@ -51,44 +51,50 @@ const iterableFactories = [ ['a sync iterable of values', () => { const chunks = ['a', 'b']; - const it = { + const iterator = { next() { return { done: chunks.length === 0, value: chunks.shift() }; - }, - [Symbol.iterator]: () => it + } + }; + const iterable = { + [Symbol.iterator]: () => iterator }; - return it; + return iterable; }], ['a sync iterable of promises', () => { const chunks = ['a', 'b']; - const it = { + const iterator = { next() { return chunks.length === 0 ? { done: true } : { done: false, value: Promise.resolve(chunks.shift()) }; - }, - [Symbol.iterator]: () => it + } + }; + const iterable = { + [Symbol.iterator]: () => iterator }; - return it; + return iterable; }], ['an async iterable', () => { const chunks = ['a', 'b']; - const it = { + const asyncIterator = { next() { return Promise.resolve({ done: chunks.length === 0, value: chunks.shift() }) - }, - [Symbol.asyncIterator]: () => it + } + }; + const asyncIterable = { + [Symbol.asyncIterator]: () => asyncIterator }; - return it; + return asyncIterable; }], ['a ReadableStream', () => { @@ -186,6 +192,18 @@ test(t => { assert_throws_exactly(theError, () => ReadableStream.from(iterable), 'from() should re-throw the error'); }, `ReadableStream.from ignores @@iterator if @@asyncIterator exists`); +test(() => { + const theError = new Error('a unique string'); + const iterable = { + [Symbol.asyncIterator]: null, + [Symbol.iterator]() { + throw theError + } + }; + + assert_throws_exactly(theError, () => ReadableStream.from(iterable), 'from() should re-throw the error'); +}, `ReadableStream.from ignores a null @@asyncIterator`); + promise_test(async () => { const iterable = { diff --git a/test/fixtures/wpt/url/WEB_FEATURES.yml b/test/fixtures/wpt/url/WEB_FEATURES.yml new file mode 100644 index 00000000000..4711efc1faf --- /dev/null +++ b/test/fixtures/wpt/url/WEB_FEATURES.yml @@ -0,0 +1,4 @@ +features: +- name: url-canparse + files: + - url-statics-canparse.* diff --git a/test/fixtures/wpt/url/a-element.html b/test/fixtures/wpt/url/a-element.html index 3429e07ec3f..3428fa00574 100644 --- a/test/fixtures/wpt/url/a-element.html +++ b/test/fixtures/wpt/url/a-element.html @@ -11,3 +11,13 @@
+ + + Link with embedded \n is parsed correctly + + diff --git a/test/fixtures/wpt/url/resources/setters_tests.json b/test/fixtures/wpt/url/resources/setters_tests.json index 82adf4cdce2..3850606d660 100644 --- a/test/fixtures/wpt/url/resources/setters_tests.json +++ b/test/fixtures/wpt/url/resources/setters_tests.json @@ -825,6 +825,17 @@ "port": "" } }, + { + "comment": "Stuff after a ? delimiter is ignored, trailing 'port'", + "href": "http://example.net/path", + "new_value": "example.com?stuff:8080", + "expected": { + "href": "http://example.com/path", + "host": "example.com", + "hostname": "example.com", + "port": "" + } + }, { "comment": "Stuff after a ? delimiter is ignored", "href": "http://example.net/path", @@ -924,6 +935,39 @@ "port": "8080" } }, + { + "comment": "Anything other than ASCII digit stops the port parser in a setter but is not an error", + "href": "http://example.net:8080", + "new_value": "example.com:invalid", + "expected": { + "href": "http://example.com:8080/", + "host": "example.com:8080", + "hostname": "example.com", + "port": "8080" + } + }, + { + "comment": "Anything other than ASCII digit stops the port parser in a setter but is not an error", + "href": "http://example.net:8080/test", + "new_value": "[::1]:invalid", + "expected": { + "href": "http://[::1]:8080/test", + "host": "[::1]:8080", + "hostname": "[::1]", + "port": "8080" + } + }, + { + "comment": "IPv6 without port", + "href": "http://example.net:8080/test", + "new_value": "[::1]", + "expected": { + "href": "http://[::1]:8080/test", + "host": "[::1]:8080", + "hostname": "[::1]", + "port": "8080" + } + }, { "comment": "Port numbers are 16 bit integers", "href": "http://example.net/path", diff --git a/test/fixtures/wpt/url/resources/toascii.json b/test/fixtures/wpt/url/resources/toascii.json index bca28b4a1e4..d02c4c7e866 100644 --- a/test/fixtures/wpt/url/resources/toascii.json +++ b/test/fixtures/wpt/url/resources/toascii.json @@ -172,5 +172,31 @@ { "input": "≯", "output": "xn--hdh" + }, + { + "comment": "NFC normalization (forbidden < and > characters are normalized to valid ones)", + "input": "=\u0338", + "output": "xn--1ch" + }, + { + "input": "<\u0338", + "output": "xn--gdh" + }, + { + "input": ">\u0338", + "output": "xn--hdh" + }, + { + "comment": "Same with inserted IDNA ignored code point", + "input": "=\u00AD\u0338", + "output": "xn--1ch" + }, + { + "input": "<\u00AD\u0338", + "output": "xn--gdh" + }, + { + "input": ">\u00AD\u0338", + "output": "xn--hdh" } ] diff --git a/test/fixtures/wpt/url/resources/urltestdata.json b/test/fixtures/wpt/url/resources/urltestdata.json index 287a84b467a..53f6d575e16 100644 --- a/test/fixtures/wpt/url/resources/urltestdata.json +++ b/test/fixtures/wpt/url/resources/urltestdata.json @@ -734,6 +734,36 @@ "search": "", "hash": "" }, + { + "input": "http://a:b@c\\", + "base": null, + "href": "http://a:b@c/", + "origin": "http://c", + "protocol": "http:", + "username": "a", + "password": "b", + "host": "c", + "hostname": "c", + "port": "", + "pathname": "/", + "search": "", + "hash": "" + }, + { + "input": "ws://a@b\\c", + "base": null, + "href": "ws://a@b/c", + "origin": "ws://b", + "protocol": "ws:", + "username": "a", + "password": "", + "host": "b", + "hostname": "b", + "port": "", + "pathname": "/c", + "search": "", + "hash": "" + }, { "input": "foo:/", "base": "http://example.org/foo/bar", @@ -1751,6 +1781,76 @@ "search": "", "hash": "" }, + { + "input": "file:///w|m", + "base": null, + "href": "file:///w|m", + "protocol": "file:", + "username": "", + "password": "", + "host": "", + "hostname": "", + "port": "", + "pathname": "/w|m", + "search": "", + "hash": "" + }, + { + "input": "file:///w||m", + "base": null, + "href": "file:///w||m", + "protocol": "file:", + "username": "", + "password": "", + "host": "", + "hostname": "", + "port": "", + "pathname": "/w||m", + "search": "", + "hash": "" + }, + { + "input": "file:///w|/m", + "base": null, + "href": "file:///w:/m", + "protocol": "file:", + "username": "", + "password": "", + "host": "", + "hostname": "", + "port": "", + "pathname": "/w:/m", + "search": "", + "hash": "" + }, + { + "input": "file:C|/m/", + "base": null, + "href": "file:///C:/m/", + "protocol": "file:", + "username": "", + "password": "", + "host": "", + "hostname": "", + "port": "", + "pathname": "/C:/m/", + "search": "", + "hash": "" + }, + { + "input": "file:C||/m/", + "base": null, + "href": "file:///C||/m/", + "protocol": "file:", + "username": "", + "password": "", + "host": "", + "hostname": "", + "port": "", + "pathname": "/C||/m/", + "search": "", + "hash": "" + }, "# Based on http://trac.webkit.org/browser/trunk/LayoutTests/fast/url/script-tests/path.js", { "input": "http://example.com/././foo", @@ -3560,6 +3660,34 @@ "search": "", "hash": "" }, + { + "input": "file:.", + "base": null, + "href": "file:///", + "protocol": "file:", + "username": "", + "password": "", + "host": "", + "hostname": "", + "port": "", + "pathname": "/", + "search": "", + "hash": "" + }, + { + "input": "file:.", + "base": "http://www.example.com/test", + "href": "file:///", + "protocol": "file:", + "username": "", + "password": "", + "host": "", + "hostname": "", + "port": "", + "pathname": "/", + "search": "", + "hash": "" + }, "# Based on http://trac.webkit.org/browser/trunk/LayoutTests/fast/url/host.html", "Basic canonicalization, uppercase should be converted to lowercase", { @@ -9529,5 +9657,160 @@ "pathname": "", "search": "", "hash": "" + }, + "Scheme relative path starting with multiple slashes", + { + "input": "///test", + "base": "http://example.org/", + "href": "http://test/", + "protocol": "http:", + "username": "", + "password": "", + "host": "test", + "hostname": "test", + "port": "", + "pathname": "/", + "search": "", + "hash": "" + }, + { + "input": "///\\//\\//test", + "base": "http://example.org/", + "href": "http://test/", + "protocol": "http:", + "username": "", + "password": "", + "host": "test", + "hostname": "test", + "port": "", + "pathname": "/", + "search": "", + "hash": "" + }, + { + "input": "///example.org/path", + "base": "http://example.org/", + "href": "http://example.org/path", + "protocol": "http:", + "username": "", + "password": "", + "host": "example.org", + "hostname": "example.org", + "port": "", + "pathname": "/path", + "search": "", + "hash": "" + }, + { + "input": "///example.org/../path", + "base": "http://example.org/", + "href": "http://example.org/path", + "protocol": "http:", + "username": "", + "password": "", + "host": "example.org", + "hostname": "example.org", + "port": "", + "pathname": "/path", + "search": "", + "hash": "" + }, + { + "input": "///example.org/../../", + "base": "http://example.org/", + "href": "http://example.org/", + "protocol": "http:", + "username": "", + "password": "", + "host": "example.org", + "hostname": "example.org", + "port": "", + "pathname": "/", + "search": "", + "hash": "" + }, + { + "input": "///example.org/../path/../../", + "base": "http://example.org/", + "href": "http://example.org/", + "protocol": "http:", + "username": "", + "password": "", + "host": "example.org", + "hostname": "example.org", + "port": "", + "pathname": "/", + "search": "", + "hash": "" + }, + { + "input": "///example.org/../path/../../path", + "base": "http://example.org/", + "href": "http://example.org/path", + "protocol": "http:", + "username": "", + "password": "", + "host": "example.org", + "hostname": "example.org", + "port": "", + "pathname": "/path", + "search": "", + "hash": "" + }, + { + "input": "/\\/\\//example.org/../path", + "base": "http://example.org/", + "href": "http://example.org/path", + "protocol": "http:", + "username": "", + "password": "", + "host": "example.org", + "hostname": "example.org", + "port": "", + "pathname": "/path", + "search": "", + "hash": "" + }, + { + "input": "///abcdef/../", + "base": "file:///", + "href": "file:///", + "protocol": "file:", + "username": "", + "password": "", + "host": "", + "hostname": "", + "port": "", + "pathname": "/", + "search": "", + "hash": "" + }, + { + "input": "/\\//\\/a/../", + "base": "file:///", + "href": "file://////", + "protocol": "file:", + "username": "", + "password": "", + "host": "", + "hostname": "", + "port": "", + "pathname": "////", + "search": "", + "hash": "" + }, + { + "input": "//a/../", + "base": "file:///", + "href": "file://a/", + "protocol": "file:", + "username": "", + "password": "", + "host": "a", + "hostname": "a", + "port": "", + "pathname": "/", + "search": "", + "hash": "" } ] diff --git a/test/fixtures/wpt/url/url-statics-parse.any.js b/test/fixtures/wpt/url/url-statics-parse.any.js new file mode 100644 index 00000000000..0822e9da07a --- /dev/null +++ b/test/fixtures/wpt/url/url-statics-parse.any.js @@ -0,0 +1,50 @@ +// This intentionally does not use resources/urltestdata.json to preserve resources. +[ + { + "url": undefined, + "base": undefined, + "expected": false + }, + { + "url": "aaa:b", + "base": undefined, + "expected": true + }, + { + "url": undefined, + "base": "aaa:b", + "expected": false + }, + { + "url": "aaa:/b", + "base": undefined, + "expected": true + }, + { + "url": undefined, + "base": "aaa:/b", + "expected": true + }, + { + "url": "https://test:test", + "base": undefined, + "expected": false + }, + { + "url": "a", + "base": "https://b/", + "expected": true + } +].forEach(({ url, base, expected }) => { + test(() => { + if (expected == false) { + assert_equals(URL.parse(url, base), null); + } else { + assert_equals(URL.parse(url, base).href, new URL(url, base).href); + } + }, `URL.parse(${url}, ${base})`); +}); + +test(() => { + assert_not_equals(URL.parse("https://example/"), URL.parse("https://example/")); +}, `URL.parse() should return a unique object`); diff --git a/test/fixtures/wpt/versions.json b/test/fixtures/wpt/versions.json index c31d76cc47f..65842342111 100644 --- a/test/fixtures/wpt/versions.json +++ b/test/fixtures/wpt/versions.json @@ -64,11 +64,11 @@ "path": "resources" }, "streams": { - "commit": "9b03282a99ef2314c1c2d5050a105a74a2940019", + "commit": "2bd26e124cf17b2f0a25c150794d640b07b2a870", "path": "streams" }, "url": { - "commit": "c2d7e70b52cbd9a5b938aa32f37078d7a71e0b21", + "commit": "6a39784534e118acc102cf5252c542378831401d", "path": "url" }, "user-timing": { @@ -95,4 +95,4 @@ "commit": "e97fac4791931fb7455ba3fad759d362c7108b09", "path": "webmessaging/broadcastchannel" } -} +} \ No newline at end of file diff --git a/test/js-native-api/6_object_wrap/test-object-wrap-ref.js b/test/js-native-api/6_object_wrap/test-object-wrap-ref.js index 81832c195c1..a7d866a6869 100644 --- a/test/js-native-api/6_object_wrap/test-object-wrap-ref.js +++ b/test/js-native-api/6_object_wrap/test-object-wrap-ref.js @@ -3,11 +3,12 @@ 'use strict'; const common = require('../../common'); const addon = require(`./build/${common.buildType}/6_object_wrap`); +const { gcUntil } = require('../../common/gc'); (function scope() { addon.objectWrapDanglingReference({}); })(); -common.gcUntil('object-wrap-ref', () => { +gcUntil('object-wrap-ref', () => { return addon.objectWrapDanglingReferenceTest(); }); diff --git a/test/js-native-api/7_factory_wrap/test.js b/test/js-native-api/7_factory_wrap/test.js index fd9771d43bb..f2afc94807c 100644 --- a/test/js-native-api/7_factory_wrap/test.js +++ b/test/js-native-api/7_factory_wrap/test.js @@ -4,6 +4,7 @@ const common = require('../../common'); const assert = require('assert'); const test = require(`./build/${common.buildType}/7_factory_wrap`); +const { gcUntil } = require('../../common/gc'); assert.strictEqual(test.finalizeCount, 0); async function runGCTests() { @@ -13,7 +14,7 @@ async function runGCTests() { assert.strictEqual(obj.plusOne(), 12); assert.strictEqual(obj.plusOne(), 13); })(); - await common.gcUntil('test 1', () => (test.finalizeCount === 1)); + await gcUntil('test 1', () => (test.finalizeCount === 1)); (() => { const obj2 = test.createObject(20); @@ -21,6 +22,6 @@ async function runGCTests() { assert.strictEqual(obj2.plusOne(), 22); assert.strictEqual(obj2.plusOne(), 23); })(); - await common.gcUntil('test 2', () => (test.finalizeCount === 2)); + await gcUntil('test 2', () => (test.finalizeCount === 2)); } runGCTests(); diff --git a/test/js-native-api/8_passing_wrapped/test.js b/test/js-native-api/8_passing_wrapped/test.js index d6da19fecd4..a192f6a7588 100644 --- a/test/js-native-api/8_passing_wrapped/test.js +++ b/test/js-native-api/8_passing_wrapped/test.js @@ -4,6 +4,7 @@ const common = require('../../common'); const assert = require('assert'); const addon = require(`./build/${common.buildType}/8_passing_wrapped`); +const { gcUntil } = require('../../common/gc'); async function runTest() { let obj1 = addon.createObject(10); @@ -14,7 +15,7 @@ async function runTest() { // Make sure the native destructor gets called. obj1 = null; obj2 = null; - await common.gcUntil('8_passing_wrapped', - () => (addon.finalizeCount() === 2)); + await gcUntil('8_passing_wrapped', + () => (addon.finalizeCount() === 2)); } runTest(); diff --git a/test/js-native-api/test_finalizer/test.js b/test/js-native-api/test_finalizer/test.js index cfbf57239c3..502db40122e 100644 --- a/test/js-native-api/test_finalizer/test.js +++ b/test/js-native-api/test_finalizer/test.js @@ -5,8 +5,10 @@ const common = require('../../common'); const test_finalizer = require(`./build/${common.buildType}/test_finalizer`); const assert = require('assert'); +const { gcUntil } = require('../../common/gc'); + // The goal of this test is to show that we can run "pure" finalizers in the -// current JS loop tick. Thus, we do not use common.gcUntil function works +// current JS loop tick. Thus, we do not use gcUntil function works // asynchronously using micro tasks. // We use IIFE for the obj scope instead of {} to be compatible with // non-V8 JS engines that do not support scoped variables. @@ -25,7 +27,7 @@ for (let i = 0; i < 10; ++i) { assert.strictEqual(test_finalizer.getFinalizerCallCount(), 1); // The finalizer that access JS cannot run synchronously. They are run in the -// next JS loop tick. Thus, we must use common.gcUntil. +// next JS loop tick. Thus, we must use gcUntil. async function runAsyncTests() { // We do not use common.mustCall() because we want to see the finalizer // called in response to GC and not as a part of env destruction. @@ -36,8 +38,8 @@ async function runAsyncTests() { const obj = {}; test_finalizer.addFinalizerWithJS(obj, () => { js_is_called = true; }); })(); - await common.gcUntil('ensure JS finalizer called', - () => (test_finalizer.getFinalizerCallCount() === 2)); + await gcUntil('ensure JS finalizer called', + () => (test_finalizer.getFinalizerCallCount() === 2)); assert(js_is_called); } runAsyncTests(); diff --git a/test/js-native-api/test_general/test.js b/test/js-native-api/test_general/test.js index 9072e734468..3d4f2f97156 100644 --- a/test/js-native-api/test_general/test.js +++ b/test/js-native-api/test_general/test.js @@ -4,6 +4,7 @@ const common = require('../../common'); const test_general = require(`./build/${common.buildType}/test_general`); const assert = require('assert'); +const { gcUntil } = require('../../common/gc'); const val1 = '1'; const val2 = 1; @@ -79,9 +80,9 @@ async function runGCTests() { assert.strictEqual(test_general.derefItemWasCalled(), false); (() => test_general.wrap({}))(); - await common.gcUntil('deref_item() was called upon garbage collecting a ' + + await gcUntil('deref_item() was called upon garbage collecting a ' + 'wrapped object.', - () => test_general.derefItemWasCalled()); + () => test_general.derefItemWasCalled()); // Ensure that removing a wrap and garbage collecting does not fire the // finalize callback. @@ -89,7 +90,7 @@ async function runGCTests() { test_general.testFinalizeWrap(z); test_general.removeWrap(z); z = null; - await common.gcUntil( + await gcUntil( 'finalize callback was not called upon garbage collection.', () => (!test_general.finalizeWasCalled())); } diff --git a/test/js-native-api/test_general/testFinalizer.js b/test/js-native-api/test_general/testFinalizer.js index 54265d61bc3..97517024926 100644 --- a/test/js-native-api/test_general/testFinalizer.js +++ b/test/js-native-api/test_general/testFinalizer.js @@ -4,6 +4,7 @@ const common = require('../../common'); const test_general = require(`./build/${common.buildType}/test_general`); const assert = require('assert'); +const { gcUntil } = require('../../common/gc'); let finalized = {}; const callback = common.mustCall(2); @@ -30,7 +31,7 @@ async function testFinalizeAndWrap() { test_general.wrap(finalizeAndWrap); test_general.addFinalizerOnly(finalizeAndWrap, common.mustCall()); finalizeAndWrap = null; - await common.gcUntil('test finalize and wrap', - () => test_general.derefItemWasCalled()); + await gcUntil('test finalize and wrap', + () => test_general.derefItemWasCalled()); } testFinalizeAndWrap(); diff --git a/test/js-native-api/test_reference/test.js b/test/js-native-api/test_reference/test.js index e65847fbdb0..34a1ac70ede 100644 --- a/test/js-native-api/test_reference/test.js +++ b/test/js-native-api/test_reference/test.js @@ -1,7 +1,8 @@ 'use strict'; // Flags: --expose-gc -const { gcUntil, buildType } = require('../../common'); +const { buildType } = require('../../common'); +const { gcUntil } = require('../../common/gc'); const assert = require('assert'); const test_reference = require(`./build/${buildType}/test_reference`); diff --git a/test/js-native-api/test_string/test.js b/test/js-native-api/test_string/test.js index ffcf0fab754..04515a286ce 100644 --- a/test/js-native-api/test_string/test.js +++ b/test/js-native-api/test_string/test.js @@ -4,131 +4,77 @@ const assert = require('assert'); // Testing api calls for string const test_string = require(`./build/${common.buildType}/test_string`); +// The insufficient buffer test case allocates a buffer of size 4, including +// the null terminator. +const kInsufficientIdx = 3; -const empty = ''; -assert.strictEqual(test_string.TestLatin1(empty), empty); -assert.strictEqual(test_string.TestUtf8(empty), empty); -assert.strictEqual(test_string.TestUtf16(empty), empty); -assert.strictEqual(test_string.TestLatin1AutoLength(empty), empty); -assert.strictEqual(test_string.TestUtf8AutoLength(empty), empty); -assert.strictEqual(test_string.TestUtf16AutoLength(empty), empty); -assert.strictEqual(test_string.TestLatin1External(empty), empty); -assert.strictEqual(test_string.TestUtf16External(empty), empty); -assert.strictEqual(test_string.TestLatin1ExternalAutoLength(empty), empty); -assert.strictEqual(test_string.TestUtf16ExternalAutoLength(empty), empty); -assert.strictEqual(test_string.TestPropertyKeyUtf16(empty), empty); -assert.strictEqual(test_string.TestPropertyKeyUtf16AutoLength(empty), empty); -assert.strictEqual(test_string.Utf16Length(empty), 0); -assert.strictEqual(test_string.Utf8Length(empty), 0); +const asciiCases = [ + '', + 'hello world', + 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789', + '?!@#$%^&*()_+-=[]{}/.,<>\'"\\', +]; -const str1 = 'hello world'; -assert.strictEqual(test_string.TestLatin1(str1), str1); -assert.strictEqual(test_string.TestUtf8(str1), str1); -assert.strictEqual(test_string.TestUtf16(str1), str1); -assert.strictEqual(test_string.TestLatin1AutoLength(str1), str1); -assert.strictEqual(test_string.TestUtf8AutoLength(str1), str1); -assert.strictEqual(test_string.TestUtf16AutoLength(str1), str1); -assert.strictEqual(test_string.TestLatin1External(str1), str1); -assert.strictEqual(test_string.TestUtf16External(str1), str1); -assert.strictEqual(test_string.TestLatin1ExternalAutoLength(str1), str1); -assert.strictEqual(test_string.TestUtf16ExternalAutoLength(str1), str1); -assert.strictEqual(test_string.TestLatin1Insufficient(str1), str1.slice(0, 3)); -assert.strictEqual(test_string.TestUtf8Insufficient(str1), str1.slice(0, 3)); -assert.strictEqual(test_string.TestUtf16Insufficient(str1), str1.slice(0, 3)); -assert.strictEqual(test_string.TestPropertyKeyUtf16(str1), str1); -assert.strictEqual(test_string.TestPropertyKeyUtf16AutoLength(str1), str1); -assert.strictEqual(test_string.Utf16Length(str1), 11); -assert.strictEqual(test_string.Utf8Length(str1), 11); +const latin1Cases = [ + { + str: '¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿', + utf8Length: 62, + utf8InsufficientIdx: 1, + }, + { + str: 'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþ', + utf8Length: 126, + utf8InsufficientIdx: 1, + }, +]; -const str2 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; -assert.strictEqual(test_string.TestLatin1(str2), str2); -assert.strictEqual(test_string.TestUtf8(str2), str2); -assert.strictEqual(test_string.TestUtf16(str2), str2); -assert.strictEqual(test_string.TestLatin1AutoLength(str2), str2); -assert.strictEqual(test_string.TestUtf8AutoLength(str2), str2); -assert.strictEqual(test_string.TestUtf16AutoLength(str2), str2); -assert.strictEqual(test_string.TestLatin1External(str2), str2); -assert.strictEqual(test_string.TestUtf16External(str2), str2); -assert.strictEqual(test_string.TestLatin1ExternalAutoLength(str2), str2); -assert.strictEqual(test_string.TestUtf16ExternalAutoLength(str2), str2); -assert.strictEqual(test_string.TestLatin1Insufficient(str2), str2.slice(0, 3)); -assert.strictEqual(test_string.TestUtf8Insufficient(str2), str2.slice(0, 3)); -assert.strictEqual(test_string.TestUtf16Insufficient(str2), str2.slice(0, 3)); -assert.strictEqual(test_string.TestPropertyKeyUtf16(str2), str2); -assert.strictEqual(test_string.TestPropertyKeyUtf16AutoLength(str2), str2); -assert.strictEqual(test_string.Utf16Length(str2), 62); -assert.strictEqual(test_string.Utf8Length(str2), 62); +const unicodeCases = [ + { + str: '\u{2003}\u{2101}\u{2001}\u{202}\u{2011}', + utf8Length: 14, + utf8InsufficientIdx: 1, + }, +]; -const str3 = '?!@#$%^&*()_+-=[]{}/.,<>\'"\\'; -assert.strictEqual(test_string.TestLatin1(str3), str3); -assert.strictEqual(test_string.TestUtf8(str3), str3); -assert.strictEqual(test_string.TestUtf16(str3), str3); -assert.strictEqual(test_string.TestLatin1AutoLength(str3), str3); -assert.strictEqual(test_string.TestUtf8AutoLength(str3), str3); -assert.strictEqual(test_string.TestUtf16AutoLength(str3), str3); -assert.strictEqual(test_string.TestLatin1External(str3), str3); -assert.strictEqual(test_string.TestUtf16External(str3), str3); -assert.strictEqual(test_string.TestLatin1ExternalAutoLength(str3), str3); -assert.strictEqual(test_string.TestUtf16ExternalAutoLength(str3), str3); -assert.strictEqual(test_string.TestLatin1Insufficient(str3), str3.slice(0, 3)); -assert.strictEqual(test_string.TestUtf8Insufficient(str3), str3.slice(0, 3)); -assert.strictEqual(test_string.TestUtf16Insufficient(str3), str3.slice(0, 3)); -assert.strictEqual(test_string.TestPropertyKeyUtf16(str3), str3); -assert.strictEqual(test_string.TestPropertyKeyUtf16AutoLength(str3), str3); -assert.strictEqual(test_string.Utf16Length(str3), 27); -assert.strictEqual(test_string.Utf8Length(str3), 27); +function testLatin1Cases(str) { + assert.strictEqual(test_string.TestLatin1(str), str); + assert.strictEqual(test_string.TestLatin1AutoLength(str), str); + assert.strictEqual(test_string.TestLatin1External(str), str); + assert.strictEqual(test_string.TestLatin1ExternalAutoLength(str), str); + assert.strictEqual(test_string.TestPropertyKeyLatin1(str), str); + assert.strictEqual(test_string.TestPropertyKeyLatin1AutoLength(str), str); + assert.strictEqual(test_string.Latin1Length(str), str.length); -const str4 = '¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿'; -assert.strictEqual(test_string.TestLatin1(str4), str4); -assert.strictEqual(test_string.TestUtf8(str4), str4); -assert.strictEqual(test_string.TestUtf16(str4), str4); -assert.strictEqual(test_string.TestLatin1AutoLength(str4), str4); -assert.strictEqual(test_string.TestUtf8AutoLength(str4), str4); -assert.strictEqual(test_string.TestUtf16AutoLength(str4), str4); -assert.strictEqual(test_string.TestLatin1External(str4), str4); -assert.strictEqual(test_string.TestUtf16External(str4), str4); -assert.strictEqual(test_string.TestLatin1ExternalAutoLength(str4), str4); -assert.strictEqual(test_string.TestUtf16ExternalAutoLength(str4), str4); -assert.strictEqual(test_string.TestLatin1Insufficient(str4), str4.slice(0, 3)); -assert.strictEqual(test_string.TestUtf8Insufficient(str4), str4.slice(0, 1)); -assert.strictEqual(test_string.TestUtf16Insufficient(str4), str4.slice(0, 3)); -assert.strictEqual(test_string.TestPropertyKeyUtf16(str4), str4); -assert.strictEqual(test_string.TestPropertyKeyUtf16AutoLength(str4), str4); -assert.strictEqual(test_string.Utf16Length(str4), 31); -assert.strictEqual(test_string.Utf8Length(str4), 62); + if (str !== '') { + assert.strictEqual(test_string.TestLatin1Insufficient(str), str.slice(0, kInsufficientIdx)); + } +} -const str5 = 'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþ'; -assert.strictEqual(test_string.TestLatin1(str5), str5); -assert.strictEqual(test_string.TestUtf8(str5), str5); -assert.strictEqual(test_string.TestUtf16(str5), str5); -assert.strictEqual(test_string.TestLatin1AutoLength(str5), str5); -assert.strictEqual(test_string.TestUtf8AutoLength(str5), str5); -assert.strictEqual(test_string.TestUtf16AutoLength(str5), str5); -assert.strictEqual(test_string.TestLatin1External(str5), str5); -assert.strictEqual(test_string.TestUtf16External(str5), str5); -assert.strictEqual(test_string.TestLatin1ExternalAutoLength(str5), str5); -assert.strictEqual(test_string.TestUtf16ExternalAutoLength(str5), str5); -assert.strictEqual(test_string.TestLatin1Insufficient(str5), str5.slice(0, 3)); -assert.strictEqual(test_string.TestUtf8Insufficient(str5), str5.slice(0, 1)); -assert.strictEqual(test_string.TestUtf16Insufficient(str5), str5.slice(0, 3)); -assert.strictEqual(test_string.TestPropertyKeyUtf16(str5), str5); -assert.strictEqual(test_string.TestPropertyKeyUtf16AutoLength(str5), str5); -assert.strictEqual(test_string.Utf16Length(str5), 63); -assert.strictEqual(test_string.Utf8Length(str5), 126); +function testUnicodeCases(str, utf8Length, utf8InsufficientIdx) { + assert.strictEqual(test_string.TestUtf8(str), str); + assert.strictEqual(test_string.TestUtf16(str), str); + assert.strictEqual(test_string.TestUtf8AutoLength(str), str); + assert.strictEqual(test_string.TestUtf16AutoLength(str), str); + assert.strictEqual(test_string.TestUtf16External(str), str); + assert.strictEqual(test_string.TestUtf16ExternalAutoLength(str), str); + assert.strictEqual(test_string.TestPropertyKeyUtf8(str), str); + assert.strictEqual(test_string.TestPropertyKeyUtf8AutoLength(str), str); + assert.strictEqual(test_string.TestPropertyKeyUtf16(str), str); + assert.strictEqual(test_string.TestPropertyKeyUtf16AutoLength(str), str); + assert.strictEqual(test_string.Utf8Length(str), utf8Length); + assert.strictEqual(test_string.Utf16Length(str), str.length); -const str6 = '\u{2003}\u{2101}\u{2001}\u{202}\u{2011}'; -assert.strictEqual(test_string.TestUtf8(str6), str6); -assert.strictEqual(test_string.TestUtf16(str6), str6); -assert.strictEqual(test_string.TestUtf8AutoLength(str6), str6); -assert.strictEqual(test_string.TestUtf16AutoLength(str6), str6); -assert.strictEqual(test_string.TestUtf16External(str6), str6); -assert.strictEqual(test_string.TestUtf16ExternalAutoLength(str6), str6); -assert.strictEqual(test_string.TestUtf8Insufficient(str6), str6.slice(0, 1)); -assert.strictEqual(test_string.TestUtf16Insufficient(str6), str6.slice(0, 3)); -assert.strictEqual(test_string.TestPropertyKeyUtf16(str6), str6); -assert.strictEqual(test_string.TestPropertyKeyUtf16AutoLength(str6), str6); -assert.strictEqual(test_string.Utf16Length(str6), 5); -assert.strictEqual(test_string.Utf8Length(str6), 14); + if (str !== '') { + assert.strictEqual(test_string.TestUtf8Insufficient(str), str.slice(0, utf8InsufficientIdx)); + assert.strictEqual(test_string.TestUtf16Insufficient(str), str.slice(0, kInsufficientIdx)); + } +} + +asciiCases.forEach(testLatin1Cases); +asciiCases.forEach((str) => testUnicodeCases(str, str.length, kInsufficientIdx)); +latin1Cases.forEach((it) => testLatin1Cases(it.str)); +latin1Cases.forEach((it) => testUnicodeCases(it.str, it.utf8Length, it.utf8InsufficientIdx)); +unicodeCases.forEach((it) => testUnicodeCases(it.str, it.utf8Length, it.utf8InsufficientIdx)); assert.throws(() => { test_string.TestLargeUtf8(); diff --git a/test/js-native-api/test_string/test_string.c b/test/js-native-api/test_string/test_string.c index 57353b9f630..01e5dbee391 100644 --- a/test/js-native-api/test_string/test_string.c +++ b/test/js-native-api/test_string/test_string.c @@ -293,6 +293,40 @@ static napi_value TestUtf16Insufficient(napi_env env, napi_callback_info info) { return output; } +static napi_value TestPropertyKeyLatin1(napi_env env, napi_callback_info info) { + return TestOneByteImpl(env, + info, + napi_get_value_string_latin1, + node_api_create_property_key_latin1, + actual_length); +} + +static napi_value TestPropertyKeyLatin1AutoLength(napi_env env, + napi_callback_info info) { + return TestOneByteImpl(env, + info, + napi_get_value_string_latin1, + node_api_create_property_key_latin1, + auto_length); +} + +static napi_value TestPropertyKeyUtf8(napi_env env, napi_callback_info info) { + return TestOneByteImpl(env, + info, + napi_get_value_string_utf8, + node_api_create_property_key_utf8, + actual_length); +} + +static napi_value TestPropertyKeyUtf8AutoLength(napi_env env, + napi_callback_info info) { + return TestOneByteImpl(env, + info, + napi_get_value_string_utf8, + node_api_create_property_key_utf8, + auto_length); +} + static napi_value TestPropertyKeyUtf16(napi_env env, napi_callback_info info) { return TestTwoByteImpl(env, info, @@ -310,6 +344,20 @@ static napi_value TestPropertyKeyUtf16AutoLength(napi_env env, auto_length); } +static napi_value Latin1Length(napi_env env, napi_callback_info info) { + napi_value args[1]; + NODE_API_CALL(env, validate_and_retrieve_single_string_arg(env, info, args)); + + size_t length; + NODE_API_CALL(env, + napi_get_value_string_latin1(env, args[0], NULL, 0, &length)); + + napi_value output; + NODE_API_CALL(env, napi_create_uint32(env, (uint32_t)length, &output)); + + return output; +} + static napi_value Utf16Length(napi_env env, napi_callback_info info) { napi_value args[1]; NODE_API_CALL(env, validate_and_retrieve_single_string_arg(env, info, args)); @@ -420,12 +468,19 @@ napi_value Init(napi_env env, napi_value exports) { DECLARE_NODE_API_PROPERTY("TestUtf16ExternalAutoLength", TestUtf16ExternalAutoLength), DECLARE_NODE_API_PROPERTY("TestUtf16Insufficient", TestUtf16Insufficient), + DECLARE_NODE_API_PROPERTY("Latin1Length", Latin1Length), DECLARE_NODE_API_PROPERTY("Utf16Length", Utf16Length), DECLARE_NODE_API_PROPERTY("Utf8Length", Utf8Length), DECLARE_NODE_API_PROPERTY("TestLargeUtf8", TestLargeUtf8), DECLARE_NODE_API_PROPERTY("TestLargeLatin1", TestLargeLatin1), DECLARE_NODE_API_PROPERTY("TestLargeUtf16", TestLargeUtf16), DECLARE_NODE_API_PROPERTY("TestMemoryCorruption", TestMemoryCorruption), + DECLARE_NODE_API_PROPERTY("TestPropertyKeyLatin1", TestPropertyKeyLatin1), + DECLARE_NODE_API_PROPERTY("TestPropertyKeyLatin1AutoLength", + TestPropertyKeyLatin1AutoLength), + DECLARE_NODE_API_PROPERTY("TestPropertyKeyUtf8", TestPropertyKeyUtf8), + DECLARE_NODE_API_PROPERTY("TestPropertyKeyUtf8AutoLength", + TestPropertyKeyUtf8AutoLength), DECLARE_NODE_API_PROPERTY("TestPropertyKeyUtf16", TestPropertyKeyUtf16), DECLARE_NODE_API_PROPERTY("TestPropertyKeyUtf16AutoLength", TestPropertyKeyUtf16AutoLength), diff --git a/test/node-api/test_reference_by_node_api_version/test.js b/test/node-api/test_reference_by_node_api_version/test.js index 32530f68150..6a9078600e1 100644 --- a/test/node-api/test_reference_by_node_api_version/test.js +++ b/test/node-api/test_reference_by_node_api_version/test.js @@ -7,7 +7,8 @@ // and symbol types, while in newer versions they can be created for // any value type. // -const { gcUntil, buildType } = require('../../common'); +const { buildType } = require('../../common'); +const { gcUntil } = require('../../common/gc'); const assert = require('assert'); const addon_v8 = require(`./build/${buildType}/test_reference_obj_only`); const addon_new = require(`./build/${buildType}/test_reference_all_types`); diff --git a/test/parallel/parallel.status b/test/parallel/parallel.status index 28f25e4be7e..79a953df7da 100644 --- a/test/parallel/parallel.status +++ b/test/parallel/parallel.status @@ -23,6 +23,10 @@ test-error-serdes: PASS, FLAKY test-sqlite: PASS, FLAKY [$system==win32] +# https://github.com/nodejs/node/issues/54807 +test-runner-watch-mode-complex: PASS, FLAKY +# https://github.com/nodejs/node/issues/54808 +test-async-context-frame: PASS, FLAKY # Windows on x86 [$system==win32 && $arch==ia32] @@ -32,8 +36,16 @@ test-worker-nearheaplimit-deadlock: PASS, FLAKY [$system==win32 && $arch==arm64] [$system==linux] -# https://github.com/nodejs/node/issues/43465 -test-http-server-request-timeouts-mixed: PASS, FLAKY +# https://github.com/nodejs/node/issues/54803 +test-performance-function: PASS, FLAKY +# https://github.com/nodejs/node/issues/54346 +test-esm-loader-hooks-inspect-wait: PASS, FLAKY +# https://github.com/nodejs/node/issues/54534 +test-runner-run-watch: PASS, FLAKY +# https://github.com/nodejs/node/issues/37692 +test-fs-utimes: PASS, FLAKY +# https://github.com/nodejs/node/issues/52274 +test-worker-arraybuffer-zerofill: PASS, FLAKY [$system==linux || $system==win32] # https://github.com/nodejs/node/issues/49605 @@ -45,6 +57,8 @@ test-http-server-headers-timeout-keepalive: PASS,FLAKY test-http-server-request-timeout-keepalive: PASS,FLAKY # https://github.com/nodejs/node/issues/50243 test-inspector-async-stack-traces-set-interval: PASS, FLAKY +# https://github.com/nodejs/node/issues/54811 +test-macos-app-sandbox: PASS, FLAKY [$arch==arm || $arch==arm64] # https://github.com/nodejs/node/pull/31178 @@ -52,6 +66,8 @@ test-crypto-dh-stateless: SKIP test-crypto-keygen: SKIP # https://github.com/nodejs/node/issues/52963 test-pipe-file-to-http: PASS, FLAKY +# https://github.com/nodejs/node/issues/54801 +test-debugger-heap-profiler: PASS, FLAKY [$system==solaris] # Also applies to SmartOS # https://github.com/nodejs/node/issues/43457 diff --git a/test/parallel/test-accessor-properties.js b/test/parallel/test-accessor-properties.js index ae7919ea318..7b6c041a8d0 100644 --- a/test/parallel/test-accessor-properties.js +++ b/test/parallel/test-accessor-properties.js @@ -1,21 +1,21 @@ -// Flags: --expose-internals +// Flags: --expose-internals --no-warnings 'use strict'; -const common = require('../common'); +const { hasCrypto } = require('../common'); // This tests that the accessor properties do not raise assertions // when called with incompatible receivers. const assert = require('assert'); +const { test } = require('node:test'); // Objects that call StreamBase::AddMethods, when setting up // their prototype const { internalBinding } = require('internal/test/binding'); -const TTY = internalBinding('tty_wrap').TTY; -const UDP = internalBinding('udp_wrap').UDP; +const { TTY } = internalBinding('tty_wrap'); +const { UDP } = internalBinding('udp_wrap'); -{ - // Should throw instead of raise assertions +test('Should throw instead of raise assertions', () => { assert.throws(() => { UDP.prototype.fd; // eslint-disable-line no-unused-expressions }, TypeError); @@ -36,20 +36,20 @@ const UDP = internalBinding('udp_wrap').UDP; 'typeof property descriptor ' + property + ' is not \'object\'' ); }); +}); - if (common.hasCrypto) { // eslint-disable-line node-core/crypto-check - // There are accessor properties in crypto too - const crypto = internalBinding('crypto'); +test('There are accessor properties in crypto too', { skip: !hasCrypto }, () => { + // There are accessor properties in crypto too + const crypto = internalBinding('crypto'); // eslint-disable-line node-core/crypto-check - assert.throws(() => { - // eslint-disable-next-line no-unused-expressions - crypto.SecureContext.prototype._external; - }, TypeError); + assert.throws(() => { + // eslint-disable-next-line no-unused-expressions + crypto.SecureContext.prototype._external; + }, TypeError); - assert.strictEqual( - typeof Object.getOwnPropertyDescriptor( - crypto.SecureContext.prototype, '_external'), - 'object' - ); - } -} + assert.strictEqual( + typeof Object.getOwnPropertyDescriptor( + crypto.SecureContext.prototype, '_external'), + 'object' + ); +}); diff --git a/test/parallel/test-arm-math-illegal-instruction.js b/test/parallel/test-arm-math-illegal-instruction.js index 4bf881d1b38..c4a6ec01ba8 100644 --- a/test/parallel/test-arm-math-illegal-instruction.js +++ b/test/parallel/test-arm-math-illegal-instruction.js @@ -1,5 +1,6 @@ 'use strict'; require('../common'); +const { test } = require('node:test'); // This test ensures Math functions don't fail with an "illegal instruction" // error on ARM devices (primarily on the Raspberry Pi 1) @@ -7,9 +8,11 @@ require('../common'); // and https://code.google.com/p/v8/issues/detail?id=4019 // Iterate over all Math functions -Object.getOwnPropertyNames(Math).forEach((functionName) => { - if (!/[A-Z]/.test(functionName)) { - // The function names don't have capital letters. - Math[functionName](-0.5); - } +test('Iterate over all Math functions', () => { + Object.getOwnPropertyNames(Math).forEach((functionName) => { + if (!/[A-Z]/.test(functionName)) { + // The function names don't have capital letters. + Math[functionName](-0.5); + } + }); }); diff --git a/test/parallel/test-assert-typedarray-deepequal.js b/test/parallel/test-assert-typedarray-deepequal.js index aee5225ca1f..1c1c4c030a2 100644 --- a/test/parallel/test-assert-typedarray-deepequal.js +++ b/test/parallel/test-assert-typedarray-deepequal.js @@ -2,6 +2,7 @@ require('../common'); const assert = require('assert'); +const { test, suite } = require('node:test'); function makeBlock(f) { const args = Array.prototype.slice.call(arguments, 1); @@ -10,82 +11,94 @@ function makeBlock(f) { }; } -const equalArrayPairs = [ - [new Uint8Array(1e5), new Uint8Array(1e5)], - [new Uint16Array(1e5), new Uint16Array(1e5)], - [new Uint32Array(1e5), new Uint32Array(1e5)], - [new Uint8ClampedArray(1e5), new Uint8ClampedArray(1e5)], - [new Int8Array(1e5), new Int8Array(1e5)], - [new Int16Array(1e5), new Int16Array(1e5)], - [new Int32Array(1e5), new Int32Array(1e5)], - [new Float32Array(1e5), new Float32Array(1e5)], - [new Float64Array(1e5), new Float64Array(1e5)], - [new Float32Array([+0.0]), new Float32Array([+0.0])], - [new Uint8Array([1, 2, 3, 4]).subarray(1), new Uint8Array([2, 3, 4])], - [new Uint16Array([1, 2, 3, 4]).subarray(1), new Uint16Array([2, 3, 4])], - [new Uint32Array([1, 2, 3, 4]).subarray(1, 3), new Uint32Array([2, 3])], - [new ArrayBuffer(3), new ArrayBuffer(3)], - [new SharedArrayBuffer(3), new SharedArrayBuffer(3)], -]; +suite('equalArrayPairs', () => { + const equalArrayPairs = [ + [new Uint8Array(1e5), new Uint8Array(1e5)], + [new Uint16Array(1e5), new Uint16Array(1e5)], + [new Uint32Array(1e5), new Uint32Array(1e5)], + [new Uint8ClampedArray(1e5), new Uint8ClampedArray(1e5)], + [new Int8Array(1e5), new Int8Array(1e5)], + [new Int16Array(1e5), new Int16Array(1e5)], + [new Int32Array(1e5), new Int32Array(1e5)], + [new Float32Array(1e5), new Float32Array(1e5)], + [new Float64Array(1e5), new Float64Array(1e5)], + [new Float32Array([+0.0]), new Float32Array([+0.0])], + [new Uint8Array([1, 2, 3, 4]).subarray(1), new Uint8Array([2, 3, 4])], + [new Uint16Array([1, 2, 3, 4]).subarray(1), new Uint16Array([2, 3, 4])], + [new Uint32Array([1, 2, 3, 4]).subarray(1, 3), new Uint32Array([2, 3])], + [new ArrayBuffer(3), new ArrayBuffer(3)], + [new SharedArrayBuffer(3), new SharedArrayBuffer(3)], + ]; -const looseEqualArrayPairs = [ - [new Float32Array([+0.0]), new Float32Array([-0.0])], - [new Float64Array([+0.0]), new Float64Array([-0.0])], -]; + for (const arrayPair of equalArrayPairs) { + test('', () => { + // eslint-disable-next-line no-restricted-properties + assert.deepEqual(arrayPair[0], arrayPair[1]); + assert.deepStrictEqual(arrayPair[0], arrayPair[1]); + }); + } +}); -const notEqualArrayPairs = [ - [new ArrayBuffer(3), new SharedArrayBuffer(3)], - [new Int16Array(256), new Uint16Array(256)], - [new Int16Array([256]), new Uint16Array([256])], - [new Float64Array([+0.0]), new Float32Array([-0.0])], - [new Uint8Array(2), new Uint8Array(3)], - [new Uint8Array([1, 2, 3]), new Uint8Array([4, 5, 6])], - [new Uint8ClampedArray([300, 2, 3]), new Uint8Array([300, 2, 3])], - [new Uint16Array([2]), new Uint16Array([3])], - [new Uint16Array([0]), new Uint16Array([256])], - [new Int16Array([0]), new Uint16Array([256])], - [new Int16Array([-256]), new Uint16Array([0xff00])], // same bits - [new Int32Array([-256]), new Uint32Array([0xffffff00])], // ditto - [new Float32Array([0.1]), new Float32Array([0.0])], - [new Float32Array([0.1]), new Float32Array([0.1, 0.2])], - [new Float64Array([0.1]), new Float64Array([0.0])], - [new Uint8Array([1, 2, 3]).buffer, new Uint8Array([4, 5, 6]).buffer], - [ - new Uint8Array(new SharedArrayBuffer(3)).fill(1).buffer, - new Uint8Array(new SharedArrayBuffer(3)).fill(2).buffer, - ], - [new ArrayBuffer(2), new ArrayBuffer(3)], - [new SharedArrayBuffer(2), new SharedArrayBuffer(3)], - [new ArrayBuffer(2), new SharedArrayBuffer(3)], - [ - new Uint8Array(new ArrayBuffer(3)).fill(1).buffer, - new Uint8Array(new SharedArrayBuffer(3)).fill(2).buffer, - ], -]; +suite('looseEqualArrayPairs', () => { + const looseEqualArrayPairs = [ + [new Float32Array([+0.0]), new Float32Array([-0.0])], + [new Float64Array([+0.0]), new Float64Array([-0.0])], + ]; -for (const arrayPair of equalArrayPairs) { - // eslint-disable-next-line no-restricted-properties - assert.deepEqual(arrayPair[0], arrayPair[1]); - assert.deepStrictEqual(arrayPair[0], arrayPair[1]); -} + for (const arrayPair of looseEqualArrayPairs) { + test('', () => { + // eslint-disable-next-line no-restricted-properties + assert.deepEqual(arrayPair[0], arrayPair[1]); + assert.throws( + makeBlock(assert.deepStrictEqual, arrayPair[0], arrayPair[1]), + assert.AssertionError + ); + }); + } +}); -for (const arrayPair of looseEqualArrayPairs) { - // eslint-disable-next-line no-restricted-properties - assert.deepEqual(arrayPair[0], arrayPair[1]); - assert.throws( - makeBlock(assert.deepStrictEqual, arrayPair[0], arrayPair[1]), - assert.AssertionError - ); -} +suite('notEqualArrayPairs', () => { + const notEqualArrayPairs = [ + [new ArrayBuffer(3), new SharedArrayBuffer(3)], + [new Int16Array(256), new Uint16Array(256)], + [new Int16Array([256]), new Uint16Array([256])], + [new Float64Array([+0.0]), new Float32Array([-0.0])], + [new Uint8Array(2), new Uint8Array(3)], + [new Uint8Array([1, 2, 3]), new Uint8Array([4, 5, 6])], + [new Uint8ClampedArray([300, 2, 3]), new Uint8Array([300, 2, 3])], + [new Uint16Array([2]), new Uint16Array([3])], + [new Uint16Array([0]), new Uint16Array([256])], + [new Int16Array([0]), new Uint16Array([256])], + [new Int16Array([-256]), new Uint16Array([0xff00])], // same bits + [new Int32Array([-256]), new Uint32Array([0xffffff00])], // ditto + [new Float32Array([0.1]), new Float32Array([0.0])], + [new Float32Array([0.1]), new Float32Array([0.1, 0.2])], + [new Float64Array([0.1]), new Float64Array([0.0])], + [new Uint8Array([1, 2, 3]).buffer, new Uint8Array([4, 5, 6]).buffer], + [ + new Uint8Array(new SharedArrayBuffer(3)).fill(1).buffer, + new Uint8Array(new SharedArrayBuffer(3)).fill(2).buffer, + ], + [new ArrayBuffer(2), new ArrayBuffer(3)], + [new SharedArrayBuffer(2), new SharedArrayBuffer(3)], + [new ArrayBuffer(2), new SharedArrayBuffer(3)], + [ + new Uint8Array(new ArrayBuffer(3)).fill(1).buffer, + new Uint8Array(new SharedArrayBuffer(3)).fill(2).buffer, + ], + ]; -for (const arrayPair of notEqualArrayPairs) { - assert.throws( - // eslint-disable-next-line no-restricted-properties - makeBlock(assert.deepEqual, arrayPair[0], arrayPair[1]), - assert.AssertionError - ); - assert.throws( - makeBlock(assert.deepStrictEqual, arrayPair[0], arrayPair[1]), - assert.AssertionError - ); -} + for (const arrayPair of notEqualArrayPairs) { + test('', () => { + assert.throws( + // eslint-disable-next-line no-restricted-properties + makeBlock(assert.deepEqual, arrayPair[0], arrayPair[1]), + assert.AssertionError + ); + assert.throws( + makeBlock(assert.deepStrictEqual, arrayPair[0], arrayPair[1]), + assert.AssertionError + ); + }); + } +}); diff --git a/test/parallel/test-assert.js b/test/parallel/test-assert.js index 26d239e8889..f4cd8670e5c 100644 --- a/test/parallel/test-assert.js +++ b/test/parallel/test-assert.js @@ -21,11 +21,11 @@ 'use strict'; -const common = require('../common'); +const { invalidArgTypeHelper } = require('../common'); const assert = require('assert'); const { inspect } = require('util'); +const { test } = require('node:test'); const vm = require('vm'); -const a = assert; // Disable colored output to prevent color codes from breaking assertion // message comparisons. This should only be an issue when process.stdout @@ -37,14 +37,31 @@ const strictEqualMessageStart = 'Expected values to be strictly equal:\n'; const start = 'Expected values to be strictly deep-equal:'; const actExp = '+ actual - expected'; -assert.ok(a.AssertionError.prototype instanceof Error, - 'a.AssertionError instanceof Error'); - -assert.throws(() => a(false), a.AssertionError, 'ok(false)'); -assert.throws(() => a.ok(false), a.AssertionError, 'ok(false)'); +/* eslint-disable no-restricted-syntax */ +/* eslint-disable no-restricted-properties */ + +test('some basics', () => { + assert.ok(assert.AssertionError.prototype instanceof Error, + 'assert.AssertionError instanceof Error'); + + assert.throws(() => assert(false), assert.AssertionError, 'ok(false)'); + assert.throws(() => assert.ok(false), assert.AssertionError, 'ok(false)'); + assert(true); + assert('test', 'ok(\'test\')'); + assert.ok(true); + assert.ok('test'); + assert.throws(() => assert.equal(true, false), + assert.AssertionError, 'equal(true, false)'); + assert.equal(null, null); + assert.equal(undefined, undefined); + assert.equal(null, undefined); + assert.equal(true, true); + assert.equal(2, '2'); + assert.notEqual(true, false); + assert.notStrictEqual(2, '2'); +}); -// Throw message if the message is instanceof Error. -{ +test('Throw message if the message is instanceof Error', () => { let threw = false; try { assert.ok(false, new Error('ok(false)')); @@ -53,10 +70,9 @@ assert.throws(() => a.ok(false), a.AssertionError, 'ok(false)'); assert.ok(e instanceof Error); } assert.ok(threw, 'Error: ok(false)'); -} +}); -// Errors created in different contexts are handled as any other custom error -{ +test('Errors created in different contexts are handled as any other custom error', () => { const context = vm.createContext(); const error = vm.runInContext('new SyntaxError("custom error")', context); @@ -64,219 +80,213 @@ assert.throws(() => a.ok(false), a.AssertionError, 'ok(false)'); message: 'custom error', name: 'SyntaxError' }); -} +}); -a(true); -a('test', 'ok(\'test\')'); -a.ok(true); -a.ok('test'); +test('assert.throws()', () => { + assert.throws(() => assert.notEqual(true, true), + assert.AssertionError, 'notEqual(true, true)'); -assert.throws(() => a.equal(true, false), - a.AssertionError, 'equal(true, false)'); + assert.throws(() => assert.strictEqual(2, '2'), + assert.AssertionError, 'strictEqual(2, \'2\')'); -a.equal(null, null); -a.equal(undefined, undefined); -a.equal(null, undefined); -a.equal(true, true); -a.equal(2, '2'); -a.notEqual(true, false); + assert.throws(() => assert.strictEqual(null, undefined), + assert.AssertionError, 'strictEqual(null, undefined)'); -assert.throws(() => a.notEqual(true, true), - a.AssertionError, 'notEqual(true, true)'); + assert.throws( + () => assert.notStrictEqual(2, 2), + { + message: 'Expected "actual" to be strictly unequal to: 2', + name: 'AssertionError' + } + ); -assert.throws(() => a.strictEqual(2, '2'), - a.AssertionError, 'strictEqual(2, \'2\')'); + assert.throws( + () => assert.notStrictEqual('a '.repeat(30), 'a '.repeat(30)), + { + message: 'Expected "actual" to be strictly unequal to:\n\n' + + `'${'a '.repeat(30)}'`, + name: 'AssertionError' + } + ); -/* eslint-disable no-restricted-syntax */ -assert.throws(() => a.strictEqual(null, undefined), - a.AssertionError, 'strictEqual(null, undefined)'); + assert.throws( + () => assert.notEqual(1, 1), + { + message: '1 != 1', + operator: '!=' + } + ); -assert.throws( - () => a.notStrictEqual(2, 2), - { - message: 'Expected "actual" to be strictly unequal to: 2', - name: 'AssertionError' + // Testing the throwing. + function thrower(errorConstructor) { + throw new errorConstructor({}); } -); -assert.throws( - () => a.notStrictEqual('a '.repeat(30), 'a '.repeat(30)), + // The basic calls work. + assert.throws(() => thrower(assert.AssertionError), assert.AssertionError, 'message'); + assert.throws(() => thrower(assert.AssertionError), assert.AssertionError); + assert.throws(() => thrower(assert.AssertionError)); + + // If not passing an error, catch all. + assert.throws(() => thrower(TypeError)); + + // When passing a type, only catch errors of the appropriate type. + assert.throws( + () => assert.throws(() => thrower(TypeError), assert.AssertionError), + { + generatedMessage: true, + actual: new TypeError({}), + expected: assert.AssertionError, + code: 'ERR_ASSERTION', + name: 'AssertionError', + operator: 'throws', + message: 'The error is expected to be an instance of "AssertionError". ' + + 'Received "TypeError"\n\nError message:\n\n[object Object]' + } + ); + + // doesNotThrow should pass through all errors. { - message: 'Expected "actual" to be strictly unequal to:\n\n' + - `'${'a '.repeat(30)}'`, - name: 'AssertionError' + let threw = false; + try { + assert.doesNotThrow(() => thrower(TypeError), assert.AssertionError); + } catch (e) { + threw = true; + assert.ok(e instanceof TypeError); + } + assert(threw, 'assert.doesNotThrow with an explicit error is eating extra errors'); } -); -assert.throws( - () => a.notEqual(1, 1), + // Key difference is that throwing our correct error makes an assertion error. { - message: '1 != 1', - operator: '!=' + let threw = false; + try { + assert.doesNotThrow(() => thrower(TypeError), TypeError); + } catch (e) { + threw = true; + assert.ok(e instanceof assert.AssertionError); + assert.ok(!e.stack.includes('at Function.doesNotThrow')); + } + assert.ok(threw, 'assert.doesNotThrow is not catching type matching errors'); } -); -a.notStrictEqual(2, '2'); - -// Testing the throwing. -function thrower(errorConstructor) { - throw new errorConstructor({}); -} + assert.throws( + () => assert.doesNotThrow(() => thrower(Error), 'user message'), + { + name: 'AssertionError', + code: 'ERR_ASSERTION', + operator: 'doesNotThrow', + message: 'Got unwanted exception: user message\n' + + 'Actual message: "[object Object]"' + } + ); -// The basic calls work. -assert.throws(() => thrower(a.AssertionError), a.AssertionError, 'message'); -assert.throws(() => thrower(a.AssertionError), a.AssertionError); -assert.throws(() => thrower(a.AssertionError)); + assert.throws( + () => assert.doesNotThrow(() => thrower(Error)), + { + code: 'ERR_ASSERTION', + message: 'Got unwanted exception.\nActual message: "[object Object]"' + } + ); -// If not passing an error, catch all. -assert.throws(() => thrower(TypeError)); + assert.throws( + () => assert.doesNotThrow(() => thrower(Error), /\[[a-z]{6}\s[A-z]{6}\]/g, 'user message'), + { + name: 'AssertionError', + code: 'ERR_ASSERTION', + operator: 'doesNotThrow', + message: 'Got unwanted exception: user message\n' + + 'Actual message: "[object Object]"' + } + ); -// When passing a type, only catch errors of the appropriate type. -assert.throws( - () => a.throws(() => thrower(TypeError), a.AssertionError), + // Make sure that validating using constructor really works. { - generatedMessage: true, - actual: new TypeError({}), - expected: a.AssertionError, - code: 'ERR_ASSERTION', - name: 'AssertionError', - operator: 'throws', - message: 'The error is expected to be an instance of "AssertionError". ' + - 'Received "TypeError"\n\nError message:\n\n[object Object]' + let threw = false; + try { + assert.throws( + () => { + throw ({}); // eslint-disable-line no-throw-literal + }, + Array + ); + } catch { + threw = true; + } + assert.ok(threw, 'wrong constructor validation'); } -); -// doesNotThrow should pass through all errors. -{ - let threw = false; - try { - a.doesNotThrow(() => thrower(TypeError), a.AssertionError); - } catch (e) { - threw = true; - assert.ok(e instanceof TypeError); - } - assert(threw, 'a.doesNotThrow with an explicit error is eating extra errors'); -} + // Use a RegExp to validate the error message. + { + assert.throws(() => thrower(TypeError), /\[object Object\]/); -// Key difference is that throwing our correct error makes an assertion error. -{ - let threw = false; - try { - a.doesNotThrow(() => thrower(TypeError), TypeError); - } catch (e) { - threw = true; - assert.ok(e instanceof a.AssertionError); - assert.ok(!e.stack.includes('at Function.doesNotThrow')); - } - assert.ok(threw, 'a.doesNotThrow is not catching type matching errors'); -} + const symbol = Symbol('foo'); + assert.throws(() => { + throw symbol; + }, /foo/); -assert.throws( - () => a.doesNotThrow(() => thrower(Error), 'user message'), - { - name: 'AssertionError', - code: 'ERR_ASSERTION', - operator: 'doesNotThrow', - message: 'Got unwanted exception: user message\n' + - 'Actual message: "[object Object]"' + assert.throws(() => { + assert.throws(() => { + throw symbol; + }, /abc/); + }, { + message: 'The input did not match the regular expression /abc/. ' + + "Input:\n\n'Symbol(foo)'\n", + code: 'ERR_ASSERTION', + operator: 'throws', + actual: symbol, + expected: /abc/ + }); } -); -assert.throws( - () => a.doesNotThrow(() => thrower(Error)), - { - code: 'ERR_ASSERTION', - message: 'Got unwanted exception.\nActual message: "[object Object]"' - } -); + // Use a fn to validate the error object. + assert.throws(() => thrower(TypeError), (err) => { + if ((err instanceof TypeError) && /\[object Object\]/.test(err)) { + return true; + } + }); -assert.throws( - () => a.doesNotThrow(() => thrower(Error), /\[[a-z]{6}\s[A-z]{6}\]/g, 'user message'), + // https://github.com/nodejs/node/issues/3188 { - name: 'AssertionError', - code: 'ERR_ASSERTION', - operator: 'doesNotThrow', - message: 'Got unwanted exception: user message\n' + - 'Actual message: "[object Object]"' - } -); - -// Make sure that validating using constructor really works. -{ - let threw = false; - try { + let actual; assert.throws( () => { - throw ({}); // eslint-disable-line no-throw-literal + const ES6Error = class extends Error {}; + const AnotherErrorType = class extends Error {}; + + assert.throws(() => { + actual = new AnotherErrorType('foo'); + throw actual; + }, ES6Error); }, - Array + (err) => { + assert.strictEqual( + err.message, + 'The error is expected to be an instance of "ES6Error". ' + + 'Received "AnotherErrorType"\n\nError message:\n\nfoo' + ); + assert.strictEqual(err.actual, actual); + return true; + } ); - } catch { - threw = true; - } - assert.ok(threw, 'wrong constructor validation'); -} - -// Use a RegExp to validate the error message. -{ - a.throws(() => thrower(TypeError), /\[object Object\]/); - - const symbol = Symbol('foo'); - a.throws(() => { - throw symbol; - }, /foo/); - - a.throws(() => { - a.throws(() => { - throw symbol; - }, /abc/); - }, { - message: 'The input did not match the regular expression /abc/. ' + - "Input:\n\n'Symbol(foo)'\n", - code: 'ERR_ASSERTION', - operator: 'throws', - actual: symbol, - expected: /abc/ - }); -} - -// Use a fn to validate the error object. -a.throws(() => thrower(TypeError), (err) => { - if ((err instanceof TypeError) && /\[object Object\]/.test(err)) { - return true; } -}); -// https://github.com/nodejs/node/issues/3188 -{ - let actual; assert.throws( - () => { - const ES6Error = class extends Error {}; - const AnotherErrorType = class extends Error {}; - - assert.throws(() => { - actual = new AnotherErrorType('foo'); - throw actual; - }, ES6Error); - }, - (err) => { - assert.strictEqual( - err.message, - 'The error is expected to be an instance of "ES6Error". ' + - 'Received "AnotherErrorType"\n\nError message:\n\nfoo' - ); - assert.strictEqual(err.actual, actual); - return true; + () => assert.strictEqual(new Error('foo'), new Error('foobar')), + { + code: 'ERR_ASSERTION', + name: 'AssertionError', + message: 'Expected "actual" to be reference-equal to "expected":\n' + + '+ actual - expected\n\n' + + '+ [Error: foo]\n- [Error: foobar]' } ); -} +}); -// Check messages from assert.throws(). -{ +test('Check messages from assert.throws()', () => { const noop = () => {}; assert.throws( - () => { a.throws((noop)); }, + () => { assert.throws((noop)); }, { code: 'ERR_ASSERTION', message: 'Missing expected exception.', @@ -286,7 +296,7 @@ a.throws(() => thrower(TypeError), (err) => { }); assert.throws( - () => { a.throws(noop, TypeError); }, + () => { assert.throws(noop, TypeError); }, { code: 'ERR_ASSERTION', message: 'Missing expected exception (TypeError).', @@ -295,7 +305,7 @@ a.throws(() => thrower(TypeError), (err) => { }); assert.throws( - () => { a.throws(noop, 'fhqwhgads'); }, + () => { assert.throws(noop, 'fhqwhgads'); }, { code: 'ERR_ASSERTION', message: 'Missing expected exception: fhqwhgads', @@ -304,7 +314,7 @@ a.throws(() => thrower(TypeError), (err) => { }); assert.throws( - () => { a.throws(noop, TypeError, 'fhqwhgads'); }, + () => { assert.throws(noop, TypeError, 'fhqwhgads'); }, { code: 'ERR_ASSERTION', message: 'Missing expected exception (TypeError): fhqwhgads', @@ -314,78 +324,80 @@ a.throws(() => thrower(TypeError), (err) => { let threw = false; try { - a.throws(noop); + assert.throws(noop); } catch (e) { threw = true; - assert.ok(e instanceof a.AssertionError); + assert.ok(e instanceof assert.AssertionError); assert.ok(!e.stack.includes('at Function.throws')); } assert.ok(threw); -} +}); + +test('Test assertion messages', () => { + const circular = { y: 1 }; + circular.x = circular; + + function testAssertionMessage(actual, expected, msg) { + assert.throws( + () => assert.strictEqual(actual, ''), + { + generatedMessage: true, + message: msg || strictEqualMessageStart + + `+ actual - expected\n\n+ ${expected}\n- ''` + } + ); + } -const circular = { y: 1 }; -circular.x = circular; + function testShortAssertionMessage(actual, expected) { + testAssertionMessage(actual, expected, strictEqualMessageStart + + `\n${inspect(actual)} !== ''\n`); + } -function testAssertionMessage(actual, expected, msg) { + testShortAssertionMessage(null, 'null'); + testShortAssertionMessage(true, 'true'); + testShortAssertionMessage(false, 'false'); + testShortAssertionMessage(100, '100'); + testShortAssertionMessage(NaN, 'NaN'); + testShortAssertionMessage(Infinity, 'Infinity'); + testShortAssertionMessage('a', '"a"'); + testShortAssertionMessage('foo', '\'foo\''); + testShortAssertionMessage(0, '0'); + testShortAssertionMessage(Symbol(), 'Symbol()'); + testShortAssertionMessage(undefined, 'undefined'); + testShortAssertionMessage(-Infinity, '-Infinity'); + testAssertionMessage([], '[]'); + testAssertionMessage(/a/, '/a/'); + testAssertionMessage(/abc/gim, '/abc/gim'); + testAssertionMessage({}, '{}'); + testAssertionMessage([1, 2, 3], '[\n+ 1,\n+ 2,\n+ 3\n+ ]'); + testAssertionMessage(function f() {}, '[Function: f]'); + testAssertionMessage(function() {}, '[Function (anonymous)]'); + testAssertionMessage(circular, + ' {\n+ x: [Circular *1],\n+ y: 1\n+ }'); + testAssertionMessage({ a: undefined, b: null }, + '{\n+ a: undefined,\n+ b: null\n+ }'); + testAssertionMessage({ a: NaN, b: Infinity, c: -Infinity }, + '{\n+ a: NaN,\n+ b: Infinity,\n+ c: -Infinity\n+ }'); + + // https://github.com/nodejs/node-v0.x-archive/issues/5292 assert.throws( - () => assert.strictEqual(actual, ''), + () => assert.strictEqual(1, 2), { - generatedMessage: true, - message: msg || strictEqualMessageStart + - `+ actual - expected\n\n+ ${expected}\n- ''` + message: `${strictEqualMessageStart}\n1 !== 2\n`, + generatedMessage: true } ); -} - -function testShortAssertionMessage(actual, expected) { - testAssertionMessage(actual, expected, strictEqualMessageStart + - `\n${inspect(actual)} !== ''\n`); -} - -testShortAssertionMessage(null, 'null'); -testShortAssertionMessage(true, 'true'); -testShortAssertionMessage(false, 'false'); -testShortAssertionMessage(100, '100'); -testShortAssertionMessage(NaN, 'NaN'); -testShortAssertionMessage(Infinity, 'Infinity'); -testShortAssertionMessage('a', '"a"'); -testShortAssertionMessage('foo', '\'foo\''); -testShortAssertionMessage(0, '0'); -testShortAssertionMessage(Symbol(), 'Symbol()'); -testShortAssertionMessage(undefined, 'undefined'); -testShortAssertionMessage(-Infinity, '-Infinity'); -testAssertionMessage([], '[]'); -testAssertionMessage(/a/, '/a/'); -testAssertionMessage(/abc/gim, '/abc/gim'); -testAssertionMessage({}, '{}'); -testAssertionMessage([1, 2, 3], '[\n+ 1,\n+ 2,\n+ 3\n+ ]'); -testAssertionMessage(function f() {}, '[Function: f]'); -testAssertionMessage(function() {}, '[Function (anonymous)]'); -testAssertionMessage(circular, - ' {\n+ x: [Circular *1],\n+ y: 1\n+ }'); -testAssertionMessage({ a: undefined, b: null }, - '{\n+ a: undefined,\n+ b: null\n+ }'); -testAssertionMessage({ a: NaN, b: Infinity, c: -Infinity }, - '{\n+ a: NaN,\n+ b: Infinity,\n+ c: -Infinity\n+ }'); - -// https://github.com/nodejs/node-v0.x-archive/issues/5292 -assert.throws( - () => assert.strictEqual(1, 2), - { - message: `${strictEqualMessageStart}\n1 !== 2\n`, - generatedMessage: true - } -); -assert.throws( - () => assert.strictEqual(1, 2, 'oh no'), - { - message: 'oh no', - generatedMessage: false - } -); + assert.throws( + () => assert.strictEqual(1, 2, 'oh no'), + { + message: 'oh no', + generatedMessage: false + } + ); +}); -{ +test('Custom errors', () => { let threw = false; const rangeError = new RangeError('my range'); @@ -402,7 +414,7 @@ assert.throws( // Verify AssertionError is the result from doesNotThrow with custom Error. try { - a.doesNotThrow(() => { + assert.doesNotThrow(() => { throw new TypeError('wrong type'); }, TypeError, rangeError); } catch (e) { @@ -412,10 +424,9 @@ assert.throws( assert.ok(!e.stack.includes('doesNotThrow'), e); } assert.ok(threw); -} +}); -{ - // Verify that throws() and doesNotThrow() throw on non-functions. +test('Verify that throws() and doesNotThrow() throw on non-functions', () => { const testBlockTypeError = (method, fn) => { assert.throws( () => method(fn), @@ -423,7 +434,7 @@ assert.throws( code: 'ERR_INVALID_ARG_TYPE', name: 'TypeError', message: 'The "fn" argument must be of type function.' + - common.invalidArgTypeHelper(fn) + invalidArgTypeHelper(fn) } ); }; @@ -446,28 +457,29 @@ assert.throws( testBlockTypeError(assert.doesNotThrow, null); testBlockTypeError(assert.throws, undefined); testBlockTypeError(assert.doesNotThrow, undefined); -} - -// https://github.com/nodejs/node/issues/3275 -// eslint-disable-next-line no-throw-literal -assert.throws(() => { throw 'error'; }, (err) => err === 'error'); -assert.throws(() => { throw new Error(); }, (err) => err instanceof Error); - -// Long values should be truncated for display. -assert.throws(() => { - assert.strictEqual('A'.repeat(1000), ''); -}, (err) => { - assert.strictEqual(err.code, 'ERR_ASSERTION'); - assert.strictEqual(err.message, - `${strictEqualMessageStart}+ actual - expected\n\n` + - `+ '${'A'.repeat(1000)}'\n- ''`); - assert.strictEqual(err.actual.length, 1000); - assert.ok(inspect(err).includes(`actual: '${'A'.repeat(488)}...'`)); - return true; }); -// Output that extends beyond 10 lines should also be truncated for display. -{ +test('https://github.com/nodejs/node/issues/3275', () => { + // eslint-disable-next-line no-throw-literal + assert.throws(() => { throw 'error'; }, (err) => err === 'error'); + assert.throws(() => { throw new Error(); }, (err) => err instanceof Error); +}); + +test('Long values should be truncated for display', () => { + assert.throws(() => { + assert.strictEqual('A'.repeat(1000), ''); + }, (err) => { + assert.strictEqual(err.code, 'ERR_ASSERTION'); + assert.strictEqual(err.message, + `${strictEqualMessageStart}+ actual - expected\n\n` + + `+ '${'A'.repeat(1000)}'\n- ''`); + assert.strictEqual(err.actual.length, 1000); + assert.ok(inspect(err).includes(`actual: '${'A'.repeat(488)}...'`)); + return true; + }); +}); + +test('Output that extends beyond 10 lines should also be truncated for display', () => { const multilineString = 'fhqwhgads\n'.repeat(15); assert.throws(() => { assert.strictEqual(multilineString, ''); @@ -481,10 +493,9 @@ assert.throws(() => { " '...'")); return true; }); -} +}); -{ - // Bad args to AssertionError constructor should throw TypeError. +test('Bad args to AssertionError constructor should throw TypeError.', () => { const args = [1, true, false, '', null, Infinity, Symbol('test'), undefined]; for (const input of args) { assert.throws( @@ -493,54 +504,43 @@ assert.throws(() => { code: 'ERR_INVALID_ARG_TYPE', name: 'TypeError', message: 'The "options" argument must be of type object.' + - common.invalidArgTypeHelper(input) + invalidArgTypeHelper(input) }); } -} +}); -assert.throws( - () => assert.strictEqual(new Error('foo'), new Error('foobar')), - { - code: 'ERR_ASSERTION', - name: 'AssertionError', - message: 'Expected "actual" to be reference-equal to "expected":\n' + - '+ actual - expected\n\n' + - '+ [Error: foo]\n- [Error: foobar]' - } -); - -a.equal(NaN, NaN); -a.throws( - () => a.notEqual(NaN, NaN), - a.AssertionError -); - -// Test strict assert. -{ - const a = require('assert'); - const assert = require('assert').strict; - /* eslint-disable no-restricted-properties */ - assert.throws(() => assert.equal(1, true), assert.AssertionError); - assert.notEqual(0, false); - assert.throws(() => assert.deepEqual(1, true), assert.AssertionError); - assert.notDeepEqual(0, false); - assert.equal(assert.strict, assert.strict.strict); - assert.equal(assert.equal, assert.strictEqual); - assert.equal(assert.deepEqual, assert.deepStrictEqual); - assert.equal(assert.notEqual, assert.notStrictEqual); - assert.equal(assert.notDeepEqual, assert.notDeepStrictEqual); - assert.equal(Object.keys(assert).length, Object.keys(a).length); - assert(7); +test('NaN is handled correctly', () => { + assert.equal(NaN, NaN); assert.throws( - () => assert(...[]), + () => assert.notEqual(NaN, NaN), + assert.AssertionError + ); +}); + +test('Test strict assert', () => { + const { strict } = require('assert'); + + strict.throws(() => strict.equal(1, true), strict.AssertionError); + strict.notEqual(0, false); + strict.throws(() => strict.deepEqual(1, true), strict.AssertionError); + strict.notDeepEqual(0, false); + strict.equal(strict.strict, strict.strict.strict); + strict.equal(strict.equal, strict.strictEqual); + strict.equal(strict.deepEqual, strict.deepStrictEqual); + strict.equal(strict.notEqual, strict.notStrictEqual); + strict.equal(strict.notDeepEqual, strict.notDeepStrictEqual); + strict.equal(Object.keys(strict).length, Object.keys(assert).length); + strict(7); + strict.throws( + () => strict(...[]), { message: 'No value argument passed to `assert.ok()`', name: 'AssertionError', generatedMessage: true } ); - assert.throws( - () => a(), + strict.throws( + () => assert(), { message: 'No value argument passed to `assert.ok()`', name: 'AssertionError' @@ -550,17 +550,17 @@ a.throws( // Test setting the limit to zero and that assert.strict works properly. const tmpLimit = Error.stackTraceLimit; Error.stackTraceLimit = 0; - assert.throws( + strict.throws( () => { - assert.ok( + strict.ok( typeof 123 === 'string' ); }, { code: 'ERR_ASSERTION', - constructor: assert.AssertionError, + constructor: strict.AssertionError, message: 'The expression evaluated to a falsy value:\n\n ' + - "assert.ok(\n typeof 123 === 'string'\n )\n" + "strict.ok(\n typeof 123 === 'string'\n )\n" } ); Error.stackTraceLimit = tmpLimit; @@ -582,8 +582,8 @@ a.throws( ' 4,', ' 5', ' ]'].join('\n'); - assert.throws( - () => assert.deepEqual([[[1, 2, 3]], 4, 5], [[[1, 2, '3']], 4, 5]), + strict.throws( + () => strict.deepEqual([[[1, 2, 3]], 4, 5], [[[1, 2, '3']], 4, 5]), { message }); message = [ @@ -602,8 +602,8 @@ a.throws( ' 1', ' ]', ].join('\n'); - assert.throws( - () => assert.deepEqual( + strict.throws( + () => strict.deepEqual( [1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1]), { message }); @@ -623,8 +623,8 @@ a.throws( ' 1', ' ]', ].join('\n'); - assert.throws( - () => assert.deepEqual( + strict.throws( + () => strict.deepEqual( [1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1]), { message }); @@ -644,8 +644,8 @@ a.throws( ' 1', ' ]', ].join('\n'); - assert.throws( - () => assert.deepEqual( + strict.throws( + () => strict.deepEqual( [1, 2, 1, 1, 0, 1, 1], [1, 1, 1, 1, 0, 1]), { message }); @@ -661,8 +661,8 @@ a.throws( '+ ]', '- undefined', ].join('\n'); - assert.throws( - () => assert.deepEqual([1, 2, 1], undefined), + strict.throws( + () => strict.deepEqual([1, 2, 1], undefined), { message }); message = [ @@ -675,8 +675,8 @@ a.throws( ' 1', ' ]', ].join('\n'); - assert.throws( - () => assert.deepEqual([1, 2, 1], [2, 1]), + strict.throws( + () => strict.deepEqual([1, 2, 1], [2, 1]), { message }); message = `${start}\n` + @@ -687,15 +687,15 @@ a.throws( '...\n' + '- 2,\n'.repeat(25) + '...'; - assert.throws( - () => assert.deepEqual(Array(28).fill(1), Array(28).fill(2)), + strict.throws( + () => strict.deepEqual(Array(28).fill(1), Array(28).fill(2)), { message }); const obj1 = {}; const obj2 = { loop: 'forever' }; obj2[inspect.custom] = () => '{}'; // No infinite loop and no custom inspect. - assert.throws(() => assert.deepEqual(obj1, obj2), { + strict.throws(() => strict.deepEqual(obj1, obj2), { message: `${start}\n` + `${actExp}\n` + '\n' + @@ -707,8 +707,8 @@ a.throws( }); // notDeepEqual tests - assert.throws( - () => assert.notDeepEqual([1], [1]), + strict.throws( + () => strict.notDeepEqual([1], [1]), { message: 'Expected "actual" not to be strictly deep-equal to:\n\n' + '[\n 1\n]\n' @@ -718,278 +718,260 @@ a.throws( message = 'Expected "actual" not to be strictly deep-equal to:' + `\n\n[${'\n 1,'.repeat(45)}\n...\n`; const data = Array(51).fill(1); - assert.throws( - () => assert.notDeepEqual(data, data), + strict.throws( + () => strict.notDeepEqual(data, data), { message }); - /* eslint-enable no-restricted-properties */ -} -assert.throws( - () => assert.ok(null), - { - code: 'ERR_ASSERTION', - constructor: assert.AssertionError, - generatedMessage: true, - message: 'The expression evaluated to a falsy value:\n\n ' + - 'assert.ok(null)\n' - } -); -assert.throws( - () => { - // This test case checks if `try` left brace without a line break - // before the assertion causes any wrong assertion message. - // Therefore, don't reformat the following code. - // Refs: https://github.com/nodejs/node/issues/30872 - try { assert.ok(0); // eslint-disable-line no-useless-catch, @stylistic/js/brace-style - } catch (err) { - throw err; +}); + +test('Additional asserts', () => { + assert.throws( + () => assert.ok(null), + { + code: 'ERR_ASSERTION', + constructor: assert.AssertionError, + generatedMessage: true, + message: 'The expression evaluated to a falsy value:\n\n ' + + 'assert.ok(null)\n' } - }, - { - code: 'ERR_ASSERTION', - constructor: assert.AssertionError, - generatedMessage: true, - message: 'The expression evaluated to a falsy value:\n\n ' + - 'assert.ok(0)\n' - } -); -assert.throws( - () => { - try { - throw new Error(); - // This test case checks if `catch` left brace without a line break - // before the assertion causes any wrong assertion message. - // Therefore, don't reformat the following code. - // Refs: https://github.com/nodejs/node/issues/30872 - } catch (err) { assert.ok(0); } // eslint-disable-line no-unused-vars - }, - { + ); + assert.throws( + () => { + // This test case checks if `try` left brace without a line break + // before the assertion causes any wrong assertion message. + // Therefore, don't reformat the following code. + // Refs: https://github.com/nodejs/node/issues/30872 + try { assert.ok(0); // eslint-disable-line no-useless-catch, @stylistic/js/brace-style + } catch (err) { + throw err; + } + }, + { + code: 'ERR_ASSERTION', + constructor: assert.AssertionError, + generatedMessage: true, + message: 'The expression evaluated to a falsy value:\n\n ' + + 'assert.ok(0)\n' + } + ); + assert.throws( + () => { + try { + throw new Error(); + // This test case checks if `catch` left brace without a line break + // before the assertion causes any wrong assertion message. + // Therefore, don't reformat the following code. + // Refs: https://github.com/nodejs/node/issues/30872 + } catch (err) { assert.ok(0); } // eslint-disable-line no-unused-vars + }, + { + code: 'ERR_ASSERTION', + constructor: assert.AssertionError, + generatedMessage: true, + message: 'The expression evaluated to a falsy value:\n\n ' + + 'assert.ok(0)\n' + } + ); + assert.throws( + () => { + // This test case checks if `function` left brace without a line break + // before the assertion causes any wrong assertion message. + // Therefore, don't reformat the following code. + // Refs: https://github.com/nodejs/node/issues/30872 + function test() { assert.ok(0); // eslint-disable-line @stylistic/js/brace-style + } + test(); + }, + { + code: 'ERR_ASSERTION', + constructor: assert.AssertionError, + generatedMessage: true, + message: 'The expression evaluated to a falsy value:\n\n ' + + 'assert.ok(0)\n' + } + ); + assert.throws( + () => assert(typeof 123n === 'string'), + { + code: 'ERR_ASSERTION', + constructor: assert.AssertionError, + generatedMessage: true, + message: 'The expression evaluated to a falsy value:\n\n ' + + "assert(typeof 123n === 'string')\n" + } + ); + + assert.throws( + () => assert(false, Symbol('foo')), + { + code: 'ERR_ASSERTION', + constructor: assert.AssertionError, + generatedMessage: false, + message: 'Symbol(foo)' + } + ); + + assert.throws( + () => { + assert.strictEqual((() => 'string')(), 123 instanceof + Buffer); + }, + { + code: 'ERR_ASSERTION', + constructor: assert.AssertionError, + message: 'Expected values to be strictly equal:\n' + + '+ actual - expected\n' + + '\n' + + "+ 'string'\n" + + '- false' + } + ); + + assert.throws( + () => { + assert.strictEqual((() => 'string')(), 123 instanceof + Buffer); + }, + { + code: 'ERR_ASSERTION', + constructor: assert.AssertionError, + message: 'Expected values to be strictly equal:\n' + + '+ actual - expected\n' + + '\n' + + "+ 'string'\n" + + '- false' + } + ); + + /* eslint-disable @stylistic/js/indent */ + assert.throws(() => { + assert.strictEqual(( + () => 'string')(), 123 instanceof + Buffer); + }, { code: 'ERR_ASSERTION', constructor: assert.AssertionError, - generatedMessage: true, - message: 'The expression evaluated to a falsy value:\n\n ' + - 'assert.ok(0)\n' - } -); -assert.throws( - () => { - // This test case checks if `function` left brace without a line break - // before the assertion causes any wrong assertion message. - // Therefore, don't reformat the following code. - // Refs: https://github.com/nodejs/node/issues/30872 - function test() { assert.ok(0); // eslint-disable-line @stylistic/js/brace-style + message: 'Expected values to be strictly equal:\n' + + '+ actual - expected\n' + + '\n' + + "+ 'string'\n" + + '- false' } - test(); - }, - { - code: 'ERR_ASSERTION', - constructor: assert.AssertionError, - generatedMessage: true, - message: 'The expression evaluated to a falsy value:\n\n ' + - 'assert.ok(0)\n' - } -); -assert.throws( - () => assert(typeof 123n === 'string'), - { - code: 'ERR_ASSERTION', - constructor: assert.AssertionError, - generatedMessage: true, - message: 'The expression evaluated to a falsy value:\n\n ' + - "assert(typeof 123n === 'string')\n" - } -); - -assert.throws( - () => assert(false, Symbol('foo')), - { - code: 'ERR_ASSERTION', - constructor: assert.AssertionError, - generatedMessage: false, - message: 'Symbol(foo)' - } -); - -assert.throws( - () => { - a( - (() => 'string')() - // eslint-disable-next-line @stylistic/js/operator-linebreak - === - 123 instanceof - Buffer - ); - }, - { - code: 'ERR_ASSERTION', - constructor: assert.AssertionError, - message: 'The expression evaluated to a falsy value:\n\n' + - ' a(\n' + - ' (() => \'string\')()\n' + - ' // eslint-disable-next-line @stylistic/js/operator-linebreak\n' + - ' ===\n' + - ' 123 instanceof\n' + - ' Buffer\n' + - ' )\n' - } -); - -assert.throws( - () => { - a( - (() => 'string')() - // eslint-disable-next-line @stylistic/js/operator-linebreak - === - 123 instanceof - Buffer - ); - }, - { - code: 'ERR_ASSERTION', - constructor: assert.AssertionError, - message: 'The expression evaluated to a falsy value:\n\n' + - ' a(\n' + - ' (() => \'string\')()\n' + - ' // eslint-disable-next-line @stylistic/js/operator-linebreak\n' + - ' ===\n' + - ' 123 instanceof\n' + - ' Buffer\n' + - ' )\n' - } -); - -/* eslint-disable @stylistic/js/indent */ -assert.throws(() => { -a(( - () => 'string')() === -123 instanceof -Buffer -); -}, { - code: 'ERR_ASSERTION', - constructor: assert.AssertionError, - message: 'The expression evaluated to a falsy value:\n\n' + - ' a((\n' + - ' () => \'string\')() ===\n' + - ' 123 instanceof\n' + - ' Buffer\n' + - ' )\n' - } -); -/* eslint-enable @stylistic/js/indent */ - -assert.throws( - () => { - assert(true); assert(null, undefined); - }, - { - code: 'ERR_ASSERTION', - constructor: assert.AssertionError, - message: 'The expression evaluated to a falsy value:\n\n ' + - 'assert(null, undefined)\n' - } -); + ); + /* eslint-enable @stylistic/js/indent */ -assert.throws( - () => { - assert - .ok(null, undefined); - }, - { - code: 'ERR_ASSERTION', - constructor: assert.AssertionError, - message: 'The expression evaluated to a falsy value:\n\n ' + - 'ok(null, undefined)\n' - } -); + assert.throws( + () => { + assert(true); assert(null, undefined); + }, + { + code: 'ERR_ASSERTION', + constructor: assert.AssertionError, + message: 'The expression evaluated to a falsy value:\n\n ' + + 'assert(null, undefined)\n' + } + ); -assert.throws( - // eslint-disable-next-line dot-notation, @stylistic/js/quotes - () => assert['ok']["apply"](null, [0]), - { - code: 'ERR_ASSERTION', - constructor: assert.AssertionError, - message: 'The expression evaluated to a falsy value:\n\n ' + - 'assert[\'ok\']["apply"](null, [0])\n' - } -); + assert.throws( + () => { + assert + .ok(null, undefined); + }, + { + code: 'ERR_ASSERTION', + constructor: assert.AssertionError, + message: 'The expression evaluated to a falsy value:\n\n ' + + 'ok(null, undefined)\n' + } + ); -assert.throws( - () => { - const wrapper = (fn, value) => fn(value); - wrapper(assert, false); - }, - { - code: 'ERR_ASSERTION', - constructor: assert.AssertionError, - message: 'The expression evaluated to a falsy value:\n\n fn(value)\n' - } -); + assert.throws( + // eslint-disable-next-line dot-notation, @stylistic/js/quotes + () => assert['ok']["apply"](null, [0]), + { + code: 'ERR_ASSERTION', + constructor: assert.AssertionError, + message: 'The expression evaluated to a falsy value:\n\n ' + + 'assert[\'ok\']["apply"](null, [0])\n' + } + ); -assert.throws( - () => assert.ok.call(null, 0), - { - code: 'ERR_ASSERTION', - constructor: assert.AssertionError, - message: 'The expression evaluated to a falsy value:\n\n ' + - 'assert.ok.call(null, 0)\n', - generatedMessage: true - } -); + assert.throws( + () => { + const wrapper = (fn, value) => fn(value); + wrapper(assert, false); + }, + { + code: 'ERR_ASSERTION', + constructor: assert.AssertionError, + message: 'The expression evaluated to a falsy value:\n\n fn(value)\n' + } + ); -assert.throws( - () => assert.ok.call(null, 0, 'test'), - { - code: 'ERR_ASSERTION', - constructor: assert.AssertionError, - message: 'test', - generatedMessage: false - } -); + assert.throws( + () => assert.ok.call(null, 0), + { + code: 'ERR_ASSERTION', + constructor: assert.AssertionError, + message: 'The expression evaluated to a falsy value:\n\n ' + + 'assert.ok.call(null, 0)\n', + generatedMessage: true + } + ); -// Works in eval. -assert.throws( - () => new Function('assert', 'assert(1 === 2);')(assert), - { - code: 'ERR_ASSERTION', - constructor: assert.AssertionError, - message: 'false == true' - } -); -assert.throws( - () => eval('console.log("FOO");\nassert.ok(1 === 2);'), - { - code: 'ERR_ASSERTION', - message: 'false == true' - } -); + assert.throws( + () => assert.ok.call(null, 0, 'test'), + { + code: 'ERR_ASSERTION', + constructor: assert.AssertionError, + message: 'test', + generatedMessage: false + } + ); -assert.throws( - () => assert.throws(() => {}, 'Error message', 'message'), - { - code: 'ERR_INVALID_ARG_TYPE', - name: 'TypeError', - message: 'The "error" argument must be of type function or ' + - 'an instance of Error, RegExp, or Object. Received type string ' + - "('Error message')" - } -); + // Works in eval. + assert.throws( + () => new Function('assert', 'assert(1 === 2);')(assert), + { + code: 'ERR_ASSERTION', + constructor: assert.AssertionError, + message: 'false == true' + } + ); + assert.throws( + () => eval('console.log("FOO");\nassert.ok(1 === 2);'), + { + code: 'ERR_ASSERTION', + message: 'false == true' + } + ); -const inputs = [1, false, Symbol()]; -for (const input of inputs) { assert.throws( - () => assert.throws(() => {}, input), + () => assert.throws(() => {}, 'Error message', 'message'), { code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', message: 'The "error" argument must be of type function or ' + - 'an instance of Error, RegExp, or Object.' + - common.invalidArgTypeHelper(input) + 'an instance of Error, RegExp, or Object. Received type string ' + + "('Error message')" } ); -} -{ + const inputs = [1, false, Symbol()]; + for (const input of inputs) { + assert.throws( + () => assert.throws(() => {}, input), + { + code: 'ERR_INVALID_ARG_TYPE', + message: 'The "error" argument must be of type function or ' + + 'an instance of Error, RegExp, or Object.' + + invalidArgTypeHelper(input) + } + ); + } +}); +test('Throws accepts objects', () => { assert.throws(() => { assert.ok((() => Boolean('' === false))()); }, { @@ -1057,7 +1039,7 @@ for (const input of inputs) { ); assert.throws( - () => a.doesNotThrow(() => { throw new Error(); }, { foo: 'bar' }), + () => assert.doesNotThrow(() => { throw new Error(); }, { foo: 'bar' }), { name: 'TypeError', code: 'ERR_INVALID_ARG_TYPE', @@ -1099,414 +1081,420 @@ for (const input of inputs) { assert.throws(() => { throw undefined; }, /undefined/); assert.throws( // eslint-disable-next-line no-throw-literal - () => a.doesNotThrow(() => { throw undefined; }), + () => assert.doesNotThrow(() => { throw undefined; }), { name: 'AssertionError', code: 'ERR_ASSERTION', message: 'Got unwanted exception.\nActual message: "undefined"' } ); -} - -assert.throws( - () => assert.throws(() => { throw new Error(); }, {}), - { - message: "The argument 'error' may not be an empty object. Received {}", - code: 'ERR_INVALID_ARG_VALUE' - } -); - -assert.throws( - () => a.throws( - // eslint-disable-next-line no-throw-literal - () => { throw 'foo'; }, - 'foo' - ), - { - code: 'ERR_AMBIGUOUS_ARGUMENT', - message: 'The "error/message" argument is ambiguous. ' + - 'The error "foo" is identical to the message.' - } -); - -assert.throws( - () => a.throws( - () => { throw new TypeError('foo'); }, - 'foo' - ), - { - code: 'ERR_AMBIGUOUS_ARGUMENT', - message: 'The "error/message" argument is ambiguous. ' + - 'The error message "foo" is identical to the message.' - } -); -/* eslint-enable no-restricted-syntax */ - -// Should not throw. -// eslint-disable-next-line no-restricted-syntax, no-throw-literal -assert.throws(() => { throw null; }, 'foo'); - -assert.throws( - () => assert.strictEqual([], []), - { - message: 'Values have same structure but are not reference-equal:\n\n[]\n' - } -); +}); -{ - const args = (function() { return arguments; })('a'); +test('Additional assert', () => { assert.throws( - () => assert.strictEqual(args, { 0: 'a' }), + () => assert.throws(() => { throw new Error(); }, {}), { - message: 'Expected "actual" to be reference-equal to "expected":\n' + - '+ actual - expected\n\n' + - "+ [Arguments] {\n- {\n '0': 'a'\n }" + message: "The argument 'error' may not be an empty object. Received {}", + code: 'ERR_INVALID_ARG_VALUE' } ); -} - -assert.throws( - () => { throw new TypeError('foobar'); }, - { - message: /foo/, - name: /^TypeError$/ - } -); -assert.throws( - () => assert.throws( - () => { throw new TypeError('foobar'); }, + assert.throws( + () => assert.throws( + // eslint-disable-next-line no-throw-literal + () => { throw 'foo'; }, + 'foo' + ), { - message: /fooa/, - name: /^TypeError$/ + code: 'ERR_AMBIGUOUS_ARGUMENT', + message: 'The "error/message" argument is ambiguous. ' + + 'The error "foo" is identical to the message.' } - ), - { - message: `${start}\n${actExp}\n\n` + - ' Comparison {\n' + - "+ message: 'foobar',\n" + - '- message: /fooa/,\n' + - " name: 'TypeError'\n" + - ' }' - } -); + ); -{ - let actual = null; - const expected = { message: 'foo' }; assert.throws( () => assert.throws( - () => { throw actual; }, - expected + () => { throw new TypeError('foo'); }, + 'foo' ), { - operator: 'throws', - actual, - expected, - generatedMessage: true, - message: `${start}\n${actExp}\n\n` + - '+ null\n' + - '- {\n' + - "- message: 'foo'\n" + - '- }' + code: 'ERR_AMBIGUOUS_ARGUMENT', + message: 'The "error/message" argument is ambiguous. ' + + 'The error message "foo" is identical to the message.' } ); - actual = 'foobar'; - const message = 'message'; + // Should not throw. + assert.throws(() => { throw null; }, 'foo'); // eslint-disable-line no-throw-literal + assert.throws( - () => assert.throws( - () => { throw actual; }, - { message: 'foobar' }, - message - ), + () => assert.strictEqual([], []), { - actual, - message, - operator: 'throws', - generatedMessage: false + message: 'Values have same structure but are not reference-equal:\n\n[]\n' } ); -} -// Indicate where the strings diverge. -assert.throws( - () => assert.strictEqual('test test', 'test foobar'), { - code: 'ERR_ASSERTION', - name: 'AssertionError', - message: strictEqualMessageStart + - '+ actual - expected\n\n' + - "+ 'test test'\n" + - "- 'test foobar'\n" + - ' ^' - } -); - -// Check for reference-equal objects in `notStrictEqual()` -assert.throws( - () => { - const obj = {}; - assert.notStrictEqual(obj, obj); - }, - { - code: 'ERR_ASSERTION', - name: 'AssertionError', - message: 'Expected "actual" not to be reference-equal to "expected": {}' + const args = (function() { return arguments; })('a'); + assert.throws( + () => assert.strictEqual(args, { 0: 'a' }), + { + message: 'Expected "actual" to be reference-equal to "expected":\n' + + '+ actual - expected\n\n' + + "+ [Arguments] {\n- {\n '0': 'a'\n }" + } + ); } -); -assert.throws( - () => { - const obj = { a: true }; - assert.notStrictEqual(obj, obj); - }, - { - code: 'ERR_ASSERTION', - name: 'AssertionError', - message: 'Expected "actual" not to be reference-equal to "expected":\n\n' + - '{\n a: true\n}\n' - } -); + assert.throws( + () => { throw new TypeError('foobar'); }, + { + message: /foo/, + name: /^TypeError$/ + } + ); -{ - let threw = false; - try { - // eslint-disable-next-line no-restricted-syntax - assert.deepStrictEqual(Array(100).fill(1), 'foobar'); - } catch (err) { - threw = true; - assert.match(inspect(err), /actual: \[Array],\n {2}expected: 'foobar',/); - } - assert(threw); -} - -assert.throws( - () => a.equal(1), - { code: 'ERR_MISSING_ARGS' } -); - -assert.throws( - () => a.deepEqual(/a/), - { code: 'ERR_MISSING_ARGS' } -); - -assert.throws( - () => a.notEqual(null), - { code: 'ERR_MISSING_ARGS' } -); - -assert.throws( - () => a.notDeepEqual('test'), - { code: 'ERR_MISSING_ARGS' } -); - -assert.throws( - () => a.strictEqual({}), - { code: 'ERR_MISSING_ARGS' } -); - -assert.throws( - () => a.deepStrictEqual(Symbol()), - { code: 'ERR_MISSING_ARGS' } -); - -assert.throws( - () => a.notStrictEqual(5n), // eslint-disable-line no-restricted-syntax - { code: 'ERR_MISSING_ARGS' } -); - -assert.throws( - () => a.notDeepStrictEqual(undefined), - { code: 'ERR_MISSING_ARGS' } -); - -assert.throws( - () => a.strictEqual(), - { code: 'ERR_MISSING_ARGS' } -); - -assert.throws( - () => a.deepStrictEqual(), - { code: 'ERR_MISSING_ARGS' } -); - -// Verify that `stackStartFunction` works as alternative to `stackStartFn`. -{ - (function hidden() { - const err = new assert.AssertionError({ - actual: 'foo', - operator: 'strictEqual', - stackStartFunction: hidden - }); - const err2 = new assert.AssertionError({ - actual: 'foo', - operator: 'strictEqual', - stackStartFn: hidden - }); - assert(!err.stack.includes('hidden')); - assert(!err2.stack.includes('hidden')); - })(); -} + assert.throws( + () => assert.throws( + () => { throw new TypeError('foobar'); }, + { + message: /fooa/, + name: /^TypeError$/ + } + ), + { + message: `${start}\n${actExp}\n\n` + + ' Comparison {\n' + + "+ message: 'foobar',\n" + + '- message: /fooa/,\n' + + " name: 'TypeError'\n" + + ' }' + } + ); -assert.throws( - () => assert.throws(() => { throw Symbol('foo'); }, RangeError), { - message: 'The error is expected to be an instance of "RangeError". ' + - 'Received "Symbol(foo)"' - } -); + let actual = null; + const expected = { message: 'foo' }; + assert.throws( + () => assert.throws( + () => { throw actual; }, + expected + ), + { + operator: 'throws', + actual, + expected, + generatedMessage: true, + message: `${start}\n${actExp}\n\n` + + '+ null\n' + + '- {\n' + + "- message: 'foo'\n" + + '- }' + } + ); -assert.throws( - // eslint-disable-next-line no-throw-literal - () => assert.throws(() => { throw [1, 2]; }, RangeError), - { - message: 'The error is expected to be an instance of "RangeError". ' + - 'Received "[Array]"' + actual = 'foobar'; + const message = 'message'; + assert.throws( + () => assert.throws( + () => { throw actual; }, + { message: 'foobar' }, + message + ), + { + actual, + message, + operator: 'throws', + generatedMessage: false + } + ); } -); -{ - const err = new TypeError('foo'); - const validate = (() => () => ({ a: true, b: [ 1, 2, 3 ] }))(); + // Indicate where the strings diverge. assert.throws( - () => assert.throws(() => { throw err; }, validate), + () => assert.strictEqual('test test', 'test foobar'), { - message: 'The validation function is expected to ' + - `return "true". Received ${inspect(validate())}\n\nCaught ` + - `error:\n\n${err}`, code: 'ERR_ASSERTION', - actual: err, - expected: validate, name: 'AssertionError', - operator: 'throws', + message: strictEqualMessageStart + + '+ actual - expected\n\n' + + "+ 'test test'\n" + + "- 'test foobar'\n" + + ' ^' } ); -} - -assert.throws( - () => { - const script = new vm.Script('new RangeError("foobar");'); - const context = vm.createContext(); - const err = script.runInContext(context); - assert.throws(() => { throw err; }, RangeError); - }, - { - message: 'The error is expected to be an instance of "RangeError". ' + - 'Received an error with identical name but a different ' + - 'prototype.\n\nError message:\n\nfoobar' - } -); -// Multiple assert.match() tests. -{ + // Check for reference-equal objects in `notStrictEqual()` assert.throws( - () => assert.match(/abc/, 'string'), + () => { + const obj = {}; + assert.notStrictEqual(obj, obj); + }, { - code: 'ERR_INVALID_ARG_TYPE', - message: 'The "regexp" argument must be an instance of RegExp. ' + - "Received type string ('string')" + code: 'ERR_ASSERTION', + name: 'AssertionError', + message: 'Expected "actual" not to be reference-equal to "expected": {}' } ); + assert.throws( - () => assert.match('string', /abc/), + () => { + const obj = { a: true }; + assert.notStrictEqual(obj, obj); + }, { - actual: 'string', - expected: /abc/, - operator: 'match', - message: 'The input did not match the regular expression /abc/. ' + - "Input:\n\n'string'\n", - generatedMessage: true + code: 'ERR_ASSERTION', + name: 'AssertionError', + message: 'Expected "actual" not to be reference-equal to "expected":\n\n' + + '{\n a: true\n}\n' } ); - assert.throws( - () => assert.match('string', /abc/, 'foobar'), - { - actual: 'string', - expected: /abc/, - operator: 'match', - message: 'foobar', - generatedMessage: false + + { + let threw = false; + try { + assert.deepStrictEqual(Array(100).fill(1), 'foobar'); + } catch (err) { + threw = true; + assert.match(inspect(err), /actual: \[Array],\n {2}expected: 'foobar',/); } + assert(threw); + } + + assert.throws( + () => assert.equal(1), + { code: 'ERR_MISSING_ARGS' } + ); + + assert.throws( + () => assert.deepEqual(/a/), + { code: 'ERR_MISSING_ARGS' } ); - const errorMessage = new RangeError('foobar'); + assert.throws( - () => assert.match('string', /abc/, errorMessage), - errorMessage + () => assert.notEqual(null), + { code: 'ERR_MISSING_ARGS' } ); + assert.throws( - () => assert.match({ abc: 123 }, /abc/), - { - actual: { abc: 123 }, - expected: /abc/, - operator: 'match', - message: 'The "string" argument must be of type string. ' + - 'Received type object ({ abc: 123 })', - generatedMessage: true - } + () => assert.notDeepEqual('test'), + { code: 'ERR_MISSING_ARGS' } ); - assert.match('I will pass', /pass$/); -} -// Multiple assert.doesNotMatch() tests. -{ assert.throws( - () => assert.doesNotMatch(/abc/, 'string'), - { - code: 'ERR_INVALID_ARG_TYPE', - message: 'The "regexp" argument must be an instance of RegExp. ' + - "Received type string ('string')" - } + () => assert.strictEqual({}), + { code: 'ERR_MISSING_ARGS' } ); + assert.throws( - () => assert.doesNotMatch('string', /string/), - { - actual: 'string', - expected: /string/, - operator: 'doesNotMatch', - message: 'The input was expected to not match the regular expression ' + - "/string/. Input:\n\n'string'\n", - generatedMessage: true - } + () => assert.deepStrictEqual(Symbol()), + { code: 'ERR_MISSING_ARGS' } + ); + + assert.throws( + () => assert.notStrictEqual(5n), + { code: 'ERR_MISSING_ARGS' } ); + + assert.throws( + () => assert.notDeepStrictEqual(undefined), + { code: 'ERR_MISSING_ARGS' } + ); + assert.throws( - () => assert.doesNotMatch('string', /string/, 'foobar'), + () => assert.strictEqual(), + { code: 'ERR_MISSING_ARGS' } + ); + + assert.throws( + () => assert.deepStrictEqual(), + { code: 'ERR_MISSING_ARGS' } + ); + + // Verify that `stackStartFunction` works as alternative to `stackStartFn`. + { + (function hidden() { + const err = new assert.AssertionError({ + actual: 'foo', + operator: 'strictEqual', + stackStartFunction: hidden + }); + const err2 = new assert.AssertionError({ + actual: 'foo', + operator: 'strictEqual', + stackStartFn: hidden + }); + assert(!err.stack.includes('hidden')); + assert(!err2.stack.includes('hidden')); + })(); + } + + assert.throws( + () => assert.throws(() => { throw Symbol('foo'); }, RangeError), { - actual: 'string', - expected: /string/, - operator: 'doesNotMatch', - message: 'foobar', - generatedMessage: false + message: 'The error is expected to be an instance of "RangeError". ' + + 'Received "Symbol(foo)"' } ); - const errorMessage = new RangeError('foobar'); + assert.throws( - () => assert.doesNotMatch('string', /string/, errorMessage), - errorMessage + // eslint-disable-next-line no-throw-literal + () => assert.throws(() => { throw [1, 2]; }, RangeError), + { + message: 'The error is expected to be an instance of "RangeError". ' + + 'Received "[Array]"' + } ); + + { + const err = new TypeError('foo'); + const validate = (() => () => ({ a: true, b: [ 1, 2, 3 ] }))(); + assert.throws( + () => assert.throws(() => { throw err; }, validate), + { + message: 'The validation function is expected to ' + + `return "true". Received ${inspect(validate())}\n\nCaught ` + + `error:\n\n${err}`, + code: 'ERR_ASSERTION', + actual: err, + expected: validate, + name: 'AssertionError', + operator: 'throws', + } + ); + } + assert.throws( - () => assert.doesNotMatch({ abc: 123 }, /abc/), + () => { + const script = new vm.Script('new RangeError("foobar");'); + const context = vm.createContext(); + const err = script.runInContext(context); + assert.throws(() => { throw err; }, RangeError); + }, { - actual: { abc: 123 }, - expected: /abc/, - operator: 'doesNotMatch', - message: 'The "string" argument must be of type string. ' + - 'Received type object ({ abc: 123 })', - generatedMessage: true + message: 'The error is expected to be an instance of "RangeError". ' + + 'Received an error with identical name but a different ' + + 'prototype.\n\nError message:\n\nfoobar' } ); - assert.doesNotMatch('I will pass', /different$/); -} -{ - const tempColor = inspect.defaultOptions.colors; - assert.throws(() => { - inspect.defaultOptions.colors = true; - // Guarantee the position indicator is placed correctly. - assert.strictEqual(111554n, 11111115); - }, (err) => { - assert.strictEqual(inspect(err).split('\n')[5], ' ^'); - inspect.defaultOptions.colors = tempColor; - return true; - }); -} + // Multiple assert.match() tests. + { + assert.throws( + () => assert.match(/abc/, 'string'), + { + code: 'ERR_INVALID_ARG_TYPE', + message: 'The "regexp" argument must be an instance of RegExp. ' + + "Received type string ('string')" + } + ); + assert.throws( + () => assert.match('string', /abc/), + { + actual: 'string', + expected: /abc/, + operator: 'match', + message: 'The input did not match the regular expression /abc/. ' + + "Input:\n\n'string'\n", + generatedMessage: true + } + ); + assert.throws( + () => assert.match('string', /abc/, 'foobar'), + { + actual: 'string', + expected: /abc/, + operator: 'match', + message: 'foobar', + generatedMessage: false + } + ); + const errorMessage = new RangeError('foobar'); + assert.throws( + () => assert.match('string', /abc/, errorMessage), + errorMessage + ); + assert.throws( + () => assert.match({ abc: 123 }, /abc/), + { + actual: { abc: 123 }, + expected: /abc/, + operator: 'match', + message: 'The "string" argument must be of type string. ' + + 'Received type object ({ abc: 123 })', + generatedMessage: true + } + ); + assert.match('I will pass', /pass$/); + } + + // Multiple assert.doesNotMatch() tests. + { + assert.throws( + () => assert.doesNotMatch(/abc/, 'string'), + { + code: 'ERR_INVALID_ARG_TYPE', + message: 'The "regexp" argument must be an instance of RegExp. ' + + "Received type string ('string')" + } + ); + assert.throws( + () => assert.doesNotMatch('string', /string/), + { + actual: 'string', + expected: /string/, + operator: 'doesNotMatch', + message: 'The input was expected to not match the regular expression ' + + "/string/. Input:\n\n'string'\n", + generatedMessage: true + } + ); + assert.throws( + () => assert.doesNotMatch('string', /string/, 'foobar'), + { + actual: 'string', + expected: /string/, + operator: 'doesNotMatch', + message: 'foobar', + generatedMessage: false + } + ); + const errorMessage = new RangeError('foobar'); + assert.throws( + () => assert.doesNotMatch('string', /string/, errorMessage), + errorMessage + ); + assert.throws( + () => assert.doesNotMatch({ abc: 123 }, /abc/), + { + actual: { abc: 123 }, + expected: /abc/, + operator: 'doesNotMatch', + message: 'The "string" argument must be of type string. ' + + 'Received type object ({ abc: 123 })', + generatedMessage: true + } + ); + assert.doesNotMatch('I will pass', /different$/); + } + + { + const tempColor = inspect.defaultOptions.colors; + assert.throws(() => { + inspect.defaultOptions.colors = true; + // Guarantee the position indicator is placed correctly. + assert.strictEqual(111554n, 11111115); + }, (err) => { + assert.strictEqual(inspect(err).split('\n')[5], ' ^'); + inspect.defaultOptions.colors = tempColor; + return true; + }); + } +}); + +test('assert/strict exists', () => { + assert.strictEqual(require('assert/strict'), assert.strict); +}); + +/* eslint-enable no-restricted-syntax */ +/* eslint-enable no-restricted-properties */ diff --git a/test/parallel/test-bootstrap-modules.js b/test/parallel/test-bootstrap-modules.js index 4b8a0de62e3..834471e3367 100644 --- a/test/parallel/test-bootstrap-modules.js +++ b/test/parallel/test-bootstrap-modules.js @@ -43,6 +43,7 @@ expected.beforePreExec = new Set([ 'NativeModule internal/assert', 'NativeModule internal/util/inspect', 'NativeModule internal/util/debuglog', + 'NativeModule internal/streams/utils', 'NativeModule internal/timers', 'NativeModule events', 'Internal Binding buffer', diff --git a/test/parallel/test-buffer-from.js b/test/parallel/test-buffer-from.js index 284c63e7d02..416a3b3a310 100644 --- a/test/parallel/test-buffer-from.js +++ b/test/parallel/test-buffer-from.js @@ -139,3 +139,6 @@ throws(() => { code: 'ERR_OUT_OF_RANGE', }) ); + +// Invalid encoding is allowed +Buffer.from('asd', 1); diff --git a/test/parallel/test-cli-node-options-docs.js b/test/parallel/test-cli-node-options-docs.js new file mode 100644 index 00000000000..03cab594ef0 --- /dev/null +++ b/test/parallel/test-cli-node-options-docs.js @@ -0,0 +1,131 @@ +'use strict'; +const common = require('../common'); +if (process.config.variables.node_without_node_options) + common.skip('missing NODE_OPTIONS support'); + +// Test options specified by env variable. + +const assert = require('assert'); +const fs = require('fs'); +const path = require('path'); + +const rootDir = path.resolve(__dirname, '..', '..'); +const cliMd = path.join(rootDir, 'doc', 'api', 'cli.md'); +const cliText = fs.readFileSync(cliMd, { encoding: 'utf8' }); + +const internalApiMd = path.join(rootDir, 'doc', 'contributing', 'internal-api.md'); +const internalApiText = fs.readFileSync(internalApiMd, { encoding: 'utf8' }); + +const nodeOptionsCC = fs.readFileSync(path.resolve(rootDir, 'src', 'node_options.cc'), 'utf8'); +const addOptionRE = /AddOption[\s\n\r]*\([\s\n\r]*"([^"]+)"(.*?)\);/gs; + +const nodeOptionsText = cliText.match(/(.*)/s)[1]; +const v8OptionsText = cliText.match(/(.*)/s)[1]; + +const manPage = path.join(rootDir, 'doc', 'nsolid.1'); +const manPageText = fs.readFileSync(manPage, { encoding: 'utf8' }); + +// Documented in /doc/api/deprecations.md +const deprecated = [ + '--debug', + '--debug-brk', +]; + + +const manPagesOptions = new Set(); + +for (const [, envVar] of manPageText.matchAll(/\.It Fl (-[a-zA-Z0-9._-]+)/g)) { + manPagesOptions.add(envVar); +} + +for (const [, envVar, config] of nodeOptionsCC.matchAll(addOptionRE)) { + let hasTrueAsDefaultValue = false; + let isInNodeOption = false; + let isV8Option = false; + let isNoOp = false; + + if (config.includes('NoOp{}')) { + isNoOp = true; + } + + if (config.includes('kAllowedInEnvvar')) { + isInNodeOption = true; + } + if (config.includes('kDisallowedInEnvvar')) { + isInNodeOption = false; + } + + if (config.includes('V8Option{}')) { + isV8Option = true; + } + + if (/^\s*true\s*$/.test(config.split(',').pop())) { + hasTrueAsDefaultValue = true; + } + + if ( + envVar.startsWith('[') || + deprecated.includes(envVar) || + isNoOp + ) { + // assert(!manPagesOptions.has(envVar.slice(1)), `Option ${envVar} should not be documented`) + manPagesOptions.delete(envVar.slice(1)); + continue; + } + + // Internal API options are documented in /doc/contributing/internal-api.md + if (new RegExp(`####.*\`${envVar}[[=\\s\\b\`]`).test(internalApiText) === true) { + manPagesOptions.delete(envVar.slice(1)); + continue; + } + + // CLI options + if (!isV8Option && !hasTrueAsDefaultValue) { + if (new RegExp(`###.*\`${envVar}[[=\\s\\b\`]`).test(cliText) === false) { + if (envVar !== '-vv') { + assert(false, `Should have option ${envVar} documented`); + } + } else { + manPagesOptions.delete(envVar.slice(1)); + } + } + + if (!hasTrueAsDefaultValue && new RegExp(`###.*\`--no${envVar.slice(1)}[[=\\s\\b\`]`).test(cliText) === true) { + assert(false, `Should not have option --no${envVar.slice(1)} documented`); + } + + if (!isV8Option && hasTrueAsDefaultValue) { + if (new RegExp(`###.*\`--no${envVar.slice(1)}[[=\\s\\b\`]`).test(cliText) === false) { + assert(false, `Should have option --no${envVar.slice(1)} documented`); + } else { + manPagesOptions.delete(`-no${envVar.slice(1)}`); + } + } + + // NODE_OPTIONS + if (isInNodeOption && !hasTrueAsDefaultValue && new RegExp(`\`${envVar}\``).test(nodeOptionsText) === false) { + assert(false, `Should have option ${envVar} in NODE_OPTIONS documented`); + } + + if (isInNodeOption && hasTrueAsDefaultValue && new RegExp(`\`--no${envVar.slice(1)}`).test(cliText) === false) { + assert(false, `Should have option --no${envVar.slice(1)} in NODE_OPTIONS documented`); + } + + if (!hasTrueAsDefaultValue && new RegExp(`\`--no${envVar.slice(1)}`).test(cliText) === true) { + assert(false, `Should not have option --no${envVar.slice(1)} in NODE_OPTIONS documented`); + } + + // V8 options + if (isV8Option) { + if (new RegExp(`###.*\`${envVar}[[=\\s\\b\`]`).test(v8OptionsText) === false) { + assert(false, `Should have option ${envVar} in V8 options documented`); + } else { + manPagesOptions.delete(envVar.slice(1)); + } + } +} + +// add alias handling +manPagesOptions.delete('-trace-events-enabled'); + +assert.strictEqual(manPagesOptions.size, 0, `Man page options not documented: ${[...manPagesOptions]}`); diff --git a/test/parallel/test-cli-node-options.js b/test/parallel/test-cli-node-options.js index 4d659a7b212..8d614e60717 100644 --- a/test/parallel/test-cli-node-options.js +++ b/test/parallel/test-cli-node-options.js @@ -69,6 +69,7 @@ if (common.hasCrypto) { // V8 options expect('--abort_on-uncaught_exception', 'B\n'); expect('--disallow-code-generation-from-strings', 'B\n'); +expect('--expose-gc', 'B\n'); expect('--huge-max-old-generation-size', 'B\n'); expect('--jitless', 'B\n'); expect('--max-old-space-size=0', 'B\n'); diff --git a/test/parallel/test-cli-permission-deny-fs.js b/test/parallel/test-cli-permission-deny-fs.js index 964a0ad0a0e..d38c4a61adb 100644 --- a/test/parallel/test-cli-permission-deny-fs.js +++ b/test/parallel/test-cli-permission-deny-fs.js @@ -27,7 +27,7 @@ const path = require('path'); } { - const tmpPath = path.resolve('/tmp/'); + const tmpPath = path.resolve('./tmp/'); const { status, stdout } = spawnSync( process.execPath, [ @@ -36,7 +36,7 @@ const path = require('path'); `console.log(process.permission.has("fs")); console.log(process.permission.has("fs.read")); console.log(process.permission.has("fs.write")); - console.log(process.permission.has("fs.write", "/tmp/"));`, + console.log(process.permission.has("fs.write", "./tmp/"));`, ] ); const [fs, fsIn, fsOut, fsOutAllowed] = stdout.toString().split('\n'); @@ -138,6 +138,9 @@ const path = require('path'); if (firstPath.startsWith('/etc')) { common.skip('/etc as firstPath'); } + if (firstPath.startsWith('/tmp')) { + common.skip('/tmp as firstPath'); + } const file = fixtures.path('permission', 'loader', 'index.js'); const { status, stderr } = spawnSync( process.execPath, diff --git a/test/parallel/test-cli-permission-multiple-allow.js b/test/parallel/test-cli-permission-multiple-allow.js index 68e9029b1dd..57ce1553530 100644 --- a/test/parallel/test-cli-permission-multiple-allow.js +++ b/test/parallel/test-cli-permission-multiple-allow.js @@ -7,8 +7,8 @@ const assert = require('assert'); const path = require('path'); { - const tmpPath = path.resolve('/tmp/'); - const otherPath = path.resolve('/other-path/'); + const tmpPath = path.resolve('./tmp/'); + const otherPath = path.resolve('./other-path/'); const { status, stdout } = spawnSync( process.execPath, [ @@ -17,8 +17,8 @@ const path = require('path'); `console.log(process.permission.has("fs")); console.log(process.permission.has("fs.read")); console.log(process.permission.has("fs.write")); - console.log(process.permission.has("fs.write", "/tmp/")); - console.log(process.permission.has("fs.write", "/other-path/"));`, + console.log(process.permission.has("fs.write", "./tmp/")); + console.log(process.permission.has("fs.write", "./other-path/"));`, ] ); const [fs, fsIn, fsOut, fsOutAllowed1, fsOutAllowed2] = stdout.toString().split('\n'); @@ -31,8 +31,8 @@ const path = require('path'); } { - const tmpPath = path.resolve('/tmp/'); - const pathWithComma = path.resolve('/other,path/'); + const tmpPath = path.resolve('./tmp/'); + const pathWithComma = path.resolve('./other,path/'); const { status, stdout } = spawnSync( process.execPath, [ @@ -45,8 +45,8 @@ const path = require('path'); `console.log(process.permission.has("fs")); console.log(process.permission.has("fs.read")); console.log(process.permission.has("fs.write")); - console.log(process.permission.has("fs.write", "/tmp/")); - console.log(process.permission.has("fs.write", "/other,path/"));`, + console.log(process.permission.has("fs.write", "./tmp/")); + console.log(process.permission.has("fs.write", "./other,path/"));`, ] ); const [fs, fsIn, fsOut, fsOutAllowed1, fsOutAllowed2] = stdout.toString().split('\n'); @@ -59,7 +59,7 @@ const path = require('path'); } { - const filePath = path.resolve('/tmp/file,with,comma.txt'); + const filePath = path.resolve('./tmp/file,with,comma.txt'); const { status, stdout, stderr } = spawnSync( process.execPath, [ @@ -70,7 +70,7 @@ const path = require('path'); `console.log(process.permission.has("fs")); console.log(process.permission.has("fs.read")); console.log(process.permission.has("fs.write")); - console.log(process.permission.has("fs.write", "/tmp/file,with,comma.txt"));`, + console.log(process.permission.has("fs.write", "./tmp/file,with,comma.txt"));`, ] ); const [fs, fsIn, fsOut, fsOutAllowed] = stdout.toString().split('\n'); diff --git a/test/parallel/test-common-gc.js b/test/parallel/test-common-gc.js index 96dc7e2e7b6..f7d73ccd042 100644 --- a/test/parallel/test-common-gc.js +++ b/test/parallel/test-common-gc.js @@ -1,7 +1,7 @@ 'use strict'; // Flags: --expose-gc const common = require('../common'); -const onGC = require('../common/ongc'); +const { onGC } = require('../common/gc'); { onGC({}, { ongc: common.mustCall() }); diff --git a/test/parallel/test-compression-decompression-stream.js b/test/parallel/test-compression-decompression-stream.js new file mode 100644 index 00000000000..1340c5c8bc4 --- /dev/null +++ b/test/parallel/test-compression-decompression-stream.js @@ -0,0 +1,41 @@ +// Flags: --no-warnings --expose-internals +'use strict'; + +require('../common'); + +const assert = require('node:assert'); +const { describe, it } = require('node:test'); +const { + CompressionStream, + DecompressionStream, +} = require('node:stream/web'); + +const { + customInspectSymbol: kInspect, +} = require('internal/util'); + +describe('DecompressionStream kInspect method', () => { + it('should return a predictable inspection string with DecompressionStream', () => { + const decompressionStream = new DecompressionStream('deflate'); + const depth = 1; + const options = {}; + const actual = decompressionStream[kInspect](depth, options); + + assert(actual.includes('DecompressionStream')); + assert(actual.includes('ReadableStream')); + assert(actual.includes('WritableStream')); + }); +}); + +describe('CompressionStream kInspect method', () => { + it('should return a predictable inspection string with CompressionStream', () => { + const compressionStream = new CompressionStream('deflate'); + const depth = 1; + const options = {}; + const actual = compressionStream[kInspect](depth, options); + + assert(actual.includes('CompressionStream')); + assert(actual.includes('ReadableStream')); + assert(actual.includes('WritableStream')); + }); +}); diff --git a/test/parallel/test-console-tty-colors.js b/test/parallel/test-console-tty-colors.js index 0eb51c72898..69951e27e3c 100644 --- a/test/parallel/test-console-tty-colors.js +++ b/test/parallel/test-console-tty-colors.js @@ -67,7 +67,7 @@ check(false, false, false); }); }, { - message: `The argument 'colorMode' is invalid. Received ${received}`, + message: `The argument 'colorMode' must be one of: 'auto', true, false. Received ${received}`, code: 'ERR_INVALID_ARG_VALUE' } ); diff --git a/test/parallel/test-crypto-sign-verify.js b/test/parallel/test-crypto-sign-verify.js index 56e5c16c286..9dd586a1a1f 100644 --- a/test/parallel/test-crypto-sign-verify.js +++ b/test/parallel/test-crypto-sign-verify.js @@ -793,3 +793,21 @@ assert.throws( }, { code: 'ERR_CRYPTO_UNSUPPORTED_OPERATION', message: 'Unsupported crypto operation' }); } } + +{ + // Dh, x25519 and x448 should not be used for signing/verifying + // https://github.com/nodejs/node/issues/53742 + for (const algo of ['dh', 'x25519', 'x448']) { + const privateKey = fixtures.readKey(`${algo}_private.pem`, 'ascii'); + const publicKey = fixtures.readKey(`${algo}_public.pem`, 'ascii'); + assert.throws(() => { + crypto.createSign('SHA256').update('Test123').sign(privateKey); + }, { code: 'ERR_OSSL_EVP_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE', message: /operation not supported for this keytype/ }); + assert.throws(() => { + crypto.createVerify('SHA256').update('Test123').verify(privateKey, 'sig'); + }, { code: 'ERR_OSSL_EVP_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE', message: /operation not supported for this keytype/ }); + assert.throws(() => { + crypto.createVerify('SHA256').update('Test123').verify(publicKey, 'sig'); + }, { code: 'ERR_OSSL_EVP_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE', message: /operation not supported for this keytype/ }); + } +} diff --git a/test/parallel/test-diagnostics-channel-net.js b/test/parallel/test-diagnostics-channel-net.js index 57dfc9a6fc2..dc84a5b4e1d 100644 --- a/test/parallel/test-diagnostics-channel-net.js +++ b/test/parallel/test-diagnostics-channel-net.js @@ -16,7 +16,7 @@ function testDiagnosticChannel(subscribers, test, after) { })); } -const testSuccessfullListen = common.mustCall(() => { +const testSuccessfulListen = common.mustCall(() => { let cb; const server = net.createServer(common.mustCall((socket) => { socket.destroy(); @@ -88,4 +88,4 @@ const testFailingListen = common.mustCall(() => { }); }); -testSuccessfullListen(); +testSuccessfulListen(); diff --git a/test/parallel/test-dns.js b/test/parallel/test-dns.js index 63e1b77ab13..a6b3e459aa0 100644 --- a/test/parallel/test-dns.js +++ b/test/parallel/test-dns.js @@ -361,11 +361,11 @@ assert.throws(() => { const cases = [ { method: 'resolveAny', answers: [ - { type: 'A', address: '1.2.3.4', ttl: 3333333333 }, - { type: 'AAAA', address: '::42', ttl: 3333333333 }, - { type: 'MX', priority: 42, exchange: 'foobar.com', ttl: 3333333333 }, - { type: 'NS', value: 'foobar.org', ttl: 3333333333 }, - { type: 'PTR', value: 'baz.org', ttl: 3333333333 }, + { type: 'A', address: '1.2.3.4', ttl: 0 }, + { type: 'AAAA', address: '::42', ttl: 0 }, + { type: 'MX', priority: 42, exchange: 'foobar.com', ttl: 0 }, + { type: 'NS', value: 'foobar.org', ttl: 0 }, + { type: 'PTR', value: 'baz.org', ttl: 0 }, { type: 'SOA', nsname: 'ns1.example.com', @@ -380,11 +380,11 @@ assert.throws(() => { { method: 'resolve4', options: { ttl: true }, - answers: [ { type: 'A', address: '1.2.3.4', ttl: 3333333333 } ] }, + answers: [ { type: 'A', address: '1.2.3.4', ttl: 0 } ] }, { method: 'resolve6', options: { ttl: true }, - answers: [ { type: 'AAAA', address: '::42', ttl: 3333333333 } ] }, + answers: [ { type: 'AAAA', address: '::42', ttl: 0 } ] }, { method: 'resolveSoa', answers: [ @@ -415,7 +415,7 @@ assert.throws(() => { (answer) => Object.assign({ domain }, answer) ), }), port, address); - }, cases.length)); + }, cases.length * 2 - 1)); server.bind(0, common.mustCall(() => { const address = server.address(); diff --git a/test/parallel/test-domain-async-id-map-leak.js b/test/parallel/test-domain-async-id-map-leak.js index 12e93ef3594..c3215cd7ce9 100644 --- a/test/parallel/test-domain-async-id-map-leak.js +++ b/test/parallel/test-domain-async-id-map-leak.js @@ -1,7 +1,8 @@ // Flags: --expose-gc 'use strict'; const common = require('../common'); -const onGC = require('../common/ongc'); +const { onGC } = require('../common/gc'); +const { gcUntil } = require('../common/gc'); const assert = require('assert'); const async_hooks = require('async_hooks'); const domain = require('domain'); @@ -40,7 +41,7 @@ d.run(() => { d = null; async function main() { - await common.gcUntil( + await gcUntil( 'All objects garbage collected', () => resourceGCed && domainGCed && emitterGCed); } diff --git a/test/parallel/test-esm-loader-hooks-inspect-brk.js b/test/parallel/test-esm-loader-hooks-inspect-brk.js new file mode 100644 index 00000000000..881bdfd2dd1 --- /dev/null +++ b/test/parallel/test-esm-loader-hooks-inspect-brk.js @@ -0,0 +1,34 @@ +// This tests esm loader's internal worker will not be blocked by --inspect-brk. +// Regression: https://github.com/nodejs/node/issues/53681 + +'use strict'; +const common = require('../common'); + +common.skipIfInspectorDisabled(); + +const assert = require('assert'); +const fixtures = require('../common/fixtures'); +const { NodeInstance } = require('../common/inspector-helper.js'); + +async function runIfWaitingForDebugger(session) { + const commands = [ + { 'method': 'Runtime.enable' }, + { 'method': 'Debugger.enable' }, + { 'method': 'Runtime.runIfWaitingForDebugger' }, + ]; + + await session.send(commands); + await session.waitForNotification('Debugger.paused'); +} + +async function runTest() { + const main = fixtures.path('es-module-loaders', 'register-loader.mjs'); + const child = new NodeInstance(['--inspect-brk=0'], '', main); + + const session = await child.connectInspectorSession(); + await runIfWaitingForDebugger(session); + await session.runToCompletion(); + assert.strictEqual((await child.expectShutdown()).exitCode, 0); +} + +runTest(); diff --git a/test/parallel/test-esm-loader-hooks-inspect-wait.js b/test/parallel/test-esm-loader-hooks-inspect-wait.js new file mode 100644 index 00000000000..cb3ae3d17b9 --- /dev/null +++ b/test/parallel/test-esm-loader-hooks-inspect-wait.js @@ -0,0 +1,30 @@ +// This tests esm loader's internal worker will not be blocked by --inspect-wait. +// Regression: https://github.com/nodejs/node/issues/53681 + +'use strict'; +const common = require('../common'); + +common.skipIfInspectorDisabled(); + +const assert = require('assert'); +const fixtures = require('../common/fixtures'); +const { NodeInstance } = require('../common/inspector-helper.js'); + +async function runTest() { + const main = fixtures.path('es-module-loaders', 'register-loader.mjs'); + const child = new NodeInstance(['--inspect-wait=0'], '', main); + + const session = await child.connectInspectorSession(); + await session.send({ method: 'NodeRuntime.enable' }); + await session.waitForNotification('NodeRuntime.waitingForDebugger'); + await session.send([ + { 'method': 'Runtime.enable' }, + { 'method': 'Debugger.enable' }, + { 'method': 'Runtime.runIfWaitingForDebugger' }, + ]); + await session.send({ method: 'NodeRuntime.disable' }); + await session.waitForDisconnect(); + assert.strictEqual((await child.expectShutdown()).exitCode, 0); +} + +runTest(); diff --git a/test/parallel/test-assert-strict-exists.js b/test/parallel/test-eventsource-disabled.js similarity index 54% rename from test/parallel/test-assert-strict-exists.js rename to test/parallel/test-eventsource-disabled.js index 50cd8a49a70..ade4f51d99e 100644 --- a/test/parallel/test-assert-strict-exists.js +++ b/test/parallel/test-eventsource-disabled.js @@ -3,4 +3,4 @@ require('../common'); const assert = require('assert'); -assert.strictEqual(require('assert/strict'), assert.strict); +assert.strictEqual(typeof EventSource, 'undefined'); diff --git a/test/parallel/test-eventsource.js b/test/parallel/test-eventsource.js new file mode 100644 index 00000000000..787195ca19d --- /dev/null +++ b/test/parallel/test-eventsource.js @@ -0,0 +1,7 @@ +// Flags: --experimental-eventsource +'use strict'; + +require('../common'); +const assert = require('assert'); + +assert.strictEqual(typeof EventSource, 'function'); diff --git a/test/parallel/test-fixed-queue.js b/test/parallel/test-fixed-queue.js index a50be1309a5..4f9b513aba8 100644 --- a/test/parallel/test-fixed-queue.js +++ b/test/parallel/test-fixed-queue.js @@ -32,3 +32,15 @@ const FixedQueue = require('internal/fixed_queue'); assert.strictEqual(queue.shift(), 'a'); assert(queue.isEmpty()); } + +{ + // FixedQueue must not be holey array + // Refs: https://github.com/nodejs/node/issues/54472 + const queue = new FixedQueue(); + for (let i = 0; i < queue.head.list.length; i++) { + assert(i in queue.head.list); + } + for (let i = 0; i < queue.tail.list.length; i++) { + assert(i in queue.tail.list); + } +} diff --git a/test/parallel/test-fs-existssync-false.js b/test/parallel/test-fs-existssync-false.js index e81e6c7a311..43e826cef56 100644 --- a/test/parallel/test-fs-existssync-false.js +++ b/test/parallel/test-fs-existssync-false.js @@ -18,15 +18,13 @@ tmpdir.refresh(); // Make a long path. for (let i = 0; i < 50; i++) { dir = `${dir}/1234567890`; - try { - fs.mkdirSync(dir, '0777'); - } catch (e) { - if (e.code !== 'EEXIST') { - throw e; - } - } } +fs.mkdirSync(dir, { + mode: '0777', + recursive: true, +}); + // Test if file exists synchronously assert(fs.existsSync(dir), 'Directory is not accessible'); diff --git a/test/parallel/test-fs-promises-watch.js b/test/parallel/test-fs-promises-watch.js index 2d417fd2886..692ed33dbcd 100644 --- a/test/parallel/test-fs-promises-watch.js +++ b/test/parallel/test-fs-promises-watch.js @@ -8,6 +8,7 @@ const { watch } = require('fs/promises'); const fs = require('fs'); const assert = require('assert'); const { join } = require('path'); +const { setTimeout } = require('timers/promises'); const tmpdir = require('../common/tmpdir'); class WatchTestCase { @@ -49,6 +50,12 @@ for (const testCase of kCases) { let interval; async function test() { + if (common.isMacOS) { + // On macOS delay watcher start to avoid leaking previous events. + // Refs: https://github.com/libuv/libuv/pull/4503 + await setTimeout(common.platformTimeout(100)); + } + const watcher = watch(testCase[testCase.field]); for await (const { eventType, filename } of watcher) { clearInterval(interval); diff --git a/test/parallel/test-fs-watch-recursive-add-file-to-new-folder.js b/test/parallel/test-fs-watch-recursive-add-file-to-new-folder.js index 2f91c968f78..32a397821b8 100644 --- a/test/parallel/test-fs-watch-recursive-add-file-to-new-folder.js +++ b/test/parallel/test-fs-watch-recursive-add-file-to-new-folder.js @@ -31,24 +31,34 @@ const filePath = path.join(testDirectory, 'folder-3'); const childrenFile = 'file-4.txt'; const childrenAbsolutePath = path.join(filePath, childrenFile); const childrenRelativePath = path.join(path.basename(filePath), childrenFile); - -const watcher = fs.watch(testDirectory, { recursive: true }); let watcherClosed = false; -watcher.on('change', function(event, filename) { - assert.strictEqual(event, 'rename'); - assert.ok(filename === path.basename(filePath) || filename === childrenRelativePath); - - if (filename === childrenRelativePath) { - watcher.close(); - watcherClosed = true; - } -}); -// Do the write with a delay to ensure that the OS is ready to notify us. -setTimeout(() => { - fs.mkdirSync(filePath); - fs.writeFileSync(childrenAbsolutePath, 'world'); -}, common.platformTimeout(200)); +function doWatch() { + const watcher = fs.watch(testDirectory, { recursive: true }); + watcher.on('change', function(event, filename) { + assert.strictEqual(event, 'rename'); + assert.ok(filename === path.basename(filePath) || filename === childrenRelativePath); + + if (filename === childrenRelativePath) { + watcher.close(); + watcherClosed = true; + } + }); + + // Do the write with a delay to ensure that the OS is ready to notify us. + setTimeout(() => { + fs.mkdirSync(filePath); + fs.writeFileSync(childrenAbsolutePath, 'world'); + }, common.platformTimeout(200)); +} + +if (common.isMacOS) { + // On macOS delay watcher start to avoid leaking previous events. + // Refs: https://github.com/libuv/libuv/pull/4503 + setTimeout(doWatch, common.platformTimeout(100)); +} else { + doWatch(); +} process.once('exit', function() { assert(watcherClosed, 'watcher Object was not closed'); diff --git a/test/parallel/test-fs-watch-recursive-symlink.js b/test/parallel/test-fs-watch-recursive-symlink.js index 602ec58eab0..37f71f56f8d 100644 --- a/test/parallel/test-fs-watch-recursive-symlink.js +++ b/test/parallel/test-fs-watch-recursive-symlink.js @@ -35,6 +35,11 @@ tmpdir.refresh(); const symlinkFolder = path.join(rootDirectory, 'symlink-folder'); fs.symlinkSync(rootDirectory, symlinkFolder); + if (common.isMacOS) { + // On macOS delay watcher start to avoid leaking previous events. + // Refs: https://github.com/libuv/libuv/pull/4503 + await setTimeout(common.platformTimeout(100)); + } const watcher = fs.watch(rootDirectory, { recursive: true }); let watcherClosed = false; @@ -74,6 +79,12 @@ tmpdir.refresh(); const forbiddenFile = path.join(subDirectory, 'forbidden.txt'); const acceptableFile = path.join(trackingSubDirectory, 'acceptable.txt'); + if (common.isMacOS) { + // On macOS delay watcher start to avoid leaking previous events. + // Refs: https://github.com/libuv/libuv/pull/4503 + await setTimeout(common.platformTimeout(100)); + } + const watcher = fs.watch(trackingSubDirectory, { recursive: true }); let watcherClosed = false; watcher.on('change', function(event, filename) { diff --git a/test/parallel/test-fs-watch-recursive-sync-write.js b/test/parallel/test-fs-watch-recursive-sync-write.js index ecc380d190e..dd7a64e1f00 100644 --- a/test/parallel/test-fs-watch-recursive-sync-write.js +++ b/test/parallel/test-fs-watch-recursive-sync-write.js @@ -25,14 +25,24 @@ const keepalive = setTimeout(() => { throw new Error('timed out'); }, common.platformTimeout(30_000)); -const watcher = watch(tmpDir, { recursive: true }, common.mustCall((eventType, _filename) => { - clearTimeout(keepalive); - watcher.close(); - assert.strictEqual(eventType, 'rename'); - assert.strictEqual(join(tmpDir, _filename), filename); -})); - -// Do the write with a delay to ensure that the OS is ready to notify us. -setTimeout(() => { - writeFileSync(filename, 'foobar2'); -}, common.platformTimeout(200)); +function doWatch() { + const watcher = watch(tmpDir, { recursive: true }, common.mustCall((eventType, _filename) => { + clearTimeout(keepalive); + watcher.close(); + assert.strictEqual(eventType, 'rename'); + assert.strictEqual(join(tmpDir, _filename), filename); + })); + + // Do the write with a delay to ensure that the OS is ready to notify us. + setTimeout(() => { + writeFileSync(filename, 'foobar2'); + }, common.platformTimeout(200)); +} + +if (common.isMacOS) { + // On macOS delay watcher start to avoid leaking previous events. + // Refs: https://github.com/libuv/libuv/pull/4503 + setTimeout(doWatch, common.platformTimeout(100)); +} else { + doWatch(); +} diff --git a/test/parallel/test-fs-watch.js b/test/parallel/test-fs-watch.js index a494b9f8df6..5194e04fce1 100644 --- a/test/parallel/test-fs-watch.js +++ b/test/parallel/test-fs-watch.js @@ -41,13 +41,7 @@ const cases = [ const tmpdir = require('../common/tmpdir'); tmpdir.refresh(); -for (const testCase of cases) { - if (testCase.shouldSkip) continue; - fs.mkdirSync(testCase.dirPath); - // Long content so it's actually flushed. - const content1 = Date.now() + testCase.fileName.toLowerCase().repeat(1e4); - fs.writeFileSync(testCase.filePath, content1); - +function doWatchTest(testCase) { let interval; const pathToWatch = testCase[testCase.field]; const watcher = fs.watch(pathToWatch); @@ -87,6 +81,23 @@ for (const testCase of cases) { }, 100); } +for (const testCase of cases) { + if (testCase.shouldSkip) continue; + fs.mkdirSync(testCase.dirPath); + // Long content so it's actually flushed. + const content1 = Date.now() + testCase.fileName.toLowerCase().repeat(1e4); + fs.writeFileSync(testCase.filePath, content1); + if (common.isMacOS) { + // On macOS delay watcher start to avoid leaking previous events. + // Refs: https://github.com/libuv/libuv/pull/4503 + setTimeout(() => { + doWatchTest(testCase); + }, common.platformTimeout(100)); + } else { + doWatchTest(testCase); + } +} + [false, 1, {}, [], null, undefined].forEach((input) => { assert.throws( () => fs.watch(input, common.mustNotCall()), diff --git a/test/parallel/test-fs-watchfile.js b/test/parallel/test-fs-watchfile.js index 5519848e026..6a83f120f70 100644 --- a/test/parallel/test-fs-watchfile.js +++ b/test/parallel/test-fs-watchfile.js @@ -86,10 +86,7 @@ watcher.on('stop', common.mustCall()); // Omitting AIX. It works but not reliably. if (common.isLinux || common.isMacOS || common.isWindows) { const dir = tmpdir.resolve('watch'); - - fs.mkdir(dir, common.mustCall(function(err) { - if (err) assert.fail(err); - + function doWatch() { const handle = fs.watch(dir, common.mustCall(function(eventType, filename) { clearInterval(interval); handle.close(); @@ -101,5 +98,15 @@ if (common.isLinux || common.isMacOS || common.isWindows) { if (err) assert.fail(err); })); }, 1); + } + + fs.mkdir(dir, common.mustSucceed(() => { + if (common.isMacOS) { + // On macOS delay watcher start to avoid leaking previous events. + // Refs: https://github.com/libuv/libuv/pull/4503 + setTimeout(doWatch, common.platformTimeout(100)); + } else { + doWatch(); + } })); } diff --git a/test/parallel/test-gc-http-client-connaborted.js b/test/parallel/test-gc-http-client-connaborted.js index e9282653f2c..93ca8ee4de5 100644 --- a/test/parallel/test-gc-http-client-connaborted.js +++ b/test/parallel/test-gc-http-client-connaborted.js @@ -4,7 +4,7 @@ // but aborting every connection that comes in. const common = require('../common'); -const onGC = require('../common/ongc'); +const { onGC } = require('../common/gc'); const http = require('http'); const os = require('os'); diff --git a/test/parallel/test-gc-net-timeout.js b/test/parallel/test-gc-net-timeout.js index dfb2bbfd92a..c4f74b34b79 100644 --- a/test/parallel/test-gc-net-timeout.js +++ b/test/parallel/test-gc-net-timeout.js @@ -4,7 +4,7 @@ // but using a net server/client instead require('../common'); -const onGC = require('../common/ongc'); +const { onGC } = require('../common/gc'); const assert = require('assert'); const net = require('net'); const os = require('os'); diff --git a/test/parallel/test-gc-tls-external-memory.js b/test/parallel/test-gc-tls-external-memory.js index 752986019e0..dcf38e11f6c 100644 --- a/test/parallel/test-gc-tls-external-memory.js +++ b/test/parallel/test-gc-tls-external-memory.js @@ -9,7 +9,7 @@ if (!common.hasCrypto) common.skip('missing crypto'); const { duplexPair } = require('stream'); -const onGC = require('../common/ongc'); +const { onGC } = require('../common/gc'); const assert = require('assert'); const tls = require('tls'); diff --git a/test/parallel/test-http-keep-alive-timeout-race-condition.js b/test/parallel/test-http-keep-alive-timeout-race-condition.js new file mode 100644 index 00000000000..08fa84265ba --- /dev/null +++ b/test/parallel/test-http-keep-alive-timeout-race-condition.js @@ -0,0 +1,38 @@ +'use strict'; + +const common = require('../common'); +const http = require('http'); + +const makeRequest = (port, agent) => + new Promise((resolve, reject) => { + const req = http.get( + { path: '/', port, agent }, + (res) => { + res.resume(); + res.on('end', () => resolve()); + }, + ); + req.on('error', (e) => reject(e)); + req.end(); + }); + +const server = http.createServer( + { keepAliveTimeout: common.platformTimeout(2000), keepAlive: true }, + common.mustCall((req, res) => { + const body = 'hello world\n'; + res.writeHead(200, { 'Content-Length': body.length }); + res.write(body); + res.end(); + }, 2) +); + +const agent = new http.Agent({ maxSockets: 5, keepAlive: true }); + +server.listen(0, common.mustCall(async function() { + await makeRequest(this.address().port, agent); + // Block the event loop for 2 seconds + Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, 2000); + await makeRequest(this.address().port, agent); + server.close(); + agent.destroy(); +})); diff --git a/test/parallel/test-http-outgoing-end-cork.js b/test/parallel/test-http-outgoing-end-cork.js index 6a217238c44..db852bf96df 100644 --- a/test/parallel/test-http-outgoing-end-cork.js +++ b/test/parallel/test-http-outgoing-end-cork.js @@ -3,11 +3,11 @@ const common = require('../common'); const assert = require('assert'); const http = require('http'); -const REQ_TIMEOUT = 500; // Set max ms of request time before abort +const REQ_TIMEOUT = common.platformTimeout(500); // Set max ms of request time before abort // Set total allowed test timeout to avoid infinite loop // that will hang test suite -const TOTAL_TEST_TIMEOUT = 1000; +const TOTAL_TEST_TIMEOUT = common.platformTimeout(1000); // Placeholder for sockets handled, to make sure that we // will reach a socket re-use case. diff --git a/test/parallel/test-http-server-connections-checking-leak.js b/test/parallel/test-http-server-connections-checking-leak.js index e28cf117c65..282c9a569fb 100644 --- a/test/parallel/test-http-server-connections-checking-leak.js +++ b/test/parallel/test-http-server-connections-checking-leak.js @@ -5,7 +5,7 @@ // Check that creating a server without listening does not leak resources. require('../common'); -const onGC = require('../common/ongc'); +const { onGC } = require('../common/gc'); const Countdown = require('../common/countdown'); const http = require('http'); diff --git a/test/parallel/test-http-server-keepalive-req-gc.js b/test/parallel/test-http-server-keepalive-req-gc.js index 93310847d67..3bfb6c9600c 100644 --- a/test/parallel/test-http-server-keepalive-req-gc.js +++ b/test/parallel/test-http-server-keepalive-req-gc.js @@ -1,7 +1,7 @@ // Flags: --expose-gc 'use strict'; const common = require('../common'); -const onGC = require('../common/ongc'); +const { onGC } = require('../common/gc'); const { createServer } = require('http'); const { connect } = require('net'); diff --git a/test/parallel/test-http2-misbehaving-multiplex.js b/test/parallel/test-http2-misbehaving-multiplex.js index 0e057e1ed28..c605f1050dc 100644 --- a/test/parallel/test-http2-misbehaving-multiplex.js +++ b/test/parallel/test-http2-misbehaving-multiplex.js @@ -14,32 +14,27 @@ const h2test = require('../common/http2'); let client; const server = h2.createServer(); -let gotFirstStreamId1; server.on('stream', common.mustCall((stream) => { stream.respond(); - stream.end('ok'); - // Http2Server should be fast enough to respond to and close - // the first streams with ID 1 and ID 3 without errors. - - // Test for errors in 'close' event to ensure no errors on some streams. - stream.on('error', () => {}); - stream.on('close', (err) => { - if (stream.id === 1) { - if (gotFirstStreamId1) { - // We expect our outgoing frames to fail on Stream ID 1 the second time - // because a stream with ID 1 was already closed before. - common.expectsError({ - constructor: NghttpError, - code: 'ERR_HTTP2_ERROR', - message: 'Stream was already closed or invalid' - }); - return; - } - gotFirstStreamId1 = true; - } - assert.strictEqual(err, undefined); - }); + if (stream.id === 3) { + stream.on('close', () => { + // A second Stream ID 1 frame should fail. + // This will cause an error to occur because the client is + // attempting to reuse an already closed stream. This must + // cause the server session to be torn down. + client.write(id1.data); + // This Stream ID 5 frame will never make it to the server. + client.write(id5.data); + }); + stream.end('ok'); + } else { + stream.on('error', common.expectsError({ + code: 'ERR_HTTP2_ERROR', + constructor: NghttpError, + message: 'Stream was already closed or invalid' + })); + } // Stream ID 5 should never reach the server assert.notStrictEqual(stream.id, 5); @@ -69,16 +64,7 @@ server.listen(0, () => { // Stream ID 1 frame will make it OK. client.write(id1.data, () => { // Stream ID 3 frame will make it OK. - client.write(id3.data, () => { - // A second Stream ID 1 frame should fail. - // This will cause an error to occur because the client is - // attempting to reuse an already closed stream. This must - // cause the server session to be torn down. - client.write(id1.data, () => { - // This Stream ID 5 frame will never make it to the server - client.write(id5.data); - }); - }); + client.write(id3.data); }); }); }); diff --git a/test/parallel/test-http2-socket-close.js b/test/parallel/test-http2-socket-close.js index 02db77bcf84..d88c10ae18e 100644 --- a/test/parallel/test-http2-socket-close.js +++ b/test/parallel/test-http2-socket-close.js @@ -42,6 +42,7 @@ netServer.listen(0, common.mustCall(() => { rejectUnauthorized: false }); + proxyClient.on('error', () => {}); proxyClient.on('close', common.mustCall(() => { netServer.close(); })); @@ -51,6 +52,7 @@ netServer.listen(0, common.mustCall(() => { ':path': '/' }); + req.on('error', () => {}); req.on('response', common.mustCall((response) => { assert.strictEqual(response[':status'], 200); diff --git a/test/parallel/test-https-argument-of-creating.js b/test/parallel/test-https-argument-of-creating.js index fe6ca9f59a6..e0d089f8111 100644 --- a/test/parallel/test-https-argument-of-creating.js +++ b/test/parallel/test-https-argument-of-creating.js @@ -45,3 +45,14 @@ const dftProtocol = {}; 0); assert.strictEqual(server.listeners('request').length, 0); } + + +// Validate that `createServer` only uses defaults when appropriate +{ + const ALPNCallback = () => {}; + const server = https.createServer({ + ALPNCallback, + }); + assert.strictEqual(server.ALPNProtocols, undefined); + assert.strictEqual(server.ALPNCallback, ALPNCallback); +} diff --git a/test/parallel/test-https-server-connections-checking-leak.js b/test/parallel/test-https-server-connections-checking-leak.js index 3e7c45e4660..e920c8e4037 100644 --- a/test/parallel/test-https-server-connections-checking-leak.js +++ b/test/parallel/test-https-server-connections-checking-leak.js @@ -10,7 +10,7 @@ if (!common.hasCrypto) { common.skip('missing crypto'); } -const onGC = require('../common/ongc'); +const { onGC } = require('../common/gc'); const Countdown = require('../common/countdown'); const https = require('https'); diff --git a/test/parallel/test-inspector-async-stack-traces-promise-then.js b/test/parallel/test-inspector-async-stack-traces-promise-then.js index 1fdd71f0a82..188f38b8ef4 100644 --- a/test/parallel/test-inspector-async-stack-traces-promise-then.js +++ b/test/parallel/test-inspector-async-stack-traces-promise-then.js @@ -31,7 +31,7 @@ async function runTests() { 'params': { 'patterns': [] } }, { 'method': 'Runtime.runIfWaitingForDebugger' }, ]); - session.send({ method: 'NodeRuntime.disable' }); + await session.send({ method: 'NodeRuntime.disable' }); await session.waitForBreakOnLine(0, '[eval]'); await session.send({ 'method': 'Debugger.resume' }); diff --git a/test/parallel/test-inspector-emit-protocol-event.js b/test/parallel/test-inspector-emit-protocol-event.js new file mode 100644 index 00000000000..eda95d34e57 --- /dev/null +++ b/test/parallel/test-inspector-emit-protocol-event.js @@ -0,0 +1,121 @@ +// Flags: --inspect=0 --experimental-network-inspection +'use strict'; +const common = require('../common'); + +common.skipIfInspectorDisabled(); + +const inspector = require('node:inspector/promises'); +const assert = require('node:assert'); + +const EXPECTED_EVENTS = { + Network: [ + { + name: 'requestWillBeSent', + params: { + requestId: 'request-id-1', + request: { + url: 'https://nodejs.org/en', + method: 'GET', + }, + timestamp: 1000, + wallTime: 1000, + }, + expected: { + requestId: 'request-id-1', + request: { + url: 'https://nodejs.org/en', + method: 'GET', + headers: {} // Headers should be an empty object if not provided. + }, + timestamp: 1000, + wallTime: 1000, + } + }, + { + name: 'responseReceived', + params: { + requestId: 'request-id-1', + timestamp: 1000, + type: 'Other', + response: { + url: 'https://nodejs.org/en', + status: 200, + headers: { host: 'nodejs.org' } + } + }, + expected: { + requestId: 'request-id-1', + timestamp: 1000, + type: 'Other', + response: { + url: 'https://nodejs.org/en', + status: 200, + statusText: '', // Status text should be an empty string if not provided. + headers: { host: 'nodejs.org' } + } + } + }, + { + name: 'loadingFinished', + params: { + requestId: 'request-id-1', + timestamp: 1000, + } + }, + { + name: 'loadingFailed', + params: { + requestId: 'request-id-1', + timestamp: 1000, + type: 'Document', + errorText: 'Failed to load resource' + } + }, + ] +}; + +// Check that all domains and events are present in the inspector object. +for (const [domain, events] of Object.entries(EXPECTED_EVENTS)) { + if (!(domain in inspector)) { + assert.fail(`Expected domain ${domain} to be present in inspector`); + } + const actualEventNames = Object.keys(inspector[domain]); + const expectedEventNames = events.map((event) => event.name); + assert.deepStrictEqual(actualEventNames, expectedEventNames, `Expected ${domain} to have events ${expectedEventNames}, but got ${actualEventNames}`); +} + +// Check that all events throw when called with a non-object argument. +for (const [domain, events] of Object.entries(EXPECTED_EVENTS)) { + for (const event of events) { + assert.throws(() => inspector[domain][event.name]('params'), { + name: 'TypeError', + code: 'ERR_INVALID_ARG_TYPE', + message: 'The "params" argument must be of type object. Received type string (\'params\')' + }); + } +} + +const runAsyncTest = async () => { + const session = new inspector.Session(); + session.connect(); + + // Check that all events emit the expected parameters. + await session.post('Network.enable'); + for (const [domain, events] of Object.entries(EXPECTED_EVENTS)) { + for (const event of events) { + session.on(`${domain}.${event.name}`, common.mustCall(({ params }) => { + assert.deepStrictEqual(params, event.expected ?? event.params); + })); + inspector[domain][event.name](event.params); + } + } + + // Check tht no events are emitted after disabling the domain. + await session.post('Network.disable'); + session.on('Network.requestWillBeSent', common.mustNotCall()); + inspector.Network.requestWillBeSent({}); +}; + +runAsyncTest().then(common.mustCall()).catch((e) => { + assert.fail(e); +}); diff --git a/test/parallel/test-inspector-network-domain.js b/test/parallel/test-inspector-network-domain.js new file mode 100644 index 00000000000..d2a56dca95a --- /dev/null +++ b/test/parallel/test-inspector-network-domain.js @@ -0,0 +1,206 @@ +// Flags: --inspect=0 --experimental-network-inspection +'use strict'; +const common = require('../common'); + +common.skipIfInspectorDisabled(); + +const assert = require('node:assert'); +const { addresses } = require('../common/internet'); +const fixtures = require('../common/fixtures'); +const http = require('node:http'); +const https = require('node:https'); +const inspector = require('node:inspector/promises'); + +const session = new inspector.Session(); +session.connect(); + +const requestHeaders = { + 'accept-language': 'en-US', + 'Cookie': ['k1=v1', 'k2=v2'], + 'age': 1000, + 'x-header1': ['value1', 'value2'] +}; + +const setResponseHeaders = (res) => { + res.setHeader('server', 'node'); + res.setHeader('etag', 12345); + res.setHeader('Set-Cookie', ['key1=value1', 'key2=value2']); + res.setHeader('x-header2', ['value1', 'value2']); +}; + +const httpServer = http.createServer((req, res) => { + const path = req.url; + switch (path) { + case '/hello-world': + setResponseHeaders(res); + res.writeHead(200); + res.end('hello world\n'); + break; + default: + assert(false, `Unexpected path: ${path}`); + } +}); + +const httpsServer = https.createServer({ + key: fixtures.readKey('agent1-key.pem'), + cert: fixtures.readKey('agent1-cert.pem') +}, (req, res) => { + const path = req.url; + switch (path) { + case '/hello-world': + setResponseHeaders(res); + res.writeHead(200); + res.end('hello world\n'); + break; + default: + assert(false, `Unexpected path: ${path}`); + } +}); + +const terminate = () => { + session.disconnect(); + httpServer.close(); + httpsServer.close(); + inspector.close(); +}; + +const testHttpGet = () => new Promise((resolve, reject) => { + session.on('Network.requestWillBeSent', common.mustCall(({ params }) => { + assert.ok(params.requestId.startsWith('node-network-event-')); + assert.strictEqual(params.request.url, 'http://127.0.0.1/hello-world'); + assert.strictEqual(params.request.method, 'GET'); + assert.strictEqual(typeof params.request.headers, 'object'); + assert.strictEqual(params.request.headers['accept-language'], 'en-US'); + assert.strictEqual(params.request.headers.cookie, 'k1=v1; k2=v2'); + assert.strictEqual(params.request.headers.age, '1000'); + assert.strictEqual(params.request.headers['x-header1'], 'value1, value2'); + assert.strictEqual(typeof params.timestamp, 'number'); + assert.strictEqual(typeof params.wallTime, 'number'); + })); + session.on('Network.responseReceived', common.mustCall(({ params }) => { + assert.ok(params.requestId.startsWith('node-network-event-')); + assert.strictEqual(typeof params.timestamp, 'number'); + assert.strictEqual(params.type, 'Other'); + assert.strictEqual(params.response.status, 200); + assert.strictEqual(params.response.statusText, 'OK'); + assert.strictEqual(params.response.url, 'http://127.0.0.1/hello-world'); + assert.strictEqual(typeof params.response.headers, 'object'); + assert.strictEqual(params.response.headers.server, 'node'); + assert.strictEqual(params.response.headers.etag, '12345'); + assert.strictEqual(params.response.headers['set-cookie'], 'key1=value1\nkey2=value2'); + assert.strictEqual(params.response.headers['x-header2'], 'value1, value2'); + })); + session.on('Network.loadingFinished', common.mustCall(({ params }) => { + assert.ok(params.requestId.startsWith('node-network-event-')); + assert.strictEqual(typeof params.timestamp, 'number'); + resolve(); + })); + + http.get({ + host: '127.0.0.1', + port: httpServer.address().port, + path: '/hello-world', + headers: requestHeaders + }, common.mustCall()); +}); + +const testHttpsGet = () => new Promise((resolve, reject) => { + session.on('Network.requestWillBeSent', common.mustCall(({ params }) => { + assert.ok(params.requestId.startsWith('node-network-event-')); + assert.strictEqual(params.request.url, 'https://127.0.0.1/hello-world'); + assert.strictEqual(params.request.method, 'GET'); + assert.strictEqual(typeof params.request.headers, 'object'); + assert.strictEqual(params.request.headers['accept-language'], 'en-US'); + assert.strictEqual(params.request.headers.cookie, 'k1=v1; k2=v2'); + assert.strictEqual(params.request.headers.age, '1000'); + assert.strictEqual(params.request.headers['x-header1'], 'value1, value2'); + assert.strictEqual(typeof params.timestamp, 'number'); + assert.strictEqual(typeof params.wallTime, 'number'); + })); + session.on('Network.responseReceived', common.mustCall(({ params }) => { + assert.ok(params.requestId.startsWith('node-network-event-')); + assert.strictEqual(typeof params.timestamp, 'number'); + assert.strictEqual(params.type, 'Other'); + assert.strictEqual(params.response.status, 200); + assert.strictEqual(params.response.statusText, 'OK'); + assert.strictEqual(params.response.url, 'https://127.0.0.1/hello-world'); + assert.strictEqual(typeof params.response.headers, 'object'); + assert.strictEqual(params.response.headers.server, 'node'); + assert.strictEqual(params.response.headers.etag, '12345'); + assert.strictEqual(params.response.headers['set-cookie'], 'key1=value1\nkey2=value2'); + assert.strictEqual(params.response.headers['x-header2'], 'value1, value2'); + })); + session.on('Network.loadingFinished', common.mustCall(({ params }) => { + assert.ok(params.requestId.startsWith('node-network-event-')); + assert.strictEqual(typeof params.timestamp, 'number'); + resolve(); + })); + + https.get({ + host: '127.0.0.1', + port: httpsServer.address().port, + path: '/hello-world', + rejectUnauthorized: false, + headers: requestHeaders, + }, common.mustCall()); +}); + +const testHttpError = () => new Promise((resolve, reject) => { + session.on('Network.requestWillBeSent', common.mustCall()); + session.on('Network.loadingFailed', common.mustCall(({ params }) => { + assert.ok(params.requestId.startsWith('node-network-event-')); + assert.strictEqual(typeof params.timestamp, 'number'); + assert.strictEqual(params.type, 'Other'); + assert.strictEqual(typeof params.errorText, 'string'); + resolve(); + })); + session.on('Network.responseReceived', common.mustNotCall()); + session.on('Network.loadingFinished', common.mustNotCall()); + + http.get({ + host: addresses.INVALID_HOST, + }, common.mustNotCall()).on('error', common.mustCall()); +}); + + +const testHttpsError = () => new Promise((resolve, reject) => { + session.on('Network.requestWillBeSent', common.mustCall()); + session.on('Network.loadingFailed', common.mustCall(({ params }) => { + assert.ok(params.requestId.startsWith('node-network-event-')); + assert.strictEqual(typeof params.timestamp, 'number'); + assert.strictEqual(params.type, 'Other'); + assert.strictEqual(typeof params.errorText, 'string'); + resolve(); + })); + session.on('Network.responseReceived', common.mustNotCall()); + session.on('Network.loadingFinished', common.mustNotCall()); + + https.get({ + host: addresses.INVALID_HOST, + }, common.mustNotCall()).on('error', common.mustCall()); +}); + +const testNetworkInspection = async () => { + await testHttpGet(); + session.removeAllListeners(); + await testHttpsGet(); + session.removeAllListeners(); + await testHttpError(); + session.removeAllListeners(); + await testHttpsError(); + session.removeAllListeners(); +}; + +httpServer.listen(0, () => { + httpsServer.listen(0, async () => { + try { + await session.post('Network.enable'); + await testNetworkInspection(); + await session.post('Network.disable'); + } catch (e) { + assert.fail(e); + } finally { + terminate(); + } + }); +}); diff --git a/test/parallel/test-internal-fs-syncwritestream.js b/test/parallel/test-internal-fs-syncwritestream.js index 93fbfbc9f4c..9f36102e894 100644 --- a/test/parallel/test-internal-fs-syncwritestream.js +++ b/test/parallel/test-internal-fs-syncwritestream.js @@ -66,6 +66,18 @@ const filename = tmpdir.resolve('sync-write-stream.txt'); assert.strictEqual(stream.fd, null); } +// Verify that the file is not closed when autoClose=false +{ + const fd = fs.openSync(filename, 'w'); + const stream = new SyncWriteStream(fd, { autoClose: false }); + + stream.on('close', common.mustCall()); + + assert.strictEqual(stream.destroy(), stream); + fs.fstatSync(fd); // Does not throw + fs.closeSync(fd); +} + // Verify that calling end() will also destroy the stream. { const fd = fs.openSync(filename, 'w'); diff --git a/test/parallel/test-internal-util-weakreference.js b/test/parallel/test-internal-util-weakreference.js index ef3c0943b1f..0ecef956a44 100644 --- a/test/parallel/test-internal-util-weakreference.js +++ b/test/parallel/test-internal-util-weakreference.js @@ -1,6 +1,7 @@ // Flags: --expose-internals --expose-gc 'use strict'; -const common = require('../common'); +require('../common'); +const { gcUntil } = require('../common/gc'); const assert = require('assert'); const { WeakReference } = require('internal/util'); @@ -10,7 +11,7 @@ assert.strictEqual(ref.get(), obj); async function main() { obj = null; - await common.gcUntil( + await gcUntil( 'Reference is garbage collected', () => ref.get() === undefined); } diff --git a/test/parallel/test-net-connect-memleak.js b/test/parallel/test-net-connect-memleak.js index 2f06e56e1f6..84f64374683 100644 --- a/test/parallel/test-net-connect-memleak.js +++ b/test/parallel/test-net-connect-memleak.js @@ -23,7 +23,7 @@ // Flags: --expose-gc const common = require('../common'); -const onGC = require('../common/ongc'); +const { onGC } = require('../common/gc'); const assert = require('assert'); const net = require('net'); diff --git a/test/parallel/test-path-relative.js b/test/parallel/test-path-relative.js index f6a9f5662a6..999ef93784b 100644 --- a/test/parallel/test-path-relative.js +++ b/test/parallel/test-path-relative.js @@ -32,6 +32,11 @@ const relativeTests = [ ['\\\\foo\\baz', '\\\\foo\\baz-quux', '..\\baz-quux'], ['C:\\baz', '\\\\foo\\bar\\baz', '\\\\foo\\bar\\baz'], ['\\\\foo\\bar\\baz', 'C:\\baz', 'C:\\baz'], + ['c:\\a\\İ', 'c:\\a\\İ\\test.txt', 'test.txt'], + ['c:\\İ\\a\\İ', 'c:\\İ\\b\\İ\\test.txt', '..\\..\\b\\İ\\test.txt'], + ['c:\\İ\\a\\i̇', 'c:\\İ\\b\\İ\\test.txt', '..\\..\\b\\İ\\test.txt'], + ['c:\\i̇\\a\\İ', 'c:\\İ\\b\\İ\\test.txt', '..\\..\\b\\İ\\test.txt'], + ['c:\\ß\\a\\ß', 'c:\\ß\\b\\ß\\test.txt', '..\\..\\b\\ß\\test.txt'], ], ], [ path.posix.relative, diff --git a/test/parallel/test-performance-nodetiming-uvmetricsinfo.js b/test/parallel/test-performance-nodetiming-uvmetricsinfo.js new file mode 100644 index 00000000000..3d32e0deb72 --- /dev/null +++ b/test/parallel/test-performance-nodetiming-uvmetricsinfo.js @@ -0,0 +1,20 @@ +'use strict'; + +const common = require('../common'); +common.skipIfWorker(); + +const { spawnSync } = require('node:child_process'); +const assert = require('node:assert'); +const fixtures = require('../common/fixtures'); + +const file = fixtures.path('test-nodetiming-uvmetricsinfo.js'); + +{ + const { status, stderr } = spawnSync( + process.execPath, + [ + file, + ], + ); + assert.strictEqual(status, 0, stderr.toString()); +} diff --git a/test/parallel/test-permission-has.js b/test/parallel/test-permission-has.js index f0fb582959f..3be45c5b2a4 100644 --- a/test/parallel/test-permission-has.js +++ b/test/parallel/test-permission-has.js @@ -21,3 +21,7 @@ const assert = require('assert'); message: 'The "reference" argument must be of type string. Received an instance of Object', })); } + +{ + assert.ok(!process.permission.has('FileSystemWrite', Buffer.from('reference'))); +} diff --git a/test/parallel/test-pipe-file-to-http.js b/test/parallel/test-pipe-file-to-http.js index 6c1244427d9..82bdbe6a832 100644 --- a/test/parallel/test-pipe-file-to-http.js +++ b/test/parallel/test-pipe-file-to-http.js @@ -32,11 +32,10 @@ const filename = tmpdir.resolve('big'); let count = 0; const server = http.createServer((req, res) => { - let timeoutId; assert.strictEqual(req.method, 'POST'); req.pause(); - setTimeout(() => { + const timeoutId = setTimeout(() => { req.resume(); }, 1000); diff --git a/test/parallel/test-primitive-timer-leak.js b/test/parallel/test-primitive-timer-leak.js index 45681af33d3..d590a0347b9 100644 --- a/test/parallel/test-primitive-timer-leak.js +++ b/test/parallel/test-primitive-timer-leak.js @@ -1,7 +1,7 @@ 'use strict'; // Flags: --expose-gc require('../common'); -const onGC = require('../common/ongc'); +const { onGC } = require('../common/gc'); // See https://github.com/nodejs/node/issues/53335 const poller = setInterval(() => { diff --git a/test/parallel/test-process-load-env-file.js b/test/parallel/test-process-load-env-file.js index 41e487b39b3..795b8773d95 100644 --- a/test/parallel/test-process-load-env-file.js +++ b/test/parallel/test-process-load-env-file.js @@ -8,7 +8,7 @@ const { join } = require('node:path'); const basicValidEnvFilePath = fixtures.path('dotenv/basic-valid.env'); const validEnvFilePath = fixtures.path('dotenv/valid.env'); -const missingEnvFile = fixtures.path('dotenv/non-existent-file.env'); +const missingEnvFile = fixtures.path('dir%20with unusual"chars \'åß∂ƒ©∆¬…`/non-existent-file.env'); describe('process.loadEnvFile()', () => { @@ -85,7 +85,11 @@ describe('process.loadEnvFile()', () => { assert.match(child.stderr, /code: 'ERR_ACCESS_DENIED'/); assert.match(child.stderr, /permission: 'FileSystemRead'/); if (!common.isWindows) { - assert(child.stderr.includes(`resource: '${JSON.stringify(missingEnvFile).replaceAll('"', '')}'`)); + const resource = /^\s+resource: (['"])(.+)\1$/m.exec(child.stderr); + assert(resource); + assert.strictEqual(resource[2], resource[1] === "'" ? + missingEnvFile.replaceAll("'", "\\'") : + JSON.stringify(missingEnvFile).slice(1, -1)); } assert.strictEqual(child.code, 1); }); diff --git a/test/parallel/test-repl.js b/test/parallel/test-repl.js index 44454127dcc..22d1c19f1d5 100644 --- a/test/parallel/test-repl.js +++ b/test/parallel/test-repl.js @@ -129,6 +129,17 @@ const strictModeTests = [ }, ]; +const possibleTokensAfterIdentifierWithLineBreak = [ + '(\n)', + '[\n0]', + '+\n1', '- \n1', '* \n1', '/ \n1', '% \n1', '** \n1', + '== \n1', '=== \n1', '!= \n1', '!== \n1', '< \n1', '> \n1', '<= \n1', '>= \n1', + '&& \n1', '|| \n1', '?? \n1', + '= \n1', '+= \n1', '-= \n1', '*= \n1', '/= \n1', '%= \n1', + ': \n', + '? \n1: 1', +]; + const errorTests = [ // Uncaught error throws and prints out { @@ -380,6 +391,16 @@ const errorTests = [ '(Press Ctrl+D to exit.)', ] }, + { + send: 'let npm = () => {};', + expect: 'undefined' + }, + ...possibleTokensAfterIdentifierWithLineBreak.map((token) => ( + { + send: `npm ${token}; undefined`, + expect: '... undefined' + } + )), { send: '(function() {\n\nreturn 1;\n})()', expect: '... ... ... 1' diff --git a/test/parallel/test-runner-assert.js b/test/parallel/test-runner-assert.js index 2af05c95414..51c6ee67ebe 100644 --- a/test/parallel/test-runner-assert.js +++ b/test/parallel/test-runner-assert.js @@ -24,3 +24,7 @@ test('only methods from node:assert are on t.assert', (t) => { 'throws', ]); }); + +test('t.assert.ok correctly parses the stacktrace', (t) => { + t.assert.throws(() => t.assert.ok(1 === 2), /t\.assert\.ok\(1 === 2\)/); +}); diff --git a/test/parallel/test-runner-mock-timers.js b/test/parallel/test-runner-mock-timers.js index 3e8d2d79ede..e2a86a52636 100644 --- a/test/parallel/test-runner-mock-timers.js +++ b/test/parallel/test-runner-mock-timers.js @@ -17,6 +17,14 @@ describe('Mock Timers Test Suite', () => { }); }); + it('should throw an error if data type of trying to enable a timer is not string', (t) => { + assert.throws(() => { + t.mock.timers.enable({ apis: [1] }); + }, { + code: 'ERR_INVALID_ARG_TYPE', + }); + }); + it('should throw an error if trying to enable a timer twice', (t) => { t.mock.timers.enable(); assert.throws(() => { diff --git a/test/parallel/test-runner-module-mocking.js b/test/parallel/test-runner-module-mocking.js new file mode 100644 index 00000000000..8e746fab416 --- /dev/null +++ b/test/parallel/test-runner-module-mocking.js @@ -0,0 +1,633 @@ +// Flags: --experimental-test-module-mocks --experimental-require-module +'use strict'; +const common = require('../common'); + +if (!common.isMainThread) { + common.skip('registering customization hooks in Workers does not work'); +} + +const fixtures = require('../common/fixtures'); +const assert = require('node:assert'); +const { relative } = require('node:path'); +const { test } = require('node:test'); +const { fileURLToPath, pathToFileURL } = require('node:url'); + +test('input validation', async (t) => { + await t.test('throws if specifier is not a string', (t) => { + assert.throws(() => { + t.mock.module(5); + }, { code: 'ERR_INVALID_ARG_TYPE' }); + }); + + await t.test('throws if options is not an object', (t) => { + assert.throws(() => { + t.mock.module(__filename, null); + }, { code: 'ERR_INVALID_ARG_TYPE' }); + }); + + await t.test('throws if cache is not a boolean', (t) => { + assert.throws(() => { + t.mock.module(__filename, { cache: 5 }); + }, { code: 'ERR_INVALID_ARG_TYPE' }); + }); + + await t.test('throws if namedExports is not an object', async (t) => { + assert.throws(() => { + t.mock.module(__filename, { + namedExports: null, + }); + }, { code: 'ERR_INVALID_ARG_TYPE' }); + }); +}); + +test('core module mocking with namedExports option', async (t) => { + await t.test('does not cache by default', async (t) => { + const original = require('readline'); + + assert.strictEqual(typeof original.cursorTo, 'function'); + assert.strictEqual(original.fn, undefined); + + t.mock.module('readline', { + namedExports: { fn() { return 42; } }, + }); + const mocked = require('readline'); + + assert.notStrictEqual(original, mocked); + assert.notStrictEqual(mocked, require('readline')); + assert.notStrictEqual(mocked, require('node:readline')); + assert.strictEqual(mocked.cursorTo, undefined); + assert.strictEqual(mocked.fn(), 42); + t.mock.reset(); + assert.strictEqual(original, require('readline')); + }); + + await t.test('explicitly enables caching', async (t) => { + const original = require('readline'); + + assert.strictEqual(typeof original.cursorTo, 'function'); + assert.strictEqual(original.fn, undefined); + + t.mock.module('readline', { + namedExports: { fn() { return 42; } }, + cache: true, + }); + const mocked = require('readline'); + + assert.notStrictEqual(original, mocked); + assert.strictEqual(mocked, require('readline')); + assert.strictEqual(mocked, require('node:readline')); + assert.strictEqual(mocked.string, undefined); + assert.strictEqual(mocked.fn(), 42); + t.mock.reset(); + assert.strictEqual(original, require('readline')); + }); + + await t.test('explicitly disables caching', async (t) => { + const original = require('readline'); + + assert.strictEqual(typeof original.cursorTo, 'function'); + assert.strictEqual(original.fn, undefined); + + t.mock.module('readline', { + namedExports: { fn() { return 42; } }, + cache: false, + }); + const mocked = require('readline'); + + assert.notStrictEqual(original, mocked); + assert.notStrictEqual(mocked, require('readline')); + assert.strictEqual(mocked.string, undefined); + assert.strictEqual(mocked.fn(), 42); + t.mock.reset(); + assert.strictEqual(original, require('readline')); + }); + + await t.test('named exports are applied to defaultExport', async (t) => { + const original = require('readline'); + + assert.strictEqual(typeof original.cursorTo, 'function'); + assert.strictEqual(original.val1, undefined); + assert.strictEqual(original.val2, undefined); + + const defaultExport = { val1: 5, val2: 3 }; + + t.mock.module('readline', { + defaultExport, + namedExports: { val1: 'mock value' }, + }); + const mocked = require('readline'); + + assert.notStrictEqual(original, mocked); + assert.strictEqual(mocked.cursorTo, undefined); + assert.strictEqual(mocked.val1, 'mock value'); + assert.strictEqual(mocked.val2, 3); + t.mock.reset(); + assert.strictEqual(original, require('readline')); + }); + + await t.test('throws if named exports cannot be applied to defaultExport', async (t) => { + const fixture = 'readline'; + const original = require(fixture); + + assert.strictEqual(typeof original.cursorTo, 'function'); + assert.strictEqual(original.val1, undefined); + + const defaultExport = null; + + t.mock.module(fixture, { + defaultExport, + namedExports: { val1: 'mock value' }, + }); + assert.throws(() => { + require(fixture); + }, /Cannot create mock/); + t.mock.reset(); + assert.strictEqual(original, require(fixture)); + }); +}); + +test('CJS mocking with namedExports option', async (t) => { + await t.test('does not cache by default', async (t) => { + const fixture = fixtures.path('module-mocking', 'basic-cjs.js'); + const original = require(fixture); + + assert.strictEqual(original.string, 'original cjs string'); + assert.strictEqual(original.fn, undefined); + + t.mock.module(fixture, { + namedExports: { fn() { return 42; } }, + }); + const mocked = require(fixture); + + assert.notStrictEqual(original, mocked); + assert.notStrictEqual(mocked, require(fixture)); + assert.strictEqual(mocked.string, undefined); + assert.strictEqual(mocked.fn(), 42); + t.mock.reset(); + assert.strictEqual(original, require(fixture)); + }); + + await t.test('explicitly enables caching', async (t) => { + const fixture = fixtures.path('module-mocking', 'basic-cjs.js'); + const original = require(fixture); + + assert.strictEqual(original.string, 'original cjs string'); + assert.strictEqual(original.fn, undefined); + + t.mock.module(fixture, { + namedExports: { fn() { return 42; } }, + cache: true, + }); + const mocked = require(fixture); + + assert.notStrictEqual(original, mocked); + assert.strictEqual(mocked, require(fixture)); + assert.strictEqual(mocked.string, undefined); + assert.strictEqual(mocked.fn(), 42); + t.mock.reset(); + assert.strictEqual(original, require(fixture)); + }); + + await t.test('explicitly disables caching', async (t) => { + const fixture = fixtures.path('module-mocking', 'basic-cjs.js'); + const original = require(fixture); + + assert.strictEqual(original.string, 'original cjs string'); + assert.strictEqual(original.fn, undefined); + + t.mock.module(fixture, { + namedExports: { fn() { return 42; } }, + cache: false, + }); + const mocked = require(fixture); + + assert.notStrictEqual(original, mocked); + assert.notStrictEqual(mocked, require(fixture)); + assert.strictEqual(mocked.string, undefined); + assert.strictEqual(mocked.fn(), 42); + t.mock.reset(); + assert.strictEqual(original, require(fixture)); + }); + + await t.test('named exports are applied to defaultExport', async (t) => { + const fixture = fixtures.path('module-mocking', 'basic-cjs.js'); + const original = require(fixture); + + assert.strictEqual(original.string, 'original cjs string'); + assert.strictEqual(original.val1, undefined); + assert.strictEqual(original.val2, undefined); + + const defaultExport = { val1: 5, val2: 3 }; + + t.mock.module(fixture, { + defaultExport, + namedExports: { val1: 'mock value' }, + }); + const mocked = require(fixture); + + assert.notStrictEqual(original, mocked); + assert.strictEqual(mocked.string, undefined); + assert.strictEqual(mocked.val1, 'mock value'); + assert.strictEqual(mocked.val2, 3); + t.mock.reset(); + assert.strictEqual(original, require(fixture)); + }); + + await t.test('throws if named exports cannot be applied to defaultExport', async (t) => { + const fixture = fixtures.path('module-mocking', 'basic-cjs.js'); + const original = require(fixture); + + assert.strictEqual(original.string, 'original cjs string'); + assert.strictEqual(original.val1, undefined); + + const defaultExport = null; + + t.mock.module(fixture, { + defaultExport, + namedExports: { val1: 'mock value' }, + }); + assert.throws(() => { + require(fixture); + }, /Cannot create mock/); + t.mock.reset(); + assert.strictEqual(original, require(fixture)); + }); +}); + +test('ESM mocking with namedExports option', async (t) => { + await t.test('does not cache by default', async (t) => { + const fixture = fixtures.path('module-mocking', 'basic-esm.mjs'); + const original = await import(fixture); + + assert.strictEqual(original.string, 'original esm string'); + assert.strictEqual(original.fn, undefined); + + t.mock.module(fixture, { + namedExports: { fn() { return 42; } }, + }); + const mocked = await import(fixture); + + assert.notStrictEqual(original, mocked); + assert.notStrictEqual(mocked, await import(fixture)); + assert.strictEqual(mocked.string, undefined); + assert.strictEqual(mocked.fn(), 42); + t.mock.reset(); + assert.strictEqual(original, await import(fixture)); + }); + + await t.test('explicitly enables caching', async (t) => { + const fixture = fixtures.path('module-mocking', 'basic-esm.mjs'); + const original = await import(fixture); + + assert.strictEqual(original.string, 'original esm string'); + assert.strictEqual(original.fn, undefined); + + t.mock.module(fixture, { + namedExports: { fn() { return 42; } }, + cache: true, + }); + const mocked = await import(fixture); + + assert.notStrictEqual(original, mocked); + assert.strictEqual(mocked, await import(fixture)); + assert.strictEqual(mocked.string, undefined); + assert.strictEqual(mocked.fn(), 42); + t.mock.reset(); + assert.strictEqual(original, await import(fixture)); + }); + + await t.test('explicitly disables caching', async (t) => { + const fixture = fixtures.path('module-mocking', 'basic-esm.mjs'); + const original = await import(fixture); + + assert.strictEqual(original.string, 'original esm string'); + assert.strictEqual(original.fn, undefined); + + t.mock.module(fixture, { + namedExports: { fn() { return 42; } }, + cache: false, + }); + const mocked = await import(fixture); + + assert.notStrictEqual(original, mocked); + assert.notStrictEqual(mocked, await import(fixture)); + assert.strictEqual(mocked.string, undefined); + assert.strictEqual(mocked.fn(), 42); + t.mock.reset(); + assert.strictEqual(original, await import(fixture)); + }); + + await t.test('named exports are not applied to defaultExport', async (t) => { + const fixture = fixtures.path('module-mocking', 'basic-esm.mjs'); + const original = await import(fixture); + + assert.strictEqual(original.string, 'original esm string'); + assert.strictEqual(original.val1, undefined); + assert.strictEqual(original.val2, undefined); + + const defaultExport = 'mock default'; + + t.mock.module(fixture, { + defaultExport, + namedExports: { val1: 'mock value' }, + }); + const mocked = await import(fixture); + + assert.notStrictEqual(original, mocked); + assert.strictEqual(mocked.string, undefined); + assert.strictEqual(mocked.default, 'mock default'); + assert.strictEqual(mocked.val1, 'mock value'); + t.mock.reset(); + assert.strictEqual(original, require(fixture)); + }); + + await t.test('throws if named exports cannot be applied to defaultExport as CJS', async (t) => { + const fixture = fixtures.path('module-mocking', 'basic-cjs.js'); + const original = await import(fixture); + + assert.strictEqual(original.default.string, 'original cjs string'); + assert.strictEqual(original.default.val1, undefined); + + const defaultExport = null; + + t.mock.module(fixture, { + defaultExport, + namedExports: { val1: 'mock value' }, + }); + await assert.rejects(async () => { + await import(fixture); + }, /Cannot create mock/); + + t.mock.reset(); + assert.strictEqual(original, await import(fixture)); + }); +}); + +test('modules cannot be mocked multiple times at once', async (t) => { + await t.test('CJS', async (t) => { + const fixture = fixtures.path('module-mocking', 'basic-cjs.js'); + + t.mock.module(fixture, { + namedExports: { fn() { return 42; } }, + }); + + assert.throws(() => { + t.mock.module(fixture, { + namedExports: { fn() { return 55; } }, + }); + }, { + code: 'ERR_INVALID_STATE', + message: /The module is already mocked/, + }); + + const mocked = require(fixture); + + assert.strictEqual(mocked.fn(), 42); + }); + + await t.test('ESM', async (t) => { + const fixture = fixtures.path('module-mocking', 'basic-esm.mjs'); + + t.mock.module(fixture, { + namedExports: { fn() { return 42; } }, + }); + + assert.throws(() => { + t.mock.module(fixture, { + namedExports: { fn() { return 55; } }, + }); + }, { + code: 'ERR_INVALID_STATE', + message: /The module is already mocked/, + }); + + const mocked = await import(fixture); + + assert.strictEqual(mocked.fn(), 42); + }); +}); + +test('mocks are automatically restored', async (t) => { + const cjsFixture = fixtures.path('module-mocking', 'basic-cjs.js'); + const esmFixture = fixtures.path('module-mocking', 'basic-esm.mjs'); + + await t.test('CJS', async (t) => { + t.mock.module(cjsFixture, { + namedExports: { fn() { return 42; } }, + }); + + const mocked = require(cjsFixture); + + assert.strictEqual(mocked.fn(), 42); + }); + + await t.test('ESM', async (t) => { + t.mock.module(esmFixture, { + namedExports: { fn() { return 43; } }, + }); + + const mocked = await import(esmFixture); + + assert.strictEqual(mocked.fn(), 43); + }); + + const cjsMock = require(cjsFixture); + const esmMock = await import(esmFixture); + + assert.strictEqual(cjsMock.string, 'original cjs string'); + assert.strictEqual(cjsMock.fn, undefined); + assert.strictEqual(esmMock.string, 'original esm string'); + assert.strictEqual(esmMock.fn, undefined); +}); + +test('mocks can be restored independently', async (t) => { + const cjsFixture = fixtures.path('module-mocking', 'basic-cjs.js'); + const esmFixture = fixtures.path('module-mocking', 'basic-esm.mjs'); + + const cjsMock = t.mock.module(cjsFixture, { + namedExports: { fn() { return 42; } }, + }); + + const esmMock = t.mock.module(esmFixture, { + namedExports: { fn() { return 43; } }, + }); + + let cjsImpl = require(cjsFixture); + let esmImpl = await import(esmFixture); + + assert.strictEqual(cjsImpl.fn(), 42); + assert.strictEqual(esmImpl.fn(), 43); + + cjsMock.restore(); + cjsImpl = require(cjsFixture); + + assert.strictEqual(cjsImpl.fn, undefined); + assert.strictEqual(esmImpl.fn(), 43); + + esmMock.restore(); + esmImpl = await import(esmFixture); + + assert.strictEqual(cjsImpl.fn, undefined); + assert.strictEqual(esmImpl.fn, undefined); +}); + +test('core module mocks can be used by both module systems', async (t) => { + const coreMock = t.mock.module('readline', { + namedExports: { fn() { return 42; } }, + }); + + let esmImpl = await import('readline'); + let cjsImpl = require('readline'); + + assert.strictEqual(esmImpl.fn(), 42); + assert.strictEqual(cjsImpl.fn(), 42); + + coreMock.restore(); + esmImpl = await import('readline'); + cjsImpl = require('readline'); + + assert.strictEqual(typeof esmImpl.cursorTo, 'function'); + assert.strictEqual(typeof cjsImpl.cursorTo, 'function'); +}); + +test('node:- core module mocks can be used by both module systems', async (t) => { + const coreMock = t.mock.module('node:readline', { + namedExports: { fn() { return 42; } }, + }); + + let esmImpl = await import('node:readline'); + let cjsImpl = require('node:readline'); + + assert.strictEqual(esmImpl.fn(), 42); + assert.strictEqual(cjsImpl.fn(), 42); + + coreMock.restore(); + esmImpl = await import('node:readline'); + cjsImpl = require('node:readline'); + + assert.strictEqual(typeof esmImpl.cursorTo, 'function'); + assert.strictEqual(typeof cjsImpl.cursorTo, 'function'); +}); + +test('CJS mocks can be used by both module systems', async (t) => { + const cjsFixture = fixtures.path('module-mocking', 'basic-cjs.js'); + const cjsMock = t.mock.module(cjsFixture, { + namedExports: { fn() { return 42; } }, + }); + let esmImpl = await import(pathToFileURL(cjsFixture)); + let cjsImpl = require(cjsFixture); + + assert.strictEqual(esmImpl.fn(), 42); + assert.strictEqual(cjsImpl.fn(), 42); + + cjsMock.restore(); + + esmImpl = await import(pathToFileURL(cjsFixture)); + cjsImpl = require(cjsFixture); + + assert.strictEqual(esmImpl.default.string, 'original cjs string'); + assert.strictEqual(cjsImpl.string, 'original cjs string'); +}); + +test('relative paths can be used by both module systems', async (t) => { + const fixture = relative( + __dirname, fixtures.path('module-mocking', 'basic-esm.mjs') + ); + const mock = t.mock.module(fixture, { + namedExports: { fn() { return 42; } }, + }); + let cjsImpl = require(fixture); + let esmImpl = await import(fixture); + + assert.strictEqual(cjsImpl.fn(), 42); + assert.strictEqual(esmImpl.fn(), 42); + + mock.restore(); + cjsImpl = require(fixture); + esmImpl = await import(fixture); + + assert.strictEqual(esmImpl.string, 'original esm string'); + assert.strictEqual(cjsImpl.string, 'original esm string'); +}); + +test('node_modules can be used by both module systems', async (t) => { + const cwd = fixtures.path('test-runner'); + const fixture = fixtures.path('test-runner', 'mock-nm.js'); + const args = ['--experimental-test-module-mocks', fixture]; + const { + code, + stdout, + signal, + } = await common.spawnPromisified(process.execPath, args, { cwd }); + + assert.strictEqual(code, 0); + assert.strictEqual(signal, null); + assert.match(stdout, /# pass 1/); +}); + +test('file:// imports are supported in ESM only', async (t) => { + const fixture = fixtures.fileURL('module-mocking', 'basic-esm.mjs').href; + const mock = t.mock.module(fixture, { + namedExports: { fn() { return 42; } }, + }); + let impl = await import(fixture); + + assert.strictEqual(impl.fn(), 42); + assert.throws(() => { + require(fixture); + }, { code: 'MODULE_NOT_FOUND' }); + mock.restore(); + impl = await import(fixture); + assert.strictEqual(impl.string, 'original esm string'); +}); + +test('mocked modules do not impact unmocked modules', async (t) => { + const mockedFixture = fixtures.fileURL('module-mocking', 'basic-cjs.js'); + const unmockedFixture = fixtures.fileURL('module-mocking', 'basic-esm.mjs'); + t.mock.module(`${mockedFixture}`, { + namedExports: { fn() { return 42; } }, + }); + const mockedImpl = await import(mockedFixture); + const unmockedImpl = await import(unmockedFixture); + + assert.strictEqual(mockedImpl.fn(), 42); + assert.strictEqual(unmockedImpl.fn, undefined); + assert.strictEqual(unmockedImpl.string, 'original esm string'); +}); + +test('defaultExports work with CJS mocks in both module systems', async (t) => { + const fixture = fixtures.path('module-mocking', 'basic-cjs.js'); + const original = require(fixture); + const defaultExport = Symbol('default'); + + assert.strictEqual(original.string, 'original cjs string'); + t.mock.module(fixture, { defaultExport }); + assert.strictEqual(require(fixture), defaultExport); + assert.strictEqual((await import(pathToFileURL(fixture))).default, defaultExport); +}); + +test('defaultExports work with ESM mocks in both module systems', async (t) => { + const fixture = fixtures.fileURL('module-mocking', 'basic-esm.mjs'); + const original = await import(fixture); + const defaultExport = Symbol('default'); + + assert.strictEqual(original.string, 'original esm string'); + t.mock.module(`${fixture}`, { defaultExport }); + assert.strictEqual((await import(fixture)).default, defaultExport); + assert.strictEqual(require(fileURLToPath(fixture)), defaultExport); +}); + +test('wrong import syntax should throw error after module mocking.', async () => { + const { stdout, stderr, code } = await common.spawnPromisified( + process.execPath, + [ + '--experimental-test-module-mocks', + '--experimental-default-type=module', + fixtures.path('module-mocking/wrong-import-after-module-mocking.js'), + ] + ); + + assert.strictEqual(stdout, ''); + assert.match(stderr, /Error \[ERR_MODULE_NOT_FOUND\]: Cannot find module/); + assert.strictEqual(code, 1); +}); diff --git a/test/parallel/test-runner-output.mjs b/test/parallel/test-runner-output.mjs index e2532d24054..9fc6a6bfb44 100644 --- a/test/parallel/test-runner-output.mjs +++ b/test/parallel/test-runner-output.mjs @@ -93,11 +93,12 @@ const lcovTransform = snapshot.transform( const tests = [ { name: 'test-runner/output/abort.js' }, + { name: 'test-runner/output/abort-runs-after-hook.js' }, { name: 'test-runner/output/abort_suite.js' }, { name: 'test-runner/output/abort_hooks.js' }, { name: 'test-runner/output/describe_it.js' }, { name: 'test-runner/output/describe_nested.js' }, - { name: 'test-runner/output/eval_dot.js' }, + { name: 'test-runner/output/eval_dot.js', transform: specTransform }, { name: 'test-runner/output/eval_spec.js', transform: specTransform }, { name: 'test-runner/output/eval_tap.js' }, { name: 'test-runner/output/hooks.js' }, @@ -114,7 +115,7 @@ const tests = [ { name: 'test-runner/output/no_refs.js' }, { name: 'test-runner/output/no_tests.js' }, { name: 'test-runner/output/only_tests.js' }, - { name: 'test-runner/output/dot_reporter.js' }, + { name: 'test-runner/output/dot_reporter.js', transform: specTransform }, { name: 'test-runner/output/junit_reporter.js', transform: junitTransform }, { name: 'test-runner/output/spec_reporter_successful.js', transform: specTransform }, { name: 'test-runner/output/spec_reporter.js', transform: specTransform }, diff --git a/test/parallel/test-runner-reporters.js b/test/parallel/test-runner-reporters.js index 6d1f9ff6be3..a412bd099ec 100644 --- a/test/parallel/test-runner-reporters.js +++ b/test/parallel/test-runner-reporters.js @@ -25,7 +25,10 @@ describe('node:test reporters', { concurrency: true }, () => { it('should default destination to stdout when passing a single reporter', async () => { const child = spawnSync(process.execPath, ['--test', '--test-reporter', 'dot', testFile]); assert.strictEqual(child.stderr.toString(), ''); - assert.strictEqual(child.stdout.toString(), '.XX.\n'); + assert.match(child.stdout.toString(), /\.XX\.\n/); + assert.match(child.stdout.toString(), /Failed tests:/); + assert.match(child.stdout.toString(), /✖ failing/); + assert.match(child.stdout.toString(), /✖ nested/); }); it('should throw when passing reporters without a destination', async () => { @@ -44,13 +47,19 @@ describe('node:test reporters', { concurrency: true }, () => { const child = spawnSync(process.execPath, ['--test', '--test-reporter', 'dot', '--test-reporter-destination', 'stdout', testFile]); assert.strictEqual(child.stderr.toString(), ''); - assert.strictEqual(child.stdout.toString(), '.XX.\n'); + assert.match(child.stdout.toString(), /\.XX\.\n/); + assert.match(child.stdout.toString(), /Failed tests:/); + assert.match(child.stdout.toString(), /✖ failing/); + assert.match(child.stdout.toString(), /✖ nested/); }); it('should support stderr as a destination', async () => { const child = spawnSync(process.execPath, ['--test', '--test-reporter', 'dot', '--test-reporter-destination', 'stderr', testFile]); - assert.strictEqual(child.stderr.toString(), '.XX.\n'); + assert.match(child.stderr.toString(), /\.XX\.\n/); + assert.match(child.stderr.toString(), /Failed tests:/); + assert.match(child.stderr.toString(), /✖ failing/); + assert.match(child.stderr.toString(), /✖ nested/); assert.strictEqual(child.stdout.toString(), ''); }); @@ -60,7 +69,11 @@ describe('node:test reporters', { concurrency: true }, () => { ['--test', '--test-reporter', 'dot', '--test-reporter-destination', file, testFile]); assert.strictEqual(child.stderr.toString(), ''); assert.strictEqual(child.stdout.toString(), ''); - assert.strictEqual(fs.readFileSync(file, 'utf8'), '.XX.\n'); + const fileContents = fs.readFileSync(file, 'utf8'); + assert.match(fileContents, /\.XX\.\n/); + assert.match(fileContents, /Failed tests:/); + assert.match(fileContents, /✖ failing/); + assert.match(fileContents, /✖ nested/); }); it('should disallow using v8-serializer as reporter', async () => { @@ -81,7 +94,11 @@ describe('node:test reporters', { concurrency: true }, () => { testFile]); assert.match(child.stdout.toString(), /TAP version 13/); assert.match(child.stdout.toString(), /# duration_ms/); - assert.strictEqual(fs.readFileSync(file, 'utf8'), '.XX.\n'); + const fileContents = fs.readFileSync(file, 'utf8'); + assert.match(fileContents, /\.XX\.\n/); + assert.match(fileContents, /Failed tests:/); + assert.match(fileContents, /✖ failing/); + assert.match(fileContents, /✖ nested/); const file2Contents = fs.readFileSync(file2, 'utf8'); assert.match(file2Contents, /▶ nested/); assert.match(file2Contents, /✔ ok/); diff --git a/test/parallel/test-runner-run.mjs b/test/parallel/test-runner-run.mjs index 548ea78ce02..ec40c9d1647 100644 --- a/test/parallel/test-runner-run.mjs +++ b/test/parallel/test-runner-run.mjs @@ -4,6 +4,7 @@ import { join } from 'node:path'; import { describe, it, run } from 'node:test'; import { dot, spec, tap } from 'node:test/reporters'; import assert from 'node:assert'; +import util from 'node:util'; const testFixtures = fixtures.path('test-runner'); @@ -76,10 +77,10 @@ describe('require(\'node:test\').run', { concurrency: true }, () => { const result = await run({ files: [join(testFixtures, 'default-behavior/test/random.cjs')] }).compose(dot).toArray(); - assert.deepStrictEqual(result, [ - '.', - '\n', - ]); + + assert.strictEqual(result.length, 2); + assert.strictEqual(util.stripVTControlCharacters(result[0]), '.'); + assert.strictEqual(result[1], '\n'); }); describe('should be piped with spec reporter', () => { diff --git a/test/parallel/test-stream-finished.js b/test/parallel/test-stream-finished.js index 6820ac18cf4..9d66cbe59b1 100644 --- a/test/parallel/test-stream-finished.js +++ b/test/parallel/test-stream-finished.js @@ -687,3 +687,16 @@ testClosed((opts) => new Writable({ write() {}, ...opts })); assert.strictEqual(stream._writableState.pendingcb, 0); })); } + +{ + const stream = new Duplex({ + write(chunk, enc, cb) {} + }); + + stream.end('foo'); + + // Simulate an old stream implementation that doesn't have pendingcb + delete stream._writableState.pendingcb; + + finished(stream, { readable: false }, common.mustCall()); +} diff --git a/test/parallel/test-stream-readable-from-web-termination.js b/test/parallel/test-stream-readable-from-web-termination.js new file mode 100644 index 00000000000..68ed7d69694 --- /dev/null +++ b/test/parallel/test-stream-readable-from-web-termination.js @@ -0,0 +1,15 @@ +'use strict'; +require('../common'); +const { Readable } = require('stream'); + +{ + const r = Readable.from(['data']); + + const wrapper = Readable.fromWeb(Readable.toWeb(r)); + + wrapper.on('data', () => { + // Destroying wrapper while emitting data should not cause uncaught + // exceptions + wrapper.destroy(); + }); +} diff --git a/test/parallel/test-stream-readable-to-web-termination.js b/test/parallel/test-stream-readable-to-web-termination.js new file mode 100644 index 00000000000..13fce9bc715 --- /dev/null +++ b/test/parallel/test-stream-readable-to-web-termination.js @@ -0,0 +1,12 @@ +'use strict'; +require('../common'); +const { Readable } = require('stream'); + +{ + const r = Readable.from([]); + // Cancelling reader while closing should not cause uncaught exceptions + r.on('close', () => reader.cancel()); + + const reader = Readable.toWeb(r).getReader(); + reader.read(); +} diff --git a/test/parallel/test-timers-timeout-promisified.js b/test/parallel/test-timers-timeout-promisified.js index a63923b7fee..a89ccad7305 100644 --- a/test/parallel/test-timers-timeout-promisified.js +++ b/test/parallel/test-timers-timeout-promisified.js @@ -63,29 +63,21 @@ process.on('multipleResolves', common.mustNotCall()); } { - Promise.all( - [1, '', false, Infinity].map( - (i) => assert.rejects(setPromiseTimeout(10, null, i), { - code: 'ERR_INVALID_ARG_TYPE' - }) - ) - ).then(common.mustCall()); - - Promise.all( - [1, '', false, Infinity, null, {}].map( - (signal) => assert.rejects(setPromiseTimeout(10, null, { signal }), { - code: 'ERR_INVALID_ARG_TYPE' - }) - ) - ).then(common.mustCall()); - - Promise.all( - [1, '', Infinity, null, {}].map( - (ref) => assert.rejects(setPromiseTimeout(10, null, { ref }), { - code: 'ERR_INVALID_ARG_TYPE' - }) - ) - ).then(common.mustCall()); + for (const delay of ['', false]) { + assert.rejects(() => setPromiseTimeout(delay, null, {}), /ERR_INVALID_ARG_TYPE/).then(common.mustCall()); + } + + for (const options of [1, '', false, Infinity]) { + assert.rejects(() => setPromiseTimeout(10, null, options), /ERR_INVALID_ARG_TYPE/).then(common.mustCall()); + } + + for (const signal of [1, '', false, Infinity, null, {}]) { + assert.rejects(() => setPromiseTimeout(10, null, { signal }), /ERR_INVALID_ARG_TYPE/).then(common.mustCall()); + } + + for (const ref of [1, '', Infinity, null, {}]) { + assert.rejects(() => setPromiseTimeout(10, null, { ref }), /ERR_INVALID_ARG_TYPE/).then(common.mustCall()); + } } { diff --git a/test/parallel/test-timers-unref.js b/test/parallel/test-timers-unref.js index 35615d111ad..34a661c761a 100644 --- a/test/parallel/test-timers-unref.js +++ b/test/parallel/test-timers-unref.js @@ -72,7 +72,7 @@ const check_unref = setInterval(() => { setInterval(() => timeout.unref(), SHORT_TIME); } -// Should not assert on args.Holder()->InternalFieldCount() > 0. +// Should not assert on args.This()->InternalFieldCount() > 0. // See https://github.com/nodejs/node-v0.x-archive/issues/4261. { const t = setInterval(() => {}, 1); diff --git a/test/parallel/test-tls-alert-handling.js b/test/parallel/test-tls-alert-handling.js index bd86149bc5a..67680099da0 100644 --- a/test/parallel/test-tls-alert-handling.js +++ b/test/parallel/test-tls-alert-handling.js @@ -31,10 +31,17 @@ const max_iter = 20; let iter = 0; const errorHandler = common.mustCall((err) => { - assert.strictEqual(err.code, 'ERR_SSL_WRONG_VERSION_NUMBER'); + let expectedErrorCode = 'ERR_SSL_WRONG_VERSION_NUMBER'; + let expectedErrorReason = 'wrong version number'; + if (common.hasOpenSSL(3, 2)) { + expectedErrorCode = 'ERR_SSL_PACKET_LENGTH_TOO_LONG'; + expectedErrorReason = 'packet length too long'; + } + + assert.strictEqual(err.code, expectedErrorCode); assert.strictEqual(err.library, 'SSL routines'); if (!common.hasOpenSSL3) assert.strictEqual(err.function, 'ssl3_get_record'); - assert.strictEqual(err.reason, 'wrong version number'); + assert.strictEqual(err.reason, expectedErrorReason); errorReceived = true; if (canCloseServer()) server.close(); @@ -87,10 +94,16 @@ function sendBADTLSRecord() { }); })); client.on('error', common.mustCall((err) => { - assert.strictEqual(err.code, 'ERR_SSL_TLSV1_ALERT_PROTOCOL_VERSION'); + let expectedErrorCode = 'ERR_SSL_TLSV1_ALERT_PROTOCOL_VERSION'; + let expectedErrorReason = 'tlsv1 alert protocol version'; + if (common.hasOpenSSL(3, 2)) { + expectedErrorCode = 'ERR_SSL_TLSV1_ALERT_RECORD_OVERFLOW'; + expectedErrorReason = 'tlsv1 alert record overflow'; + } + assert.strictEqual(err.code, expectedErrorCode); assert.strictEqual(err.library, 'SSL routines'); if (!common.hasOpenSSL3) assert.strictEqual(err.function, 'ssl3_read_bytes'); - assert.strictEqual(err.reason, 'tlsv1 alert protocol version'); + assert.strictEqual(err.reason, expectedErrorReason); })); } diff --git a/test/parallel/test-tls-client-allow-partial-trust-chain.js b/test/parallel/test-tls-client-allow-partial-trust-chain.js new file mode 100644 index 00000000000..56a426ff840 --- /dev/null +++ b/test/parallel/test-tls-client-allow-partial-trust-chain.js @@ -0,0 +1,53 @@ +'use strict'; +const common = require('../common'); +if (!common.hasCrypto) { common.skip('missing crypto'); } + +const assert = require('assert'); +const { once } = require('events'); +const fixtures = require('../common/fixtures'); + +// agent6-cert.pem is signed by intermediate cert of ca3. +// The server has a cert chain of agent6->ca3->ca1(root). + +const { it, beforeEach, afterEach, describe } = require('node:test'); + +describe('allowPartialTrustChain', { skip: !common.hasCrypto }, function() { + const tls = require('tls'); + let server; + let client; + let opts; + + beforeEach(async function() { + server = tls.createServer({ + ca: fixtures.readKey('ca3-cert.pem'), + key: fixtures.readKey('agent6-key.pem'), + cert: fixtures.readKey('agent6-cert.pem'), + }, (socket) => socket.resume()); + server.listen(0); + await once(server, 'listening'); + + opts = { + port: server.address().port, + ca: fixtures.readKey('ca3-cert.pem'), + checkServerIdentity() {} + }; + }); + + afterEach(async function() { + client?.destroy(); + server?.close(); + }); + + it('can connect successfully with allowPartialTrustChain: true', async function() { + client = tls.connect({ ...opts, allowPartialTrustChain: true }); + await once(client, 'secureConnect'); // Should not throw + }); + + it('fails without with allowPartialTrustChain: true for an intermediate cert in the CA', async function() { + // Consistency check: Connecting fails without allowPartialTrustChain: true + await assert.rejects(async () => { + const client = tls.connect(opts); + await once(client, 'secureConnect'); + }, { code: 'UNABLE_TO_GET_ISSUER_CERT' }); + }); +}); diff --git a/test/parallel/test-tls-client-auth.js b/test/parallel/test-tls-client-auth.js index 04756924e5e..de4c8f038ec 100644 --- a/test/parallel/test-tls-client-auth.js +++ b/test/parallel/test-tls-client-auth.js @@ -79,8 +79,10 @@ connect({ }, function(err, pair, cleanup) { assert.strictEqual(pair.server.err.code, 'ERR_SSL_PEER_DID_NOT_RETURN_A_CERTIFICATE'); + const expectedErr = common.hasOpenSSL(3, 2) ? + 'ERR_SSL_SSL/TLS_ALERT_HANDSHAKE_FAILURE' : 'ERR_SSL_SSLV3_ALERT_HANDSHAKE_FAILURE'; assert.strictEqual(pair.client.err.code, - 'ERR_SSL_SSLV3_ALERT_HANDSHAKE_FAILURE'); + expectedErr); return cleanup(); }); diff --git a/test/parallel/test-tls-client-mindhsize.js b/test/parallel/test-tls-client-mindhsize.js index 92ac9959368..2295f1f064f 100644 --- a/test/parallel/test-tls-client-mindhsize.js +++ b/test/parallel/test-tls-client-mindhsize.js @@ -35,11 +35,12 @@ function test(size, err, next) { }); server.listen(0, function() { - // Client set minimum DH parameter size to 2048 bits so that - // it fails when it make a connection to the tls server where - // dhparams is 1024 bits + // Client set minimum DH parameter size to 2048 or 3072 bits + // so that it fails when it makes a connection to the tls + // server where is too small + const minDHSize = common.hasOpenSSL(3, 2) ? 3072 : 2048; const client = tls.connect({ - minDHSize: 2048, + minDHSize: minDHSize, port: this.address().port, rejectUnauthorized: false, maxVersion: 'TLSv1.2', @@ -60,16 +61,27 @@ function test(size, err, next) { // A client connection fails with an error when a client has an // 2048 bits minDHSize option and a server has 1024 bits dhparam function testDHE1024() { - test(1024, true, testDHE2048); + test(1024, true, testDHE2048(false, null)); +} + +// Test a client connection when a client has an +// 2048 bits minDHSize option +function testDHE2048(expect_to_fail, next) { + test(2048, expect_to_fail, next); } // A client connection successes when a client has an -// 2048 bits minDHSize option and a server has 2048 bits dhparam -function testDHE2048() { - test(2048, false, null); +// 3072 bits minDHSize option and a server has 3072 bits dhparam +function testDHE3072() { + test(3072, false, null); } -testDHE1024(); +if (common.hasOpenSSL(3, 2)) { + // Minimum size for OpenSSL 3.2 is 2048 by default + testDHE2048(true, testDHE3072); +} else { + testDHE1024(); +} assert.throws(() => test(512, true, common.mustNotCall()), /DH parameter is less than 1024 bits/); diff --git a/test/parallel/test-tls-connect-memleak.js b/test/parallel/test-tls-connect-memleak.js index b0dedfa0bba..5bdcbe89f78 100644 --- a/test/parallel/test-tls-connect-memleak.js +++ b/test/parallel/test-tls-connect-memleak.js @@ -26,7 +26,7 @@ const common = require('../common'); if (!common.hasCrypto) common.skip('missing crypto'); -const onGC = require('../common/ongc'); +const { onGC } = require('../common/gc'); const assert = require('assert'); const tls = require('tls'); const fixtures = require('../common/fixtures'); diff --git a/test/parallel/test-tls-dhe.js b/test/parallel/test-tls-dhe.js index 46779b09ff6..21739ce4242 100644 --- a/test/parallel/test-tls-dhe.js +++ b/test/parallel/test-tls-dhe.js @@ -43,9 +43,12 @@ const dheCipher = 'DHE-RSA-AES128-SHA256'; const ecdheCipher = 'ECDHE-RSA-AES128-SHA256'; const ciphers = `${dheCipher}:${ecdheCipher}`; -// Test will emit a warning because the DH parameter size is < 2048 bits -common.expectWarning('SecurityWarning', - 'DH parameter is less than 2048 bits'); +if (!common.hasOpenSSL(3, 2)) { + // Test will emit a warning because the DH parameter size is < 2048 bits + // when the test is run on versions lower than OpenSSL32 + common.expectWarning('SecurityWarning', + 'DH parameter is less than 2048 bits'); +} function loadDHParam(n) { const keyname = `dh${n}.pem`; @@ -104,7 +107,11 @@ function testCustomParam(keylen, expectedCipher) { }, /DH parameter is less than 1024 bits/); // Custom DHE parameters are supported (but discouraged). - await testCustomParam(1024, dheCipher); + if (!common.hasOpenSSL(3, 2)) { + await testCustomParam(1024, dheCipher); + } else { + await testCustomParam(3072, dheCipher); + } await testCustomParam(2048, dheCipher); // Invalid DHE parameters are discarded. ECDHE remains enabled. diff --git a/test/parallel/test-tls-junk-server.js b/test/parallel/test-tls-junk-server.js index 273fe9def4e..2226ac93d28 100644 --- a/test/parallel/test-tls-junk-server.js +++ b/test/parallel/test-tls-junk-server.js @@ -20,8 +20,12 @@ server.listen(0, function() { const req = https.request({ port: this.address().port }); req.end(); + let expectedErrorMessage = new RegExp('wrong version number'); + if (common.hasOpenSSL(3, 2)) { + expectedErrorMessage = new RegExp('packet length too long'); + } req.once('error', common.mustCall(function(err) { - assert(/wrong version number/.test(err.message)); + assert(expectedErrorMessage.test(err.message)); server.close(); })); }); diff --git a/test/parallel/test-tls-legacy-pfx.js b/test/parallel/test-tls-legacy-pfx.js new file mode 100644 index 00000000000..33b4c58fc6c --- /dev/null +++ b/test/parallel/test-tls-legacy-pfx.js @@ -0,0 +1,27 @@ +'use strict'; +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); +if (!common.hasOpenSSL3) + common.skip('OpenSSL legacy failures are only testable with OpenSSL 3+'); + +const fixtures = require('../common/fixtures'); + +const { + assert, connect, keys +} = require(fixtures.path('tls-connect')); + +const legacyPfx = fixtures.readKey('legacy.pfx'); + +connect({ + client: { + pfx: legacyPfx, + passphrase: 'legacy', + rejectUnauthorized: false + }, + server: keys.agent1 +}, common.mustCall((e, pair, cleanup) => { + assert.strictEqual(e.code, 'ERR_CRYPTO_UNSUPPORTED_OPERATION'); + assert.strictEqual(e.message, 'Unsupported PKCS12 PFX data'); + cleanup(); +})); diff --git a/test/parallel/test-tls-set-sigalgs.js b/test/parallel/test-tls-set-sigalgs.js index 59dc2ca0c78..3f3d152f4d8 100644 --- a/test/parallel/test-tls-set-sigalgs.js +++ b/test/parallel/test-tls-set-sigalgs.js @@ -9,13 +9,6 @@ const { assert, connect, keys } = require(fixtures.path('tls-connect')); -function assert_arrays_equal(left, right) { - assert.strictEqual(left.length, right.length); - for (let i = 0; i < left.length; i++) { - assert.strictEqual(left[i], right[i]); - } -} - function test(csigalgs, ssigalgs, shared_sigalgs, cerr, serr) { assert(shared_sigalgs || serr || cerr, 'test missing any expectations'); connect({ @@ -43,16 +36,19 @@ function test(csigalgs, ssigalgs, shared_sigalgs, cerr, serr) { assert.ifError(pair.client.err); assert(pair.server.conn); assert(pair.client.conn); - assert_arrays_equal(pair.server.conn.getSharedSigalgs(), shared_sigalgs); + assert.deepStrictEqual( + pair.server.conn.getSharedSigalgs(), + shared_sigalgs + ); } else { if (serr) { assert(pair.server.err); - assert(pair.server.err.code, serr); + assert.strictEqual(pair.server.err.code, serr); } if (cerr) { assert(pair.client.err); - assert(pair.client.err.code, cerr); + assert.strictEqual(pair.client.err.code, cerr); } } @@ -67,8 +63,12 @@ test('RSA-PSS+SHA256:RSA-PSS+SHA512:ECDSA+SHA256', ['RSA-PSS+SHA256', 'ECDSA+SHA256']); // Do not have shared sigalgs. +const handshakeErr = common.hasOpenSSL(3, 2) ? + 'ERR_SSL_SSL/TLS_ALERT_HANDSHAKE_FAILURE' : 'ERR_SSL_SSLV3_ALERT_HANDSHAKE_FAILURE'; test('RSA-PSS+SHA384', 'ECDSA+SHA256', - undefined, 'ECONNRESET', 'ERR_SSL_NO_SHARED_SIGNATURE_ALGORITMS'); + undefined, handshakeErr, + 'ERR_SSL_NO_SHARED_SIGNATURE_ALGORITHMS'); test('RSA-PSS+SHA384:ECDSA+SHA256', 'ECDSA+SHA384:RSA-PSS+SHA256', - undefined, 'ECONNRESET', 'ERR_SSL_NO_SHARED_SIGNATURE_ALGORITMS'); + undefined, handshakeErr, + 'ERR_SSL_NO_SHARED_SIGNATURE_ALGORITHMS'); diff --git a/test/parallel/test-url-domain-ascii-unicode.js b/test/parallel/test-url-domain-ascii-unicode.js index 737294c241f..f0a2f3db139 100644 --- a/test/parallel/test-url-domain-ascii-unicode.js +++ b/test/parallel/test-url-domain-ascii-unicode.js @@ -1,14 +1,10 @@ 'use strict'; -const common = require('../common'); -if (!common.hasIntl) - common.skip('missing Intl'); +const { hasIntl } = require('../common'); -const strictEqual = require('assert').strictEqual; -const url = require('url'); - -const domainToASCII = url.domainToASCII; -const domainToUnicode = url.domainToUnicode; +const { strictEqual } = require('node:assert'); +const { domainToASCII, domainToUnicode } = require('node:url'); +const { test } = require('node:test'); const domainWithASCII = [ ['ıíd', 'xn--d-iga7r'], @@ -21,11 +17,11 @@ const domainWithASCII = [ ['भारत.org', 'xn--h2brj9c.org'], ]; -domainWithASCII.forEach((pair) => { - const domain = pair[0]; - const ascii = pair[1]; - const domainConvertedToASCII = domainToASCII(domain); - strictEqual(domainConvertedToASCII, ascii); - const asciiConvertedToUnicode = domainToUnicode(ascii); - strictEqual(asciiConvertedToUnicode, domain); +test('domainToASCII and domainToUnicode', { skip: !hasIntl }, () => { + for (const [domain, ascii] of domainWithASCII) { + const domainConvertedToASCII = domainToASCII(domain); + strictEqual(domainConvertedToASCII, ascii); + const asciiConvertedToUnicode = domainToUnicode(ascii); + strictEqual(asciiConvertedToUnicode, domain); + } }); diff --git a/test/parallel/test-url-fileurltopath.js b/test/parallel/test-url-fileurltopath.js index 6bd4e280483..338efacaa1a 100644 --- a/test/parallel/test-url-fileurltopath.js +++ b/test/parallel/test-url-fileurltopath.js @@ -1,25 +1,25 @@ 'use strict'; const { isWindows } = require('../common'); -const assert = require('assert'); -const url = require('url'); -function testInvalidArgs(...args) { - for (const arg of args) { +const { test } = require('node:test'); +const assert = require('node:assert'); +const url = require('node:url'); + +test('invalid arguments', () => { + for (const arg of [null, undefined, 1, {}, true]) { assert.throws(() => url.fileURLToPath(arg), { code: 'ERR_INVALID_ARG_TYPE' }); } -} - -// Input must be string or URL -testInvalidArgs(null, undefined, 1, {}, true); +}); -// Input must be a file URL -assert.throws(() => url.fileURLToPath('https://a/b/c'), { - code: 'ERR_INVALID_URL_SCHEME' +test('input must be a file URL', () => { + assert.throws(() => url.fileURLToPath('https://a/b/c'), { + code: 'ERR_INVALID_URL_SCHEME' + }); }); -{ +test('fileURLToPath with host', () => { const withHost = new URL('file://host/a'); if (isWindows) { @@ -29,9 +29,9 @@ assert.throws(() => url.fileURLToPath('https://a/b/c'), { code: 'ERR_INVALID_FILE_URL_HOST' }); } -} +}); -{ +test('fileURLToPath with invalid path', () => { if (isWindows) { assert.throws(() => url.fileURLToPath('file:///C:/a%2F/'), { code: 'ERR_INVALID_FILE_URL_PATH' @@ -47,7 +47,7 @@ assert.throws(() => url.fileURLToPath('https://a/b/c'), { code: 'ERR_INVALID_FILE_URL_PATH' }); } -} +}); const windowsTestCases = [ // Lowercase ascii alpha @@ -95,6 +95,7 @@ const windowsTestCases = [ // UNC path (see https://docs.microsoft.com/en-us/archive/blogs/ie/file-uris-in-windows) { path: '\\\\nas\\My Docs\\File.doc', fileURL: 'file://nas/My%20Docs/File.doc' }, ]; + const posixTestCases = [ // Lowercase ascii alpha { path: '/foo', fileURL: 'file:///foo' }, @@ -140,29 +141,37 @@ const posixTestCases = [ { path: '/🚀', fileURL: 'file:///%F0%9F%9A%80' }, ]; -for (const { path, fileURL } of windowsTestCases) { - const fromString = url.fileURLToPath(fileURL, { windows: true }); - assert.strictEqual(fromString, path); - const fromURL = url.fileURLToPath(new URL(fileURL), { windows: true }); - assert.strictEqual(fromURL, path); -} +test('fileURLToPath with windows path', { skip: !isWindows }, () => { + + for (const { path, fileURL } of windowsTestCases) { + const fromString = url.fileURLToPath(fileURL, { windows: true }); + assert.strictEqual(fromString, path); + const fromURL = url.fileURLToPath(new URL(fileURL), { windows: true }); + assert.strictEqual(fromURL, path); + } +}); -for (const { path, fileURL } of posixTestCases) { - const fromString = url.fileURLToPath(fileURL, { windows: false }); - assert.strictEqual(fromString, path); - const fromURL = url.fileURLToPath(new URL(fileURL), { windows: false }); - assert.strictEqual(fromURL, path); -} +test('fileURLToPath with posix path', { skip: isWindows }, () => { + for (const { path, fileURL } of posixTestCases) { + const fromString = url.fileURLToPath(fileURL, { windows: false }); + assert.strictEqual(fromString, path); + const fromURL = url.fileURLToPath(new URL(fileURL), { windows: false }); + assert.strictEqual(fromURL, path); + } +}); const defaultTestCases = isWindows ? windowsTestCases : posixTestCases; -// Test when `options` is null -const whenNullActual = url.fileURLToPath(new URL(defaultTestCases[0].fileURL), null); -assert.strictEqual(whenNullActual, defaultTestCases[0].path); +test('options is null', () => { + const whenNullActual = url.fileURLToPath(new URL(defaultTestCases[0].fileURL), null); + assert.strictEqual(whenNullActual, defaultTestCases[0].path); +}); -for (const { path, fileURL } of defaultTestCases) { - const fromString = url.fileURLToPath(fileURL); - assert.strictEqual(fromString, path); - const fromURL = url.fileURLToPath(new URL(fileURL)); - assert.strictEqual(fromURL, path); -} +test('defaultTestCases', () => { + for (const { path, fileURL } of defaultTestCases) { + const fromString = url.fileURLToPath(fileURL); + assert.strictEqual(fromString, path); + const fromURL = url.fileURLToPath(new URL(fileURL)); + assert.strictEqual(fromURL, path); + } +}); diff --git a/test/parallel/test-url-format-invalid-input.js b/test/parallel/test-url-format-invalid-input.js index efa1a9ba1df..4395ececfe6 100644 --- a/test/parallel/test-url-format-invalid-input.js +++ b/test/parallel/test-url-format-invalid-input.js @@ -1,27 +1,30 @@ 'use strict'; -const common = require('../common'); -const assert = require('assert'); -const url = require('url'); -const throwsObjsAndReportTypes = [ - undefined, - null, - true, - false, - 0, - function() {}, - Symbol('foo'), -]; +require('../common'); -for (const urlObject of throwsObjsAndReportTypes) { - assert.throws(() => { - url.format(urlObject); - }, { - code: 'ERR_INVALID_ARG_TYPE', - name: 'TypeError', - message: 'The "urlObject" argument must be one of type object or string.' + - common.invalidArgTypeHelper(urlObject) - }); -} -assert.strictEqual(url.format(''), ''); -assert.strictEqual(url.format({}), ''); +const assert = require('node:assert'); +const url = require('node:url'); +const { test } = require('node:test'); + +test('format invalid input', () => { + const throwsObjsAndReportTypes = [ + undefined, + null, + true, + false, + 0, + function() {}, + Symbol('foo'), + ]; + + for (const urlObject of throwsObjsAndReportTypes) { + assert.throws(() => { + url.format(urlObject); + }, { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + }); + } + assert.strictEqual(url.format(''), ''); + assert.strictEqual(url.format({}), ''); +}); diff --git a/test/parallel/test-url-format-whatwg.js b/test/parallel/test-url-format-whatwg.js index bf9f8eaac63..f399e0faf1d 100644 --- a/test/parallel/test-url-format-whatwg.js +++ b/test/parallel/test-url-format-whatwg.js @@ -1,147 +1,149 @@ 'use strict'; -const common = require('../common'); -if (!common.hasIntl) - common.skip('missing Intl'); +const { hasIntl } = require('../common'); -const assert = require('assert'); -const url = require('url'); +const assert = require('node:assert'); +const url = require('node:url'); +const { test } = require('node:test'); const myURL = new URL('http://user:pass@xn--lck1c3crb1723bpq4a.com/a?a=b#c'); -assert.strictEqual( - url.format(myURL), - 'http://user:pass@xn--lck1c3crb1723bpq4a.com/a?a=b#c' -); +test('should format', { skip: !hasIntl }, () => { + assert.strictEqual( + url.format(myURL), + 'http://user:pass@xn--lck1c3crb1723bpq4a.com/a?a=b#c' + ); -assert.strictEqual( - url.format(myURL, {}), - 'http://user:pass@xn--lck1c3crb1723bpq4a.com/a?a=b#c' -); + assert.strictEqual( + url.format(myURL, {}), + 'http://user:pass@xn--lck1c3crb1723bpq4a.com/a?a=b#c' + ); +}); -{ - [true, 1, 'test', Infinity].forEach((value) => { +test('handle invalid arguments', { skip: !hasIntl }, () => { + for (const value of [true, 1, 'test', Infinity]) { assert.throws( () => url.format(myURL, value), { code: 'ERR_INVALID_ARG_TYPE', name: 'TypeError', - message: 'The "options" argument must be of type object.' + - common.invalidArgTypeHelper(value) } ); - }); -} - -// Any falsy value other than undefined will be treated as false. -// Any truthy value will be treated as true. - -assert.strictEqual( - url.format(myURL, { auth: false }), - 'http://xn--lck1c3crb1723bpq4a.com/a?a=b#c' -); - -assert.strictEqual( - url.format(myURL, { auth: '' }), - 'http://xn--lck1c3crb1723bpq4a.com/a?a=b#c' -); - -assert.strictEqual( - url.format(myURL, { auth: 0 }), - 'http://xn--lck1c3crb1723bpq4a.com/a?a=b#c' -); - -assert.strictEqual( - url.format(myURL, { auth: 1 }), - 'http://user:pass@xn--lck1c3crb1723bpq4a.com/a?a=b#c' -); - -assert.strictEqual( - url.format(myURL, { auth: {} }), - 'http://user:pass@xn--lck1c3crb1723bpq4a.com/a?a=b#c' -); - -assert.strictEqual( - url.format(myURL, { fragment: false }), - 'http://user:pass@xn--lck1c3crb1723bpq4a.com/a?a=b' -); - -assert.strictEqual( - url.format(myURL, { fragment: '' }), - 'http://user:pass@xn--lck1c3crb1723bpq4a.com/a?a=b' -); - -assert.strictEqual( - url.format(myURL, { fragment: 0 }), - 'http://user:pass@xn--lck1c3crb1723bpq4a.com/a?a=b' -); - -assert.strictEqual( - url.format(myURL, { fragment: 1 }), - 'http://user:pass@xn--lck1c3crb1723bpq4a.com/a?a=b#c' -); - -assert.strictEqual( - url.format(myURL, { fragment: {} }), - 'http://user:pass@xn--lck1c3crb1723bpq4a.com/a?a=b#c' -); - -assert.strictEqual( - url.format(myURL, { search: false }), - 'http://user:pass@xn--lck1c3crb1723bpq4a.com/a#c' -); - -assert.strictEqual( - url.format(myURL, { search: '' }), - 'http://user:pass@xn--lck1c3crb1723bpq4a.com/a#c' -); - -assert.strictEqual( - url.format(myURL, { search: 0 }), - 'http://user:pass@xn--lck1c3crb1723bpq4a.com/a#c' -); - -assert.strictEqual( - url.format(myURL, { search: 1 }), - 'http://user:pass@xn--lck1c3crb1723bpq4a.com/a?a=b#c' -); - -assert.strictEqual( - url.format(myURL, { search: {} }), - 'http://user:pass@xn--lck1c3crb1723bpq4a.com/a?a=b#c' -); - -assert.strictEqual( - url.format(myURL, { unicode: true }), - 'http://user:pass@理容ナカムラ.com/a?a=b#c' -); - -assert.strictEqual( - url.format(myURL, { unicode: 1 }), - 'http://user:pass@理容ナカムラ.com/a?a=b#c' -); - -assert.strictEqual( - url.format(myURL, { unicode: {} }), - 'http://user:pass@理容ナカムラ.com/a?a=b#c' -); - -assert.strictEqual( - url.format(myURL, { unicode: false }), - 'http://user:pass@xn--lck1c3crb1723bpq4a.com/a?a=b#c' -); - -assert.strictEqual( - url.format(myURL, { unicode: 0 }), - 'http://user:pass@xn--lck1c3crb1723bpq4a.com/a?a=b#c' -); - -assert.strictEqual( - url.format(new URL('http://user:pass@xn--0zwm56d.com:8080/path'), { unicode: true }), - 'http://user:pass@测试.com:8080/path' -); - -assert.strictEqual( - url.format(new URL('tel:123')), - url.format(new URL('tel:123'), { unicode: true }) -); + } +}); + +test('any falsy value other than undefined will be treated as false', { skip: !hasIntl }, () => { + assert.strictEqual( + url.format(myURL, { auth: false }), + 'http://xn--lck1c3crb1723bpq4a.com/a?a=b#c' + ); + + assert.strictEqual( + url.format(myURL, { auth: '' }), + 'http://xn--lck1c3crb1723bpq4a.com/a?a=b#c' + ); + + assert.strictEqual( + url.format(myURL, { auth: 0 }), + 'http://xn--lck1c3crb1723bpq4a.com/a?a=b#c' + ); + + assert.strictEqual( + url.format(myURL, { auth: 1 }), + 'http://user:pass@xn--lck1c3crb1723bpq4a.com/a?a=b#c' + ); + + assert.strictEqual( + url.format(myURL, { auth: {} }), + 'http://user:pass@xn--lck1c3crb1723bpq4a.com/a?a=b#c' + ); + + assert.strictEqual( + url.format(myURL, { fragment: false }), + 'http://user:pass@xn--lck1c3crb1723bpq4a.com/a?a=b' + ); + + assert.strictEqual( + url.format(myURL, { fragment: '' }), + 'http://user:pass@xn--lck1c3crb1723bpq4a.com/a?a=b' + ); + + assert.strictEqual( + url.format(myURL, { fragment: 0 }), + 'http://user:pass@xn--lck1c3crb1723bpq4a.com/a?a=b' + ); + + assert.strictEqual( + url.format(myURL, { fragment: 1 }), + 'http://user:pass@xn--lck1c3crb1723bpq4a.com/a?a=b#c' + ); + + assert.strictEqual( + url.format(myURL, { fragment: {} }), + 'http://user:pass@xn--lck1c3crb1723bpq4a.com/a?a=b#c' + ); + + assert.strictEqual( + url.format(myURL, { search: false }), + 'http://user:pass@xn--lck1c3crb1723bpq4a.com/a#c' + ); + + assert.strictEqual( + url.format(myURL, { search: '' }), + 'http://user:pass@xn--lck1c3crb1723bpq4a.com/a#c' + ); + + assert.strictEqual( + url.format(myURL, { search: 0 }), + 'http://user:pass@xn--lck1c3crb1723bpq4a.com/a#c' + ); + + assert.strictEqual( + url.format(myURL, { search: 1 }), + 'http://user:pass@xn--lck1c3crb1723bpq4a.com/a?a=b#c' + ); + + assert.strictEqual( + url.format(myURL, { search: {} }), + 'http://user:pass@xn--lck1c3crb1723bpq4a.com/a?a=b#c' + ); + + assert.strictEqual( + url.format(myURL, { unicode: true }), + 'http://user:pass@理容ナカムラ.com/a?a=b#c' + ); + + assert.strictEqual( + url.format(myURL, { unicode: 1 }), + 'http://user:pass@理容ナカムラ.com/a?a=b#c' + ); + + assert.strictEqual( + url.format(myURL, { unicode: {} }), + 'http://user:pass@理容ナカムラ.com/a?a=b#c' + ); + + assert.strictEqual( + url.format(myURL, { unicode: false }), + 'http://user:pass@xn--lck1c3crb1723bpq4a.com/a?a=b#c' + ); + + assert.strictEqual( + url.format(myURL, { unicode: 0 }), + 'http://user:pass@xn--lck1c3crb1723bpq4a.com/a?a=b#c' + ); +}); + +test('should format with unicode: true', { skip: !hasIntl }, () => { + assert.strictEqual( + url.format(new URL('http://user:pass@xn--0zwm56d.com:8080/path'), { unicode: true }), + 'http://user:pass@测试.com:8080/path' + ); +}); + +test('should format tel: prefix', { skip: !hasIntl }, () => { + assert.strictEqual( + url.format(new URL('tel:123')), + url.format(new URL('tel:123'), { unicode: true }) + ); +}); diff --git a/test/parallel/test-url-format.js b/test/parallel/test-url-format.js index 883d060ac2a..4de8f51ef27 100644 --- a/test/parallel/test-url-format.js +++ b/test/parallel/test-url-format.js @@ -1,277 +1,278 @@ 'use strict'; -const common = require('../common'); -const assert = require('assert'); -const url = require('url'); -if (!common.hasIntl) - common.skip('missing Intl'); +const { hasIntl } = require('../common'); -// Formatting tests to verify that it'll format slightly wonky content to a -// valid URL. -const formatTests = { - 'http://example.com?': { - href: 'http://example.com/?', - protocol: 'http:', - slashes: true, - host: 'example.com', - hostname: 'example.com', - search: '?', - query: {}, - pathname: '/' - }, - 'http://example.com?foo=bar#frag': { - href: 'http://example.com/?foo=bar#frag', - protocol: 'http:', - host: 'example.com', - hostname: 'example.com', - hash: '#frag', - search: '?foo=bar', - query: 'foo=bar', - pathname: '/' - }, - 'http://example.com?foo=@bar#frag': { - href: 'http://example.com/?foo=@bar#frag', - protocol: 'http:', - host: 'example.com', - hostname: 'example.com', - hash: '#frag', - search: '?foo=@bar', - query: 'foo=@bar', - pathname: '/' - }, - 'http://example.com?foo=/bar/#frag': { - href: 'http://example.com/?foo=/bar/#frag', - protocol: 'http:', - host: 'example.com', - hostname: 'example.com', - hash: '#frag', - search: '?foo=/bar/', - query: 'foo=/bar/', - pathname: '/' - }, - 'http://example.com?foo=?bar/#frag': { - href: 'http://example.com/?foo=?bar/#frag', - protocol: 'http:', - host: 'example.com', - hostname: 'example.com', - hash: '#frag', - search: '?foo=?bar/', - query: 'foo=?bar/', - pathname: '/' - }, - 'http://example.com#frag=?bar/#frag': { - href: 'http://example.com/#frag=?bar/#frag', - protocol: 'http:', - host: 'example.com', - hostname: 'example.com', - hash: '#frag=?bar/#frag', - pathname: '/' - }, - 'http://google.com" onload="alert(42)/': { - href: 'http://google.com/%22%20onload=%22alert(42)/', - protocol: 'http:', - host: 'google.com', - pathname: '/%22%20onload=%22alert(42)/' - }, - 'http://a.com/a/b/c?s#h': { - href: 'http://a.com/a/b/c?s#h', - protocol: 'http', - host: 'a.com', - pathname: 'a/b/c', - hash: 'h', - search: 's' - }, - 'xmpp:isaacschlueter@jabber.org': { - href: 'xmpp:isaacschlueter@jabber.org', - protocol: 'xmpp:', - host: 'jabber.org', - auth: 'isaacschlueter', - hostname: 'jabber.org' - }, - 'http://atpass:foo%40bar@127.0.0.1/': { - href: 'http://atpass:foo%40bar@127.0.0.1/', - auth: 'atpass:foo@bar', - hostname: '127.0.0.1', - protocol: 'http:', - pathname: '/' - }, - 'http://atslash%2F%40:%2F%40@foo/': { - href: 'http://atslash%2F%40:%2F%40@foo/', - auth: 'atslash/@:/@', - hostname: 'foo', - protocol: 'http:', - pathname: '/' - }, - 'svn+ssh://foo/bar': { - href: 'svn+ssh://foo/bar', - hostname: 'foo', - protocol: 'svn+ssh:', - pathname: '/bar', - slashes: true - }, - 'dash-test://foo/bar': { - href: 'dash-test://foo/bar', - hostname: 'foo', - protocol: 'dash-test:', - pathname: '/bar', - slashes: true - }, - 'dash-test:foo/bar': { - href: 'dash-test:foo/bar', - hostname: 'foo', - protocol: 'dash-test:', - pathname: '/bar' - }, - 'dot.test://foo/bar': { - href: 'dot.test://foo/bar', - hostname: 'foo', - protocol: 'dot.test:', - pathname: '/bar', - slashes: true - }, - 'dot.test:foo/bar': { - href: 'dot.test:foo/bar', - hostname: 'foo', - protocol: 'dot.test:', - pathname: '/bar' - }, - // IPv6 support - 'coap:u:p@[::1]:61616/.well-known/r?n=Temperature': { - href: 'coap:u:p@[::1]:61616/.well-known/r?n=Temperature', - protocol: 'coap:', - auth: 'u:p', - hostname: '::1', - port: '61616', - pathname: '/.well-known/r', - search: 'n=Temperature' - }, - 'coap:[fedc:ba98:7654:3210:fedc:ba98:7654:3210]:61616/s/stopButton': { - href: 'coap:[fedc:ba98:7654:3210:fedc:ba98:7654:3210]:61616/s/stopButton', - protocol: 'coap', - host: '[fedc:ba98:7654:3210:fedc:ba98:7654:3210]:61616', - pathname: '/s/stopButton' - }, - 'http://[::]/': { - href: 'http://[::]/', - protocol: 'http:', - hostname: '[::]', - pathname: '/' - }, +const assert = require('node:assert'); +const url = require('node:url'); +const { test } = require('node:test'); - // Encode context-specific delimiters in path and query, but do not touch - // other non-delimiter chars like `%`. - // +test('format slightly wonky content to a valid URL', { skip: !hasIntl }, () => { + const formatTests = { + 'http://example.com?': { + href: 'http://example.com/?', + protocol: 'http:', + slashes: true, + host: 'example.com', + hostname: 'example.com', + search: '?', + query: {}, + pathname: '/' + }, + 'http://example.com?foo=bar#frag': { + href: 'http://example.com/?foo=bar#frag', + protocol: 'http:', + host: 'example.com', + hostname: 'example.com', + hash: '#frag', + search: '?foo=bar', + query: 'foo=bar', + pathname: '/' + }, + 'http://example.com?foo=@bar#frag': { + href: 'http://example.com/?foo=@bar#frag', + protocol: 'http:', + host: 'example.com', + hostname: 'example.com', + hash: '#frag', + search: '?foo=@bar', + query: 'foo=@bar', + pathname: '/' + }, + 'http://example.com?foo=/bar/#frag': { + href: 'http://example.com/?foo=/bar/#frag', + protocol: 'http:', + host: 'example.com', + hostname: 'example.com', + hash: '#frag', + search: '?foo=/bar/', + query: 'foo=/bar/', + pathname: '/' + }, + 'http://example.com?foo=?bar/#frag': { + href: 'http://example.com/?foo=?bar/#frag', + protocol: 'http:', + host: 'example.com', + hostname: 'example.com', + hash: '#frag', + search: '?foo=?bar/', + query: 'foo=?bar/', + pathname: '/' + }, + 'http://example.com#frag=?bar/#frag': { + href: 'http://example.com/#frag=?bar/#frag', + protocol: 'http:', + host: 'example.com', + hostname: 'example.com', + hash: '#frag=?bar/#frag', + pathname: '/' + }, + 'http://google.com" onload="alert(42)/': { + href: 'http://google.com/%22%20onload=%22alert(42)/', + protocol: 'http:', + host: 'google.com', + pathname: '/%22%20onload=%22alert(42)/' + }, + 'http://a.com/a/b/c?s#h': { + href: 'http://a.com/a/b/c?s#h', + protocol: 'http', + host: 'a.com', + pathname: 'a/b/c', + hash: 'h', + search: 's' + }, + 'xmpp:isaacschlueter@jabber.org': { + href: 'xmpp:isaacschlueter@jabber.org', + protocol: 'xmpp:', + host: 'jabber.org', + auth: 'isaacschlueter', + hostname: 'jabber.org' + }, + 'http://atpass:foo%40bar@127.0.0.1/': { + href: 'http://atpass:foo%40bar@127.0.0.1/', + auth: 'atpass:foo@bar', + hostname: '127.0.0.1', + protocol: 'http:', + pathname: '/' + }, + 'http://atslash%2F%40:%2F%40@foo/': { + href: 'http://atslash%2F%40:%2F%40@foo/', + auth: 'atslash/@:/@', + hostname: 'foo', + protocol: 'http:', + pathname: '/' + }, + 'svn+ssh://foo/bar': { + href: 'svn+ssh://foo/bar', + hostname: 'foo', + protocol: 'svn+ssh:', + pathname: '/bar', + slashes: true + }, + 'dash-test://foo/bar': { + href: 'dash-test://foo/bar', + hostname: 'foo', + protocol: 'dash-test:', + pathname: '/bar', + slashes: true + }, + 'dash-test:foo/bar': { + href: 'dash-test:foo/bar', + hostname: 'foo', + protocol: 'dash-test:', + pathname: '/bar' + }, + 'dot.test://foo/bar': { + href: 'dot.test://foo/bar', + hostname: 'foo', + protocol: 'dot.test:', + pathname: '/bar', + slashes: true + }, + 'dot.test:foo/bar': { + href: 'dot.test:foo/bar', + hostname: 'foo', + protocol: 'dot.test:', + pathname: '/bar' + }, + // IPv6 support + 'coap:u:p@[::1]:61616/.well-known/r?n=Temperature': { + href: 'coap:u:p@[::1]:61616/.well-known/r?n=Temperature', + protocol: 'coap:', + auth: 'u:p', + hostname: '::1', + port: '61616', + pathname: '/.well-known/r', + search: 'n=Temperature' + }, + 'coap:[fedc:ba98:7654:3210:fedc:ba98:7654:3210]:61616/s/stopButton': { + href: 'coap:[fedc:ba98:7654:3210:fedc:ba98:7654:3210]:61616/s/stopButton', + protocol: 'coap', + host: '[fedc:ba98:7654:3210:fedc:ba98:7654:3210]:61616', + pathname: '/s/stopButton' + }, + 'http://[::]/': { + href: 'http://[::]/', + protocol: 'http:', + hostname: '[::]', + pathname: '/' + }, + + // Encode context-specific delimiters in path and query, but do not touch + // other non-delimiter chars like `%`. + // - // `#`,`?` in path - '/path/to/%%23%3F+=&.txt?foo=theA1#bar': { - href: '/path/to/%%23%3F+=&.txt?foo=theA1#bar', - pathname: '/path/to/%#?+=&.txt', - query: { - foo: 'theA1' + // `#`,`?` in path + '/path/to/%%23%3F+=&.txt?foo=theA1#bar': { + href: '/path/to/%%23%3F+=&.txt?foo=theA1#bar', + pathname: '/path/to/%#?+=&.txt', + query: { + foo: 'theA1' + }, + hash: '#bar' }, - hash: '#bar' - }, - // `#`,`?` in path + `#` in query - '/path/to/%%23%3F+=&.txt?foo=the%231#bar': { - href: '/path/to/%%23%3F+=&.txt?foo=the%231#bar', - pathname: '/path/to/%#?+=&.txt', - query: { - foo: 'the#1' + // `#`,`?` in path + `#` in query + '/path/to/%%23%3F+=&.txt?foo=the%231#bar': { + href: '/path/to/%%23%3F+=&.txt?foo=the%231#bar', + pathname: '/path/to/%#?+=&.txt', + query: { + foo: 'the#1' + }, + hash: '#bar' }, - hash: '#bar' - }, - // `#` in path end + `#` in query - '/path/to/%%23?foo=the%231#bar': { - href: '/path/to/%%23?foo=the%231#bar', - pathname: '/path/to/%#', - query: { - foo: 'the#1' + // `#` in path end + `#` in query + '/path/to/%%23?foo=the%231#bar': { + href: '/path/to/%%23?foo=the%231#bar', + pathname: '/path/to/%#', + query: { + foo: 'the#1' + }, + hash: '#bar' }, - hash: '#bar' - }, - // `?` and `#` in path and search - 'http://ex.com/foo%3F100%m%23r?abc=the%231?&foo=bar#frag': { - href: 'http://ex.com/foo%3F100%m%23r?abc=the%231?&foo=bar#frag', - protocol: 'http:', - hostname: 'ex.com', - hash: '#frag', - search: '?abc=the#1?&foo=bar', - pathname: '/foo?100%m#r', - }, + // `?` and `#` in path and search + 'http://ex.com/foo%3F100%m%23r?abc=the%231?&foo=bar#frag': { + href: 'http://ex.com/foo%3F100%m%23r?abc=the%231?&foo=bar#frag', + protocol: 'http:', + hostname: 'ex.com', + hash: '#frag', + search: '?abc=the#1?&foo=bar', + pathname: '/foo?100%m#r', + }, - // `?` and `#` in search only - 'http://ex.com/fooA100%mBr?abc=the%231?&foo=bar#frag': { - href: 'http://ex.com/fooA100%mBr?abc=the%231?&foo=bar#frag', - protocol: 'http:', - hostname: 'ex.com', - hash: '#frag', - search: '?abc=the#1?&foo=bar', - pathname: '/fooA100%mBr', - }, + // `?` and `#` in search only + 'http://ex.com/fooA100%mBr?abc=the%231?&foo=bar#frag': { + href: 'http://ex.com/fooA100%mBr?abc=the%231?&foo=bar#frag', + protocol: 'http:', + hostname: 'ex.com', + hash: '#frag', + search: '?abc=the#1?&foo=bar', + pathname: '/fooA100%mBr', + }, + + // Multiple `#` in search + 'http://example.com/?foo=bar%231%232%233&abc=%234%23%235#frag': { + href: 'http://example.com/?foo=bar%231%232%233&abc=%234%23%235#frag', + protocol: 'http:', + slashes: true, + host: 'example.com', + hostname: 'example.com', + hash: '#frag', + search: '?foo=bar#1#2#3&abc=#4##5', + query: {}, + pathname: '/' + }, - // Multiple `#` in search - 'http://example.com/?foo=bar%231%232%233&abc=%234%23%235#frag': { - href: 'http://example.com/?foo=bar%231%232%233&abc=%234%23%235#frag', - protocol: 'http:', - slashes: true, - host: 'example.com', - hostname: 'example.com', - hash: '#frag', - search: '?foo=bar#1#2#3&abc=#4##5', - query: {}, - pathname: '/' - }, + // More than 255 characters in hostname which exceeds the limit + [`http://${'a'.repeat(255)}.com/node`]: { + href: 'http:///node', + protocol: 'http:', + slashes: true, + host: '', + hostname: '', + pathname: '/node', + path: '/node' + }, - // More than 255 characters in hostname which exceeds the limit - [`http://${'a'.repeat(255)}.com/node`]: { - href: 'http:///node', - protocol: 'http:', - slashes: true, - host: '', - hostname: '', - pathname: '/node', - path: '/node' - }, + // Greater than or equal to 63 characters after `.` in hostname + [`http://www.${'z'.repeat(63)}example.com/node`]: { + href: `http://www.${'z'.repeat(63)}example.com/node`, + protocol: 'http:', + slashes: true, + host: `www.${'z'.repeat(63)}example.com`, + hostname: `www.${'z'.repeat(63)}example.com`, + pathname: '/node', + path: '/node' + }, - // Greater than or equal to 63 characters after `.` in hostname - [`http://www.${'z'.repeat(63)}example.com/node`]: { - href: `http://www.${'z'.repeat(63)}example.com/node`, - protocol: 'http:', - slashes: true, - host: `www.${'z'.repeat(63)}example.com`, - hostname: `www.${'z'.repeat(63)}example.com`, - pathname: '/node', - path: '/node' - }, + // https://github.com/nodejs/node/issues/3361 + 'file:///home/user': { + href: 'file:///home/user', + protocol: 'file', + pathname: '/home/user', + path: '/home/user' + }, - // https://github.com/nodejs/node/issues/3361 - 'file:///home/user': { - href: 'file:///home/user', - protocol: 'file', - pathname: '/home/user', - path: '/home/user' - }, + // surrogate in auth + 'http://%F0%9F%98%80@www.example.com/': { + href: 'http://%F0%9F%98%80@www.example.com/', + protocol: 'http:', + auth: '\uD83D\uDE00', + hostname: 'www.example.com', + pathname: '/' + } + }; - // surrogate in auth - 'http://%F0%9F%98%80@www.example.com/': { - href: 'http://%F0%9F%98%80@www.example.com/', - protocol: 'http:', - auth: '\uD83D\uDE00', - hostname: 'www.example.com', - pathname: '/' + for (const u in formatTests) { + const expect = formatTests[u].href; + delete formatTests[u].href; + const actual = url.format(u); + const actualObj = url.format(formatTests[u]); + assert.strictEqual(actual, expect, + `wonky format(${u}) == ${expect}\nactual:${actual}`); + assert.strictEqual(actualObj, expect, + `wonky format(${JSON.stringify(formatTests[u])}) == ${ + expect}\nactual: ${actualObj}`); } -}; -for (const u in formatTests) { - const expect = formatTests[u].href; - delete formatTests[u].href; - const actual = url.format(u); - const actualObj = url.format(formatTests[u]); - assert.strictEqual(actual, expect, - `wonky format(${u}) == ${expect}\nactual:${actual}`); - assert.strictEqual(actualObj, expect, - `wonky format(${JSON.stringify(formatTests[u])}) == ${ - expect}\nactual: ${actualObj}`); -} +}); diff --git a/test/parallel/test-url-is-url-internal.js b/test/parallel/test-url-is-url-internal.js new file mode 100644 index 00000000000..b7b67b637f3 --- /dev/null +++ b/test/parallel/test-url-is-url-internal.js @@ -0,0 +1,19 @@ +// Flags: --expose-internals +'use strict'; + +require('../common'); + +const { URL, parse } = require('node:url'); +const assert = require('node:assert'); +const { isURL } = require('internal/url'); +const { test } = require('node:test'); + +test('isURL', () => { + assert.strictEqual(isURL(new URL('https://www.nodejs.org')), true); + assert.strictEqual(isURL(parse('https://www.nodejs.org')), false); + assert.strictEqual(isURL({ + href: 'https://www.nodejs.org', + protocol: 'https:', + path: '/', + }), false); +}); diff --git a/test/parallel/test-url-is-url.js b/test/parallel/test-url-is-url.js deleted file mode 100644 index 6bb8a1595df..00000000000 --- a/test/parallel/test-url-is-url.js +++ /dev/null @@ -1,16 +0,0 @@ -// Flags: --expose-internals -'use strict'; - -require('../common'); - -const { URL, parse } = require('url'); -const assert = require('assert'); -const { isURL } = require('internal/url'); - -assert.strictEqual(isURL(new URL('https://www.nodejs.org')), true); -assert.strictEqual(isURL(parse('https://www.nodejs.org')), false); -assert.strictEqual(isURL({ - href: 'https://www.nodejs.org', - protocol: 'https:', - path: '/', -}), false); diff --git a/test/parallel/test-url-null-char.js b/test/parallel/test-url-null-char.js deleted file mode 100644 index d81cbcfb664..00000000000 --- a/test/parallel/test-url-null-char.js +++ /dev/null @@ -1,8 +0,0 @@ -'use strict'; -require('../common'); -const assert = require('assert'); - -assert.throws( - () => { new URL('a\0b'); }, - { code: 'ERR_INVALID_URL', input: 'a\0b' } -); diff --git a/test/parallel/test-url-parse-format.js b/test/parallel/test-url-parse-format.js index f8761514a30..4e36e1306d3 100644 --- a/test/parallel/test-url-parse-format.js +++ b/test/parallel/test-url-parse-format.js @@ -1,13 +1,10 @@ 'use strict'; -const common = require('../common'); +const { hasIntl } = require('../common'); -if (!common.hasIntl) - common.skip('missing Intl'); - -const assert = require('assert'); -const inspect = require('util').inspect; - -const url = require('url'); +const assert = require('node:assert'); +const { inspect } = require('node:util'); +const url = require('node:url'); +const { test } = require('node:test'); // URLs to parse, and expected data // { url : parsed } @@ -1025,36 +1022,38 @@ const parseTests = { } }; -for (const u in parseTests) { - let actual = url.parse(u); - const spaced = url.parse(` \t ${u}\n\t`); - let expected = Object.assign(new url.Url(), parseTests[u]); - - Object.keys(actual).forEach(function(i) { - if (expected[i] === undefined && actual[i] === null) { - expected[i] = null; - } - }); +test('should parse and format', { skip: !hasIntl }, () => { + for (const u in parseTests) { + let actual = url.parse(u); + const spaced = url.parse(` \t ${u}\n\t`); + let expected = Object.assign(new url.Url(), parseTests[u]); + + Object.keys(actual).forEach(function(i) { + if (expected[i] === undefined && actual[i] === null) { + expected[i] = null; + } + }); + + assert.deepStrictEqual( + actual, + expected, + `parsing ${u} and expected ${inspect(expected)} but got ${inspect(actual)}` + ); + assert.deepStrictEqual( + spaced, + expected, + `expected ${inspect(expected)}, got ${inspect(spaced)}` + ); + + expected = parseTests[u].href; + actual = url.format(parseTests[u]); + + assert.strictEqual(actual, expected, + `format(${u}) == ${u}\nactual:${actual}`); + } +}); - assert.deepStrictEqual( - actual, - expected, - `parsing ${u} and expected ${inspect(expected)} but got ${inspect(actual)}` - ); - assert.deepStrictEqual( - spaced, - expected, - `expected ${inspect(expected)}, got ${inspect(spaced)}` - ); - - expected = parseTests[u].href; - actual = url.format(parseTests[u]); - - assert.strictEqual(actual, expected, - `format(${u}) == ${u}\nactual:${actual}`); -} - -{ +test('parse result should equal new url.Url()', { skip: !hasIntl }, () => { const parsed = url.parse('http://nodejs.org/') .resolveObject('jAvascript:alert(1);a=\x27@white-listed.com\x27'); @@ -1074,4 +1073,4 @@ for (const u in parseTests) { }); assert.deepStrictEqual(parsed, expected); -} +}); diff --git a/test/parallel/test-url-pathtofileurl.js b/test/parallel/test-url-pathtofileurl.js index abbd6c95cb5..20609eb0ff5 100644 --- a/test/parallel/test-url-pathtofileurl.js +++ b/test/parallel/test-url-pathtofileurl.js @@ -104,8 +104,12 @@ const windowsTestCases = [ { path: 'C:\\€', expected: 'file:///C:/%E2%82%AC' }, // Rocket emoji (non-BMP code point) { path: 'C:\\🚀', expected: 'file:///C:/%F0%9F%9A%80' }, + // Local extended path + { path: '\\\\?\\C:\\path\\to\\file.txt', expected: 'file:///C:/path/to/file.txt' }, // UNC path (see https://docs.microsoft.com/en-us/archive/blogs/ie/file-uris-in-windows) { path: '\\\\nas\\My Docs\\File.doc', expected: 'file://nas/My%20Docs/File.doc' }, + // Extended UNC path + { path: '\\\\?\\UNC\\server\\share\\folder\\file.txt', expected: 'file://server/share/folder/file.txt' }, ]; const posixTestCases = [ // Lowercase ascii alpha diff --git a/test/parallel/util-parse-env.js b/test/parallel/test-util-parse-env.js similarity index 97% rename from test/parallel/util-parse-env.js rename to test/parallel/test-util-parse-env.js index 755bd98f103..13d2fda37a0 100644 --- a/test/parallel/util-parse-env.js +++ b/test/parallel/test-util-parse-env.js @@ -52,6 +52,7 @@ const fs = require('node:fs'); SINGLE_QUOTES_INSIDE_DOUBLE: "single 'quotes' work inside double quotes", SINGLE_QUOTES_SPACED: ' single quotes ', SPACED_KEY: 'parsed', + SPACE_BEFORE_DOUBLE_QUOTES: 'space before double quotes', TRIM_SPACE_FROM_UNQUOTED: 'some spaced out string', }); } diff --git a/test/parallel/test-util-styletext.js b/test/parallel/test-util-styletext.js index 6baa6a60eac..764ce6f1a31 100644 --- a/test/parallel/test-util-styletext.js +++ b/test/parallel/test-util-styletext.js @@ -1,7 +1,12 @@ 'use strict'; -require('../common'); -const assert = require('assert'); -const util = require('util'); + +const common = require('../common'); +const assert = require('node:assert'); +const util = require('node:util'); +const { WriteStream } = require('node:tty'); + +const styled = '\u001b[31mtest\u001b[39m'; +const noChange = 'test'; [ undefined, @@ -31,13 +36,69 @@ assert.throws(() => { code: 'ERR_INVALID_ARG_VALUE', }); -assert.strictEqual(util.styleText('red', 'test'), '\u001b[31mtest\u001b[39m'); +assert.strictEqual( + util.styleText('red', 'test', { validateStream: false }), + '\u001b[31mtest\u001b[39m', +); + +assert.strictEqual( + util.styleText(['bold', 'red'], 'test', { validateStream: false }), + '\u001b[1m\u001b[31mtest\u001b[39m\u001b[22m', +); -assert.strictEqual(util.styleText(['bold', 'red'], 'test'), '\u001b[1m\u001b[31mtest\u001b[39m\u001b[22m'); -assert.strictEqual(util.styleText(['bold', 'red'], 'test'), util.styleText('bold', util.styleText('red', 'test'))); +assert.strictEqual( + util.styleText(['bold', 'red'], 'test', { validateStream: false }), + util.styleText( + 'bold', + util.styleText('red', 'test', { validateStream: false }), + { validateStream: false }, + ), +); assert.throws(() => { util.styleText(['invalid'], 'text'); }, { code: 'ERR_INVALID_ARG_VALUE', }); + +assert.throws(() => { + util.styleText('red', 'text', { stream: {} }); +}, { + code: 'ERR_INVALID_ARG_TYPE', +}); + +// does not throw +util.styleText('red', 'text', { stream: {}, validateStream: false }); + +assert.strictEqual( + util.styleText('red', 'test', { validateStream: false }), + styled, +); + +const fd = common.getTTYfd(); +if (fd !== -1) { + const writeStream = new WriteStream(fd); + + const originalEnv = process.env; + [ + { isTTY: true, env: {}, expected: styled }, + { isTTY: false, env: {}, expected: noChange }, + { isTTY: true, env: { NODE_DISABLE_COLORS: '1' }, expected: noChange }, + { isTTY: true, env: { NO_COLOR: '1' }, expected: noChange }, + { isTTY: true, env: { FORCE_COLOR: '1' }, expected: styled }, + { isTTY: true, env: { FORCE_COLOR: '1', NODE_DISABLE_COLORS: '1' }, expected: styled }, + { isTTY: false, env: { FORCE_COLOR: '1', NO_COLOR: '1', NODE_DISABLE_COLORS: '1' }, expected: styled }, + { isTTY: true, env: { FORCE_COLOR: '1', NO_COLOR: '1', NODE_DISABLE_COLORS: '1' }, expected: styled }, + ].forEach((testCase) => { + writeStream.isTTY = testCase.isTTY; + process.env = { + ...process.env, + ...testCase.env + }; + const output = util.styleText('red', 'test', { stream: writeStream }); + assert.strictEqual(output, testCase.expected); + process.env = originalEnv; + }); +} else { + common.skip('Could not create TTY fd'); +} diff --git a/test/parallel/test-v8-serialize-leak.js b/test/parallel/test-v8-serialize-leak.js index ce0a06196e9..dd51a879eff 100644 --- a/test/parallel/test-v8-serialize-leak.js +++ b/test/parallel/test-v8-serialize-leak.js @@ -2,6 +2,7 @@ // Flags: --expose-gc const common = require('../common'); +const { gcUntil } = require('../common/gc'); // On IBMi, the rss memory always returns zero if (common.isIBMi) @@ -16,7 +17,7 @@ for (let i = 0; i < 1000000; i++) { } async function main() { - await common.gcUntil('RSS should go down', () => { + await gcUntil('RSS should go down', () => { const after = process.memoryUsage.rss(); if (common.isASan) { console.log(`ASan: before=${before} after=${after}`); diff --git a/test/parallel/test-vm-context-dont-contextify.js b/test/parallel/test-vm-context-dont-contextify.js new file mode 100644 index 00000000000..6cbd62e8947 --- /dev/null +++ b/test/parallel/test-vm-context-dont-contextify.js @@ -0,0 +1,185 @@ +'use strict'; + +// Check vm.constants.DONT_CONTEXTIFY works. + +const common = require('../common'); + +const assert = require('assert'); +const vm = require('vm'); +const fixtures = require('../common/fixtures'); + +{ + // Check identity of the returned object. + const context = vm.createContext(vm.constants.DONT_CONTEXTIFY); + // The globalThis in the new context should be reference equal to the returned object. + assert.strictEqual(vm.runInContext('globalThis', context), context); + assert(vm.isContext(context)); + assert.strictEqual(typeof context.Array, 'function'); // Can access builtins directly. + assert.deepStrictEqual(Object.keys(context), []); // Properties on the global proxy are not enumerable +} + +{ + // Check that vm.createContext can return the original context if re-passed. + const context = vm.createContext(vm.constants.DONT_CONTEXTIFY); + const context2 = new vm.createContext(context); + assert.strictEqual(context, context2); +} + +{ + // Check that the context is vanilla and that Script.runInContext works. + const context = vm.createContext(vm.constants.DONT_CONTEXTIFY); + const result = + new vm.Script('globalThis.hey = 1; Object.freeze(globalThis); globalThis.process') + .runInContext(context); + assert.strictEqual(globalThis.hey, undefined); // Should not leak into current context. + assert.strictEqual(result, undefined); // Vanilla context has no Node.js globals +} + +{ + // Check Script.runInNewContext works. + const result = + new vm.Script('globalThis.hey = 1; Object.freeze(globalThis); globalThis.process') + .runInNewContext(vm.constants.DONT_CONTEXTIFY); + assert.strictEqual(globalThis.hey, undefined); // Should not leak into current context. + assert.strictEqual(result, undefined); // Vanilla context has no Node.js globals +} + +{ + // Check that vm.runInNewContext() works + const result = vm.runInNewContext( + 'globalThis.hey = 1; Object.freeze(globalThis); globalThis.process', + vm.constants.DONT_CONTEXTIFY); + assert.strictEqual(globalThis.hey, undefined); // Should not leak into current context. + assert.strictEqual(result, undefined); // Vanilla context has no Node.js globals +} + +{ + // Check that the global object of vanilla contexts work as expected. + const context = vm.createContext(vm.constants.DONT_CONTEXTIFY); + + // Check mutation via globalThis. + vm.runInContext('globalThis.foo = 1;', context); + assert.strictEqual(globalThis.foo, undefined); // Should not pollute the current context. + assert.strictEqual(context.foo, 1); + assert.strictEqual(vm.runInContext('globalThis.foo', context), 1); + assert.strictEqual(vm.runInContext('foo', context), 1); + + // Check mutation from outside. + context.foo = 2; + assert.strictEqual(context.foo, 2); + assert.strictEqual(vm.runInContext('globalThis.foo', context), 2); + assert.strictEqual(vm.runInContext('foo', context), 2); + + // Check contextual mutation. + vm.runInContext('bar = 1;', context); + assert.strictEqual(globalThis.bar, undefined); // Should not pollute the current context. + assert.strictEqual(context.bar, 1); + assert.strictEqual(vm.runInContext('globalThis.bar', context), 1); + assert.strictEqual(vm.runInContext('bar', context), 1); + + // Check adding new property from outside. + context.baz = 1; + assert.strictEqual(context.baz, 1); + assert.strictEqual(vm.runInContext('globalThis.baz', context), 1); + assert.strictEqual(vm.runInContext('baz', context), 1); + + // Check mutation via Object.defineProperty(). + vm.runInContext('Object.defineProperty(globalThis, "qux", {' + + 'enumerable: false, configurable: false, get() { return 1; } })', context); + assert.strictEqual(globalThis.qux, undefined); // Should not pollute the current context. + assert.strictEqual(context.qux, 1); + assert.strictEqual(vm.runInContext('qux', context), 1); + const desc = Object.getOwnPropertyDescriptor(context, 'qux'); + assert.strictEqual(desc.enumerable, false); + assert.strictEqual(desc.configurable, false); + assert.strictEqual(typeof desc.get, 'function'); + assert.throws(() => { context.qux = 1; }, { name: 'TypeError' }); + assert.throws(() => { Object.defineProperty(context, 'qux', { value: 1 }); }, { name: 'TypeError' }); + // Setting a value without a setter fails silently. + assert.strictEqual(vm.runInContext('qux = 2; qux', context), 1); + assert.throws(() => { + vm.runInContext('Object.defineProperty(globalThis, "qux", { value: 1 });'); + }, { name: 'TypeError' }); +} + +function checkFrozen(context) { + // Check mutation via globalThis. + vm.runInContext('globalThis.foo = 1', context); // Invoking setters on freezed object fails silently. + assert.strictEqual(context.foo, undefined); + assert.strictEqual(vm.runInContext('globalThis.foo', context), undefined); + assert.throws(() => { + vm.runInContext('foo', context); // It should not be looked up contextually. + }, { + name: 'ReferenceError' + }); + + // Check mutation from outside. + assert.throws(() => { + context.foo = 2; + }, { name: 'TypeError' }); + assert.strictEqual(context.foo, undefined); + assert.strictEqual(vm.runInContext('globalThis.foo', context), undefined); + assert.throws(() => { + vm.runInContext('foo', context); // It should not be looked up contextually. + }, { + name: 'ReferenceError' + }); + + // Check contextual mutation. + vm.runInContext('bar = 1', context); // Invoking setters on freezed object fails silently. + assert.strictEqual(context.bar, undefined); + assert.strictEqual(vm.runInContext('globalThis.bar', context), undefined); + assert.throws(() => { + vm.runInContext('bar', context); // It should not be looked up contextually. + }, { + name: 'ReferenceError' + }); + + // Check mutation via Object.defineProperty(). + assert.throws(() => { + vm.runInContext('Object.defineProperty(globalThis, "qux", {' + + 'enumerable: false, configurable: false, get() { return 1; } })', context); + }, { + name: 'TypeError' + }); + assert.strictEqual(context.qux, undefined); + assert.strictEqual(vm.runInContext('globalThis.qux', context), undefined); + assert.strictEqual(Object.getOwnPropertyDescriptor(context, 'qux'), undefined); + assert.throws(() => { Object.defineProperty(context, 'qux', { value: 1 }); }, { name: 'TypeError' }); + assert.throws(() => { + vm.runInContext('qux', context); + }, { + name: 'ReferenceError' + }); +} + +{ + // Check freezing the vanilla context's global object from within the context. + const context = vm.createContext(vm.constants.DONT_CONTEXTIFY); + // Only vanilla contexts' globals can be freezed. Contextified global objects cannot be freezed + // due to the presence of interceptors. + vm.runInContext('Object.freeze(globalThis)', context); + checkFrozen(context); +} + +{ + // Check freezing the vanilla context's global object from outside the context. + const context = vm.createContext(vm.constants.DONT_CONTEXTIFY); + Object.freeze(context); + checkFrozen(context); +} + +// Check importModuleDynamically works. +(async function() { + { + const moduleUrl = fixtures.fileURL('es-modules', 'message.mjs'); + const namespace = await import(moduleUrl.href); + // Check dynamic import works + const context = vm.createContext(vm.constants.DONT_CONTEXTIFY); + const script = new vm.Script(`import('${encodeURI(moduleUrl.href)}')`, { + importModuleDynamically: vm.constants.USE_MAIN_CONTEXT_DEFAULT_LOADER, + }); + const promise = script.runInContext(context); + assert.strictEqual(await promise, namespace); + } +})().catch(common.mustNotCall()); diff --git a/test/parallel/test-vm-module-basic.js b/test/parallel/test-vm-module-basic.js index b563fd6de2b..cba1e037ac4 100644 --- a/test/parallel/test-vm-module-basic.js +++ b/test/parallel/test-vm-module-basic.js @@ -84,13 +84,15 @@ const util = require('util'); assert.strictEqual(util.inspect(m, { depth: -1 }), '[SourceTextModule]'); - assert.throws( - () => m[util.inspect.custom].call({ __proto__: null }), - { - code: 'ERR_VM_MODULE_NOT_MODULE', - message: 'Provided module is not an instance of Module' - }, - ); + for (const value of [null, { __proto__: null }, SourceTextModule.prototype]) { + assert.throws( + () => m[util.inspect.custom].call(value), + { + code: 'ERR_INVALID_ARG_TYPE', + message: /The "this" argument must be an instance of Module/, + }, + ); + } } { diff --git a/test/parallel/test-vm-module-errors.js b/test/parallel/test-vm-module-errors.js index bec8258a414..ad247f83edc 100644 --- a/test/parallel/test-vm-module-errors.js +++ b/test/parallel/test-vm-module-errors.js @@ -216,8 +216,8 @@ async function checkInvalidOptionForEvaluate() { await assert.rejects(async () => { await Module.prototype[method](); }, { - code: 'ERR_VM_MODULE_NOT_MODULE', - message: /Provided module is not an instance of Module/ + code: 'ERR_INVALID_ARG_TYPE', + message: /The "this" argument must be an instance of Module/ }); }); } @@ -241,8 +241,8 @@ function checkInvalidCachedData() { function checkGettersErrors() { const expectedError = { - code: 'ERR_VM_MODULE_NOT_MODULE', - message: /Provided module is not an instance of Module/ + code: 'ERR_INVALID_ARG_TYPE', + message: /The "this" argument must be an instance of (?:Module|SourceTextModule)/, }; const getters = ['identifier', 'context', 'namespace', 'status', 'error']; getters.forEach((getter) => { diff --git a/test/parallel/test-vm-module-link.js b/test/parallel/test-vm-module-link.js index 6b19a4d4916..26dcb69885b 100644 --- a/test/parallel/test-vm-module-link.js +++ b/test/parallel/test-vm-module-link.js @@ -28,6 +28,22 @@ async function simple() { delete globalThis.fiveResult; } +async function invalidLinkValue() { + const invalidValues = [ + undefined, + null, + {}, + SourceTextModule.prototype, + ]; + + for (const value of invalidValues) { + const module = new SourceTextModule('import "foo"'); + await assert.rejects(module.link(() => value), { + code: 'ERR_VM_MODULE_NOT_MODULE', + }); + } +} + async function depth() { const foo = new SourceTextModule('export default 5'); await foo.link(common.mustNotCall()); @@ -143,6 +159,7 @@ const finished = common.mustCall(); (async function main() { await simple(); + await invalidLinkValue(); await depth(); await circular(); await circular2(); diff --git a/test/parallel/test-vm-module-synthetic.js b/test/parallel/test-vm-module-synthetic.js index 9d1c07ead5c..48e4ed6b132 100644 --- a/test/parallel/test-vm-module-synthetic.js +++ b/test/parallel/test-vm-module-synthetic.js @@ -66,12 +66,12 @@ const assert = require('assert'); }); } - { + for (const value of [null, {}, SyntheticModule.prototype]) { assert.throws(() => { - SyntheticModule.prototype.setExport.call({}, 'foo'); + SyntheticModule.prototype.setExport.call(value, 'foo'); }, { - code: 'ERR_VM_MODULE_NOT_MODULE', - message: /Provided module is not an instance of Module/ + code: 'ERR_INVALID_ARG_TYPE', + message: /The "this" argument must be an instance of SyntheticModule/ }); } diff --git a/test/parallel/test-webstream-readable-from.js b/test/parallel/test-webstream-readable-from.js new file mode 100644 index 00000000000..470ee5d60d7 --- /dev/null +++ b/test/parallel/test-webstream-readable-from.js @@ -0,0 +1,9 @@ +'use strict'; + +require('../common'); +const assert = require('node:assert'); + +assert.throws( + () => ReadableStream.from({}), + { code: 'ERR_ARG_NOT_ITERABLE', name: 'TypeError' }, +); diff --git a/test/parallel/test-whatwg-readablestream.js b/test/parallel/test-whatwg-readablestream.js index 122500a3cfe..9af751ddd02 100644 --- a/test/parallel/test-whatwg-readablestream.js +++ b/test/parallel/test-whatwg-readablestream.js @@ -1701,3 +1701,50 @@ class Source { assert.deepStrictEqual(value, new Uint8Array([1, 1, 1])); })); } + +// Initial Pull Delay +{ + const stream = new ReadableStream({ + start(controller) { + controller.enqueue('data'); + controller.close(); + } + }); + + const iterator = stream.values(); + + let microtaskCompleted = false; + Promise.resolve().then(() => { microtaskCompleted = true; }); + + iterator.next().then(common.mustCall(({ done, value }) => { + assert.strictEqual(done, false); + assert.strictEqual(value, 'data'); + assert.strictEqual(microtaskCompleted, true); + })); +} + +// Avoiding Prototype Pollution +{ + const stream = new ReadableStream({ + start(controller) { + controller.enqueue('data'); + controller.close(); + } + }); + + const iterator = stream.values(); + + // Modify Promise.prototype.then to simulate prototype pollution + const originalThen = Promise.prototype.then; + Promise.prototype.then = function(onFulfilled, onRejected) { + return originalThen.call(this, onFulfilled, onRejected); + }; + + iterator.next().then(common.mustCall(({ done, value }) => { + assert.strictEqual(done, false); + assert.strictEqual(value, 'data'); + + // Restore original then method + Promise.prototype.then = originalThen; + })); +} diff --git a/test/parallel/test-worker-arraybuffer-zerofill.js b/test/parallel/test-worker-arraybuffer-zerofill.js deleted file mode 100644 index 3dcf4c006eb..00000000000 --- a/test/parallel/test-worker-arraybuffer-zerofill.js +++ /dev/null @@ -1,33 +0,0 @@ -'use strict'; -require('../common'); -const assert = require('assert'); -const { Worker } = require('worker_threads'); - -// Make sure that allocating uninitialized ArrayBuffers in one thread does not -// affect the zero-initialization in other threads. - -const w = new Worker(` -const { parentPort } = require('worker_threads'); - -function post() { - const uint32array = new Uint32Array(64); - parentPort.postMessage(uint32array.reduce((a, b) => a + b)); -} - -setInterval(post, 0); -`, { eval: true }); - -function allocBuffers() { - Buffer.allocUnsafe(32 * 1024 * 1024); -} - -const interval = setInterval(allocBuffers, 0); - -let messages = 0; -w.on('message', (sum) => { - assert.strictEqual(sum, 0); - if (messages++ === 100) { - clearInterval(interval); - w.terminate(); - } -}); diff --git a/test/parallel/test-worker-cli-options.js b/test/parallel/test-worker-cli-options.js new file mode 100644 index 00000000000..ae59dcb6e62 --- /dev/null +++ b/test/parallel/test-worker-cli-options.js @@ -0,0 +1,31 @@ +// Flags: --expose-internals --expose-gc +'use strict'; +require('../common'); +const { Worker } = require('worker_threads'); +const assert = require('assert'); + +const CODE = ` +// If the --expose-internals flag does not pass to worker +// require function will throw an error +require('internal/options'); +global.gc(); +`; + +// Test if the flags is passed to worker threads correctly +// and do not throw an error with the invalid execArgv +// when execArgv is inherited from parent +// See https://github.com/nodejs/node/issues/52825 +// See https://github.com/nodejs/node/issues/53011 + +// Inherited env, execArgv from the parent will be ok +new Worker(CODE, { eval: true }); +// Pass process.env explicitly and inherited execArgv from parent will be ok +new Worker(CODE, { eval: true, env: process.env }); +// Inherited env from the parent and pass execArgv (Node.js options) explicitly will be ok +new Worker(CODE, { eval: true, execArgv: ['--expose-internals'] }); +// Pass process.env and execArgv (Node.js options) explicitly will be ok +new Worker(CODE, { eval: true, env: process.env, execArgv: ['--expose-internals'] }); +// Pass execArgv (V8 options) explicitly will throw an error +assert.throws(() => { + new Worker(CODE, { eval: true, execArgv: ['--expose-gc'] }); +}, /ERR_WORKER_INVALID_EXEC_ARGV/); diff --git a/test/parallel/test-worker-workerdata-messageport.js b/test/parallel/test-worker-workerdata-messageport.js index 0df48465a07..fb263b10b6f 100644 --- a/test/parallel/test-worker-workerdata-messageport.js +++ b/test/parallel/test-worker-workerdata-messageport.js @@ -8,7 +8,7 @@ const { } = require('node:worker_threads'); const channel = new MessageChannel(); -const workerData = { mesage: channel.port1 }; +const workerData = { message: channel.port1 }; const transferList = [channel.port1]; const meowScript = () => 'meow'; diff --git a/test/parallel/test-zlib-invalid-input-memory.js b/test/parallel/test-zlib-invalid-input-memory.js index d626e6e5b8d..9761e4bbf09 100644 --- a/test/parallel/test-zlib-invalid-input-memory.js +++ b/test/parallel/test-zlib-invalid-input-memory.js @@ -1,7 +1,7 @@ // Flags: --expose-gc 'use strict'; const common = require('../common'); -const onGC = require('../common/ongc'); +const { onGC } = require('../common/gc'); const assert = require('assert'); const zlib = require('zlib'); diff --git a/test/pummel/pummel.status b/test/pummel/pummel.status index fa95696e345..b9b0469da5c 100644 --- a/test/pummel/pummel.status +++ b/test/pummel/pummel.status @@ -9,8 +9,6 @@ prefix pummel [$system==win32] # https://github.com/nodejs/node/issues/40728 test-fs-watch-non-recursive: PASS,FLAKY -# https://github.com/nodejs/node/issues/50260 -test-structuredclone-jstransferable: PASS,FLAKY [$system==macos] diff --git a/test/pummel/test-fs-watch-non-recursive.js b/test/pummel/test-fs-watch-non-recursive.js index e0ef20bef0b..218f485d83c 100644 --- a/test/pummel/test-fs-watch-non-recursive.js +++ b/test/pummel/test-fs-watch-non-recursive.js @@ -38,14 +38,24 @@ const filepath = path.join(testsubdir, 'watch.txt'); fs.mkdirSync(testsubdir, 0o700); -const watcher = fs.watch(testDir, { persistent: true }, (event, filename) => { - // This function may be called with the directory depending on timing but - // must not be called with the file.. - assert.strictEqual(filename, 'testsubdir'); -}); -setTimeout(() => { - fs.writeFileSync(filepath, 'test'); -}, 100); -setTimeout(() => { - watcher.close(); -}, 500); +function doWatch() { + const watcher = fs.watch(testDir, { persistent: true }, (event, filename) => { + // This function may be called with the directory depending on timing but + // must not be called with the file.. + assert.strictEqual(filename, 'testsubdir'); + }); + setTimeout(() => { + fs.writeFileSync(filepath, 'test'); + }, 100); + setTimeout(() => { + watcher.close(); + }, 500); +} + +if (common.isMacOS) { + // On macOS delay watcher start to avoid leaking previous events. + // Refs: https://github.com/libuv/libuv/pull/4503 + setTimeout(doWatch, common.platformTimeout(100)); +} else { + doWatch(); +} diff --git a/test/sequential/sequential.status b/test/sequential/sequential.status index ccab879b6e5..a539649d553 100644 --- a/test/sequential/sequential.status +++ b/test/sequential/sequential.status @@ -19,10 +19,16 @@ test-http-max-sockets: PASS, FLAKY # https://github.com/nodejs/node/issues/49630 test-single-executable-application-snapshot: PASS, FLAKY test-single-executable-application-snapshot-and-code-cache: PASS, FLAKY +# https://github.com/nodejs/node/issues/47409 +test-http2-large-file: PASS, FLAKY [$system==linux] +# https://github.com/nodejs/node/issues/54817 +test-http-server-request-timeouts-mixed: PASS, FLAKY [$system==macos] +# https://github.com/nodejs/node/issues/54816 +test-single-executable-application-empty: PASS, FLAKY [$system==solaris] # Also applies to SmartOS diff --git a/test/sequential/test-fs-watch.js b/test/sequential/test-fs-watch.js index b7b60abaa5c..cb12acfc115 100644 --- a/test/sequential/test-fs-watch.js +++ b/test/sequential/test-fs-watch.js @@ -95,24 +95,34 @@ function repeat(fn) { const testsubdir = fs.mkdtempSync(testDir + path.sep); const filepath = path.join(testsubdir, 'newfile.txt'); - const watcher = - fs.watch(testsubdir, common.mustCall(function(event, filename) { - const renameEv = common.isSunOS || common.isAIX ? 'change' : 'rename'; - assert.strictEqual(event, renameEv); - if (expectFilePath) { - assert.strictEqual(filename, 'newfile.txt'); - } else { - assert.strictEqual(filename, null); - } - clearInterval(interval); - watcher.close(); - })); + function doWatch() { + const watcher = + fs.watch(testsubdir, common.mustCall(function(event, filename) { + const renameEv = common.isSunOS || common.isAIX ? 'change' : 'rename'; + assert.strictEqual(event, renameEv); + if (expectFilePath) { + assert.strictEqual(filename, 'newfile.txt'); + } else { + assert.strictEqual(filename, null); + } + clearInterval(interval); + watcher.close(); + })); + + const interval = repeat(() => { + fs.rmSync(filepath, { force: true }); + const fd = fs.openSync(filepath, 'w'); + fs.closeSync(fd); + }); + } - const interval = repeat(() => { - fs.rmSync(filepath, { force: true }); - const fd = fs.openSync(filepath, 'w'); - fs.closeSync(fd); - }); + if (common.isMacOS) { + // On macOS delay watcher start to avoid leaking previous events. + // Refs: https://github.com/libuv/libuv/pull/4503 + setTimeout(doWatch, common.platformTimeout(100)); + } else { + doWatch(); + } } // https://github.com/joyent/node/issues/2293 - non-persistent watcher should diff --git a/test/sequential/test-gc-http-client-onerror.js b/test/sequential/test-gc-http-client-onerror.js index 7574c0f9373..95e65ae0db6 100644 --- a/test/sequential/test-gc-http-client-onerror.js +++ b/test/sequential/test-gc-http-client-onerror.js @@ -4,7 +4,7 @@ // but with an on('error') handler that does nothing. const common = require('../common'); -const onGC = require('../common/ongc'); +const { onGC } = require('../common/gc'); const cpus = require('os').availableParallelism(); diff --git a/test/sequential/test-gc-http-client-timeout.js b/test/sequential/test-gc-http-client-timeout.js index 02913e178ad..e88578e765a 100644 --- a/test/sequential/test-gc-http-client-timeout.js +++ b/test/sequential/test-gc-http-client-timeout.js @@ -3,7 +3,7 @@ // Like test-gc-http-client.js, but with a timeout set. const common = require('../common'); -const onGC = require('../common/ongc'); +const { onGC } = require('../common/gc'); const http = require('http'); function serverHandler(req, res) { diff --git a/test/sequential/test-gc-http-client.js b/test/sequential/test-gc-http-client.js index 8e9d3e9e729..b072d2c179b 100644 --- a/test/sequential/test-gc-http-client.js +++ b/test/sequential/test-gc-http-client.js @@ -3,7 +3,7 @@ // just a simple http server and client. const common = require('../common'); -const onGC = require('../common/ongc'); +const { onGC } = require('../common/gc'); const cpus = require('os').availableParallelism(); diff --git a/test/sequential/test-worker-arraybuffer-zerofill.js b/test/sequential/test-worker-arraybuffer-zerofill.js new file mode 100644 index 00000000000..b30f3e513c6 --- /dev/null +++ b/test/sequential/test-worker-arraybuffer-zerofill.js @@ -0,0 +1,43 @@ +'use strict'; +require('../common'); +const Countdown = require('../common/countdown'); +const assert = require('assert'); +const { Worker } = require('worker_threads'); +const { describe, it, mock } = require('node:test'); + +describe('Allocating uninitialized ArrayBuffers ...', () => { + it('...should not affect zero-fill in other threads', () => { + const w = new Worker(` + const { parentPort } = require('worker_threads'); + + function post() { + const uint32array = new Uint32Array(64); + parentPort.postMessage(uint32array.reduce((a, b) => a + b)); + } + + setInterval(post, 0); + `, { eval: true }); + + const fn = mock.fn(() => { + // Continuously allocate memory in the main thread. The allocUnsafe + // here sets a scope internally that indicates that the memory should + // not be initialized. While this is happening, the other thread is + // also allocating buffers that must remain zero-filled. The purpose + // of this test is to ensure that the scope used to determine whether + // to zero-fill or not does not impact the other thread. + setInterval(() => Buffer.allocUnsafe(32 * 1024 * 1024), 0).unref(); + }); + + w.on('online', fn); + + const countdown = new Countdown(100, () => { + w.terminate(); + assert(fn.mock.calls.length > 0); + }); + + w.on('message', (sum) => { + assert.strictEqual(sum, 0); + if (countdown.remaining) countdown.dec(); + }); + }); +}); diff --git a/test/wpt/status/streams.json b/test/wpt/status/streams.json index 3b6e0ce6429..5425c86bba8 100644 --- a/test/wpt/status/streams.json +++ b/test/wpt/status/streams.json @@ -16,6 +16,13 @@ "readable-streams/cross-realm-crash.window.js": { "skip": "Browser-specific test" }, + "readable-streams/from.any.js": { + "fail": { + "expected": [ + "ReadableStream.from ignores a null @@asyncIterator" + ] + } + }, "readable-streams/owning-type-message-port.any.js": { "fail": { "note": "Readable streams with type owning are not yet supported", @@ -40,6 +47,9 @@ ] } }, + "readable-streams/read-task-handling.window.js": { + "skip": "Browser-specific test" + }, "transferable/deserialize-error.window.js": { "skip": "Browser-specific test" }, @@ -56,8 +66,5 @@ }, "transform-streams/invalid-realm.tentative.window.js": { "skip": "Browser-specific test" - }, - "readable-streams/read-task-handling.window.js": { - "skip": "Browser-specific test" } } diff --git a/tools/actions/merge.sh b/tools/actions/merge.sh new file mode 100755 index 00000000000..898e9e59ea3 --- /dev/null +++ b/tools/actions/merge.sh @@ -0,0 +1,62 @@ +#!/bin/sh + +# Requires [gh](https://cli.github.com/), [jq](https://jqlang.github.io), git, and grep. Also awk if you pass a URL. + +# This script can be used to "purple-merge" PRs that are supposed to land as a single commit, using the "Squash and Merge" feature of GitHub. +# To land a PR with this tool: +# 1. Run `git node land --fixupAll` +# 2. Copy the hash of the commit at the top of the PR branch. +# 3. Run `tools/actions/merge.sh `. + +set -xe + +pr=$1 +commit_head=$2 +shift 2 || { echo "Expected two arguments"; exit 1; } + +OWNER=nodejs +REPOSITORY=node + +if expr "X$pr" : 'Xhttps://github.com/[^/]\{1,\}/[^/]\{1,\}/pull/[0-9]\{1,\}' >/dev/null; then + OWNER="$(echo "$pr" | awk 'BEGIN { FS = "/" } ; { print $4 }')" + REPOSITORY="$(echo "$pr" | awk 'BEGIN { FS = "/" } ; { print $5 }')" + pr="$(echo "$pr" | awk 'BEGIN { FS = "/" } ; { print $7 }')" +elif ! expr "X$pr" : 'X[0-9]\{1,\}' >/dev/null; then + echo "The first argument should be the PR ID or URL" +fi + +git log -1 HEAD --pretty='format:%B' | git interpret-trailers --parse --no-divider | \ + grep -q -x "^PR-URL: https://github.com/$OWNER/$REPOSITORY/pull/$pr$" || { + echo "Invalid PR-URL trailer" + exit 1 + } +git log -1 HEAD^ --pretty='format:%B' | git interpret-trailers --parse --no-divider | \ + grep -q -x "^PR-URL: https://github.com/$OWNER/$REPOSITORY/pull/$pr$" && { + echo "Refuse to squash and merge a PR landing in more than one commit" + exit 1 + } + +commit_title=$(git log -1 --pretty='format:%s') +commit_body=$(git log -1 --pretty='format:%b') + +jq -n \ + --arg title "${commit_title}" \ + --arg body "${commit_body}" \ + --arg head "${commit_head}" \ + '{merge_method:"squash",commit_title:$title,commit_message:$body,sha:$head}' > output.json +cat output.json +if ! gh api -X PUT "repos/${OWNER}/${REPOSITORY}/pulls/${pr}/merge" --input output.json > output; then + cat output + echo "Failed to merge $pr" + rm output output.json + exit 1 +fi +cat output +if ! commits="$(jq -r 'if .merged then .sha else error("not merged") end' < output)"; then + echo "Failed to merge $pr" + rm output output.json + exit 1 +fi +rm output.json output + +gh pr comment "$pr" --repo "$OWNER/$REPOSITORY" --body "Landed in $commits" diff --git a/tools/actions/rebase.sh b/tools/actions/rebase.sh new file mode 100755 index 00000000000..6fdf07af0b8 --- /dev/null +++ b/tools/actions/rebase.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +set -xe + +# shellcheck disable=SC2016 +gh api graphql -F "prID=$(gh pr view "$1" --json id --jq .id || true)" -f query=' +mutation RebasePR($prID: ID!) { + updatePullRequestBranch(input:{pullRequestId:$prID,updateMethod:REBASE}) { + clientMutationId + } +}' diff --git a/tools/clang-format/package-lock.json b/tools/clang-format/package-lock.json index 537314a7cb6..7601a5e8c91 100644 --- a/tools/clang-format/package-lock.json +++ b/tools/clang-format/package-lock.json @@ -1,319 +1,26 @@ { - "name": "node-core-clang-format", - "version": "1.0.0", - "lockfileVersion": 2, + "name": "clang-format", + "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "node-core-clang-format", - "version": "1.0.0", - "license": "MIT", - "dependencies": { - "clang-format": "^1.8.0" - } - }, - "node_modules/async": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.3.tgz", - "integrity": "sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g==" - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/clang-format": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/clang-format/-/clang-format-1.8.0.tgz", - "integrity": "sha512-pK8gzfu55/lHzIpQ1givIbWfn3eXnU7SfxqIwVgnn5jEM6j4ZJYjpFqFs4iSBPNedzRMmfjYjuQhu657WAXHXw==", - "dependencies": { - "async": "^3.2.3", - "glob": "^7.0.0", - "resolve": "^1.1.6" - }, - "bin": { - "check-clang-format": "bin/check-clang-format.js", - "clang-format": "index.js", - "git-clang-format": "bin/git-clang-format" - } - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "node_modules/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/is-core-module": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.1.tgz", - "integrity": "sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==", - "dependencies": { - "has": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "dependencies": { - "wrappy": "1" + "@wasm-fmt/clang-format": "^18.1.8" } }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" - }, - "node_modules/resolve": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", - "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==", - "dependencies": { - "is-core-module": "^2.8.1", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, + "node_modules/@wasm-fmt/clang-format": { + "version": "18.1.8", + "resolved": "https://registry.npmjs.org/@wasm-fmt/clang-format/-/clang-format-18.1.8.tgz", + "integrity": "sha512-JWX9ILldydxP0/Z6ksCiyWbpN9mB7X1Kj8ESVGkZ3KA5aV363EEzTctHb/Y/FHXAsNIdWO7dp73OMNM0uCUPBg==", + "license": "MIT", "bin": { - "resolve": "bin/resolve" + "clang-format": "clang-format-cli.js", + "clang-format-diff": "clang-format-diff.py", + "git-clang-format": "git-clang-format" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - } - }, - "dependencies": { - "async": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.3.tgz", - "integrity": "sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g==" - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "clang-format": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/clang-format/-/clang-format-1.8.0.tgz", - "integrity": "sha512-pK8gzfu55/lHzIpQ1givIbWfn3eXnU7SfxqIwVgnn5jEM6j4ZJYjpFqFs4iSBPNedzRMmfjYjuQhu657WAXHXw==", - "requires": { - "async": "^3.2.3", - "glob": "^7.0.0", - "resolve": "^1.1.6" - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "requires": { - "function-bind": "^1.1.1" - } - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "is-core-module": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.1.tgz", - "integrity": "sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==", - "requires": { - "has": "^1.0.3" + "node": ">=16.17.0" } - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" - }, - "path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" - }, - "resolve": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", - "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==", - "requires": { - "is-core-module": "^2.8.1", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - } - }, - "supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" } } } diff --git a/tools/clang-format/package.json b/tools/clang-format/package.json index 4ae7d36a33c..12db10d2927 100644 --- a/tools/clang-format/package.json +++ b/tools/clang-format/package.json @@ -1,9 +1,6 @@ { - "name": "node-core-clang-format", - "version": "1.0.0", "description": "Formatting C++ files for Node.js core", - "license": "MIT", "dependencies": { - "clang-format": "^1.8.0" + "@wasm-fmt/clang-format": "^18.1.8" } } diff --git a/tools/cpplint.py b/tools/cpplint.py index 85732b5aa43..5d6172d5a4e 100755 --- a/tools/cpplint.py +++ b/tools/cpplint.py @@ -325,7 +325,6 @@ 'readability/casting', 'readability/check', 'readability/constructors', - 'readability/fn_size', 'readability/inheritance', 'readability/pointer_notation', 'readability/multiline_comment', @@ -398,7 +397,10 @@ # flag. By default all errors are on, so only add here categories that should be # off by default (i.e., categories that must be enabled by the --filter= flags). # All entries here should start with a '-' or '+', as in the --filter= flag. -_DEFAULT_FILTERS = ['-build/include_alpha'] +_DEFAULT_FILTERS = [ + '-build/include_alpha', + '-readability/fn_size', + ] # The default list of categories suppressed for C (not C++) files. _DEFAULT_C_SUPPRESSED_CATEGORIES = [ diff --git a/tools/dep_updaters/update-undici.sh b/tools/dep_updaters/update-undici.sh index e50a3b909b8..f8906f64e84 100755 --- a/tools/dep_updaters/update-undici.sh +++ b/tools/dep_updaters/update-undici.sh @@ -5,9 +5,10 @@ # This script must be in the tools directory when it runs because it uses the # script source file path to determine directories to work in. -set -ex +set -e ROOT=$(cd "$(dirname "$0")/../.." && pwd) +DEPS_DIR="$ROOT/deps" [ -z "$NODE" ] && NODE="$ROOT/out/Release/node" [ -x "$NODE" ] || NODE=$(command -v node) NPM="$ROOT/deps/npm/bin/npm-cli.js" @@ -15,29 +16,74 @@ NPM="$ROOT/deps/npm/bin/npm-cli.js" # shellcheck disable=SC1091 . "$ROOT/tools/dep_updaters/utils.sh" -NEW_VERSION=$("$NODE" "$NPM" view undici dist-tags.latest) -CURRENT_VERSION=$("$NODE" -p "require('./deps/undici/src/package.json').version") +NEW_VERSION="$("$NODE" --input-type=module <<'EOF' +const res = await fetch('https://api.github.com/repos/nodejs/undici/releases/latest', + process.env.GITHUB_TOKEN && { + headers: { + "Authorization": `Bearer ${process.env.GITHUB_TOKEN}` + }, + }); +if (!res.ok) throw new Error(`FetchError: ${res.status} ${res.statusText}`, { cause: res }); +const { tag_name } = await res.json(); +console.log(tag_name.replace('v', '')); +EOF +)" + +CURRENT_VERSION=$("$NODE" -p "require('$DEPS_DIR/undici/src/package.json').version") + +echo "$CURRENT_VERSION" +echo "$NEW_VERSION" # This function exit with 0 if new version and current version are the same compare_dependency_version "undici" "$NEW_VERSION" "$CURRENT_VERSION" -cd "$( dirname "$0" )/../.." || exit rm -rf deps/undici/src rm -f deps/undici/undici.js +WORKSPACE=$(mktemp -d 2> /dev/null || mktemp -d -t 'tmp') +echo "$WORKSPACE" +cleanup () { + EXIT_CODE=$? + [ -d "$WORKSPACE" ] && rm -rf "$WORKSPACE" + exit $EXIT_CODE +} + +trap cleanup INT TERM EXIT + +UNDICI_ZIP="undici-$NEW_VERSION" +cd "$WORKSPACE" + +echo "Fetching UNDICI source archive..." +curl -sL -o "$UNDICI_ZIP.zip" "https://github.com/nodejs/undici/archive/refs/tags/v$NEW_VERSION.zip" + +log_and_verify_sha256sum "undici" "$UNDICI_ZIP.zip" + +echo "Unzipping..." +unzip "$UNDICI_ZIP.zip" -d "src" +mv "src/$UNDICI_ZIP" "$DEPS_DIR/undici/src" +rm "$UNDICI_ZIP.zip" +cd "$ROOT" + ( - rm -rf undici-tmp - mkdir undici-tmp - cd undici-tmp || exit - - "$NODE" "$NPM" init --yes - - "$NODE" "$NPM" install --global-style --no-bin-links --ignore-scripts "undici@$NEW_VERSION" - cd node_modules/undici - "$NODE" "$NPM" install --no-bin-link --ignore-scripts - "$NODE" "$NPM" run build:node - "$NODE" "$NPM" prune --production - rm node_modules/.package-lock.json + cd "$DEPS_DIR/undici/src" + + # remove components we don't need to keep in nodejs/deps + rm -rf .husky || true + rm -rf .github || true + rm -rf test + rm -rf benchmarks + rm -rf docs-tmp + mv docs docs-tmp + mkdir docs + mv docs-tmp/docs docs/docs + rm -rf docs-tmp + + # Rebuild components from source + rm lib/llhttp/llhttp*.* + "$NODE" "$NPM" install --no-bin-link --ignore-scripts + "$NODE" "$NPM" run build:wasm > lib/llhttp/wasm_build_env.txt + "$NODE" "$NPM" run build:node + "$NODE" "$NPM" prune --production ) # update version information in src/undici_version.h @@ -50,12 +96,9 @@ cat > "$ROOT/src/undici_version.h" <nul') do set p=%%i +if defined p ( + for /f "tokens=*" %%j in ('"%p%" --version') do set python_version=%%j + goto :found-python +) + goto :no-python diff --git a/tools/v8_gypfiles/toolchain.gypi b/tools/v8_gypfiles/toolchain.gypi index 0f506f71494..0f03b8ee7be 100644 --- a/tools/v8_gypfiles/toolchain.gypi +++ b/tools/v8_gypfiles/toolchain.gypi @@ -82,7 +82,6 @@ 'v8_toolset_for_shell%': 'target', 'host_os%': '<(OS)', - 'werror%': '-Werror', # For a shared library build, results in "libv8-<(soname_version).so". 'soname_version%': '', @@ -133,13 +132,21 @@ '<(V8_ROOT)', '<(V8_ROOT)/include', ], + 'cflags!': ['-Wall', '-Wextra'], 'conditions': [ - ['clang', { - 'cflags': [ '-Werror', '-Wno-unknown-pragmas' ], - },{ - 'cflags!': [ '-Wall', '-Wextra' ], + ['clang==0 and OS!="win"', { 'cflags': [ + # In deps/v8/BUILD.gn: if (!is_clang && !is_win) { cflags += [...] } + '-Wno-strict-overflow', '-Wno-return-type', + '-Wno-int-in-bool-context', + '-Wno-deprecated', + '-Wno-stringop-overflow', + '-Wno-stringop-overread', + '-Wno-restrict', + '-Wno-array-bounds', + '-Wno-nonnull', + '-Wno-dangling-pointer', # On by default in Clang and V8 requires it at least for arm64. '-flax-vector-conversions', ], @@ -428,9 +435,6 @@ ['_toolset=="target"', { 'conditions': [ ['v8_target_arch==target_arch', { - 'cflags': [ - '-Wno-error=array-bounds', # Workaround https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56273 - ], 'conditions': [ ['v8_target_arch=="mips64el"', { 'cflags': ['-EL'], diff --git a/tools/v8_gypfiles/v8.gyp b/tools/v8_gypfiles/v8.gyp index 9ffa6e9c6f4..45f6e0db865 100644 --- a/tools/v8_gypfiles/v8.gyp +++ b/tools/v8_gypfiles/v8.gyp @@ -1746,7 +1746,7 @@ ['enable_lto=="true"', { 'cflags_cc': [ '-fno-lto' ], }], - ['clang or OS!="win"', { + ['clang==1 or OS!="win"', { 'conditions': [ ['_toolset == "host" and host_arch == "x64" or _toolset == "target" and target_arch=="x64"', { 'sources': [ @@ -1981,12 +1981,6 @@ ] }], ], - # -Wno-invalid-offsetof flag is not valid for C. - # The flag is initially set in `toolchain.gypi` for all targets. - 'cflags!': [ '-Wno-invalid-offsetof' ], - 'xcode_settings': { - 'WARNING_CFLAGS!': ['-Wno-invalid-offsetof'] - }, 'direct_dependent_settings': { 'include_dirs': [ '<(V8_ROOT)/third_party/zlib', diff --git a/typings/globals.d.ts b/typings/globals.d.ts index bc47c08b02b..52b64bf9c34 100644 --- a/typings/globals.d.ts +++ b/typings/globals.d.ts @@ -16,19 +16,6 @@ import {URLBinding} from "./internalBinding/url"; import {UtilBinding} from "./internalBinding/util"; import {WorkerBinding} from "./internalBinding/worker"; -declare type TypedArray = - | Uint8Array - | Uint8ClampedArray - | Uint16Array - | Uint32Array - | Int8Array - | Int16Array - | Int32Array - | Float32Array - | Float64Array - | BigUint64Array - | BigInt64Array; - interface InternalBindingMap { async_wrap: AsyncWrapBinding; blob: BlobBinding; @@ -54,6 +41,19 @@ type InternalBindingKeys = keyof InternalBindingMap; declare function internalBinding(binding: T): InternalBindingMap[T] declare global { + type TypedArray = + | Uint8Array + | Uint8ClampedArray + | Uint16Array + | Uint32Array + | Int8Array + | Int16Array + | Int32Array + | Float32Array + | Float64Array + | BigUint64Array + | BigInt64Array; + namespace NodeJS { interface Global { internalBinding(binding: T): InternalBindingMap[T] diff --git a/typings/internalBinding/fs.d.ts b/typings/internalBinding/fs.d.ts index c8281253eed..26f45175569 100644 --- a/typings/internalBinding/fs.d.ts +++ b/typings/internalBinding/fs.d.ts @@ -57,7 +57,7 @@ declare namespace InternalFSBinding { } function access(path: StringOrBuffer, mode: number, req: FSReqCallback): void; - function access(path: StringOrBuffer, mode: number, req: undefined, ctx: FSSyncContext): void; + function access(path: StringOrBuffer, mode: number): void; function access(path: StringOrBuffer, mode: number, usePromises: typeof kUsePromises): Promise; function chmod(path: string, mode: number, req: FSReqCallback): void; @@ -70,7 +70,7 @@ declare namespace InternalFSBinding { function chown(path: string, uid: number, gid: number): void; function close(fd: number, req: FSReqCallback): void; - function close(fd: number, req: undefined, ctx: FSSyncContext): void; + function close(fd: number): void; function copyFile(src: StringOrBuffer, dest: StringOrBuffer, mode: number, req: FSReqCallback): void; function copyFile(src: StringOrBuffer, dest: StringOrBuffer, mode: number, req: undefined, ctx: FSSyncContext): void; @@ -154,7 +154,7 @@ declare namespace InternalFSBinding { function mkdir(path: string, mode: number, recursive: false, usePromises: typeof kUsePromises): Promise; function open(path: StringOrBuffer, flags: number, mode: number, req: FSReqCallback): void; - function open(path: StringOrBuffer, flags: number, mode: number, req: undefined, ctx: FSSyncContext): number; + function open(path: StringOrBuffer, flags: number, mode: number): number; function openFileHandle(path: StringOrBuffer, flags: number, mode: number, usePromises: typeof kUsePromises): Promise; @@ -176,6 +176,8 @@ declare namespace InternalFSBinding { function readdir(path: StringOrBuffer, encoding: unknown, withFileTypes: true, usePromises: typeof kUsePromises): Promise<[string[], number[]]>; function readdir(path: StringOrBuffer, encoding: unknown, withFileTypes: false, usePromises: typeof kUsePromises): Promise; + function readFileUtf8(path: StringOrBuffer, flags: number): string; + function readlink(path: StringOrBuffer, encoding: unknown, req: FSReqCallback): void; function readlink(path: StringOrBuffer, encoding: unknown, req: undefined, ctx: FSSyncContext): string | Buffer; function readlink(path: StringOrBuffer, encoding: unknown, usePromises: typeof kUsePromises): Promise; @@ -273,6 +275,7 @@ export interface FsBinding { read: typeof InternalFSBinding.read; readBuffers: typeof InternalFSBinding.readBuffers; readdir: typeof InternalFSBinding.readdir; + readFileUtf8: typeof InternalFSBinding.readFileUtf8; readlink: typeof InternalFSBinding.readlink; realpath: typeof InternalFSBinding.realpath; rename: typeof InternalFSBinding.rename; @@ -283,6 +286,7 @@ export interface FsBinding { utimes: typeof InternalFSBinding.utimes; writeBuffer: typeof InternalFSBinding.writeBuffer; writeBuffers: typeof InternalFSBinding.writeBuffers; + writeFileUtf8: typeof InternalFSBinding.writeFileUtf8; writeString: typeof InternalFSBinding.writeString; getFormatOfExtensionlessFile: typeof InternalFSBinding.getFormatOfExtensionlessFile; diff --git a/typings/internalBinding/util.d.ts b/typings/internalBinding/util.d.ts index 9963d07d7f8..34b4b31c1d8 100644 --- a/typings/internalBinding/util.d.ts +++ b/typings/internalBinding/util.d.ts @@ -44,4 +44,5 @@ export interface UtilBinding { WeakReference: typeof InternalUtilBinding.WeakReference; guessHandleType(fd: number): 'TCP' | 'TTY' | 'UDP' | 'FILE' | 'PIPE' | 'UNKNOWN'; parseEnv(content: string): Record; + styleText(format: Array | string, text: string): string; }