- ooperatii_comune: verific_partener nu mai construieste SQL NULL cand contul primit e NULL (EMPTY(.NULL.) e .F. in VFP) - utile\context_watch.ps1 si utile\docs_revizie_check.ps1: masurarea contextului sesiunii si cadenta reviziei de documentatie, prin hook-uri Claude Code (instalare in docs\monitorizare-context.md) - reguli_lucru: delegare la subagenti, modificari minime si scoped, scrierea si revizuirea documentatiei, changelog strictul necesar (regulile 3, 6, 9, 11, 12) - scripturi-migrare-db: continutul unui script (scoped, fara select, idempotent) - teste noi pentru cele doua erori din achizitia de import - restul documentatiei compactata, fara pierdere de reguli Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RYbiinqXxdEqXi53x4Ro7K
72 lines
3.5 KiB
Markdown
72 lines
3.5 KiB
Markdown
# Capcană: corupere diacritice la editarea `.sc2`/`.vc2` (encoding cp1252)
|
|
|
|
Partajat între proiectele ROA* — capcana ține de formatul `.sc2`/`.vc2` produs de FoxBin2Prg,
|
|
nu de un proiect anume.
|
|
|
|
## De ce se întâmplă
|
|
|
|
Fișierele `.sc2`/`.vc2` sunt **cp1252** (Windows-1252), nu UTF-8 (vezi antetul: `CPID="1252"`).
|
|
Dacă un editor/tool citește fișierul ca UTF-8, fiecare byte >= 0x80 (diacritic) devine invalid
|
|
ca secvență UTF-8 și e înlocuit cu U+FFFD. Dacă tool-ul apoi **salvează tot ca UTF-8**, acel
|
|
U+FFFD e scris ca 3 octeți (`0xEF 0xBF 0xBD`) — care, citiți înapoi ca cp1252 (cum face
|
|
FoxBin2Prg la write-back), apar ca `�`. Caracterul original e **ireversibil pierdut**
|
|
(recuperabil DOAR din altă sursă: git history, backup).
|
|
|
|
Codebase-ul ROA "reciclează" caractere cp1252 fără echivalent direct pentru Ș/ă/ț:
|
|
|
|
| Literă românească | Caracter folosit (cp1252) | Byte |
|
|
|---|---|---|
|
|
| ă | ã (a-tilde) | `0xE3` |
|
|
| Ă | Ã | `0xC3` |
|
|
| ț | þ (thorn minuscul) | `0xFE` |
|
|
| Ș (majusculă) | ª (ordinal masculin) | `0xAA` |
|
|
| ș (minusculă) | º (ordinal feminin) | `0xBA` |
|
|
| î, â | î, â (native cp1252) | `0xEE`, `0xE2` |
|
|
|
|
Par "gunoi"/typo într-un editor UTF-8 (`ã`, `þ`, `ª`, `º`) — **sunt corecte, nu le "corecta"
|
|
fără să verifici encoding-ul.**
|
|
|
|
## Cum se verifică dacă un fișier `.sc2`/`.vc2` e corupt
|
|
|
|
```powershell
|
|
$bytes = [System.IO.File]::ReadAllBytes("<path>.vc2")
|
|
$text = [System.Text.Encoding]::GetEncoding(1252).GetString($bytes)
|
|
$text -split "`r`n" | Select-String ([char]0xFFFD) # cauta caracterul de replacement
|
|
```
|
|
|
|
Dacă apare `�` (sau `$text` conține U+FFFD) — fișierul are corupere de encoding.
|
|
|
|
## Cum se repară
|
|
|
|
1. **Nu edita orbește peste corupere** — caracterul original e deja pierdut din fișierul curent.
|
|
2. Dacă corupera s-a întâmplat într-o sesiune anterioară necomisă (HEAD-ul git încă e curat):
|
|
recuperează originalul convertind binarul din HEAD în text:
|
|
```bash
|
|
git show HEAD:<cale>.vcx > /tmp/head.vcx
|
|
git show HEAD:<cale>.vct > /tmp/head.vct # (sau .VCT, dupa caz)
|
|
powershell -File D:\ROA\UTIL\foxbin2prg\vcx2txt.ps1 -Source /tmp/head.vcx -CacheRoot /tmp/head_out
|
|
```
|
|
apoi decodează ambele fișiere (HEAD curat + curent corupt) ca cp1252 și compară linie cu
|
|
linie (PowerShell, nu `diff`/Bash direct — nu decodează cp1252 corect la afișare, deși
|
|
detectează totuși diferența de octeți).
|
|
3. Reconstruiește fișierul text pornind de la versiunea HEAD (curată), reaplicând DOAR
|
|
modificările intenționate din sesiunea curentă (nu invers — nu cârpi fișierul corupt
|
|
caracter cu caracter).
|
|
4. Scrie rezultatul înapoi ca bytes cp1252
|
|
(`[System.Text.Encoding]::GetEncoding(1252).GetBytes(...)`), NU ca string UTF-8/`Out-File`
|
|
implicit.
|
|
5. Rulează write-back (`txt2vcx.ps1 -Force`) și verifică fidelity check = zero diferențe.
|
|
|
|
## Cum se evită pe viitor
|
|
|
|
Când editezi `.sc2`/`.vc2` cu tool-uri text (Read/Edit/Write), verifică întâi dacă fișierul
|
|
conține diacritice (`ã`, `þ`, `ª`, `º`, `î`, `â` etc.) — dacă da, **orice rescrie completă
|
|
trebuie făcută la nivel de octeți cu encoding cp1252 explicit**, nu presupunând UTF-8.
|
|
Editările punctuale (Edit tool, string replace) sunt sigure DOAR dacă tool-ul păstrează restul
|
|
fișierului byte-identic (nu rescrie tot fișierul reîncodat).
|
|
|
|
## Vezi și
|
|
|
|
`PROMPT_cautare_vfp.md` din acest folder, pasul 3.c — menționează riscul pe scurt; acest fișier
|
|
e detalierea completă (tabel de caractere, pași de recuperare din git).
|