PHP és Oracle nemes harca a 64-bites bigendian platformok ellen

Ez persze egy sokéves történet, amit már sokszor felhoztam, részletek itt.
Na de most újra ránéztem, és a következő szépséget pillantottam meg:

#if defined(OCI_MAJOR_VERSION) && (OCI_MAJOR_VERSION > 10) && \
        (defined(__x86_64__) || defined(__LP64__) || defined(_LP64) || defined(_WIN64))
    typedef ub8 oci_phpsized_int;
#else
    typedef ub4 oci_phpsized_int;
#endif

Vagyis még ha a PHP maga 64-bites, ha az Oracle10-es vagy régebbi, akkor ez a oci_phpsized_int 32-bites lesz (ub4: Oracle nyelven unsigned, 4 bytes).

Namostan ha egyvalami biztos, akkor az az, hogy ezt valaki valamilyen segítő megkönnyítésként tette oda, áldassék a neve. Azt mégis túlzás lenne elvárni tőle, hogy odategyen mellé valami magyarázatot, esetleg egy linket egy hibajegyre, vagy bármi ilyesmi...

Szintén nem várható tőle, hogy belegondoljon, hogy big-endian platformon ez is gondot okoz, amikor a saját nyolcbájtos 'zend_long' típusának a pointerét a négybájtos 'oci_phpsized_int' típus pointerévé alakítva adja át az Oracle-nak.

Persze az annál is érthetőbb, mivel az egész bugreport erről szól, és az elmúlt öt évben még egy 'too long, did not read' szerű reakció sem jött semmilyen fejlesztőtől.

Hozzászólások

Meg szerencse, hogy van itthon popcorn.

A strange game. The only winning move is not to play. How about a nice game of chess?

Nem igazán, de már kezdek arra gondolni, hogy valamilyen régebbi bűnömért a karma a 'problémás hibakeresések felelőse' beosztást adományozta nekem.

Már a BS2000-időkben is így volt, pl. amikor a 'nincs alloca(3), de kellene, valahogy csinálj' című feladat jutott nekem. Vagy az, hogy 'az IDA nevű debugger jószándékúan felülír egy bizonyos bitet a programban egy rögzített címen, mit tegyünk?'

Szerkesztve: 2021. 08. 26., cs – 17:04

Namostan ha egyvalami biztos, akkor az az, hogy ezt valaki valamilyen segítő megkönnyítésként tette oda, áldassék a neve. Azt mégis túlzás lenne elvárni tőle, hogy odategyen mellé valami magyarázatot, esetleg egy linket egy hibajegyre, vagy bármi ilyesmi...

Ha hozzáhozzáférsz, megkeresheted a commitot a VCS-ben. Persze ha nincs szerencséd akkor egy több ezer soros commitban adták hozzá aminek teljesen általános message-e van.

Szerk: https://github.com/php/php-src/commit/fa3615f14ee9c0be361d8c45251f9d30c…

Köszönöm a linket, így elsőre úgy látom, ez a php_sized_int korábban fixen ub4 volt, de az Oracle10-zel már akkor is kavartak.

Kieg: Ki fogsz nevetni, de én ennyi év után csak tegnap tudtam meg, hogy van github-juk, és ott lenne érdemes pull-request-tel próbálkozni. Itt szólta el magát valaki: https://bugs.php.net/bug.php?id=81382

ilyenkor nem a php kavar, hanem az oracle10 library hasznal belul 32bites szamot, ha te oda beletolsz egy barmilyen 64 bites szamot, akkor valamit felul fogsz irni amit nemkene, es ebbol lesznek a vulnerability-k :D. ezert a php ezt lekezeli, es ha o10 feletti a library akkor a hasznal 64bites szamokat, ha o10 akkor csak 32 biteseket hasznal.

A vegtelen ciklus is vegeter egyszer, csak kelloen eros hardver kell hozza!

Ebben van valami, a bug74625 hivatkozik a bug68298-ra, az pedig erre az Oracle doksira, ami azt mondja, hogy 11.2-től képes 64-bites bind-változók kezelésére.

A 68298 azt teszi szóvá, hogy egy 64-bites PHP-változó címét adják át az Orának, azzal, hogy 'nesze, itt egy négybájtos objektum címe'. Ez lett a javítás. Szóval Oracle-10 esetén maradjon a hibás működés.

Marad még az a kérdés, hogy ki értett félre mit. Az én kis méréseim szerint a 64-bites Oracle10-es kliens (10.2.0.5) jól elműködget 64-bit számokkal.

Lehet, hogy arra gondolt a költő, hogy Ora11-től már a 32-bites kliens is kezeli a 64-bites változókat. Ez igaz, csak nem releváns a jelen esetben.

Kieg: Mondjuk ha megnézzük az OCIBindByPos-t, látjuk, hogy van egy valuep meg egy value_sz, az előbbi az adatunk címe, a második a hossza. Pl.


    long l;
    OCIBindByPos (..., &l, sizeof l, SQLT_INT, ...);

Namostan amennyire tudom, ez minden klienssel megy, viszont 32-bites Orace10 esetén ez nem megy:


    long long ll;
    OCIBindByPos (..., &ll, sizeof ll, SQLT_INT, ...);

Szóval ha 64-bites számmal akarunk dolgozni, akkor vagy 64-bites programot kell alkotnunk (64-bit Oracle klienssel), vagy maradni 32-biten, de a klienssel feljebb lépni 11+ -ra.