123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507 |
- diff -u libmagic.orig/apprentice.c libmagic/apprentice.c
- --- libmagic.orig/apprentice.c 2021-02-23 01:51:11.000000000 +0100
- +++ libmagic/apprentice.c 2022-06-16 13:39:41.570984700 +0200
- @@ -29,6 +29,8 @@
- * apprentice - make one pass through /etc/magic, learning its secrets.
- */
-
- +#include "php.h"
- +
- #include "file.h"
-
- #ifndef lint
- @@ -37,19 +39,33 @@
-
- #include "magic.h"
- #include <stdlib.h>
- +
- +#if defined(__hpux) && !defined(HAVE_STRTOULL)
- +#if SIZEOF_LONG == 8
- +# define strtoull strtoul
- +#else
- +# define strtoull __strtoull
- +#endif
- +#endif
- +
- +#ifdef PHP_WIN32
- +#include "win32/unistd.h"
- +#define strtoull _strtoui64
- +#else
- #ifdef HAVE_UNISTD_H
- #include <unistd.h>
- #endif
- -#include <stddef.h>
- +#endif
- #include <string.h>
- #include <assert.h>
- #include <ctype.h>
- #include <fcntl.h>
- -#ifdef QUICK
- -#include <sys/mman.h>
- +
- +#ifndef SSIZE_MAX
- +#define MAXMAGIC_SIZE ((ssize_t)0x7fffffff)
- +#else
- +#define MAXMAGIC_SIZE SSIZE_MAX
- #endif
- -#include <dirent.h>
- -#include <limits.h>
-
-
- #define EATAB {while (isascii(CAST(unsigned char, *l)) && \
- @@ -66,6 +82,10 @@
- #endif
- #endif
-
- +#ifndef offsetof
- +#define offsetof(STRUCTURE,FIELD) ((int)((char*)&((STRUCTURE*)0)->FIELD))
- +#endif
- +
- #ifndef MAP_FAILED
- #define MAP_FAILED (void *) -1
- #endif
- @@ -128,10 +148,7 @@
- private uint32_t swap4(uint32_t);
- private uint64_t swap8(uint64_t);
- private char *mkdbname(struct magic_set *, const char *, int);
- -private struct magic_map *apprentice_buf(struct magic_set *, struct magic *,
- - size_t);
- private struct magic_map *apprentice_map(struct magic_set *, const char *);
- -private int check_buffer(struct magic_set *, struct magic_map *, const char *);
- private void apprentice_unmap(struct magic_map *);
- private int apprentice_compile(struct magic_set *, struct magic_map *,
- const char *);
- @@ -167,38 +184,7 @@
- { NULL, 0, NULL }
- };
-
- -#ifdef COMPILE_ONLY
- -
- -int main(int, char *[]);
- -
- -int
- -main(int argc, char *argv[])
- -{
- - int ret;
- - struct magic_set *ms;
- - char *progname;
- -
- - if ((progname = strrchr(argv[0], '/')) != NULL)
- - progname++;
- - else
- - progname = argv[0];
- -
- - if (argc != 2) {
- - (void)fprintf(stderr, "Usage: %s file\n", progname);
- - return 1;
- - }
- -
- - if ((ms = magic_open(MAGIC_CHECK)) == NULL) {
- - (void)fprintf(stderr, "%s: %s\n", progname, strerror(errno));
- - return 1;
- - }
- - ret = magic_compile(ms, argv[1]) == -1 ? 1 : 0;
- - if (ret == 1)
- - (void)fprintf(stderr, "%s: %s\n", progname, magic_error(ms));
- - magic_close(ms);
- - return ret;
- -}
- -#endif /* COMPILE_ONLY */
- +#include "../data_file.c"
-
- struct type_tbl_s {
- const char name[16];
- @@ -417,7 +403,7 @@
- struct mlist *ml;
-
- mlp->map = NULL;
- - if ((ml = CAST(struct mlist *, malloc(sizeof(*ml)))) == NULL)
- + if ((ml = CAST(struct mlist *, emalloc(sizeof(*ml)))) == NULL)
- return -1;
-
- ml->map = idx == 0 ? map : NULL;
- @@ -502,10 +488,16 @@
- return;
- for (i = 0; i < MAGIC_SETS; i++)
- mlist_free(ms->mlist[i]);
- - free(ms->o.pbuf);
- - free(ms->o.buf);
- - free(ms->c.li);
- - free(ms);
- + if (ms->o.pbuf) {
- + efree(ms->o.pbuf);
- + }
- + if (ms->o.buf) {
- + efree(ms->o.buf);
- + }
- + if (ms->c.li) {
- + efree(ms->c.li);
- + }
- + efree(ms);
- }
-
- protected struct magic_set *
- @@ -514,7 +506,7 @@
- struct magic_set *ms;
- size_t i, len;
-
- - if ((ms = CAST(struct magic_set *, calloc(CAST(size_t, 1u),
- + if ((ms = CAST(struct magic_set *, ecalloc(CAST(size_t, 1u),
- sizeof(struct magic_set)))) == NULL)
- return NULL;
-
- @@ -527,7 +519,7 @@
- ms->o.blen = 0;
- len = (ms->c.len = 10) * sizeof(*ms->c.li);
-
- - if ((ms->c.li = CAST(struct level_info *, malloc(len))) == NULL)
- + if ((ms->c.li = CAST(struct level_info *, emalloc(len))) == NULL)
- goto free;
-
- ms->event_flags = 0;
- @@ -546,48 +538,35 @@
- ms->encoding_max = FILE_ENCODING_MAX;
- return ms;
- free:
- - free(ms);
- + efree(ms);
- return NULL;
- }
-
- private void
- apprentice_unmap(struct magic_map *map)
- {
- - size_t i;
- if (map == NULL)
- return;
- -
- - switch (map->type) {
- - case MAP_TYPE_USER:
- - break;
- - case MAP_TYPE_MALLOC:
- - for (i = 0; i < MAGIC_SETS; i++) {
- - void *b = map->magic[i];
- - void *p = map->p;
- - if (CAST(char *, b) >= CAST(char *, p) &&
- - CAST(char *, b) <= CAST(char *, p) + map->len)
- - continue;
- - free(map->magic[i]);
- + if (map->p != php_magic_database) {
- + if (map->p == NULL) {
- + int j;
- + for (j = 0; j < MAGIC_SETS; j++) {
- + if (map->magic[j]) {
- + efree(map->magic[j]);
- + }
- + }
- + } else {
- + efree(map->p);
- }
- - free(map->p);
- - break;
- -#ifdef QUICK
- - case MAP_TYPE_MMAP:
- - if (map->p && map->p != MAP_FAILED)
- - (void)munmap(map->p, map->len);
- - break;
- -#endif
- - default:
- - abort();
- }
- - free(map);
- + efree(map);
- }
-
- private struct mlist *
- mlist_alloc(void)
- {
- struct mlist *mlist;
- - if ((mlist = CAST(struct mlist *, calloc(1, sizeof(*mlist)))) == NULL) {
- + if ((mlist = CAST(struct mlist *, ecalloc(1, sizeof(*mlist)))) == NULL) {
- return NULL;
- }
- mlist->next = mlist->prev = mlist;
- @@ -610,7 +589,7 @@
- {
- if (ml->map)
- apprentice_unmap(CAST(struct magic_map *, ml->map));
- - free(ml);
- + efree(ml);
- }
-
- private void
- @@ -629,51 +608,6 @@
- mlist_free_one(mlist);
- }
-
- -#ifndef COMPILE_ONLY
- -/* void **bufs: an array of compiled magic files */
- -protected int
- -buffer_apprentice(struct magic_set *ms, struct magic **bufs,
- - size_t *sizes, size_t nbufs)
- -{
- - size_t i, j;
- - struct mlist *ml;
- - struct magic_map *map;
- -
- - if (nbufs == 0)
- - return -1;
- -
- - (void)file_reset(ms, 0);
- -
- - init_file_tables();
- -
- - for (i = 0; i < MAGIC_SETS; i++) {
- - mlist_free(ms->mlist[i]);
- - if ((ms->mlist[i] = mlist_alloc()) == NULL) {
- - file_oomem(ms, sizeof(*ms->mlist[i]));
- - goto fail;
- - }
- - }
- -
- - for (i = 0; i < nbufs; i++) {
- - map = apprentice_buf(ms, bufs[i], sizes[i]);
- - if (map == NULL)
- - goto fail;
- -
- - for (j = 0; j < MAGIC_SETS; j++) {
- - if (add_mlist(ms->mlist[j], map, j) == -1) {
- - file_oomem(ms, sizeof(*ml));
- - goto fail;
- - }
- - }
- - }
- -
- - return 0;
- -fail:
- - mlist_free_all(ms);
- - return -1;
- -}
- -#endif
- -
- /* const char *fn: list of magic files and directories */
- protected int
- file_apprentice(struct magic_set *ms, const char *fn, int action)
- @@ -684,12 +618,28 @@
-
- (void)file_reset(ms, 0);
-
- +/* XXX disabling default magic loading so the compiled in data is used */
- +#if 0
- if ((fn = magic_getpath(fn, action)) == NULL)
- return -1;
- +#endif
-
- init_file_tables();
-
- - if ((mfn = strdup(fn)) == NULL) {
- + if (fn == NULL)
- + fn = getenv("MAGIC");
- + if (fn == NULL) {
- + for (i = 0; i < MAGIC_SETS; i++) {
- + mlist_free(ms->mlist[i]);
- + if ((ms->mlist[i] = mlist_alloc()) == NULL) {
- + file_oomem(ms, sizeof(*ms->mlist[i]));
- + return -1;
- + }
- + }
- + return apprentice_1(ms, fn, action);
- + }
- +
- + if ((mfn = estrdup(fn)) == NULL) {
- file_oomem(ms, strlen(fn));
- return -1;
- }
- @@ -702,7 +652,7 @@
- mlist_free(ms->mlist[j]);
- ms->mlist[j] = NULL;
- }
- - free(mfn);
- + efree(mfn);
- return -1;
- }
- }
- @@ -719,7 +669,7 @@
- fn = p;
- }
-
- - free(mfn);
- + efree(mfn);
-
- if (errs == -1) {
- for (i = 0; i < MAGIC_SETS; i++) {
- @@ -1159,7 +1109,7 @@
-
- mset[i].max += ALLOC_INCR;
- if ((mp = CAST(struct magic_entry *,
- - realloc(mset[i].me, sizeof(*mp) * mset[i].max))) ==
- + erealloc(mset[i].me, sizeof(*mp) * mset[i].max))) ==
- NULL) {
- file_oomem(ms, sizeof(*mp) * mset[i].max);
- return -1;
- @@ -1180,13 +1130,19 @@
- load_1(struct magic_set *ms, int action, const char *fn, int *errs,
- struct magic_entry_set *mset)
- {
- - size_t lineno = 0, llen = 0;
- + char buffer[BUFSIZ + 1];
- char *line = NULL;
- - ssize_t len;
- + size_t len;
- + size_t lineno = 0;
- struct magic_entry me;
-
- - FILE *f = fopen(ms->file = fn, "r");
- - if (f == NULL) {
- + php_stream *stream;
- +
- +
- + ms->file = fn;
- + stream = php_stream_open_wrapper((char *)fn, "rb", REPORT_ERRORS, NULL);
- +
- + if (stream == NULL) {
- if (errno != ENOENT)
- file_error(ms, errno, "cannot read magic file `%s'",
- fn);
- @@ -1196,8 +1152,7 @@
-
- memset(&me, 0, sizeof(me));
- /* read and parse this file */
- - for (ms->line = 1; (len = getline(&line, &llen, f)) != -1;
- - ms->line++) {
- + for (ms->line = 1; (line = php_stream_get_line(stream, buffer , BUFSIZ, &len)) != NULL; ms->line++) {
- if (len == 0) /* null line, garbage, etc */
- continue;
- if (line[len - 1] == '\n') {
- @@ -1256,8 +1211,8 @@
- }
- if (me.mp)
- (void)addentry(ms, &me, mset);
- - free(line);
- - (void)fclose(f);
- + efree(line);
- + php_stream_close(stream);
- }
-
- /*
- @@ -1336,7 +1291,7 @@
- mentrycount += me[i].cont_count;
-
- slen = sizeof(**ma) * mentrycount;
- - if ((*ma = CAST(struct magic *, malloc(slen))) == NULL) {
- + if ((*ma = CAST(struct magic *, emalloc(slen))) == NULL) {
- file_oomem(ms, slen);
- return -1;
- }
- @@ -1358,8 +1313,8 @@
- if (me == NULL)
- return;
- for (i = 0; i < nme; i++)
- - free(me[i].mp);
- - free(me);
- + efree(me[i].mp);
- + efree(me);
- }
-
- private struct magic_map *
- @@ -1368,18 +1323,19 @@
- int errs = 0;
- uint32_t i, j;
- size_t files = 0, maxfiles = 0;
- - char **filearr = NULL, *mfn;
- - struct stat st;
- + char **filearr = NULL;
- + zend_stat_t st;
- struct magic_map *map;
- struct magic_entry_set mset[MAGIC_SETS];
- - DIR *dir;
- - struct dirent *d;
- + php_stream *dir;
- + php_stream_dirent d;
- +
-
- memset(mset, 0, sizeof(mset));
- ms->flags |= MAGIC_CHECK; /* Enable checks for parsed files */
-
-
- - if ((map = CAST(struct magic_map *, calloc(1, sizeof(*map)))) == NULL)
- + if ((map = CAST(struct magic_map *, ecalloc(1, sizeof(*map)))) == NULL)
- {
- file_oomem(ms, sizeof(*map));
- return NULL;
- @@ -1391,52 +1347,50 @@
- (void)fprintf(stderr, "%s\n", usg_hdr);
-
- /* load directory or file */
- - if (stat(fn, &st) == 0 && S_ISDIR(st.st_mode)) {
- - dir = opendir(fn);
- + /* FIXME: Read file names and sort them to prevent
- + non-determinism. See Debian bug #488562. */
- + if (php_sys_stat(fn, &st) == 0 && S_ISDIR(st.st_mode)) {
- + int mflen;
- + char mfn[MAXPATHLEN];
- +
- + dir = php_stream_opendir((char *)fn, REPORT_ERRORS, NULL);
- if (!dir) {
- errs++;
- goto out;
- }
- - while ((d = readdir(dir)) != NULL) {
- - if (d->d_name[0] == '.')
- - continue;
- - if (asprintf(&mfn, "%s/%s", fn, d->d_name) < 0) {
- + while (php_stream_readdir(dir, &d)) {
- + if ((mflen = snprintf(mfn, sizeof(mfn), "%s/%s", fn, d.d_name)) < 0) {
- file_oomem(ms,
- - strlen(fn) + strlen(d->d_name) + 2);
- + strlen(fn) + strlen(d.d_name) + 2);
- errs++;
- - closedir(dir);
- + php_stream_closedir(dir);
- goto out;
- }
- - if (stat(mfn, &st) == -1 || !S_ISREG(st.st_mode)) {
- - free(mfn);
- + if (zend_stat(mfn, &st) == -1 || !S_ISREG(st.st_mode)) {
- continue;
- }
- if (files >= maxfiles) {
- size_t mlen;
- - char **nfilearr;
- maxfiles = (maxfiles + 1) * 2;
- mlen = maxfiles * sizeof(*filearr);
- - if ((nfilearr = CAST(char **,
- - realloc(filearr, mlen))) == NULL) {
- + if ((filearr = CAST(char **,
- + erealloc(filearr, mlen))) == NULL) {
- file_oomem(ms, mlen);
- - free(mfn);
- - closedir(dir);
- + php_stream_closedir(dir);
- errs++;
- goto out;
- }
- - filearr = nfilearr;
- }
- - filearr[files++] = mfn;
- + filearr[files++] = estrndup(mfn, (mflen > sizeof(mfn) - 1)? sizeof(mfn) - 1: mflen);
- }
- - closedir(dir);
- + php_stream_closedir(dir);
- if (filearr) {
- qsort(filearr, files, sizeof(*filearr), cmpstrp);
- for (i = 0; i < files; i++) {
- load_1(ms, action, filearr[i], &errs, mset);
- - free(filearr[i]);
- + efree(filearr[i]);
- }
- - free(filearr);
- - filearr = NULL;
- + efree(filearr);
- }
- } else
- load_1(ms, action, fn, &errs, mset);
- @@ -1474,7 +1428,6 @@
- }
-
- out:
- - free(filearr);
- for (j = 0; j < MAGIC_SETS; j++)
- magic_entry_free(mset[j].me, mset[j].count);
-
- @@ -1910,7 +1863,7 @@
- if (me->cont_count == me->max_count) {
- struct magic *nm;
- size_t cnt = me->max_count + ALLOC_CHUNK;
- - if ((nm = CAST(struct magic *, realloc(me->mp,
- + if ((nm = CAST(struct magic *, erealloc(me->mp,
- sizeof(*nm) * cnt))) == NULL) {
- file_oomem(ms, sizeof(*nm) * cnt);
- return -1;
- @@ -1925,7 +1878,7 @@
- static const size_t len = sizeof(*m) * ALLOC_CHUNK;
- if (me->mp != NULL)
- return 1;
- - if ((m = CAST(struct magic *, malloc(len))) == NULL) {
- + if ((m = CAST(struct magic *, emalloc(len))) == NULL) {
- file_oomem(ms, len);
- return -1;
- }
- @@ -2148,7 +2101,7 @@
-
- m->mask_op = 0;
- if (*l == '~') {
- - if (!IS_STRING(m->type))
- + if (!IS_LIBMAGIC_STRING(m->type))
- m->mask_op |= FILE_OPINVERSE;
- else if (ms->flags & MAGIC_CHECK)
- file_magwarn(ms, "'~' invalid for string types");
- @@ -2157,7 +2110,7 @@
- m->str_range = 0;
- m->str_flags = m->type == FILE_PSTRING ? PSTRING_1_LE : 0;
- if ((op = get_op(*l)) != -1) {
- - if (IS_STRING(m->type)) {
- + if (IS_LIBMAGIC_STRING(m->type)) {
- int r;
-
- if (op != FILE_OPDIVIDE) {
- @@ -2277,7 +2230,7 @@
- */
- private int
- parse_strength(struct magic_set *ms, struct magic_entry *me, const char *line,
- - size_t len __attribute__((__unused__)))
- + size_t len)
- {
- const char *l = line;
- char *el;
- @@ -2339,8 +2292,7 @@
-
- private int
- parse_extra(struct magic_set *ms, struct magic_entry *me, const char *line,
- - size_t llen, off_t off, size_t len, const char *name, const char *extra,
- - int nt)
- + size_t llen, zend_off_t off, size_t len, const char *name, const char *extra, int nt)
- {
- size_t i;
- const char *l = line;
- @@ -2705,14 +2657,19 @@
- return -1;
- }
- if (m->type == FILE_REGEX) {
- - file_regex_t rx;
- - int rc = file_regcomp(&rx, m->value.s, REG_EXTENDED);
- - if (rc) {
- - if (ms->flags & MAGIC_CHECK)
- - file_regerror(&rx, rc, ms);
- + zend_string *pattern;
- + int options = 0;
- + pcre_cache_entry *pce;
- +
- + pattern = convert_libmagic_pattern(m->value.s, strlen(m->value.s), options);
- +
- + if ((pce = pcre_get_compiled_regex_cache(pattern)) == NULL) {
- + zend_string_release(pattern);
- + return -1;
- }
- - file_regfree(&rx);
- - return rc ? -1 : 0;
- + zend_string_release(pattern);
- +
- + return 0;
- }
- return 0;
- default:
- @@ -3068,120 +3025,83 @@
- }
-
- /*
- - * handle a buffer containing a compiled file.
- - */
- -private struct magic_map *
- -apprentice_buf(struct magic_set *ms, struct magic *buf, size_t len)
- -{
- - struct magic_map *map;
- -
- - if ((map = CAST(struct magic_map *, calloc(1, sizeof(*map)))) == NULL) {
- - file_oomem(ms, sizeof(*map));
- - return NULL;
- - }
- - map->len = len;
- - map->p = buf;
- - map->type = MAP_TYPE_USER;
- - if (check_buffer(ms, map, "buffer") != 0) {
- - apprentice_unmap(map);
- - return NULL;
- - }
- - return map;
- -}
- -
- -/*
- * handle a compiled file.
- */
-
- private struct magic_map *
- apprentice_map(struct magic_set *ms, const char *fn)
- {
- - int fd;
- - struct stat st;
- + uint32_t *ptr;
- + uint32_t version, entries = 0, nentries;
- + int needsbyteswap;
- char *dbname = NULL;
- struct magic_map *map;
- - struct magic_map *rv = NULL;
- + size_t i;
- + php_stream *stream = NULL;
- + php_stream_statbuf st;
- +
- +
-
- - fd = -1;
- - if ((map = CAST(struct magic_map *, calloc(1, sizeof(*map)))) == NULL) {
- + if ((map = CAST(struct magic_map *, ecalloc(1, sizeof(*map)))) == NULL) {
- file_oomem(ms, sizeof(*map));
- - goto error;
- + return NULL;
- }
- - map->type = MAP_TYPE_USER; /* unspecified */
- +
- + if (fn == NULL) {
- + map->p = (void *)&php_magic_database;
- + goto internal_loaded;
- + }
- +
- +#ifdef PHP_WIN32
- + /* Don't bother on windows with php_stream_open_wrapper,
- + return to give apprentice_load() a chance. */
- + if (php_stream_stat_path_ex((char *)fn, 0, &st, NULL) == SUCCESS) {
- + if (st.sb.st_mode & S_IFDIR) {
- + goto error;
- + }
- + }
- +#endif
-
- dbname = mkdbname(ms, fn, 0);
- if (dbname == NULL)
- goto error;
-
- - if ((fd = open(dbname, O_RDONLY|O_BINARY)) == -1)
- + stream = php_stream_open_wrapper((char *)fn, "rb", REPORT_ERRORS, NULL);
- +
- + if (!stream) {
- goto error;
- + }
-
- - if (fstat(fd, &st) == -1) {
- +#ifndef PHP_WIN32
- + if (php_stream_stat(stream, &st) < 0) {
- file_error(ms, errno, "cannot stat `%s'", dbname);
- goto error;
- }
- - if (st.st_size < 8 || st.st_size > maxoff_t()) {
- +#endif
- + if (st.sb.st_size < 8 || st.sb.st_size > maxoff_t()) {
- file_error(ms, 0, "file `%s' is too %s", dbname,
- - st.st_size < 8 ? "small" : "large");
- + st.sb.st_size < 8 ? "small" : "large");
- goto error;
- }
-
- - map->len = CAST(size_t, st.st_size);
- -#ifdef QUICK
- - map->type = MAP_TYPE_MMAP;
- - if ((map->p = mmap(0, CAST(size_t, st.st_size), PROT_READ|PROT_WRITE,
- - MAP_PRIVATE|MAP_FILE, fd, CAST(off_t, 0))) == MAP_FAILED) {
- - file_error(ms, errno, "cannot map `%s'", dbname);
- - goto error;
- - }
- -#else
- map->type = MAP_TYPE_MALLOC;
- - if ((map->p = CAST(void *, malloc(map->len))) == NULL) {
- - file_oomem(ms, map->len);
- - goto error;
- - }
- - if (read(fd, map->p, map->len) != (ssize_t)map->len) {
- - file_badread(ms);
- - goto error;
- - }
- -#endif
- - (void)close(fd);
- - fd = -1;
- + map->len = CAST(size_t, st.sb.st_size);
- + map->p = CAST(void *, emalloc(map->len));
-
- - if (check_buffer(ms, map, dbname) != 0) {
- - goto error;
- - }
- -#ifdef QUICK
- - if (mprotect(map->p, CAST(size_t, st.st_size), PROT_READ) == -1) {
- - file_error(ms, errno, "cannot mprotect `%s'", dbname);
- + if (php_stream_read(stream, map->p, (size_t)st.sb.st_size) != (size_t)st.sb.st_size) {
- + file_badread(ms);
- goto error;
- }
- -#endif
- -
- - free(dbname);
- - return map;
- -
- -error:
- - if (fd != -1)
- - (void)close(fd);
- - apprentice_unmap(map);
- - free(dbname);
- - return rv;
- -}
-
- -private int
- -check_buffer(struct magic_set *ms, struct magic_map *map, const char *dbname)
- -{
- - uint32_t *ptr;
- - uint32_t entries, nentries;
- - uint32_t version;
- - int i, needsbyteswap;
- + php_stream_close(stream);
- + stream = NULL;
-
- - ptr = CAST(uint32_t *, map->p);
- +internal_loaded:
- + ptr = (uint32_t *)(void *)map->p;
- if (*ptr != MAGICNO) {
- if (swap4(*ptr) != MAGICNO) {
- file_error(ms, 0, "bad magic in `%s'", dbname);
- - return -1;
- + goto error;
- }
- needsbyteswap = 1;
- } else
- @@ -3191,17 +3111,29 @@
- else
- version = ptr[1];
- if (version != VERSIONNO) {
- - file_error(ms, 0, "File %s supports only version %d magic "
- - "files. `%s' is version %d", VERSION,
- + file_error(ms, 0, "File %d supports only version %d magic "
- + "files. `%s' is version %d", MAGIC_VERSION,
- VERSIONNO, dbname, version);
- - return -1;
- + goto error;
- }
- - entries = CAST(uint32_t, map->len / sizeof(struct magic));
- - if ((entries * sizeof(struct magic)) != map->len) {
- - file_error(ms, 0, "Size of `%s' %" SIZE_T_FORMAT "u is not "
- - "a multiple of %" SIZE_T_FORMAT "u",
- - dbname, map->len, sizeof(struct magic));
- - return -1;
- +
- + /* php_magic_database is a const, performing writes will segfault. This is for big-endian
- + machines only, PPC and Sparc specifically. Consider static variable or MINIT in
- + future. */
- + if (needsbyteswap && fn == NULL) {
- + map->p = emalloc(sizeof(php_magic_database));
- + map->p = memcpy(map->p, php_magic_database, sizeof(php_magic_database));
- + }
- +
- + if (NULL != fn) {
- + nentries = (uint32_t)(st.sb.st_size / sizeof(struct magic));
- + entries = (uint32_t)(st.sb.st_size / sizeof(struct magic));
- + if ((zend_off_t)(entries * sizeof(struct magic)) != st.sb.st_size) {
- + file_error(ms, 0, "Size of `%s' %llu is not a multiple of %zu",
- + dbname, (unsigned long long)st.sb.st_size,
- + sizeof(struct magic));
- + goto error;
- + }
- }
- map->magic[0] = CAST(struct magic *, map->p) + 1;
- nentries = 0;
- @@ -3214,15 +3146,29 @@
- map->magic[i + 1] = map->magic[i] + map->nmagic[i];
- nentries += map->nmagic[i];
- }
- - if (entries != nentries + 1) {
- + if (NULL != fn && entries != nentries + 1) {
- file_error(ms, 0, "Inconsistent entries in `%s' %u != %u",
- dbname, entries, nentries + 1);
- - return -1;
- + goto error;
- }
- if (needsbyteswap)
- for (i = 0; i < MAGIC_SETS; i++)
- byteswap(map->magic[i], map->nmagic[i]);
- - return 0;
- +
- + if (dbname) {
- + efree(dbname);
- + }
- + return map;
- +
- +error:
- + if (stream) {
- + php_stream_close(stream);
- + }
- + apprentice_unmap(map);
- + if (dbname) {
- + efree(dbname);
- + }
- + return NULL;
- }
-
- /*
- @@ -3233,7 +3179,6 @@
- {
- static const size_t nm = sizeof(*map->nmagic) * MAGIC_SETS;
- static const size_t m = sizeof(**map->magic);
- - int fd = -1;
- size_t len;
- char *dbname;
- int rv = -1;
- @@ -3242,14 +3187,17 @@
- struct magic m;
- uint32_t h[2 + MAGIC_SETS];
- } hdr;
- + php_stream *stream;
-
- dbname = mkdbname(ms, fn, 1);
-
- if (dbname == NULL)
- goto out;
-
- - if ((fd = open(dbname, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0644)) == -1)
- - {
- + /* wb+ == O_WRONLY|O_CREAT|O_TRUNC|O_BINARY */
- + stream = php_stream_open_wrapper((char *)fn, "wb+", REPORT_ERRORS, NULL);
- +
- + if (!stream) {
- file_error(ms, errno, "cannot open `%s'", dbname);
- goto out;
- }
- @@ -3258,26 +3206,25 @@
- hdr.h[1] = VERSIONNO;
- memcpy(hdr.h + 2, map->nmagic, nm);
-
- - if (write(fd, &hdr, sizeof(hdr)) != CAST(ssize_t, sizeof(hdr))) {
- + if (php_stream_write(stream,(const char *)&hdr, sizeof(hdr)) != (ssize_t)sizeof(hdr)) {
- file_error(ms, errno, "error writing `%s'", dbname);
- - goto out2;
- + goto out;
- }
-
- for (i = 0; i < MAGIC_SETS; i++) {
- len = m * map->nmagic[i];
- - if (write(fd, map->magic[i], len) != CAST(ssize_t, len)) {
- + if (php_stream_write(stream, (const char *)map->magic[i], len) != (ssize_t)len) {
- file_error(ms, errno, "error writing `%s'", dbname);
- - goto out2;
- + goto out;
- }
- }
-
- + if (stream) {
- + php_stream_close(stream);
- + }
- rv = 0;
- -out2:
- - if (fd != -1)
- - (void)close(fd);
- out:
- - apprentice_unmap(map);
- - free(dbname);
- + efree(dbname);
- return rv;
- }
-
- @@ -3311,17 +3258,18 @@
- q++;
- /* Compatibility with old code that looked in .mime */
- if (ms->flags & MAGIC_MIME) {
- - if (asprintf(&buf, "%.*s.mime%s", CAST(int, q - fn), fn, ext)
- - < 0)
- - return NULL;
- - if (access(buf, R_OK) != -1) {
- + spprintf(&buf, MAXPATHLEN, "%.*s.mime%s", CAST(int, q - fn), fn, ext);
- +#ifdef PHP_WIN32
- + if (VCWD_ACCESS(buf, R_OK) == 0) {
- +#else
- + if (VCWD_ACCESS(buf, R_OK) != -1) {
- +#endif
- ms->flags &= MAGIC_MIME_TYPE;
- return buf;
- }
- - free(buf);
- + efree(buf);
- }
- - if (asprintf(&buf, "%.*s%s", CAST(int, q - fn), fn, ext) < 0)
- - return NULL;
- + spprintf(&buf, MAXPATHLEN, "%.*s%s", CAST(int, q - fn), fn, ext);
-
- /* Compatibility with old code that looked in .mime */
- if (strstr(fn, ".mime") != NULL)
- @@ -3411,7 +3359,7 @@
- m->offset = swap4(CAST(uint32_t, m->offset));
- m->in_offset = swap4(CAST(uint32_t, m->in_offset));
- m->lineno = swap4(CAST(uint32_t, m->lineno));
- - if (IS_STRING(m->type)) {
- + if (IS_LIBMAGIC_STRING(m->type)) {
- m->str_range = swap4(m->str_range);
- m->str_flags = swap4(m->str_flags);
- }
- diff -u libmagic.orig/ascmagic.c libmagic/ascmagic.c
- --- libmagic.orig/ascmagic.c 2021-02-23 01:49:06.000000000 +0100
- +++ libmagic/ascmagic.c 2022-06-16 13:39:41.570984700 +0200
- @@ -96,7 +96,7 @@
- rv = file_ascmagic_with_encoding(ms, &bb,
- ubuf, ulen, code, type, text);
-
- - free(ubuf);
- + efree(ubuf);
-
- return rv;
- }
- @@ -143,7 +143,7 @@
- /* malloc size is a conservative overestimate; could be
- improved, or at least realloced after conversion. */
- mlen = ulen * 6;
- - if ((utf8_buf = CAST(unsigned char *, malloc(mlen))) == NULL) {
- + if ((utf8_buf = CAST(unsigned char *, emalloc(mlen))) == NULL) {
- file_oomem(ms, mlen);
- goto done;
- }
- @@ -330,7 +330,8 @@
- }
- rv = 1;
- done:
- - free(utf8_buf);
- + if (utf8_buf)
- + efree(utf8_buf);
-
- return rv;
- }
- diff -u libmagic.orig/buffer.c libmagic/buffer.c
- --- libmagic.orig/buffer.c 2021-02-23 01:49:26.000000000 +0100
- +++ libmagic/buffer.c 2021-09-21 13:27:27.982716100 +0200
- @@ -31,19 +31,23 @@
- #endif /* lint */
-
- #include "magic.h"
- +#ifdef PHP_WIN32
- +#include "win32/unistd.h"
- +#else
- #include <unistd.h>
- +#endif
- #include <string.h>
- #include <stdlib.h>
- #include <sys/stat.h>
-
- void
- -buffer_init(struct buffer *b, int fd, const struct stat *st, const void *data,
- +buffer_init(struct buffer *b, int fd, const zend_stat_t *st, const void *data,
- size_t len)
- {
- b->fd = fd;
- if (st)
- memcpy(&b->st, st, sizeof(b->st));
- - else if (b->fd == -1 || fstat(b->fd, &b->st) == -1)
- + else if (b->fd == -1 || zend_fstat(b->fd, &b->st) == -1)
- memset(&b->st, 0, sizeof(b->st));
- b->fbuf = data;
- b->flen = len;
- @@ -55,7 +59,7 @@
- void
- buffer_fini(struct buffer *b)
- {
- - free(b->ebuf);
- + efree(b->ebuf);
- }
-
- int
- @@ -71,12 +75,14 @@
-
- b->elen = CAST(size_t, b->st.st_size) < b->flen ?
- CAST(size_t, b->st.st_size) : b->flen;
- - if ((b->ebuf = malloc(b->elen)) == NULL)
- + if ((b->ebuf = emalloc(b->elen)) == NULL)
- goto out;
-
- b->eoff = b->st.st_size - b->elen;
- - if (pread(b->fd, b->ebuf, b->elen, b->eoff) == -1) {
- - free(b->ebuf);
- + if (FINFO_LSEEK_FUNC(b->fd, b->eoff, SEEK_SET) == (zend_off_t)-1 ||
- + FINFO_READ_FUNC(b->fd, b->ebuf, b->elen) != (ssize_t)b->elen)
- + {
- + efree(b->ebuf);
- b->ebuf = NULL;
- goto out;
- }
- diff -u libmagic.orig/cdf.c libmagic/cdf.c
- --- libmagic.orig/cdf.c 2021-02-23 01:49:06.000000000 +0100
- +++ libmagic/cdf.c 2021-09-21 13:27:27.983695600 +0200
- @@ -43,7 +43,17 @@
- #include <err.h>
- #endif
- #include <stdlib.h>
- +
- +#ifdef PHP_WIN32
- +#include "win32/unistd.h"
- +#else
- #include <unistd.h>
- +#endif
- +
- +#ifndef UINT32_MAX
- +# define UINT32_MAX (0xffffffff)
- +#endif
- +
- #include <string.h>
- #include <time.h>
- #include <ctype.h>
- @@ -85,40 +95,9 @@
- CDF_TOLE8(CAST(uint64_t, x))))
- #define CDF_GETUINT32(x, y) cdf_getuint32(x, y)
-
- -#define CDF_MALLOC(n) cdf_malloc(__FILE__, __LINE__, (n))
- -#define CDF_REALLOC(p, n) cdf_realloc(__FILE__, __LINE__, (p), (n))
- -#define CDF_CALLOC(n, u) cdf_calloc(__FILE__, __LINE__, (n), (u))
- -
- -
- -/*ARGSUSED*/
- -static void *
- -cdf_malloc(const char *file __attribute__((__unused__)),
- - size_t line __attribute__((__unused__)), size_t n)
- -{
- - DPRINTF(("%s,%" SIZE_T_FORMAT "u: %s %" SIZE_T_FORMAT "u\n",
- - file, line, __func__, n));
- - return malloc(n);
- -}
- -
- -/*ARGSUSED*/
- -static void *
- -cdf_realloc(const char *file __attribute__((__unused__)),
- - size_t line __attribute__((__unused__)), void *p, size_t n)
- -{
- - DPRINTF(("%s,%" SIZE_T_FORMAT "u: %s %" SIZE_T_FORMAT "u\n",
- - file, line, __func__, n));
- - return realloc(p, n);
- -}
- -
- -/*ARGSUSED*/
- -static void *
- -cdf_calloc(const char *file __attribute__((__unused__)),
- - size_t line __attribute__((__unused__)), size_t n, size_t u)
- -{
- - DPRINTF(("%s,%" SIZE_T_FORMAT "u: %s %" SIZE_T_FORMAT "u %"
- - SIZE_T_FORMAT "u\n", file, line, __func__, n, u));
- - return calloc(n, u);
- -}
- +#define CDF_MALLOC(n) emalloc(n)
- +#define CDF_REALLOC(p, n) erealloc(p, n)
- +#define CDF_CALLOC(n, u) ecalloc(n, u)
-
- /*
- * swap a short
- @@ -314,7 +293,7 @@
- scn->sst_len = 0;
- scn->sst_dirlen = 0;
- scn->sst_ss = 0;
- - free(scn->sst_tab);
- + efree(scn->sst_tab);
- scn->sst_tab = NULL;
- return -1;
- }
- @@ -322,9 +301,11 @@
- static size_t
- cdf_check_stream(const cdf_stream_t *sst, const cdf_header_t *h)
- {
- +#ifndef NDEBUG
- size_t ss = sst->sst_dirlen < h->h_min_size_standard_stream ?
- CDF_SHORT_SEC_SIZE(h) : CDF_SEC_SIZE(h);
- assert(ss == sst->sst_ss);
- +#endif
- return sst->sst_ss;
- }
-
- @@ -347,11 +328,11 @@
- }
-
- static ssize_t
- -cdf_read(const cdf_info_t *info, off_t off, void *buf, size_t len)
- +cdf_read(const cdf_info_t *info, zend_off_t off, void *buf, size_t len)
- {
- size_t siz = CAST(size_t, off + len);
-
- - if (CAST(off_t, off + len) != CAST(off_t, siz))
- + if (CAST(zend_off_t, off + len) != CAST(zend_off_t, siz))
- goto out;
-
- if (info->i_buf != NULL && info->i_len >= siz) {
- @@ -362,7 +343,10 @@
- if (info->i_fd == -1)
- goto out;
-
- - if (pread(info->i_fd, buf, len, off) != CAST(ssize_t, len))
- + if (FINFO_LSEEK_FUNC(info->i_fd, off, SEEK_SET) == (zend_off_t)-1)
- + return -1;
- +
- + if (FINFO_READ_FUNC(info->i_fd, buf, len) != (ssize_t)len)
- return -1;
-
- return CAST(ssize_t, len);
- @@ -377,7 +361,7 @@
- char buf[512];
-
- (void)memcpy(cdf_bo.s, "\01\02\03\04", 4);
- - if (cdf_read(info, CAST(off_t, 0), buf, sizeof(buf)) == -1)
- + if (cdf_read(info, CAST(zend_off_t, 0), buf, sizeof(buf)) == -1)
- return -1;
- cdf_unpack_header(h, buf);
- cdf_swap_header(h);
- @@ -524,14 +508,14 @@
- }
- out:
- sat->sat_len = i;
- - free(msa);
- + efree(msa);
- return 0;
- out3:
- errno = EFTYPE;
- out2:
- - free(msa);
- + efree(msa);
- out1:
- - free(sat->sat_tab);
- + efree(sat->sat_tab);
- return -1;
- }
-
- @@ -699,7 +683,7 @@
- return -1;
-
- if ((buf = CAST(char *, CDF_MALLOC(ss))) == NULL) {
- - free(dir->dir_tab);
- + efree(dir->dir_tab);
- return -1;
- }
-
- @@ -722,11 +706,11 @@
- if (NEED_SWAP)
- for (i = 0; i < dir->dir_len; i++)
- cdf_swap_dir(&dir->dir_tab[i]);
- - free(buf);
- + efree(buf);
- return 0;
- out:
- - free(dir->dir_tab);
- - free(buf);
- + efree(dir->dir_tab);
- + efree(buf);
- errno = EFTYPE;
- return -1;
- }
- @@ -771,7 +755,7 @@
- out:
- errno = EFTYPE;
- out1:
- - free(ssat->sat_tab);
- + efree(ssat->sat_tab);
- return -1;
- }
-
- @@ -933,7 +917,7 @@
- *maxcount = newcount;
- return inp;
- out:
- - free(*info);
- + efree(*info);
- *maxcount = 0;
- *info = NULL;
- return NULL;
- @@ -1115,7 +1099,7 @@
- }
- return 0;
- out:
- - free(*info);
- + efree(*info);
- *info = NULL;
- *count = 0;
- *maxcount = 0;
- @@ -1407,7 +1391,7 @@
- cdf_directory_t *d;
- char name[__arraycount(d->d_name)];
- cdf_stream_t scn;
- - struct timespec ts;
- + struct timeval ts;
-
- static const char *types[] = { "empty", "user storage",
- "user stream", "lockbytes", "property", "root storage" };
- @@ -1449,7 +1433,7 @@
- break;
- }
- cdf_dump_stream(&scn);
- - free(scn.sst_tab);
- + efree(scn.sst_tab);
- break;
- default:
- break;
- @@ -1462,7 +1446,7 @@
- cdf_dump_property_info(const cdf_property_info_t *info, size_t count)
- {
- cdf_timestamp_t tp;
- - struct timespec ts;
- + struct timeval ts;
- char buf[64];
- size_t i, j;
-
- @@ -1547,7 +1531,7 @@
- (void)fprintf(stderr, "Class %s\n", buf);
- (void)fprintf(stderr, "Count %d\n", ssi.si_count);
- cdf_dump_property_info(info, count);
- - free(info);
- + efree(info);
- }
-
-
- @@ -1568,7 +1552,7 @@
- cdf_u16tos8(sbuf, ce[i].ce_namlen, ce[i].ce_name),
- cdf_ctime(&ts.tv_sec, tbuf));
- }
- - free(cat);
- + efree(cat);
- }
-
- #endif
- diff -u libmagic.orig/cdf.h libmagic/cdf.h
- --- libmagic.orig/cdf.h 2021-02-23 01:49:06.000000000 +0100
- +++ libmagic/cdf.h 2021-09-21 13:27:27.984674900 +0200
- @@ -35,10 +35,10 @@
- #ifndef _H_CDF_
- #define _H_CDF_
-
- -#ifdef WIN32
- +#ifdef PHP_WIN32
- #include <winsock2.h>
- -#define timespec timeval
- -#define tv_nsec tv_usec
- +#define asctime_r php_asctime_r
- +#define ctime_r php_ctime_r
- #endif
- #ifdef __DJGPP__
- #define timespec timeval
- diff -u libmagic.orig/cdf_time.c libmagic/cdf_time.c
- --- libmagic.orig/cdf_time.c 2021-02-23 01:49:06.000000000 +0100
- +++ libmagic/cdf_time.c 2021-09-21 13:27:27.985654400 +0200
- @@ -23,6 +23,7 @@
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
- +#include "php.h"
-
- #include "file.h"
-
- @@ -152,7 +153,7 @@
- #endif
- #ifdef notyet
- struct tm tm;
- - if (gmtime_r(&ts->ts_sec, &tm) == NULL) {
- + if (php_gmtime_r(&ts->ts_sec, &tm) == NULL) {
- errno = EINVAL;
- return -1;
- }
- @@ -168,7 +169,7 @@
- char *
- cdf_ctime(const time_t *sec, char *buf)
- {
- - char *ptr = ctime_r(sec, buf);
- + char *ptr = php_ctime_r(sec, buf);
- if (ptr != NULL)
- return buf;
- (void)snprintf(buf, 26, "*Bad* %#16.16" INT64_T_FORMAT "x\n",
- diff -u libmagic.orig/compress.c libmagic/compress.c
- --- libmagic.orig/compress.c 2021-02-23 01:49:07.000000000 +0100
- +++ libmagic/compress.c 2022-06-16 13:39:41.586609800 +0200
- @@ -51,7 +51,7 @@
- #ifndef HAVE_SIG_T
- typedef void (*sig_t)(int);
- #endif /* HAVE_SIG_T */
- -#if !defined(__MINGW32__) && !defined(WIN32) && !defined(__MINGW64__)
- +#ifndef PHP_WIN32
- #include <sys/ioctl.h>
- #endif
- #ifdef HAVE_SYS_WAIT_H
- @@ -60,13 +60,14 @@
- #if defined(HAVE_SYS_TIME_H)
- #include <sys/time.h>
- #endif
- -
- -#if defined(HAVE_ZLIB_H) && defined(ZLIBSUPPORT)
- +#if defined(HAVE_ZLIB_H) && defined(PHP_FILEINFO_UNCOMPRESS)
- #define BUILTIN_DECOMPRESS
- #include <zlib.h>
- #endif
-
- -#if defined(HAVE_BZLIB_H) && defined(BZLIBSUPPORT)
- +#undef FIONREAD
- +
- +#if defined(PHP_FILEINFO_UNCOMPRESS)
- #define BUILTIN_BZLIB
- #include <bzlib.h>
- #endif
- @@ -118,6 +119,8 @@
- }
- #endif
-
- +#ifdef PHP_FILEINFO_UNCOMPRESS
- +
- static int
- lzmacmp(const unsigned char *buf)
- {
- @@ -221,8 +224,7 @@
- size_t *);
- #endif
-
- -static int makeerror(unsigned char **, size_t *, const char *, ...)
- - __attribute__((__format__(__printf__, 3, 4)));
- +static int makeerror(unsigned char **, size_t *, const char *, ...);
- private const char *methodname(size_t);
-
- private int
- @@ -294,7 +296,7 @@
- if (urv == ERRDATA)
- prv = format_decompression_error(ms, i, newbuf);
- else
- - prv = file_buffer(ms, -1, NULL, name, newbuf, nsz);
- + prv = file_buffer(ms, NULL, NULL, name, newbuf, nsz);
- if (prv == -1)
- goto error;
- rv = 1;
- @@ -311,17 +313,17 @@
- * XXX: If file_buffer fails here, we overwrite
- * the compressed text. FIXME.
- */
- - if (file_buffer(ms, -1, NULL, NULL, buf, nbytes) == -1) {
- + if (file_buffer(ms, NULL, NULL, NULL, buf, nbytes) == -1) {
- if (file_pop_buffer(ms, pb) != NULL)
- abort();
- goto error;
- }
- if ((rbuf = file_pop_buffer(ms, pb)) != NULL) {
- if (file_printf(ms, "%s", rbuf) == -1) {
- - free(rbuf);
- + efree(rbuf);
- goto error;
- }
- - free(rbuf);
- + efree(rbuf);
- }
- if (!mime && file_printf(ms, ")") == -1)
- goto error;
- @@ -342,7 +344,8 @@
- if (sa_saved && sig_act.sa_handler != SIG_IGN)
- (void)sigaction(SIGPIPE, &sig_act, NULL);
-
- - free(newbuf);
- + if (newbuf)
- + efree(newbuf);
- ms->flags |= MAGIC_COMPRESS;
- DPRINTF("Zmagic returns %d\n", rv);
- return rv;
- @@ -377,7 +380,7 @@
- * `safe' read for sockets and pipes.
- */
- protected ssize_t
- -sread(int fd, void *buf, size_t n, int canbepipe __attribute__((__unused__)))
- +sread(int fd, void *buf, size_t n, int canbepipe)
- {
- ssize_t rv;
- #ifdef FIONREAD
- @@ -425,7 +428,7 @@
-
- nocheck:
- do
- - switch ((rv = read(fd, buf, n))) {
- + switch ((rv = FINFO_READ_FUNC(fd, buf, n))) {
- case -1:
- if (errno == EINTR)
- continue;
- @@ -504,13 +507,13 @@
- return -1;
- }
- (void)close(tfd);
- - if (lseek(fd, CAST(off_t, 0), SEEK_SET) == CAST(off_t, -1)) {
- + if (FINFO_LSEEK_FUNC(fd, (zend_off_t)0, SEEK_SET) == (zend_off_t)-1) {
- file_badseek(ms);
- return -1;
- }
- return fd;
- }
- -#if HAVE_FORK
- +#ifdef PHP_FILEINFO_UNCOMPRESS
- #ifdef BUILTIN_DECOMPRESS
-
- #define FHCRC (1 << 1)
- @@ -561,7 +564,7 @@
- int rc;
- z_stream z;
-
- - if ((*newch = CAST(unsigned char *, malloc(bytes_max + 1))) == NULL)
- + if ((*newch = CAST(unsigned char *, emalloc(bytes_max + 1))) == NULL)
- return makeerror(newch, n, "No buffer, %s", strerror(errno));
-
- z.next_in = CCAST(Bytef *, old);
- @@ -986,3 +989,4 @@
- return rv;
- }
- #endif
- +#endif
- diff -u libmagic.orig/der.c libmagic/der.c
- --- libmagic.orig/der.c 2021-02-23 01:49:06.000000000 +0100
- +++ libmagic/der.c 2022-06-16 13:39:41.586609800 +0200
- @@ -54,7 +54,9 @@
- #include "magic.h"
- #include "der.h"
- #else
- +#ifndef PHP_WIN32
- #include <sys/mman.h>
- +#endif
- #include <sys/stat.h>
- #include <err.h>
- #endif
- diff -u libmagic.orig/elfclass.h libmagic/elfclass.h
- --- libmagic.orig/elfclass.h 2021-02-23 01:49:06.000000000 +0100
- +++ libmagic/elfclass.h 2021-09-21 13:27:27.989571700 +0200
- @@ -41,7 +41,7 @@
- return toomany(ms, "program headers", phnum);
- flags |= FLAGS_IS_CORE;
- if (dophn_core(ms, clazz, swap, fd,
- - CAST(off_t, elf_getu(swap, elfhdr.e_phoff)), phnum,
- + CAST(zend_off_t, elf_getu(swap, elfhdr.e_phoff)), phnum,
- CAST(size_t, elf_getu16(swap, elfhdr.e_phentsize)),
- fsize, &flags, ¬ecount) == -1)
- return -1;
- @@ -56,7 +56,7 @@
- if (shnum > ms->elf_shnum_max)
- return toomany(ms, "section", shnum);
- if (dophn_exec(ms, clazz, swap, fd,
- - CAST(off_t, elf_getu(swap, elfhdr.e_phoff)), phnum,
- + CAST(zend_off_t, elf_getu(swap, elfhdr.e_phoff)), phnum,
- CAST(size_t, elf_getu16(swap, elfhdr.e_phentsize)),
- fsize, shnum, &flags, ¬ecount) == -1)
- return -1;
- @@ -66,7 +66,7 @@
- if (shnum > ms->elf_shnum_max)
- return toomany(ms, "section headers", shnum);
- if (doshn(ms, clazz, swap, fd,
- - CAST(off_t, elf_getu(swap, elfhdr.e_shoff)), shnum,
- + CAST(zend_off_t, elf_getu(swap, elfhdr.e_shoff)), shnum,
- CAST(size_t, elf_getu16(swap, elfhdr.e_shentsize)),
- fsize, elf_getu16(swap, elfhdr.e_machine),
- CAST(int, elf_getu16(swap, elfhdr.e_shstrndx)),
- diff -u libmagic.orig/encoding.c libmagic/encoding.c
- --- libmagic.orig/encoding.c 2021-02-23 01:49:06.000000000 +0100
- +++ libmagic/encoding.c 2022-06-16 13:39:41.586609800 +0200
- @@ -98,14 +98,14 @@
- nbytes = ms->encoding_max;
-
- mlen = (nbytes + 1) * sizeof((*ubuf)[0]);
- - *ubuf = CAST(file_unichar_t *, calloc(CAST(size_t, 1), mlen));
- + *ubuf = CAST(file_unichar_t *, ecalloc(CAST(size_t, 1), mlen));
- if (*ubuf == NULL) {
- file_oomem(ms, mlen);
- goto done;
- }
- mlen = (nbytes + 1) * sizeof(nbuf[0]);
- if ((nbuf = CAST(unsigned char *,
- - calloc(CAST(size_t, 1), mlen))) == NULL) {
- + ecalloc(CAST(size_t, 1), mlen))) == NULL) {
- file_oomem(ms, mlen);
- goto done;
- }
- @@ -174,9 +174,9 @@
- }
-
- done:
- - free(nbuf);
- + efree(nbuf);
- if (ubuf == &udefbuf)
- - free(udefbuf);
- + efree(udefbuf);
-
- return rv;
- }
- @@ -283,7 +283,7 @@
- u = 0; \
- for (i = 0; i < __arraycount(dist); i++) { \
- if (dist[i]) \
- - u++; \
- + u += dist[i]; \
- } \
- if (u < 3) \
- return 0; \
- diff -u libmagic.orig/file.h libmagic/file.h
- --- libmagic.orig/file.h 2021-02-23 01:49:06.000000000 +0100
- +++ libmagic/file.h 2022-06-16 13:39:41.586609800 +0200
- @@ -33,17 +33,14 @@
- #ifndef __file_h__
- #define __file_h__
-
- -#ifdef HAVE_CONFIG_H
- -#include <config.h>
- -#endif
- +#include "config.h"
-
- -#ifdef HAVE_STDINT_H
- -#include <stdint.h>
- -#endif
- +#include "php.h"
- +#include "ext/standard/php_string.h"
- +#include "ext/pcre/php_pcre.h"
-
- -#ifdef HAVE_INTTYPES_H
- +#include <stdint.h>
- #include <inttypes.h>
- -#endif
-
- #ifndef __STDC_LIMIT_MACROS
- #define __STDC_LIMIT_MACROS
- @@ -79,23 +76,26 @@
- #include <stdio.h> /* Include that here, to make sure __P gets defined */
- #include <errno.h>
- #include <fcntl.h> /* For open and flags */
- -#include <regex.h>
- -#include <time.h>
- +
- #include <sys/types.h>
- -#ifndef WIN32
- +#ifdef PHP_WIN32
- +#include "win32/param.h"
- +#else
- #include <sys/param.h>
- #endif
- /* Do this here and now, because struct stat gets re-defined on solaris */
- #include <sys/stat.h>
- #include <stdarg.h>
-
- +#define abort() zend_error_noreturn(E_ERROR, "fatal libmagic error")
- +
- #define ENABLE_CONDITIONALS
-
- #ifndef MAGIC
- #define MAGIC "/etc/magic"
- #endif
-
- -#if defined(__EMX__) || defined (WIN32)
- +#if defined(__EMX__) || defined(PHP_WIN32)
- #define PATHSEP ';'
- #else
- #define PATHSEP ':'
- @@ -129,12 +129,6 @@
- #endif
- #endif
-
- -#ifndef __GNUC__
- -#ifndef __attribute__
- -#define __attribute__(a)
- -#endif
- -#endif
- -
- #ifndef MIN
- #define MIN(a,b) (((a) < (b)) ? (a) : (b))
- #endif
- @@ -169,10 +163,10 @@
-
- struct buffer {
- int fd;
- - struct stat st;
- + zend_stat_t st;
- const void *fbuf;
- size_t flen;
- - off_t eoff;
- + zend_off_t eoff;
- void *ebuf;
- size_t elen;
- };
- @@ -266,7 +260,7 @@
- #define FILE_OFFSET 50
- #define FILE_NAMES_SIZE 51 /* size of array to contain all names */
-
- -#define IS_STRING(t) \
- +#define IS_LIBMAGIC_STRING(t) \
- ((t) == FILE_STRING || \
- (t) == FILE_PSTRING || \
- (t) == FILE_BESTRING16 || \
- @@ -484,13 +478,11 @@
- protected const char *file_fmttime(char *, size_t, uint64_t, int);
- protected struct magic_set *file_ms_alloc(int);
- protected void file_ms_free(struct magic_set *);
- -protected int file_default(struct magic_set *, size_t);
- -protected int file_buffer(struct magic_set *, int, struct stat *, const char *,
- - const void *, size_t);
- -protected int file_fsmagic(struct magic_set *, const char *, struct stat *);
- +protected int file_buffer(struct magic_set *, php_stream *, zend_stat_t *, const char *, const void *,
- + size_t);
- +protected int file_fsmagic(struct magic_set *, const char *, zend_stat_t *);
- protected int file_pipe2file(struct magic_set *, int, const void *, size_t);
- -protected int file_vprintf(struct magic_set *, const char *, va_list)
- - __attribute__((__format__(__printf__, 2, 0)));
- +protected int file_vprintf(struct magic_set *, const char *, va_list);
- protected int file_separator(struct magic_set *);
- protected char *file_copystr(char *, size_t, size_t, const char *);
- protected int file_checkfmt(char *, size_t, const char *);
- @@ -498,12 +490,11 @@
- protected int file_print_guid(char *, size_t, const uint64_t *);
- protected int file_parse_guid(const char *, uint64_t *);
- protected int file_replace(struct magic_set *, const char *, const char *);
- -protected int file_printf(struct magic_set *, const char *, ...)
- - __attribute__((__format__(__printf__, 2, 3)));
- +protected int file_printf(struct magic_set *, const char *, ...);
- protected int file_reset(struct magic_set *, int);
- protected int file_tryelf(struct magic_set *, const struct buffer *);
- protected int file_trycdf(struct magic_set *, const struct buffer *);
- -#if HAVE_FORK
- +#ifdef PHP_FILEINFO_UNCOMPRESS
- protected int file_zmagic(struct magic_set *, const struct buffer *,
- const char *);
- #endif
- @@ -527,12 +518,9 @@
- protected void file_badread(struct magic_set *);
- protected void file_badseek(struct magic_set *);
- protected void file_oomem(struct magic_set *, size_t);
- -protected void file_error(struct magic_set *, int, const char *, ...)
- - __attribute__((__format__(__printf__, 3, 4)));
- -protected void file_magerror(struct magic_set *, const char *, ...)
- - __attribute__((__format__(__printf__, 2, 3)));
- -protected void file_magwarn(struct magic_set *, const char *, ...)
- - __attribute__((__format__(__printf__, 2, 3)));
- +protected void file_error(struct magic_set *, int, const char *, ...);
- +protected void file_magerror(struct magic_set *, const char *, ...);
- +protected void file_magwarn(struct magic_set *, const char *, ...);
- protected void file_mdump(struct magic *);
- protected void file_showstr(FILE *, const char *, size_t);
- protected size_t file_mbswidth(const char *);
- @@ -554,34 +542,12 @@
- protected int file_clear_closexec(int);
- protected char *file_strtrim(char *);
-
- -protected void buffer_init(struct buffer *, int, const struct stat *,
- +protected void buffer_init(struct buffer *, int, const zend_stat_t *,
- const void *, size_t);
- protected void buffer_fini(struct buffer *);
- protected int buffer_fill(const struct buffer *);
-
- -#include <locale.h>
- -#if defined(HAVE_XLOCALE_H)
- -#include <xlocale.h>
- -#endif
- -
- -typedef struct {
- - const char *pat;
- -#if defined(HAVE_NEWLOCALE) && defined(HAVE_USELOCALE) && defined(HAVE_FREELOCALE)
- -#define USE_C_LOCALE
- - locale_t old_lc_ctype;
- - locale_t c_lc_ctype;
- -#else
- - char *old_lc_ctype;
- -#endif
- - int rc;
- - regex_t rx;
- -} file_regex_t;
- -
- -protected int file_regcomp(file_regex_t *, const char *, int);
- -protected int file_regexec(file_regex_t *, const char *, size_t, regmatch_t *,
- - int);
- -protected void file_regfree(file_regex_t *);
- -protected void file_regerror(file_regex_t *, int, struct magic_set *);
- +public zend_string* convert_libmagic_pattern(const char *val, size_t len, uint32_t options);
-
- typedef struct {
- char *buf;
- @@ -597,23 +563,10 @@
- extern const size_t file_nnames;
- #endif
-
- -#ifndef HAVE_PREAD
- -ssize_t pread(int, void *, size_t, off_t);
- -#endif
- -#ifndef HAVE_VASPRINTF
- -int vasprintf(char **, const char *, va_list);
- -#endif
- -#ifndef HAVE_ASPRINTF
- -int asprintf(char **, const char *, ...);
- -#endif
- -#ifndef HAVE_DPRINTF
- -int dprintf(int, const char *, ...);
- -#endif
- -
- -#ifndef HAVE_STRLCPY
- +#ifndef strlcpy
- size_t strlcpy(char *, const char *, size_t);
- #endif
- -#ifndef HAVE_STRLCAT
- +#ifndef strlcat
- size_t strlcat(char *, const char *, size_t);
- #endif
- #ifndef HAVE_STRCASESTR
- @@ -629,39 +582,6 @@
- #ifndef HAVE_ASCTIME_R
- char *asctime_r(const struct tm *, char *);
- #endif
- -#ifndef HAVE_GMTIME_R
- -struct tm *gmtime_r(const time_t *, struct tm *);
- -#endif
- -#ifndef HAVE_LOCALTIME_R
- -struct tm *localtime_r(const time_t *, struct tm *);
- -#endif
- -#ifndef HAVE_FMTCHECK
- -const char *fmtcheck(const char *, const char *)
- - __attribute__((__format_arg__(2)));
- -#endif
- -
- -#ifdef HAVE_LIBSECCOMP
- -// basic filter
- -// this mode should not interfere with normal operations
- -// only some dangerous syscalls are blacklisted
- -int enable_sandbox_basic(void);
- -
- -// enhanced filter
- -// this mode allows only the necessary syscalls used during normal operation
- -// extensive testing required !!!
- -int enable_sandbox_full(void);
- -#endif
- -
- -protected const char *file_getprogname(void);
- -protected void file_setprogname(const char *);
- -protected void file_err(int, const char *, ...)
- - __attribute__((__format__(__printf__, 2, 3), __noreturn__));
- -protected void file_errx(int, const char *, ...)
- - __attribute__((__format__(__printf__, 2, 3), __noreturn__));
- -protected void file_warn(const char *, ...)
- - __attribute__((__format__(__printf__, 1, 2)));
- -protected void file_warnx(const char *, ...)
- - __attribute__((__format__(__printf__, 1, 2)));
-
- #if defined(HAVE_MMAP) && defined(HAVE_SYS_MMAN_H) && !defined(QUICK)
- #define QUICK
- @@ -691,4 +611,16 @@
- #define __RCSID(a)
- #endif
-
- +#ifdef PHP_WIN32
- +#ifdef _WIN64
- +#define FINFO_LSEEK_FUNC _lseeki64
- +#else
- +#define FINFO_LSEEK_FUNC _lseek
- +#endif
- +#define FINFO_READ_FUNC _read
- +#else
- +#define FINFO_LSEEK_FUNC lseek
- +#define FINFO_READ_FUNC read
- +#endif
- +
- #endif /* __file_h__ */
- diff -u libmagic.orig/fsmagic.c libmagic/fsmagic.c
- --- libmagic.orig/fsmagic.c 2021-02-23 01:49:06.000000000 +0100
- +++ libmagic/fsmagic.c 2021-09-21 13:27:27.992511000 +0200
- @@ -66,26 +66,10 @@
- # define minor(dev) ((dev) & 0xff)
- #endif
- #undef HAVE_MAJOR
- -#ifdef S_IFLNK
- -private int
- -bad_link(struct magic_set *ms, int err, char *buf)
- -{
- - int mime = ms->flags & MAGIC_MIME;
- - if ((mime & MAGIC_MIME_TYPE) &&
- - file_printf(ms, "inode/symlink")
- - == -1)
- - return -1;
- - else if (!mime) {
- - if (ms->flags & MAGIC_ERROR) {
- - file_error(ms, err,
- - "broken symbolic link to %s", buf);
- - return -1;
- - }
- - if (file_printf(ms, "broken symbolic link to %s", buf) == -1)
- - return -1;
- - }
- - return 1;
- -}
- +
- +#ifdef PHP_WIN32
- +
- +# undef S_IFIFO
- #endif
- private int
- handle_mime(struct magic_set *ms, int mime, const char *str)
- @@ -103,60 +87,17 @@
- }
-
- protected int
- -file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb)
- +file_fsmagic(struct magic_set *ms, const char *fn, zend_stat_t *sb)
- {
- int ret, did = 0;
- int mime = ms->flags & MAGIC_MIME;
- int silent = ms->flags & (MAGIC_APPLE|MAGIC_EXTENSION);
- -#ifdef S_IFLNK
- - char buf[BUFSIZ+4];
- - ssize_t nch;
- - struct stat tstatbuf;
- -#endif
-
- if (fn == NULL)
- return 0;
-
- #define COMMA (did++ ? ", " : "")
- - /*
- - * Fstat is cheaper but fails for files you don't have read perms on.
- - * On 4.2BSD and similar systems, use lstat() to identify symlinks.
- - */
- -#ifdef S_IFLNK
- - if ((ms->flags & MAGIC_SYMLINK) == 0)
- - ret = lstat(fn, sb);
- - else
- -#endif
- - ret = stat(fn, sb); /* don't merge into if; see "ret =" above */
- -
- -#ifdef WIN32
- - {
- - HANDLE hFile = CreateFile((LPCSTR)fn, 0, FILE_SHARE_DELETE |
- - FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0,
- - NULL);
- - if (hFile != INVALID_HANDLE_VALUE) {
- - /*
- - * Stat failed, but we can still open it - assume it's
- - * a block device, if nothing else.
- - */
- - if (ret) {
- - sb->st_mode = S_IFBLK;
- - ret = 0;
- - }
- - switch (GetFileType(hFile)) {
- - case FILE_TYPE_CHAR:
- - sb->st_mode |= S_IFCHR;
- - sb->st_mode &= ~S_IFREG;
- - break;
- - case FILE_TYPE_PIPE:
- - sb->st_mode |= S_IFIFO;
- - sb->st_mode &= ~S_IFREG;
- - break;
- - }
- - CloseHandle(hFile);
- - }
- - }
- -#endif
- + ret = php_sys_stat(fn, sb);
-
- if (ret) {
- if (ms->flags & MAGIC_ERROR) {
- @@ -189,32 +130,24 @@
- }
-
- switch (sb->st_mode & S_IFMT) {
- - case S_IFDIR:
- - if (mime) {
- - if (handle_mime(ms, mime, "directory") == -1)
- - return -1;
- - } else if (silent) {
- - } else if (file_printf(ms, "%sdirectory", COMMA) == -1)
- - return -1;
- - break;
- -#ifdef S_IFCHR
- - case S_IFCHR:
- - /*
- - * If -s has been specified, treat character special files
- - * like ordinary files. Otherwise, just report that they
- - * are block special files and go on to the next file.
- - */
- - if ((ms->flags & MAGIC_DEVICES) != 0) {
- - ret = 0;
- - break;
- - }
- - if (mime) {
- - if (handle_mime(ms, mime, "chardevice") == -1)
- - return -1;
- - } else if (silent) {
- - } else {
- -#ifdef HAVE_STRUCT_STAT_ST_RDEV
- -# ifdef dv_unit
- +#ifndef PHP_WIN32
- +# ifdef S_IFCHR
- + case S_IFCHR:
- + /*
- + * If -s has been specified, treat character special files
- + * like ordinary files. Otherwise, just report that they
- + * are block special files and go on to the next file.
- + */
- + if ((ms->flags & MAGIC_DEVICES) != 0) {
- + ret = 0;
- + break;
- + }
- + if (mime) {
- + if (handle_mime(ms, mime, "chardevice") == -1)
- + return -1;
- + } else {
- +# ifdef HAVE_STAT_ST_RDEV
- +# ifdef dv_unit
- if (file_printf(ms, "%scharacter special (%d/%d/%d)",
- COMMA, major(sb->st_rdev), dv_unit(sb->st_rdev),
- dv_subunit(sb->st_rdev)) == -1)
- @@ -229,45 +162,11 @@
- if (file_printf(ms, "%scharacter special", COMMA) == -1)
- return -1;
- #endif
- - }
- - break;
- -#endif
- -#ifdef S_IFBLK
- - case S_IFBLK:
- - /*
- - * If -s has been specified, treat block special files
- - * like ordinary files. Otherwise, just report that they
- - * are block special files and go on to the next file.
- - */
- - if ((ms->flags & MAGIC_DEVICES) != 0) {
- - ret = 0;
- - break;
- - }
- - if (mime) {
- - if (handle_mime(ms, mime, "blockdevice") == -1)
- - return -1;
- - } else if (silent) {
- - } else {
- -#ifdef HAVE_STRUCT_STAT_ST_RDEV
- -# ifdef dv_unit
- - if (file_printf(ms, "%sblock special (%d/%d/%d)",
- - COMMA, major(sb->st_rdev), dv_unit(sb->st_rdev),
- - dv_subunit(sb->st_rdev)) == -1)
- - return -1;
- -# else
- - if (file_printf(ms, "%sblock special (%ld/%ld)",
- - COMMA, (long)major(sb->st_rdev),
- - (long)minor(sb->st_rdev)) == -1)
- - return -1;
- + }
- + return 1;
- # endif
- -#else
- - if (file_printf(ms, "%sblock special", COMMA) == -1)
- - return -1;
- #endif
- - }
- - break;
- -#endif
- - /* TODO add code to handle V7 MUX and Blit MUX files */
- +
- #ifdef S_IFIFO
- case S_IFIFO:
- if((ms->flags & MAGIC_DEVICES) != 0)
- @@ -292,92 +191,14 @@
- #endif
- #ifdef S_IFLNK
- case S_IFLNK:
- - if ((nch = readlink(fn, buf, BUFSIZ-1)) <= 0) {
- + /* stat is used, if it made here then the link is broken */
- if (ms->flags & MAGIC_ERROR) {
- - file_error(ms, errno, "unreadable symlink `%s'",
- - fn);
- + file_error(ms, errno, "unreadable symlink `%s'", fn);
- return -1;
- }
- - if (mime) {
- - if (handle_mime(ms, mime, "symlink") == -1)
- - return -1;
- - } else if (silent) {
- - } else if (file_printf(ms,
- - "%sunreadable symlink `%s' (%s)", COMMA, fn,
- - strerror(errno)) == -1)
- - return -1;
- - break;
- - }
- - buf[nch] = '\0'; /* readlink(2) does not do this */
- -
- - /* If broken symlink, say so and quit early. */
- -#ifdef __linux__
- - /*
- - * linux procfs/devfs makes symlinks like pipe:[3515864880]
- - * that we can't stat their readlink output, so stat the
- - * original filename instead.
- - */
- - if (stat(fn, &tstatbuf) < 0)
- - return bad_link(ms, errno, buf);
- -#else
- - if (*buf == '/') {
- - if (stat(buf, &tstatbuf) < 0)
- - return bad_link(ms, errno, buf);
- - } else {
- - char *tmp;
- - char buf2[BUFSIZ+BUFSIZ+4];
- -
- - if ((tmp = strrchr(fn, '/')) == NULL) {
- - tmp = buf; /* in current directory anyway */
- - } else {
- - if (tmp - fn + 1 > BUFSIZ) {
- - if (ms->flags & MAGIC_ERROR) {
- - file_error(ms, 0,
- - "path too long: `%s'", buf);
- - return -1;
- - }
- - if (mime) {
- - if (handle_mime(ms, mime,
- - "x-path-too-long") == -1)
- - return -1;
- - } else if (silent) {
- - } else if (file_printf(ms,
- - "%spath too long: `%s'", COMMA,
- - fn) == -1)
- - return -1;
- - break;
- - }
- - /* take dir part */
- - (void)strlcpy(buf2, fn, sizeof buf2);
- - buf2[tmp - fn + 1] = '\0';
- - /* plus (rel) link */
- - (void)strlcat(buf2, buf, sizeof buf2);
- - tmp = buf2;
- - }
- - if (stat(tmp, &tstatbuf) < 0)
- - return bad_link(ms, errno, buf);
- - }
- + return 1;
- #endif
-
- - /* Otherwise, handle it. */
- - if ((ms->flags & MAGIC_SYMLINK) != 0) {
- - const char *p;
- - ms->flags &= MAGIC_SYMLINK;
- - p = magic_file(ms, buf);
- - ms->flags |= MAGIC_SYMLINK;
- - if (p == NULL)
- - return -1;
- - } else { /* just print what it points to */
- - if (mime) {
- - if (handle_mime(ms, mime, "symlink") == -1)
- - return -1;
- - } else if (silent) {
- - } else if (file_printf(ms, "%ssymbolic link to %s",
- - COMMA, buf) == -1)
- - return -1;
- - }
- - break;
- -#endif
- #ifdef S_IFSOCK
- #ifndef __COHERENT__
- case S_IFSOCK:
- diff -u libmagic.orig/funcs.c libmagic/funcs.c
- --- libmagic.orig/funcs.c 2021-02-23 01:49:06.000000000 +0100
- +++ libmagic/funcs.c 2022-06-16 13:39:41.586609800 +0200
- @@ -51,6 +51,13 @@
- #define SIZE_MAX ((size_t)~0)
- #endif
-
- +#include "php.h"
- +#include "main/php_network.h"
- +
- +#ifndef PREG_OFFSET_CAPTURE
- +# define PREG_OFFSET_CAPTURE (1<<8)
- +#endif
- +
- protected char *
- file_copystr(char *buf, size_t blen, size_t width, const char *str)
- {
- @@ -63,7 +70,7 @@
- private void
- file_clearbuf(struct magic_set *ms)
- {
- - free(ms->o.buf);
- + efree(ms->o.buf);
- ms->o.buf = NULL;
- ms->o.blen = 0;
- }
- @@ -128,7 +135,7 @@
- protected int
- file_vprintf(struct magic_set *ms, const char *fmt, va_list ap)
- {
- - int len;
- + size_t len;
- char *buf, *newstr;
- char tbuf[1024];
-
- @@ -141,10 +148,10 @@
- return -1;
- }
-
- - len = vasprintf(&buf, fmt, ap);
- - if (len < 0 || (size_t)len > 1024 || len + ms->o.blen > 1024 * 1024) {
- + len = vspprintf(&buf, 0, fmt, ap);
- + if (len > 1024 || len + ms->o.blen > 1024 * 1024) {
- size_t blen = ms->o.blen;
- - free(buf);
- + if (buf) efree(buf);
- file_clearbuf(ms);
- file_error(ms, 0, "Output buffer space exceeded %d+%zu", len,
- blen);
- @@ -152,20 +159,14 @@
- }
-
- if (ms->o.buf != NULL) {
- - len = asprintf(&newstr, "%s%s", ms->o.buf, buf);
- - free(buf);
- - if (len < 0)
- - goto out;
- - free(ms->o.buf);
- + len = spprintf(&newstr, 0, "%s%s", ms->o.buf, buf);
- + efree(buf);
- + efree(ms->o.buf);
- buf = newstr;
- }
- ms->o.buf = buf;
- ms->o.blen = len;
- return 0;
- -out:
- - file_clearbuf(ms);
- - file_error(ms, errno, "vasprintf failed");
- - return -1;
- }
-
- protected int
- @@ -184,7 +185,6 @@
- * error - print best error message possible
- */
- /*VARARGS*/
- -__attribute__((__format__(__printf__, 3, 0)))
- private void
- file_error_core(struct magic_set *ms, int error, const char *f, va_list va,
- size_t lineno)
- @@ -316,8 +316,8 @@
- */
- /*ARGSUSED*/
- protected int
- -file_buffer(struct magic_set *ms, int fd, struct stat *st,
- - const char *inname __attribute__ ((__unused__)),
- +file_buffer(struct magic_set *ms, php_stream *stream, zend_stat_t *st,
- + const char *inname,
- const void *buf, size_t nb)
- {
- int m = 0, rv = 0, looks_text = 0;
- @@ -327,6 +327,19 @@
- const char *ftype = NULL;
- char *rbuf = NULL;
- struct buffer b;
- + int fd = -1;
- +
- + if (stream) {
- +#ifdef _WIN64
- + php_socket_t _fd = fd;
- +#else
- + int _fd;
- +#endif
- + int _ret = php_stream_cast(stream, PHP_STREAM_AS_FD, (void **)&_fd, 0);
- + if (SUCCESS == _ret) {
- + fd = (int)_fd;
- + }
- + }
-
- buffer_init(&b, fd, st, buf, nb);
- ms->mode = b.st.st_mode;
- @@ -359,7 +372,8 @@
- }
- }
- #endif
- -#if HAVE_FORK
- +
- +#if PHP_FILEINFO_UNCOMPRESS
- /* try compression stuff */
- if ((ms->flags & MAGIC_NO_CHECK_COMPRESS) == 0) {
- m = file_zmagic(ms, &b, inname);
- @@ -484,10 +498,10 @@
- if (file_printf(ms, "%s", code_mime) == -1)
- rv = -1;
- }
- -#if HAVE_FORK
- +#if PHP_FILEINFO_UNCOMPRESS
- done_encoding:
- #endif
- - free(rbuf);
- + efree(rbuf);
- buffer_fini(&b);
- if (rv)
- return rv;
- @@ -505,7 +519,7 @@
- }
- file_clearbuf(ms);
- if (ms->o.pbuf) {
- - free(ms->o.pbuf);
- + efree(ms->o.pbuf);
- ms->o.pbuf = NULL;
- }
- ms->event_flags &= ~EVENT_HAD_ERR;
- @@ -543,7 +557,7 @@
- return NULL;
- }
- psize = len * 4 + 1;
- - if ((pbuf = CAST(char *, realloc(ms->o.pbuf, psize))) == NULL) {
- + if ((pbuf = CAST(char *, erealloc(ms->o.pbuf, psize))) == NULL) {
- file_oomem(ms, psize);
- return NULL;
- }
- @@ -607,8 +621,8 @@
- if (level >= ms->c.len) {
- len = (ms->c.len = 20 + level) * sizeof(*ms->c.li);
- ms->c.li = CAST(struct level_info *, (ms->c.li == NULL) ?
- - malloc(len) :
- - realloc(ms->c.li, len));
- + emalloc(len) :
- + erealloc(ms->c.li, len));
- if (ms->c.li == NULL) {
- file_oomem(ms, len);
- return -1;
- @@ -631,82 +645,38 @@
- protected int
- file_replace(struct magic_set *ms, const char *pat, const char *rep)
- {
- - file_regex_t rx;
- - int rc, rv = -1;
- -
- - rc = file_regcomp(&rx, pat, REG_EXTENDED);
- - if (rc) {
- - file_regerror(&rx, rc, ms);
- - } else {
- - regmatch_t rm;
- - int nm = 0;
- - while (file_regexec(&rx, ms->o.buf, 1, &rm, 0) == 0) {
- - ms->o.buf[rm.rm_so] = '\0';
- - if (file_printf(ms, "%s%s", rep,
- - rm.rm_eo != 0 ? ms->o.buf + rm.rm_eo : "") == -1)
- - goto out;
- - nm++;
- - }
- - rv = nm;
- + zend_string *pattern;
- + uint32_t opts = 0;
- + pcre_cache_entry *pce;
- + zend_string *res;
- + zend_string *repl;
- + size_t rep_cnt = 0;
- +
- + opts |= PCRE2_MULTILINE;
- + pattern = convert_libmagic_pattern((char*)pat, strlen(pat), opts);
- + if ((pce = pcre_get_compiled_regex_cache_ex(pattern, 0)) == NULL) {
- + zend_string_release(pattern);
- + rep_cnt = -1;
- + goto out;
- + }
- + zend_string_release(pattern);
- +
- + repl = zend_string_init(rep, strlen(rep), 0);
- + res = php_pcre_replace_impl(pce, NULL, ms->o.buf, strlen(ms->o.buf), repl, -1, &rep_cnt);
- +
- + zend_string_release_ex(repl, 0);
- + if (NULL == res) {
- + rep_cnt = -1;
- + goto out;
- }
- -out:
- - file_regfree(&rx);
- - return rv;
- -}
-
- -protected int
- -file_regcomp(file_regex_t *rx, const char *pat, int flags)
- -{
- -#ifdef USE_C_LOCALE
- - rx->c_lc_ctype = newlocale(LC_CTYPE_MASK, "C", 0);
- - assert(rx->c_lc_ctype != NULL);
- - rx->old_lc_ctype = uselocale(rx->c_lc_ctype);
- - assert(rx->old_lc_ctype != NULL);
- -#else
- - rx->old_lc_ctype = setlocale(LC_CTYPE, NULL);
- - assert(rx->old_lc_ctype != NULL);
- - rx->old_lc_ctype = strdup(rx->old_lc_ctype);
- - assert(rx->old_lc_ctype != NULL);
- - (void)setlocale(LC_CTYPE, "C");
- -#endif
- - rx->pat = pat;
- -
- - return rx->rc = regcomp(&rx->rx, pat, flags);
- -}
- -
- -protected int
- -file_regexec(file_regex_t *rx, const char *str, size_t nmatch,
- - regmatch_t* pmatch, int eflags)
- -{
- - assert(rx->rc == 0);
- - /* XXX: force initialization because glibc does not always do this */
- - if (nmatch != 0)
- - memset(pmatch, 0, nmatch * sizeof(*pmatch));
- - return regexec(&rx->rx, str, nmatch, pmatch, eflags);
- -}
- -
- -protected void
- -file_regfree(file_regex_t *rx)
- -{
- - if (rx->rc == 0)
- - regfree(&rx->rx);
- -#ifdef USE_C_LOCALE
- - (void)uselocale(rx->old_lc_ctype);
- - freelocale(rx->c_lc_ctype);
- -#else
- - (void)setlocale(LC_CTYPE, rx->old_lc_ctype);
- - free(rx->old_lc_ctype);
- -#endif
- -}
- + strncpy(ms->o.buf, ZSTR_VAL(res), ZSTR_LEN(res));
- + ms->o.buf[ZSTR_LEN(res)] = '\0';
-
- -protected void
- -file_regerror(file_regex_t *rx, int rc, struct magic_set *ms)
- -{
- - char errmsg[512];
- + zend_string_release_ex(res, 0);
-
- - (void)regerror(rc, &rx->rx, errmsg, sizeof(errmsg));
- - file_magerror(ms, "regex error %d for `%s', (%s)", rc, rx->pat,
- - errmsg);
- +out:
- + return rep_cnt;
- }
-
- protected file_pushbuf_t *
- @@ -717,7 +687,7 @@
- if (ms->event_flags & EVENT_HAD_ERR)
- return NULL;
-
- - if ((pb = (CAST(file_pushbuf_t *, malloc(sizeof(*pb))))) == NULL)
- + if ((pb = (CAST(file_pushbuf_t *, emalloc(sizeof(*pb))))) == NULL)
- return NULL;
-
- pb->buf = ms->o.buf;
- @@ -737,8 +707,8 @@
- char *rbuf;
-
- if (ms->event_flags & EVENT_HAD_ERR) {
- - free(pb->buf);
- - free(pb);
- + efree(pb->buf);
- + efree(pb);
- return NULL;
- }
-
- @@ -748,7 +718,7 @@
- ms->o.blen = pb->blen;
- ms->offset = pb->offset;
-
- - free(pb);
- + efree(pb);
- return rbuf;
- }
-
- @@ -809,6 +779,7 @@
- g->data4[6], g->data4[7]);
- }
-
- +#if 0
- protected int
- file_pipe_closexec(int *fds)
- {
- @@ -827,6 +798,7 @@
- file_clear_closexec(int fd) {
- return fcntl(fd, F_SETFD, 0);
- }
- +#endif
-
- protected char *
- file_strtrim(char *str)
- diff -u libmagic.orig/magic.c libmagic/magic.c
- --- libmagic.orig/magic.c 2021-02-23 01:49:06.000000000 +0100
- +++ libmagic/magic.c 2022-06-16 13:39:41.586609800 +0200
- @@ -25,11 +25,6 @@
- * SUCH DAMAGE.
- */
-
- -#ifdef WIN32
- -#include <windows.h>
- -#include <shlwapi.h>
- -#endif
- -
- #include "file.h"
-
- #ifndef lint
- @@ -39,10 +34,16 @@
- #include "magic.h"
-
- #include <stdlib.h>
- +#ifdef PHP_WIN32
- +#include "win32/unistd.h"
- +#else
- #include <unistd.h>
- +#endif
- #include <string.h>
- -#ifdef QUICK
- -#include <sys/mman.h>
- +#include "config.h"
- +
- +#ifdef PHP_WIN32
- +#include <shlwapi.h>
- #endif
- #include <limits.h> /* for PIPE_BUF */
-
- @@ -69,194 +70,18 @@
- #endif
- #endif
-
- -private void close_and_restore(const struct magic_set *, const char *, int,
- - const struct stat *);
- -private int unreadable_info(struct magic_set *, mode_t, const char *);
- -private const char* get_default_magic(void);
- -#ifndef COMPILE_ONLY
- -private const char *file_or_fd(struct magic_set *, const char *, int);
- +#ifdef PHP_WIN32
- +# undef S_IFLNK
- +# undef S_IFIFO
- #endif
-
- +private int unreadable_info(struct magic_set *, mode_t, const char *);
- +private const char *file_or_stream(struct magic_set *, const char *, php_stream *);
- +
- #ifndef STDIN_FILENO
- #define STDIN_FILENO 0
- #endif
-
- -#ifdef WIN32
- -/* HINSTANCE of this shared library. Needed for get_default_magic() */
- -static HINSTANCE _w32_dll_instance = NULL;
- -
- -static void
- -_w32_append_path(char **hmagicpath, const char *fmt, ...)
- -{
- - char *tmppath;
- - char *newpath;
- - va_list ap;
- -
- - va_start(ap, fmt);
- - if (vasprintf(&tmppath, fmt, ap) < 0) {
- - va_end(ap);
- - return;
- - }
- - va_end(ap);
- -
- - if (access(tmppath, R_OK) == -1)
- - goto out;
- -
- - if (*hmagicpath == NULL) {
- - *hmagicpath = tmppath;
- - return;
- - }
- -
- - if (asprintf(&newpath, "%s%c%s", *hmagicpath, PATHSEP, tmppath) < 0)
- - goto out;
- -
- - free(*hmagicpath);
- - free(tmppath);
- - *hmagicpath = newpath;
- - return;
- -out:
- - free(tmppath);
- -}
- -
- -static void
- -_w32_get_magic_relative_to(char **hmagicpath, HINSTANCE module)
- -{
- - static const char *trypaths[] = {
- - "%s/share/misc/magic.mgc",
- - "%s/magic.mgc",
- - };
- - LPSTR dllpath;
- - size_t sp;
- -
- - dllpath = calloc(MAX_PATH + 1, sizeof(*dllpath));
- -
- - if (!GetModuleFileNameA(module, dllpath, MAX_PATH))
- - goto out;
- -
- - PathRemoveFileSpecA(dllpath);
- -
- - if (module) {
- - char exepath[MAX_PATH];
- - GetModuleFileNameA(NULL, exepath, MAX_PATH);
- - PathRemoveFileSpecA(exepath);
- - if (stricmp(exepath, dllpath) == 0)
- - goto out;
- - }
- -
- - sp = strlen(dllpath);
- - if (sp > 3 && stricmp(&dllpath[sp - 3], "bin") == 0) {
- - _w32_append_path(hmagicpath,
- - "%s/../share/misc/magic.mgc", dllpath);
- - goto out;
- - }
- -
- - for (sp = 0; sp < __arraycount(trypaths); sp++)
- - _w32_append_path(hmagicpath, trypaths[sp], dllpath);
- -out:
- - free(dllpath);
- -}
- -
- -/* Placate GCC by offering a sacrificial previous prototype */
- -BOOL WINAPI DllMain(HINSTANCE, DWORD, LPVOID);
- -
- -BOOL WINAPI
- -DllMain(HINSTANCE hinstDLL, DWORD fdwReason,
- - LPVOID lpvReserved __attribute__((__unused__)))
- -{
- - if (fdwReason == DLL_PROCESS_ATTACH)
- - _w32_dll_instance = hinstDLL;
- - return 1;
- -}
- -#endif
- -
- -private const char *
- -get_default_magic(void)
- -{
- - static const char hmagic[] = "/.magic/magic.mgc";
- - static char *default_magic;
- - char *home, *hmagicpath;
- -
- -#ifndef WIN32
- - struct stat st;
- -
- - if (default_magic) {
- - free(default_magic);
- - default_magic = NULL;
- - }
- - if ((home = getenv("HOME")) == NULL)
- - return MAGIC;
- -
- - if (asprintf(&hmagicpath, "%s/.magic.mgc", home) < 0)
- - return MAGIC;
- - if (stat(hmagicpath, &st) == -1) {
- - free(hmagicpath);
- - if (asprintf(&hmagicpath, "%s/.magic", home) < 0)
- - return MAGIC;
- - if (stat(hmagicpath, &st) == -1)
- - goto out;
- - if (S_ISDIR(st.st_mode)) {
- - free(hmagicpath);
- - if (asprintf(&hmagicpath, "%s/%s", home, hmagic) < 0)
- - return MAGIC;
- - if (access(hmagicpath, R_OK) == -1)
- - goto out;
- - }
- - }
- -
- - if (asprintf(&default_magic, "%s:%s", hmagicpath, MAGIC) < 0)
- - goto out;
- - free(hmagicpath);
- - return default_magic;
- -out:
- - default_magic = NULL;
- - free(hmagicpath);
- - return MAGIC;
- -#else
- - hmagicpath = NULL;
- -
- - if (default_magic) {
- - free(default_magic);
- - default_magic = NULL;
- - }
- -
- - /* First, try to get a magic file from user-application data */
- - if ((home = getenv("LOCALAPPDATA")) != NULL)
- - _w32_append_path(&hmagicpath, "%s%s", home, hmagic);
- -
- - /* Second, try to get a magic file from the user profile data */
- - if ((home = getenv("USERPROFILE")) != NULL)
- - _w32_append_path(&hmagicpath,
- - "%s/Local Settings/Application Data%s", home, hmagic);
- -
- - /* Third, try to get a magic file from Common Files */
- - if ((home = getenv("COMMONPROGRAMFILES")) != NULL)
- - _w32_append_path(&hmagicpath, "%s%s", home, hmagic);
- -
- - /* Fourth, try to get magic file relative to exe location */
- - _w32_get_magic_relative_to(&hmagicpath, NULL);
- -
- - /* Fifth, try to get magic file relative to dll location */
- - _w32_get_magic_relative_to(&hmagicpath, _w32_dll_instance);
- -
- - /* Avoid MAGIC constant - it likely points to a file within MSys tree */
- - default_magic = hmagicpath;
- - return default_magic;
- -#endif
- -}
- -
- -public const char *
- -magic_getpath(const char *magicfile, int action)
- -{
- - if (magicfile != NULL)
- - return magicfile;
- -
- - magicfile = getenv("MAGIC");
- - if (magicfile != NULL)
- - return magicfile;
- -
- - return action == FILE_LOAD ? get_default_magic() : MAGIC;
- -}
- -
- public struct magic_set *
- magic_open(int flags)
- {
- @@ -302,21 +127,6 @@
- return file_apprentice(ms, magicfile, FILE_LOAD);
- }
-
- -#ifndef COMPILE_ONLY
- -/*
- - * Install a set of compiled magic buffers.
- - */
- -public int
- -magic_load_buffers(struct magic_set *ms, void **bufs, size_t *sizes,
- - size_t nbufs)
- -{
- - if (ms == NULL)
- - return -1;
- - return buffer_apprentice(ms, RCAST(struct magic **, bufs),
- - sizes, nbufs);
- -}
- -#endif
- -
- public int
- magic_compile(struct magic_set *ms, const char *magicfile)
- {
- @@ -341,39 +151,6 @@
- return file_apprentice(ms, magicfile, FILE_LIST);
- }
-
- -private void
- -close_and_restore(const struct magic_set *ms, const char *name, int fd,
- - const struct stat *sb)
- -{
- - if (fd == STDIN_FILENO || name == NULL)
- - return;
- - (void) close(fd);
- -
- - if ((ms->flags & MAGIC_PRESERVE_ATIME) != 0) {
- - /*
- - * Try to restore access, modification times if read it.
- - * This is really *bad* because it will modify the status
- - * time of the file... And of course this will affect
- - * backup programs
- - */
- -#ifdef HAVE_UTIMES
- - struct timeval utsbuf[2];
- - (void)memset(utsbuf, 0, sizeof(utsbuf));
- - utsbuf[0].tv_sec = sb->st_atime;
- - utsbuf[1].tv_sec = sb->st_mtime;
- -
- - (void) utimes(name, utsbuf); /* don't care if loses */
- -#elif defined(HAVE_UTIME_H) || defined(HAVE_SYS_UTIME_H)
- - struct utimbuf utbuf;
- -
- - (void)memset(&utbuf, 0, sizeof(utbuf));
- - utbuf.actime = sb->st_atime;
- - utbuf.modtime = sb->st_mtime;
- - (void) utime(name, &utbuf); /* don't care if loses */
- -#endif
- - }
- -}
- -
- #ifndef COMPILE_ONLY
-
- /*
- @@ -384,7 +161,7 @@
- {
- if (ms == NULL)
- return NULL;
- - return file_or_fd(ms, NULL, fd);
- + return file_or_stream(ms, NULL, NULL);
- }
-
- /*
- @@ -395,19 +172,25 @@
- {
- if (ms == NULL)
- return NULL;
- - return file_or_fd(ms, inname, STDIN_FILENO);
- + return file_or_stream(ms, inname, NULL);
- +}
- +
- +public const char *
- +magic_stream(struct magic_set *ms, php_stream *stream)
- +{
- + if (ms == NULL)
- + return NULL;
- + return file_or_stream(ms, NULL, stream);
- }
-
- private const char *
- -file_or_fd(struct magic_set *ms, const char *inname, int fd)
- +file_or_stream(struct magic_set *ms, const char *inname, php_stream *stream)
- {
- int rv = -1;
- unsigned char *buf;
- - struct stat sb;
- + zend_stat_t sb;
- ssize_t nbytes = 0; /* number of bytes read from a datafile */
- - int ispipe = 0;
- - int okstat = 0;
- - off_t pos = CAST(off_t, -1);
- + int no_in_stream = 0;
-
- if (file_reset(ms, 1) == -1)
- goto out;
- @@ -417,7 +200,7 @@
- * some overlapping space for matches near EOF
- */
- #define SLOP (1 + sizeof(union VALUETYPE))
- - if ((buf = CAST(unsigned char *, malloc(ms->bytes_max + SLOP))) == NULL)
- + if ((buf = CAST(unsigned char *, emalloc(ms->bytes_max + SLOP))) == NULL)
- return NULL;
-
- switch (file_fsmagic(ms, inname, &sb)) {
- @@ -430,98 +213,46 @@
- goto done;
- }
-
- -#ifdef WIN32
- - /* Place stdin in binary mode, so EOF (Ctrl+Z) doesn't stop early. */
- - if (fd == STDIN_FILENO)
- - _setmode(STDIN_FILENO, O_BINARY);
- -#endif
- - if (inname != NULL) {
- - int flags = O_RDONLY|O_BINARY|O_NONBLOCK|O_CLOEXEC;
- - errno = 0;
- - if ((fd = open(inname, flags)) < 0) {
- - okstat = stat(inname, &sb) == 0;
- - if (okstat && S_ISFIFO(sb.st_mode))
- - ispipe = 1;
- -#ifdef WIN32
- - /*
- - * Can't stat, can't open. It may have been opened in
- - * fsmagic, so if the user doesn't have read permission,
- - * allow it to say so; otherwise an error was probably
- - * displayed in fsmagic.
- - */
- - if (!okstat && errno == EACCES) {
- - sb.st_mode = S_IFBLK;
- - okstat = 1;
- - }
- -#endif
- - if (okstat &&
- - unreadable_info(ms, sb.st_mode, inname) == -1)
- + errno = 0;
- +
- + if (inname && !stream) {
- + no_in_stream = 1;
- + stream = php_stream_open_wrapper((char *)inname, "rb", REPORT_ERRORS, NULL);
- + if (!stream) {
- + if (unreadable_info(ms, sb.st_mode, inname) == -1)
- goto done;
- - rv = 0;
- + rv = -1;
- goto done;
- }
- -#if O_CLOEXEC == 0
- - (void)fcntl(fd, F_SETFD, FD_CLOEXEC);
- -#endif
- }
-
- - if (fd != -1) {
- - okstat = fstat(fd, &sb) == 0;
- - if (okstat && S_ISFIFO(sb.st_mode))
- - ispipe = 1;
- - if (inname == NULL)
- - pos = lseek(fd, CAST(off_t, 0), SEEK_CUR);
- + php_stream_statbuf ssb;
- + if (php_stream_stat(stream, &ssb) < 0) {
- + if (ms->flags & MAGIC_ERROR) {
- + file_error(ms, errno, "cannot stat `%s'", inname);
- + rv = -1;
- + goto done;
- + }
- }
- + memcpy(&sb, &ssb.sb, sizeof(zend_stat_t));
-
- /*
- * try looking at the first ms->bytes_max bytes
- */
- - if (ispipe) {
- - if (fd != -1) {
- - ssize_t r = 0;
- -
- - while ((r = sread(fd, RCAST(void *, &buf[nbytes]),
- - CAST(size_t, ms->bytes_max - nbytes), 1)) > 0) {
- - nbytes += r;
- - if (r < PIPE_BUF) break;
- - }
- - }
- -
- - if (nbytes == 0 && inname) {
- - /* We can not read it, but we were able to stat it. */
- - if (unreadable_info(ms, sb.st_mode, inname) == -1)
- - goto done;
- - rv = 0;
- - goto done;
- - }
- -
- - } else if (fd != -1) {
- - /* Windows refuses to read from a big console buffer. */
- - size_t howmany =
- -#if defined(WIN32)
- - _isatty(fd) ? 8 * 1024 :
- -#endif
- - ms->bytes_max;
- - if ((nbytes = read(fd, RCAST(void *, buf), howmany)) == -1) {
- - if (inname == NULL && fd != STDIN_FILENO)
- - file_error(ms, errno, "cannot read fd %d", fd);
- - else
- - file_error(ms, errno, "cannot read `%s'",
- - inname == NULL ? "/dev/stdin" : inname);
- - goto done;
- - }
- + if ((nbytes = php_stream_read(stream, (char *)buf, ms->bytes_max - nbytes)) < 0) {
- + file_error(ms, errno, "cannot read `%s'", inname);
- + goto done;
- }
-
- (void)memset(buf + nbytes, 0, SLOP); /* NUL terminate */
- - if (file_buffer(ms, fd, okstat ? &sb : NULL, inname, buf, CAST(size_t, nbytes)) == -1)
- + if (file_buffer(ms, stream, &sb, inname, buf, CAST(size_t, nbytes)) == -1)
- goto done;
- rv = 0;
- done:
- - free(buf);
- - if (fd != -1) {
- - if (pos != CAST(off_t, -1))
- - (void)lseek(fd, pos, SEEK_SET);
- - close_and_restore(ms, inname, fd, &sb);
- + efree(buf);
- +
- + if (no_in_stream && stream) {
- + php_stream_close(stream);
- }
- out:
- return rv == 0 ? file_getbuffer(ms) : NULL;
- @@ -539,7 +270,7 @@
- * The main work is done here!
- * We have the file name and/or the data buffer to be identified.
- */
- - if (file_buffer(ms, -1, NULL, NULL, buf, nb) == -1) {
- + if (file_buffer(ms, NULL, NULL, NULL, buf, nb) == -1) {
- return NULL;
- }
- return file_getbuffer(ms);
- diff -u libmagic.orig/magic.h libmagic/magic.h
- --- libmagic.orig/magic.h 2022-06-30 17:16:06.144009900 +0200
- +++ libmagic/magic.h 2022-06-16 13:39:41.586609800 +0200
- @@ -126,6 +126,7 @@
-
- const char *magic_getpath(const char *, int);
- const char *magic_file(magic_t, const char *);
- +const char *magic_stream(magic_t, php_stream *);
- const char *magic_descriptor(magic_t, int);
- const char *magic_buffer(magic_t, const void *, size_t);
-
- diff -u libmagic.orig/print.c libmagic/print.c
- --- libmagic.orig/print.c 2021-02-23 01:49:07.000000000 +0100
- +++ libmagic/print.c 2021-09-21 13:27:27.998388700 +0200
- @@ -28,6 +28,7 @@
- /*
- * print.c - debugging printout routines
- */
- +#include "php.h"
-
- #include "file.h"
-
- @@ -73,7 +74,7 @@
- if (m->mask_op & FILE_OPINVERSE)
- (void) fputc('~', stderr);
-
- - if (IS_STRING(m->type)) {
- + if (IS_LIBMAGIC_STRING(m->type)) {
- if (m->str_flags) {
- (void) fputc('/', stderr);
- if (m->str_flags & STRING_COMPACT_WHITESPACE)
- @@ -225,18 +226,18 @@
- file_magwarn(struct magic_set *ms, const char *f, ...)
- {
- va_list va;
- + char *expanded_format = NULL;
- + int expanded_len;
-
- - /* cuz we use stdout for most, stderr here */
- - (void) fflush(stdout);
- -
- - if (ms->file)
- - (void) fprintf(stderr, "%s, %lu: ", ms->file,
- - CAST(unsigned long, ms->line));
- - (void) fprintf(stderr, "Warning: ");
- va_start(va, f);
- - (void) vfprintf(stderr, f, va);
- + expanded_len = vasprintf(&expanded_format, f, va);
- va_end(va);
- - (void) fputc('\n', stderr);
- +
- + if (expanded_len >= 0 && expanded_format) {
- + php_error_docref(NULL, E_WARNING, "%s", expanded_format);
- +
- + free(expanded_format);
- + }
- }
-
- protected const char *
- @@ -257,13 +258,13 @@
- }
-
- if (flags & FILE_T_LOCAL) {
- - tm = localtime_r(&t, &tmz);
- + tm = php_localtime_r(&t, &tmz);
- } else {
- - tm = gmtime_r(&t, &tmz);
- + tm = php_gmtime_r(&t, &tmz);
- }
- if (tm == NULL)
- goto out;
- - pp = asctime_r(tm, buf);
- + pp = php_asctime_r(tm, buf);
-
- if (pp == NULL)
- goto out;
- diff -u libmagic.orig/readcdf.c libmagic/readcdf.c
- --- libmagic.orig/readcdf.c 2021-02-23 01:49:08.000000000 +0100
- +++ libmagic/readcdf.c 2021-09-21 13:27:27.999369100 +0200
- @@ -31,7 +31,11 @@
-
- #include <assert.h>
- #include <stdlib.h>
- +#ifdef PHP_WIN32
- +#include "win32/unistd.h"
- +#else
- #include <unistd.h>
- +#endif
- #include <string.h>
- #include <time.h>
- #include <ctype.h>
- @@ -100,10 +104,6 @@
- if (clsid[0] == cv[i].clsid[0] && clsid[1] == cv[i].clsid[1])
- return cv[i].mime;
- }
- -#ifdef CDF_DEBUG
- - fprintf(stderr, "unknown mime %" PRIx64 ", %" PRIx64 "\n", clsid[0],
- - clsid[1]);
- -#endif
- return NULL;
- }
-
- @@ -112,35 +112,24 @@
- {
- size_t i;
- const char *rv = NULL;
- -#ifdef USE_C_LOCALE
- - locale_t old_lc_ctype, c_lc_ctype;
- + char *vbuf_lower;
-
- - c_lc_ctype = newlocale(LC_CTYPE_MASK, "C", 0);
- - assert(c_lc_ctype != NULL);
- - old_lc_ctype = uselocale(c_lc_ctype);
- - assert(old_lc_ctype != NULL);
- -#else
- - char *old_lc_ctype = setlocale(LC_CTYPE, NULL);
- - assert(old_lc_ctype != NULL);
- - old_lc_ctype = strdup(old_lc_ctype);
- - assert(old_lc_ctype != NULL);
- - (void)setlocale(LC_CTYPE, "C");
- -#endif
- - for (i = 0; nv[i].pattern != NULL; i++)
- - if (strcasestr(vbuf, nv[i].pattern) != NULL) {
- + vbuf_lower = zend_str_tolower_dup(vbuf, strlen(vbuf));
- + for (i = 0; nv[i].pattern != NULL; i++) {
- + char *pattern_lower;
- + int found;
- +
- + pattern_lower = zend_str_tolower_dup(nv[i].pattern, strlen(nv[i].pattern));
- + found = (strstr(vbuf_lower, pattern_lower) != NULL);
- + efree(pattern_lower);
- +
- + if (found) {
- rv = nv[i].mime;
- break;
- }
- -#ifdef CDF_DEBUG
- - fprintf(stderr, "unknown app %s\n", vbuf);
- -#endif
- -#ifdef USE_C_LOCALE
- - (void)uselocale(old_lc_ctype);
- - freelocale(c_lc_ctype);
- -#else
- - (void)setlocale(LC_CTYPE, old_lc_ctype);
- - free(old_lc_ctype);
- -#endif
- + }
- +
- + efree(vbuf_lower);
- return rv;
- }
-
- @@ -156,7 +145,9 @@
- const char *s, *e;
- int len;
-
- - if (!NOTMIME(ms) && root_storage)
- + memset(&ts, 0, sizeof(ts));
- +
- + if (!NOTMIME(ms) && root_storage)
- str = cdf_clsid_to_mime(root_storage->d_storage_uuid,
- clsid2mime);
-
- @@ -282,10 +273,10 @@
- if (file_printf(ms, "%s%s",
- cdf_u16tos8(buf, ce[i].ce_namlen, ce[i].ce_name),
- i == cat->cat_num - 1 ? "]" : ", ") == -1) {
- - free(cat);
- + efree(cat);
- return -1;
- }
- - free(cat);
- + efree(cat);
- } else if (ms->flags & MAGIC_MIME_TYPE) {
- if (file_printf(ms, "application/CDFV2") == -1)
- return -1;
- @@ -346,7 +337,7 @@
- }
-
- m = cdf_file_property_info(ms, info, count, root_storage);
- - free(info);
- + efree(info);
-
- return m == -1 ? -2 : m;
- }
- @@ -656,11 +647,11 @@
- cdf_zero_stream(&scn);
- cdf_zero_stream(&sst);
- out3:
- - free(dir.dir_tab);
- + efree(dir.dir_tab);
- out2:
- - free(ssat.sat_tab);
- + efree(ssat.sat_tab);
- out1:
- - free(sat.sat_tab);
- + efree(sat.sat_tab);
- out0:
- /* If we handled it already, return */
- if (i != -1)
- diff -u libmagic.orig/softmagic.c libmagic/softmagic.c
- --- libmagic.orig/softmagic.c 2021-02-23 01:49:06.000000000 +0100
- +++ libmagic/softmagic.c 2022-06-30 16:58:15.521661800 +0200
- @@ -43,6 +43,10 @@
- #include <time.h>
- #include "der.h"
-
- +#ifndef PREG_OFFSET_CAPTURE
- +# define PREG_OFFSET_CAPTURE (1<<8)
- +#endif
- +
- private int match(struct magic_set *, struct magic *, uint32_t,
- const struct buffer *, size_t, int, int, int, uint16_t *,
- uint16_t *, int *, int *, int *, int *);
- @@ -139,8 +143,8 @@
- return 0;
- }
-
- -#define FILE_FMTDEBUG
- -#ifdef FILE_FMTDEBUG
- +
- +#if defined(FILE_FMTDEBUG) && defined(HAVE_FMTCHECK)
- #define F(a, b, c) file_fmtcheck((a), (b), (c), __FILE__, __LINE__)
-
- private const char * __attribute__((__format_arg__(3)))
- @@ -159,10 +163,14 @@
- " with `%s'", file, line, desc, def);
- return ptr;
- }
- -#else
- +#elif defined(HAVE_FMTCHECK)
- #define F(a, b, c) fmtcheck((b), (c))
- +#else
- +#define F(a, b, c) ((b))
- #endif
-
- +/* NOTE this function has been kept an the state of 5.39 for BC. Observe
- + * further as the upgrade to 5.41 or above goes. */
- /*
- * Go through the whole list, stopping if you find a match. Process all
- * the continuations of that match before returning.
- @@ -222,7 +230,7 @@
- struct magic *m = &magic[magindex];
-
- if (m->type != FILE_NAME)
- - if ((IS_STRING(m->type) &&
- + if ((IS_LIBMAGIC_STRING(m->type) &&
- #define FLT (STRING_BINTEST | STRING_TEXTTEST)
- ((text && (m->str_flags & FLT) == STRING_BINTEST) ||
- (!text && (m->str_flags & FLT) == STRING_TEXTTEST))) ||
- @@ -277,9 +285,11 @@
- goto flush;
- }
-
- + if (*m->desc)
- + *found_match = 1;
- +
- if ((e = handle_annotation(ms, m, firstline)) != 0)
- {
- - *found_match = 1;
- *need_separator = 1;
- *printed_something = 1;
- *returnval = 1;
- @@ -290,17 +300,14 @@
- * If we are going to print something, we'll need to print
- * a blank before we print something else.
- */
- - if (*m->desc) {
- - *found_match = 1;
- + if (print && *m->desc) {
- + *need_separator = 1;
- + *printed_something = 1;
- *returnval = 1;
- - if (print) {
- - *need_separator = 1;
- - *printed_something = 1;
- - if (print_sep(ms, firstline) == -1)
- - return -1;
- - if (mprint(ms, m) == -1)
- - return -1;
- - }
- + if (print_sep(ms, firstline) == -1)
- + return -1;
- + if (mprint(ms, m) == -1)
- + return -1;
- }
-
- switch (moffset(ms, m, &bb, &ms->c.li[cont_level].off)) {
- @@ -391,18 +398,16 @@
- } else
- ms->c.li[cont_level].got_match = 1;
-
- + if (*m->desc)
- + *found_match = 1;
- +
- if ((e = handle_annotation(ms, m, firstline))
- != 0) {
- - *found_match = 1;
- *need_separator = 1;
- *printed_something = 1;
- *returnval = 1;
- return e;
- }
- - if (*m->desc) {
- - *found_match = 1;
- - *returnval = 1;
- - }
- if (print && *m->desc) {
- /*
- * This continuation matched. Print
- @@ -427,6 +432,7 @@
- if (file_printf(ms, " ") == -1)
- return -1;
- }
- + *returnval = 1;
- *need_separator = 0;
- if (mprint(ms, m) == -1)
- return -1;
- @@ -458,43 +464,39 @@
- firstline = 0;
- }
- if (*found_match) {
- - if ((ms->flags & MAGIC_CONTINUE) == 0)
- - goto out;
- - // So that we print a separator
- - *printed_something = 0;
- - firstline = 0;
- + if ((ms->flags & MAGIC_CONTINUE) == 0)
- + return *returnval; /* don't keep searching */
- + // So that we print a separator
- + *printed_something = 0;
- + firstline = 0;
- }
- cont_level = 0;
- }
- -out:
- - /*
- - * If we are not printing (we are doing mime etc.)
- - * and we did not find a mime entry, and we are at 0 level
- - * we want to return 0 so that the default mime printer
- - * takes over and prints "application/octet-stream"
- - */
- - if (! print && ! *printed_something && ! *name_count)
- - return 0;
- return *returnval; /* This is hit if -k is set or there is no match */
- }
-
- private int
- check_fmt(struct magic_set *ms, const char *fmt)
- {
- - file_regex_t rx;
- - int rc, rv = -1;
- + pcre_cache_entry *pce;
- + int rv = -1;
- + zend_string *pattern;
-
- if (strchr(fmt, '%') == NULL)
- return 0;
-
- - rc = file_regcomp(&rx, "%[-0-9\\.]*s", REG_EXTENDED|REG_NOSUB);
- - if (rc) {
- - file_regerror(&rx, rc, ms);
- + pattern = zend_string_init("~%[-0-9\\.]*s~", sizeof("~%[-0-9\\.]*s~") - 1, 0);
- + if ((pce = pcre_get_compiled_regex_cache_ex(pattern, 0)) == NULL) {
- + rv = -1;
- } else {
- - rc = file_regexec(&rx, fmt, 0, 0, 0);
- - rv = !rc;
- + pcre2_code *re = php_pcre_pce_re(pce);
- + pcre2_match_data *match_data = php_pcre_create_match_data(0, re);
- + if (match_data) {
- + rv = pcre2_match(re, (PCRE2_SPTR)fmt, strlen(fmt), 0, 0, match_data, php_pcre_mctx()) > 0;
- + php_pcre_free_match_data(match_data);
- + }
- }
- - file_regfree(&rx);
- + zend_string_release(pattern);
- return rv;
- }
-
- @@ -1531,11 +1533,7 @@
- size_t len;
- *c = ms->c;
- len = c->len * sizeof(*c->li);
- - ms->c.li = CAST(struct level_info *, malloc(len));
- - if (ms->c.li == NULL) {
- - ms->c = *c;
- - return -1;
- - }
- + ms->c.li = CAST(struct level_info *, emalloc(len));
- memcpy(ms->c.li, c->li, len);
- return 0;
- }
- @@ -1543,7 +1541,7 @@
- private void
- restore_cont(struct magic_set *ms, struct cont *c)
- {
- - free(ms->c.li);
- + efree(ms->c.li);
- ms->c = *c;
- }
-
- @@ -1845,15 +1843,15 @@
- if ((ms->flags & MAGIC_NODESC) == 0 &&
- file_printf(ms, F(ms, m->desc, "%u"), offset) == -1)
- {
- - free(rbuf);
- + if (rbuf) efree(rbuf);
- return -1;
- }
- if (file_printf(ms, "%s", rbuf) == -1) {
- - free(rbuf);
- + if (rbuf) efree(rbuf);
- return -1;
- }
- }
- - free(rbuf);
- + if (rbuf) efree(rbuf);
- return rv;
-
- case FILE_USE:
- @@ -1958,10 +1956,13 @@
- }
- else if ((flags & STRING_COMPACT_WHITESPACE) &&
- isspace(*a)) {
- + /* XXX Dirty. The data and the pattern is what is causing this.
- + Revert _i for the next port and see if it still matters. */
- + uint32_t _i = 0;
- a++;
- if (isspace(*b++)) {
- if (!isspace(*a))
- - while (b < eb && isspace(*b))
- + while (EXPECTED(_i++ < 2048) && b < eb && isspace(*b))
- b++;
- }
- else {
- @@ -1997,6 +1998,60 @@
- return file_strncmp(a, b, len, maxlen, flags);
- }
-
- +public zend_string* convert_libmagic_pattern(const char *val, size_t len, uint32_t options)
- +{
- + int i, j;
- + zend_string *t;
- +
- + for (i = j = 0; i < len; i++) {
- + switch (val[i]) {
- + case '~':
- + j += 2;
- + break;
- + case '\0':
- + j += 4;
- + break;
- + default:
- + j++;
- + break;
- + }
- + }
- + t = zend_string_alloc(j + 4, 0);
- +
- + j = 0;
- + ZSTR_VAL(t)[j++] = '~';
- +
- + for (i = 0; i < len; i++, j++) {
- + switch (val[i]) {
- + case '~':
- + ZSTR_VAL(t)[j++] = '\\';
- + ZSTR_VAL(t)[j] = '~';
- + break;
- + case '\0':
- + ZSTR_VAL(t)[j++] = '\\';
- + ZSTR_VAL(t)[j++] = 'x';
- + ZSTR_VAL(t)[j++] = '0';
- + ZSTR_VAL(t)[j] = '0';
- + break;
- + default:
- + ZSTR_VAL(t)[j] = val[i];
- + break;
- + }
- + }
- + ZSTR_VAL(t)[j++] = '~';
- +
- + if (options & PCRE2_CASELESS)
- + ZSTR_VAL(t)[j++] = 'i';
- +
- + if (options & PCRE2_MULTILINE)
- + ZSTR_VAL(t)[j++] = 'm';
- +
- + ZSTR_VAL(t)[j]='\0';
- + ZSTR_LEN(t) = j;
- +
- + return t;
- +}
- +
- private int
- magiccheck(struct magic_set *ms, struct magic *m)
- {
- @@ -2176,65 +2231,77 @@
- break;
- }
- case FILE_REGEX: {
- - int rc;
- - file_regex_t rx;
- - const char *search;
- + zend_string *pattern;
- + uint32_t options = 0;
- + pcre_cache_entry *pce;
-
- - if (ms->search.s == NULL)
- - return 0;
- + options |= PCRE2_MULTILINE;
-
- - l = 0;
- - rc = file_regcomp(&rx, m->value.s,
- - REG_EXTENDED|REG_NEWLINE|
- - ((m->str_flags & STRING_IGNORE_CASE) ? REG_ICASE : 0));
- - if (rc) {
- - file_regerror(&rx, rc, ms);
- - v = CAST(uint64_t, -1);
- + if (m->str_flags & STRING_IGNORE_CASE) {
- + options |= PCRE2_CASELESS;
- + }
- +
- + pattern = convert_libmagic_pattern((char *)m->value.s, m->vallen, options);
- +
- + l = v = 0;
- + if ((pce = pcre_get_compiled_regex_cache(pattern)) == NULL) {
- + zend_string_release(pattern);
- + return -1;
- } else {
- - regmatch_t pmatch;
- - size_t slen = ms->search.s_len;
- - char *copy;
- - if (slen != 0) {
- - copy = CAST(char *, malloc(slen));
- - if (copy == NULL) {
- - file_regfree(&rx);
- - file_error(ms, errno,
- - "can't allocate %" SIZE_T_FORMAT "u bytes",
- - slen);
- + /* pce now contains the compiled regex */
- + zval retval;
- + zval subpats;
- + zend_string *haystack;
- +
- + ZVAL_NULL(&retval);
- + ZVAL_NULL(&subpats);
- +
- + /* Cut the search len from haystack, equals to REG_STARTEND */
- + haystack = zend_string_init(ms->search.s, ms->search.s_len, 0);
- +
- + /* match v = 0, no match v = 1 */
- + php_pcre_match_impl(pce, haystack, &retval, &subpats, 0, 1, PREG_OFFSET_CAPTURE, 0);
- + /* Free haystack */
- + zend_string_release(haystack);
- +
- + if (Z_LVAL(retval) < 0) {
- + zval_ptr_dtor(&subpats);
- + zend_string_release(pattern);
- return -1;
- - }
- - memcpy(copy, ms->search.s, slen);
- - copy[--slen] = '\0';
- - search = copy;
- + } else if ((Z_LVAL(retval) > 0) && (Z_TYPE(subpats) == IS_ARRAY)) {
- + /* Need to fetch global match which equals pmatch[0] */
- + zval *pzval;
- + HashTable *ht = Z_ARRVAL(subpats);
- + if ((pzval = zend_hash_index_find(ht, 0)) != NULL && Z_TYPE_P(pzval) == IS_ARRAY) {
- + /* If everything goes according to the master plan
- + tmpcopy now contains two elements:
- + 0 = the match
- + 1 = starting position of the match */
- + zval *match, *offset;
- + if ((match = zend_hash_index_find(Z_ARRVAL_P(pzval), 0)) &&
- + (offset = zend_hash_index_find(Z_ARRVAL_P(pzval), 1))) {
- + if (Z_TYPE_P(match) != IS_STRING && Z_TYPE_P(offset) != IS_LONG) {
- + goto error_out;
- + }
- + ms->search.s += Z_LVAL_P(offset); /* this is where the match starts */
- + ms->search.offset += Z_LVAL_P(offset); /* this is where the match starts as size_t */
- + ms->search.rm_len = Z_STRLEN_P(match) /* This is the length of the matched pattern */;
- + v = 0;
- + } else {
- + goto error_out;
- + }
- + } else {
- +error_out:
- + zval_ptr_dtor(&subpats);
- + zend_string_release(pattern);
- + return -1;
- + }
- } else {
- - search = CCAST(char *, "");
- - copy = NULL;
- - }
- - rc = file_regexec(&rx, RCAST(const char *, search),
- - 1, &pmatch, 0);
- - free(copy);
- - switch (rc) {
- - case 0:
- - ms->search.s += CAST(int, pmatch.rm_so);
- - ms->search.offset += CAST(size_t, pmatch.rm_so);
- - ms->search.rm_len = CAST(size_t,
- - pmatch.rm_eo - pmatch.rm_so);
- - v = 0;
- - break;
- -
- - case REG_NOMATCH:
- v = 1;
- - break;
- -
- - default:
- - file_regerror(&rx, rc, ms);
- - v = CAST(uint64_t, -1);
- - break;
- }
- + zval_ptr_dtor(&subpats);
- + zend_string_release(pattern);
- }
- - file_regfree(&rx);
- - if (v == CAST(uint64_t, -1))
- - return -1;
- break;
- }
- case FILE_USE:
- diff -u libmagic.orig/strcasestr.c libmagic/strcasestr.c
- --- libmagic.orig/strcasestr.c 2021-02-23 01:49:12.000000000 +0100
- +++ libmagic/strcasestr.c 2021-09-21 13:27:28.002306200 +0200
- @@ -39,6 +39,8 @@
-
- #include "file.h"
-
- +#include "php_stdint.h"
- +
- #include <assert.h>
- #include <ctype.h>
- #include <string.h>
|