Conversation
Four small, surgical fixes for silent-data-corruption and UB bugs identified in the full code review: - socketcan.ts: replace `x << 32` (which is `x << 0` in JS) with `x * TWO_TO_32` when reassembling the high word of decoded signals. The old expression silently dropped the high 32 bits for any signal wider than 32 bits. - socketcan.ts: switch `min/maxValue` bounds checks from truthy to `!= null` so that a legitimate bound of `0` is honoured. - can.cc: reject Send() payloads larger than CAN_MAX_DLEN before the memcpy into the 8-byte `struct can_frame.data`, preventing a stack overwrite on caller error. - signals.cc: validate that `bitLength` is in the range 1..64 in both DecodeSignal and EncodeSignal. Out-of-range values previously caused shifts of full type width / by negative amounts (UB). Tests: - test-signal_conversion.js: high-word regression case plus bitLength range validation for encode and decode. - test-signal_bounds.js: new file covering the `0`-boundary cases for Signal min/maxValue. - test-send_overflow.js: new file asserting Send() throws on oversized buffers (skips when vcan0 is unavailable). Also includes ESLint auto-fix formatting touched by `npm run lint` (trailing commas, switch reformatting) across `parse_kcd.ts`, `can.d.ts`, `can_signals.d.ts`, and `socketcan.ts`. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
4 tasks
The previous _getvalue / _setvalue always memcpy'd bytes 0..7 of the local buffer into a uint64_t and shifted from there. That assumption predates CAN-FD support: for any signal whose bit offset lies past byte 7 of a 64-byte CAN-FD payload, the routine returned garbage or hit shift-by-full-type-width UB (Intel offset >= 64) / size_t underflow on the Motorola shift formula 64 - offset - length (offset > 64). Encoding had the symmetric bug. Rewrite both helpers as a windowed fast path plus a per-bit fallback: - Fast path (essentially all real signals): memcpy 8 bytes starting at data[offset/8], endian-swap, then shift by (offset % 8) for Intel or (64 - bit_in_byte - length) for Motorola, then mask. Same shape and cost as the previous code, just with the byte_start factored out. - Fallback: when bit_in_byte + length > 64 — a 58..64 bit signal at a non-byte-aligned offset, essentially never seen in real CAN databases — walk the signal bit by bit. Both endiannesses handled. The local scratch buffer grows from 64 to 72 bytes (MAX_PAYLOAD_BYTES + WINDOW_SAFETY_PAD = 8) so the 8-byte windowed memcpy is always in-bounds even for a signal sitting at byte 63. The padding stays zero and any bits read from it are masked off. EncodeSignal now also memsets the local buffer before the memcpy-in. The fast-path RMW may touch bytes past the caller's payload inside the scratch buffer, and previously those bytes were uninitialised stack memory — harmless because they're never written back, but flagged as UB by the model. Two new bounds checks are added in DecodeSignal and EncodeSignal: - offset + effectiveBitLength must fit in MAX_TOTAL_BITS (512). - signal must fit within the caller's JS buffer length. Both throw TypeError with a clear message rather than silently producing wrong results. The KAYAK_DATA_CHECK debug blocks are removed: the per-bit walk that they referenced is now the production fallback path, so the self-comparison is no longer meaningful. Tests cover all the worked examples plus the boundaries: - Intel 16-bit at offset 200 (decode + encode, RMW preserves neighbours) - Motorola 12-bit at byte-aligned offset 144 (decode + encode) - Motorola 10-bit at non-byte-aligned offset 147 (round-trip) - 8-bit at byte 63 (last byte of CAN-FD payload) - 64-bit Intel at offsets 0 and 64 (length-64 boundary) - 58-bit Intel at offset 7 (exercises the per-bit fallback) - All four out-of-bounds throws (frame and buffer). All 13 new cases plus the 27 pre-existing signal tests pass in the node:22-bookworm-slim Docker container. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2 tasks
* Bump @typescript-eslint/parser from 8.60.0 to 8.60.1 Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 8.60.0 to 8.60.1. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.60.1/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-version: 8.60.1 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * Bump @typescript-eslint/eslint-plugin from 8.60.0 to 8.60.1 Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 8.60.0 to 8.60.1. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.60.1/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-version: 8.60.1 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * Bump @types/node from 25.9.1 to 25.9.2 Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 25.9.1 to 25.9.2. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-version: 25.9.2 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * Bump node-gyp from 12.3.0 to 12.4.0 Bumps [node-gyp](https://github.com/nodejs/node-gyp) from 12.3.0 to 12.4.0. - [Release notes](https://github.com/nodejs/node-gyp/releases) - [Changelog](https://github.com/nodejs/node-gyp/blob/main/CHANGELOG.md) - [Commits](nodejs/node-gyp@v12.3.0...v12.4.0) --- updated-dependencies: - dependency-name: node-gyp dependency-version: 12.4.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * Bump node-gyp from 12.4.0 to 13.0.0 Bumps [node-gyp](https://github.com/nodejs/node-gyp) from 12.4.0 to 13.0.0. - [Release notes](https://github.com/nodejs/node-gyp/releases) - [Changelog](https://github.com/nodejs/node-gyp/blob/main/CHANGELOG.md) - [Commits](nodejs/node-gyp@v12.4.0...v13.0.0) --- updated-dependencies: - dependency-name: node-gyp dependency-version: 13.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> * Bump @typescript-eslint/eslint-plugin from 8.60.1 to 8.61.0 Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 8.60.1 to 8.61.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.61.0/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-version: 8.61.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * Bump @types/node from 25.9.2 to 25.9.3 Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 25.9.2 to 25.9.3. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-version: 25.9.3 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * Bump prettier from 3.8.3 to 3.8.4 Bumps [prettier](https://github.com/prettier/prettier) from 3.8.3 to 3.8.4. - [Release notes](https://github.com/prettier/prettier/releases) - [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md) - [Commits](prettier/prettier@3.8.3...3.8.4) --- updated-dependencies: - dependency-name: prettier dependency-version: 3.8.4 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * Bump eslint from 10.4.1 to 10.5.0 Bumps [eslint](https://github.com/eslint/eslint) from 10.4.1 to 10.5.0. - [Release notes](https://github.com/eslint/eslint/releases) - [Commits](eslint/eslint@v10.4.1...v10.5.0) --- updated-dependencies: - dependency-name: eslint dependency-version: 10.5.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * Bump version to 4.2.2 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Bump @typescript-eslint/eslint-plugin from 8.61.0 to 8.61.1 Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 8.61.0 to 8.61.1. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.61.1/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-version: 8.61.1 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * Bump @types/node from 25.9.3 to 26.0.0 Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 25.9.3 to 26.0.0. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-version: 26.0.0 dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> * Bump tar in the npm_and_yarn group across 1 directory Bumps the npm_and_yarn group with 1 update in the / directory: [tar](https://github.com/isaacs/node-tar). Updates `tar` from 7.5.15 to 7.5.16 - [Release notes](https://github.com/isaacs/node-tar/releases) - [Changelog](https://github.com/isaacs/node-tar/blob/main/CHANGELOG.md) - [Commits](isaacs/node-tar@v7.5.15...v7.5.16) --- updated-dependencies: - dependency-name: tar dependency-version: 7.5.16 dependency-type: indirect dependency-group: npm_and_yarn ... Signed-off-by: dependabot[bot] <support@github.com> * Bump @typescript-eslint/parser from 8.61.0 to 8.61.1 Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 8.61.0 to 8.61.1. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.61.1/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-version: 8.61.1 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * fix(signals): add missing <endian.h> include for ARM64 build le64toh/be64toh/htole64/htobe64 are declared in <endian.h>. The header was being pulled in transitively on x86 but not on ARM64, so the build failed there with "'le64toh' was not declared in this scope". Include it explicitly. Verified to compile under -std=c++20 on glibc and musl. Fixes #182 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * ci: build and test on ARM64 runners Add ubuntu-24.04-arm to the matrix (with fail-fast: false) so the native addon is validated on ARM64, the platform that regressed in #182. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Bump version to 4.2.3 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Bump @typescript-eslint/eslint-plugin from 8.61.1 to 8.62.0 Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 8.61.1 to 8.62.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.62.0/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-version: 8.62.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * Bump node-addon-api from 8.8.0 to 8.9.0 Bumps [node-addon-api](https://github.com/nodejs/node-addon-api) from 8.8.0 to 8.9.0. - [Release notes](https://github.com/nodejs/node-addon-api/releases) - [Changelog](https://github.com/nodejs/node-addon-api/blob/main/CHANGELOG.md) - [Commits](nodejs/node-addon-api@v8.8.0...v8.9.0) --- updated-dependencies: - dependency-name: node-addon-api dependency-version: 8.9.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * Bump prettier from 3.8.4 to 3.9.1 Bumps [prettier](https://github.com/prettier/prettier) from 3.8.4 to 3.9.1. - [Release notes](https://github.com/prettier/prettier/releases) - [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md) - [Commits](prettier/prettier@3.8.4...3.9.1) --- updated-dependencies: - dependency-name: prettier dependency-version: 3.9.1 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * Bump @types/node from 26.0.0 to 26.0.1 Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 26.0.0 to 26.0.1. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-version: 26.0.1 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * Bump eslint from 10.5.0 to 10.6.0 Bumps [eslint](https://github.com/eslint/eslint) from 10.5.0 to 10.6.0. - [Release notes](https://github.com/eslint/eslint/releases) - [Commits](eslint/eslint@v10.5.0...v10.6.0) --- updated-dependencies: - dependency-name: eslint dependency-version: 10.6.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * Bump @types/node from 26.0.1 to 26.1.0 Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 26.0.1 to 26.1.0. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-version: 26.1.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * Bump prettier from 3.9.1 to 3.9.4 Bumps [prettier](https://github.com/prettier/prettier) from 3.9.1 to 3.9.4. - [Release notes](https://github.com/prettier/prettier/releases) - [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md) - [Commits](prettier/prettier@3.9.1...3.9.4) --- updated-dependencies: - dependency-name: prettier dependency-version: 3.9.4 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * Bump @typescript-eslint/parser from 8.62.0 to 8.62.1 Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 8.62.0 to 8.62.1. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.62.1/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-version: 8.62.1 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * Bump @typescript-eslint/eslint-plugin from 8.62.0 to 8.62.1 Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 8.62.0 to 8.62.1. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.62.1/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-version: 8.62.1 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * Bump @types/node from 26.1.0 to 26.1.1 Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 26.1.0 to 26.1.1. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-version: 26.1.1 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * Bump @typescript-eslint/eslint-plugin from 8.62.1 to 8.64.0 Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 8.62.1 to 8.64.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.64.0/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-version: 8.64.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * Bump globals from 17.6.0 to 17.7.0 Bumps [globals](https://github.com/sindresorhus/globals) from 17.6.0 to 17.7.0. - [Release notes](https://github.com/sindresorhus/globals/releases) - [Commits](sindresorhus/globals@v17.6.0...v17.7.0) --- updated-dependencies: - dependency-name: globals dependency-version: 17.7.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * Bump node-gyp from 13.0.0 to 13.0.1 Bumps [node-gyp](https://github.com/nodejs/node-gyp) from 13.0.0 to 13.0.1. - [Release notes](https://github.com/nodejs/node-gyp/releases) - [Changelog](https://github.com/nodejs/node-gyp/blob/main/CHANGELOG.md) - [Commits](nodejs/node-gyp@v13.0.0...v13.0.1) --- updated-dependencies: - dependency-name: node-gyp dependency-version: 13.0.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * chore: upgrade dependencies, bump to v4.2.4 (#201) - Bump @types/node, @typescript-eslint/*, eslint, globals, node-addon-api, node-gyp, prettier to latest within existing semver ranges - Pin brace-expansion to ^5.0.8 via overrides to fix high-severity DoS (GHSA-mh99-v99m-4gvg) pulled in transitively via mocha's glob/minimatch, following the same pattern used for diff/serialize-javascript/uuid - Reformat src/*.ts per updated prettier/eslint defaults (npm run lint --fix) - Leave typescript on ^6.0.0 (6.0.3): 7.0.2 is a same-day major release, already tracked separately by the open dependabot/npm_and_yarn/typescript-7.0.2 PR Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com> * chore: sync package-lock.json version to 4.2.4 PR #201 bumped package.json to 4.2.4 but left the lockfile's version fields at 4.2.3. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * fix: bound CAN data length before memcpy in Send/SendFD (#199, #200) (#202) * fix: bound CAN data length before memcpy in Send/SendFD (#199, #200) RawChannel::Send and RawChannel::SendFD copied the caller-controlled JS Buffer into a fixed-size stack field (frame.data[8] / frameFD.data[64]) using the Buffer's own byte length as the copy size, with no upper bound before the memcpy. A data Buffer longer than the field overflowed it and smashed adjacent stack memory (CWE-787). In SendFD the existing len > 64 clamp ran after the memcpy, so it never bounded the copy. Reject over-length buffers with a thrown error before the copy, sized to the actual struct field via sizeof(). Throwing rather than silently truncating surfaces the caller's mistake instead of sending a malformed frame. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore: bump version to 4.2.5 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> * Bump @types/node from 26.1.1 to 26.1.2 (#205) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 26.1.1 to 26.1.2. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-version: 26.1.2 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump globals from 17.7.0 to 17.9.0 (#208) Bumps [globals](https://github.com/sindresorhus/globals) from 17.7.0 to 17.9.0. - [Release notes](https://github.com/sindresorhus/globals/releases) - [Commits](sindresorhus/globals@v17.7.0...v17.9.0) --- updated-dependencies: - dependency-name: globals dependency-version: 17.9.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump @typescript-eslint/eslint-plugin from 8.65.0 to 8.66.0 (#206) Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 8.65.0 to 8.66.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.66.0/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-version: 8.66.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump mocha from 11.7.6 to 11.8.0 (#207) Bumps [mocha](https://github.com/mochajs/mocha) from 11.7.6 to 11.8.0. - [Release notes](https://github.com/mochajs/mocha/releases) - [Changelog](https://github.com/mochajs/mocha/blob/v11.8.0/CHANGELOG.md) - [Commits](mochajs/mocha@v11.7.6...v11.8.0) --- updated-dependencies: - dependency-name: mocha dependency-version: 11.8.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore: update dependencies and migrate to pnpm (#209) * chore: bump version to 4.3.0 * ci: use npm trusted publishing (#210) * Bump node-gyp from 13.0.1 to 13.0.2 (#214) Bumps [node-gyp](https://github.com/nodejs/node-gyp) from 13.0.1 to 13.0.2. - [Release notes](https://github.com/nodejs/node-gyp/releases) - [Changelog](https://github.com/nodejs/node-gyp/blob/main/CHANGELOG.md) - [Commits](nodejs/node-gyp@v13.0.1...v13.0.2) --- updated-dependencies: - dependency-name: node-gyp dependency-version: 13.0.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump @types/node from 26.2.0 to 26.4.0 (#213) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 26.2.0 to 26.4.0. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-version: 26.4.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump eslint from 10.8.1 to 10.9.1 (#212) Bumps [eslint](https://github.com/eslint/eslint) from 10.8.1 to 10.9.1. - [Release notes](https://github.com/eslint/eslint/releases) - [Commits](eslint/eslint@v10.8.1...v10.9.1) --- updated-dependencies: - dependency-name: eslint dependency-version: 10.9.1 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump @typescript-eslint/parser from 8.67.0 to 8.68.0 (#211) Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 8.67.0 to 8.68.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.68.0/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-version: 8.68.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * fix: recover RawChannel from transient POLLERR events (#216) * fix: recover RawChannel from transient poll errors * chore: bump version to 4.3.1 * test: cover RawChannel interface lifecycle * test: expect channel recovery while interface is down * Fix correctness bugs in signal decoding and frame sending Four small, surgical fixes for silent-data-corruption and UB bugs identified in the full code review: - socketcan.ts: replace `x << 32` (which is `x << 0` in JS) with `x * TWO_TO_32` when reassembling the high word of decoded signals. The old expression silently dropped the high 32 bits for any signal wider than 32 bits. - socketcan.ts: switch `min/maxValue` bounds checks from truthy to `!= null` so that a legitimate bound of `0` is honoured. - can.cc: reject Send() payloads larger than CAN_MAX_DLEN before the memcpy into the 8-byte `struct can_frame.data`, preventing a stack overwrite on caller error. - signals.cc: validate that `bitLength` is in the range 1..64 in both DecodeSignal and EncodeSignal. Out-of-range values previously caused shifts of full type width / by negative amounts (UB). Tests: - test-signal_conversion.js: high-word regression case plus bitLength range validation for encode and decode. - test-signal_bounds.js: new file covering the `0`-boundary cases for Signal min/maxValue. - test-send_overflow.js: new file asserting Send() throws on oversized buffers (skips when vcan0 is unavailable). Also includes ESLint auto-fix formatting touched by `npm run lint` (trailing commas, switch reformatting) across `parse_kcd.ts`, `can.d.ts`, `can_signals.d.ts`, and `socketcan.ts`. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Fix CAN-FD bit extraction for signals past byte 7 The previous _getvalue / _setvalue always memcpy'd bytes 0..7 of the local buffer into a uint64_t and shifted from there. That assumption predates CAN-FD support: for any signal whose bit offset lies past byte 7 of a 64-byte CAN-FD payload, the routine returned garbage or hit shift-by-full-type-width UB (Intel offset >= 64) / size_t underflow on the Motorola shift formula 64 - offset - length (offset > 64). Encoding had the symmetric bug. Rewrite both helpers as a windowed fast path plus a per-bit fallback: - Fast path (essentially all real signals): memcpy 8 bytes starting at data[offset/8], endian-swap, then shift by (offset % 8) for Intel or (64 - bit_in_byte - length) for Motorola, then mask. Same shape and cost as the previous code, just with the byte_start factored out. - Fallback: when bit_in_byte + length > 64 — a 58..64 bit signal at a non-byte-aligned offset, essentially never seen in real CAN databases — walk the signal bit by bit. Both endiannesses handled. The local scratch buffer grows from 64 to 72 bytes (MAX_PAYLOAD_BYTES + WINDOW_SAFETY_PAD = 8) so the 8-byte windowed memcpy is always in-bounds even for a signal sitting at byte 63. The padding stays zero and any bits read from it are masked off. EncodeSignal now also memsets the local buffer before the memcpy-in. The fast-path RMW may touch bytes past the caller's payload inside the scratch buffer, and previously those bytes were uninitialised stack memory — harmless because they're never written back, but flagged as UB by the model. Two new bounds checks are added in DecodeSignal and EncodeSignal: - offset + effectiveBitLength must fit in MAX_TOTAL_BITS (512). - signal must fit within the caller's JS buffer length. Both throw TypeError with a clear message rather than silently producing wrong results. The KAYAK_DATA_CHECK debug blocks are removed: the per-bit walk that they referenced is now the production fallback path, so the self-comparison is no longer meaningful. Tests cover all the worked examples plus the boundaries: - Intel 16-bit at offset 200 (decode + encode, RMW preserves neighbours) - Motorola 12-bit at byte-aligned offset 144 (decode + encode) - Motorola 10-bit at non-byte-aligned offset 147 (round-trip) - 8-bit at byte 63 (last byte of CAN-FD payload) - 64-bit Intel at offsets 0 and 64 (length-64 boundary) - 58-bit Intel at offset 7 (exercises the per-bit fallback) - All four out-of-bounds throws (frame and buffer). All 13 new cases plus the 27 pre-existing signal tests pass in the node:22-bookworm-slim Docker container. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Fix lifecycle / teardown races in RawChannel Four small correctness fixes in native/can.cc: - ~RawChannel closed m_SocketFd BEFORE joining the reader thread, while the reader is mid-poll() on that fd. Closing an fd from one thread while another is in poll() on it is POSIX-undefined — the fd can be reused by an unrelated open() before poll() returns. Reorder: stopThread() first, then close(m_SocketFd). - async_channel_stopped() could run twice — once from JS Stop() and once from the reader-thread uv_async_send issued on POLLHUP/POLLERR. The second invocation would re-run the listener loop, schedule a double uv_close (libuv assertion), and call Unref() one too many times. Add an m_StoppedAlready single-shot guard. - pthread_create's return value was ignored. The subsequent CHECK_CONDITION(m_Thread, ...) checked the output pthread_t handle, which is an opaque type that may legitimately be zero on some implementations. Capture rc and check rc == 0 instead. - pthread_mutex_init / pthread_cond_init were paired with nothing in the destructor. Add pthread_*_destroy calls in ~RawChannel, gated by a new m_SyncInitialized flag (the sync primitives are only initialised on the successful constructor path, after a successful bind()). These are review-validated fixes; the races (and the Unref ordering) are hard or impossible to surface from a mocha test without thread- sanitizer instrumentation or kernel-level cooperation. No behavioural test is shipped — the Docker build-test passes 47/57 (same as master; the 10 failures are all pre-existing 'Error while creating channel' caused by missing vcan0/vcan1 in the build image). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix: validate signal offsets and reset restart cleanup; bump to 4.3.2 --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fix signal corruption and channel teardown bugs, and bump the patch version to 4.3.2.
Includes the CAN-FD and lifecycle fixes from the dependent branches. Master is merged into this branch; the remaining diff contains the fixes, tests, changelog, and version bump.
Type of change
Validation
The final file contents match the version validated with Apple Container on Linux ARM64, Node.js 22.23.2, and the custom SocketCAN-enabled kernel
6.18.5-cz-7800b4642171:vcan0/vcan1andNODE_CAN_RUN_PRIVILEGED_TESTS=1, including interface recovery/removal and restart cleanup.Final commit
e238305passed all 12 push and PR build/test jobs across Node.js 22.22.2, 24.15.0, and 26.x on x64 and ARM64. CodeQL analysis for Actions, C/C++, and JavaScript/TypeScript and the aggregate CodeQL check also passed.Checklist
pnpm run build:allpassespnpm testpasses with virtual CAN interfaces