From 4201643fc5426cd7e98941930fc9b9e978f45871 Mon Sep 17 00:00:00 2001 From: vchuser Date: Tue, 28 Jul 2026 14:41:24 +0200 Subject: [PATCH] Fix Samsung density-code regex to honor fixed field width The lazy quantifier {4,6}? never expanded beyond its minimum because the trailing greedy [A-Z0-9]* always absorbed the rest up to the hyphen, so a longer density code would silently be truncated to 5 chars and could match an unrelated table entry, producing wrong specs instead of null. The density code is actually fixed-width (A + 4 chars); the revision after it is the variable part. Tighten the pattern to {4}, rewrite the stale comment (which still claimed a fixed 3-char revision), and add a test that every Samsung density key is exactly 5 characters so a future mismatched table entry can't silently become unreachable. Co-Authored-By: Claude Opus 5 (1M context) --- src/pn-tables.js | 16 +++++++++------- test/pn-decoder.test.js | 8 ++++++++ 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/pn-tables.js b/src/pn-tables.js index 62b67a6..23c943d 100644 --- a/src/pn-tables.js +++ b/src/pn-tables.js @@ -10,13 +10,15 @@ export const VENDOR_TABLES = [ { vendor: 'Samsung', - // M-- - // Hinweis: Die im Brief angegebene Fassung dieses Musters liess die - // fuehrende Generationskennung 'A' ausserhalb der Erfassungsgruppe und - // erfasste dadurch nie den vollstaendigen Dichte-Code 'A8K40' - die - // Tabellensuche schlug immer fehl. Hier korrigiert: 'A' gehoert zur - // erfassten Dichte-Gruppe, die Revision hat feste Laenge 3. - pattern: /^M(\d{3})(A[A-Z0-9]{4,6}?)[A-Z0-9]*-([A-Z]{3})/, + // M- + // Der Dichte-Code hat feste Breite: die Generationskennung 'A' plus vier + // weitere Zeichen, also fuenf insgesamt. Die Revision danach ist die + // variable Groesse und wird nicht separat erfasst. Der + // Geschwindigkeitscode sind die drei Buchstaben direkt nach dem + // Bindestrich. Achtung: Ein Dichte-Code abweichender Laenge kann von + // diesem Muster nicht erfasst werden - ein solcher Tabelleneintrag + // bliebe wirkungslos, die Tabellensuche schluege dafuer stets fehl. + pattern: /^M(\d{3})(A[A-Z0-9]{4})[A-Z0-9]*-([A-Z]{3})/, formFactor: { 378: 'UDIMM', 391: 'UDIMM', diff --git a/test/pn-decoder.test.js b/test/pn-decoder.test.js index d61a6e9..f82bbdd 100644 --- a/test/pn-decoder.test.js +++ b/test/pn-decoder.test.js @@ -1,6 +1,7 @@ import { test } from 'node:test'; import assert from 'node:assert/strict'; import { decodePartNumber } from '../src/pn-decoder.js'; +import { VENDOR_TABLES } from '../src/pn-tables.js'; test('dekodiert die Samsung-Teilenummer aus dem Referenzmodul', () => { const spec = decodePartNumber('M386A8K40BM1-CRC4Y'); @@ -55,3 +56,10 @@ test('erkennt Bauform und Geschwindigkeit auch mit vierteiliger Revision', () => assert.equal(spec.capacityGb, null, 'unbekannter Dichte-Code laesst das Feld offen'); assert.equal(spec.partNumber, 'M393A2K43BBX1-CTD'); }); + +test('Samsung-Dichte-Codes sind exakt fuenf Zeichen lang (feste Feldbreite im Muster)', () => { + const samsung = VENDOR_TABLES.find((table) => table.vendor === 'Samsung'); + for (const key of Object.keys(samsung.density)) { + assert.equal(key.length, 5, `Dichte-Code '${key}' hat nicht die geforderte Laenge 5 und waere im Muster wirkungslos`); + } +});