Egy napos reggelen a laptopom előtt ültem, és átalakítottam egy C# kódot. Minden jól megy, és eredményes nap lesz. Aztán túl sok egyenlő jelet tettem hozzá a konstans zsinórhoz, és minden felrobbant. A termelékenység eltűnt. A vasárnapi nyugodt újjáépítés már mögöttünk van. Még a nap is úgy döntött, hogy a felhők mögé bújik.
30-40 perc után próbáltam rájönni, mit csinálok rosszul, rájöttem, hogy nem én vagyok a hibás. Ez a Microsoft. Úgy tűnik, egy régi hibára bukkantam a Base64 dekódoló funkcióban.Convert.FromBase64StringEz a hiba mindenképpen 2003-ban megjelent .NET 1.1 óta. Hú! Ez régi. És nem túl nehéz reprodukálni. Szép munka:
Technikailag ez illegális Base64. A jogi verzió "abc=". Megjegyzés: csak egy töltelék karakter =. A Base64 kódolás minden 6 bites bináris bemenetet egy ASCII karakterben jeleníti meg. Ez azt jelenti, hogy egy Base64 kódolt stringben minden 4 karakter 3 bájtot képvisel. Ha a kódolt adat nem 3 bájt többszöröse, a Base64 kódoló egy töltőkaraktert ad hozzá, így a Base64 4 karakter többszöröse lesz. Ez egy Base64 stringet generál, amely megfelelően van feltöltve "abc="-vel. Ha hozzáadunk egy másik =-t, érvényteleníti.
A Base64 "abc=" két bájtként van dekódolva [105, 183]. Így van. Ha a végén egy másik párnázási karaktert adunk hozzá, nem igazán változtathatná meg a kódolt értéket. Olyan, mintha egy mondat végére szóközet adnál hozzá. Igen, ott van, de nem változtatja meg a mondat jelentését. De a .NET nem így gondolja. Az "abc==" bájtként van dekódolva [109]. Nemcsak rövidebb lett, ami furcsa volt, mert hosszabbá tettük a bemenetet. Ez is mássá vált. Az első bájt 105-ről 109-re megy. És ez sem hozott kivételt. Ha hozzáadunk egy másik =-et, kivételt kapsz. Csodálatos!
Kód:
Hozam:
'abc=' -> [105, 183] 'abc==' -> [109] Igazán csodálatos, hogy senki sem vette észre ezt ennyi évek óta. Vagy megtalálták, de nem javították. A Base64 nagyon fontos az információcserében a hálózaton. Mindenhol látható. Azonban a .NET évek óta nem szabadult meg a hibás Base64 dekódertől.
Eleinte nem hittem el, és elkezdtem nyomozni. Egy ideig kerestem a Google-ben, de nem találtam sok információt. Aztán posztoltam a StackOverflow-ra, de nem volt sok szerencsém. Miután rájöttem, mi történik, még a saját kérdéseimet is meg kellett válaszolnom. Miután egy ideig kerestem a GitHubon, rábukkantam egy javításra, amit 2018 júliusában készítettek .NET Core-ban. Tehát a legfrissebb .NET Core verzió helyesen kezeli ezt a problémát, és kivételt dob:
Kezeletlen kivétel: System.FormatException: A bemenet nem érvényes Base-64 string, mivel tartalmaz egy nem alap 64 karaktert, több mint két töltő karaktert, vagy egy illegális karaktert a Karakterek párnázása. at System.Convert.FromBase64CharPtr(Char* inputPtr, Int32 inputLength) a System.Convert.FromBase64String(String s) címen a Program.DecodeAndPrint (String base64) címen a ./base64/Program.cs:line 13 a program.main() oldalon ./base64/Program.cs:line 8 Körülbelül 15 évbe telt, mire megtalálták és megjavították a problémát. Érdekes módon senki sem próbálta igazán megoldani. Ez akkor történt, amikor újraírták a kódot, hogy gyorsabb legyen:
A Convert.FromBase64() apró hibája van, amikor a lánc végén a második illegálisan kipárolt karakter miatt a dekódolás "sikeres" lesz, ha eltávolítja az utolsó előtti karaktert.
Mi itt vagyunk. Ezt a hibát véletlenül javították, amikor az API-t a NetCore 2.1-ben optimalizálták. Teszteket adjunk hozzá a hibák naplózásához, és győződj meg róla, hogy ne menünk vissza. Tehát ezt a problémát a .NET Core 2.2-ben orvosolták. De a .NET Framework 4.7.2 legfrissebb verziójában még mindig vannak problémák. Úgy tűnik, Mono is elromlott.
A .NET 4.7.2 megoldása, hogy a rosszul feltöltött stringet valami ilyesmivel töltjük ki:
Eredeti:A hiperlink bejelentkezés látható.
|