123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060 |
- #include <stdio.h>
- #include "php.h"
- #include "php_rand.h"
- #include "php_string.h"
- #include "php_variables.h"
- #include <locale.h>
- #ifdef HAVE_LANGINFO_H
- # include <langinfo.h>
- #endif
- #ifdef HAVE_LIBINTL
- # include <libintl.h> /* For LC_MESSAGES */
- #endif
- #include "scanf.h"
- #include "zend_API.h"
- #include "zend_execute.h"
- #include "php_globals.h"
- #include "basic_functions.h"
- #include "zend_smart_str.h"
- #include <Zend/zend_exceptions.h>
- #ifdef ZTS
- #include "TSRM.h"
- #endif
- #include "ext/standard/file.h"
- #include "ext/standard/html.h"
- #define STR_PAD_LEFT 0
- #define STR_PAD_RIGHT 1
- #define STR_PAD_BOTH 2
- #define PHP_PATHINFO_DIRNAME 1
- #define PHP_PATHINFO_BASENAME 2
- #define PHP_PATHINFO_EXTENSION 4
- #define PHP_PATHINFO_FILENAME 8
- #define PHP_PATHINFO_ALL (PHP_PATHINFO_DIRNAME | PHP_PATHINFO_BASENAME | PHP_PATHINFO_EXTENSION | PHP_PATHINFO_FILENAME)
- #define STR_STRSPN 0
- #define STR_STRCSPN 1
- void register_string_constants(INIT_FUNC_ARGS)
- {
- REGISTER_LONG_CONSTANT("STR_PAD_LEFT", STR_PAD_LEFT, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("STR_PAD_RIGHT", STR_PAD_RIGHT, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("STR_PAD_BOTH", STR_PAD_BOTH, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PATHINFO_DIRNAME", PHP_PATHINFO_DIRNAME, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PATHINFO_BASENAME", PHP_PATHINFO_BASENAME, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PATHINFO_EXTENSION", PHP_PATHINFO_EXTENSION, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PATHINFO_FILENAME", PHP_PATHINFO_FILENAME, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PATHINFO_ALL", PHP_PATHINFO_ALL, CONST_CS | CONST_PERSISTENT);
-
- REGISTER_LONG_CONSTANT("CHAR_MAX", CHAR_MAX, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("LC_CTYPE", LC_CTYPE, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("LC_NUMERIC", LC_NUMERIC, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("LC_TIME", LC_TIME, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("LC_COLLATE", LC_COLLATE, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("LC_MONETARY", LC_MONETARY, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("LC_ALL", LC_ALL, CONST_CS | CONST_PERSISTENT);
- # ifdef LC_MESSAGES
- REGISTER_LONG_CONSTANT("LC_MESSAGES", LC_MESSAGES, CONST_CS | CONST_PERSISTENT);
- # endif
- }
- int php_tag_find(char *tag, size_t len, const char *set);
- ZEND_SET_ALIGNED(16, static const char hexconvtab[]) = "0123456789abcdef";
- #ifdef ZTS
- static MUTEX_T locale_mutex = NULL;
- #endif
- static zend_string *php_bin2hex(const unsigned char *old, const size_t oldlen)
- {
- zend_string *result;
- size_t i, j;
- result = zend_string_safe_alloc(oldlen, 2 * sizeof(char), 0, 0);
- for (i = j = 0; i < oldlen; i++) {
- ZSTR_VAL(result)[j++] = hexconvtab[old[i] >> 4];
- ZSTR_VAL(result)[j++] = hexconvtab[old[i] & 15];
- }
- ZSTR_VAL(result)[j] = '\0';
- return result;
- }
- static zend_string *php_hex2bin(const unsigned char *old, const size_t oldlen)
- {
- size_t target_length = oldlen >> 1;
- zend_string *str = zend_string_alloc(target_length, 0);
- unsigned char *ret = (unsigned char *)ZSTR_VAL(str);
- size_t i, j;
- for (i = j = 0; i < target_length; i++) {
- unsigned char c = old[j++];
- unsigned char l = c & ~0x20;
- int is_letter = ((unsigned int) ((l - 'A') ^ (l - 'F' - 1))) >> (8 * sizeof(unsigned int) - 1);
- unsigned char d;
-
- if (EXPECTED((((c ^ '0') - 10) >> (8 * sizeof(unsigned int) - 1)) | is_letter)) {
- d = (l - 0x10 - 0x27 * is_letter) << 4;
- } else {
- zend_string_efree(str);
- return NULL;
- }
- c = old[j++];
- l = c & ~0x20;
- is_letter = ((unsigned int) ((l - 'A') ^ (l - 'F' - 1))) >> (8 * sizeof(unsigned int) - 1);
- if (EXPECTED((((c ^ '0') - 10) >> (8 * sizeof(unsigned int) - 1)) | is_letter)) {
- d |= l - 0x10 - 0x27 * is_letter;
- } else {
- zend_string_efree(str);
- return NULL;
- }
- ret[i] = d;
- }
- ret[i] = '\0';
- return str;
- }
- PHPAPI struct lconv *localeconv_r(struct lconv *out)
- {
- #ifdef ZTS
- tsrm_mutex_lock( locale_mutex );
- #endif
- #if defined(PHP_WIN32) && _MSC_VER < 1900 && defined(ZTS)
- {
-
- _locale_t cur = _get_current_locale();
- *out = *cur->locinfo->lconv;
- _free_locale(cur);
- }
- #else
-
- *out = *localeconv();
- #endif
- #ifdef ZTS
- tsrm_mutex_unlock( locale_mutex );
- #endif
- return out;
- }
- #ifdef ZTS
- PHP_MINIT_FUNCTION(localeconv)
- {
- locale_mutex = tsrm_mutex_alloc();
- return SUCCESS;
- }
- PHP_MSHUTDOWN_FUNCTION(localeconv)
- {
- tsrm_mutex_free( locale_mutex );
- locale_mutex = NULL;
- return SUCCESS;
- }
- #endif
- PHP_FUNCTION(bin2hex)
- {
- zend_string *result;
- zend_string *data;
- ZEND_PARSE_PARAMETERS_START(1, 1)
- Z_PARAM_STR(data)
- ZEND_PARSE_PARAMETERS_END();
- result = php_bin2hex((unsigned char *)ZSTR_VAL(data), ZSTR_LEN(data));
- RETURN_STR(result);
- }
- PHP_FUNCTION(hex2bin)
- {
- zend_string *result, *data;
- ZEND_PARSE_PARAMETERS_START(1, 1)
- Z_PARAM_STR(data)
- ZEND_PARSE_PARAMETERS_END();
- if (ZSTR_LEN(data) % 2 != 0) {
- php_error_docref(NULL, E_WARNING, "Hexadecimal input string must have an even length");
- RETURN_FALSE;
- }
- result = php_hex2bin((unsigned char *)ZSTR_VAL(data), ZSTR_LEN(data));
- if (!result) {
- php_error_docref(NULL, E_WARNING, "Input string must be hexadecimal string");
- RETURN_FALSE;
- }
- RETVAL_STR(result);
- }
- static void php_spn_common_handler(INTERNAL_FUNCTION_PARAMETERS, int behavior)
- {
- zend_string *s11, *s22;
- zend_long start = 0, len = 0;
- bool len_is_null = 1;
- ZEND_PARSE_PARAMETERS_START(2, 4)
- Z_PARAM_STR(s11)
- Z_PARAM_STR(s22)
- Z_PARAM_OPTIONAL
- Z_PARAM_LONG(start)
- Z_PARAM_LONG_OR_NULL(len, len_is_null)
- ZEND_PARSE_PARAMETERS_END();
- size_t remain_len = ZSTR_LEN(s11);
- if (start < 0) {
- start += remain_len;
- if (start < 0) {
- start = 0;
- }
- } else if ((size_t) start > remain_len) {
- start = remain_len;
- }
- remain_len -= start;
- if (!len_is_null) {
- if (len < 0) {
- len += remain_len;
- if (len < 0) {
- len = 0;
- }
- } else if ((size_t) len > remain_len) {
- len = remain_len;
- }
- } else {
- len = remain_len;
- }
- if (len == 0) {
- RETURN_LONG(0);
- }
- if (behavior == STR_STRSPN) {
- RETURN_LONG(php_strspn(ZSTR_VAL(s11) + start ,
- ZSTR_VAL(s22) ,
- ZSTR_VAL(s11) + start + len ,
- ZSTR_VAL(s22) + ZSTR_LEN(s22) ));
- } else {
- ZEND_ASSERT(behavior == STR_STRCSPN);
- RETURN_LONG(php_strcspn(ZSTR_VAL(s11) + start ,
- ZSTR_VAL(s22) ,
- ZSTR_VAL(s11) + start + len ,
- ZSTR_VAL(s22) + ZSTR_LEN(s22) ));
- }
- }
- PHP_FUNCTION(strspn)
- {
- php_spn_common_handler(INTERNAL_FUNCTION_PARAM_PASSTHRU, STR_STRSPN);
- }
- PHP_FUNCTION(strcspn)
- {
- php_spn_common_handler(INTERNAL_FUNCTION_PARAM_PASSTHRU, STR_STRCSPN);
- }
- #if HAVE_NL_LANGINFO
- PHP_MINIT_FUNCTION(nl_langinfo)
- {
- #define REGISTER_NL_LANGINFO_CONSTANT(x) REGISTER_LONG_CONSTANT(#x, x, CONST_CS | CONST_PERSISTENT)
- #ifdef ABDAY_1
- REGISTER_NL_LANGINFO_CONSTANT(ABDAY_1);
- REGISTER_NL_LANGINFO_CONSTANT(ABDAY_2);
- REGISTER_NL_LANGINFO_CONSTANT(ABDAY_3);
- REGISTER_NL_LANGINFO_CONSTANT(ABDAY_4);
- REGISTER_NL_LANGINFO_CONSTANT(ABDAY_5);
- REGISTER_NL_LANGINFO_CONSTANT(ABDAY_6);
- REGISTER_NL_LANGINFO_CONSTANT(ABDAY_7);
- #endif
- #ifdef DAY_1
- REGISTER_NL_LANGINFO_CONSTANT(DAY_1);
- REGISTER_NL_LANGINFO_CONSTANT(DAY_2);
- REGISTER_NL_LANGINFO_CONSTANT(DAY_3);
- REGISTER_NL_LANGINFO_CONSTANT(DAY_4);
- REGISTER_NL_LANGINFO_CONSTANT(DAY_5);
- REGISTER_NL_LANGINFO_CONSTANT(DAY_6);
- REGISTER_NL_LANGINFO_CONSTANT(DAY_7);
- #endif
- #ifdef ABMON_1
- REGISTER_NL_LANGINFO_CONSTANT(ABMON_1);
- REGISTER_NL_LANGINFO_CONSTANT(ABMON_2);
- REGISTER_NL_LANGINFO_CONSTANT(ABMON_3);
- REGISTER_NL_LANGINFO_CONSTANT(ABMON_4);
- REGISTER_NL_LANGINFO_CONSTANT(ABMON_5);
- REGISTER_NL_LANGINFO_CONSTANT(ABMON_6);
- REGISTER_NL_LANGINFO_CONSTANT(ABMON_7);
- REGISTER_NL_LANGINFO_CONSTANT(ABMON_8);
- REGISTER_NL_LANGINFO_CONSTANT(ABMON_9);
- REGISTER_NL_LANGINFO_CONSTANT(ABMON_10);
- REGISTER_NL_LANGINFO_CONSTANT(ABMON_11);
- REGISTER_NL_LANGINFO_CONSTANT(ABMON_12);
- #endif
- #ifdef MON_1
- REGISTER_NL_LANGINFO_CONSTANT(MON_1);
- REGISTER_NL_LANGINFO_CONSTANT(MON_2);
- REGISTER_NL_LANGINFO_CONSTANT(MON_3);
- REGISTER_NL_LANGINFO_CONSTANT(MON_4);
- REGISTER_NL_LANGINFO_CONSTANT(MON_5);
- REGISTER_NL_LANGINFO_CONSTANT(MON_6);
- REGISTER_NL_LANGINFO_CONSTANT(MON_7);
- REGISTER_NL_LANGINFO_CONSTANT(MON_8);
- REGISTER_NL_LANGINFO_CONSTANT(MON_9);
- REGISTER_NL_LANGINFO_CONSTANT(MON_10);
- REGISTER_NL_LANGINFO_CONSTANT(MON_11);
- REGISTER_NL_LANGINFO_CONSTANT(MON_12);
- #endif
- #ifdef AM_STR
- REGISTER_NL_LANGINFO_CONSTANT(AM_STR);
- #endif
- #ifdef PM_STR
- REGISTER_NL_LANGINFO_CONSTANT(PM_STR);
- #endif
- #ifdef D_T_FMT
- REGISTER_NL_LANGINFO_CONSTANT(D_T_FMT);
- #endif
- #ifdef D_FMT
- REGISTER_NL_LANGINFO_CONSTANT(D_FMT);
- #endif
- #ifdef T_FMT
- REGISTER_NL_LANGINFO_CONSTANT(T_FMT);
- #endif
- #ifdef T_FMT_AMPM
- REGISTER_NL_LANGINFO_CONSTANT(T_FMT_AMPM);
- #endif
- #ifdef ERA
- REGISTER_NL_LANGINFO_CONSTANT(ERA);
- #endif
- #ifdef ERA_YEAR
- REGISTER_NL_LANGINFO_CONSTANT(ERA_YEAR);
- #endif
- #ifdef ERA_D_T_FMT
- REGISTER_NL_LANGINFO_CONSTANT(ERA_D_T_FMT);
- #endif
- #ifdef ERA_D_FMT
- REGISTER_NL_LANGINFO_CONSTANT(ERA_D_FMT);
- #endif
- #ifdef ERA_T_FMT
- REGISTER_NL_LANGINFO_CONSTANT(ERA_T_FMT);
- #endif
- #ifdef ALT_DIGITS
- REGISTER_NL_LANGINFO_CONSTANT(ALT_DIGITS);
- #endif
- #ifdef INT_CURR_SYMBOL
- REGISTER_NL_LANGINFO_CONSTANT(INT_CURR_SYMBOL);
- #endif
- #ifdef CURRENCY_SYMBOL
- REGISTER_NL_LANGINFO_CONSTANT(CURRENCY_SYMBOL);
- #endif
- #ifdef CRNCYSTR
- REGISTER_NL_LANGINFO_CONSTANT(CRNCYSTR);
- #endif
- #ifdef MON_DECIMAL_POINT
- REGISTER_NL_LANGINFO_CONSTANT(MON_DECIMAL_POINT);
- #endif
- #ifdef MON_THOUSANDS_SEP
- REGISTER_NL_LANGINFO_CONSTANT(MON_THOUSANDS_SEP);
- #endif
- #ifdef MON_GROUPING
- REGISTER_NL_LANGINFO_CONSTANT(MON_GROUPING);
- #endif
- #ifdef POSITIVE_SIGN
- REGISTER_NL_LANGINFO_CONSTANT(POSITIVE_SIGN);
- #endif
- #ifdef NEGATIVE_SIGN
- REGISTER_NL_LANGINFO_CONSTANT(NEGATIVE_SIGN);
- #endif
- #ifdef INT_FRAC_DIGITS
- REGISTER_NL_LANGINFO_CONSTANT(INT_FRAC_DIGITS);
- #endif
- #ifdef FRAC_DIGITS
- REGISTER_NL_LANGINFO_CONSTANT(FRAC_DIGITS);
- #endif
- #ifdef P_CS_PRECEDES
- REGISTER_NL_LANGINFO_CONSTANT(P_CS_PRECEDES);
- #endif
- #ifdef P_SEP_BY_SPACE
- REGISTER_NL_LANGINFO_CONSTANT(P_SEP_BY_SPACE);
- #endif
- #ifdef N_CS_PRECEDES
- REGISTER_NL_LANGINFO_CONSTANT(N_CS_PRECEDES);
- #endif
- #ifdef N_SEP_BY_SPACE
- REGISTER_NL_LANGINFO_CONSTANT(N_SEP_BY_SPACE);
- #endif
- #ifdef P_SIGN_POSN
- REGISTER_NL_LANGINFO_CONSTANT(P_SIGN_POSN);
- #endif
- #ifdef N_SIGN_POSN
- REGISTER_NL_LANGINFO_CONSTANT(N_SIGN_POSN);
- #endif
- #ifdef DECIMAL_POINT
- REGISTER_NL_LANGINFO_CONSTANT(DECIMAL_POINT);
- #endif
- #ifdef RADIXCHAR
- REGISTER_NL_LANGINFO_CONSTANT(RADIXCHAR);
- #endif
- #ifdef THOUSANDS_SEP
- REGISTER_NL_LANGINFO_CONSTANT(THOUSANDS_SEP);
- #endif
- #ifdef THOUSEP
- REGISTER_NL_LANGINFO_CONSTANT(THOUSEP);
- #endif
- #ifdef GROUPING
- REGISTER_NL_LANGINFO_CONSTANT(GROUPING);
- #endif
- #ifdef YESEXPR
- REGISTER_NL_LANGINFO_CONSTANT(YESEXPR);
- #endif
- #ifdef NOEXPR
- REGISTER_NL_LANGINFO_CONSTANT(NOEXPR);
- #endif
- #ifdef YESSTR
- REGISTER_NL_LANGINFO_CONSTANT(YESSTR);
- #endif
- #ifdef NOSTR
- REGISTER_NL_LANGINFO_CONSTANT(NOSTR);
- #endif
- #ifdef CODESET
- REGISTER_NL_LANGINFO_CONSTANT(CODESET);
- #endif
- #undef REGISTER_NL_LANGINFO_CONSTANT
- return SUCCESS;
- }
- PHP_FUNCTION(nl_langinfo)
- {
- zend_long item;
- char *value;
- ZEND_PARSE_PARAMETERS_START(1, 1)
- Z_PARAM_LONG(item)
- ZEND_PARSE_PARAMETERS_END();
- switch(item) {
- #ifdef ABDAY_1
- case ABDAY_1:
- case ABDAY_2:
- case ABDAY_3:
- case ABDAY_4:
- case ABDAY_5:
- case ABDAY_6:
- case ABDAY_7:
- #endif
- #ifdef DAY_1
- case DAY_1:
- case DAY_2:
- case DAY_3:
- case DAY_4:
- case DAY_5:
- case DAY_6:
- case DAY_7:
- #endif
- #ifdef ABMON_1
- case ABMON_1:
- case ABMON_2:
- case ABMON_3:
- case ABMON_4:
- case ABMON_5:
- case ABMON_6:
- case ABMON_7:
- case ABMON_8:
- case ABMON_9:
- case ABMON_10:
- case ABMON_11:
- case ABMON_12:
- #endif
- #ifdef MON_1
- case MON_1:
- case MON_2:
- case MON_3:
- case MON_4:
- case MON_5:
- case MON_6:
- case MON_7:
- case MON_8:
- case MON_9:
- case MON_10:
- case MON_11:
- case MON_12:
- #endif
- #ifdef AM_STR
- case AM_STR:
- #endif
- #ifdef PM_STR
- case PM_STR:
- #endif
- #ifdef D_T_FMT
- case D_T_FMT:
- #endif
- #ifdef D_FMT
- case D_FMT:
- #endif
- #ifdef T_FMT
- case T_FMT:
- #endif
- #ifdef T_FMT_AMPM
- case T_FMT_AMPM:
- #endif
- #ifdef ERA
- case ERA:
- #endif
- #ifdef ERA_YEAR
- case ERA_YEAR:
- #endif
- #ifdef ERA_D_T_FMT
- case ERA_D_T_FMT:
- #endif
- #ifdef ERA_D_FMT
- case ERA_D_FMT:
- #endif
- #ifdef ERA_T_FMT
- case ERA_T_FMT:
- #endif
- #ifdef ALT_DIGITS
- case ALT_DIGITS:
- #endif
- #ifdef INT_CURR_SYMBOL
- case INT_CURR_SYMBOL:
- #endif
- #ifdef CURRENCY_SYMBOL
- case CURRENCY_SYMBOL:
- #endif
- #ifdef CRNCYSTR
- case CRNCYSTR:
- #endif
- #ifdef MON_DECIMAL_POINT
- case MON_DECIMAL_POINT:
- #endif
- #ifdef MON_THOUSANDS_SEP
- case MON_THOUSANDS_SEP:
- #endif
- #ifdef MON_GROUPING
- case MON_GROUPING:
- #endif
- #ifdef POSITIVE_SIGN
- case POSITIVE_SIGN:
- #endif
- #ifdef NEGATIVE_SIGN
- case NEGATIVE_SIGN:
- #endif
- #ifdef INT_FRAC_DIGITS
- case INT_FRAC_DIGITS:
- #endif
- #ifdef FRAC_DIGITS
- case FRAC_DIGITS:
- #endif
- #ifdef P_CS_PRECEDES
- case P_CS_PRECEDES:
- #endif
- #ifdef P_SEP_BY_SPACE
- case P_SEP_BY_SPACE:
- #endif
- #ifdef N_CS_PRECEDES
- case N_CS_PRECEDES:
- #endif
- #ifdef N_SEP_BY_SPACE
- case N_SEP_BY_SPACE:
- #endif
- #ifdef P_SIGN_POSN
- case P_SIGN_POSN:
- #endif
- #ifdef N_SIGN_POSN
- case N_SIGN_POSN:
- #endif
- #ifdef DECIMAL_POINT
- case DECIMAL_POINT:
- #elif defined(RADIXCHAR)
- case RADIXCHAR:
- #endif
- #ifdef THOUSANDS_SEP
- case THOUSANDS_SEP:
- #elif defined(THOUSEP)
- case THOUSEP:
- #endif
- #ifdef GROUPING
- case GROUPING:
- #endif
- #ifdef YESEXPR
- case YESEXPR:
- #endif
- #ifdef NOEXPR
- case NOEXPR:
- #endif
- #ifdef YESSTR
- case YESSTR:
- #endif
- #ifdef NOSTR
- case NOSTR:
- #endif
- #ifdef CODESET
- case CODESET:
- #endif
- break;
- default:
- php_error_docref(NULL, E_WARNING, "Item '" ZEND_LONG_FMT "' is not valid", item);
- RETURN_FALSE;
- }
-
- value = nl_langinfo(item);
- if (value == NULL) {
- RETURN_FALSE;
- } else {
- RETURN_STRING(value);
- }
- }
- #endif
- PHP_FUNCTION(strcoll)
- {
- zend_string *s1, *s2;
- ZEND_PARSE_PARAMETERS_START(2, 2)
- Z_PARAM_STR(s1)
- Z_PARAM_STR(s2)
- ZEND_PARSE_PARAMETERS_END();
- RETURN_LONG(strcoll((const char *) ZSTR_VAL(s1),
- (const char *) ZSTR_VAL(s2)));
- }
- static inline int php_charmask(const unsigned char *input, size_t len, char *mask)
- {
- const unsigned char *end;
- unsigned char c;
- int result = SUCCESS;
- memset(mask, 0, 256);
- for (end = input+len; input < end; input++) {
- c=*input;
- if ((input+3 < end) && input[1] == '.' && input[2] == '.'
- && input[3] >= c) {
- memset(mask+c, 1, input[3] - c + 1);
- input+=3;
- } else if ((input+1 < end) && input[0] == '.' && input[1] == '.') {
-
- if (end-len >= input) {
- php_error_docref(NULL, E_WARNING, "Invalid '..'-range, no character to the left of '..'");
- result = FAILURE;
- continue;
- }
- if (input+2 >= end) {
- php_error_docref(NULL, E_WARNING, "Invalid '..'-range, no character to the right of '..'");
- result = FAILURE;
- continue;
- }
- if (input[-1] > input[2]) {
- php_error_docref(NULL, E_WARNING, "Invalid '..'-range, '..'-range needs to be incrementing");
- result = FAILURE;
- continue;
- }
-
- php_error_docref(NULL, E_WARNING, "Invalid '..'-range");
- result = FAILURE;
- continue;
- } else {
- mask[c]=1;
- }
- }
- return result;
- }
- static zend_always_inline zend_string *php_trim_int(zend_string *str, const char *what, size_t what_len, int mode)
- {
- const char *start = ZSTR_VAL(str);
- const char *end = start + ZSTR_LEN(str);
- char mask[256];
- if (what) {
- if (what_len == 1) {
- char p = *what;
- if (mode & 1) {
- while (start != end) {
- if (*start == p) {
- start++;
- } else {
- break;
- }
- }
- }
- if (mode & 2) {
- while (start != end) {
- if (*(end-1) == p) {
- end--;
- } else {
- break;
- }
- }
- }
- } else {
- php_charmask((const unsigned char *) what, what_len, mask);
- if (mode & 1) {
- while (start != end) {
- if (mask[(unsigned char)*start]) {
- start++;
- } else {
- break;
- }
- }
- }
- if (mode & 2) {
- while (start != end) {
- if (mask[(unsigned char)*(end-1)]) {
- end--;
- } else {
- break;
- }
- }
- }
- }
- } else {
- if (mode & 1) {
- while (start != end) {
- unsigned char c = (unsigned char)*start;
- if (c <= ' ' &&
- (c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == '\v' || c == '\0')) {
- start++;
- } else {
- break;
- }
- }
- }
- if (mode & 2) {
- while (start != end) {
- unsigned char c = (unsigned char)*(end-1);
- if (c <= ' ' &&
- (c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == '\v' || c == '\0')) {
- end--;
- } else {
- break;
- }
- }
- }
- }
- if (ZSTR_LEN(str) == end - start) {
- return zend_string_copy(str);
- } else if (end - start == 0) {
- return ZSTR_EMPTY_ALLOC();
- } else {
- return zend_string_init(start, end - start, 0);
- }
- }
- PHPAPI zend_string *php_trim(zend_string *str, const char *what, size_t what_len, int mode)
- {
- return php_trim_int(str, what, what_len, mode);
- }
- static zend_always_inline void php_do_trim(INTERNAL_FUNCTION_PARAMETERS, int mode)
- {
- zend_string *str;
- zend_string *what = NULL;
- ZEND_PARSE_PARAMETERS_START(1, 2)
- Z_PARAM_STR(str)
- Z_PARAM_OPTIONAL
- Z_PARAM_STR(what)
- ZEND_PARSE_PARAMETERS_END();
- ZVAL_STR(return_value, php_trim_int(str, (what ? ZSTR_VAL(what) : NULL), (what ? ZSTR_LEN(what) : 0), mode));
- }
- PHP_FUNCTION(trim)
- {
- php_do_trim(INTERNAL_FUNCTION_PARAM_PASSTHRU, 3);
- }
- PHP_FUNCTION(rtrim)
- {
- php_do_trim(INTERNAL_FUNCTION_PARAM_PASSTHRU, 2);
- }
- PHP_FUNCTION(ltrim)
- {
- php_do_trim(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
- }
- PHP_FUNCTION(wordwrap)
- {
- zend_string *text;
- char *breakchar = "\n";
- size_t newtextlen, chk, breakchar_len = 1;
- size_t alloced;
- zend_long current = 0, laststart = 0, lastspace = 0;
- zend_long linelength = 75;
- bool docut = 0;
- zend_string *newtext;
- ZEND_PARSE_PARAMETERS_START(1, 4)
- Z_PARAM_STR(text)
- Z_PARAM_OPTIONAL
- Z_PARAM_LONG(linelength)
- Z_PARAM_STRING(breakchar, breakchar_len)
- Z_PARAM_BOOL(docut)
- ZEND_PARSE_PARAMETERS_END();
- if (ZSTR_LEN(text) == 0) {
- RETURN_EMPTY_STRING();
- }
- if (breakchar_len == 0) {
- zend_argument_value_error(3, "cannot be empty");
- RETURN_THROWS();
- }
- if (linelength == 0 && docut) {
- zend_argument_value_error(4, "cannot be true when argument #2 ($width) is 0");
- RETURN_THROWS();
- }
-
- if (breakchar_len == 1 && !docut) {
- newtext = zend_string_init(ZSTR_VAL(text), ZSTR_LEN(text), 0);
- laststart = lastspace = 0;
- for (current = 0; current < (zend_long)ZSTR_LEN(text); current++) {
- if (ZSTR_VAL(text)[current] == breakchar[0]) {
- laststart = lastspace = current + 1;
- } else if (ZSTR_VAL(text)[current] == ' ') {
- if (current - laststart >= linelength) {
- ZSTR_VAL(newtext)[current] = breakchar[0];
- laststart = current + 1;
- }
- lastspace = current;
- } else if (current - laststart >= linelength && laststart != lastspace) {
- ZSTR_VAL(newtext)[lastspace] = breakchar[0];
- laststart = lastspace + 1;
- }
- }
- RETURN_NEW_STR(newtext);
- } else {
-
- if (linelength > 0) {
- chk = (size_t)(ZSTR_LEN(text)/linelength + 1);
- newtext = zend_string_safe_alloc(chk, breakchar_len, ZSTR_LEN(text), 0);
- alloced = ZSTR_LEN(text) + chk * breakchar_len + 1;
- } else {
- chk = ZSTR_LEN(text);
- alloced = ZSTR_LEN(text) * (breakchar_len + 1) + 1;
- newtext = zend_string_safe_alloc(ZSTR_LEN(text), breakchar_len + 1, 0, 0);
- }
-
- newtextlen = 0;
- laststart = lastspace = 0;
- for (current = 0; current < (zend_long)ZSTR_LEN(text); current++) {
- if (chk == 0) {
- alloced += (size_t) (((ZSTR_LEN(text) - current + 1)/linelength + 1) * breakchar_len) + 1;
- newtext = zend_string_extend(newtext, alloced, 0);
- chk = (size_t) ((ZSTR_LEN(text) - current)/linelength) + 1;
- }
-
- if (ZSTR_VAL(text)[current] == breakchar[0]
- && current + breakchar_len < ZSTR_LEN(text)
- && !strncmp(ZSTR_VAL(text) + current, breakchar, breakchar_len)) {
- memcpy(ZSTR_VAL(newtext) + newtextlen, ZSTR_VAL(text) + laststart, current - laststart + breakchar_len);
- newtextlen += current - laststart + breakchar_len;
- current += breakchar_len - 1;
- laststart = lastspace = current + 1;
- chk--;
- }
-
- else if (ZSTR_VAL(text)[current] == ' ') {
- if (current - laststart >= linelength) {
- memcpy(ZSTR_VAL(newtext) + newtextlen, ZSTR_VAL(text) + laststart, current - laststart);
- newtextlen += current - laststart;
- memcpy(ZSTR_VAL(newtext) + newtextlen, breakchar, breakchar_len);
- newtextlen += breakchar_len;
- laststart = current + 1;
- chk--;
- }
- lastspace = current;
- }
-
- else if (current - laststart >= linelength
- && docut && laststart >= lastspace) {
- memcpy(ZSTR_VAL(newtext) + newtextlen, ZSTR_VAL(text) + laststart, current - laststart);
- newtextlen += current - laststart;
- memcpy(ZSTR_VAL(newtext) + newtextlen, breakchar, breakchar_len);
- newtextlen += breakchar_len;
- laststart = lastspace = current;
- chk--;
- }
-
- else if (current - laststart >= linelength
- && laststart < lastspace) {
- memcpy(ZSTR_VAL(newtext) + newtextlen, ZSTR_VAL(text) + laststart, lastspace - laststart);
- newtextlen += lastspace - laststart;
- memcpy(ZSTR_VAL(newtext) + newtextlen, breakchar, breakchar_len);
- newtextlen += breakchar_len;
- laststart = lastspace = lastspace + 1;
- chk--;
- }
- }
-
- if (laststart != current) {
- memcpy(ZSTR_VAL(newtext) + newtextlen, ZSTR_VAL(text) + laststart, current - laststart);
- newtextlen += current - laststart;
- }
- ZSTR_VAL(newtext)[newtextlen] = '\0';
-
- newtext = zend_string_truncate(newtext, newtextlen, 0);
- RETURN_NEW_STR(newtext);
- }
- }
- PHPAPI void php_explode(const zend_string *delim, zend_string *str, zval *return_value, zend_long limit)
- {
- const char *p1 = ZSTR_VAL(str);
- const char *endp = ZSTR_VAL(str) + ZSTR_LEN(str);
- const char *p2 = php_memnstr(ZSTR_VAL(str), ZSTR_VAL(delim), ZSTR_LEN(delim), endp);
- zval tmp;
- if (p2 == NULL) {
- ZVAL_STR_COPY(&tmp, str);
- zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), &tmp);
- } else {
- zend_hash_real_init_packed(Z_ARRVAL_P(return_value));
- ZEND_HASH_FILL_PACKED(Z_ARRVAL_P(return_value)) {
- do {
- ZEND_HASH_FILL_GROW();
- ZEND_HASH_FILL_SET_STR(zend_string_init_fast(p1, p2 - p1));
- ZEND_HASH_FILL_NEXT();
- p1 = p2 + ZSTR_LEN(delim);
- p2 = php_memnstr(p1, ZSTR_VAL(delim), ZSTR_LEN(delim), endp);
- } while (p2 != NULL && --limit > 1);
- if (p1 <= endp) {
- ZEND_HASH_FILL_GROW();
- ZEND_HASH_FILL_SET_STR(zend_string_init_fast(p1, endp - p1));
- ZEND_HASH_FILL_NEXT();
- }
- } ZEND_HASH_FILL_END();
- }
- }
- PHPAPI void php_explode_negative_limit(const zend_string *delim, zend_string *str, zval *return_value, zend_long limit)
- {
- #define EXPLODE_ALLOC_STEP 64
- const char *p1 = ZSTR_VAL(str);
- const char *endp = ZSTR_VAL(str) + ZSTR_LEN(str);
- const char *p2 = php_memnstr(ZSTR_VAL(str), ZSTR_VAL(delim), ZSTR_LEN(delim), endp);
- zval tmp;
- if (p2 == NULL) {
-
- } else {
- size_t allocated = EXPLODE_ALLOC_STEP, found = 0;
- zend_long i, to_return;
- const char **positions = emalloc(allocated * sizeof(char *));
- positions[found++] = p1;
- do {
- if (found >= allocated) {
- allocated = found + EXPLODE_ALLOC_STEP;
- positions = erealloc(ZEND_VOIDP(positions), allocated*sizeof(char *));
- }
- positions[found++] = p1 = p2 + ZSTR_LEN(delim);
- p2 = php_memnstr(p1, ZSTR_VAL(delim), ZSTR_LEN(delim), endp);
- } while (p2 != NULL);
- to_return = limit + found;
-
- for (i = 0; i < to_return; i++) {
- ZVAL_STRINGL(&tmp, positions[i], (positions[i+1] - ZSTR_LEN(delim)) - positions[i]);
- zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), &tmp);
- }
- efree((void *)positions);
- }
- #undef EXPLODE_ALLOC_STEP
- }
- PHP_FUNCTION(explode)
- {
- zend_string *str, *delim;
- zend_long limit = ZEND_LONG_MAX;
- zval tmp;
- ZEND_PARSE_PARAMETERS_START(2, 3)
- Z_PARAM_STR(delim)
- Z_PARAM_STR(str)
- Z_PARAM_OPTIONAL
- Z_PARAM_LONG(limit)
- ZEND_PARSE_PARAMETERS_END();
- if (ZSTR_LEN(delim) == 0) {
- zend_argument_value_error(1, "cannot be empty");
- RETURN_THROWS();
- }
- array_init(return_value);
- if (ZSTR_LEN(str) == 0) {
- if (limit >= 0) {
- ZVAL_EMPTY_STRING(&tmp);
- zend_hash_index_add_new(Z_ARRVAL_P(return_value), 0, &tmp);
- }
- return;
- }
- if (limit > 1) {
- php_explode(delim, str, return_value, limit);
- } else if (limit < 0) {
- php_explode_negative_limit(delim, str, return_value, limit);
- } else {
- ZVAL_STR_COPY(&tmp, str);
- zend_hash_index_add_new(Z_ARRVAL_P(return_value), 0, &tmp);
- }
- }
- PHPAPI void php_implode(const zend_string *glue, HashTable *pieces, zval *return_value)
- {
- zval *tmp;
- int numelems;
- zend_string *str;
- char *cptr;
- size_t len = 0;
- struct {
- zend_string *str;
- zend_long lval;
- } *strings, *ptr;
- ALLOCA_FLAG(use_heap)
- numelems = zend_hash_num_elements(pieces);
- if (numelems == 0) {
- RETURN_EMPTY_STRING();
- } else if (numelems == 1) {
-
- ZEND_HASH_FOREACH_VAL(pieces, tmp) {
- RETURN_STR(zval_get_string(tmp));
- } ZEND_HASH_FOREACH_END();
- }
- ptr = strings = do_alloca((sizeof(*strings)) * numelems, use_heap);
- ZEND_HASH_FOREACH_VAL(pieces, tmp) {
- if (EXPECTED(Z_TYPE_P(tmp) == IS_STRING)) {
- ptr->str = Z_STR_P(tmp);
- len += ZSTR_LEN(ptr->str);
- ptr->lval = 0;
- ptr++;
- } else if (UNEXPECTED(Z_TYPE_P(tmp) == IS_LONG)) {
- zend_long val = Z_LVAL_P(tmp);
- ptr->str = NULL;
- ptr->lval = val;
- ptr++;
- if (val <= 0) {
- len++;
- }
- while (val) {
- val /= 10;
- len++;
- }
- } else {
- ptr->str = zval_get_string_func(tmp);
- len += ZSTR_LEN(ptr->str);
- ptr->lval = 1;
- ptr++;
- }
- } ZEND_HASH_FOREACH_END();
-
- str = zend_string_safe_alloc(numelems - 1, ZSTR_LEN(glue), len, 0);
- cptr = ZSTR_VAL(str) + ZSTR_LEN(str);
- *cptr = 0;
- while (1) {
- ptr--;
- if (EXPECTED(ptr->str)) {
- cptr -= ZSTR_LEN(ptr->str);
- memcpy(cptr, ZSTR_VAL(ptr->str), ZSTR_LEN(ptr->str));
- if (ptr->lval) {
- zend_string_release_ex(ptr->str, 0);
- }
- } else {
- char *oldPtr = cptr;
- char oldVal = *cptr;
- cptr = zend_print_long_to_buf(cptr, ptr->lval);
- *oldPtr = oldVal;
- }
- if (ptr == strings) {
- break;
- }
- cptr -= ZSTR_LEN(glue);
- memcpy(cptr, ZSTR_VAL(glue), ZSTR_LEN(glue));
- }
- free_alloca(strings, use_heap);
- RETURN_NEW_STR(str);
- }
- PHP_FUNCTION(implode)
- {
- zend_string *arg1_str = NULL;
- HashTable *arg1_array = NULL;
- zend_array *pieces = NULL;
- ZEND_PARSE_PARAMETERS_START(1, 2)
- Z_PARAM_ARRAY_HT_OR_STR(arg1_array, arg1_str)
- Z_PARAM_OPTIONAL
- Z_PARAM_ARRAY_HT_OR_NULL(pieces)
- ZEND_PARSE_PARAMETERS_END();
- if (pieces == NULL) {
- if (arg1_array == NULL) {
- zend_type_error("%s(): Argument #1 ($pieces) must be of type array, string given", get_active_function_name());
- RETURN_THROWS();
- }
- arg1_str = ZSTR_EMPTY_ALLOC();
- pieces = arg1_array;
- } else {
- if (arg1_str == NULL) {
- zend_argument_type_error(1, "must be of type string, array given");
- RETURN_THROWS();
- }
- }
- php_implode(arg1_str, pieces, return_value);
- }
- #define STRTOK_TABLE(p) BG(strtok_table)[(unsigned char) *p]
- PHP_FUNCTION(strtok)
- {
- zend_string *str, *tok = NULL;
- char *token;
- char *token_end;
- char *p;
- char *pe;
- size_t skipped = 0;
- ZEND_PARSE_PARAMETERS_START(1, 2)
- Z_PARAM_STR(str)
- Z_PARAM_OPTIONAL
- Z_PARAM_STR_OR_NULL(tok)
- ZEND_PARSE_PARAMETERS_END();
- if (!tok) {
- tok = str;
- } else {
- if (BG(strtok_string)) {
- zend_string_release(BG(strtok_string));
- }
- BG(strtok_string) = zend_string_copy(str);
- BG(strtok_last) = ZSTR_VAL(str);
- BG(strtok_len) = ZSTR_LEN(str);
- }
- if (!BG(strtok_string)) {
-
-
- RETURN_FALSE;
- }
- p = BG(strtok_last);
- pe = ZSTR_VAL(BG(strtok_string)) + BG(strtok_len);
- if (p >= pe) {
-
- RETURN_FALSE;
- }
- token = ZSTR_VAL(tok);
- token_end = token + ZSTR_LEN(tok);
- while (token < token_end) {
- STRTOK_TABLE(token++) = 1;
- }
-
- while (STRTOK_TABLE(p)) {
- if (++p >= pe) {
-
- goto return_false;
- }
- skipped++;
- }
-
- while (++p < pe) {
- if (STRTOK_TABLE(p)) {
- goto return_token;
- }
- }
- if (p - BG(strtok_last)) {
- return_token:
- RETVAL_STRINGL(BG(strtok_last) + skipped, (p - BG(strtok_last)) - skipped);
- BG(strtok_last) = p + 1;
- } else {
- return_false:
- RETVAL_FALSE;
- zend_string_release(BG(strtok_string));
- BG(strtok_string) = NULL;
- }
-
- token = ZSTR_VAL(tok);
- while (token < token_end) {
- STRTOK_TABLE(token++) = 0;
- }
- }
- PHPAPI char *php_strtoupper(char *s, size_t len)
- {
- unsigned char *c;
- const unsigned char *e;
- c = (unsigned char *)s;
- e = (unsigned char *)c+len;
- while (c < e) {
- *c = toupper(*c);
- c++;
- }
- return s;
- }
- PHPAPI zend_string *php_string_toupper(zend_string *s)
- {
- unsigned char *c;
- const unsigned char *e;
- c = (unsigned char *)ZSTR_VAL(s);
- e = c + ZSTR_LEN(s);
- while (c < e) {
- if (islower(*c)) {
- unsigned char *r;
- zend_string *res = zend_string_alloc(ZSTR_LEN(s), 0);
- if (c != (unsigned char*)ZSTR_VAL(s)) {
- memcpy(ZSTR_VAL(res), ZSTR_VAL(s), c - (unsigned char*)ZSTR_VAL(s));
- }
- r = c + (ZSTR_VAL(res) - ZSTR_VAL(s));
- while (c < e) {
- *r = toupper(*c);
- r++;
- c++;
- }
- *r = '\0';
- return res;
- }
- c++;
- }
- return zend_string_copy(s);
- }
- PHP_FUNCTION(strtoupper)
- {
- zend_string *arg;
- ZEND_PARSE_PARAMETERS_START(1, 1)
- Z_PARAM_STR(arg)
- ZEND_PARSE_PARAMETERS_END();
- RETURN_STR(php_string_toupper(arg));
- }
- PHPAPI char *php_strtolower(char *s, size_t len)
- {
- unsigned char *c;
- const unsigned char *e;
- c = (unsigned char *)s;
- e = c+len;
- while (c < e) {
- *c = tolower(*c);
- c++;
- }
- return s;
- }
- PHPAPI zend_string *php_string_tolower(zend_string *s)
- {
- unsigned char *c;
- const unsigned char *e;
- if (EXPECTED(!BG(ctype_string))) {
- return zend_string_tolower(s);
- } else {
- c = (unsigned char *)ZSTR_VAL(s);
- e = c + ZSTR_LEN(s);
- while (c < e) {
- if (isupper(*c)) {
- unsigned char *r;
- zend_string *res = zend_string_alloc(ZSTR_LEN(s), 0);
- if (c != (unsigned char*)ZSTR_VAL(s)) {
- memcpy(ZSTR_VAL(res), ZSTR_VAL(s), c - (unsigned char*)ZSTR_VAL(s));
- }
- r = c + (ZSTR_VAL(res) - ZSTR_VAL(s));
- while (c < e) {
- *r = tolower(*c);
- r++;
- c++;
- }
- *r = '\0';
- return res;
- }
- c++;
- }
- return zend_string_copy(s);
- }
- }
- PHP_FUNCTION(strtolower)
- {
- zend_string *str;
- ZEND_PARSE_PARAMETERS_START(1, 1)
- Z_PARAM_STR(str)
- ZEND_PARSE_PARAMETERS_END();
- RETURN_STR(php_string_tolower(str));
- }
- #if defined(PHP_WIN32)
- static bool _is_basename_start(const char *start, const char *pos)
- {
- if (pos - start >= 1
- && *(pos-1) != '/'
- && *(pos-1) != '\\') {
- if (pos - start == 1) {
- return 1;
- } else if (*(pos-2) == '/' || *(pos-2) == '\\') {
- return 1;
- } else if (*(pos-2) == ':'
- && _is_basename_start(start, pos - 2)) {
- return 1;
- }
- }
- return 0;
- }
- #endif
- PHPAPI zend_string *php_basename(const char *s, size_t len, const char *suffix, size_t suffix_len)
- {
- const char *basename_start;
- const char *basename_end;
- if (CG(ascii_compatible_locale)) {
- basename_end = s + len - 1;
-
- while (basename_end >= s
- #if defined(PHP_WIN32)
- && (*basename_end == '/'
- || *basename_end == '\\'
- || (*basename_end == ':'
- && _is_basename_start(s, basename_end)))) {
- #else
- && *basename_end == '/') {
- #endif
- basename_end--;
- }
- if (basename_end < s) {
- return ZSTR_EMPTY_ALLOC();
- }
-
- basename_start = basename_end;
- basename_end++;
- while (basename_start > s
- #if defined(PHP_WIN32)
- && *(basename_start-1) != '/'
- && *(basename_start-1) != '\\') {
- if (*(basename_start-1) == ':' &&
- _is_basename_start(s, basename_start - 1)) {
- break;
- }
- #else
- && *(basename_start-1) != '/') {
- #endif
- basename_start--;
- }
- } else {
-
- int state = 0;
- basename_start = s;
- basename_end = s;
- while (len > 0) {
- int inc_len = (*s == '\0' ? 1 : php_mblen(s, len));
- switch (inc_len) {
- case 0:
- goto quit_loop;
- case 1:
- #if defined(PHP_WIN32)
- if (*s == '/' || *s == '\\') {
- #else
- if (*s == '/') {
- #endif
- if (state == 1) {
- state = 0;
- basename_end = s;
- }
- #if defined(PHP_WIN32)
-
- } else if ((*s == ':' && (s - basename_start == 1))) {
- if (state == 0) {
- basename_start = s;
- state = 1;
- } else {
- basename_end = s;
- state = 0;
- }
- #endif
- } else {
- if (state == 0) {
- basename_start = s;
- state = 1;
- }
- }
- break;
- default:
- if (inc_len < 0) {
-
- inc_len = 1;
- php_mb_reset();
- }
- if (state == 0) {
- basename_start = s;
- state = 1;
- }
- break;
- }
- s += inc_len;
- len -= inc_len;
- }
- quit_loop:
- if (state == 1) {
- basename_end = s;
- }
- }
- if (suffix != NULL && suffix_len < (size_t)(basename_end - basename_start) &&
- memcmp(basename_end - suffix_len, suffix, suffix_len) == 0) {
- basename_end -= suffix_len;
- }
- return zend_string_init(basename_start, basename_end - basename_start, 0);
- }
- PHP_FUNCTION(basename)
- {
- char *string, *suffix = NULL;
- size_t string_len, suffix_len = 0;
- ZEND_PARSE_PARAMETERS_START(1, 2)
- Z_PARAM_STRING(string, string_len)
- Z_PARAM_OPTIONAL
- Z_PARAM_STRING(suffix, suffix_len)
- ZEND_PARSE_PARAMETERS_END();
- RETURN_STR(php_basename(string, string_len, suffix, suffix_len));
- }
- PHPAPI size_t php_dirname(char *path, size_t len)
- {
- return zend_dirname(path, len);
- }
- PHP_FUNCTION(dirname)
- {
- char *str;
- size_t str_len;
- zend_string *ret;
- zend_long levels = 1;
- ZEND_PARSE_PARAMETERS_START(1, 2)
- Z_PARAM_STRING(str, str_len)
- Z_PARAM_OPTIONAL
- Z_PARAM_LONG(levels)
- ZEND_PARSE_PARAMETERS_END();
- ret = zend_string_init(str, str_len, 0);
- if (levels == 1) {
-
- #ifdef PHP_WIN32
- ZSTR_LEN(ret) = php_win32_ioutil_dirname(ZSTR_VAL(ret), str_len);
- #else
- ZSTR_LEN(ret) = zend_dirname(ZSTR_VAL(ret), str_len);
- #endif
- } else if (levels < 1) {
- zend_argument_value_error(2, "must be greater than or equal to 1");
- zend_string_efree(ret);
- RETURN_THROWS();
- } else {
-
- do {
- #ifdef PHP_WIN32
- ZSTR_LEN(ret) = php_win32_ioutil_dirname(ZSTR_VAL(ret), str_len = ZSTR_LEN(ret));
- #else
- ZSTR_LEN(ret) = zend_dirname(ZSTR_VAL(ret), str_len = ZSTR_LEN(ret));
- #endif
- } while (ZSTR_LEN(ret) < str_len && --levels);
- }
- RETURN_NEW_STR(ret);
- }
- PHP_FUNCTION(pathinfo)
- {
- zval tmp;
- char *path, *dirname;
- size_t path_len;
- int have_basename;
- zend_long opt = PHP_PATHINFO_ALL;
- zend_string *ret = NULL;
- ZEND_PARSE_PARAMETERS_START(1, 2)
- Z_PARAM_STRING(path, path_len)
- Z_PARAM_OPTIONAL
- Z_PARAM_LONG(opt)
- ZEND_PARSE_PARAMETERS_END();
- have_basename = ((opt & PHP_PATHINFO_BASENAME) == PHP_PATHINFO_BASENAME);
- array_init(&tmp);
- if ((opt & PHP_PATHINFO_DIRNAME) == PHP_PATHINFO_DIRNAME) {
- dirname = estrndup(path, path_len);
- php_dirname(dirname, path_len);
- if (*dirname) {
- add_assoc_string(&tmp, "dirname", dirname);
- }
- efree(dirname);
- }
- if (have_basename) {
- ret = php_basename(path, path_len, NULL, 0);
- add_assoc_str(&tmp, "basename", zend_string_copy(ret));
- }
- if ((opt & PHP_PATHINFO_EXTENSION) == PHP_PATHINFO_EXTENSION) {
- const char *p;
- ptrdiff_t idx;
- if (!have_basename) {
- ret = php_basename(path, path_len, NULL, 0);
- }
- p = zend_memrchr(ZSTR_VAL(ret), '.', ZSTR_LEN(ret));
- if (p) {
- idx = p - ZSTR_VAL(ret);
- add_assoc_stringl(&tmp, "extension", ZSTR_VAL(ret) + idx + 1, ZSTR_LEN(ret) - idx - 1);
- }
- }
- if ((opt & PHP_PATHINFO_FILENAME) == PHP_PATHINFO_FILENAME) {
- const char *p;
- ptrdiff_t idx;
-
- if (!have_basename && !ret) {
- ret = php_basename(path, path_len, NULL, 0);
- }
- p = zend_memrchr(ZSTR_VAL(ret), '.', ZSTR_LEN(ret));
- idx = p ? (p - ZSTR_VAL(ret)) : (ptrdiff_t)ZSTR_LEN(ret);
- add_assoc_stringl(&tmp, "filename", ZSTR_VAL(ret), idx);
- }
- if (ret) {
- zend_string_release_ex(ret, 0);
- }
- if (opt == PHP_PATHINFO_ALL) {
- RETURN_COPY_VALUE(&tmp);
- } else {
- zval *element;
- if ((element = zend_hash_get_current_data(Z_ARRVAL(tmp))) != NULL) {
- RETVAL_COPY_DEREF(element);
- } else {
- RETVAL_EMPTY_STRING();
- }
- zval_ptr_dtor(&tmp);
- }
- }
- PHPAPI char *php_stristr(char *s, char *t, size_t s_len, size_t t_len)
- {
- php_strtolower(s, s_len);
- php_strtolower(t, t_len);
- return (char*)php_memnstr(s, t, t_len, s + s_len);
- }
- PHPAPI size_t php_strspn(const char *s1, const char *s2, const char *s1_end, const char *s2_end)
- {
- const char *p = s1, *spanp;
- char c = *p;
- cont:
- for (spanp = s2; p != s1_end && spanp != s2_end;) {
- if (*spanp++ == c) {
- c = *(++p);
- goto cont;
- }
- }
- return (p - s1);
- }
- PHPAPI size_t php_strcspn(const char *s1, const char *s2, const char *s1_end, const char *s2_end)
- {
- const char *p, *spanp;
- char c = *s1;
- for (p = s1;;) {
- spanp = s2;
- do {
- if (*spanp == c || p == s1_end) {
- return p - s1;
- }
- } while (spanp++ < (s2_end - 1));
- c = *++p;
- }
-
- }
- PHP_FUNCTION(stristr)
- {
- zend_string *haystack, *needle;
- const char *found = NULL;
- size_t found_offset;
- char *haystack_dup;
- char *orig_needle;
- bool part = 0;
- ZEND_PARSE_PARAMETERS_START(2, 3)
- Z_PARAM_STR(haystack)
- Z_PARAM_STR(needle)
- Z_PARAM_OPTIONAL
- Z_PARAM_BOOL(part)
- ZEND_PARSE_PARAMETERS_END();
- haystack_dup = estrndup(ZSTR_VAL(haystack), ZSTR_LEN(haystack));
- orig_needle = estrndup(ZSTR_VAL(needle), ZSTR_LEN(needle));
- found = php_stristr(haystack_dup, orig_needle, ZSTR_LEN(haystack), ZSTR_LEN(needle));
- efree(orig_needle);
- if (found) {
- found_offset = found - haystack_dup;
- if (part) {
- RETVAL_STRINGL(ZSTR_VAL(haystack), found_offset);
- } else {
- RETVAL_STRINGL(ZSTR_VAL(haystack) + found_offset, ZSTR_LEN(haystack) - found_offset);
- }
- } else {
- RETVAL_FALSE;
- }
- efree(haystack_dup);
- }
- PHP_FUNCTION(strstr)
- {
- zend_string *haystack, *needle;
- const char *found = NULL;
- zend_long found_offset;
- bool part = 0;
- ZEND_PARSE_PARAMETERS_START(2, 3)
- Z_PARAM_STR(haystack)
- Z_PARAM_STR(needle)
- Z_PARAM_OPTIONAL
- Z_PARAM_BOOL(part)
- ZEND_PARSE_PARAMETERS_END();
- found = php_memnstr(ZSTR_VAL(haystack), ZSTR_VAL(needle), ZSTR_LEN(needle), ZSTR_VAL(haystack) + ZSTR_LEN(haystack));
- if (found) {
- found_offset = found - ZSTR_VAL(haystack);
- if (part) {
- RETURN_STRINGL(ZSTR_VAL(haystack), found_offset);
- } else {
- RETURN_STRINGL(found, ZSTR_LEN(haystack) - found_offset);
- }
- }
- RETURN_FALSE;
- }
- PHP_FUNCTION(str_contains)
- {
- zend_string *haystack, *needle;
- ZEND_PARSE_PARAMETERS_START(2, 2)
- Z_PARAM_STR(haystack)
- Z_PARAM_STR(needle)
- ZEND_PARSE_PARAMETERS_END();
- RETURN_BOOL(php_memnstr(ZSTR_VAL(haystack), ZSTR_VAL(needle), ZSTR_LEN(needle), ZSTR_VAL(haystack) + ZSTR_LEN(haystack)));
- }
- PHP_FUNCTION(str_starts_with)
- {
- zend_string *haystack, *needle;
- ZEND_PARSE_PARAMETERS_START(2, 2)
- Z_PARAM_STR(haystack)
- Z_PARAM_STR(needle)
- ZEND_PARSE_PARAMETERS_END();
- if (ZSTR_LEN(needle) > ZSTR_LEN(haystack)) {
- RETURN_FALSE;
- }
- RETURN_BOOL(memcmp(ZSTR_VAL(haystack), ZSTR_VAL(needle), ZSTR_LEN(needle)) == 0);
- }
- PHP_FUNCTION(str_ends_with)
- {
- zend_string *haystack, *needle;
- ZEND_PARSE_PARAMETERS_START(2, 2)
- Z_PARAM_STR(haystack)
- Z_PARAM_STR(needle)
- ZEND_PARSE_PARAMETERS_END();
- if (ZSTR_LEN(needle) > ZSTR_LEN(haystack)) {
- RETURN_FALSE;
- }
- RETURN_BOOL(memcmp(
- ZSTR_VAL(haystack) + ZSTR_LEN(haystack) - ZSTR_LEN(needle),
- ZSTR_VAL(needle), ZSTR_LEN(needle)) == 0);
- }
- PHP_FUNCTION(strpos)
- {
- zend_string *haystack, *needle;
- const char *found = NULL;
- zend_long offset = 0;
- ZEND_PARSE_PARAMETERS_START(2, 3)
- Z_PARAM_STR(haystack)
- Z_PARAM_STR(needle)
- Z_PARAM_OPTIONAL
- Z_PARAM_LONG(offset)
- ZEND_PARSE_PARAMETERS_END();
- if (offset < 0) {
- offset += (zend_long)ZSTR_LEN(haystack);
- }
- if (offset < 0 || (size_t)offset > ZSTR_LEN(haystack)) {
- zend_argument_value_error(3, "must be contained in argument #1 ($haystack)");
- RETURN_THROWS();
- }
- found = (char*)php_memnstr(ZSTR_VAL(haystack) + offset,
- ZSTR_VAL(needle), ZSTR_LEN(needle),
- ZSTR_VAL(haystack) + ZSTR_LEN(haystack));
- if (found) {
- RETURN_LONG(found - ZSTR_VAL(haystack));
- } else {
- RETURN_FALSE;
- }
- }
- PHP_FUNCTION(stripos)
- {
- const char *found = NULL;
- zend_string *haystack, *needle;
- zend_long offset = 0;
- zend_string *needle_dup = NULL, *haystack_dup;
- ZEND_PARSE_PARAMETERS_START(2, 3)
- Z_PARAM_STR(haystack)
- Z_PARAM_STR(needle)
- Z_PARAM_OPTIONAL
- Z_PARAM_LONG(offset)
- ZEND_PARSE_PARAMETERS_END();
- if (offset < 0) {
- offset += (zend_long)ZSTR_LEN(haystack);
- }
- if (offset < 0 || (size_t)offset > ZSTR_LEN(haystack)) {
- zend_argument_value_error(3, "must be contained in argument #1 ($haystack)");
- RETURN_THROWS();
- }
- if (ZSTR_LEN(needle) > ZSTR_LEN(haystack)) {
- RETURN_FALSE;
- }
- haystack_dup = php_string_tolower(haystack);
- needle_dup = php_string_tolower(needle);
- found = (char*)php_memnstr(ZSTR_VAL(haystack_dup) + offset,
- ZSTR_VAL(needle_dup), ZSTR_LEN(needle_dup), ZSTR_VAL(haystack_dup) + ZSTR_LEN(haystack));
- if (found) {
- RETVAL_LONG(found - ZSTR_VAL(haystack_dup));
- } else {
- RETVAL_FALSE;
- }
- zend_string_release_ex(haystack_dup, 0);
- zend_string_release_ex(needle_dup, 0);
- }
- PHP_FUNCTION(strrpos)
- {
- zend_string *needle;
- zend_string *haystack;
- zend_long offset = 0;
- const char *p, *e, *found;
- ZEND_PARSE_PARAMETERS_START(2, 3)
- Z_PARAM_STR(haystack)
- Z_PARAM_STR(needle)
- Z_PARAM_OPTIONAL
- Z_PARAM_LONG(offset)
- ZEND_PARSE_PARAMETERS_END();
- if (offset >= 0) {
- if ((size_t)offset > ZSTR_LEN(haystack)) {
- zend_argument_value_error(3, "must be contained in argument #1 ($haystack)");
- RETURN_THROWS();
- }
- p = ZSTR_VAL(haystack) + (size_t)offset;
- e = ZSTR_VAL(haystack) + ZSTR_LEN(haystack);
- } else {
- if (offset < -ZEND_LONG_MAX || (size_t)(-offset) > ZSTR_LEN(haystack)) {
- zend_argument_value_error(3, "must be contained in argument #1 ($haystack)");
- RETURN_THROWS();
- }
- p = ZSTR_VAL(haystack);
- if ((size_t)-offset < ZSTR_LEN(needle)) {
- e = ZSTR_VAL(haystack) + ZSTR_LEN(haystack);
- } else {
- e = ZSTR_VAL(haystack) + ZSTR_LEN(haystack) + offset + ZSTR_LEN(needle);
- }
- }
- if ((found = zend_memnrstr(p, ZSTR_VAL(needle), ZSTR_LEN(needle), e))) {
- RETURN_LONG(found - ZSTR_VAL(haystack));
- }
- RETURN_FALSE;
- }
- PHP_FUNCTION(strripos)
- {
- zend_string *needle;
- zend_string *haystack;
- zend_long offset = 0;
- const char *p, *e, *found;
- zend_string *needle_dup, *haystack_dup;
- ZEND_PARSE_PARAMETERS_START(2, 3)
- Z_PARAM_STR(haystack)
- Z_PARAM_STR(needle)
- Z_PARAM_OPTIONAL
- Z_PARAM_LONG(offset)
- ZEND_PARSE_PARAMETERS_END();
- if (ZSTR_LEN(needle) == 1) {
-
- char lowered;
- if (offset >= 0) {
- if ((size_t)offset > ZSTR_LEN(haystack)) {
- zend_argument_value_error(3, "must be contained in argument #1 ($haystack)");
- RETURN_THROWS();
- }
- p = ZSTR_VAL(haystack) + (size_t)offset;
- e = ZSTR_VAL(haystack) + ZSTR_LEN(haystack) - 1;
- } else {
- p = ZSTR_VAL(haystack);
- if (offset < -ZEND_LONG_MAX || (size_t)(-offset) > ZSTR_LEN(haystack)) {
- zend_argument_value_error(3, "must be contained in argument #1 ($haystack)");
- RETURN_THROWS();
- }
- e = ZSTR_VAL(haystack) + (ZSTR_LEN(haystack) + (size_t)offset);
- }
-
- lowered = tolower(*ZSTR_VAL(needle));
- while (e >= p) {
- if (tolower(*e) == lowered) {
- RETURN_LONG(e - p + (offset > 0 ? offset : 0));
- }
- e--;
- }
- RETURN_FALSE;
- }
- haystack_dup = php_string_tolower(haystack);
- if (offset >= 0) {
- if ((size_t)offset > ZSTR_LEN(haystack)) {
- zend_string_release_ex(haystack_dup, 0);
- zend_argument_value_error(3, "must be contained in argument #1 ($haystack)");
- RETURN_THROWS();
- }
- p = ZSTR_VAL(haystack_dup) + offset;
- e = ZSTR_VAL(haystack_dup) + ZSTR_LEN(haystack);
- } else {
- if (offset < -ZEND_LONG_MAX || (size_t)(-offset) > ZSTR_LEN(haystack)) {
- zend_string_release_ex(haystack_dup, 0);
- zend_argument_value_error(3, "must be contained in argument #1 ($haystack)");
- RETURN_THROWS();
- }
- p = ZSTR_VAL(haystack_dup);
- if ((size_t)-offset < ZSTR_LEN(needle)) {
- e = ZSTR_VAL(haystack_dup) + ZSTR_LEN(haystack);
- } else {
- e = ZSTR_VAL(haystack_dup) + ZSTR_LEN(haystack) + offset + ZSTR_LEN(needle);
- }
- }
- needle_dup = php_string_tolower(needle);
- if ((found = (char *)zend_memnrstr(p, ZSTR_VAL(needle_dup), ZSTR_LEN(needle_dup), e))) {
- RETVAL_LONG(found - ZSTR_VAL(haystack_dup));
- zend_string_release_ex(needle_dup, 0);
- zend_string_release_ex(haystack_dup, 0);
- } else {
- zend_string_release_ex(needle_dup, 0);
- zend_string_release_ex(haystack_dup, 0);
- RETURN_FALSE;
- }
- }
- PHP_FUNCTION(strrchr)
- {
- zend_string *haystack, *needle;
- const char *found = NULL;
- zend_long found_offset;
- ZEND_PARSE_PARAMETERS_START(2, 2)
- Z_PARAM_STR(haystack)
- Z_PARAM_STR(needle)
- ZEND_PARSE_PARAMETERS_END();
- found = zend_memrchr(ZSTR_VAL(haystack), *ZSTR_VAL(needle), ZSTR_LEN(haystack));
- if (found) {
- found_offset = found - ZSTR_VAL(haystack);
- RETURN_STRINGL(found, ZSTR_LEN(haystack) - found_offset);
- } else {
- RETURN_FALSE;
- }
- }
- static zend_string *php_chunk_split(const char *src, size_t srclen, const char *end, size_t endlen, size_t chunklen)
- {
- char *q;
- const char *p;
- size_t chunks;
- size_t restlen;
- zend_string *dest;
- chunks = srclen / chunklen;
- restlen = srclen - chunks * chunklen;
- if (restlen) {
-
- chunks++;
- }
- dest = zend_string_safe_alloc(chunks, endlen, srclen, 0);
- for (p = src, q = ZSTR_VAL(dest); p < (src + srclen - chunklen + 1); ) {
- memcpy(q, p, chunklen);
- q += chunklen;
- memcpy(q, end, endlen);
- q += endlen;
- p += chunklen;
- }
- if (restlen) {
- memcpy(q, p, restlen);
- q += restlen;
- memcpy(q, end, endlen);
- q += endlen;
- }
- *q = '\0';
- ZEND_ASSERT(q - ZSTR_VAL(dest) == ZSTR_LEN(dest));
- return dest;
- }
- PHP_FUNCTION(chunk_split)
- {
- zend_string *str;
- char *end = "\r\n";
- size_t endlen = 2;
- zend_long chunklen = 76;
- zend_string *result;
- ZEND_PARSE_PARAMETERS_START(1, 3)
- Z_PARAM_STR(str)
- Z_PARAM_OPTIONAL
- Z_PARAM_LONG(chunklen)
- Z_PARAM_STRING(end, endlen)
- ZEND_PARSE_PARAMETERS_END();
- if (chunklen <= 0) {
- zend_argument_value_error(2, "must be greater than 0");
- RETURN_THROWS();
- }
- if ((size_t)chunklen > ZSTR_LEN(str)) {
-
- result = zend_string_safe_alloc(ZSTR_LEN(str), 1, endlen, 0);
- memcpy(ZSTR_VAL(result), ZSTR_VAL(str), ZSTR_LEN(str));
- memcpy(ZSTR_VAL(result) + ZSTR_LEN(str), end, endlen);
- ZSTR_VAL(result)[ZSTR_LEN(result)] = '\0';
- RETURN_NEW_STR(result);
- }
- if (!ZSTR_LEN(str)) {
- RETURN_EMPTY_STRING();
- }
- result = php_chunk_split(ZSTR_VAL(str), ZSTR_LEN(str), end, endlen, (size_t)chunklen);
- RETURN_STR(result);
- }
- PHP_FUNCTION(substr)
- {
- zend_string *str;
- zend_long l = 0, f;
- bool len_is_null = 1;
- ZEND_PARSE_PARAMETERS_START(2, 3)
- Z_PARAM_STR(str)
- Z_PARAM_LONG(f)
- Z_PARAM_OPTIONAL
- Z_PARAM_LONG_OR_NULL(l, len_is_null)
- ZEND_PARSE_PARAMETERS_END();
- if (f < 0) {
-
- if (-(size_t)f > ZSTR_LEN(str)) {
- f = 0;
- } else {
- f = (zend_long)ZSTR_LEN(str) + f;
- }
- } else if ((size_t)f > ZSTR_LEN(str)) {
- RETURN_EMPTY_STRING();
- }
- if (!len_is_null) {
- if (l < 0) {
-
- if (-(size_t)l > ZSTR_LEN(str) - (size_t)f) {
- l = 0;
- } else {
- l = (zend_long)ZSTR_LEN(str) - f + l;
- }
- } else if ((size_t)l > ZSTR_LEN(str) - (size_t)f) {
- l = (zend_long)ZSTR_LEN(str) - f;
- }
- } else {
- l = (zend_long)ZSTR_LEN(str) - f;
- }
- if (l == ZSTR_LEN(str)) {
- RETURN_STR_COPY(str);
- } else {
- RETURN_STRINGL_FAST(ZSTR_VAL(str) + f, l);
- }
- }
- PHP_FUNCTION(substr_replace)
- {
- zend_string *str, *repl_str;
- HashTable *str_ht, *repl_ht;
- HashTable *from_ht;
- zend_long from_long;
- HashTable *len_ht = NULL;
- zend_long len_long;
- bool len_is_null = 1;
- zend_long l = 0;
- zend_long f;
- zend_string *result;
- HashPosition from_idx, repl_idx, len_idx;
- zval *tmp_str = NULL, *tmp_repl, *tmp_from = NULL, *tmp_len= NULL;
- ZEND_PARSE_PARAMETERS_START(3, 4)
- Z_PARAM_ARRAY_HT_OR_STR(str_ht, str)
- Z_PARAM_ARRAY_HT_OR_STR(repl_ht, repl_str)
- Z_PARAM_ARRAY_HT_OR_LONG(from_ht, from_long)
- Z_PARAM_OPTIONAL
- Z_PARAM_ARRAY_HT_OR_LONG_OR_NULL(len_ht, len_long, len_is_null)
- ZEND_PARSE_PARAMETERS_END();
- if (len_is_null) {
- if (str) {
- l = ZSTR_LEN(str);
- }
- } else if (!len_ht) {
- l = len_long;
- }
- if (str) {
- if (from_ht) {
- zend_argument_type_error(3, "cannot be an array when working on a single string");
- RETURN_THROWS();
- }
- if (len_ht) {
- zend_argument_type_error(4, "cannot be an array when working on a single string");
- RETURN_THROWS();
- }
- f = from_long;
-
- if (f < 0) {
- f = (zend_long)ZSTR_LEN(str) + f;
- if (f < 0) {
- f = 0;
- }
- } else if ((size_t)f > ZSTR_LEN(str)) {
- f = ZSTR_LEN(str);
- }
-
- if (l < 0) {
- l = ((zend_long)ZSTR_LEN(str) - f) + l;
- if (l < 0) {
- l = 0;
- }
- }
- if ((size_t)l > ZSTR_LEN(str) || (l < 0 && (size_t)(-l) > ZSTR_LEN(str))) {
- l = ZSTR_LEN(str);
- }
- if ((f + l) > (zend_long)ZSTR_LEN(str)) {
- l = ZSTR_LEN(str) - f;
- }
- zend_string *tmp_repl_str = NULL;
- if (repl_ht) {
- repl_idx = 0;
- while (repl_idx < repl_ht->nNumUsed) {
- tmp_repl = &repl_ht->arData[repl_idx].val;
- if (Z_TYPE_P(tmp_repl) != IS_UNDEF) {
- break;
- }
- repl_idx++;
- }
- if (repl_idx < repl_ht->nNumUsed) {
- repl_str = zval_get_tmp_string(tmp_repl, &tmp_repl_str);
- } else {
- repl_str = STR_EMPTY_ALLOC();
- }
- }
- result = zend_string_safe_alloc(1, ZSTR_LEN(str) - l + ZSTR_LEN(repl_str), 0, 0);
- memcpy(ZSTR_VAL(result), ZSTR_VAL(str), f);
- if (ZSTR_LEN(repl_str)) {
- memcpy((ZSTR_VAL(result) + f), ZSTR_VAL(repl_str), ZSTR_LEN(repl_str));
- }
- memcpy((ZSTR_VAL(result) + f + ZSTR_LEN(repl_str)), ZSTR_VAL(str) + f + l, ZSTR_LEN(str) - f - l);
- ZSTR_VAL(result)[ZSTR_LEN(result)] = '\0';
- zend_tmp_string_release(tmp_repl_str);
- RETURN_NEW_STR(result);
- } else {
- zend_string *str_index = NULL;
- size_t result_len;
- zend_ulong num_index;
-
- array_init(return_value);
- from_idx = len_idx = repl_idx = 0;
- ZEND_HASH_FOREACH_KEY_VAL(str_ht, num_index, str_index, tmp_str) {
- zend_string *tmp_orig_str;
- zend_string *orig_str = zval_get_tmp_string(tmp_str, &tmp_orig_str);
- if (from_ht) {
- while (from_idx < from_ht->nNumUsed) {
- tmp_from = &from_ht->arData[from_idx].val;
- if (Z_TYPE_P(tmp_from) != IS_UNDEF) {
- break;
- }
- from_idx++;
- }
- if (from_idx < from_ht->nNumUsed) {
- f = zval_get_long(tmp_from);
- if (f < 0) {
- f = (zend_long)ZSTR_LEN(orig_str) + f;
- if (f < 0) {
- f = 0;
- }
- } else if (f > (zend_long)ZSTR_LEN(orig_str)) {
- f = ZSTR_LEN(orig_str);
- }
- from_idx++;
- } else {
- f = 0;
- }
- } else {
- f = from_long;
- if (f < 0) {
- f = (zend_long)ZSTR_LEN(orig_str) + f;
- if (f < 0) {
- f = 0;
- }
- } else if (f > (zend_long)ZSTR_LEN(orig_str)) {
- f = ZSTR_LEN(orig_str);
- }
- }
- if (len_ht) {
- while (len_idx < len_ht->nNumUsed) {
- tmp_len = &len_ht->arData[len_idx].val;
- if (Z_TYPE_P(tmp_len) != IS_UNDEF) {
- break;
- }
- len_idx++;
- }
- if (len_idx < len_ht->nNumUsed) {
- l = zval_get_long(tmp_len);
- len_idx++;
- } else {
- l = ZSTR_LEN(orig_str);
- }
- } else if (!len_is_null) {
- l = len_long;
- } else {
- l = ZSTR_LEN(orig_str);
- }
- if (l < 0) {
- l = (ZSTR_LEN(orig_str) - f) + l;
- if (l < 0) {
- l = 0;
- }
- }
- ZEND_ASSERT(0 <= f && f <= ZEND_LONG_MAX);
- ZEND_ASSERT(0 <= l && l <= ZEND_LONG_MAX);
- if (((size_t) f + l) > ZSTR_LEN(orig_str)) {
- l = ZSTR_LEN(orig_str) - f;
- }
- result_len = ZSTR_LEN(orig_str) - l;
- if (repl_ht) {
- while (repl_idx < repl_ht->nNumUsed) {
- tmp_repl = &repl_ht->arData[repl_idx].val;
- if (repl_ht != IS_UNDEF) {
- break;
- }
- repl_idx++;
- }
- if (repl_idx < repl_ht->nNumUsed) {
- zend_string *tmp_repl_str;
- zend_string *repl_str = zval_get_tmp_string(tmp_repl, &tmp_repl_str);
- result_len += ZSTR_LEN(repl_str);
- repl_idx++;
- result = zend_string_safe_alloc(1, result_len, 0, 0);
- memcpy(ZSTR_VAL(result), ZSTR_VAL(orig_str), f);
- memcpy((ZSTR_VAL(result) + f), ZSTR_VAL(repl_str), ZSTR_LEN(repl_str));
- memcpy((ZSTR_VAL(result) + f + ZSTR_LEN(repl_str)), ZSTR_VAL(orig_str) + f + l, ZSTR_LEN(orig_str) - f - l);
- zend_tmp_string_release(tmp_repl_str);
- } else {
- result = zend_string_safe_alloc(1, result_len, 0, 0);
- memcpy(ZSTR_VAL(result), ZSTR_VAL(orig_str), f);
- memcpy((ZSTR_VAL(result) + f), ZSTR_VAL(orig_str) + f + l, ZSTR_LEN(orig_str) - f - l);
- }
- } else {
- result_len += ZSTR_LEN(repl_str);
- result = zend_string_safe_alloc(1, result_len, 0, 0);
- memcpy(ZSTR_VAL(result), ZSTR_VAL(orig_str), f);
- memcpy((ZSTR_VAL(result) + f), ZSTR_VAL(repl_str), ZSTR_LEN(repl_str));
- memcpy((ZSTR_VAL(result) + f + ZSTR_LEN(repl_str)), ZSTR_VAL(orig_str) + f + l, ZSTR_LEN(orig_str) - f - l);
- }
- ZSTR_VAL(result)[ZSTR_LEN(result)] = '\0';
- if (str_index) {
- zval tmp;
- ZVAL_NEW_STR(&tmp, result);
- zend_symtable_update(Z_ARRVAL_P(return_value), str_index, &tmp);
- } else {
- add_index_str(return_value, num_index, result);
- }
- zend_tmp_string_release(tmp_orig_str);
- } ZEND_HASH_FOREACH_END();
- }
- }
- PHP_FUNCTION(quotemeta)
- {
- zend_string *old;
- const char *old_end, *p;
- char *q;
- char c;
- zend_string *str;
- ZEND_PARSE_PARAMETERS_START(1, 1)
- Z_PARAM_STR(old)
- ZEND_PARSE_PARAMETERS_END();
- old_end = ZSTR_VAL(old) + ZSTR_LEN(old);
- if (ZSTR_LEN(old) == 0) {
- RETURN_EMPTY_STRING();
- }
- str = zend_string_safe_alloc(2, ZSTR_LEN(old), 0, 0);
- for (p = ZSTR_VAL(old), q = ZSTR_VAL(str); p != old_end; p++) {
- c = *p;
- switch (c) {
- case '.':
- case '\\':
- case '+':
- case '*':
- case '?':
- case '[':
- case '^':
- case ']':
- case '$':
- case '(':
- case ')':
- *q++ = '\\';
- ZEND_FALLTHROUGH;
- default:
- *q++ = c;
- }
- }
- *q = '\0';
- RETURN_NEW_STR(zend_string_truncate(str, q - ZSTR_VAL(str), 0));
- }
- PHP_FUNCTION(ord)
- {
- zend_string *str;
- ZEND_PARSE_PARAMETERS_START(1, 1)
- Z_PARAM_STR(str)
- ZEND_PARSE_PARAMETERS_END();
- RETURN_LONG((unsigned char) ZSTR_VAL(str)[0]);
- }
- PHP_FUNCTION(chr)
- {
- zend_long c;
- ZEND_PARSE_PARAMETERS_START(1, 1)
- Z_PARAM_LONG(c)
- ZEND_PARSE_PARAMETERS_END();
- c &= 0xff;
- RETURN_CHAR(c);
- }
- static zend_string* php_ucfirst(zend_string *str)
- {
- const unsigned char ch = ZSTR_VAL(str)[0];
- unsigned char r = toupper(ch);
- if (r == ch) {
- return zend_string_copy(str);
- } else {
- zend_string *s = zend_string_init(ZSTR_VAL(str), ZSTR_LEN(str), 0);
- ZSTR_VAL(s)[0] = r;
- return s;
- }
- }
- PHP_FUNCTION(ucfirst)
- {
- zend_string *str;
- ZEND_PARSE_PARAMETERS_START(1, 1)
- Z_PARAM_STR(str)
- ZEND_PARSE_PARAMETERS_END();
- if (!ZSTR_LEN(str)) {
- RETURN_EMPTY_STRING();
- }
- RETURN_STR(php_ucfirst(str));
- }
- static zend_string* php_lcfirst(zend_string *str)
- {
- unsigned char r = tolower(ZSTR_VAL(str)[0]);
- if (r == ZSTR_VAL(str)[0]) {
- return zend_string_copy(str);
- } else {
- zend_string *s = zend_string_init(ZSTR_VAL(str), ZSTR_LEN(str), 0);
- ZSTR_VAL(s)[0] = r;
- return s;
- }
- }
- PHP_FUNCTION(lcfirst)
- {
- zend_string *str;
- ZEND_PARSE_PARAMETERS_START(1, 1)
- Z_PARAM_STR(str)
- ZEND_PARSE_PARAMETERS_END();
- if (!ZSTR_LEN(str)) {
- RETURN_EMPTY_STRING();
- }
- RETURN_STR(php_lcfirst(str));
- }
- PHP_FUNCTION(ucwords)
- {
- zend_string *str;
- char *delims = " \t\r\n\f\v";
- char *r;
- const char *r_end;
- size_t delims_len = 6;
- char mask[256];
- ZEND_PARSE_PARAMETERS_START(1, 2)
- Z_PARAM_STR(str)
- Z_PARAM_OPTIONAL
- Z_PARAM_STRING(delims, delims_len)
- ZEND_PARSE_PARAMETERS_END();
- if (!ZSTR_LEN(str)) {
- RETURN_EMPTY_STRING();
- }
- php_charmask((const unsigned char *) delims, delims_len, mask);
- ZVAL_STRINGL(return_value, ZSTR_VAL(str), ZSTR_LEN(str));
- r = Z_STRVAL_P(return_value);
- *r = toupper((unsigned char) *r);
- for (r_end = r + Z_STRLEN_P(return_value) - 1; r < r_end; ) {
- if (mask[(unsigned char)*r++]) {
- *r = toupper((unsigned char) *r);
- }
- }
- }
- PHPAPI char *php_strtr(char *str, size_t len, const char *str_from, const char *str_to, size_t trlen)
- {
- size_t i;
- if (UNEXPECTED(trlen < 1)) {
- return str;
- } else if (trlen == 1) {
- char ch_from = *str_from;
- char ch_to = *str_to;
- for (i = 0; i < len; i++) {
- if (str[i] == ch_from) {
- str[i] = ch_to;
- }
- }
- } else {
- unsigned char xlat[256];
- memset(xlat, 0, sizeof(xlat));
- for (i = 0; i < trlen; i++) {
- xlat[(size_t)(unsigned char) str_from[i]] = str_to[i] - str_from[i];
- }
- for (i = 0; i < len; i++) {
- str[i] += xlat[(size_t)(unsigned char) str[i]];
- }
- }
- return str;
- }
- static zend_string *php_strtr_ex(zend_string *str, const char *str_from, const char *str_to, size_t trlen)
- {
- zend_string *new_str = NULL;
- size_t i;
- if (UNEXPECTED(trlen < 1)) {
- return zend_string_copy(str);
- } else if (trlen == 1) {
- char ch_from = *str_from;
- char ch_to = *str_to;
- for (i = 0; i < ZSTR_LEN(str); i++) {
- if (ZSTR_VAL(str)[i] == ch_from) {
- new_str = zend_string_alloc(ZSTR_LEN(str), 0);
- memcpy(ZSTR_VAL(new_str), ZSTR_VAL(str), i);
- ZSTR_VAL(new_str)[i] = ch_to;
- i++;
- for (; i < ZSTR_LEN(str); i++) {
- ZSTR_VAL(new_str)[i] = (ZSTR_VAL(str)[i] != ch_from) ? ZSTR_VAL(str)[i] : ch_to;
- }
- ZSTR_VAL(new_str)[i] = 0;
- return new_str;
- }
- }
- } else {
- unsigned char xlat[256];
- memset(xlat, 0, sizeof(xlat));;
- for (i = 0; i < trlen; i++) {
- xlat[(size_t)(unsigned char) str_from[i]] = str_to[i] - str_from[i];
- }
- for (i = 0; i < ZSTR_LEN(str); i++) {
- if (xlat[(size_t)(unsigned char) ZSTR_VAL(str)[i]]) {
- new_str = zend_string_alloc(ZSTR_LEN(str), 0);
- memcpy(ZSTR_VAL(new_str), ZSTR_VAL(str), i);
- do {
- ZSTR_VAL(new_str)[i] = ZSTR_VAL(str)[i] + xlat[(size_t)(unsigned char) ZSTR_VAL(str)[i]];
- i++;
- } while (i < ZSTR_LEN(str));
- ZSTR_VAL(new_str)[i] = 0;
- return new_str;
- }
- }
- }
- return zend_string_copy(str);
- }
- static void php_strtr_array(zval *return_value, zend_string *input, HashTable *pats)
- {
- const char *str = ZSTR_VAL(input);
- size_t slen = ZSTR_LEN(input);
- zend_ulong num_key;
- zend_string *str_key;
- size_t len, pos, old_pos;
- int num_keys = 0;
- size_t minlen = 128*1024;
- size_t maxlen = 0;
- HashTable str_hash;
- zval *entry;
- const char *key;
- smart_str result = {0};
- zend_ulong bitset[256/sizeof(zend_ulong)];
- zend_ulong *num_bitset;
-
- num_bitset = ecalloc((slen + sizeof(zend_ulong)) / sizeof(zend_ulong), sizeof(zend_ulong));
- memset(bitset, 0, sizeof(bitset));
-
- ZEND_HASH_FOREACH_STR_KEY(pats, str_key) {
- if (UNEXPECTED(!str_key)) {
- num_keys = 1;
- } else {
- len = ZSTR_LEN(str_key);
- if (UNEXPECTED(len < 1)) {
- php_error_docref(NULL, E_WARNING, "Ignoring replacement of empty string");
- continue;
- } else if (UNEXPECTED(len > slen)) {
-
- continue;
- }
- if (len > maxlen) {
- maxlen = len;
- }
- if (len < minlen) {
- minlen = len;
- }
-
- num_bitset[len / sizeof(zend_ulong)] |= Z_UL(1) << (len % sizeof(zend_ulong));
- bitset[((unsigned char)ZSTR_VAL(str_key)[0]) / sizeof(zend_ulong)] |= Z_UL(1) << (((unsigned char)ZSTR_VAL(str_key)[0]) % sizeof(zend_ulong));
- }
- } ZEND_HASH_FOREACH_END();
- if (UNEXPECTED(num_keys)) {
- zend_string *key_used;
-
- zend_hash_init(&str_hash, zend_hash_num_elements(pats), NULL, NULL, 0);
- ZEND_HASH_FOREACH_KEY_VAL(pats, num_key, str_key, entry) {
- if (UNEXPECTED(!str_key)) {
- key_used = zend_long_to_str(num_key);
- len = ZSTR_LEN(key_used);
- if (UNEXPECTED(len > slen)) {
-
- zend_string_release(key_used);
- continue;
- }
- if (len > maxlen) {
- maxlen = len;
- }
- if (len < minlen) {
- minlen = len;
- }
-
- num_bitset[len / sizeof(zend_ulong)] |= Z_UL(1) << (len % sizeof(zend_ulong));
- bitset[((unsigned char)ZSTR_VAL(key_used)[0]) / sizeof(zend_ulong)] |= Z_UL(1) << (((unsigned char)ZSTR_VAL(key_used)[0]) % sizeof(zend_ulong));
- } else {
- key_used = str_key;
- len = ZSTR_LEN(key_used);
- if (UNEXPECTED(len > slen)) {
-
- continue;
- }
- }
- zend_hash_add(&str_hash, key_used, entry);
- if (UNEXPECTED(!str_key)) {
- zend_string_release_ex(key_used, 0);
- }
- } ZEND_HASH_FOREACH_END();
- pats = &str_hash;
- }
- if (UNEXPECTED(minlen > maxlen)) {
-
- if (pats == &str_hash) {
- zend_hash_destroy(&str_hash);
- }
- efree(num_bitset);
- RETURN_STR_COPY(input);
- }
- old_pos = pos = 0;
- while (pos <= slen - minlen) {
- key = str + pos;
- if (bitset[((unsigned char)key[0]) / sizeof(zend_ulong)] & (Z_UL(1) << (((unsigned char)key[0]) % sizeof(zend_ulong)))) {
- len = maxlen;
- if (len > slen - pos) {
- len = slen - pos;
- }
- while (len >= minlen) {
- if ((num_bitset[len / sizeof(zend_ulong)] & (Z_UL(1) << (len % sizeof(zend_ulong))))) {
- entry = zend_hash_str_find(pats, key, len);
- if (entry != NULL) {
- zend_string *tmp;
- zend_string *s = zval_get_tmp_string(entry, &tmp);
- smart_str_appendl(&result, str + old_pos, pos - old_pos);
- smart_str_append(&result, s);
- old_pos = pos + len;
- pos = old_pos - 1;
- zend_tmp_string_release(tmp);
- break;
- }
- }
- len--;
- }
- }
- pos++;
- }
- if (result.s) {
- smart_str_appendl(&result, str + old_pos, slen - old_pos);
- smart_str_0(&result);
- RETVAL_NEW_STR(result.s);
- } else {
- smart_str_free(&result);
- RETVAL_STR_COPY(input);
- }
- if (pats == &str_hash) {
- zend_hash_destroy(&str_hash);
- }
- efree(num_bitset);
- }
- static zend_string* php_char_to_str_ex(zend_string *str, char from, char *to, size_t to_len, int case_sensitivity, zend_long *replace_count)
- {
- zend_string *result;
- size_t char_count = 0;
- int lc_from = 0;
- const char *source, *source_end= ZSTR_VAL(str) + ZSTR_LEN(str);
- char *target;
- if (case_sensitivity) {
- char *p = ZSTR_VAL(str), *e = p + ZSTR_LEN(str);
- while ((p = memchr(p, from, (e - p)))) {
- char_count++;
- p++;
- }
- } else {
- lc_from = tolower(from);
- for (source = ZSTR_VAL(str); source < source_end; source++) {
- if (tolower(*source) == lc_from) {
- char_count++;
- }
- }
- }
- if (char_count == 0) {
- return zend_string_copy(str);
- }
- if (to_len > 0) {
- result = zend_string_safe_alloc(char_count, to_len - 1, ZSTR_LEN(str), 0);
- } else {
- result = zend_string_alloc(ZSTR_LEN(str) - char_count, 0);
- }
- target = ZSTR_VAL(result);
- if (case_sensitivity) {
- char *p = ZSTR_VAL(str), *e = p + ZSTR_LEN(str), *s = ZSTR_VAL(str);
- while ((p = memchr(p, from, (e - p)))) {
- memcpy(target, s, (p - s));
- target += p - s;
- memcpy(target, to, to_len);
- target += to_len;
- p++;
- s = p;
- if (replace_count) {
- *replace_count += 1;
- }
- }
- if (s < e) {
- memcpy(target, s, (e - s));
- target += e - s;
- }
- } else {
- for (source = ZSTR_VAL(str); source < source_end; source++) {
- if (tolower(*source) == lc_from) {
- if (replace_count) {
- *replace_count += 1;
- }
- memcpy(target, to, to_len);
- target += to_len;
- } else {
- *target = *source;
- target++;
- }
- }
- }
- *target = 0;
- return result;
- }
- static zend_string *php_str_to_str_ex(zend_string *haystack,
- const char *needle, size_t needle_len, const char *str, size_t str_len, zend_long *replace_count)
- {
- if (needle_len < ZSTR_LEN(haystack)) {
- zend_string *new_str;
- const char *end;
- const char *p, *r;
- char *e;
- if (needle_len == str_len) {
- new_str = NULL;
- end = ZSTR_VAL(haystack) + ZSTR_LEN(haystack);
- for (p = ZSTR_VAL(haystack); (r = (char*)php_memnstr(p, needle, needle_len, end)); p = r + needle_len) {
- if (!new_str) {
- new_str = zend_string_init(ZSTR_VAL(haystack), ZSTR_LEN(haystack), 0);
- }
- memcpy(ZSTR_VAL(new_str) + (r - ZSTR_VAL(haystack)), str, str_len);
- (*replace_count)++;
- }
- if (!new_str) {
- goto nothing_todo;
- }
- return new_str;
- } else {
- size_t count = 0;
- const char *o = ZSTR_VAL(haystack);
- const char *n = needle;
- const char *endp = o + ZSTR_LEN(haystack);
- while ((o = (char*)php_memnstr(o, n, needle_len, endp))) {
- o += needle_len;
- count++;
- }
- if (count == 0) {
-
- goto nothing_todo;
- }
- if (str_len > needle_len) {
- new_str = zend_string_safe_alloc(count, str_len - needle_len, ZSTR_LEN(haystack), 0);
- } else {
- new_str = zend_string_alloc(count * (str_len - needle_len) + ZSTR_LEN(haystack), 0);
- }
- e = ZSTR_VAL(new_str);
- end = ZSTR_VAL(haystack) + ZSTR_LEN(haystack);
- for (p = ZSTR_VAL(haystack); (r = (char*)php_memnstr(p, needle, needle_len, end)); p = r + needle_len) {
- memcpy(e, p, r - p);
- e += r - p;
- memcpy(e, str, str_len);
- e += str_len;
- (*replace_count)++;
- }
- if (p < end) {
- memcpy(e, p, end - p);
- e += end - p;
- }
- *e = '\0';
- return new_str;
- }
- } else if (needle_len > ZSTR_LEN(haystack) || memcmp(ZSTR_VAL(haystack), needle, ZSTR_LEN(haystack))) {
- nothing_todo:
- return zend_string_copy(haystack);
- } else {
- (*replace_count)++;
- return zend_string_init_fast(str, str_len);
- }
- }
- static zend_string *php_str_to_str_i_ex(zend_string *haystack, const char *lc_haystack,
- zend_string *needle, const char *str, size_t str_len, zend_long *replace_count)
- {
- zend_string *new_str = NULL;
- zend_string *lc_needle;
- if (ZSTR_LEN(needle) < ZSTR_LEN(haystack)) {
- const char *end;
- const char *p, *r;
- char *e;
- if (ZSTR_LEN(needle) == str_len) {
- lc_needle = php_string_tolower(needle);
- end = lc_haystack + ZSTR_LEN(haystack);
- for (p = lc_haystack; (r = (char*)php_memnstr(p, ZSTR_VAL(lc_needle), ZSTR_LEN(lc_needle), end)); p = r + ZSTR_LEN(lc_needle)) {
- if (!new_str) {
- new_str = zend_string_init(ZSTR_VAL(haystack), ZSTR_LEN(haystack), 0);
- }
- memcpy(ZSTR_VAL(new_str) + (r - lc_haystack), str, str_len);
- (*replace_count)++;
- }
- zend_string_release_ex(lc_needle, 0);
- if (!new_str) {
- goto nothing_todo;
- }
- return new_str;
- } else {
- size_t count = 0;
- const char *o = lc_haystack;
- const char *n;
- const char *endp = o + ZSTR_LEN(haystack);
- lc_needle = php_string_tolower(needle);
- n = ZSTR_VAL(lc_needle);
- while ((o = (char*)php_memnstr(o, n, ZSTR_LEN(lc_needle), endp))) {
- o += ZSTR_LEN(lc_needle);
- count++;
- }
- if (count == 0) {
-
- zend_string_release_ex(lc_needle, 0);
- goto nothing_todo;
- }
- if (str_len > ZSTR_LEN(lc_needle)) {
- new_str = zend_string_safe_alloc(count, str_len - ZSTR_LEN(lc_needle), ZSTR_LEN(haystack), 0);
- } else {
- new_str = zend_string_alloc(count * (str_len - ZSTR_LEN(lc_needle)) + ZSTR_LEN(haystack), 0);
- }
- e = ZSTR_VAL(new_str);
- end = lc_haystack + ZSTR_LEN(haystack);
- for (p = lc_haystack; (r = (char*)php_memnstr(p, ZSTR_VAL(lc_needle), ZSTR_LEN(lc_needle), end)); p = r + ZSTR_LEN(lc_needle)) {
- memcpy(e, ZSTR_VAL(haystack) + (p - lc_haystack), r - p);
- e += r - p;
- memcpy(e, str, str_len);
- e += str_len;
- (*replace_count)++;
- }
- if (p < end) {
- memcpy(e, ZSTR_VAL(haystack) + (p - lc_haystack), end - p);
- e += end - p;
- }
- *e = '\0';
- zend_string_release_ex(lc_needle, 0);
- return new_str;
- }
- } else if (ZSTR_LEN(needle) > ZSTR_LEN(haystack)) {
- nothing_todo:
- return zend_string_copy(haystack);
- } else {
- lc_needle = php_string_tolower(needle);
- if (memcmp(lc_haystack, ZSTR_VAL(lc_needle), ZSTR_LEN(lc_needle))) {
- zend_string_release_ex(lc_needle, 0);
- goto nothing_todo;
- }
- zend_string_release_ex(lc_needle, 0);
- new_str = zend_string_init(str, str_len, 0);
- (*replace_count)++;
- return new_str;
- }
- }
- PHPAPI zend_string *php_str_to_str(const char *haystack, size_t length, const char *needle, size_t needle_len, const char *str, size_t str_len)
- {
- zend_string *new_str;
- if (needle_len < length) {
- const char *end;
- const char *s, *p;
- char *e, *r;
- if (needle_len == str_len) {
- new_str = zend_string_init(haystack, length, 0);
- end = ZSTR_VAL(new_str) + length;
- for (p = ZSTR_VAL(new_str); (r = (char*)php_memnstr(p, needle, needle_len, end)); p = r + needle_len) {
- memcpy(r, str, str_len);
- }
- return new_str;
- } else {
- if (str_len < needle_len) {
- new_str = zend_string_alloc(length, 0);
- } else {
- size_t count = 0;
- const char *o = haystack;
- const char *n = needle;
- const char *endp = o + length;
- while ((o = (char*)php_memnstr(o, n, needle_len, endp))) {
- o += needle_len;
- count++;
- }
- if (count == 0) {
-
- new_str = zend_string_init(haystack, length, 0);
- return new_str;
- } else {
- if (str_len > needle_len) {
- new_str = zend_string_safe_alloc(count, str_len - needle_len, length, 0);
- } else {
- new_str = zend_string_alloc(count * (str_len - needle_len) + length, 0);
- }
- }
- }
- s = e = ZSTR_VAL(new_str);
- end = haystack + length;
- for (p = haystack; (r = (char*)php_memnstr(p, needle, needle_len, end)); p = r + needle_len) {
- memcpy(e, p, r - p);
- e += r - p;
- memcpy(e, str, str_len);
- e += str_len;
- }
- if (p < end) {
- memcpy(e, p, end - p);
- e += end - p;
- }
- *e = '\0';
- new_str = zend_string_truncate(new_str, e - s, 0);
- return new_str;
- }
- } else if (needle_len > length || memcmp(haystack, needle, length)) {
- new_str = zend_string_init(haystack, length, 0);
- return new_str;
- } else {
- new_str = zend_string_init(str, str_len, 0);
- return new_str;
- }
- }
- PHP_FUNCTION(strtr)
- {
- zend_string *str, *from_str = NULL;
- HashTable *from_ht = NULL;
- char *to = NULL;
- size_t to_len = 0;
- ZEND_PARSE_PARAMETERS_START(2, 3)
- Z_PARAM_STR(str)
- Z_PARAM_ARRAY_HT_OR_STR(from_ht, from_str)
- Z_PARAM_OPTIONAL
- Z_PARAM_STRING_OR_NULL(to, to_len)
- ZEND_PARSE_PARAMETERS_END();
- if (!to && from_ht == NULL) {
- zend_argument_type_error(2, "must be of type array, string given");
- RETURN_THROWS();
- } else if (to && from_str == NULL) {
- zend_argument_type_error(2, "must be of type string, array given");
- RETURN_THROWS();
- }
-
- if (ZSTR_LEN(str) == 0) {
- RETURN_EMPTY_STRING();
- }
- if (!to) {
- if (zend_hash_num_elements(from_ht) < 1) {
- RETURN_STR_COPY(str);
- } else if (zend_hash_num_elements(from_ht) == 1) {
- zend_long num_key;
- zend_string *str_key, *tmp_str, *replace, *tmp_replace;
- zval *entry;
- ZEND_HASH_FOREACH_KEY_VAL(from_ht, num_key, str_key, entry) {
- tmp_str = NULL;
- if (UNEXPECTED(!str_key)) {
- str_key = tmp_str = zend_long_to_str(num_key);
- }
- replace = zval_get_tmp_string(entry, &tmp_replace);
- if (ZSTR_LEN(str_key) < 1) {
- php_error_docref(NULL, E_WARNING, "Ignoring replacement of empty string");
- RETVAL_STR_COPY(str);
- } else if (ZSTR_LEN(str_key) == 1) {
- RETVAL_STR(php_char_to_str_ex(str,
- ZSTR_VAL(str_key)[0],
- ZSTR_VAL(replace),
- ZSTR_LEN(replace),
- 1,
- NULL));
- } else {
- zend_long dummy;
- RETVAL_STR(php_str_to_str_ex(str,
- ZSTR_VAL(str_key), ZSTR_LEN(str_key),
- ZSTR_VAL(replace), ZSTR_LEN(replace), &dummy));
- }
- zend_tmp_string_release(tmp_str);
- zend_tmp_string_release(tmp_replace);
- return;
- } ZEND_HASH_FOREACH_END();
- } else {
- php_strtr_array(return_value, str, from_ht);
- }
- } else {
- RETURN_STR(php_strtr_ex(str,
- ZSTR_VAL(from_str),
- to,
- MIN(ZSTR_LEN(from_str), to_len)));
- }
- }
- #if ZEND_INTRIN_SSSE3_NATIVE
- #include <tmmintrin.h>
- #elif defined(__aarch64__)
- #include <arm_neon.h>
- #endif
- PHP_FUNCTION(strrev)
- {
- zend_string *str;
- const char *s, *e;
- char *p;
- zend_string *n;
- ZEND_PARSE_PARAMETERS_START(1, 1)
- Z_PARAM_STR(str)
- ZEND_PARSE_PARAMETERS_END();
- n = zend_string_alloc(ZSTR_LEN(str), 0);
- p = ZSTR_VAL(n);
- s = ZSTR_VAL(str);
- e = s + ZSTR_LEN(str);
- --e;
- #if ZEND_INTRIN_SSSE3_NATIVE
- if (e - s > 15) {
- const __m128i map = _mm_set_epi8(
- 0, 1, 2, 3,
- 4, 5, 6, 7,
- 8, 9, 10, 11,
- 12, 13, 14, 15);
- do {
- const __m128i str = _mm_loadu_si128((__m128i *)(e - 15));
- _mm_storeu_si128((__m128i *)p, _mm_shuffle_epi8(str, map));
- p += 16;
- e -= 16;
- } while (e - s > 15);
- }
- #elif defined(__aarch64__)
- if (e - s > 15) {
- do {
- const uint8x16_t str = vld1q_u8((uint8_t *)(e - 15));
-
- const uint8x16_t rev = vrev64q_u8(str);
- const uint8x16_t ext = (uint8x16_t)
- vextq_u64((uint64x2_t)rev, (uint64x2_t)rev, 1);
- vst1q_u8((uint8_t *)p, ext);
- p += 16;
- e -= 16;
- } while (e - s > 15);
- }
- #endif
- while (e >= s) {
- *p++ = *e--;
- }
- *p = '\0';
- RETVAL_NEW_STR(n);
- }
- static void php_similar_str(const char *txt1, size_t len1, const char *txt2, size_t len2, size_t *pos1, size_t *pos2, size_t *max, size_t *count)
- {
- const char *p, *q;
- const char *end1 = (char *) txt1 + len1;
- const char *end2 = (char *) txt2 + len2;
- size_t l;
- *max = 0;
- *count = 0;
- for (p = (char *) txt1; p < end1; p++) {
- for (q = (char *) txt2; q < end2; q++) {
- for (l = 0; (p + l < end1) && (q + l < end2) && (p[l] == q[l]); l++);
- if (l > *max) {
- *max = l;
- *count += 1;
- *pos1 = p - txt1;
- *pos2 = q - txt2;
- }
- }
- }
- }
- static size_t php_similar_char(const char *txt1, size_t len1, const char *txt2, size_t len2)
- {
- size_t sum;
- size_t pos1 = 0, pos2 = 0, max, count;
- php_similar_str(txt1, len1, txt2, len2, &pos1, &pos2, &max, &count);
- if ((sum = max)) {
- if (pos1 && pos2 && count > 1) {
- sum += php_similar_char(txt1, pos1,
- txt2, pos2);
- }
- if ((pos1 + max < len1) && (pos2 + max < len2)) {
- sum += php_similar_char(txt1 + pos1 + max, len1 - pos1 - max,
- txt2 + pos2 + max, len2 - pos2 - max);
- }
- }
- return sum;
- }
- PHP_FUNCTION(similar_text)
- {
- zend_string *t1, *t2;
- zval *percent = NULL;
- int ac = ZEND_NUM_ARGS();
- size_t sim;
- ZEND_PARSE_PARAMETERS_START(2, 3)
- Z_PARAM_STR(t1)
- Z_PARAM_STR(t2)
- Z_PARAM_OPTIONAL
- Z_PARAM_ZVAL(percent)
- ZEND_PARSE_PARAMETERS_END();
- if (ZSTR_LEN(t1) + ZSTR_LEN(t2) == 0) {
- if (ac > 2) {
- ZEND_TRY_ASSIGN_REF_DOUBLE(percent, 0);
- }
- RETURN_LONG(0);
- }
- sim = php_similar_char(ZSTR_VAL(t1), ZSTR_LEN(t1), ZSTR_VAL(t2), ZSTR_LEN(t2));
- if (ac > 2) {
- ZEND_TRY_ASSIGN_REF_DOUBLE(percent, sim * 200.0 / (ZSTR_LEN(t1) + ZSTR_LEN(t2)));
- }
- RETURN_LONG(sim);
- }
- PHP_FUNCTION(addcslashes)
- {
- zend_string *str, *what;
- ZEND_PARSE_PARAMETERS_START(2, 2)
- Z_PARAM_STR(str)
- Z_PARAM_STR(what)
- ZEND_PARSE_PARAMETERS_END();
- if (ZSTR_LEN(str) == 0) {
- RETURN_EMPTY_STRING();
- }
- if (ZSTR_LEN(what) == 0) {
- RETURN_STR_COPY(str);
- }
- RETURN_STR(php_addcslashes_str(ZSTR_VAL(str), ZSTR_LEN(str), ZSTR_VAL(what), ZSTR_LEN(what)));
- }
- PHP_FUNCTION(addslashes)
- {
- zend_string *str;
- ZEND_PARSE_PARAMETERS_START(1, 1)
- Z_PARAM_STR(str)
- ZEND_PARSE_PARAMETERS_END();
- if (ZSTR_LEN(str) == 0) {
- RETURN_EMPTY_STRING();
- }
- RETURN_STR(php_addslashes(str));
- }
- PHP_FUNCTION(stripcslashes)
- {
- zend_string *str;
- ZEND_PARSE_PARAMETERS_START(1, 1)
- Z_PARAM_STR(str)
- ZEND_PARSE_PARAMETERS_END();
- ZVAL_STRINGL(return_value, ZSTR_VAL(str), ZSTR_LEN(str));
- php_stripcslashes(Z_STR_P(return_value));
- }
- PHP_FUNCTION(stripslashes)
- {
- zend_string *str;
- ZEND_PARSE_PARAMETERS_START(1, 1)
- Z_PARAM_STR(str)
- ZEND_PARSE_PARAMETERS_END();
- ZVAL_STRINGL(return_value, ZSTR_VAL(str), ZSTR_LEN(str));
- php_stripslashes(Z_STR_P(return_value));
- }
- PHPAPI void php_stripcslashes(zend_string *str)
- {
- const char *source, *end;
- char *target;
- size_t nlen = ZSTR_LEN(str), i;
- char numtmp[4];
- for (source = (char*)ZSTR_VAL(str), end = source + ZSTR_LEN(str), target = ZSTR_VAL(str); source < end; source++) {
- if (*source == '\\' && source + 1 < end) {
- source++;
- switch (*source) {
- case 'n': *target++='\n'; nlen--; break;
- case 'r': *target++='\r'; nlen--; break;
- case 'a': *target++='\a'; nlen--; break;
- case 't': *target++='\t'; nlen--; break;
- case 'v': *target++='\v'; nlen--; break;
- case 'b': *target++='\b'; nlen--; break;
- case 'f': *target++='\f'; nlen--; break;
- case '\\': *target++='\\'; nlen--; break;
- case 'x':
- if (source+1 < end && isxdigit((int)(*(source+1)))) {
- numtmp[0] = *++source;
- if (source+1 < end && isxdigit((int)(*(source+1)))) {
- numtmp[1] = *++source;
- numtmp[2] = '\0';
- nlen-=3;
- } else {
- numtmp[1] = '\0';
- nlen-=2;
- }
- *target++=(char)strtol(numtmp, NULL, 16);
- break;
- }
- ZEND_FALLTHROUGH;
- default:
- i=0;
- while (source < end && *source >= '0' && *source <= '7' && i<3) {
- numtmp[i++] = *source++;
- }
- if (i) {
- numtmp[i]='\0';
- *target++=(char)strtol(numtmp, NULL, 8);
- nlen-=i;
- source--;
- } else {
- *target++=*source;
- nlen--;
- }
- }
- } else {
- *target++=*source;
- }
- }
- if (nlen != 0) {
- *target='\0';
- }
- ZSTR_LEN(str) = nlen;
- }
- PHPAPI zend_string *php_addcslashes_str(const char *str, size_t len, const char *what, size_t wlength)
- {
- char flags[256];
- char *target;
- const char *source, *end;
- char c;
- size_t newlen;
- zend_string *new_str = zend_string_safe_alloc(4, len, 0, 0);
- php_charmask((const unsigned char *) what, wlength, flags);
- for (source = str, end = source + len, target = ZSTR_VAL(new_str); source < end; source++) {
- c = *source;
- if (flags[(unsigned char)c]) {
- if ((unsigned char) c < 32 || (unsigned char) c > 126) {
- *target++ = '\\';
- switch (c) {
- case '\n': *target++ = 'n'; break;
- case '\t': *target++ = 't'; break;
- case '\r': *target++ = 'r'; break;
- case '\a': *target++ = 'a'; break;
- case '\v': *target++ = 'v'; break;
- case '\b': *target++ = 'b'; break;
- case '\f': *target++ = 'f'; break;
- default: target += sprintf(target, "%03o", (unsigned char) c);
- }
- continue;
- }
- *target++ = '\\';
- }
- *target++ = c;
- }
- *target = 0;
- newlen = target - ZSTR_VAL(new_str);
- if (newlen < len * 4) {
- new_str = zend_string_truncate(new_str, newlen, 0);
- }
- return new_str;
- }
- PHPAPI zend_string *php_addcslashes(zend_string *str, const char *what, size_t wlength)
- {
- return php_addcslashes_str(ZSTR_VAL(str), ZSTR_LEN(str), what, wlength);
- }
- #if ZEND_INTRIN_SSE4_2_NATIVE
- # include <nmmintrin.h>
- # include "Zend/zend_bitset.h"
- #elif ZEND_INTRIN_SSE4_2_RESOLVER
- # include <nmmintrin.h>
- # include "Zend/zend_bitset.h"
- # include "Zend/zend_cpuinfo.h"
- ZEND_INTRIN_SSE4_2_FUNC_DECL(zend_string *php_addslashes_sse42(zend_string *str));
- zend_string *php_addslashes_default(zend_string *str);
- ZEND_INTRIN_SSE4_2_FUNC_DECL(void php_stripslashes_sse42(zend_string *str));
- void php_stripslashes_default(zend_string *str);
- # if ZEND_INTRIN_SSE4_2_FUNC_PROTO
- PHPAPI zend_string *php_addslashes(zend_string *str) __attribute__((ifunc("resolve_addslashes")));
- PHPAPI void php_stripslashes(zend_string *str) __attribute__((ifunc("resolve_stripslashes")));
- typedef zend_string *(*php_addslashes_func_t)(zend_string *);
- typedef void (*php_stripslashes_func_t)(zend_string *);
- ZEND_NO_SANITIZE_ADDRESS
- ZEND_ATTRIBUTE_UNUSED
- static php_addslashes_func_t resolve_addslashes(void) {
- if (zend_cpu_supports_sse42()) {
- return php_addslashes_sse42;
- }
- return php_addslashes_default;
- }
- ZEND_NO_SANITIZE_ADDRESS
- ZEND_ATTRIBUTE_UNUSED
- static php_stripslashes_func_t resolve_stripslashes(void) {
- if (zend_cpu_supports_sse42()) {
- return php_stripslashes_sse42;
- }
- return php_stripslashes_default;
- }
- # else
- static zend_string *(*php_addslashes_ptr)(zend_string *str) = NULL;
- static void (*php_stripslashes_ptr)(zend_string *str) = NULL;
- PHPAPI zend_string *php_addslashes(zend_string *str) {
- return php_addslashes_ptr(str);
- }
- PHPAPI void php_stripslashes(zend_string *str) {
- php_stripslashes_ptr(str);
- }
- PHP_MINIT_FUNCTION(string_intrin)
- {
- if (zend_cpu_supports_sse42()) {
- php_addslashes_ptr = php_addslashes_sse42;
- php_stripslashes_ptr = php_stripslashes_sse42;
- } else {
- php_addslashes_ptr = php_addslashes_default;
- php_stripslashes_ptr = php_stripslashes_default;
- }
- return SUCCESS;
- }
- # endif
- #endif
- #if ZEND_INTRIN_SSE4_2_NATIVE || ZEND_INTRIN_SSE4_2_RESOLVER
- # if ZEND_INTRIN_SSE4_2_NATIVE
- PHPAPI zend_string *php_addslashes(zend_string *str)
- # elif ZEND_INTRIN_SSE4_2_RESOLVER
- zend_string *php_addslashes_sse42(zend_string *str)
- # endif
- {
- ZEND_SET_ALIGNED(16, static const char slashchars[16]) = "\'\"\\\0";
- __m128i w128, s128;
- uint32_t res = 0;
-
- char *target;
- const char *source, *end;
- size_t offset;
- zend_string *new_str;
- if (!str) {
- return ZSTR_EMPTY_ALLOC();
- }
- source = ZSTR_VAL(str);
- end = source + ZSTR_LEN(str);
- if (ZSTR_LEN(str) > 15) {
- w128 = _mm_load_si128((__m128i *)slashchars);
- do {
- s128 = _mm_loadu_si128((__m128i *)source);
- res = _mm_cvtsi128_si32(_mm_cmpestrm(w128, 4, s128, 16, _SIDD_UBYTE_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_BIT_MASK));
- if (res) {
- goto do_escape;
- }
- source += 16;
- } while ((end - source) > 15);
- }
- while (source < end) {
- switch (*source) {
- case '\0':
- case '\'':
- case '\"':
- case '\\':
- goto do_escape;
- default:
- source++;
- break;
- }
- }
- return zend_string_copy(str);
- do_escape:
- offset = source - (char *)ZSTR_VAL(str);
- new_str = zend_string_safe_alloc(2, ZSTR_LEN(str) - offset, offset, 0);
- memcpy(ZSTR_VAL(new_str), ZSTR_VAL(str), offset);
- target = ZSTR_VAL(new_str) + offset;
- if (res) {
- int pos = 0;
- do {
- int i, n = zend_ulong_ntz(res);
- for (i = 0; i < n; i++) {
- *target++ = source[pos + i];
- }
- pos += n;
- *target++ = '\\';
- if (source[pos] == '\0') {
- *target++ = '0';
- } else {
- *target++ = source[pos];
- }
- pos++;
- res = res >> (n + 1);
- } while (res);
- for (; pos < 16; pos++) {
- *target++ = source[pos];
- }
- source += 16;
- } else if (end - source > 15) {
- w128 = _mm_load_si128((__m128i *)slashchars);
- }
- for (; end - source > 15; source += 16) {
- int pos = 0;
- s128 = _mm_loadu_si128((__m128i *)source);
- res = _mm_cvtsi128_si32(_mm_cmpestrm(w128, 4, s128, 16, _SIDD_UBYTE_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_BIT_MASK));
- if (res) {
- do {
- int i, n = zend_ulong_ntz(res);
- for (i = 0; i < n; i++) {
- *target++ = source[pos + i];
- }
- pos += n;
- *target++ = '\\';
- if (source[pos] == '\0') {
- *target++ = '0';
- } else {
- *target++ = source[pos];
- }
- pos++;
- res = res >> (n + 1);
- } while (res);
- for (; pos < 16; pos++) {
- *target++ = source[pos];
- }
- } else {
- _mm_storeu_si128((__m128i*)target, s128);
- target += 16;
- }
- }
- while (source < end) {
- switch (*source) {
- case '\0':
- *target++ = '\\';
- *target++ = '0';
- break;
- case '\'':
- case '\"':
- case '\\':
- *target++ = '\\';
- ZEND_FALLTHROUGH;
- default:
- *target++ = *source;
- break;
- }
- source++;
- }
- *target = '\0';
- if (ZSTR_LEN(new_str) - (target - ZSTR_VAL(new_str)) > 16) {
- new_str = zend_string_truncate(new_str, target - ZSTR_VAL(new_str), 0);
- } else {
- ZSTR_LEN(new_str) = target - ZSTR_VAL(new_str);
- }
- return new_str;
- }
- #endif
- #ifdef __aarch64__
- typedef union {
- uint8_t mem[16];
- uint64_t dw[2];
- } quad_word;
- static zend_always_inline quad_word aarch64_contains_slash_chars(uint8x16_t x) {
- uint8x16_t s0 = vceqq_u8(x, vdupq_n_u8('\0'));
- uint8x16_t s1 = vceqq_u8(x, vdupq_n_u8('\''));
- uint8x16_t s2 = vceqq_u8(x, vdupq_n_u8('\"'));
- uint8x16_t s3 = vceqq_u8(x, vdupq_n_u8('\\'));
- uint8x16_t s01 = vorrq_u8(s0, s1);
- uint8x16_t s23 = vorrq_u8(s2, s3);
- uint8x16_t s0123 = vorrq_u8(s01, s23);
- quad_word qw;
- vst1q_u8(qw.mem, s0123);
- return qw;
- }
- static zend_always_inline char *aarch64_add_slashes(quad_word res, const char *source, char *target)
- {
- int i = 0;
- for (; i < 16; i++) {
- char s = source[i];
- if (res.mem[i] == 0)
- *target++ = s;
- else {
- *target++ = '\\';
- if (s == '\0')
- *target++ = '0';
- else
- *target++ = s;
- }
- }
- return target;
- }
- #endif
- #if !ZEND_INTRIN_SSE4_2_NATIVE
- # if ZEND_INTRIN_SSE4_2_RESOLVER
- zend_string *php_addslashes_default(zend_string *str)
- # else
- PHPAPI zend_string *php_addslashes(zend_string *str)
- # endif
- {
-
- char *target;
- const char *source, *end;
- size_t offset;
- zend_string *new_str;
- if (!str) {
- return ZSTR_EMPTY_ALLOC();
- }
- source = ZSTR_VAL(str);
- end = source + ZSTR_LEN(str);
- # ifdef __aarch64__
- quad_word res = {0};
- if (ZSTR_LEN(str) > 15) {
- do {
- res = aarch64_contains_slash_chars(vld1q_u8((uint8_t *)source));
- if (res.dw[0] | res.dw[1])
- goto do_escape;
- source += 16;
- } while ((end - source) > 15);
- }
-
- # endif
- while (source < end) {
- switch (*source) {
- case '\0':
- case '\'':
- case '\"':
- case '\\':
- goto do_escape;
- default:
- source++;
- break;
- }
- }
- return zend_string_copy(str);
- do_escape:
- offset = source - (char *)ZSTR_VAL(str);
- new_str = zend_string_safe_alloc(2, ZSTR_LEN(str) - offset, offset, 0);
- memcpy(ZSTR_VAL(new_str), ZSTR_VAL(str), offset);
- target = ZSTR_VAL(new_str) + offset;
- # ifdef __aarch64__
- if (res.dw[0] | res.dw[1]) {
- target = aarch64_add_slashes(res, source, target);
- source += 16;
- }
- for (; end - source > 15; source += 16) {
- uint8x16_t x = vld1q_u8((uint8_t *)source);
- res = aarch64_contains_slash_chars(x);
- if (res.dw[0] | res.dw[1]) {
- target = aarch64_add_slashes(res, source, target);
- } else {
- vst1q_u8((uint8_t*)target, x);
- target += 16;
- }
- }
-
- # endif
- while (source < end) {
- switch (*source) {
- case '\0':
- *target++ = '\\';
- *target++ = '0';
- break;
- case '\'':
- case '\"':
- case '\\':
- *target++ = '\\';
- ZEND_FALLTHROUGH;
- default:
- *target++ = *source;
- break;
- }
- source++;
- }
- *target = '\0';
- if (ZSTR_LEN(new_str) - (target - ZSTR_VAL(new_str)) > 16) {
- new_str = zend_string_truncate(new_str, target - ZSTR_VAL(new_str), 0);
- } else {
- ZSTR_LEN(new_str) = target - ZSTR_VAL(new_str);
- }
- return new_str;
- }
- #endif
- static zend_always_inline char *php_stripslashes_impl(const char *str, char *out, size_t len)
- {
- #ifdef __aarch64__
- while (len > 15) {
- uint8x16_t x = vld1q_u8((uint8_t *)str);
- quad_word q;
- vst1q_u8(q.mem, vceqq_u8(x, vdupq_n_u8('\\')));
- if (q.dw[0] | q.dw[1]) {
- int i = 0;
- for (; i < 16; i++) {
- if (q.mem[i] == 0) {
- *out++ = str[i];
- continue;
- }
- i++;
- char s = str[i];
- if (s == '0')
- *out++ = '\0';
- else
- *out++ = s;
- }
- str += i;
- len -= i;
- } else {
- vst1q_u8((uint8_t*)out, x);
- out += 16;
- str += 16;
- len -= 16;
- }
- }
-
- #endif
- while (len > 0) {
- if (*str == '\\') {
- str++;
- len--;
- if (len > 0) {
- if (*str == '0') {
- *out++='\0';
- str++;
- } else {
- *out++ = *str++;
- }
- len--;
- }
- } else {
- *out++ = *str++;
- len--;
- }
- }
- return out;
- }
- #if ZEND_INTRIN_SSE4_2_NATIVE || ZEND_INTRIN_SSE4_2_RESOLVER
- # if ZEND_INTRIN_SSE4_2_NATIVE
- PHPAPI void php_stripslashes(zend_string *str)
- # elif ZEND_INTRIN_SSE4_2_RESOLVER
- void php_stripslashes_sse42(zend_string *str)
- # endif
- {
- const char *s = ZSTR_VAL(str);
- char *t = ZSTR_VAL(str);
- size_t l = ZSTR_LEN(str);
- if (l > 15) {
- const __m128i slash = _mm_set1_epi8('\\');
- do {
- __m128i in = _mm_loadu_si128((__m128i *)s);
- __m128i any_slash = _mm_cmpeq_epi8(in, slash);
- uint32_t res = _mm_movemask_epi8(any_slash);
- if (res) {
- int i, n = zend_ulong_ntz(res);
- const char *e = s + 15;
- l -= n;
- for (i = 0; i < n; i++) {
- *t++ = *s++;
- }
- for (; s < e; s++) {
- if (*s == '\\') {
- s++;
- l--;
- if (*s == '0') {
- *t = '\0';
- } else {
- *t = *s;
- }
- } else {
- *t = *s;
- }
- t++;
- l--;
- }
- } else {
- _mm_storeu_si128((__m128i *)t, in);
- s += 16;
- t += 16;
- l -= 16;
- }
- } while (l > 15);
- }
- t = php_stripslashes_impl(s, t, l);
- if (t != (ZSTR_VAL(str) + ZSTR_LEN(str))) {
- ZSTR_LEN(str) = t - ZSTR_VAL(str);
- ZSTR_VAL(str)[ZSTR_LEN(str)] = '\0';
- }
- }
- #endif
- #if !ZEND_INTRIN_SSE4_2_NATIVE
- # if ZEND_INTRIN_SSE4_2_RESOLVER
- void php_stripslashes_default(zend_string *str)
- # else
- PHPAPI void php_stripslashes(zend_string *str)
- # endif
- {
- const char *t = php_stripslashes_impl(ZSTR_VAL(str), ZSTR_VAL(str), ZSTR_LEN(str));
- if (t != (ZSTR_VAL(str) + ZSTR_LEN(str))) {
- ZSTR_LEN(str) = t - ZSTR_VAL(str);
- ZSTR_VAL(str)[ZSTR_LEN(str)] = '\0';
- }
- }
- #endif
- #define _HEB_BLOCK_TYPE_ENG 1
- #define _HEB_BLOCK_TYPE_HEB 2
- #define isheb(c) (((((unsigned char) c) >= 224) && (((unsigned char) c) <= 250)) ? 1 : 0)
- #define _isblank(c) (((((unsigned char) c) == ' ' || ((unsigned char) c) == '\t')) ? 1 : 0)
- #define _isnewline(c) (((((unsigned char) c) == '\n' || ((unsigned char) c) == '\r')) ? 1 : 0)
- static zend_long php_str_replace_in_subject(
- zend_string *search_str, HashTable *search_ht, zend_string *replace_str, HashTable *replace_ht,
- zend_string *subject_str, zval *result, int case_sensitivity
- ) {
- zval *search_entry;
- zend_string *tmp_result;
- char *replace_value = NULL;
- size_t replace_len = 0;
- zend_long replace_count = 0;
- zend_string *lc_subject_str = NULL;
- uint32_t replace_idx;
- if (ZSTR_LEN(subject_str) == 0) {
- ZVAL_EMPTY_STRING(result);
- return 0;
- }
-
- if (search_ht) {
-
- zend_string_addref(subject_str);
- if (replace_ht) {
- replace_idx = 0;
- } else {
-
- replace_value = ZSTR_VAL(replace_str);
- replace_len = ZSTR_LEN(replace_str);
- }
-
- ZEND_HASH_FOREACH_VAL(search_ht, search_entry) {
-
- zend_string *tmp_search_str;
- zend_string *search_str = zval_get_tmp_string(search_entry, &tmp_search_str);
- zend_string *replace_entry_str, *tmp_replace_entry_str = NULL;
-
- if (replace_ht) {
-
- zval *replace_entry = NULL;
- while (replace_idx < replace_ht->nNumUsed) {
- replace_entry = &replace_ht->arData[replace_idx].val;
- if (Z_TYPE_P(replace_entry) != IS_UNDEF) {
- break;
- }
- replace_idx++;
- }
- if (replace_idx < replace_ht->nNumUsed) {
-
- replace_entry_str = zval_get_tmp_string(replace_entry, &tmp_replace_entry_str);
-
- replace_value = ZSTR_VAL(replace_entry_str);
- replace_len = ZSTR_LEN(replace_entry_str);
- replace_idx++;
- } else {
-
- replace_value = "";
- replace_len = 0;
- }
- }
- if (ZSTR_LEN(search_str) == 1) {
- zend_long old_replace_count = replace_count;
- tmp_result = php_char_to_str_ex(subject_str,
- ZSTR_VAL(search_str)[0],
- replace_value,
- replace_len,
- case_sensitivity,
- &replace_count);
- if (lc_subject_str && replace_count != old_replace_count) {
- zend_string_release_ex(lc_subject_str, 0);
- lc_subject_str = NULL;
- }
- } else if (ZSTR_LEN(search_str) > 1) {
- if (case_sensitivity) {
- tmp_result = php_str_to_str_ex(subject_str,
- ZSTR_VAL(search_str), ZSTR_LEN(search_str),
- replace_value, replace_len, &replace_count);
- } else {
- zend_long old_replace_count = replace_count;
- if (!lc_subject_str) {
- lc_subject_str = php_string_tolower(subject_str);
- }
- tmp_result = php_str_to_str_i_ex(subject_str, ZSTR_VAL(lc_subject_str),
- search_str, replace_value, replace_len, &replace_count);
- if (replace_count != old_replace_count) {
- zend_string_release_ex(lc_subject_str, 0);
- lc_subject_str = NULL;
- }
- }
- } else {
- zend_tmp_string_release(tmp_search_str);
- zend_tmp_string_release(tmp_replace_entry_str);
- continue;
- }
- zend_tmp_string_release(tmp_search_str);
- zend_tmp_string_release(tmp_replace_entry_str);
- if (subject_str == tmp_result) {
- zend_string_delref(subject_str);
- } else {
- zend_string_release_ex(subject_str, 0);
- subject_str = tmp_result;
- if (ZSTR_LEN(subject_str) == 0) {
- zend_string_release_ex(subject_str, 0);
- ZVAL_EMPTY_STRING(result);
- if (lc_subject_str) {
- zend_string_release_ex(lc_subject_str, 0);
- }
- return replace_count;
- }
- }
- } ZEND_HASH_FOREACH_END();
- ZVAL_STR(result, subject_str);
- if (lc_subject_str) {
- zend_string_release_ex(lc_subject_str, 0);
- }
- } else {
- ZEND_ASSERT(search_str);
- if (ZSTR_LEN(search_str) == 1) {
- ZVAL_STR(result,
- php_char_to_str_ex(subject_str,
- ZSTR_VAL(search_str)[0],
- ZSTR_VAL(replace_str),
- ZSTR_LEN(replace_str),
- case_sensitivity,
- &replace_count));
- } else if (ZSTR_LEN(search_str) > 1) {
- if (case_sensitivity) {
- ZVAL_STR(result, php_str_to_str_ex(subject_str,
- ZSTR_VAL(search_str), ZSTR_LEN(search_str),
- ZSTR_VAL(replace_str), ZSTR_LEN(replace_str), &replace_count));
- } else {
- lc_subject_str = php_string_tolower(subject_str);
- ZVAL_STR(result, php_str_to_str_i_ex(subject_str, ZSTR_VAL(lc_subject_str),
- search_str, ZSTR_VAL(replace_str), ZSTR_LEN(replace_str), &replace_count));
- zend_string_release_ex(lc_subject_str, 0);
- }
- } else {
- ZVAL_STR_COPY(result, subject_str);
- }
- }
- return replace_count;
- }
- static void php_str_replace_common(INTERNAL_FUNCTION_PARAMETERS, int case_sensitivity)
- {
- zend_string *search_str;
- HashTable *search_ht;
- zend_string *replace_str;
- HashTable *replace_ht;
- zend_string *subject_str;
- HashTable *subject_ht;
- zval *subject_entry, *zcount = NULL;
- zval result;
- zend_string *string_key;
- zend_ulong num_key;
- zend_long count = 0;
- ZEND_PARSE_PARAMETERS_START(3, 4)
- Z_PARAM_ARRAY_HT_OR_STR(search_ht, search_str)
- Z_PARAM_ARRAY_HT_OR_STR(replace_ht, replace_str)
- Z_PARAM_ARRAY_HT_OR_STR(subject_ht, subject_str)
- Z_PARAM_OPTIONAL
- Z_PARAM_ZVAL(zcount)
- ZEND_PARSE_PARAMETERS_END();
-
- if (search_str && replace_ht) {
- zend_argument_type_error(2, "must be of type %s when argument #1 ($search) is %s",
- search_str ? "string" : "array", search_str ? "a string" : "an array"
- );
- RETURN_THROWS();
- }
-
- if (subject_ht) {
- array_init(return_value);
-
- ZEND_HASH_FOREACH_KEY_VAL(subject_ht, num_key, string_key, subject_entry) {
- zend_string *tmp_subject_str;
- ZVAL_DEREF(subject_entry);
- subject_str = zval_get_tmp_string(subject_entry, &tmp_subject_str);
- count += php_str_replace_in_subject(search_str, search_ht, replace_str, replace_ht, subject_str, &result, case_sensitivity);
- zend_tmp_string_release(tmp_subject_str);
-
- if (string_key) {
- zend_hash_add_new(Z_ARRVAL_P(return_value), string_key, &result);
- } else {
- zend_hash_index_add_new(Z_ARRVAL_P(return_value), num_key, &result);
- }
- } ZEND_HASH_FOREACH_END();
- } else {
- count = php_str_replace_in_subject(search_str, search_ht, replace_str, replace_ht, subject_str, return_value, case_sensitivity);
- }
- if (zcount) {
- ZEND_TRY_ASSIGN_REF_LONG(zcount, count);
- }
- }
- PHP_FUNCTION(str_replace)
- {
- php_str_replace_common(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
- }
- PHP_FUNCTION(str_ireplace)
- {
- php_str_replace_common(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
- }
- PHP_FUNCTION(hebrev)
- {
- char *str, *heb_str, *target;
- const char *tmp;
- size_t block_start, block_end, block_type, block_length, i;
- zend_long max_chars=0, char_count;
- size_t begin, end, orig_begin;
- size_t str_len;
- zend_string *broken_str;
- ZEND_PARSE_PARAMETERS_START(1, 2)
- Z_PARAM_STRING(str, str_len)
- Z_PARAM_OPTIONAL
- Z_PARAM_LONG(max_chars)
- ZEND_PARSE_PARAMETERS_END();
- if (str_len == 0) {
- RETURN_EMPTY_STRING();
- }
- tmp = str;
- block_start=block_end=0;
- heb_str = (char *) emalloc(str_len+1);
- target = heb_str+str_len;
- *target = 0;
- target--;
- block_length=0;
- if (isheb(*tmp)) {
- block_type = _HEB_BLOCK_TYPE_HEB;
- } else {
- block_type = _HEB_BLOCK_TYPE_ENG;
- }
- do {
- if (block_type == _HEB_BLOCK_TYPE_HEB) {
- while ((isheb((int)*(tmp+1)) || _isblank((int)*(tmp+1)) || ispunct((int)*(tmp+1)) || (int)*(tmp+1)=='\n' ) && block_end<str_len-1) {
- tmp++;
- block_end++;
- block_length++;
- }
- for (i = block_start+1; i<= block_end+1; i++) {
- *target = str[i-1];
- switch (*target) {
- case '(':
- *target = ')';
- break;
- case ')':
- *target = '(';
- break;
- case '[':
- *target = ']';
- break;
- case ']':
- *target = '[';
- break;
- case '{':
- *target = '}';
- break;
- case '}':
- *target = '{';
- break;
- case '<':
- *target = '>';
- break;
- case '>':
- *target = '<';
- break;
- case '\\':
- *target = '/';
- break;
- case '/':
- *target = '\\';
- break;
- default:
- break;
- }
- target--;
- }
- block_type = _HEB_BLOCK_TYPE_ENG;
- } else {
- while (!isheb(*(tmp+1)) && (int)*(tmp+1)!='\n' && block_end < str_len-1) {
- tmp++;
- block_end++;
- block_length++;
- }
- while ((_isblank((int)*tmp) || ispunct((int)*tmp)) && *tmp!='/' && *tmp!='-' && block_end > block_start) {
- tmp--;
- block_end--;
- }
- for (i = block_end+1; i >= block_start+1; i--) {
- *target = str[i-1];
- target--;
- }
- block_type = _HEB_BLOCK_TYPE_HEB;
- }
- block_start=block_end+1;
- } while (block_end < str_len-1);
- broken_str = zend_string_alloc(str_len, 0);
- begin = end = str_len-1;
- target = ZSTR_VAL(broken_str);
- while (1) {
- char_count=0;
- while ((!max_chars || (max_chars > 0 && char_count < max_chars)) && begin > 0) {
- char_count++;
- begin--;
- if (_isnewline(heb_str[begin])) {
- while (begin > 0 && _isnewline(heb_str[begin-1])) {
- begin--;
- char_count++;
- }
- break;
- }
- }
- if (max_chars >= 0 && char_count == max_chars) {
- size_t new_char_count=char_count, new_begin=begin;
- while (new_char_count > 0) {
- if (_isblank(heb_str[new_begin]) || _isnewline(heb_str[new_begin])) {
- break;
- }
- new_begin++;
- new_char_count--;
- }
- if (new_char_count > 0) {
- begin=new_begin;
- }
- }
- orig_begin=begin;
- if (_isblank(heb_str[begin])) {
- heb_str[begin]='\n';
- }
- while (begin <= end && _isnewline(heb_str[begin])) {
- begin++;
- }
- for (i = begin; i <= end; i++) {
- *target = heb_str[i];
- target++;
- }
- for (i = orig_begin; i <= end && _isnewline(heb_str[i]); i++) {
- *target = heb_str[i];
- target++;
- }
- begin=orig_begin;
- if (begin == 0) {
- *target = 0;
- break;
- }
- begin--;
- end=begin;
- }
- efree(heb_str);
- RETURN_NEW_STR(broken_str);
- }
- PHP_FUNCTION(nl2br)
- {
-
- const char *tmp, *end;
- zend_string *str;
- char *target;
- size_t repl_cnt = 0;
- bool is_xhtml = 1;
- zend_string *result;
- ZEND_PARSE_PARAMETERS_START(1, 2)
- Z_PARAM_STR(str)
- Z_PARAM_OPTIONAL
- Z_PARAM_BOOL(is_xhtml)
- ZEND_PARSE_PARAMETERS_END();
- tmp = ZSTR_VAL(str);
- end = ZSTR_VAL(str) + ZSTR_LEN(str);
-
- while (tmp < end) {
- if (*tmp == '\r') {
- if (*(tmp+1) == '\n') {
- tmp++;
- }
- repl_cnt++;
- } else if (*tmp == '\n') {
- if (*(tmp+1) == '\r') {
- tmp++;
- }
- repl_cnt++;
- }
- tmp++;
- }
- if (repl_cnt == 0) {
- RETURN_STR_COPY(str);
- }
- {
- size_t repl_len = is_xhtml ? (sizeof("<br />") - 1) : (sizeof("<br>") - 1);
- result = zend_string_safe_alloc(repl_cnt, repl_len, ZSTR_LEN(str), 0);
- target = ZSTR_VAL(result);
- }
- tmp = ZSTR_VAL(str);
- while (tmp < end) {
- switch (*tmp) {
- case '\r':
- case '\n':
- *target++ = '<';
- *target++ = 'b';
- *target++ = 'r';
- if (is_xhtml) {
- *target++ = ' ';
- *target++ = '/';
- }
- *target++ = '>';
- if ((*tmp == '\r' && *(tmp+1) == '\n') || (*tmp == '\n' && *(tmp+1) == '\r')) {
- *target++ = *tmp++;
- }
- ZEND_FALLTHROUGH;
- default:
- *target++ = *tmp;
- }
- tmp++;
- }
- *target = '\0';
- RETURN_NEW_STR(result);
- }
- PHP_FUNCTION(strip_tags)
- {
- zend_string *buf;
- zend_string *str;
- zend_string *allow_str = NULL;
- HashTable *allow_ht = NULL;
- const char *allowed_tags=NULL;
- size_t allowed_tags_len=0;
- smart_str tags_ss = {0};
- ZEND_PARSE_PARAMETERS_START(1, 2)
- Z_PARAM_STR(str)
- Z_PARAM_OPTIONAL
- Z_PARAM_ARRAY_HT_OR_STR_OR_NULL(allow_ht, allow_str)
- ZEND_PARSE_PARAMETERS_END();
- if (allow_ht) {
- zval *tmp;
- zend_string *tag;
- ZEND_HASH_FOREACH_VAL(allow_ht, tmp) {
- tag = zval_get_string(tmp);
- smart_str_appendc(&tags_ss, '<');
- smart_str_append(&tags_ss, tag);
- smart_str_appendc(&tags_ss, '>');
- zend_string_release(tag);
- } ZEND_HASH_FOREACH_END();
- if (tags_ss.s) {
- smart_str_0(&tags_ss);
- allowed_tags = ZSTR_VAL(tags_ss.s);
- allowed_tags_len = ZSTR_LEN(tags_ss.s);
- }
- } else if (allow_str) {
- allowed_tags = ZSTR_VAL(allow_str);
- allowed_tags_len = ZSTR_LEN(allow_str);
- }
- buf = zend_string_init(ZSTR_VAL(str), ZSTR_LEN(str), 0);
- ZSTR_LEN(buf) = php_strip_tags_ex(ZSTR_VAL(buf), ZSTR_LEN(str), allowed_tags, allowed_tags_len, 0);
- smart_str_free(&tags_ss);
- RETURN_NEW_STR(buf);
- }
- static zend_string *try_setlocale_str(zend_long cat, zend_string *loc) {
- const char *retval;
- if (zend_string_equals_literal(loc, "0")) {
- loc = NULL;
- } else {
- if (ZSTR_LEN(loc) >= 255) {
- php_error_docref(NULL, E_WARNING, "Specified locale name is too long");
- return NULL;
- }
- }
- # ifndef PHP_WIN32
- retval = setlocale(cat, loc ? ZSTR_VAL(loc) : NULL);
- # else
- if (loc) {
-
- char *locp = ZSTR_VAL(loc);
- if (ZSTR_LEN(loc) >= 5 && locp[2] == '_'
- && locp[0] >= 'a' && locp[0] <= 'z' && locp[1] >= 'a' && locp[1] <= 'z'
- && locp[3] >= 'A' && locp[3] <= 'Z' && locp[4] >= 'A' && locp[4] <= 'Z'
- && (locp[5] == '\0' || locp[5] == '.')
- && !(locp[0] == 'u' && (locp[1] == 'k' || locp[1] == 's')
- && locp[3] == 'U' && (locp[4] == 'K' || locp[4] == 'S')
- && locp[5] == '\0')
- ) {
- retval = NULL;
- } else {
- retval = setlocale(cat, ZSTR_VAL(loc));
- }
- } else {
- retval = setlocale(cat, NULL);
- }
- # endif
- if (!retval) {
- return NULL;
- }
- if (loc) {
-
- size_t len = strlen(retval);
- BG(locale_changed) = 1;
- if (cat == LC_CTYPE || cat == LC_ALL) {
- zend_update_current_locale();
- if (BG(ctype_string)) {
- zend_string_release_ex(BG(ctype_string), 0);
- }
- if (len == 1 && *retval == 'C') {
-
- BG(ctype_string) = NULL;
- return ZSTR_CHAR('C');
- } else if (len == ZSTR_LEN(loc) && !memcmp(ZSTR_VAL(loc), retval, len)) {
- BG(ctype_string) = zend_string_copy(loc);
- return zend_string_copy(BG(ctype_string));
- } else {
- BG(ctype_string) = zend_string_init(retval, len, 0);
- return zend_string_copy(BG(ctype_string));
- }
- } else if (len == ZSTR_LEN(loc) && !memcmp(ZSTR_VAL(loc), retval, len)) {
- return zend_string_copy(loc);
- }
- }
- return zend_string_init(retval, strlen(retval), 0);
- }
- static zend_string *try_setlocale_zval(zend_long cat, zval *loc_zv) {
- zend_string *tmp_loc_str;
- zend_string *loc_str = zval_try_get_tmp_string(loc_zv, &tmp_loc_str);
- if (UNEXPECTED(loc_str == NULL)) {
- return NULL;
- }
- zend_string *result = try_setlocale_str(cat, loc_str);
- zend_tmp_string_release(tmp_loc_str);
- return result;
- }
- PHP_FUNCTION(setlocale)
- {
- zend_long cat;
- zval *args = NULL;
- int num_args;
- ZEND_PARSE_PARAMETERS_START(2, -1)
- Z_PARAM_LONG(cat)
- Z_PARAM_VARIADIC('+', args, num_args)
- ZEND_PARSE_PARAMETERS_END();
- for (uint32_t i = 0; i < num_args; i++) {
- if (Z_TYPE(args[i]) == IS_ARRAY) {
- zval *elem;
- ZEND_HASH_FOREACH_VAL(Z_ARRVAL(args[i]), elem) {
- zend_string *result = try_setlocale_zval(cat, elem);
- if (EG(exception)) {
- RETURN_THROWS();
- }
- if (result) {
- RETURN_STR(result);
- }
- } ZEND_HASH_FOREACH_END();
- } else {
- zend_string *result = try_setlocale_zval(cat, &args[i]);
- if (EG(exception)) {
- RETURN_THROWS();
- }
- if (result) {
- RETURN_STR(result);
- }
- }
- }
- RETURN_FALSE;
- }
- PHP_FUNCTION(parse_str)
- {
- char *arg;
- zval *arrayArg = NULL;
- char *res = NULL;
- size_t arglen;
- ZEND_PARSE_PARAMETERS_START(2, 2)
- Z_PARAM_STRING(arg, arglen)
- Z_PARAM_ZVAL(arrayArg)
- ZEND_PARSE_PARAMETERS_END();
- arrayArg = zend_try_array_init(arrayArg);
- if (!arrayArg) {
- RETURN_THROWS();
- }
- res = estrndup(arg, arglen);
- sapi_module.treat_data(PARSE_STRING, res, arrayArg);
- }
- #define PHP_TAG_BUF_SIZE 1023
- int php_tag_find(char *tag, size_t len, const char *set) {
- char c, *n;
- const char *t;
- int state=0, done=0;
- char *norm;
- if (len == 0) {
- return 0;
- }
- norm = emalloc(len+1);
- n = norm;
- t = tag;
- c = tolower(*t);
-
- while (!done) {
- switch (c) {
- case '<':
- *(n++) = c;
- break;
- case '>':
- done =1;
- break;
- default:
- if (!isspace((int)c)) {
- if (state == 0) {
- state=1;
- }
- if (c != '/' || (*(t-1) != '<' && *(t+1) != '>')) {
- *(n++) = c;
- }
- } else {
- if (state == 1)
- done=1;
- }
- break;
- }
- c = tolower(*(++t));
- }
- *(n++) = '>';
- *n = '\0';
- if (strstr(set, norm)) {
- done=1;
- } else {
- done=0;
- }
- efree(norm);
- return done;
- }
- PHPAPI size_t php_strip_tags(char *rbuf, size_t len, const char *allow, size_t allow_len)
- {
- return php_strip_tags_ex(rbuf, len, allow, allow_len, 0);
- }
- PHPAPI size_t php_strip_tags_ex(char *rbuf, size_t len, const char *allow, size_t allow_len, bool allow_tag_spaces)
- {
- char *tbuf, *tp, *rp, c, lc;
- const char *buf, *p, *end;
- int br, depth=0, in_q = 0;
- uint8_t state = 0;
- size_t pos;
- char *allow_free = NULL;
- char is_xml = 0;
- buf = estrndup(rbuf, len);
- end = buf + len;
- lc = '\0';
- p = buf;
- rp = rbuf;
- br = 0;
- if (allow) {
- allow_free = zend_str_tolower_dup_ex(allow, allow_len);
- allow = allow_free ? allow_free : allow;
- tbuf = emalloc(PHP_TAG_BUF_SIZE + 1);
- tp = tbuf;
- } else {
- tbuf = tp = NULL;
- }
- state_0:
- if (p >= end) {
- goto finish;
- }
- c = *p;
- switch (c) {
- case '\0':
- break;
- case '<':
- if (in_q) {
- break;
- }
- if (isspace(*(p + 1)) && !allow_tag_spaces) {
- *(rp++) = c;
- break;
- }
- lc = '<';
- state = 1;
- if (allow) {
- if (tp - tbuf >= PHP_TAG_BUF_SIZE) {
- pos = tp - tbuf;
- tbuf = erealloc(tbuf, (tp - tbuf) + PHP_TAG_BUF_SIZE + 1);
- tp = tbuf + pos;
- }
- *(tp++) = '<';
- }
- p++;
- goto state_1;
- case '>':
- if (depth) {
- depth--;
- break;
- }
- if (in_q) {
- break;
- }
- *(rp++) = c;
- break;
- default:
- *(rp++) = c;
- break;
- }
- p++;
- goto state_0;
- state_1:
- if (p >= end) {
- goto finish;
- }
- c = *p;
- switch (c) {
- case '\0':
- break;
- case '<':
- if (in_q) {
- break;
- }
- if (isspace(*(p + 1)) && !allow_tag_spaces) {
- goto reg_char_1;
- }
- depth++;
- break;
- case '>':
- if (depth) {
- depth--;
- break;
- }
- if (in_q) {
- break;
- }
- lc = '>';
- if (is_xml && p >= buf + 1 && *(p -1) == '-') {
- break;
- }
- in_q = state = is_xml = 0;
- if (allow) {
- if (tp - tbuf >= PHP_TAG_BUF_SIZE) {
- pos = tp - tbuf;
- tbuf = erealloc(tbuf, (tp - tbuf) + PHP_TAG_BUF_SIZE + 1);
- tp = tbuf + pos;
- }
- *(tp++) = '>';
- *tp='\0';
- if (php_tag_find(tbuf, tp-tbuf, allow)) {
- memcpy(rp, tbuf, tp-tbuf);
- rp += tp-tbuf;
- }
- tp = tbuf;
- }
- p++;
- goto state_0;
- case '"':
- case '\'':
- if (p != buf && (!in_q || *p == in_q)) {
- if (in_q) {
- in_q = 0;
- } else {
- in_q = *p;
- }
- }
- goto reg_char_1;
- case '!':
-
- if (p >= buf + 1 && *(p-1) == '<') {
- state = 3;
- lc = c;
- p++;
- goto state_3;
- } else {
- goto reg_char_1;
- }
- break;
- case '?':
- if (p >= buf + 1 && *(p-1) == '<') {
- br=0;
- state = 2;
- p++;
- goto state_2;
- } else {
- goto reg_char_1;
- }
- break;
- default:
- reg_char_1:
- if (allow) {
- if (tp - tbuf >= PHP_TAG_BUF_SIZE) {
- pos = tp - tbuf;
- tbuf = erealloc(tbuf, (tp - tbuf) + PHP_TAG_BUF_SIZE + 1);
- tp = tbuf + pos;
- }
- *(tp++) = c;
- }
- break;
- }
- p++;
- goto state_1;
- state_2:
- if (p >= end) {
- goto finish;
- }
- c = *p;
- switch (c) {
- case '(':
- if (lc != '"' && lc != '\'') {
- lc = '(';
- br++;
- }
- break;
- case ')':
- if (lc != '"' && lc != '\'') {
- lc = ')';
- br--;
- }
- break;
- case '>':
- if (depth) {
- depth--;
- break;
- }
- if (in_q) {
- break;
- }
- if (!br && p >= buf + 1 && lc != '\"' && *(p-1) == '?') {
- in_q = state = 0;
- tp = tbuf;
- p++;
- goto state_0;
- }
- break;
- case '"':
- case '\'':
- if (p >= buf + 1 && *(p-1) != '\\') {
- if (lc == c) {
- lc = '\0';
- } else if (lc != '\\') {
- lc = c;
- }
- if (p != buf && (!in_q || *p == in_q)) {
- if (in_q) {
- in_q = 0;
- } else {
- in_q = *p;
- }
- }
- }
- break;
- case 'l':
- case 'L':
-
- if (state == 2 && p > buf+4
- && (*(p-1) == 'm' || *(p-1) == 'M')
- && (*(p-2) == 'x' || *(p-2) == 'X')
- && *(p-3) == '?'
- && *(p-4) == '<') {
- state = 1; is_xml=1;
- p++;
- goto state_1;
- }
- break;
- default:
- break;
- }
- p++;
- goto state_2;
- state_3:
- if (p >= end) {
- goto finish;
- }
- c = *p;
- switch (c) {
- case '>':
- if (depth) {
- depth--;
- break;
- }
- if (in_q) {
- break;
- }
- in_q = state = 0;
- tp = tbuf;
- p++;
- goto state_0;
- case '"':
- case '\'':
- if (p != buf && *(p-1) != '\\' && (!in_q || *p == in_q)) {
- if (in_q) {
- in_q = 0;
- } else {
- in_q = *p;
- }
- }
- break;
- case '-':
- if (p >= buf + 2 && *(p-1) == '-' && *(p-2) == '!') {
- state = 4;
- p++;
- goto state_4;
- }
- break;
- case 'E':
- case 'e':
-
- if (p > buf+6
- && (*(p-1) == 'p' || *(p-1) == 'P')
- && (*(p-2) == 'y' || *(p-2) == 'Y')
- && (*(p-3) == 't' || *(p-3) == 'T')
- && (*(p-4) == 'c' || *(p-4) == 'C')
- && (*(p-5) == 'o' || *(p-5) == 'O')
- && (*(p-6) == 'd' || *(p-6) == 'D')) {
- state = 1;
- p++;
- goto state_1;
- }
- break;
- default:
- break;
- }
- p++;
- goto state_3;
- state_4:
- while (p < end) {
- c = *p;
- if (c == '>' && !in_q) {
- if (p >= buf + 2 && *(p-1) == '-' && *(p-2) == '-') {
- in_q = state = 0;
- tp = tbuf;
- p++;
- goto state_0;
- }
- }
- p++;
- }
- finish:
- if (rp < rbuf + len) {
- *rp = '\0';
- }
- efree((void *)buf);
- if (tbuf) {
- efree(tbuf);
- }
- if (allow_free) {
- efree(allow_free);
- }
- return (size_t)(rp - rbuf);
- }
- PHP_FUNCTION(str_getcsv)
- {
- zend_string *str;
- char delim = ',', enc = '"';
- int esc = (unsigned char) '\\';
- char *delim_str = NULL, *enc_str = NULL, *esc_str = NULL;
- size_t delim_len = 0, enc_len = 0, esc_len = 0;
- ZEND_PARSE_PARAMETERS_START(1, 4)
- Z_PARAM_STR(str)
- Z_PARAM_OPTIONAL
- Z_PARAM_STRING(delim_str, delim_len)
- Z_PARAM_STRING(enc_str, enc_len)
- Z_PARAM_STRING(esc_str, esc_len)
- ZEND_PARSE_PARAMETERS_END();
- delim = delim_len ? delim_str[0] : delim;
- enc = enc_len ? enc_str[0] : enc;
- if (esc_str != NULL) {
- esc = esc_len ? (unsigned char) esc_str[0] : PHP_CSV_NO_ESCAPE;
- }
- php_fgetcsv(NULL, delim, enc, esc, ZSTR_LEN(str), ZSTR_VAL(str), return_value);
- }
- PHP_FUNCTION(str_repeat)
- {
- zend_string *input_str;
- zend_long mult;
- zend_string *result;
- size_t result_len;
- ZEND_PARSE_PARAMETERS_START(2, 2)
- Z_PARAM_STR(input_str)
- Z_PARAM_LONG(mult)
- ZEND_PARSE_PARAMETERS_END();
- if (mult < 0) {
- zend_argument_value_error(2, "must be greater than or equal to 0");
- RETURN_THROWS();
- }
-
-
- if (ZSTR_LEN(input_str) == 0 || mult == 0)
- RETURN_EMPTY_STRING();
-
- result = zend_string_safe_alloc(ZSTR_LEN(input_str), mult, 0, 0);
- result_len = ZSTR_LEN(input_str) * mult;
-
- if (ZSTR_LEN(input_str) == 1) {
- memset(ZSTR_VAL(result), *ZSTR_VAL(input_str), mult);
- } else {
- const char *s, *ee;
- char *e;
- ptrdiff_t l=0;
- memcpy(ZSTR_VAL(result), ZSTR_VAL(input_str), ZSTR_LEN(input_str));
- s = ZSTR_VAL(result);
- e = ZSTR_VAL(result) + ZSTR_LEN(input_str);
- ee = ZSTR_VAL(result) + result_len;
- while (e<ee) {
- l = (e-s) < (ee-e) ? (e-s) : (ee-e);
- memmove(e, s, l);
- e += l;
- }
- }
- ZSTR_VAL(result)[result_len] = '\0';
- RETURN_NEW_STR(result);
- }
- PHP_FUNCTION(count_chars)
- {
- zend_string *input;
- int chars[256];
- zend_long mymode=0;
- const unsigned char *buf;
- int inx;
- char retstr[256];
- size_t retlen=0;
- size_t tmp = 0;
- ZEND_PARSE_PARAMETERS_START(1, 2)
- Z_PARAM_STR(input)
- Z_PARAM_OPTIONAL
- Z_PARAM_LONG(mymode)
- ZEND_PARSE_PARAMETERS_END();
- if (mymode < 0 || mymode > 4) {
- zend_argument_value_error(2, "must be between 1 and 4 (inclusive)");
- RETURN_THROWS();
- }
- buf = (const unsigned char *) ZSTR_VAL(input);
- memset((void*) chars, 0, sizeof(chars));
- while (tmp < ZSTR_LEN(input)) {
- chars[*buf]++;
- buf++;
- tmp++;
- }
- if (mymode < 3) {
- array_init(return_value);
- }
- for (inx = 0; inx < 256; inx++) {
- switch (mymode) {
- case 0:
- add_index_long(return_value, inx, chars[inx]);
- break;
- case 1:
- if (chars[inx] != 0) {
- add_index_long(return_value, inx, chars[inx]);
- }
- break;
- case 2:
- if (chars[inx] == 0) {
- add_index_long(return_value, inx, chars[inx]);
- }
- break;
- case 3:
- if (chars[inx] != 0) {
- retstr[retlen++] = inx;
- }
- break;
- case 4:
- if (chars[inx] == 0) {
- retstr[retlen++] = inx;
- }
- break;
- }
- }
- if (mymode == 3 || mymode == 4) {
- RETURN_STRINGL(retstr, retlen);
- }
- }
- static void php_strnatcmp(INTERNAL_FUNCTION_PARAMETERS, int fold_case)
- {
- zend_string *s1, *s2;
- ZEND_PARSE_PARAMETERS_START(2, 2)
- Z_PARAM_STR(s1)
- Z_PARAM_STR(s2)
- ZEND_PARSE_PARAMETERS_END();
- RETURN_LONG(strnatcmp_ex(ZSTR_VAL(s1), ZSTR_LEN(s1),
- ZSTR_VAL(s2), ZSTR_LEN(s2),
- fold_case));
- }
- PHPAPI int string_natural_compare_function_ex(zval *result, zval *op1, zval *op2, bool case_insensitive)
- {
- zend_string *tmp_str1, *tmp_str2;
- zend_string *str1 = zval_get_tmp_string(op1, &tmp_str1);
- zend_string *str2 = zval_get_tmp_string(op2, &tmp_str2);
- ZVAL_LONG(result, strnatcmp_ex(ZSTR_VAL(str1), ZSTR_LEN(str1), ZSTR_VAL(str2), ZSTR_LEN(str2), case_insensitive));
- zend_tmp_string_release(tmp_str1);
- zend_tmp_string_release(tmp_str2);
- return SUCCESS;
- }
- PHPAPI int string_natural_case_compare_function(zval *result, zval *op1, zval *op2)
- {
- return string_natural_compare_function_ex(result, op1, op2, 1);
- }
- PHPAPI int string_natural_compare_function(zval *result, zval *op1, zval *op2)
- {
- return string_natural_compare_function_ex(result, op1, op2, 0);
- }
- PHP_FUNCTION(strnatcmp)
- {
- php_strnatcmp(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
- }
- PHP_FUNCTION(localeconv)
- {
- zval grouping, mon_grouping;
- int len, i;
- ZEND_PARSE_PARAMETERS_NONE();
- array_init(return_value);
- array_init(&grouping);
- array_init(&mon_grouping);
- {
- struct lconv currlocdata;
- localeconv_r( &currlocdata );
-
- len = (int)strlen(currlocdata.grouping);
- for (i = 0; i < len; i++) {
- add_index_long(&grouping, i, currlocdata.grouping[i]);
- }
-
- len = (int)strlen(currlocdata.mon_grouping);
- for (i = 0; i < len; i++) {
- add_index_long(&mon_grouping, i, currlocdata.mon_grouping[i]);
- }
- add_assoc_string(return_value, "decimal_point", currlocdata.decimal_point);
- add_assoc_string(return_value, "thousands_sep", currlocdata.thousands_sep);
- add_assoc_string(return_value, "int_curr_symbol", currlocdata.int_curr_symbol);
- add_assoc_string(return_value, "currency_symbol", currlocdata.currency_symbol);
- add_assoc_string(return_value, "mon_decimal_point", currlocdata.mon_decimal_point);
- add_assoc_string(return_value, "mon_thousands_sep", currlocdata.mon_thousands_sep);
- add_assoc_string(return_value, "positive_sign", currlocdata.positive_sign);
- add_assoc_string(return_value, "negative_sign", currlocdata.negative_sign);
- add_assoc_long( return_value, "int_frac_digits", currlocdata.int_frac_digits);
- add_assoc_long( return_value, "frac_digits", currlocdata.frac_digits);
- add_assoc_long( return_value, "p_cs_precedes", currlocdata.p_cs_precedes);
- add_assoc_long( return_value, "p_sep_by_space", currlocdata.p_sep_by_space);
- add_assoc_long( return_value, "n_cs_precedes", currlocdata.n_cs_precedes);
- add_assoc_long( return_value, "n_sep_by_space", currlocdata.n_sep_by_space);
- add_assoc_long( return_value, "p_sign_posn", currlocdata.p_sign_posn);
- add_assoc_long( return_value, "n_sign_posn", currlocdata.n_sign_posn);
- }
- zend_hash_str_update(Z_ARRVAL_P(return_value), "grouping", sizeof("grouping")-1, &grouping);
- zend_hash_str_update(Z_ARRVAL_P(return_value), "mon_grouping", sizeof("mon_grouping")-1, &mon_grouping);
- }
- PHP_FUNCTION(strnatcasecmp)
- {
- php_strnatcmp(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
- }
- PHP_FUNCTION(substr_count)
- {
- char *haystack, *needle;
- zend_long offset = 0, length = 0;
- bool length_is_null = 1;
- zend_long count = 0;
- size_t haystack_len, needle_len;
- const char *p, *endp;
- char cmp;
- ZEND_PARSE_PARAMETERS_START(2, 4)
- Z_PARAM_STRING(haystack, haystack_len)
- Z_PARAM_STRING(needle, needle_len)
- Z_PARAM_OPTIONAL
- Z_PARAM_LONG(offset)
- Z_PARAM_LONG_OR_NULL(length, length_is_null)
- ZEND_PARSE_PARAMETERS_END();
- if (needle_len == 0) {
- zend_argument_value_error(2, "cannot be empty");
- RETURN_THROWS();
- }
- p = haystack;
- endp = p + haystack_len;
- if (offset < 0) {
- offset += (zend_long)haystack_len;
- }
- if ((offset < 0) || ((size_t)offset > haystack_len)) {
- zend_argument_value_error(3, "must be contained in argument #1 ($haystack)");
- RETURN_THROWS();
- }
- p += offset;
- if (!length_is_null) {
- if (length < 0) {
- length += (haystack_len - offset);
- }
- if (length < 0 || ((size_t)length > (haystack_len - offset))) {
- zend_argument_value_error(4, "must be contained in argument #1 ($haystack)");
- RETURN_THROWS();
- }
- endp = p + length;
- }
- if (needle_len == 1) {
- cmp = needle[0];
- while ((p = memchr(p, cmp, endp - p))) {
- count++;
- p++;
- }
- } else {
- while ((p = (char*)php_memnstr(p, needle, needle_len, endp))) {
- p += needle_len;
- count++;
- }
- }
- RETURN_LONG(count);
- }
- PHP_FUNCTION(str_pad)
- {
-
- zend_string *input;
- zend_long pad_length;
-
- size_t num_pad_chars;
- char *pad_str = " ";
- size_t pad_str_len = 1;
- zend_long pad_type_val = STR_PAD_RIGHT;
- size_t i, left_pad=0, right_pad=0;
- zend_string *result = NULL;
- ZEND_PARSE_PARAMETERS_START(2, 4)
- Z_PARAM_STR(input)
- Z_PARAM_LONG(pad_length)
- Z_PARAM_OPTIONAL
- Z_PARAM_STRING(pad_str, pad_str_len)
- Z_PARAM_LONG(pad_type_val)
- ZEND_PARSE_PARAMETERS_END();
-
- if (pad_length < 0 || (size_t)pad_length <= ZSTR_LEN(input)) {
- RETURN_STR_COPY(input);
- }
- if (pad_str_len == 0) {
- zend_argument_value_error(3, "must be a non-empty string");
- RETURN_THROWS();
- }
- if (pad_type_val < STR_PAD_LEFT || pad_type_val > STR_PAD_BOTH) {
- zend_argument_value_error(4, "must be STR_PAD_LEFT, STR_PAD_RIGHT, or STR_PAD_BOTH");
- RETURN_THROWS();
- }
- num_pad_chars = pad_length - ZSTR_LEN(input);
- result = zend_string_safe_alloc(1, ZSTR_LEN(input), num_pad_chars, 0);
- ZSTR_LEN(result) = 0;
-
- switch (pad_type_val) {
- case STR_PAD_RIGHT:
- left_pad = 0;
- right_pad = num_pad_chars;
- break;
- case STR_PAD_LEFT:
- left_pad = num_pad_chars;
- right_pad = 0;
- break;
- case STR_PAD_BOTH:
- left_pad = num_pad_chars / 2;
- right_pad = num_pad_chars - left_pad;
- break;
- }
-
- for (i = 0; i < left_pad; i++)
- ZSTR_VAL(result)[ZSTR_LEN(result)++] = pad_str[i % pad_str_len];
-
- memcpy(ZSTR_VAL(result) + ZSTR_LEN(result), ZSTR_VAL(input), ZSTR_LEN(input));
- ZSTR_LEN(result) += ZSTR_LEN(input);
-
- for (i = 0; i < right_pad; i++)
- ZSTR_VAL(result)[ZSTR_LEN(result)++] = pad_str[i % pad_str_len];
- ZSTR_VAL(result)[ZSTR_LEN(result)] = '\0';
- RETURN_NEW_STR(result);
- }
- PHP_FUNCTION(sscanf)
- {
- zval *args = NULL;
- char *str, *format;
- size_t str_len, format_len;
- int result, num_args = 0;
- ZEND_PARSE_PARAMETERS_START(2, -1)
- Z_PARAM_STRING(str, str_len)
- Z_PARAM_STRING(format, format_len)
- Z_PARAM_VARIADIC('*', args, num_args)
- ZEND_PARSE_PARAMETERS_END();
- result = php_sscanf_internal(str, format, num_args, args, 0, return_value);
- if (SCAN_ERROR_WRONG_PARAM_COUNT == result) {
- WRONG_PARAM_COUNT;
- }
- }
- #ifdef __SSE2__
- #include <emmintrin.h>
- #endif
- static zend_string *php_str_rot13(zend_string *str)
- {
- zend_string *ret;
- const char *p, *e;
- char *target;
- if (UNEXPECTED(ZSTR_LEN(str) == 0)) {
- return ZSTR_EMPTY_ALLOC();
- }
- ret = zend_string_alloc(ZSTR_LEN(str), 0);
- p = ZSTR_VAL(str);
- e = p + ZSTR_LEN(str);
- target = ZSTR_VAL(ret);
- #ifdef __SSE2__
- if (e - p > 15) {
- const __m128i a_minus_1 = _mm_set1_epi8('a' - 1);
- const __m128i m_plus_1 = _mm_set1_epi8('m' + 1);
- const __m128i n_minus_1 = _mm_set1_epi8('n' - 1);
- const __m128i z_plus_1 = _mm_set1_epi8('z' + 1);
- const __m128i A_minus_1 = _mm_set1_epi8('A' - 1);
- const __m128i M_plus_1 = _mm_set1_epi8('M' + 1);
- const __m128i N_minus_1 = _mm_set1_epi8('N' - 1);
- const __m128i Z_plus_1 = _mm_set1_epi8('Z' + 1);
- const __m128i add = _mm_set1_epi8(13);
- const __m128i sub = _mm_set1_epi8(-13);
- do {
- __m128i in, gt, lt, cmp, delta;
- delta = _mm_setzero_si128();
- in = _mm_loadu_si128((__m128i *)p);
- gt = _mm_cmpgt_epi8(in, a_minus_1);
- lt = _mm_cmplt_epi8(in, m_plus_1);
- cmp = _mm_and_si128(lt, gt);
- if (_mm_movemask_epi8(cmp)) {
- cmp = _mm_and_si128(cmp, add);
- delta = _mm_or_si128(delta, cmp);
- }
- gt = _mm_cmpgt_epi8(in, n_minus_1);
- lt = _mm_cmplt_epi8(in, z_plus_1);
- cmp = _mm_and_si128(lt, gt);
- if (_mm_movemask_epi8(cmp)) {
- cmp = _mm_and_si128(cmp, sub);
- delta = _mm_or_si128(delta, cmp);
- }
- gt = _mm_cmpgt_epi8(in, A_minus_1);
- lt = _mm_cmplt_epi8(in, M_plus_1);
- cmp = _mm_and_si128(lt, gt);
- if (_mm_movemask_epi8(cmp)) {
- cmp = _mm_and_si128(cmp, add);
- delta = _mm_or_si128(delta, cmp);
- }
- gt = _mm_cmpgt_epi8(in, N_minus_1);
- lt = _mm_cmplt_epi8(in, Z_plus_1);
- cmp = _mm_and_si128(lt, gt);
- if (_mm_movemask_epi8(cmp)) {
- cmp = _mm_and_si128(cmp, sub);
- delta = _mm_or_si128(delta, cmp);
- }
- in = _mm_add_epi8(in, delta);
- _mm_storeu_si128((__m128i *)target, in);
- p += 16;
- target += 16;
- } while (e - p > 15);
- }
- #endif
- while (p < e) {
- if (*p >= 'a' && *p <= 'z') {
- *target++ = 'a' + (((*p++ - 'a') + 13) % 26);
- } else if (*p >= 'A' && *p <= 'Z') {
- *target++ = 'A' + (((*p++ - 'A') + 13) % 26);
- } else {
- *target++ = *p++;
- }
- }
- *target = '\0';
- return ret;
- }
- PHP_FUNCTION(str_rot13)
- {
- zend_string *arg;
- ZEND_PARSE_PARAMETERS_START(1, 1)
- Z_PARAM_STR(arg)
- ZEND_PARSE_PARAMETERS_END();
- RETURN_STR(php_str_rot13(arg));
- }
- static void php_string_shuffle(char *str, zend_long len)
- {
- zend_long n_elems, rnd_idx, n_left;
- char temp;
-
-
- n_elems = len;
- if (n_elems <= 1) {
- return;
- }
- n_left = n_elems;
- while (--n_left) {
- rnd_idx = php_mt_rand_range(0, n_left);
- if (rnd_idx != n_left) {
- temp = str[n_left];
- str[n_left] = str[rnd_idx];
- str[rnd_idx] = temp;
- }
- }
- }
- PHP_FUNCTION(str_shuffle)
- {
- zend_string *arg;
- ZEND_PARSE_PARAMETERS_START(1, 1)
- Z_PARAM_STR(arg)
- ZEND_PARSE_PARAMETERS_END();
- RETVAL_STRINGL(ZSTR_VAL(arg), ZSTR_LEN(arg));
- if (Z_STRLEN_P(return_value) > 1) {
- php_string_shuffle(Z_STRVAL_P(return_value), (zend_long) Z_STRLEN_P(return_value));
- }
- }
- PHP_FUNCTION(str_word_count)
- {
- zend_string *str;
- char *char_list = NULL, ch[256];
- const char *p, *e, *s;
- size_t char_list_len = 0, word_count = 0;
- zend_long type = 0;
- ZEND_PARSE_PARAMETERS_START(1, 3)
- Z_PARAM_STR(str)
- Z_PARAM_OPTIONAL
- Z_PARAM_LONG(type)
- Z_PARAM_STRING_OR_NULL(char_list, char_list_len)
- ZEND_PARSE_PARAMETERS_END();
- switch(type) {
- case 1:
- case 2:
- array_init(return_value);
- if (!ZSTR_LEN(str)) {
- return;
- }
- break;
- case 0:
- if (!ZSTR_LEN(str)) {
- RETURN_LONG(0);
- }
-
- break;
- default:
- zend_argument_value_error(2, "must be a valid format value");
- RETURN_THROWS();
- }
- if (char_list) {
- php_charmask((const unsigned char *) char_list, char_list_len, ch);
- }
- p = ZSTR_VAL(str);
- e = ZSTR_VAL(str) + ZSTR_LEN(str);
-
- if ((*p == '\'' && (!char_list || !ch['\''])) || (*p == '-' && (!char_list || !ch['-']))) {
- p++;
- }
-
- if (*(e - 1) == '-' && (!char_list || !ch['-'])) {
- e--;
- }
- while (p < e) {
- s = p;
- while (p < e && (isalpha((unsigned char)*p) || (char_list && ch[(unsigned char)*p]) || *p == '\'' || *p == '-')) {
- p++;
- }
- if (p > s) {
- switch (type)
- {
- case 1:
- add_next_index_stringl(return_value, s, p - s);
- break;
- case 2:
- add_index_stringl(return_value, (s - ZSTR_VAL(str)), s, p - s);
- break;
- default:
- word_count++;
- break;
- }
- }
- p++;
- }
- if (!type) {
- RETURN_LONG(word_count);
- }
- }
- PHP_FUNCTION(str_split)
- {
- zend_string *str;
- zend_long split_length = 1;
- const char *p;
- size_t n_reg_segments;
- ZEND_PARSE_PARAMETERS_START(1, 2)
- Z_PARAM_STR(str)
- Z_PARAM_OPTIONAL
- Z_PARAM_LONG(split_length)
- ZEND_PARSE_PARAMETERS_END();
- if (split_length <= 0) {
- zend_argument_value_error(2, "must be greater than 0");
- RETURN_THROWS();
- }
- if (0 == ZSTR_LEN(str) || (size_t)split_length >= ZSTR_LEN(str)) {
- array_init_size(return_value, 1);
- add_next_index_stringl(return_value, ZSTR_VAL(str), ZSTR_LEN(str));
- return;
- }
- array_init_size(return_value, (uint32_t)(((ZSTR_LEN(str) - 1) / split_length) + 1));
- n_reg_segments = ZSTR_LEN(str) / split_length;
- p = ZSTR_VAL(str);
- while (n_reg_segments-- > 0) {
- add_next_index_stringl(return_value, p, split_length);
- p += split_length;
- }
- if (p != (ZSTR_VAL(str) + ZSTR_LEN(str))) {
- add_next_index_stringl(return_value, p, (ZSTR_VAL(str) + ZSTR_LEN(str) - p));
- }
- }
- PHP_FUNCTION(strpbrk)
- {
- zend_string *haystack, *char_list;
- const char *haystack_ptr, *cl_ptr;
- ZEND_PARSE_PARAMETERS_START(2, 2)
- Z_PARAM_STR(haystack)
- Z_PARAM_STR(char_list)
- ZEND_PARSE_PARAMETERS_END();
- if (!ZSTR_LEN(char_list)) {
- zend_argument_value_error(2, "must be a non-empty string");
- RETURN_THROWS();
- }
- for (haystack_ptr = ZSTR_VAL(haystack); haystack_ptr < (ZSTR_VAL(haystack) + ZSTR_LEN(haystack)); ++haystack_ptr) {
- for (cl_ptr = ZSTR_VAL(char_list); cl_ptr < (ZSTR_VAL(char_list) + ZSTR_LEN(char_list)); ++cl_ptr) {
- if (*cl_ptr == *haystack_ptr) {
- RETURN_STRINGL(haystack_ptr, (ZSTR_VAL(haystack) + ZSTR_LEN(haystack) - haystack_ptr));
- }
- }
- }
- RETURN_FALSE;
- }
- PHP_FUNCTION(substr_compare)
- {
- zend_string *s1, *s2;
- zend_long offset, len=0;
- bool len_is_default=1;
- bool cs=0;
- size_t cmp_len;
- ZEND_PARSE_PARAMETERS_START(3, 5)
- Z_PARAM_STR(s1)
- Z_PARAM_STR(s2)
- Z_PARAM_LONG(offset)
- Z_PARAM_OPTIONAL
- Z_PARAM_LONG_OR_NULL(len, len_is_default)
- Z_PARAM_BOOL(cs)
- ZEND_PARSE_PARAMETERS_END();
- if (!len_is_default && len <= 0) {
- if (len == 0) {
- RETURN_LONG(0L);
- } else {
- zend_argument_value_error(4, "must be greater than or equal to 0");
- RETURN_THROWS();
- }
- }
- if (offset < 0) {
- offset = ZSTR_LEN(s1) + offset;
- offset = (offset < 0) ? 0 : offset;
- }
- if ((size_t)offset > ZSTR_LEN(s1)) {
- zend_argument_value_error(3, "must be contained in argument #1 ($main_str)");
- RETURN_THROWS();
- }
- cmp_len = len ? (size_t)len : MAX(ZSTR_LEN(s2), (ZSTR_LEN(s1) - offset));
- if (!cs) {
- RETURN_LONG(zend_binary_strncmp(ZSTR_VAL(s1) + offset, (ZSTR_LEN(s1) - offset), ZSTR_VAL(s2), ZSTR_LEN(s2), cmp_len));
- } else {
- RETURN_LONG(zend_binary_strncasecmp_l(ZSTR_VAL(s1) + offset, (ZSTR_LEN(s1) - offset), ZSTR_VAL(s2), ZSTR_LEN(s2), cmp_len));
- }
- }
- static zend_string *php_utf8_encode(const char *s, size_t len)
- {
- size_t pos = len;
- zend_string *str;
- unsigned char c;
- str = zend_string_safe_alloc(len, 2, 0, 0);
- ZSTR_LEN(str) = 0;
- while (pos > 0) {
-
- c = (unsigned char)(*s);
- if (c < 0x80) {
- ZSTR_VAL(str)[ZSTR_LEN(str)++] = (char) c;
-
- } else {
- ZSTR_VAL(str)[ZSTR_LEN(str)++] = (0xc0 | (c >> 6));
- ZSTR_VAL(str)[ZSTR_LEN(str)++] = (0x80 | (c & 0x3f));
- }
- pos--;
- s++;
- }
- ZSTR_VAL(str)[ZSTR_LEN(str)] = '\0';
- str = zend_string_truncate(str, ZSTR_LEN(str), 0);
- return str;
- }
- static zend_string *php_utf8_decode(const char *s, size_t len)
- {
- size_t pos = 0;
- unsigned int c;
- zend_string *str;
- str = zend_string_alloc(len, 0);
- ZSTR_LEN(str) = 0;
- while (pos < len) {
- int status = FAILURE;
- c = php_next_utf8_char((const unsigned char*)s, (size_t) len, &pos, &status);
-
- if (status == FAILURE || c > 0xFFU) {
- c = '?';
- }
- ZSTR_VAL(str)[ZSTR_LEN(str)++] = c;
- }
- ZSTR_VAL(str)[ZSTR_LEN(str)] = '\0';
- if (ZSTR_LEN(str) < len) {
- str = zend_string_truncate(str, ZSTR_LEN(str), 0);
- }
- return str;
- }
- PHP_FUNCTION(utf8_encode)
- {
- char *arg;
- size_t arg_len;
- ZEND_PARSE_PARAMETERS_START(1, 1)
- Z_PARAM_STRING(arg, arg_len)
- ZEND_PARSE_PARAMETERS_END();
- RETURN_STR(php_utf8_encode(arg, arg_len));
- }
- PHP_FUNCTION(utf8_decode)
- {
- char *arg;
- size_t arg_len;
- ZEND_PARSE_PARAMETERS_START(1, 1)
- Z_PARAM_STRING(arg, arg_len)
- ZEND_PARSE_PARAMETERS_END();
- RETURN_STR(php_utf8_decode(arg, arg_len));
- }
|