Skip to content

FIX Prof id pasted with its separator spaces is truncated (SIREN, SIRET) - #39679

Open
daGrumpf-bxp wants to merge 1 commit into
Dolibarr:24.0from
daGrumpf-bxp:fix/profid-paste-with-separator-spaces
Open

FIX Prof id pasted with its separator spaces is truncated (SIREN, SIRET)#39679
daGrumpf-bxp wants to merge 1 commit into
Dolibarr:24.0from
daGrumpf-bxp:fix/profid-paste-with-separator-spaces

Conversation

@daGrumpf-bxp

@daGrumpf-bxp daGrumpf-bxp commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

FIX Prof id pasted with its separator spaces is truncated (SIREN, SIRET)

A SIREN is presented everywhere as 849 943 618, a SIRET as 849 943 618 00012 — on the Kbis, on the INSEE certificate, on the invoices of the third party. That is what the user copies, and what they paste into "Id prof 1" / "Id prof 2" of a third party.

The input built by FormCompany::get_input_id_prof() carries maxlength="9" (resp. 14), and that length counts the pasted spaces. The browser silently drops the end of the paste, and the third party is recorded with 849 943 6. Nothing warns about it, and at a glance the value looks right.

Reproduce (France, MAIN_DISABLEPROFIDRULES off)

  1. Third party → new, copy 849 943 618 and paste it in "Id prof 1 (SIREN)"
  2. The field holds 849 943 6 — three digits short
  3. Save: llx_societe.siren = 849 943 6, and the card shows a "wrong value" warning

Worse than the warning: pasting an id that is a few characters too long, say 84994361812, truncates to 849943618, which passes the Luhn check and displays with its link to the public directory. A slip silently becomes another company's identity.

Fix

The separator spaces are removed from the pasted text before it is inserted, so maxlength applies to the id itself rather than to its presentation.

Widening maxlength would not do: it counts characters, not separators, so three digits too many would go through just as well as three spaces — the length guard would be lost for the exact case above.

  • isProfIdWithoutSpace() tells whether a space in a prof id can only be a separator. That is the case of the ids isValidProfIds() checks, since each of those checks strips the spaces first: FR 1 and 2, ES/PT/DZ/BE 1.
  • get_input_id_prof() marks those inputs with data-profidnospace. No maxlength changes, on any field.
  • lib_head.js.php gets a delegated paste handler on input[data-profidnospace]: it cleans the pasted text and inserts it with execCommand("insertText"), which keeps the undo history and — unlike setRangeText — remains subject to the field's maxlength. A paste with nothing to clean is left to the browser untouched.

A French idprof4 keeps the spaces of RCS Poitiers B 849 943 618, since it carries no marker.

Tests

test/phpunit/ProfidLibTest.php gets testIsProfIdWithoutSpace().

Checked by hand on a 24.0 instance, France, third party creation then edit, with real Ctrl+V pastes:

pasted field recorded
849 943 618 (idprof1) 849943618 849943618
732 829 320 00074 (idprof2) 73282932000074 73282932000074
84994361812 (idprof1, 11 digits) 849943618 — truncated to 9, as before this PR
73282932000074999 (idprof2, 17 digits) 73282932000074 — truncated to 14, as before this PR
RCS Poitiers B 732 829 320 (idprof4) unchanged RCS Poitiers B 732 829 320
732 829 320 00074 77 (idprof1) 732829320 — the SIREN 732829320
732 829 320 00074 77 (idprof2) 73282932000074 — the SIRET 73282932000074

The card then shows 849 943 618 and 732 829 320 00074, grouped again by dol_print_profids(), with no "wrong value" warning.

The last two rows are worth a word: French ids nest by prefix — a SIRET is the 9 digits of the SIREN followed by the 5 of the NIC. Once the separators are out of the way, the maxlength each field already had isolates exactly the right id, so pasting a whole SIRET into "Id prof 1" now yields the SIREN. The same paste used to give 732 829 3 there, and 732 829 320 00 in "Id prof 2" — two values fit for the bin.


The bug is old and present on every maintained branch; I am targeting 24.0 because the fix adds a function to profid.lib.php. Say the word and I retarget to develop, or to an older branch if you would rather have it there.

@daGrumpf-bxp
daGrumpf-bxp force-pushed the fix/profid-paste-with-separator-spaces branch from 3337da1 to 7e2b820 Compare August 23, 2026 18:57
A SIREN is presented everywhere as "849 943 618" and a SIRET as "849 943 618
00012", so that is what a user copies. The input built by get_input_id_prof()
carries maxlength=9 (resp. 14), and that length counts the pasted spaces: the
browser silently drops the end of the paste and the third party is recorded
with "849 943 6". Nothing warns about it, and the value looks right at a
glance.

The spaces are now removed from the pasted text before it is inserted, so that
maxlength applies to the id itself instead of to its presentation. Widening
maxlength would not do: it counts characters, not separators, and three digits
too many would go through just as well as three spaces.

The paste handler lives in lib_head.js.php and only acts on the inputs marked
by get_input_id_prof() with data-profidnospace, that is the ids whose recorded
value never holds a space (isProfIdWithoutSpace(): the ones isValidProfIds()
checks after having removed the spaces). A French idprof4 keeps the spaces of
"RCS Poitiers B 849 943 618", and every maxlength stays exactly what it was.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012WXV1H3xDj9tnAKfSw5DSU
@daGrumpf-bxp
daGrumpf-bxp force-pushed the fix/profid-paste-with-separator-spaces branch from 7e2b820 to 252b617 Compare August 23, 2026 19:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant