» »

Odkrit resen hrošč v PHP 5.3.7

Odkrit resen hrošč v PHP 5.3.7

Slashdot - V prejšnji teden izdani novi verziji skriptnega jezika PHP 5.3.7 so odkrili resno ranljivost, zaradi katere avtorji priporočajo, da z nadgradnjo počakamo. Čeprav je bila inačica 5.3.7 izdana prav z namenom počistiti zalego hroščev, kar ji je dobro uspelo, je prinesla novega.

Odkrili so namreč napako v kriptografski funkciji crypt(). Kadar ta uporablja kodirni algoritem MD5, potem vrača enostavno le vrednost uporabljenega salta. Pri uporabi drugih algoritmov, recimo Blowfish ali DES, težav ni. Napaka je bila odkrita in javljena v sredo, dan pred izidom nove verzije. Razvijalci so problem že diagnosticirali in izdelali popravek, ki bo vključen v PHP 5.3.8, ki bo izšel kmalu. Do takrat pa uporabnikom priporočajo uporabo PHP 5.3.6.

50 komentarjev

«
1
2

MrBrdo ::

function crypt($str, $salt) {
  // this should return the md5 hash
  return $salt;
}

komično :)
MrBrdo

Spura ::

> PHP
> 2011
ISHYGDDT

MrStein ::

Avtomatski unit testi? Kaj je to?
Ah nič, saj je open source in bo nekdo odkril, ter tudi popravil...
Motiti se je človeško.
Motiti se pogosto je neumno.
Vztrajati pri zmoti je... oh, pozdravljen!

Ales ::

Saj je nekdo odkril in popravil. In ja, en od bolj glupih bugov, kar jih pomnim. Tvoj point je, da se v zaprtokodnem programju kaj takega ne more zgodit?

jype ::

MrStein> Avtomatski unit testi? Kaj je to?

V PHP? Si resen?

BlueRunner ::

Nov moto za PHP...

PHP 5.3.7: Please enter your username and any password.

ali pa "Welcome to PHP 5.3.7, where any password will do just fine."

>:D

To je skoraj tako "komično" kot "optimizacija" RNG pri Ubuntu. Čeprav je imel tisti bug mnogo bolj daljnosežne posledice... :(

joebanana ::

jype je izjavil:

MrStein> Avtomatski unit testi? Kaj je to?

V PHP? Si resen?


Zakaj ne?

Sergio ::

@Spura: Torej: Java 7 je sranje, Java 6 je sranje, C# je zanic, PHP je fail, c je prevec hardcore...

Kaj ti torej sploh ustreza? :)
Tako grem jaz, tako gre vsak, kdor čuti cilj v daljavi:
če usoda ustavi mu korak,
on se ji zoperstavi.

KaRkY ::

When you look long into an abyss, the abyss looks into you

Mavrik ::

Sergio je izjavil:

@Spura: Torej: Java 7 je sranje, Java 6 je sranje, C# je zanic, PHP je fail, c je prevec hardcore...

Kaj ti torej sploh ustreza? :)


Resni itak programirajo COBOL. COBOL.NET.
The truth is rarely pure and never simple.

Senitel ::

Sergio je izjavil:

Kaj ti torej sploh ustreza? :)

Logo? >:D

MrStein ::

Ales je izjavil:

Saj je nekdo odkril in popravil. In ja, en od bolj glupih bugov, kar jih pomnim. Tvoj point je, da se v zaprtokodnem programju kaj takega ne more zgodit?

Point je lepo bil zapisan v prvem stavku.
Evo še enkrat: testi
Motiti se je človeško.
Motiti se pogosto je neumno.
Vztrajati pri zmoti je... oh, pozdravljen!

Ales ::

Se pravi da si tisto o open source slučajno napisal zraven? ;)

MrStein ::

Ne, to je letelo na določeno skupino ljudi.
Motiti se je človeško.
Motiti se pogosto je neumno.
Vztrajati pri zmoti je... oh, pozdravljen!

jype ::

joebanana> Zakaj ne?

Because nobody cares, that's why.

Unit testing je v mnogih okoljih del razvojne paradigme - a ne v PHP.

fiction ::

BlueRunner je izjavil:

ali pa "Welcome to PHP 5.3.7, where any password will do just fine."
>:D
Hehe. V bistvu bolj "where no password will work". Šele, če si na 5.3.7 spremenil password, je potem prijelo kar koli I guess. Kar pa itak ne bi smel brez tega da vpišeš staro geslo (razen če to dela kak admin ali pa kakšen "forgot my password" feature).

BlueRunner je izjavil:


To je skoraj tako "komično" kot "optimizacija" RNG pri Ubuntu. Čeprav je imel tisti bug mnogo bolj daljnosežne posledice... :(
To misliš na tisti Debian OpenSSL fiasko? Predvsem je bilo tisto dlje skrito, ker je zgledalo kot da vseeno nekaj dela.

Zanimivo kakšen je diff.

dbevfat ::

jype je izjavil:

joebanana> Zakaj ne?

Because nobody cares, that's why.

Unit testing je v mnogih okoljih del razvojne paradigme - a ne v PHP.

PHP (kot jezik) ima ogromno avtomatskih testov in kar nekaj odličnih orodij za testiranje PHP kode, povsem na nivoju, ali še višje, kot ostali "konkurenčni" jeziki. Vse od enostavnih unit testov, prek browser testingov z Minkom, do continuous integrationa. Ni problem v jeziku, problem je v odnosu in znanju. Očitno tudi v tvojem. ;)

Kar pa ne zmanjša neumnosti tega buga ... le kako jim je uspelo, ker crypt funkcija ima svoje teste?
nvr2fat

jype ::

dbevfat> Kar pa ne zmanjša neumnosti tega buga ... le kako jim je uspelo, ker crypt funkcija ima svoje teste?

That's what I said:

jype> Unit testing je v mnogih okoljih del razvojne paradigme - a ne v PHP.

Putr ::

jype je izjavil:

joebanana> Zakaj ne?

Because nobody cares, that's why.

Unit testing je v mnogih okoljih del razvojne paradigme - a ne v PHP.


To je stigma php programerja (kot mi je pripovedoval en C# developer) se nas vidi kot opice k poogoglajo kako se naredi, copy/paste, poogoglajo zakaj ne dela, copy/paste.
Verjeti ali ne ostajajo tudi "pravi" programerji v phpju. Mnogi izmed njih pa tudi uporabljamo unit teste.

BDW Bug je že popravljen (5 min nazaj so spustil .8).
Unit testing je v mnogih okoljih del razvojne paradigme - a ne v PHP.

@jype A lahko prosim dobimo tvoje reference in podrobno obrazložitve tvoje trditve. Ker ti si itak najpametnješi kot vsi profesionalni php programerji.

Zgodovina sprememb…

  • spremenil: Putr ()

fiction ::

Sem pogledal php_crypt_r.c. Tista implementacija bi morala bit broken samo na UNIX-u in ne pri Windows buildih - nobeden tega ni izpostavil v bug reportu.

Zanimiva je primerjava z verzijo od PHK-ja crypt_md5.c. PHP ni spremenil praktično ničesar...

Offending commit

memcpy(passwd, MD5_MAGIC, MD5_MAGIC_LEN);
strlcpy(passwd + MD5_MAGIC_LEN, sp, sl + 1);
strXXXcat(passwd, "$", YYY);
...
p = passwd + sl + MD5_MAGIC_LEN + 1;
...


strcat() - kot je predlagan fix - je v konkretnem primeru praktično isto kot strlcat(), right? Kako to potem lahko karkoli reši?! Razlika od prej je, da je bil prej strncat() z 1, kar pomeni, da ni ASCII 0 terminirov stringa.

Ampak potem itak s p še naprej čaraš po tem stringu. Pointer p bi moral kazati na prvi naslednji znak (kamor potem napišeš rezultat MD5 magica).

Problem bi bil samo, če p kaže en znak preveč naprej. Hm base + length v bistvu že kaže na naslednji znak, se pravi je tista 1 preveč ali sem kaj spregledal? Potemtakem je že od začetka v izhodu od php_md5_crypt_r() vedno en neinicializiran bajt. Tukaj je samo težava v tem, da je "security fix" povzročil, da je ta bajt postal 0, kar je potem prehitro končalo string.

Brane2 ::

Meni ni jasno, kako lahko kdo fukne kaj takega v source, ne da bi ga zaščemelo v kosteh.
On the journey of life, I chose the psycho path.

jype ::

Putr> Verjeti ali ne ostajajo tudi "pravi" programerji v phpju.

Ja, saj jaz sem eden izmed njih, a se PHPja otepam, ker me prepogosto pusti na cedilu.

Putr> @jype A lahko prosim dobimo tvoje reference in podrobno obrazložitve tvoje trditve. Ker ti si itak najpametnješi kot vsi profesionalni php programerji.

Reference? Napisal sem že več sto tisoč vrstic PHP kode, razvil štiri razširitve za PHP, žal pa to vse pri delodajalcih, ki niso dovolili objave oziroma distribucije ustvarjenega. To je bilo, ko sem bil še majhen, pa se mi ni zdelo pomembno delat za delodajalca, ki ceni prosto programje in se potrudi vračati uslugo skupnosti.

Nekje po spletu se recimo še vedno valja md5crypt.php, ki sem ga v tistih časih prepisal iz pythona in je potem za nekaj let postal del več PHP projektov, ki so morali znat računat posoljene MD5 zgostitve.

fiction ::

V crypt manualu piše "As of PHP 5.3.0, PHP contains its own implementation and will use that if the system lacks of support for one or more of the algorithms.". Kako lahko forcaš uporabo PHP-jevskih implementacij, po možnosti brez tega, da bi moral pohekati configure?

Meni se namreč dozdeva, da PHP-jev crypt() nikoli ni delal prav ter da ta fix v 5.3.8 v bistvu tudi ne reši problema. Problemov pa ponavadi ni, ker se itak uporabi sistemski crypt().

Senitel ::

fiction je izjavil:



memcpy(passwd, MD5_MAGIC, MD5_MAGIC_LEN);
strlcpy(passwd + MD5_MAGIC_LEN, sp, sl + 1);
strXXXcat(passwd, "$", YYY);
...
p = passwd + sl + MD5_MAGIC_LEN + 1;
...


strcat() - kot je predlagan fix - je v konkretnem primeru praktično isto kot strlcat(), right? Kako to potem lahko karkoli reši?! Razlika od prej je, da je bil prej strncat() z 1, kar pomeni, da ni ASCII 0 terminirov stringa.

strcat skopira src string (drugi parameter) na konec dst stringa (prvi parameter). strlcat skopira samo dokler je skupna dolžina dst stringa < length (tretji parameter).
strncat skopira največ len (tretji parameter) znakov v dst.
Problematična koda na konec passwd stringa ni pripela "$".

Pa on-topic... To ni PHP development... To je C development. >:D

P.S.: Sicer ne vem kako točno define postavlja glede na okolje, ampak glede na #if PHP_WIN32 in #if _MSC_VER >= 1500 tole zadane samo win32 builde na Visual C++ 6.0 (antika).

P.S.2.: Second look pove, da sem falil vrstico... Unix only ja.

Zgodovina sprememb…

  • spremenil: Senitel ()

BlueRunner ::

@fiction: kudos, da si me opozoril, da je bil "izvorni greh" v Debian-u, ne v Ubuntu.

To je stigma php programerja (kot mi je pripovedoval en C# developer) se nas vidi kot opice k poogoglajo kako se naredi, copy/paste, poogoglajo zakaj ne dela, copy/paste.

Ne mešaj tistih, ki programirajo v okolju PHP s tistimi, ki programirajo okolje PHP. Če kaj, potem so drugi dejansko C programerji. PHP je rezultat njihovega dela.

Si pa drznem misliti, da ta ekipa razvijalcev res nima ravno kakšnega posebej razvitega odnosa do tega sistema in prevečkrat deluje po sistemu "WorksForMe™". Kar je v osnovi njihova stvar, ampak mene to recimo odbija od celotnega sistema.

fiction ::

Senitel: Hvala glede strlcat(). Sem si narobe predstavljal length parameter pri teh funkcijah.

Khm, samo a ni potem tudi
strlcpy(passwd + MD5_MAGIC_LEN, sp, sl + 1);

malo čuden? Čisto konceptualno bi temu raje rekel strncpy(), ker sl navezuje na to koliko od sp je uporabnega (do kam je res salt).

MrStein ::

Senitel je izjavil:


Pa on-topic... To ni PHP development... To je C development. >:D

Točno tak.
A bo zdaj jype rekel, da tudi C-jaši ne testirajo?
Motiti se je človeško.
Motiti se pogosto je neumno.
Vztrajati pri zmoti je... oh, pozdravljen!

Senitel ::

fiction: l v strl* nakazuje največjo dolžino stringa (length), n v strn* nakazuje največ kolk se bo kopiral (number of chars to copy).
Tale vrstica je mal tricky ker je dst passwd + MD5_MAGIC_LEN. Torej se dejanski string začne šele na MD5_MAGIC_LEN znaku passwd in od tam naprej gre do največ sl. Imaš pa še par konceptualnih razlik npr. strl* da vedno \0 na konec in ne pada \0 vse do konca stringa, če v src prej zmanjka znakov.

fiction ::

Po postu od Sentinela mi je vse skupaj končno malo bolj jasno. Fix je ok in moje hipoteze napačne, se opravičujem. Prej se '$' zaradi napačnega razumevanja strlcat() ni skopiral (avtor je očitno prav tako kot jaz narobe razumel parameter length oz. ni preučil manuala).

Točno ta '$' je tudi vzrok za tisto + 1 v p. Jaz sem vse skupaj intepretiral kot (v psevdokodi) buffer[length(buffer)], kar je pri zero-based indexih že 1 naprej od konca, buffer[length(buffer) + 1] bi bil pa typo, ki se pogosto pojavlja. Nisem pa upošteval tega nesrečnega '$' na koncu salta, ki ni vštet v nobeno dolžino. Z strlcat() je bila pa 1 res preveč in potem je bil
tam ASCII 0, ki je končal string, kljub temu da je bil za tem v pomnilniku še vedno pravi MD5, sam kaj ko so stringi zero terminated.

BlueRunner ::

Tole s "ni preučil manuala" je pri uporabi libc str* funkcij kar precej pogosta napaka, ki se zgodi tudi kakšnem starejšem mačku.

Težava se je izgleda pokazala v točki, da unit teste imajo, vendar pa jih ne poganjajo pred vsakim releasom. Kar kaže na splošen odnos teh razvijalcev do unit testov.

Resnici na ljubo pa so unit testi pri programerjih tipično precej osovraženi. Večino časa so vsi "zeleni", trošijo ti pa čas, ko bi rad stvar že enkrat zaključil. No... ko se opečeš, postanejo stvar rutine, ker ti je tisti čas več kot bolj poplačan s tem, da si izogneš letu ali dvem zafrkavanja s strani svojih "sotrpinov", ko ti zaradi nepotrebne napake, ki bo jo test ujel gazijo ego.

Pri tistih pa, ki se vedno znova opečejo (recimo kolektivno kot ekipa, ker pri projektih veriga je močna samo toliko kot najšibkejši člen), pa svojega obnašanja ne spremenijo... kaj naj rečem. Stran od njih.

Zgodovina sprememb…

jype ::

MrStein> A bo zdaj jype rekel, da tudi C-jaši ne testirajo?

Kaj tebi ni jasno? PHP development je že leta tak, to nima zveze z jezikom, v katerem je razvit, ima pa veliko zveze z načinom, kako se reč razvija.

fiction ::

Senitel je izjavil:

fiction: l v strl* nakazuje največjo dolžino stringa (length), n v strn* nakazuje največ kolk se bo kopiral (number of chars to copy).
Tale vrstica je mal tricky ker je dst passwd + MD5_MAGIC_LEN. Torej se dejanski string začne šele na MD5_MAGIC_LEN znaku passwd in od tam naprej gre do največ sl. Imaš pa še par konceptualnih razlik npr. strl* da vedno \0 na konec in ne pada \0 vse do konca stringa, če v src prej zmanjka znakov.
Ja, sej ta passwd + MD5_MAGIC_LEN mi je jasen, don't worry. In vse skupaj tudi čisto lepo dela (ker je ta string za enkrat prazen).

Ni mi všeč samo zaradi tega, ker gre pri strlcat() očitno za to, "koliko dam lahko še v ciljni buffer da bo max toliko poln kolikor hočem" (oz. da ne bo buffer overflowa), medtem ko je pri strncat() vprašanje "koliko od izvora lahko vzamem" (spet lahko z istim namenom). In pri tisti vrstici gre za to, koliko iz salta vzamem. Da ne pride do overflowa je že implicitno zagotovljeno s tem, da je dolžina salta lahko največ 8, kar spet ni ravno najlepše dokumentirano IMHO.

Zbrka je zaradi tega, ker je vsak kratek opis strlcat v stilu "safe-version of strncat", zato pač pomisliš na to, da je malo bolj poskrbljeno za null termination ali pa kakšna druga malenkost, nikakor pa ne, da length pomeni nekaj čisto drugega.

fiction ::

BlueRunner je izjavil:

Težava se je izgleda pokazala v točki, da unit teste imajo, vendar pa jih ne poganjajo pred vsakim releasom. Kar kaže na splošen odnos teh razvijalcev do unit testov.
Če imajo res unit teste je kul, ampak mene bolj skrbi, da imajo samo neke PHP test-case. Potem sicer lahko rečeš testiral bom crypt del, sam kaj ko na tem nivoju nimaš več pojma o tem a testiraš sistemski crypt(), PHP-jevo crypt() implementacijo ali pa neko čudno mešanico obojega.

BlueRunner ::

Hm. Pa saj za končen efekt je to čisto vseeno. Unit test je ravno to - unit test. Če škatlica dela pravilno, dela pravilno, če ne dela pravilno, greš gledati kje, kaj, zakaj, ... V kontekstu testiranja je vseeno zakaj dobi uporabnik razvojnega ogrodja ven napačen rezultat. To je pomembno samo v kontekstu odprave napake, kjer je unit test zamo "vhoden podatek", ostalo pa morajo narediti male sive celice.

MrStein ::

jype je izjavil:

MrStein> A bo zdaj jype rekel, da tudi C-jaši ne testirajo?

Kaj tebi ni jasno? PHP development je že leta tak, to nima zveze z jezikom, v katerem je razvit, ima pa veliko zveze z načinom, kako se reč razvija.

Hecno, par postov višje pa piše, da imajo unit teste.
Motiti se je človeško.
Motiti se pogosto je neumno.
Vztrajati pri zmoti je... oh, pozdravljen!

fiction ::

Tudi za C obstaja precej unit test frameworkov.

MrStein je izjavil:

Hecno, par postov višje pa piše, da imajo unit teste.
Ne vem, če imajo unit teste. O tem nisem prepričan, zgooglov sem samo to, da imajo QA team, ki skrbi za PHPT fajle (torej teste v PHP-ju) in ti se izvedejo tudi, ko rečeš "make test". Verjetno kar nekaj od teh testov napišejo tudi sami razvijalci.

BlueRunner je izjavil:

Hm. Pa saj za končen efekt je to čisto vseeno. Unit test je ravno to - unit test.
Ja, unit test je to, da stestiraš posamezno opeko preden iz večih različnih zgradiš hišo. Ampak če delaš samo tako kot sumim da dela PHP team (correct me if i'm wrong), je pa to v bistvo funkcionalno testiranje. Gledaš če je bajta ok, ne moreš pa takrat več reči zdaj bom pa pogledal to ta spodnjo opeko, če sama zase dovolj dobro funkcionira. Lahko da je tam pristala sistemska opeka, pa se to ne vidi zaradi ometa.

BlueRunner ::

Imaš point. Kaj je unit test pri razvojnem okvirju? Testiranje crypt funkcije, kot jo vidi uporabnik, ali testiranje česa drugega...

No, za konkreten primer, kot je bil zgoraj podan, je testiranje PHP crypt funkcije IMHO kar "unit test". Njena konkretna implementacija pa je nerelevantna, ker se jo testira kot osnoven gradnik. Roko na srce, ni to ravno neka uber kompleksna funkcija, da bi jo imelo smisla razbijati na manjše gradnike.

MrStein ::

Unit test bi bil:

char * result = php_md5_crypt_r("password","salt","foo");
if (strcmp(result,"precomputed result"))  fail_test("php_md5_crypt_r() failed");
Motiti se je človeško.
Motiti se pogosto je neumno.
Vztrajati pri zmoti je... oh, pozdravljen!

dbevfat ::

jype je izjavil:

dbevfat> Kar pa ne zmanjša neumnosti tega buga ... le kako jim je uspelo, ker crypt funkcija ima svoje teste?
That's what I said:
jype> Unit testing je v mnogih okoljih del razvojne paradigme - a ne v PHP.

Dal sem celo link direktno do testa za funkcijo crypt. Lahko ti dam linke do milijona test fajlov, namenjenih testiranju core PHP funkcij. Kako to sovpada s tvojo izjavo, da testing ni del razvojne paradigme PHP-ja?
nvr2fat

fiction ::

MrStein: Exactly.

Nekako podobno temu bi moral izgledati _unit test_, medtem ko to da zbuildaš cel PHP in potem v PHP-ju poskusiš, če dela crypt z MD5, _ni več_ unit test. To je bil ves čas moj point, ampak zgleda, da sem se preveč crypt()-ično izrazil :)
Ampak česa takega ne najdem nikjer v PHP sourcu. Čisto možno, da gledam na napačnem koncu ali pa unit testov preprosto ni.

Drugo vprašanje, ki ga imam v zvezi s tem je, kako da na OpenSUSE (po PHP bug reportu) ni delal sistemski crypt z MD5? A ni ta del itak v glibc in bi moral delati na praktično vsaki Linux distribuciji? Poleg tega vem, da je na BSD-jih to 100 % implementirano (če ne drugega od tam izvira). Edino na MacOS X MD5 ni supported pri crypt(), ker se uporablja nek FreeSec 1.0 lib za to.

jype ::

dbevfat> Kako to sovpada s tvojo izjavo, da testing ni del razvojne paradigme PHP-ja?

Novica> Odkrit resen hrošč v PHP 5.3.7

Tako.

dbevfat ::

jype je izjavil:

dbevfat> Kako to sovpada s tvojo izjavo, da testing ni del razvojne paradigme PHP-ja?
Novica> Odkrit resen hrošč v PHP 5.3.7
Tako.

To, da je odkrit resen hrošč, ni dokaz tvoje trditve, da avtomatično testiranje ni del razvojne paradigme PHP-ja. Naj te spomnim. Osebne preference do PHP gor ali dol, posploševanje in zaničevanje nekega jezika zaradi lastnega nepoznavanja situacije ni lastnost dobrega razvijalca.
nvr2fat

jype ::

Uh, z zaničevanjem jezika raje sploh začel ne bi...

dbevfat> To, da je odkrit resen hrošč, ni dokaz tvoje trditve, da avtomatično testiranje ni del razvojne paradigme PHP-ja.

Ja, je. Avtomatično testiranje _je_ del paradigme ravno zato, da se take reči _ne morejo_ zgoditi.

Ne morem si predstavljat, kako lahko kdorkoli objavi različico, ki ni bila avtomatično testirana, če je avtomatično testiranje del razvojnega cikla (in postopka objave nove različice) - pa pri PHP očitno ni.

Če bi bila, bi test spodletel in napaka ne bi prišla med uporabnike.

dbevfat ::

jype je izjavil:

Uh, z zaničevanjem jezika raje sploh začel ne bi...

dbevfat> To, da je odkrit resen hrošč, ni dokaz tvoje trditve, da avtomatično testiranje ni del razvojne paradigme PHP-ja.

Ja, je. Avtomatično testiranje _je_ del paradigme ravno zato, da se take reči _ne morejo_ zgoditi.

Ne morem si predstavljat, kako lahko kdorkoli objavi različico, ki ni bila avtomatično testirana, če je avtomatično testiranje del razvojnega cikla (in postopka objave nove različice) - pa pri PHP očitno ni.

Če bi bila, bi test spodletel in napaka ne bi prišla med uporabnike.

Če tvojo logiko razširim, pri nobenem jeziku avtomatično testiranje ni del razvojne paradigme. Ne obstaja tak, ki še ni imel vsaj enega velikega hrošča.

Mogoče samo prehitro sklepaš. Obstoj avtomatičnih testov in testnega okolja za laufanje le-teh (hudiča, cel web site imajo posvečen samo testiranju platforme) ti mora biti jasen namig, da PHP te zadeve ima in podpira kot integralni del razvojnega cikla. Lahko da je šlo za človeško napako nekje v procesu, lahko je proces testiranja bil pognan in je crknil (kakšen nov bug v test runnerju morda?). Lahko samo mogoče ni bil napisan test za crypt md5, bil pa je za ostalih 5 hashov in enkripcij. Vse te možnosti so povsem verjetne, ti pa takoj z gotovostjo trdiš, da je vzrok v razvojni paradigmi.

Seveda od tebe ne pričakujem, da boš priznal, da si prehitro in pregrobo ocenil situacijo, v razmislek na skrivaj naj ti pa bo.
nvr2fat

MrStein ::

Ja, če bi se jasneje izražal, vi vsi vedeli, da govori isto kot jaz in ne bi bilo te "debate".
Motiti se je človeško.
Motiti se pogosto je neumno.
Vztrajati pri zmoti je... oh, pozdravljen!

jype ::

dbevfat> Če tvojo logiko razširim, pri nobenem jeziku avtomatično testiranje ni del razvojne paradigme. Ne obstaja tak, ki še ni imel vsaj enega velikega hrošča.

Dej preberi diff od spornega commita, no.

dbevfat ::

jype je izjavil:

dbevfat> Če tvojo logiko razširim, pri nobenem jeziku avtomatično testiranje ni del razvojne paradigme. Ne obstaja tak, ki še ni imel vsaj enega velikega hrošča.
Dej preberi diff od spornega commita, no.

Če je to največ, kar si sposoben dati od sebe, sem ti očitno uspel razložiti.
nvr2fat

micro77 ::

Sami PHP haterji.

Rajši vložite čas v učenje le-tega, pa vam ne bo več odžiral 99% trga.

PaX_MaN ::

Hvala, imam raje kaj drugega in zaradi manjšega stresa 15 let daljše življenje.
«
1
2


Vredno ogleda ...

TemaSporočilaOglediZadnje sporočilo
TemaSporočilaOglediZadnje sporočilo
»

Odkrit resen hrošč v PHP 5.3.7 (strani: 1 2 )

Oddelek: Novice / Varnost
5017067 (14834) Spura
»

PHP4 se počasi poslavlja

Oddelek: Novice / Omrežja / internet
374333 (2965) sverde21
»

Namestitev Apache 2.x in PHP5.x

Oddelek: Izdelava spletišč
71384 (1329) yoshi
»

PHP - objektno programiranje

Oddelek: Izdelava spletišč
344195 (3583) Trubadur

Več podobnih tem