fix: keep the full 5-byte OTA counter on increments (v3.6.23)
spNextCntr coerced the 40-bit replay counter with `>>> 0`, so any counter above FFFFFFFF lost its top byte after an accepted send: the live 10000AAAC8 came back as 00000AAAC9, and spCntrSyncPreset then stored the broken value in the card preset - the RAM/Explore flows (ramIncrementCntr, which is correct) inherited it. - spNextCntr: 40-bit arithmetic (`% 0x10000000000`, wrap at FFFFFFFFFF kept) instead of the 32-bit >>> 0 coercion plus slice(-10). - spCntrAdjust (+/-): the same 40-bit wrap (an 11-digit value could be produced at the maximum). - tests: 10000AAAC8 -> 10000AAAC9, separator handling, FFFFFFFFF7 -> FFFFFFFFF8, FFFFFFFFFFF -> 0000000000 wrap, out-of-range input clamps. The server side (_increment_counter_hex, _ram_next_cntr, final_cntr) was already exact. 653 frontend / 500 Python green; version 3.6.23; sw simple-v296.
This commit is contained in:
@@ -253,6 +253,14 @@ test('spNextCntr increments with carry', () => {
|
||||
assert.strictEqual(spNextCntr('0000ABCDEF'), '0000ABCDF0');
|
||||
});
|
||||
|
||||
test('spNextCntr keeps the full 5 bytes (no 32-bit truncation)', () => {
|
||||
assert.strictEqual(spNextCntr('10000AAAC8'), '10000AAAC9'); // the reported case
|
||||
assert.strictEqual(spNextCntr('1000 0AAAC8'), '10000AAAC9'); // separators stripped
|
||||
assert.strictEqual(spNextCntr('FFFFFFFFF7'), 'FFFFFFFFF8');
|
||||
assert.strictEqual(spNextCntr('FFFFFFFFFF'), '0000000000'); // 40-bit wrap
|
||||
assert.strictEqual(spNextCntr('10000000000'), '0000000001'); // out of range clamps
|
||||
});
|
||||
|
||||
test('spNextCntr tolerates lower case and separators', () => {
|
||||
assert.strictEqual(spNextCntr('00000000 0a'), '000000000B');
|
||||
assert.strictEqual(spNextCntr(''), '0000000001');
|
||||
|
||||
Reference in New Issue
Block a user