Files
comun/docs/conventie_encoding_cp1252.md
Marius Mutu 940bb39701 Import eFactura in lot: borderou cu ce lipseste, coada de contabilizare, alegerea contului
Borderoul tine per factura ce mai are de completat si daca are articole de gestiune
(camp gest, coloana si filtru), coada contabilizeaza in serie facturile bifate si
incheie cu un rezumat, iar contul de furnizor/client se alege din planul de conturi.
Cheia normalizata de articol, rezolvarea automata a partenerului si anularea in bloc
intra tot aici. Pozitia in lista se pastreaza peste reaplicarea filtrului.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Aroafxp4z8bmM5oVECZRXY
2026-09-09 22:06:48 +03:00

3.5 KiB

Capcana: corupere diacritice la editare (.sc2/.vc2 si orice fisier non-ASCII)

Comun tuturor proiectelor ROA*.

Regula generala (orice fisier)

Orice fisier care contine octeti non-ASCII (>= 0x80) se editeaza numai byte-safe - PowerShell [IO.File]::ReadAllText/WriteAllText cu GetEncoding(<codepage>) - niciodata cu Edit-ul agentului: acesta rescrie fisierul ca UTF-8 si inlocuieste octetii non-ASCII cu EF BF BD (caracterul de inlocuire), inclusiv in zone neatinse si inclusiv in .prg obisnuite, nu doar .sc2/.vc2. Cens obligatoriu inainte SI dupa editare: numarul si secventa octetilor >= 0x80 trebuie sa fie identice (citire ca bytes; comparatie cu git show HEAD:<cale> cand fisierul e urmarit).

Specific .sc2/.vc2 (FoxBin2Prg)

Tine de formatul .sc2/.vc2, nu de un proiect anume.

Faptul

Fisierele .sc2/.vc2 sunt cp1250 (Europa Centrala), nu UTF-8, desi antetul FoxBin2Prg declara CPID="1252" - eticheta din antet nu e adevarul despre encoding. Controalele cu text diacritic au FontCharSet = 238.

Tabelul de octeti (cp1250 real -> aparenta daca decodezi gresit ca cp1252)

Litera Byte Aparenta cp1252 gresita
a cu caciula minuscul 0xE3 a-tilde
A cu caciula majuscul 0xC3 A-tilde
i cu caciula minuscul 0xEE identic (zona comuna cp1250/cp1252)
I cu caciula majuscul 0xCE identic (zona comuna cp1250/cp1252)
a circumflex 0xE2 identic (zona comuna cp1250/cp1252)
t cu virgula minuscul 0xFE thorn minuscul
S cu virgula majuscul 0xAA ordinal masculin
s cu virgula minuscul 0xBA ordinal feminin

Nu "corecta" un s-cu-virgula crezand ca e typo - e litera corecta in cp1250.

Regula operationala

Orice scriere cu un tool care nu pastreaza octetii nativ (Edit/Write) corupe TOATE caracterele

= 0x80 din TOT fisierul (0xBA -> EF BF BD), chiar la o singura linie schimbata, si se repeta la FIECARE scriere. Nu re-encoda niciodata fisierul intreg: lucreaza pe octeti ([IO.File]::ReadAllBytes/WriteAllBytes cu GetEncoding(1250)) sau scrie strict ASCII in continutul nou. Editeaza tot ce ai de editat, verifica, repara o singura data DUPA ultima scriere.

Verificare (cens de octeti)

od -An -tx1 <fisier> | tr ' ' '\n' | grep -v '^$' | awk '$1>"7f"' | sort | uniq -c

La stricare censul CRESTE (un octet devine trei) - nu urmari doar scaderile. Cauta explicit secventa EF BF BD, nu tiparul generic C3/C4/C5/C8 (acela apare si in UTF-8 legitim din cod). Decodat cp1250, EF BF BD apare ca "�" in caption.

Varianta veche, utila cand cauti pozitia exacta (linia) a unui octet suspect:

perl -ne 'print "$.\n" if /[\x80-\xFF]/' <fisier>

Reparare

EF BF BD nu spune ce caracter s-a pierdut (toate diacriticele devin la fel) - inlocuirea oarba cu 0xBA strica alte litere din alte pozitii. Ia octetul corect per pozitie din svn cat <fisier> sau git cat-file blob <commit>:<cale>, din Bash, niciodata cu > din PowerShell 5.1 (adauga BOM si re-encodeaza). Scrie inapoi ca bytes cp1250 explicit, apoi txt2vcx.ps1 + fidelity check.

Coruperea se repeta la FIECARE scriere, nu doar la prima: editeaza tot ce ai de editat, verifica byte-level, si repara o singura data DUPA ultima scriere - nu intre editari.

Cazul simplu (s-a pierdut doar un octet, cel original cunoscut, ex. 0xBA pentru s-cu-virgula), inlocuire punctuala pe secventa corupta - acelasi risc de coliziune poate afecta si alte fisiere cu acelasi octet, nu doar pozitia curenta:

perl -e 'binmode(STDIN);binmode(STDOUT);local $/;$_=<STDIN>;s/\xEF\xBF\xBD/\xBA/g;print' < f > f.tmp