dillon1000/react
Commit
Browse files [DevTools] Fix printOperationsArray decode of applied activity slice change (#36935)
`printOperationsArray` in `react-devtools-shared` walks an operations
array under
the invariant that each `switch` case leaves `i` pointing at the next
opcode (loop
header at `packages/react-devtools-shared/src/utils.js`).
The `TREE_OPERATION_APPLIED_ACTIVITY_SLICE_CHANGE` case broke that
invariant:
```js
case TREE_OPERATION_APPLIED_ACTIVITY_SLICE_CHANGE: {
i++; // skip opcode -> i now at the value slot
const activitySliceIDChange = operations[i + 1]; // reads the slot AFTER the value; i not advanced
...
}
```
The operation is exactly two slots, `[opcode, activitySliceID]` (see the
writer in
`packages/react-devtools-shared/src/backend/fiber/renderer.js`, which
pushes the
opcode then the id). So the case did two things wrong:
1. It logged the wrong number: `operations[i + 1]` reads the slot
*after* the
value (the next operation's opcode, or `undefined` at the end of the
array).
2. It left `i` pointing at the value slot, so the outer `while (i <
operations.length)` loop re-read the activity-slice id as an opcode. For
any
non-zero slice id that falls through to `default: throw
Error("Unsupported
Bridge operation ...")`, aborting the whole dump.
The two canonical decoders of this same operation both use the correct
pattern
(skip the opcode, then read *and* advance past the value):
- `devtools/store.js`: `i++; nextActivitySliceID = operations[i++];`
- `devtools/views/Profiler/CommitTreeBuilder.js`: `i++; const
activitySliceIDChange = operations[i++];`
This change makes `printOperationsArray` match them by reading
`operations[i++]`.
This is a debug-only diagnostic path: the only caller is the
`__DEBUG__`-guarded
dump in `backend/legacy/renderer.js`, so it is not a production crash.
The bug was
introduced in #34908.
## How did you test this change?
Added a regression test for `printOperationsArray` in
`packages/react-devtools-shared/src/__tests__/utils-test.js`. The
fixture chains
two activity-slice operations, `[rendererID, rootID, stringTableSize=0,
opcode, 42,
opcode, 0]`; the trailing operation is what forces the reader to advance
past the
first value slot rather than re-read it. It asserts the call does not
throw, logs
once, and that the message contains both `Applied activity slice change
to 42` and
`Reset applied activity slice`.
Ran the DevTools Jest project (built first, as that project requires a
build):
- With the fix: 51/51 pass, including the new test.
- Reverting only the one-line fix back to `operations[i + 1]` and
rebuilding: the
new test fails with `Unsupported Bridge operation "42"` (exactly the
predicted
failure), 50 pass / 1 fail. Restored the fix and it is green again.
`yarn prettier-check` and `yarn linc` are clean on the changed files.Changed paths2 files
First-parent comparisonpackages/react-devtools-shared/src/__tests__/utils-test.js ModifiedM packages/react-devtools-shared/src/utils.js ModifiedPatch
Files changed
Rendering syntax-highlighted changes…