libmagic.patch 86 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507
  1. diff -u libmagic.orig/apprentice.c libmagic/apprentice.c
  2. --- libmagic.orig/apprentice.c 2021-02-23 01:51:11.000000000 +0100
  3. +++ libmagic/apprentice.c 2022-06-16 13:39:41.570984700 +0200
  4. @@ -29,6 +29,8 @@
  5. * apprentice - make one pass through /etc/magic, learning its secrets.
  6. */
  7. +#include "php.h"
  8. +
  9. #include "file.h"
  10. #ifndef lint
  11. @@ -37,19 +39,33 @@
  12. #include "magic.h"
  13. #include <stdlib.h>
  14. +
  15. +#if defined(__hpux) && !defined(HAVE_STRTOULL)
  16. +#if SIZEOF_LONG == 8
  17. +# define strtoull strtoul
  18. +#else
  19. +# define strtoull __strtoull
  20. +#endif
  21. +#endif
  22. +
  23. +#ifdef PHP_WIN32
  24. +#include "win32/unistd.h"
  25. +#define strtoull _strtoui64
  26. +#else
  27. #ifdef HAVE_UNISTD_H
  28. #include <unistd.h>
  29. #endif
  30. -#include <stddef.h>
  31. +#endif
  32. #include <string.h>
  33. #include <assert.h>
  34. #include <ctype.h>
  35. #include <fcntl.h>
  36. -#ifdef QUICK
  37. -#include <sys/mman.h>
  38. +
  39. +#ifndef SSIZE_MAX
  40. +#define MAXMAGIC_SIZE ((ssize_t)0x7fffffff)
  41. +#else
  42. +#define MAXMAGIC_SIZE SSIZE_MAX
  43. #endif
  44. -#include <dirent.h>
  45. -#include <limits.h>
  46. #define EATAB {while (isascii(CAST(unsigned char, *l)) && \
  47. @@ -66,6 +82,10 @@
  48. #endif
  49. #endif
  50. +#ifndef offsetof
  51. +#define offsetof(STRUCTURE,FIELD) ((int)((char*)&((STRUCTURE*)0)->FIELD))
  52. +#endif
  53. +
  54. #ifndef MAP_FAILED
  55. #define MAP_FAILED (void *) -1
  56. #endif
  57. @@ -128,10 +148,7 @@
  58. private uint32_t swap4(uint32_t);
  59. private uint64_t swap8(uint64_t);
  60. private char *mkdbname(struct magic_set *, const char *, int);
  61. -private struct magic_map *apprentice_buf(struct magic_set *, struct magic *,
  62. - size_t);
  63. private struct magic_map *apprentice_map(struct magic_set *, const char *);
  64. -private int check_buffer(struct magic_set *, struct magic_map *, const char *);
  65. private void apprentice_unmap(struct magic_map *);
  66. private int apprentice_compile(struct magic_set *, struct magic_map *,
  67. const char *);
  68. @@ -167,38 +184,7 @@
  69. { NULL, 0, NULL }
  70. };
  71. -#ifdef COMPILE_ONLY
  72. -
  73. -int main(int, char *[]);
  74. -
  75. -int
  76. -main(int argc, char *argv[])
  77. -{
  78. - int ret;
  79. - struct magic_set *ms;
  80. - char *progname;
  81. -
  82. - if ((progname = strrchr(argv[0], '/')) != NULL)
  83. - progname++;
  84. - else
  85. - progname = argv[0];
  86. -
  87. - if (argc != 2) {
  88. - (void)fprintf(stderr, "Usage: %s file\n", progname);
  89. - return 1;
  90. - }
  91. -
  92. - if ((ms = magic_open(MAGIC_CHECK)) == NULL) {
  93. - (void)fprintf(stderr, "%s: %s\n", progname, strerror(errno));
  94. - return 1;
  95. - }
  96. - ret = magic_compile(ms, argv[1]) == -1 ? 1 : 0;
  97. - if (ret == 1)
  98. - (void)fprintf(stderr, "%s: %s\n", progname, magic_error(ms));
  99. - magic_close(ms);
  100. - return ret;
  101. -}
  102. -#endif /* COMPILE_ONLY */
  103. +#include "../data_file.c"
  104. struct type_tbl_s {
  105. const char name[16];
  106. @@ -417,7 +403,7 @@
  107. struct mlist *ml;
  108. mlp->map = NULL;
  109. - if ((ml = CAST(struct mlist *, malloc(sizeof(*ml)))) == NULL)
  110. + if ((ml = CAST(struct mlist *, emalloc(sizeof(*ml)))) == NULL)
  111. return -1;
  112. ml->map = idx == 0 ? map : NULL;
  113. @@ -502,10 +488,16 @@
  114. return;
  115. for (i = 0; i < MAGIC_SETS; i++)
  116. mlist_free(ms->mlist[i]);
  117. - free(ms->o.pbuf);
  118. - free(ms->o.buf);
  119. - free(ms->c.li);
  120. - free(ms);
  121. + if (ms->o.pbuf) {
  122. + efree(ms->o.pbuf);
  123. + }
  124. + if (ms->o.buf) {
  125. + efree(ms->o.buf);
  126. + }
  127. + if (ms->c.li) {
  128. + efree(ms->c.li);
  129. + }
  130. + efree(ms);
  131. }
  132. protected struct magic_set *
  133. @@ -514,7 +506,7 @@
  134. struct magic_set *ms;
  135. size_t i, len;
  136. - if ((ms = CAST(struct magic_set *, calloc(CAST(size_t, 1u),
  137. + if ((ms = CAST(struct magic_set *, ecalloc(CAST(size_t, 1u),
  138. sizeof(struct magic_set)))) == NULL)
  139. return NULL;
  140. @@ -527,7 +519,7 @@
  141. ms->o.blen = 0;
  142. len = (ms->c.len = 10) * sizeof(*ms->c.li);
  143. - if ((ms->c.li = CAST(struct level_info *, malloc(len))) == NULL)
  144. + if ((ms->c.li = CAST(struct level_info *, emalloc(len))) == NULL)
  145. goto free;
  146. ms->event_flags = 0;
  147. @@ -546,48 +538,35 @@
  148. ms->encoding_max = FILE_ENCODING_MAX;
  149. return ms;
  150. free:
  151. - free(ms);
  152. + efree(ms);
  153. return NULL;
  154. }
  155. private void
  156. apprentice_unmap(struct magic_map *map)
  157. {
  158. - size_t i;
  159. if (map == NULL)
  160. return;
  161. -
  162. - switch (map->type) {
  163. - case MAP_TYPE_USER:
  164. - break;
  165. - case MAP_TYPE_MALLOC:
  166. - for (i = 0; i < MAGIC_SETS; i++) {
  167. - void *b = map->magic[i];
  168. - void *p = map->p;
  169. - if (CAST(char *, b) >= CAST(char *, p) &&
  170. - CAST(char *, b) <= CAST(char *, p) + map->len)
  171. - continue;
  172. - free(map->magic[i]);
  173. + if (map->p != php_magic_database) {
  174. + if (map->p == NULL) {
  175. + int j;
  176. + for (j = 0; j < MAGIC_SETS; j++) {
  177. + if (map->magic[j]) {
  178. + efree(map->magic[j]);
  179. + }
  180. + }
  181. + } else {
  182. + efree(map->p);
  183. }
  184. - free(map->p);
  185. - break;
  186. -#ifdef QUICK
  187. - case MAP_TYPE_MMAP:
  188. - if (map->p && map->p != MAP_FAILED)
  189. - (void)munmap(map->p, map->len);
  190. - break;
  191. -#endif
  192. - default:
  193. - abort();
  194. }
  195. - free(map);
  196. + efree(map);
  197. }
  198. private struct mlist *
  199. mlist_alloc(void)
  200. {
  201. struct mlist *mlist;
  202. - if ((mlist = CAST(struct mlist *, calloc(1, sizeof(*mlist)))) == NULL) {
  203. + if ((mlist = CAST(struct mlist *, ecalloc(1, sizeof(*mlist)))) == NULL) {
  204. return NULL;
  205. }
  206. mlist->next = mlist->prev = mlist;
  207. @@ -610,7 +589,7 @@
  208. {
  209. if (ml->map)
  210. apprentice_unmap(CAST(struct magic_map *, ml->map));
  211. - free(ml);
  212. + efree(ml);
  213. }
  214. private void
  215. @@ -629,51 +608,6 @@
  216. mlist_free_one(mlist);
  217. }
  218. -#ifndef COMPILE_ONLY
  219. -/* void **bufs: an array of compiled magic files */
  220. -protected int
  221. -buffer_apprentice(struct magic_set *ms, struct magic **bufs,
  222. - size_t *sizes, size_t nbufs)
  223. -{
  224. - size_t i, j;
  225. - struct mlist *ml;
  226. - struct magic_map *map;
  227. -
  228. - if (nbufs == 0)
  229. - return -1;
  230. -
  231. - (void)file_reset(ms, 0);
  232. -
  233. - init_file_tables();
  234. -
  235. - for (i = 0; i < MAGIC_SETS; i++) {
  236. - mlist_free(ms->mlist[i]);
  237. - if ((ms->mlist[i] = mlist_alloc()) == NULL) {
  238. - file_oomem(ms, sizeof(*ms->mlist[i]));
  239. - goto fail;
  240. - }
  241. - }
  242. -
  243. - for (i = 0; i < nbufs; i++) {
  244. - map = apprentice_buf(ms, bufs[i], sizes[i]);
  245. - if (map == NULL)
  246. - goto fail;
  247. -
  248. - for (j = 0; j < MAGIC_SETS; j++) {
  249. - if (add_mlist(ms->mlist[j], map, j) == -1) {
  250. - file_oomem(ms, sizeof(*ml));
  251. - goto fail;
  252. - }
  253. - }
  254. - }
  255. -
  256. - return 0;
  257. -fail:
  258. - mlist_free_all(ms);
  259. - return -1;
  260. -}
  261. -#endif
  262. -
  263. /* const char *fn: list of magic files and directories */
  264. protected int
  265. file_apprentice(struct magic_set *ms, const char *fn, int action)
  266. @@ -684,12 +618,28 @@
  267. (void)file_reset(ms, 0);
  268. +/* XXX disabling default magic loading so the compiled in data is used */
  269. +#if 0
  270. if ((fn = magic_getpath(fn, action)) == NULL)
  271. return -1;
  272. +#endif
  273. init_file_tables();
  274. - if ((mfn = strdup(fn)) == NULL) {
  275. + if (fn == NULL)
  276. + fn = getenv("MAGIC");
  277. + if (fn == NULL) {
  278. + for (i = 0; i < MAGIC_SETS; i++) {
  279. + mlist_free(ms->mlist[i]);
  280. + if ((ms->mlist[i] = mlist_alloc()) == NULL) {
  281. + file_oomem(ms, sizeof(*ms->mlist[i]));
  282. + return -1;
  283. + }
  284. + }
  285. + return apprentice_1(ms, fn, action);
  286. + }
  287. +
  288. + if ((mfn = estrdup(fn)) == NULL) {
  289. file_oomem(ms, strlen(fn));
  290. return -1;
  291. }
  292. @@ -702,7 +652,7 @@
  293. mlist_free(ms->mlist[j]);
  294. ms->mlist[j] = NULL;
  295. }
  296. - free(mfn);
  297. + efree(mfn);
  298. return -1;
  299. }
  300. }
  301. @@ -719,7 +669,7 @@
  302. fn = p;
  303. }
  304. - free(mfn);
  305. + efree(mfn);
  306. if (errs == -1) {
  307. for (i = 0; i < MAGIC_SETS; i++) {
  308. @@ -1159,7 +1109,7 @@
  309. mset[i].max += ALLOC_INCR;
  310. if ((mp = CAST(struct magic_entry *,
  311. - realloc(mset[i].me, sizeof(*mp) * mset[i].max))) ==
  312. + erealloc(mset[i].me, sizeof(*mp) * mset[i].max))) ==
  313. NULL) {
  314. file_oomem(ms, sizeof(*mp) * mset[i].max);
  315. return -1;
  316. @@ -1180,13 +1130,19 @@
  317. load_1(struct magic_set *ms, int action, const char *fn, int *errs,
  318. struct magic_entry_set *mset)
  319. {
  320. - size_t lineno = 0, llen = 0;
  321. + char buffer[BUFSIZ + 1];
  322. char *line = NULL;
  323. - ssize_t len;
  324. + size_t len;
  325. + size_t lineno = 0;
  326. struct magic_entry me;
  327. - FILE *f = fopen(ms->file = fn, "r");
  328. - if (f == NULL) {
  329. + php_stream *stream;
  330. +
  331. +
  332. + ms->file = fn;
  333. + stream = php_stream_open_wrapper((char *)fn, "rb", REPORT_ERRORS, NULL);
  334. +
  335. + if (stream == NULL) {
  336. if (errno != ENOENT)
  337. file_error(ms, errno, "cannot read magic file `%s'",
  338. fn);
  339. @@ -1196,8 +1152,7 @@
  340. memset(&me, 0, sizeof(me));
  341. /* read and parse this file */
  342. - for (ms->line = 1; (len = getline(&line, &llen, f)) != -1;
  343. - ms->line++) {
  344. + for (ms->line = 1; (line = php_stream_get_line(stream, buffer , BUFSIZ, &len)) != NULL; ms->line++) {
  345. if (len == 0) /* null line, garbage, etc */
  346. continue;
  347. if (line[len - 1] == '\n') {
  348. @@ -1256,8 +1211,8 @@
  349. }
  350. if (me.mp)
  351. (void)addentry(ms, &me, mset);
  352. - free(line);
  353. - (void)fclose(f);
  354. + efree(line);
  355. + php_stream_close(stream);
  356. }
  357. /*
  358. @@ -1336,7 +1291,7 @@
  359. mentrycount += me[i].cont_count;
  360. slen = sizeof(**ma) * mentrycount;
  361. - if ((*ma = CAST(struct magic *, malloc(slen))) == NULL) {
  362. + if ((*ma = CAST(struct magic *, emalloc(slen))) == NULL) {
  363. file_oomem(ms, slen);
  364. return -1;
  365. }
  366. @@ -1358,8 +1313,8 @@
  367. if (me == NULL)
  368. return;
  369. for (i = 0; i < nme; i++)
  370. - free(me[i].mp);
  371. - free(me);
  372. + efree(me[i].mp);
  373. + efree(me);
  374. }
  375. private struct magic_map *
  376. @@ -1368,18 +1323,19 @@
  377. int errs = 0;
  378. uint32_t i, j;
  379. size_t files = 0, maxfiles = 0;
  380. - char **filearr = NULL, *mfn;
  381. - struct stat st;
  382. + char **filearr = NULL;
  383. + zend_stat_t st;
  384. struct magic_map *map;
  385. struct magic_entry_set mset[MAGIC_SETS];
  386. - DIR *dir;
  387. - struct dirent *d;
  388. + php_stream *dir;
  389. + php_stream_dirent d;
  390. +
  391. memset(mset, 0, sizeof(mset));
  392. ms->flags |= MAGIC_CHECK; /* Enable checks for parsed files */
  393. - if ((map = CAST(struct magic_map *, calloc(1, sizeof(*map)))) == NULL)
  394. + if ((map = CAST(struct magic_map *, ecalloc(1, sizeof(*map)))) == NULL)
  395. {
  396. file_oomem(ms, sizeof(*map));
  397. return NULL;
  398. @@ -1391,52 +1347,50 @@
  399. (void)fprintf(stderr, "%s\n", usg_hdr);
  400. /* load directory or file */
  401. - if (stat(fn, &st) == 0 && S_ISDIR(st.st_mode)) {
  402. - dir = opendir(fn);
  403. + /* FIXME: Read file names and sort them to prevent
  404. + non-determinism. See Debian bug #488562. */
  405. + if (php_sys_stat(fn, &st) == 0 && S_ISDIR(st.st_mode)) {
  406. + int mflen;
  407. + char mfn[MAXPATHLEN];
  408. +
  409. + dir = php_stream_opendir((char *)fn, REPORT_ERRORS, NULL);
  410. if (!dir) {
  411. errs++;
  412. goto out;
  413. }
  414. - while ((d = readdir(dir)) != NULL) {
  415. - if (d->d_name[0] == '.')
  416. - continue;
  417. - if (asprintf(&mfn, "%s/%s", fn, d->d_name) < 0) {
  418. + while (php_stream_readdir(dir, &d)) {
  419. + if ((mflen = snprintf(mfn, sizeof(mfn), "%s/%s", fn, d.d_name)) < 0) {
  420. file_oomem(ms,
  421. - strlen(fn) + strlen(d->d_name) + 2);
  422. + strlen(fn) + strlen(d.d_name) + 2);
  423. errs++;
  424. - closedir(dir);
  425. + php_stream_closedir(dir);
  426. goto out;
  427. }
  428. - if (stat(mfn, &st) == -1 || !S_ISREG(st.st_mode)) {
  429. - free(mfn);
  430. + if (zend_stat(mfn, &st) == -1 || !S_ISREG(st.st_mode)) {
  431. continue;
  432. }
  433. if (files >= maxfiles) {
  434. size_t mlen;
  435. - char **nfilearr;
  436. maxfiles = (maxfiles + 1) * 2;
  437. mlen = maxfiles * sizeof(*filearr);
  438. - if ((nfilearr = CAST(char **,
  439. - realloc(filearr, mlen))) == NULL) {
  440. + if ((filearr = CAST(char **,
  441. + erealloc(filearr, mlen))) == NULL) {
  442. file_oomem(ms, mlen);
  443. - free(mfn);
  444. - closedir(dir);
  445. + php_stream_closedir(dir);
  446. errs++;
  447. goto out;
  448. }
  449. - filearr = nfilearr;
  450. }
  451. - filearr[files++] = mfn;
  452. + filearr[files++] = estrndup(mfn, (mflen > sizeof(mfn) - 1)? sizeof(mfn) - 1: mflen);
  453. }
  454. - closedir(dir);
  455. + php_stream_closedir(dir);
  456. if (filearr) {
  457. qsort(filearr, files, sizeof(*filearr), cmpstrp);
  458. for (i = 0; i < files; i++) {
  459. load_1(ms, action, filearr[i], &errs, mset);
  460. - free(filearr[i]);
  461. + efree(filearr[i]);
  462. }
  463. - free(filearr);
  464. - filearr = NULL;
  465. + efree(filearr);
  466. }
  467. } else
  468. load_1(ms, action, fn, &errs, mset);
  469. @@ -1474,7 +1428,6 @@
  470. }
  471. out:
  472. - free(filearr);
  473. for (j = 0; j < MAGIC_SETS; j++)
  474. magic_entry_free(mset[j].me, mset[j].count);
  475. @@ -1910,7 +1863,7 @@
  476. if (me->cont_count == me->max_count) {
  477. struct magic *nm;
  478. size_t cnt = me->max_count + ALLOC_CHUNK;
  479. - if ((nm = CAST(struct magic *, realloc(me->mp,
  480. + if ((nm = CAST(struct magic *, erealloc(me->mp,
  481. sizeof(*nm) * cnt))) == NULL) {
  482. file_oomem(ms, sizeof(*nm) * cnt);
  483. return -1;
  484. @@ -1925,7 +1878,7 @@
  485. static const size_t len = sizeof(*m) * ALLOC_CHUNK;
  486. if (me->mp != NULL)
  487. return 1;
  488. - if ((m = CAST(struct magic *, malloc(len))) == NULL) {
  489. + if ((m = CAST(struct magic *, emalloc(len))) == NULL) {
  490. file_oomem(ms, len);
  491. return -1;
  492. }
  493. @@ -2148,7 +2101,7 @@
  494. m->mask_op = 0;
  495. if (*l == '~') {
  496. - if (!IS_STRING(m->type))
  497. + if (!IS_LIBMAGIC_STRING(m->type))
  498. m->mask_op |= FILE_OPINVERSE;
  499. else if (ms->flags & MAGIC_CHECK)
  500. file_magwarn(ms, "'~' invalid for string types");
  501. @@ -2157,7 +2110,7 @@
  502. m->str_range = 0;
  503. m->str_flags = m->type == FILE_PSTRING ? PSTRING_1_LE : 0;
  504. if ((op = get_op(*l)) != -1) {
  505. - if (IS_STRING(m->type)) {
  506. + if (IS_LIBMAGIC_STRING(m->type)) {
  507. int r;
  508. if (op != FILE_OPDIVIDE) {
  509. @@ -2277,7 +2230,7 @@
  510. */
  511. private int
  512. parse_strength(struct magic_set *ms, struct magic_entry *me, const char *line,
  513. - size_t len __attribute__((__unused__)))
  514. + size_t len)
  515. {
  516. const char *l = line;
  517. char *el;
  518. @@ -2339,8 +2292,7 @@
  519. private int
  520. parse_extra(struct magic_set *ms, struct magic_entry *me, const char *line,
  521. - size_t llen, off_t off, size_t len, const char *name, const char *extra,
  522. - int nt)
  523. + size_t llen, zend_off_t off, size_t len, const char *name, const char *extra, int nt)
  524. {
  525. size_t i;
  526. const char *l = line;
  527. @@ -2705,14 +2657,19 @@
  528. return -1;
  529. }
  530. if (m->type == FILE_REGEX) {
  531. - file_regex_t rx;
  532. - int rc = file_regcomp(&rx, m->value.s, REG_EXTENDED);
  533. - if (rc) {
  534. - if (ms->flags & MAGIC_CHECK)
  535. - file_regerror(&rx, rc, ms);
  536. + zend_string *pattern;
  537. + int options = 0;
  538. + pcre_cache_entry *pce;
  539. +
  540. + pattern = convert_libmagic_pattern(m->value.s, strlen(m->value.s), options);
  541. +
  542. + if ((pce = pcre_get_compiled_regex_cache(pattern)) == NULL) {
  543. + zend_string_release(pattern);
  544. + return -1;
  545. }
  546. - file_regfree(&rx);
  547. - return rc ? -1 : 0;
  548. + zend_string_release(pattern);
  549. +
  550. + return 0;
  551. }
  552. return 0;
  553. default:
  554. @@ -3068,120 +3025,83 @@
  555. }
  556. /*
  557. - * handle a buffer containing a compiled file.
  558. - */
  559. -private struct magic_map *
  560. -apprentice_buf(struct magic_set *ms, struct magic *buf, size_t len)
  561. -{
  562. - struct magic_map *map;
  563. -
  564. - if ((map = CAST(struct magic_map *, calloc(1, sizeof(*map)))) == NULL) {
  565. - file_oomem(ms, sizeof(*map));
  566. - return NULL;
  567. - }
  568. - map->len = len;
  569. - map->p = buf;
  570. - map->type = MAP_TYPE_USER;
  571. - if (check_buffer(ms, map, "buffer") != 0) {
  572. - apprentice_unmap(map);
  573. - return NULL;
  574. - }
  575. - return map;
  576. -}
  577. -
  578. -/*
  579. * handle a compiled file.
  580. */
  581. private struct magic_map *
  582. apprentice_map(struct magic_set *ms, const char *fn)
  583. {
  584. - int fd;
  585. - struct stat st;
  586. + uint32_t *ptr;
  587. + uint32_t version, entries = 0, nentries;
  588. + int needsbyteswap;
  589. char *dbname = NULL;
  590. struct magic_map *map;
  591. - struct magic_map *rv = NULL;
  592. + size_t i;
  593. + php_stream *stream = NULL;
  594. + php_stream_statbuf st;
  595. +
  596. +
  597. - fd = -1;
  598. - if ((map = CAST(struct magic_map *, calloc(1, sizeof(*map)))) == NULL) {
  599. + if ((map = CAST(struct magic_map *, ecalloc(1, sizeof(*map)))) == NULL) {
  600. file_oomem(ms, sizeof(*map));
  601. - goto error;
  602. + return NULL;
  603. }
  604. - map->type = MAP_TYPE_USER; /* unspecified */
  605. +
  606. + if (fn == NULL) {
  607. + map->p = (void *)&php_magic_database;
  608. + goto internal_loaded;
  609. + }
  610. +
  611. +#ifdef PHP_WIN32
  612. + /* Don't bother on windows with php_stream_open_wrapper,
  613. + return to give apprentice_load() a chance. */
  614. + if (php_stream_stat_path_ex((char *)fn, 0, &st, NULL) == SUCCESS) {
  615. + if (st.sb.st_mode & S_IFDIR) {
  616. + goto error;
  617. + }
  618. + }
  619. +#endif
  620. dbname = mkdbname(ms, fn, 0);
  621. if (dbname == NULL)
  622. goto error;
  623. - if ((fd = open(dbname, O_RDONLY|O_BINARY)) == -1)
  624. + stream = php_stream_open_wrapper((char *)fn, "rb", REPORT_ERRORS, NULL);
  625. +
  626. + if (!stream) {
  627. goto error;
  628. + }
  629. - if (fstat(fd, &st) == -1) {
  630. +#ifndef PHP_WIN32
  631. + if (php_stream_stat(stream, &st) < 0) {
  632. file_error(ms, errno, "cannot stat `%s'", dbname);
  633. goto error;
  634. }
  635. - if (st.st_size < 8 || st.st_size > maxoff_t()) {
  636. +#endif
  637. + if (st.sb.st_size < 8 || st.sb.st_size > maxoff_t()) {
  638. file_error(ms, 0, "file `%s' is too %s", dbname,
  639. - st.st_size < 8 ? "small" : "large");
  640. + st.sb.st_size < 8 ? "small" : "large");
  641. goto error;
  642. }
  643. - map->len = CAST(size_t, st.st_size);
  644. -#ifdef QUICK
  645. - map->type = MAP_TYPE_MMAP;
  646. - if ((map->p = mmap(0, CAST(size_t, st.st_size), PROT_READ|PROT_WRITE,
  647. - MAP_PRIVATE|MAP_FILE, fd, CAST(off_t, 0))) == MAP_FAILED) {
  648. - file_error(ms, errno, "cannot map `%s'", dbname);
  649. - goto error;
  650. - }
  651. -#else
  652. map->type = MAP_TYPE_MALLOC;
  653. - if ((map->p = CAST(void *, malloc(map->len))) == NULL) {
  654. - file_oomem(ms, map->len);
  655. - goto error;
  656. - }
  657. - if (read(fd, map->p, map->len) != (ssize_t)map->len) {
  658. - file_badread(ms);
  659. - goto error;
  660. - }
  661. -#endif
  662. - (void)close(fd);
  663. - fd = -1;
  664. + map->len = CAST(size_t, st.sb.st_size);
  665. + map->p = CAST(void *, emalloc(map->len));
  666. - if (check_buffer(ms, map, dbname) != 0) {
  667. - goto error;
  668. - }
  669. -#ifdef QUICK
  670. - if (mprotect(map->p, CAST(size_t, st.st_size), PROT_READ) == -1) {
  671. - file_error(ms, errno, "cannot mprotect `%s'", dbname);
  672. + if (php_stream_read(stream, map->p, (size_t)st.sb.st_size) != (size_t)st.sb.st_size) {
  673. + file_badread(ms);
  674. goto error;
  675. }
  676. -#endif
  677. -
  678. - free(dbname);
  679. - return map;
  680. -
  681. -error:
  682. - if (fd != -1)
  683. - (void)close(fd);
  684. - apprentice_unmap(map);
  685. - free(dbname);
  686. - return rv;
  687. -}
  688. -private int
  689. -check_buffer(struct magic_set *ms, struct magic_map *map, const char *dbname)
  690. -{
  691. - uint32_t *ptr;
  692. - uint32_t entries, nentries;
  693. - uint32_t version;
  694. - int i, needsbyteswap;
  695. + php_stream_close(stream);
  696. + stream = NULL;
  697. - ptr = CAST(uint32_t *, map->p);
  698. +internal_loaded:
  699. + ptr = (uint32_t *)(void *)map->p;
  700. if (*ptr != MAGICNO) {
  701. if (swap4(*ptr) != MAGICNO) {
  702. file_error(ms, 0, "bad magic in `%s'", dbname);
  703. - return -1;
  704. + goto error;
  705. }
  706. needsbyteswap = 1;
  707. } else
  708. @@ -3191,17 +3111,29 @@
  709. else
  710. version = ptr[1];
  711. if (version != VERSIONNO) {
  712. - file_error(ms, 0, "File %s supports only version %d magic "
  713. - "files. `%s' is version %d", VERSION,
  714. + file_error(ms, 0, "File %d supports only version %d magic "
  715. + "files. `%s' is version %d", MAGIC_VERSION,
  716. VERSIONNO, dbname, version);
  717. - return -1;
  718. + goto error;
  719. }
  720. - entries = CAST(uint32_t, map->len / sizeof(struct magic));
  721. - if ((entries * sizeof(struct magic)) != map->len) {
  722. - file_error(ms, 0, "Size of `%s' %" SIZE_T_FORMAT "u is not "
  723. - "a multiple of %" SIZE_T_FORMAT "u",
  724. - dbname, map->len, sizeof(struct magic));
  725. - return -1;
  726. +
  727. + /* php_magic_database is a const, performing writes will segfault. This is for big-endian
  728. + machines only, PPC and Sparc specifically. Consider static variable or MINIT in
  729. + future. */
  730. + if (needsbyteswap && fn == NULL) {
  731. + map->p = emalloc(sizeof(php_magic_database));
  732. + map->p = memcpy(map->p, php_magic_database, sizeof(php_magic_database));
  733. + }
  734. +
  735. + if (NULL != fn) {
  736. + nentries = (uint32_t)(st.sb.st_size / sizeof(struct magic));
  737. + entries = (uint32_t)(st.sb.st_size / sizeof(struct magic));
  738. + if ((zend_off_t)(entries * sizeof(struct magic)) != st.sb.st_size) {
  739. + file_error(ms, 0, "Size of `%s' %llu is not a multiple of %zu",
  740. + dbname, (unsigned long long)st.sb.st_size,
  741. + sizeof(struct magic));
  742. + goto error;
  743. + }
  744. }
  745. map->magic[0] = CAST(struct magic *, map->p) + 1;
  746. nentries = 0;
  747. @@ -3214,15 +3146,29 @@
  748. map->magic[i + 1] = map->magic[i] + map->nmagic[i];
  749. nentries += map->nmagic[i];
  750. }
  751. - if (entries != nentries + 1) {
  752. + if (NULL != fn && entries != nentries + 1) {
  753. file_error(ms, 0, "Inconsistent entries in `%s' %u != %u",
  754. dbname, entries, nentries + 1);
  755. - return -1;
  756. + goto error;
  757. }
  758. if (needsbyteswap)
  759. for (i = 0; i < MAGIC_SETS; i++)
  760. byteswap(map->magic[i], map->nmagic[i]);
  761. - return 0;
  762. +
  763. + if (dbname) {
  764. + efree(dbname);
  765. + }
  766. + return map;
  767. +
  768. +error:
  769. + if (stream) {
  770. + php_stream_close(stream);
  771. + }
  772. + apprentice_unmap(map);
  773. + if (dbname) {
  774. + efree(dbname);
  775. + }
  776. + return NULL;
  777. }
  778. /*
  779. @@ -3233,7 +3179,6 @@
  780. {
  781. static const size_t nm = sizeof(*map->nmagic) * MAGIC_SETS;
  782. static const size_t m = sizeof(**map->magic);
  783. - int fd = -1;
  784. size_t len;
  785. char *dbname;
  786. int rv = -1;
  787. @@ -3242,14 +3187,17 @@
  788. struct magic m;
  789. uint32_t h[2 + MAGIC_SETS];
  790. } hdr;
  791. + php_stream *stream;
  792. dbname = mkdbname(ms, fn, 1);
  793. if (dbname == NULL)
  794. goto out;
  795. - if ((fd = open(dbname, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0644)) == -1)
  796. - {
  797. + /* wb+ == O_WRONLY|O_CREAT|O_TRUNC|O_BINARY */
  798. + stream = php_stream_open_wrapper((char *)fn, "wb+", REPORT_ERRORS, NULL);
  799. +
  800. + if (!stream) {
  801. file_error(ms, errno, "cannot open `%s'", dbname);
  802. goto out;
  803. }
  804. @@ -3258,26 +3206,25 @@
  805. hdr.h[1] = VERSIONNO;
  806. memcpy(hdr.h + 2, map->nmagic, nm);
  807. - if (write(fd, &hdr, sizeof(hdr)) != CAST(ssize_t, sizeof(hdr))) {
  808. + if (php_stream_write(stream,(const char *)&hdr, sizeof(hdr)) != (ssize_t)sizeof(hdr)) {
  809. file_error(ms, errno, "error writing `%s'", dbname);
  810. - goto out2;
  811. + goto out;
  812. }
  813. for (i = 0; i < MAGIC_SETS; i++) {
  814. len = m * map->nmagic[i];
  815. - if (write(fd, map->magic[i], len) != CAST(ssize_t, len)) {
  816. + if (php_stream_write(stream, (const char *)map->magic[i], len) != (ssize_t)len) {
  817. file_error(ms, errno, "error writing `%s'", dbname);
  818. - goto out2;
  819. + goto out;
  820. }
  821. }
  822. + if (stream) {
  823. + php_stream_close(stream);
  824. + }
  825. rv = 0;
  826. -out2:
  827. - if (fd != -1)
  828. - (void)close(fd);
  829. out:
  830. - apprentice_unmap(map);
  831. - free(dbname);
  832. + efree(dbname);
  833. return rv;
  834. }
  835. @@ -3311,17 +3258,18 @@
  836. q++;
  837. /* Compatibility with old code that looked in .mime */
  838. if (ms->flags & MAGIC_MIME) {
  839. - if (asprintf(&buf, "%.*s.mime%s", CAST(int, q - fn), fn, ext)
  840. - < 0)
  841. - return NULL;
  842. - if (access(buf, R_OK) != -1) {
  843. + spprintf(&buf, MAXPATHLEN, "%.*s.mime%s", CAST(int, q - fn), fn, ext);
  844. +#ifdef PHP_WIN32
  845. + if (VCWD_ACCESS(buf, R_OK) == 0) {
  846. +#else
  847. + if (VCWD_ACCESS(buf, R_OK) != -1) {
  848. +#endif
  849. ms->flags &= MAGIC_MIME_TYPE;
  850. return buf;
  851. }
  852. - free(buf);
  853. + efree(buf);
  854. }
  855. - if (asprintf(&buf, "%.*s%s", CAST(int, q - fn), fn, ext) < 0)
  856. - return NULL;
  857. + spprintf(&buf, MAXPATHLEN, "%.*s%s", CAST(int, q - fn), fn, ext);
  858. /* Compatibility with old code that looked in .mime */
  859. if (strstr(fn, ".mime") != NULL)
  860. @@ -3411,7 +3359,7 @@
  861. m->offset = swap4(CAST(uint32_t, m->offset));
  862. m->in_offset = swap4(CAST(uint32_t, m->in_offset));
  863. m->lineno = swap4(CAST(uint32_t, m->lineno));
  864. - if (IS_STRING(m->type)) {
  865. + if (IS_LIBMAGIC_STRING(m->type)) {
  866. m->str_range = swap4(m->str_range);
  867. m->str_flags = swap4(m->str_flags);
  868. }
  869. diff -u libmagic.orig/ascmagic.c libmagic/ascmagic.c
  870. --- libmagic.orig/ascmagic.c 2021-02-23 01:49:06.000000000 +0100
  871. +++ libmagic/ascmagic.c 2022-06-16 13:39:41.570984700 +0200
  872. @@ -96,7 +96,7 @@
  873. rv = file_ascmagic_with_encoding(ms, &bb,
  874. ubuf, ulen, code, type, text);
  875. - free(ubuf);
  876. + efree(ubuf);
  877. return rv;
  878. }
  879. @@ -143,7 +143,7 @@
  880. /* malloc size is a conservative overestimate; could be
  881. improved, or at least realloced after conversion. */
  882. mlen = ulen * 6;
  883. - if ((utf8_buf = CAST(unsigned char *, malloc(mlen))) == NULL) {
  884. + if ((utf8_buf = CAST(unsigned char *, emalloc(mlen))) == NULL) {
  885. file_oomem(ms, mlen);
  886. goto done;
  887. }
  888. @@ -330,7 +330,8 @@
  889. }
  890. rv = 1;
  891. done:
  892. - free(utf8_buf);
  893. + if (utf8_buf)
  894. + efree(utf8_buf);
  895. return rv;
  896. }
  897. diff -u libmagic.orig/buffer.c libmagic/buffer.c
  898. --- libmagic.orig/buffer.c 2021-02-23 01:49:26.000000000 +0100
  899. +++ libmagic/buffer.c 2021-09-21 13:27:27.982716100 +0200
  900. @@ -31,19 +31,23 @@
  901. #endif /* lint */
  902. #include "magic.h"
  903. +#ifdef PHP_WIN32
  904. +#include "win32/unistd.h"
  905. +#else
  906. #include <unistd.h>
  907. +#endif
  908. #include <string.h>
  909. #include <stdlib.h>
  910. #include <sys/stat.h>
  911. void
  912. -buffer_init(struct buffer *b, int fd, const struct stat *st, const void *data,
  913. +buffer_init(struct buffer *b, int fd, const zend_stat_t *st, const void *data,
  914. size_t len)
  915. {
  916. b->fd = fd;
  917. if (st)
  918. memcpy(&b->st, st, sizeof(b->st));
  919. - else if (b->fd == -1 || fstat(b->fd, &b->st) == -1)
  920. + else if (b->fd == -1 || zend_fstat(b->fd, &b->st) == -1)
  921. memset(&b->st, 0, sizeof(b->st));
  922. b->fbuf = data;
  923. b->flen = len;
  924. @@ -55,7 +59,7 @@
  925. void
  926. buffer_fini(struct buffer *b)
  927. {
  928. - free(b->ebuf);
  929. + efree(b->ebuf);
  930. }
  931. int
  932. @@ -71,12 +75,14 @@
  933. b->elen = CAST(size_t, b->st.st_size) < b->flen ?
  934. CAST(size_t, b->st.st_size) : b->flen;
  935. - if ((b->ebuf = malloc(b->elen)) == NULL)
  936. + if ((b->ebuf = emalloc(b->elen)) == NULL)
  937. goto out;
  938. b->eoff = b->st.st_size - b->elen;
  939. - if (pread(b->fd, b->ebuf, b->elen, b->eoff) == -1) {
  940. - free(b->ebuf);
  941. + if (FINFO_LSEEK_FUNC(b->fd, b->eoff, SEEK_SET) == (zend_off_t)-1 ||
  942. + FINFO_READ_FUNC(b->fd, b->ebuf, b->elen) != (ssize_t)b->elen)
  943. + {
  944. + efree(b->ebuf);
  945. b->ebuf = NULL;
  946. goto out;
  947. }
  948. diff -u libmagic.orig/cdf.c libmagic/cdf.c
  949. --- libmagic.orig/cdf.c 2021-02-23 01:49:06.000000000 +0100
  950. +++ libmagic/cdf.c 2021-09-21 13:27:27.983695600 +0200
  951. @@ -43,7 +43,17 @@
  952. #include <err.h>
  953. #endif
  954. #include <stdlib.h>
  955. +
  956. +#ifdef PHP_WIN32
  957. +#include "win32/unistd.h"
  958. +#else
  959. #include <unistd.h>
  960. +#endif
  961. +
  962. +#ifndef UINT32_MAX
  963. +# define UINT32_MAX (0xffffffff)
  964. +#endif
  965. +
  966. #include <string.h>
  967. #include <time.h>
  968. #include <ctype.h>
  969. @@ -85,40 +95,9 @@
  970. CDF_TOLE8(CAST(uint64_t, x))))
  971. #define CDF_GETUINT32(x, y) cdf_getuint32(x, y)
  972. -#define CDF_MALLOC(n) cdf_malloc(__FILE__, __LINE__, (n))
  973. -#define CDF_REALLOC(p, n) cdf_realloc(__FILE__, __LINE__, (p), (n))
  974. -#define CDF_CALLOC(n, u) cdf_calloc(__FILE__, __LINE__, (n), (u))
  975. -
  976. -
  977. -/*ARGSUSED*/
  978. -static void *
  979. -cdf_malloc(const char *file __attribute__((__unused__)),
  980. - size_t line __attribute__((__unused__)), size_t n)
  981. -{
  982. - DPRINTF(("%s,%" SIZE_T_FORMAT "u: %s %" SIZE_T_FORMAT "u\n",
  983. - file, line, __func__, n));
  984. - return malloc(n);
  985. -}
  986. -
  987. -/*ARGSUSED*/
  988. -static void *
  989. -cdf_realloc(const char *file __attribute__((__unused__)),
  990. - size_t line __attribute__((__unused__)), void *p, size_t n)
  991. -{
  992. - DPRINTF(("%s,%" SIZE_T_FORMAT "u: %s %" SIZE_T_FORMAT "u\n",
  993. - file, line, __func__, n));
  994. - return realloc(p, n);
  995. -}
  996. -
  997. -/*ARGSUSED*/
  998. -static void *
  999. -cdf_calloc(const char *file __attribute__((__unused__)),
  1000. - size_t line __attribute__((__unused__)), size_t n, size_t u)
  1001. -{
  1002. - DPRINTF(("%s,%" SIZE_T_FORMAT "u: %s %" SIZE_T_FORMAT "u %"
  1003. - SIZE_T_FORMAT "u\n", file, line, __func__, n, u));
  1004. - return calloc(n, u);
  1005. -}
  1006. +#define CDF_MALLOC(n) emalloc(n)
  1007. +#define CDF_REALLOC(p, n) erealloc(p, n)
  1008. +#define CDF_CALLOC(n, u) ecalloc(n, u)
  1009. /*
  1010. * swap a short
  1011. @@ -314,7 +293,7 @@
  1012. scn->sst_len = 0;
  1013. scn->sst_dirlen = 0;
  1014. scn->sst_ss = 0;
  1015. - free(scn->sst_tab);
  1016. + efree(scn->sst_tab);
  1017. scn->sst_tab = NULL;
  1018. return -1;
  1019. }
  1020. @@ -322,9 +301,11 @@
  1021. static size_t
  1022. cdf_check_stream(const cdf_stream_t *sst, const cdf_header_t *h)
  1023. {
  1024. +#ifndef NDEBUG
  1025. size_t ss = sst->sst_dirlen < h->h_min_size_standard_stream ?
  1026. CDF_SHORT_SEC_SIZE(h) : CDF_SEC_SIZE(h);
  1027. assert(ss == sst->sst_ss);
  1028. +#endif
  1029. return sst->sst_ss;
  1030. }
  1031. @@ -347,11 +328,11 @@
  1032. }
  1033. static ssize_t
  1034. -cdf_read(const cdf_info_t *info, off_t off, void *buf, size_t len)
  1035. +cdf_read(const cdf_info_t *info, zend_off_t off, void *buf, size_t len)
  1036. {
  1037. size_t siz = CAST(size_t, off + len);
  1038. - if (CAST(off_t, off + len) != CAST(off_t, siz))
  1039. + if (CAST(zend_off_t, off + len) != CAST(zend_off_t, siz))
  1040. goto out;
  1041. if (info->i_buf != NULL && info->i_len >= siz) {
  1042. @@ -362,7 +343,10 @@
  1043. if (info->i_fd == -1)
  1044. goto out;
  1045. - if (pread(info->i_fd, buf, len, off) != CAST(ssize_t, len))
  1046. + if (FINFO_LSEEK_FUNC(info->i_fd, off, SEEK_SET) == (zend_off_t)-1)
  1047. + return -1;
  1048. +
  1049. + if (FINFO_READ_FUNC(info->i_fd, buf, len) != (ssize_t)len)
  1050. return -1;
  1051. return CAST(ssize_t, len);
  1052. @@ -377,7 +361,7 @@
  1053. char buf[512];
  1054. (void)memcpy(cdf_bo.s, "\01\02\03\04", 4);
  1055. - if (cdf_read(info, CAST(off_t, 0), buf, sizeof(buf)) == -1)
  1056. + if (cdf_read(info, CAST(zend_off_t, 0), buf, sizeof(buf)) == -1)
  1057. return -1;
  1058. cdf_unpack_header(h, buf);
  1059. cdf_swap_header(h);
  1060. @@ -524,14 +508,14 @@
  1061. }
  1062. out:
  1063. sat->sat_len = i;
  1064. - free(msa);
  1065. + efree(msa);
  1066. return 0;
  1067. out3:
  1068. errno = EFTYPE;
  1069. out2:
  1070. - free(msa);
  1071. + efree(msa);
  1072. out1:
  1073. - free(sat->sat_tab);
  1074. + efree(sat->sat_tab);
  1075. return -1;
  1076. }
  1077. @@ -699,7 +683,7 @@
  1078. return -1;
  1079. if ((buf = CAST(char *, CDF_MALLOC(ss))) == NULL) {
  1080. - free(dir->dir_tab);
  1081. + efree(dir->dir_tab);
  1082. return -1;
  1083. }
  1084. @@ -722,11 +706,11 @@
  1085. if (NEED_SWAP)
  1086. for (i = 0; i < dir->dir_len; i++)
  1087. cdf_swap_dir(&dir->dir_tab[i]);
  1088. - free(buf);
  1089. + efree(buf);
  1090. return 0;
  1091. out:
  1092. - free(dir->dir_tab);
  1093. - free(buf);
  1094. + efree(dir->dir_tab);
  1095. + efree(buf);
  1096. errno = EFTYPE;
  1097. return -1;
  1098. }
  1099. @@ -771,7 +755,7 @@
  1100. out:
  1101. errno = EFTYPE;
  1102. out1:
  1103. - free(ssat->sat_tab);
  1104. + efree(ssat->sat_tab);
  1105. return -1;
  1106. }
  1107. @@ -933,7 +917,7 @@
  1108. *maxcount = newcount;
  1109. return inp;
  1110. out:
  1111. - free(*info);
  1112. + efree(*info);
  1113. *maxcount = 0;
  1114. *info = NULL;
  1115. return NULL;
  1116. @@ -1115,7 +1099,7 @@
  1117. }
  1118. return 0;
  1119. out:
  1120. - free(*info);
  1121. + efree(*info);
  1122. *info = NULL;
  1123. *count = 0;
  1124. *maxcount = 0;
  1125. @@ -1407,7 +1391,7 @@
  1126. cdf_directory_t *d;
  1127. char name[__arraycount(d->d_name)];
  1128. cdf_stream_t scn;
  1129. - struct timespec ts;
  1130. + struct timeval ts;
  1131. static const char *types[] = { "empty", "user storage",
  1132. "user stream", "lockbytes", "property", "root storage" };
  1133. @@ -1449,7 +1433,7 @@
  1134. break;
  1135. }
  1136. cdf_dump_stream(&scn);
  1137. - free(scn.sst_tab);
  1138. + efree(scn.sst_tab);
  1139. break;
  1140. default:
  1141. break;
  1142. @@ -1462,7 +1446,7 @@
  1143. cdf_dump_property_info(const cdf_property_info_t *info, size_t count)
  1144. {
  1145. cdf_timestamp_t tp;
  1146. - struct timespec ts;
  1147. + struct timeval ts;
  1148. char buf[64];
  1149. size_t i, j;
  1150. @@ -1547,7 +1531,7 @@
  1151. (void)fprintf(stderr, "Class %s\n", buf);
  1152. (void)fprintf(stderr, "Count %d\n", ssi.si_count);
  1153. cdf_dump_property_info(info, count);
  1154. - free(info);
  1155. + efree(info);
  1156. }
  1157. @@ -1568,7 +1552,7 @@
  1158. cdf_u16tos8(sbuf, ce[i].ce_namlen, ce[i].ce_name),
  1159. cdf_ctime(&ts.tv_sec, tbuf));
  1160. }
  1161. - free(cat);
  1162. + efree(cat);
  1163. }
  1164. #endif
  1165. diff -u libmagic.orig/cdf.h libmagic/cdf.h
  1166. --- libmagic.orig/cdf.h 2021-02-23 01:49:06.000000000 +0100
  1167. +++ libmagic/cdf.h 2021-09-21 13:27:27.984674900 +0200
  1168. @@ -35,10 +35,10 @@
  1169. #ifndef _H_CDF_
  1170. #define _H_CDF_
  1171. -#ifdef WIN32
  1172. +#ifdef PHP_WIN32
  1173. #include <winsock2.h>
  1174. -#define timespec timeval
  1175. -#define tv_nsec tv_usec
  1176. +#define asctime_r php_asctime_r
  1177. +#define ctime_r php_ctime_r
  1178. #endif
  1179. #ifdef __DJGPP__
  1180. #define timespec timeval
  1181. diff -u libmagic.orig/cdf_time.c libmagic/cdf_time.c
  1182. --- libmagic.orig/cdf_time.c 2021-02-23 01:49:06.000000000 +0100
  1183. +++ libmagic/cdf_time.c 2021-09-21 13:27:27.985654400 +0200
  1184. @@ -23,6 +23,7 @@
  1185. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  1186. * POSSIBILITY OF SUCH DAMAGE.
  1187. */
  1188. +#include "php.h"
  1189. #include "file.h"
  1190. @@ -152,7 +153,7 @@
  1191. #endif
  1192. #ifdef notyet
  1193. struct tm tm;
  1194. - if (gmtime_r(&ts->ts_sec, &tm) == NULL) {
  1195. + if (php_gmtime_r(&ts->ts_sec, &tm) == NULL) {
  1196. errno = EINVAL;
  1197. return -1;
  1198. }
  1199. @@ -168,7 +169,7 @@
  1200. char *
  1201. cdf_ctime(const time_t *sec, char *buf)
  1202. {
  1203. - char *ptr = ctime_r(sec, buf);
  1204. + char *ptr = php_ctime_r(sec, buf);
  1205. if (ptr != NULL)
  1206. return buf;
  1207. (void)snprintf(buf, 26, "*Bad* %#16.16" INT64_T_FORMAT "x\n",
  1208. diff -u libmagic.orig/compress.c libmagic/compress.c
  1209. --- libmagic.orig/compress.c 2021-02-23 01:49:07.000000000 +0100
  1210. +++ libmagic/compress.c 2022-06-16 13:39:41.586609800 +0200
  1211. @@ -51,7 +51,7 @@
  1212. #ifndef HAVE_SIG_T
  1213. typedef void (*sig_t)(int);
  1214. #endif /* HAVE_SIG_T */
  1215. -#if !defined(__MINGW32__) && !defined(WIN32) && !defined(__MINGW64__)
  1216. +#ifndef PHP_WIN32
  1217. #include <sys/ioctl.h>
  1218. #endif
  1219. #ifdef HAVE_SYS_WAIT_H
  1220. @@ -60,13 +60,14 @@
  1221. #if defined(HAVE_SYS_TIME_H)
  1222. #include <sys/time.h>
  1223. #endif
  1224. -
  1225. -#if defined(HAVE_ZLIB_H) && defined(ZLIBSUPPORT)
  1226. +#if defined(HAVE_ZLIB_H) && defined(PHP_FILEINFO_UNCOMPRESS)
  1227. #define BUILTIN_DECOMPRESS
  1228. #include <zlib.h>
  1229. #endif
  1230. -#if defined(HAVE_BZLIB_H) && defined(BZLIBSUPPORT)
  1231. +#undef FIONREAD
  1232. +
  1233. +#if defined(PHP_FILEINFO_UNCOMPRESS)
  1234. #define BUILTIN_BZLIB
  1235. #include <bzlib.h>
  1236. #endif
  1237. @@ -118,6 +119,8 @@
  1238. }
  1239. #endif
  1240. +#ifdef PHP_FILEINFO_UNCOMPRESS
  1241. +
  1242. static int
  1243. lzmacmp(const unsigned char *buf)
  1244. {
  1245. @@ -221,8 +224,7 @@
  1246. size_t *);
  1247. #endif
  1248. -static int makeerror(unsigned char **, size_t *, const char *, ...)
  1249. - __attribute__((__format__(__printf__, 3, 4)));
  1250. +static int makeerror(unsigned char **, size_t *, const char *, ...);
  1251. private const char *methodname(size_t);
  1252. private int
  1253. @@ -294,7 +296,7 @@
  1254. if (urv == ERRDATA)
  1255. prv = format_decompression_error(ms, i, newbuf);
  1256. else
  1257. - prv = file_buffer(ms, -1, NULL, name, newbuf, nsz);
  1258. + prv = file_buffer(ms, NULL, NULL, name, newbuf, nsz);
  1259. if (prv == -1)
  1260. goto error;
  1261. rv = 1;
  1262. @@ -311,17 +313,17 @@
  1263. * XXX: If file_buffer fails here, we overwrite
  1264. * the compressed text. FIXME.
  1265. */
  1266. - if (file_buffer(ms, -1, NULL, NULL, buf, nbytes) == -1) {
  1267. + if (file_buffer(ms, NULL, NULL, NULL, buf, nbytes) == -1) {
  1268. if (file_pop_buffer(ms, pb) != NULL)
  1269. abort();
  1270. goto error;
  1271. }
  1272. if ((rbuf = file_pop_buffer(ms, pb)) != NULL) {
  1273. if (file_printf(ms, "%s", rbuf) == -1) {
  1274. - free(rbuf);
  1275. + efree(rbuf);
  1276. goto error;
  1277. }
  1278. - free(rbuf);
  1279. + efree(rbuf);
  1280. }
  1281. if (!mime && file_printf(ms, ")") == -1)
  1282. goto error;
  1283. @@ -342,7 +344,8 @@
  1284. if (sa_saved && sig_act.sa_handler != SIG_IGN)
  1285. (void)sigaction(SIGPIPE, &sig_act, NULL);
  1286. - free(newbuf);
  1287. + if (newbuf)
  1288. + efree(newbuf);
  1289. ms->flags |= MAGIC_COMPRESS;
  1290. DPRINTF("Zmagic returns %d\n", rv);
  1291. return rv;
  1292. @@ -377,7 +380,7 @@
  1293. * `safe' read for sockets and pipes.
  1294. */
  1295. protected ssize_t
  1296. -sread(int fd, void *buf, size_t n, int canbepipe __attribute__((__unused__)))
  1297. +sread(int fd, void *buf, size_t n, int canbepipe)
  1298. {
  1299. ssize_t rv;
  1300. #ifdef FIONREAD
  1301. @@ -425,7 +428,7 @@
  1302. nocheck:
  1303. do
  1304. - switch ((rv = read(fd, buf, n))) {
  1305. + switch ((rv = FINFO_READ_FUNC(fd, buf, n))) {
  1306. case -1:
  1307. if (errno == EINTR)
  1308. continue;
  1309. @@ -504,13 +507,13 @@
  1310. return -1;
  1311. }
  1312. (void)close(tfd);
  1313. - if (lseek(fd, CAST(off_t, 0), SEEK_SET) == CAST(off_t, -1)) {
  1314. + if (FINFO_LSEEK_FUNC(fd, (zend_off_t)0, SEEK_SET) == (zend_off_t)-1) {
  1315. file_badseek(ms);
  1316. return -1;
  1317. }
  1318. return fd;
  1319. }
  1320. -#if HAVE_FORK
  1321. +#ifdef PHP_FILEINFO_UNCOMPRESS
  1322. #ifdef BUILTIN_DECOMPRESS
  1323. #define FHCRC (1 << 1)
  1324. @@ -561,7 +564,7 @@
  1325. int rc;
  1326. z_stream z;
  1327. - if ((*newch = CAST(unsigned char *, malloc(bytes_max + 1))) == NULL)
  1328. + if ((*newch = CAST(unsigned char *, emalloc(bytes_max + 1))) == NULL)
  1329. return makeerror(newch, n, "No buffer, %s", strerror(errno));
  1330. z.next_in = CCAST(Bytef *, old);
  1331. @@ -986,3 +989,4 @@
  1332. return rv;
  1333. }
  1334. #endif
  1335. +#endif
  1336. diff -u libmagic.orig/der.c libmagic/der.c
  1337. --- libmagic.orig/der.c 2021-02-23 01:49:06.000000000 +0100
  1338. +++ libmagic/der.c 2022-06-16 13:39:41.586609800 +0200
  1339. @@ -54,7 +54,9 @@
  1340. #include "magic.h"
  1341. #include "der.h"
  1342. #else
  1343. +#ifndef PHP_WIN32
  1344. #include <sys/mman.h>
  1345. +#endif
  1346. #include <sys/stat.h>
  1347. #include <err.h>
  1348. #endif
  1349. diff -u libmagic.orig/elfclass.h libmagic/elfclass.h
  1350. --- libmagic.orig/elfclass.h 2021-02-23 01:49:06.000000000 +0100
  1351. +++ libmagic/elfclass.h 2021-09-21 13:27:27.989571700 +0200
  1352. @@ -41,7 +41,7 @@
  1353. return toomany(ms, "program headers", phnum);
  1354. flags |= FLAGS_IS_CORE;
  1355. if (dophn_core(ms, clazz, swap, fd,
  1356. - CAST(off_t, elf_getu(swap, elfhdr.e_phoff)), phnum,
  1357. + CAST(zend_off_t, elf_getu(swap, elfhdr.e_phoff)), phnum,
  1358. CAST(size_t, elf_getu16(swap, elfhdr.e_phentsize)),
  1359. fsize, &flags, &notecount) == -1)
  1360. return -1;
  1361. @@ -56,7 +56,7 @@
  1362. if (shnum > ms->elf_shnum_max)
  1363. return toomany(ms, "section", shnum);
  1364. if (dophn_exec(ms, clazz, swap, fd,
  1365. - CAST(off_t, elf_getu(swap, elfhdr.e_phoff)), phnum,
  1366. + CAST(zend_off_t, elf_getu(swap, elfhdr.e_phoff)), phnum,
  1367. CAST(size_t, elf_getu16(swap, elfhdr.e_phentsize)),
  1368. fsize, shnum, &flags, &notecount) == -1)
  1369. return -1;
  1370. @@ -66,7 +66,7 @@
  1371. if (shnum > ms->elf_shnum_max)
  1372. return toomany(ms, "section headers", shnum);
  1373. if (doshn(ms, clazz, swap, fd,
  1374. - CAST(off_t, elf_getu(swap, elfhdr.e_shoff)), shnum,
  1375. + CAST(zend_off_t, elf_getu(swap, elfhdr.e_shoff)), shnum,
  1376. CAST(size_t, elf_getu16(swap, elfhdr.e_shentsize)),
  1377. fsize, elf_getu16(swap, elfhdr.e_machine),
  1378. CAST(int, elf_getu16(swap, elfhdr.e_shstrndx)),
  1379. diff -u libmagic.orig/encoding.c libmagic/encoding.c
  1380. --- libmagic.orig/encoding.c 2021-02-23 01:49:06.000000000 +0100
  1381. +++ libmagic/encoding.c 2022-06-16 13:39:41.586609800 +0200
  1382. @@ -98,14 +98,14 @@
  1383. nbytes = ms->encoding_max;
  1384. mlen = (nbytes + 1) * sizeof((*ubuf)[0]);
  1385. - *ubuf = CAST(file_unichar_t *, calloc(CAST(size_t, 1), mlen));
  1386. + *ubuf = CAST(file_unichar_t *, ecalloc(CAST(size_t, 1), mlen));
  1387. if (*ubuf == NULL) {
  1388. file_oomem(ms, mlen);
  1389. goto done;
  1390. }
  1391. mlen = (nbytes + 1) * sizeof(nbuf[0]);
  1392. if ((nbuf = CAST(unsigned char *,
  1393. - calloc(CAST(size_t, 1), mlen))) == NULL) {
  1394. + ecalloc(CAST(size_t, 1), mlen))) == NULL) {
  1395. file_oomem(ms, mlen);
  1396. goto done;
  1397. }
  1398. @@ -174,9 +174,9 @@
  1399. }
  1400. done:
  1401. - free(nbuf);
  1402. + efree(nbuf);
  1403. if (ubuf == &udefbuf)
  1404. - free(udefbuf);
  1405. + efree(udefbuf);
  1406. return rv;
  1407. }
  1408. @@ -283,7 +283,7 @@
  1409. u = 0; \
  1410. for (i = 0; i < __arraycount(dist); i++) { \
  1411. if (dist[i]) \
  1412. - u++; \
  1413. + u += dist[i]; \
  1414. } \
  1415. if (u < 3) \
  1416. return 0; \
  1417. diff -u libmagic.orig/file.h libmagic/file.h
  1418. --- libmagic.orig/file.h 2021-02-23 01:49:06.000000000 +0100
  1419. +++ libmagic/file.h 2022-06-16 13:39:41.586609800 +0200
  1420. @@ -33,17 +33,14 @@
  1421. #ifndef __file_h__
  1422. #define __file_h__
  1423. -#ifdef HAVE_CONFIG_H
  1424. -#include <config.h>
  1425. -#endif
  1426. +#include "config.h"
  1427. -#ifdef HAVE_STDINT_H
  1428. -#include <stdint.h>
  1429. -#endif
  1430. +#include "php.h"
  1431. +#include "ext/standard/php_string.h"
  1432. +#include "ext/pcre/php_pcre.h"
  1433. -#ifdef HAVE_INTTYPES_H
  1434. +#include <stdint.h>
  1435. #include <inttypes.h>
  1436. -#endif
  1437. #ifndef __STDC_LIMIT_MACROS
  1438. #define __STDC_LIMIT_MACROS
  1439. @@ -79,23 +76,26 @@
  1440. #include <stdio.h> /* Include that here, to make sure __P gets defined */
  1441. #include <errno.h>
  1442. #include <fcntl.h> /* For open and flags */
  1443. -#include <regex.h>
  1444. -#include <time.h>
  1445. +
  1446. #include <sys/types.h>
  1447. -#ifndef WIN32
  1448. +#ifdef PHP_WIN32
  1449. +#include "win32/param.h"
  1450. +#else
  1451. #include <sys/param.h>
  1452. #endif
  1453. /* Do this here and now, because struct stat gets re-defined on solaris */
  1454. #include <sys/stat.h>
  1455. #include <stdarg.h>
  1456. +#define abort() zend_error_noreturn(E_ERROR, "fatal libmagic error")
  1457. +
  1458. #define ENABLE_CONDITIONALS
  1459. #ifndef MAGIC
  1460. #define MAGIC "/etc/magic"
  1461. #endif
  1462. -#if defined(__EMX__) || defined (WIN32)
  1463. +#if defined(__EMX__) || defined(PHP_WIN32)
  1464. #define PATHSEP ';'
  1465. #else
  1466. #define PATHSEP ':'
  1467. @@ -129,12 +129,6 @@
  1468. #endif
  1469. #endif
  1470. -#ifndef __GNUC__
  1471. -#ifndef __attribute__
  1472. -#define __attribute__(a)
  1473. -#endif
  1474. -#endif
  1475. -
  1476. #ifndef MIN
  1477. #define MIN(a,b) (((a) < (b)) ? (a) : (b))
  1478. #endif
  1479. @@ -169,10 +163,10 @@
  1480. struct buffer {
  1481. int fd;
  1482. - struct stat st;
  1483. + zend_stat_t st;
  1484. const void *fbuf;
  1485. size_t flen;
  1486. - off_t eoff;
  1487. + zend_off_t eoff;
  1488. void *ebuf;
  1489. size_t elen;
  1490. };
  1491. @@ -266,7 +260,7 @@
  1492. #define FILE_OFFSET 50
  1493. #define FILE_NAMES_SIZE 51 /* size of array to contain all names */
  1494. -#define IS_STRING(t) \
  1495. +#define IS_LIBMAGIC_STRING(t) \
  1496. ((t) == FILE_STRING || \
  1497. (t) == FILE_PSTRING || \
  1498. (t) == FILE_BESTRING16 || \
  1499. @@ -484,13 +478,11 @@
  1500. protected const char *file_fmttime(char *, size_t, uint64_t, int);
  1501. protected struct magic_set *file_ms_alloc(int);
  1502. protected void file_ms_free(struct magic_set *);
  1503. -protected int file_default(struct magic_set *, size_t);
  1504. -protected int file_buffer(struct magic_set *, int, struct stat *, const char *,
  1505. - const void *, size_t);
  1506. -protected int file_fsmagic(struct magic_set *, const char *, struct stat *);
  1507. +protected int file_buffer(struct magic_set *, php_stream *, zend_stat_t *, const char *, const void *,
  1508. + size_t);
  1509. +protected int file_fsmagic(struct magic_set *, const char *, zend_stat_t *);
  1510. protected int file_pipe2file(struct magic_set *, int, const void *, size_t);
  1511. -protected int file_vprintf(struct magic_set *, const char *, va_list)
  1512. - __attribute__((__format__(__printf__, 2, 0)));
  1513. +protected int file_vprintf(struct magic_set *, const char *, va_list);
  1514. protected int file_separator(struct magic_set *);
  1515. protected char *file_copystr(char *, size_t, size_t, const char *);
  1516. protected int file_checkfmt(char *, size_t, const char *);
  1517. @@ -498,12 +490,11 @@
  1518. protected int file_print_guid(char *, size_t, const uint64_t *);
  1519. protected int file_parse_guid(const char *, uint64_t *);
  1520. protected int file_replace(struct magic_set *, const char *, const char *);
  1521. -protected int file_printf(struct magic_set *, const char *, ...)
  1522. - __attribute__((__format__(__printf__, 2, 3)));
  1523. +protected int file_printf(struct magic_set *, const char *, ...);
  1524. protected int file_reset(struct magic_set *, int);
  1525. protected int file_tryelf(struct magic_set *, const struct buffer *);
  1526. protected int file_trycdf(struct magic_set *, const struct buffer *);
  1527. -#if HAVE_FORK
  1528. +#ifdef PHP_FILEINFO_UNCOMPRESS
  1529. protected int file_zmagic(struct magic_set *, const struct buffer *,
  1530. const char *);
  1531. #endif
  1532. @@ -527,12 +518,9 @@
  1533. protected void file_badread(struct magic_set *);
  1534. protected void file_badseek(struct magic_set *);
  1535. protected void file_oomem(struct magic_set *, size_t);
  1536. -protected void file_error(struct magic_set *, int, const char *, ...)
  1537. - __attribute__((__format__(__printf__, 3, 4)));
  1538. -protected void file_magerror(struct magic_set *, const char *, ...)
  1539. - __attribute__((__format__(__printf__, 2, 3)));
  1540. -protected void file_magwarn(struct magic_set *, const char *, ...)
  1541. - __attribute__((__format__(__printf__, 2, 3)));
  1542. +protected void file_error(struct magic_set *, int, const char *, ...);
  1543. +protected void file_magerror(struct magic_set *, const char *, ...);
  1544. +protected void file_magwarn(struct magic_set *, const char *, ...);
  1545. protected void file_mdump(struct magic *);
  1546. protected void file_showstr(FILE *, const char *, size_t);
  1547. protected size_t file_mbswidth(const char *);
  1548. @@ -554,34 +542,12 @@
  1549. protected int file_clear_closexec(int);
  1550. protected char *file_strtrim(char *);
  1551. -protected void buffer_init(struct buffer *, int, const struct stat *,
  1552. +protected void buffer_init(struct buffer *, int, const zend_stat_t *,
  1553. const void *, size_t);
  1554. protected void buffer_fini(struct buffer *);
  1555. protected int buffer_fill(const struct buffer *);
  1556. -#include <locale.h>
  1557. -#if defined(HAVE_XLOCALE_H)
  1558. -#include <xlocale.h>
  1559. -#endif
  1560. -
  1561. -typedef struct {
  1562. - const char *pat;
  1563. -#if defined(HAVE_NEWLOCALE) && defined(HAVE_USELOCALE) && defined(HAVE_FREELOCALE)
  1564. -#define USE_C_LOCALE
  1565. - locale_t old_lc_ctype;
  1566. - locale_t c_lc_ctype;
  1567. -#else
  1568. - char *old_lc_ctype;
  1569. -#endif
  1570. - int rc;
  1571. - regex_t rx;
  1572. -} file_regex_t;
  1573. -
  1574. -protected int file_regcomp(file_regex_t *, const char *, int);
  1575. -protected int file_regexec(file_regex_t *, const char *, size_t, regmatch_t *,
  1576. - int);
  1577. -protected void file_regfree(file_regex_t *);
  1578. -protected void file_regerror(file_regex_t *, int, struct magic_set *);
  1579. +public zend_string* convert_libmagic_pattern(const char *val, size_t len, uint32_t options);
  1580. typedef struct {
  1581. char *buf;
  1582. @@ -597,23 +563,10 @@
  1583. extern const size_t file_nnames;
  1584. #endif
  1585. -#ifndef HAVE_PREAD
  1586. -ssize_t pread(int, void *, size_t, off_t);
  1587. -#endif
  1588. -#ifndef HAVE_VASPRINTF
  1589. -int vasprintf(char **, const char *, va_list);
  1590. -#endif
  1591. -#ifndef HAVE_ASPRINTF
  1592. -int asprintf(char **, const char *, ...);
  1593. -#endif
  1594. -#ifndef HAVE_DPRINTF
  1595. -int dprintf(int, const char *, ...);
  1596. -#endif
  1597. -
  1598. -#ifndef HAVE_STRLCPY
  1599. +#ifndef strlcpy
  1600. size_t strlcpy(char *, const char *, size_t);
  1601. #endif
  1602. -#ifndef HAVE_STRLCAT
  1603. +#ifndef strlcat
  1604. size_t strlcat(char *, const char *, size_t);
  1605. #endif
  1606. #ifndef HAVE_STRCASESTR
  1607. @@ -629,39 +582,6 @@
  1608. #ifndef HAVE_ASCTIME_R
  1609. char *asctime_r(const struct tm *, char *);
  1610. #endif
  1611. -#ifndef HAVE_GMTIME_R
  1612. -struct tm *gmtime_r(const time_t *, struct tm *);
  1613. -#endif
  1614. -#ifndef HAVE_LOCALTIME_R
  1615. -struct tm *localtime_r(const time_t *, struct tm *);
  1616. -#endif
  1617. -#ifndef HAVE_FMTCHECK
  1618. -const char *fmtcheck(const char *, const char *)
  1619. - __attribute__((__format_arg__(2)));
  1620. -#endif
  1621. -
  1622. -#ifdef HAVE_LIBSECCOMP
  1623. -// basic filter
  1624. -// this mode should not interfere with normal operations
  1625. -// only some dangerous syscalls are blacklisted
  1626. -int enable_sandbox_basic(void);
  1627. -
  1628. -// enhanced filter
  1629. -// this mode allows only the necessary syscalls used during normal operation
  1630. -// extensive testing required !!!
  1631. -int enable_sandbox_full(void);
  1632. -#endif
  1633. -
  1634. -protected const char *file_getprogname(void);
  1635. -protected void file_setprogname(const char *);
  1636. -protected void file_err(int, const char *, ...)
  1637. - __attribute__((__format__(__printf__, 2, 3), __noreturn__));
  1638. -protected void file_errx(int, const char *, ...)
  1639. - __attribute__((__format__(__printf__, 2, 3), __noreturn__));
  1640. -protected void file_warn(const char *, ...)
  1641. - __attribute__((__format__(__printf__, 1, 2)));
  1642. -protected void file_warnx(const char *, ...)
  1643. - __attribute__((__format__(__printf__, 1, 2)));
  1644. #if defined(HAVE_MMAP) && defined(HAVE_SYS_MMAN_H) && !defined(QUICK)
  1645. #define QUICK
  1646. @@ -691,4 +611,16 @@
  1647. #define __RCSID(a)
  1648. #endif
  1649. +#ifdef PHP_WIN32
  1650. +#ifdef _WIN64
  1651. +#define FINFO_LSEEK_FUNC _lseeki64
  1652. +#else
  1653. +#define FINFO_LSEEK_FUNC _lseek
  1654. +#endif
  1655. +#define FINFO_READ_FUNC _read
  1656. +#else
  1657. +#define FINFO_LSEEK_FUNC lseek
  1658. +#define FINFO_READ_FUNC read
  1659. +#endif
  1660. +
  1661. #endif /* __file_h__ */
  1662. diff -u libmagic.orig/fsmagic.c libmagic/fsmagic.c
  1663. --- libmagic.orig/fsmagic.c 2021-02-23 01:49:06.000000000 +0100
  1664. +++ libmagic/fsmagic.c 2021-09-21 13:27:27.992511000 +0200
  1665. @@ -66,26 +66,10 @@
  1666. # define minor(dev) ((dev) & 0xff)
  1667. #endif
  1668. #undef HAVE_MAJOR
  1669. -#ifdef S_IFLNK
  1670. -private int
  1671. -bad_link(struct magic_set *ms, int err, char *buf)
  1672. -{
  1673. - int mime = ms->flags & MAGIC_MIME;
  1674. - if ((mime & MAGIC_MIME_TYPE) &&
  1675. - file_printf(ms, "inode/symlink")
  1676. - == -1)
  1677. - return -1;
  1678. - else if (!mime) {
  1679. - if (ms->flags & MAGIC_ERROR) {
  1680. - file_error(ms, err,
  1681. - "broken symbolic link to %s", buf);
  1682. - return -1;
  1683. - }
  1684. - if (file_printf(ms, "broken symbolic link to %s", buf) == -1)
  1685. - return -1;
  1686. - }
  1687. - return 1;
  1688. -}
  1689. +
  1690. +#ifdef PHP_WIN32
  1691. +
  1692. +# undef S_IFIFO
  1693. #endif
  1694. private int
  1695. handle_mime(struct magic_set *ms, int mime, const char *str)
  1696. @@ -103,60 +87,17 @@
  1697. }
  1698. protected int
  1699. -file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb)
  1700. +file_fsmagic(struct magic_set *ms, const char *fn, zend_stat_t *sb)
  1701. {
  1702. int ret, did = 0;
  1703. int mime = ms->flags & MAGIC_MIME;
  1704. int silent = ms->flags & (MAGIC_APPLE|MAGIC_EXTENSION);
  1705. -#ifdef S_IFLNK
  1706. - char buf[BUFSIZ+4];
  1707. - ssize_t nch;
  1708. - struct stat tstatbuf;
  1709. -#endif
  1710. if (fn == NULL)
  1711. return 0;
  1712. #define COMMA (did++ ? ", " : "")
  1713. - /*
  1714. - * Fstat is cheaper but fails for files you don't have read perms on.
  1715. - * On 4.2BSD and similar systems, use lstat() to identify symlinks.
  1716. - */
  1717. -#ifdef S_IFLNK
  1718. - if ((ms->flags & MAGIC_SYMLINK) == 0)
  1719. - ret = lstat(fn, sb);
  1720. - else
  1721. -#endif
  1722. - ret = stat(fn, sb); /* don't merge into if; see "ret =" above */
  1723. -
  1724. -#ifdef WIN32
  1725. - {
  1726. - HANDLE hFile = CreateFile((LPCSTR)fn, 0, FILE_SHARE_DELETE |
  1727. - FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0,
  1728. - NULL);
  1729. - if (hFile != INVALID_HANDLE_VALUE) {
  1730. - /*
  1731. - * Stat failed, but we can still open it - assume it's
  1732. - * a block device, if nothing else.
  1733. - */
  1734. - if (ret) {
  1735. - sb->st_mode = S_IFBLK;
  1736. - ret = 0;
  1737. - }
  1738. - switch (GetFileType(hFile)) {
  1739. - case FILE_TYPE_CHAR:
  1740. - sb->st_mode |= S_IFCHR;
  1741. - sb->st_mode &= ~S_IFREG;
  1742. - break;
  1743. - case FILE_TYPE_PIPE:
  1744. - sb->st_mode |= S_IFIFO;
  1745. - sb->st_mode &= ~S_IFREG;
  1746. - break;
  1747. - }
  1748. - CloseHandle(hFile);
  1749. - }
  1750. - }
  1751. -#endif
  1752. + ret = php_sys_stat(fn, sb);
  1753. if (ret) {
  1754. if (ms->flags & MAGIC_ERROR) {
  1755. @@ -189,32 +130,24 @@
  1756. }
  1757. switch (sb->st_mode & S_IFMT) {
  1758. - case S_IFDIR:
  1759. - if (mime) {
  1760. - if (handle_mime(ms, mime, "directory") == -1)
  1761. - return -1;
  1762. - } else if (silent) {
  1763. - } else if (file_printf(ms, "%sdirectory", COMMA) == -1)
  1764. - return -1;
  1765. - break;
  1766. -#ifdef S_IFCHR
  1767. - case S_IFCHR:
  1768. - /*
  1769. - * If -s has been specified, treat character special files
  1770. - * like ordinary files. Otherwise, just report that they
  1771. - * are block special files and go on to the next file.
  1772. - */
  1773. - if ((ms->flags & MAGIC_DEVICES) != 0) {
  1774. - ret = 0;
  1775. - break;
  1776. - }
  1777. - if (mime) {
  1778. - if (handle_mime(ms, mime, "chardevice") == -1)
  1779. - return -1;
  1780. - } else if (silent) {
  1781. - } else {
  1782. -#ifdef HAVE_STRUCT_STAT_ST_RDEV
  1783. -# ifdef dv_unit
  1784. +#ifndef PHP_WIN32
  1785. +# ifdef S_IFCHR
  1786. + case S_IFCHR:
  1787. + /*
  1788. + * If -s has been specified, treat character special files
  1789. + * like ordinary files. Otherwise, just report that they
  1790. + * are block special files and go on to the next file.
  1791. + */
  1792. + if ((ms->flags & MAGIC_DEVICES) != 0) {
  1793. + ret = 0;
  1794. + break;
  1795. + }
  1796. + if (mime) {
  1797. + if (handle_mime(ms, mime, "chardevice") == -1)
  1798. + return -1;
  1799. + } else {
  1800. +# ifdef HAVE_STAT_ST_RDEV
  1801. +# ifdef dv_unit
  1802. if (file_printf(ms, "%scharacter special (%d/%d/%d)",
  1803. COMMA, major(sb->st_rdev), dv_unit(sb->st_rdev),
  1804. dv_subunit(sb->st_rdev)) == -1)
  1805. @@ -229,45 +162,11 @@
  1806. if (file_printf(ms, "%scharacter special", COMMA) == -1)
  1807. return -1;
  1808. #endif
  1809. - }
  1810. - break;
  1811. -#endif
  1812. -#ifdef S_IFBLK
  1813. - case S_IFBLK:
  1814. - /*
  1815. - * If -s has been specified, treat block special files
  1816. - * like ordinary files. Otherwise, just report that they
  1817. - * are block special files and go on to the next file.
  1818. - */
  1819. - if ((ms->flags & MAGIC_DEVICES) != 0) {
  1820. - ret = 0;
  1821. - break;
  1822. - }
  1823. - if (mime) {
  1824. - if (handle_mime(ms, mime, "blockdevice") == -1)
  1825. - return -1;
  1826. - } else if (silent) {
  1827. - } else {
  1828. -#ifdef HAVE_STRUCT_STAT_ST_RDEV
  1829. -# ifdef dv_unit
  1830. - if (file_printf(ms, "%sblock special (%d/%d/%d)",
  1831. - COMMA, major(sb->st_rdev), dv_unit(sb->st_rdev),
  1832. - dv_subunit(sb->st_rdev)) == -1)
  1833. - return -1;
  1834. -# else
  1835. - if (file_printf(ms, "%sblock special (%ld/%ld)",
  1836. - COMMA, (long)major(sb->st_rdev),
  1837. - (long)minor(sb->st_rdev)) == -1)
  1838. - return -1;
  1839. + }
  1840. + return 1;
  1841. # endif
  1842. -#else
  1843. - if (file_printf(ms, "%sblock special", COMMA) == -1)
  1844. - return -1;
  1845. #endif
  1846. - }
  1847. - break;
  1848. -#endif
  1849. - /* TODO add code to handle V7 MUX and Blit MUX files */
  1850. +
  1851. #ifdef S_IFIFO
  1852. case S_IFIFO:
  1853. if((ms->flags & MAGIC_DEVICES) != 0)
  1854. @@ -292,92 +191,14 @@
  1855. #endif
  1856. #ifdef S_IFLNK
  1857. case S_IFLNK:
  1858. - if ((nch = readlink(fn, buf, BUFSIZ-1)) <= 0) {
  1859. + /* stat is used, if it made here then the link is broken */
  1860. if (ms->flags & MAGIC_ERROR) {
  1861. - file_error(ms, errno, "unreadable symlink `%s'",
  1862. - fn);
  1863. + file_error(ms, errno, "unreadable symlink `%s'", fn);
  1864. return -1;
  1865. }
  1866. - if (mime) {
  1867. - if (handle_mime(ms, mime, "symlink") == -1)
  1868. - return -1;
  1869. - } else if (silent) {
  1870. - } else if (file_printf(ms,
  1871. - "%sunreadable symlink `%s' (%s)", COMMA, fn,
  1872. - strerror(errno)) == -1)
  1873. - return -1;
  1874. - break;
  1875. - }
  1876. - buf[nch] = '\0'; /* readlink(2) does not do this */
  1877. -
  1878. - /* If broken symlink, say so and quit early. */
  1879. -#ifdef __linux__
  1880. - /*
  1881. - * linux procfs/devfs makes symlinks like pipe:[3515864880]
  1882. - * that we can't stat their readlink output, so stat the
  1883. - * original filename instead.
  1884. - */
  1885. - if (stat(fn, &tstatbuf) < 0)
  1886. - return bad_link(ms, errno, buf);
  1887. -#else
  1888. - if (*buf == '/') {
  1889. - if (stat(buf, &tstatbuf) < 0)
  1890. - return bad_link(ms, errno, buf);
  1891. - } else {
  1892. - char *tmp;
  1893. - char buf2[BUFSIZ+BUFSIZ+4];
  1894. -
  1895. - if ((tmp = strrchr(fn, '/')) == NULL) {
  1896. - tmp = buf; /* in current directory anyway */
  1897. - } else {
  1898. - if (tmp - fn + 1 > BUFSIZ) {
  1899. - if (ms->flags & MAGIC_ERROR) {
  1900. - file_error(ms, 0,
  1901. - "path too long: `%s'", buf);
  1902. - return -1;
  1903. - }
  1904. - if (mime) {
  1905. - if (handle_mime(ms, mime,
  1906. - "x-path-too-long") == -1)
  1907. - return -1;
  1908. - } else if (silent) {
  1909. - } else if (file_printf(ms,
  1910. - "%spath too long: `%s'", COMMA,
  1911. - fn) == -1)
  1912. - return -1;
  1913. - break;
  1914. - }
  1915. - /* take dir part */
  1916. - (void)strlcpy(buf2, fn, sizeof buf2);
  1917. - buf2[tmp - fn + 1] = '\0';
  1918. - /* plus (rel) link */
  1919. - (void)strlcat(buf2, buf, sizeof buf2);
  1920. - tmp = buf2;
  1921. - }
  1922. - if (stat(tmp, &tstatbuf) < 0)
  1923. - return bad_link(ms, errno, buf);
  1924. - }
  1925. + return 1;
  1926. #endif
  1927. - /* Otherwise, handle it. */
  1928. - if ((ms->flags & MAGIC_SYMLINK) != 0) {
  1929. - const char *p;
  1930. - ms->flags &= MAGIC_SYMLINK;
  1931. - p = magic_file(ms, buf);
  1932. - ms->flags |= MAGIC_SYMLINK;
  1933. - if (p == NULL)
  1934. - return -1;
  1935. - } else { /* just print what it points to */
  1936. - if (mime) {
  1937. - if (handle_mime(ms, mime, "symlink") == -1)
  1938. - return -1;
  1939. - } else if (silent) {
  1940. - } else if (file_printf(ms, "%ssymbolic link to %s",
  1941. - COMMA, buf) == -1)
  1942. - return -1;
  1943. - }
  1944. - break;
  1945. -#endif
  1946. #ifdef S_IFSOCK
  1947. #ifndef __COHERENT__
  1948. case S_IFSOCK:
  1949. diff -u libmagic.orig/funcs.c libmagic/funcs.c
  1950. --- libmagic.orig/funcs.c 2021-02-23 01:49:06.000000000 +0100
  1951. +++ libmagic/funcs.c 2022-06-16 13:39:41.586609800 +0200
  1952. @@ -51,6 +51,13 @@
  1953. #define SIZE_MAX ((size_t)~0)
  1954. #endif
  1955. +#include "php.h"
  1956. +#include "main/php_network.h"
  1957. +
  1958. +#ifndef PREG_OFFSET_CAPTURE
  1959. +# define PREG_OFFSET_CAPTURE (1<<8)
  1960. +#endif
  1961. +
  1962. protected char *
  1963. file_copystr(char *buf, size_t blen, size_t width, const char *str)
  1964. {
  1965. @@ -63,7 +70,7 @@
  1966. private void
  1967. file_clearbuf(struct magic_set *ms)
  1968. {
  1969. - free(ms->o.buf);
  1970. + efree(ms->o.buf);
  1971. ms->o.buf = NULL;
  1972. ms->o.blen = 0;
  1973. }
  1974. @@ -128,7 +135,7 @@
  1975. protected int
  1976. file_vprintf(struct magic_set *ms, const char *fmt, va_list ap)
  1977. {
  1978. - int len;
  1979. + size_t len;
  1980. char *buf, *newstr;
  1981. char tbuf[1024];
  1982. @@ -141,10 +148,10 @@
  1983. return -1;
  1984. }
  1985. - len = vasprintf(&buf, fmt, ap);
  1986. - if (len < 0 || (size_t)len > 1024 || len + ms->o.blen > 1024 * 1024) {
  1987. + len = vspprintf(&buf, 0, fmt, ap);
  1988. + if (len > 1024 || len + ms->o.blen > 1024 * 1024) {
  1989. size_t blen = ms->o.blen;
  1990. - free(buf);
  1991. + if (buf) efree(buf);
  1992. file_clearbuf(ms);
  1993. file_error(ms, 0, "Output buffer space exceeded %d+%zu", len,
  1994. blen);
  1995. @@ -152,20 +159,14 @@
  1996. }
  1997. if (ms->o.buf != NULL) {
  1998. - len = asprintf(&newstr, "%s%s", ms->o.buf, buf);
  1999. - free(buf);
  2000. - if (len < 0)
  2001. - goto out;
  2002. - free(ms->o.buf);
  2003. + len = spprintf(&newstr, 0, "%s%s", ms->o.buf, buf);
  2004. + efree(buf);
  2005. + efree(ms->o.buf);
  2006. buf = newstr;
  2007. }
  2008. ms->o.buf = buf;
  2009. ms->o.blen = len;
  2010. return 0;
  2011. -out:
  2012. - file_clearbuf(ms);
  2013. - file_error(ms, errno, "vasprintf failed");
  2014. - return -1;
  2015. }
  2016. protected int
  2017. @@ -184,7 +185,6 @@
  2018. * error - print best error message possible
  2019. */
  2020. /*VARARGS*/
  2021. -__attribute__((__format__(__printf__, 3, 0)))
  2022. private void
  2023. file_error_core(struct magic_set *ms, int error, const char *f, va_list va,
  2024. size_t lineno)
  2025. @@ -316,8 +316,8 @@
  2026. */
  2027. /*ARGSUSED*/
  2028. protected int
  2029. -file_buffer(struct magic_set *ms, int fd, struct stat *st,
  2030. - const char *inname __attribute__ ((__unused__)),
  2031. +file_buffer(struct magic_set *ms, php_stream *stream, zend_stat_t *st,
  2032. + const char *inname,
  2033. const void *buf, size_t nb)
  2034. {
  2035. int m = 0, rv = 0, looks_text = 0;
  2036. @@ -327,6 +327,19 @@
  2037. const char *ftype = NULL;
  2038. char *rbuf = NULL;
  2039. struct buffer b;
  2040. + int fd = -1;
  2041. +
  2042. + if (stream) {
  2043. +#ifdef _WIN64
  2044. + php_socket_t _fd = fd;
  2045. +#else
  2046. + int _fd;
  2047. +#endif
  2048. + int _ret = php_stream_cast(stream, PHP_STREAM_AS_FD, (void **)&_fd, 0);
  2049. + if (SUCCESS == _ret) {
  2050. + fd = (int)_fd;
  2051. + }
  2052. + }
  2053. buffer_init(&b, fd, st, buf, nb);
  2054. ms->mode = b.st.st_mode;
  2055. @@ -359,7 +372,8 @@
  2056. }
  2057. }
  2058. #endif
  2059. -#if HAVE_FORK
  2060. +
  2061. +#if PHP_FILEINFO_UNCOMPRESS
  2062. /* try compression stuff */
  2063. if ((ms->flags & MAGIC_NO_CHECK_COMPRESS) == 0) {
  2064. m = file_zmagic(ms, &b, inname);
  2065. @@ -484,10 +498,10 @@
  2066. if (file_printf(ms, "%s", code_mime) == -1)
  2067. rv = -1;
  2068. }
  2069. -#if HAVE_FORK
  2070. +#if PHP_FILEINFO_UNCOMPRESS
  2071. done_encoding:
  2072. #endif
  2073. - free(rbuf);
  2074. + efree(rbuf);
  2075. buffer_fini(&b);
  2076. if (rv)
  2077. return rv;
  2078. @@ -505,7 +519,7 @@
  2079. }
  2080. file_clearbuf(ms);
  2081. if (ms->o.pbuf) {
  2082. - free(ms->o.pbuf);
  2083. + efree(ms->o.pbuf);
  2084. ms->o.pbuf = NULL;
  2085. }
  2086. ms->event_flags &= ~EVENT_HAD_ERR;
  2087. @@ -543,7 +557,7 @@
  2088. return NULL;
  2089. }
  2090. psize = len * 4 + 1;
  2091. - if ((pbuf = CAST(char *, realloc(ms->o.pbuf, psize))) == NULL) {
  2092. + if ((pbuf = CAST(char *, erealloc(ms->o.pbuf, psize))) == NULL) {
  2093. file_oomem(ms, psize);
  2094. return NULL;
  2095. }
  2096. @@ -607,8 +621,8 @@
  2097. if (level >= ms->c.len) {
  2098. len = (ms->c.len = 20 + level) * sizeof(*ms->c.li);
  2099. ms->c.li = CAST(struct level_info *, (ms->c.li == NULL) ?
  2100. - malloc(len) :
  2101. - realloc(ms->c.li, len));
  2102. + emalloc(len) :
  2103. + erealloc(ms->c.li, len));
  2104. if (ms->c.li == NULL) {
  2105. file_oomem(ms, len);
  2106. return -1;
  2107. @@ -631,82 +645,38 @@
  2108. protected int
  2109. file_replace(struct magic_set *ms, const char *pat, const char *rep)
  2110. {
  2111. - file_regex_t rx;
  2112. - int rc, rv = -1;
  2113. -
  2114. - rc = file_regcomp(&rx, pat, REG_EXTENDED);
  2115. - if (rc) {
  2116. - file_regerror(&rx, rc, ms);
  2117. - } else {
  2118. - regmatch_t rm;
  2119. - int nm = 0;
  2120. - while (file_regexec(&rx, ms->o.buf, 1, &rm, 0) == 0) {
  2121. - ms->o.buf[rm.rm_so] = '\0';
  2122. - if (file_printf(ms, "%s%s", rep,
  2123. - rm.rm_eo != 0 ? ms->o.buf + rm.rm_eo : "") == -1)
  2124. - goto out;
  2125. - nm++;
  2126. - }
  2127. - rv = nm;
  2128. + zend_string *pattern;
  2129. + uint32_t opts = 0;
  2130. + pcre_cache_entry *pce;
  2131. + zend_string *res;
  2132. + zend_string *repl;
  2133. + size_t rep_cnt = 0;
  2134. +
  2135. + opts |= PCRE2_MULTILINE;
  2136. + pattern = convert_libmagic_pattern((char*)pat, strlen(pat), opts);
  2137. + if ((pce = pcre_get_compiled_regex_cache_ex(pattern, 0)) == NULL) {
  2138. + zend_string_release(pattern);
  2139. + rep_cnt = -1;
  2140. + goto out;
  2141. + }
  2142. + zend_string_release(pattern);
  2143. +
  2144. + repl = zend_string_init(rep, strlen(rep), 0);
  2145. + res = php_pcre_replace_impl(pce, NULL, ms->o.buf, strlen(ms->o.buf), repl, -1, &rep_cnt);
  2146. +
  2147. + zend_string_release_ex(repl, 0);
  2148. + if (NULL == res) {
  2149. + rep_cnt = -1;
  2150. + goto out;
  2151. }
  2152. -out:
  2153. - file_regfree(&rx);
  2154. - return rv;
  2155. -}
  2156. -protected int
  2157. -file_regcomp(file_regex_t *rx, const char *pat, int flags)
  2158. -{
  2159. -#ifdef USE_C_LOCALE
  2160. - rx->c_lc_ctype = newlocale(LC_CTYPE_MASK, "C", 0);
  2161. - assert(rx->c_lc_ctype != NULL);
  2162. - rx->old_lc_ctype = uselocale(rx->c_lc_ctype);
  2163. - assert(rx->old_lc_ctype != NULL);
  2164. -#else
  2165. - rx->old_lc_ctype = setlocale(LC_CTYPE, NULL);
  2166. - assert(rx->old_lc_ctype != NULL);
  2167. - rx->old_lc_ctype = strdup(rx->old_lc_ctype);
  2168. - assert(rx->old_lc_ctype != NULL);
  2169. - (void)setlocale(LC_CTYPE, "C");
  2170. -#endif
  2171. - rx->pat = pat;
  2172. -
  2173. - return rx->rc = regcomp(&rx->rx, pat, flags);
  2174. -}
  2175. -
  2176. -protected int
  2177. -file_regexec(file_regex_t *rx, const char *str, size_t nmatch,
  2178. - regmatch_t* pmatch, int eflags)
  2179. -{
  2180. - assert(rx->rc == 0);
  2181. - /* XXX: force initialization because glibc does not always do this */
  2182. - if (nmatch != 0)
  2183. - memset(pmatch, 0, nmatch * sizeof(*pmatch));
  2184. - return regexec(&rx->rx, str, nmatch, pmatch, eflags);
  2185. -}
  2186. -
  2187. -protected void
  2188. -file_regfree(file_regex_t *rx)
  2189. -{
  2190. - if (rx->rc == 0)
  2191. - regfree(&rx->rx);
  2192. -#ifdef USE_C_LOCALE
  2193. - (void)uselocale(rx->old_lc_ctype);
  2194. - freelocale(rx->c_lc_ctype);
  2195. -#else
  2196. - (void)setlocale(LC_CTYPE, rx->old_lc_ctype);
  2197. - free(rx->old_lc_ctype);
  2198. -#endif
  2199. -}
  2200. + strncpy(ms->o.buf, ZSTR_VAL(res), ZSTR_LEN(res));
  2201. + ms->o.buf[ZSTR_LEN(res)] = '\0';
  2202. -protected void
  2203. -file_regerror(file_regex_t *rx, int rc, struct magic_set *ms)
  2204. -{
  2205. - char errmsg[512];
  2206. + zend_string_release_ex(res, 0);
  2207. - (void)regerror(rc, &rx->rx, errmsg, sizeof(errmsg));
  2208. - file_magerror(ms, "regex error %d for `%s', (%s)", rc, rx->pat,
  2209. - errmsg);
  2210. +out:
  2211. + return rep_cnt;
  2212. }
  2213. protected file_pushbuf_t *
  2214. @@ -717,7 +687,7 @@
  2215. if (ms->event_flags & EVENT_HAD_ERR)
  2216. return NULL;
  2217. - if ((pb = (CAST(file_pushbuf_t *, malloc(sizeof(*pb))))) == NULL)
  2218. + if ((pb = (CAST(file_pushbuf_t *, emalloc(sizeof(*pb))))) == NULL)
  2219. return NULL;
  2220. pb->buf = ms->o.buf;
  2221. @@ -737,8 +707,8 @@
  2222. char *rbuf;
  2223. if (ms->event_flags & EVENT_HAD_ERR) {
  2224. - free(pb->buf);
  2225. - free(pb);
  2226. + efree(pb->buf);
  2227. + efree(pb);
  2228. return NULL;
  2229. }
  2230. @@ -748,7 +718,7 @@
  2231. ms->o.blen = pb->blen;
  2232. ms->offset = pb->offset;
  2233. - free(pb);
  2234. + efree(pb);
  2235. return rbuf;
  2236. }
  2237. @@ -809,6 +779,7 @@
  2238. g->data4[6], g->data4[7]);
  2239. }
  2240. +#if 0
  2241. protected int
  2242. file_pipe_closexec(int *fds)
  2243. {
  2244. @@ -827,6 +798,7 @@
  2245. file_clear_closexec(int fd) {
  2246. return fcntl(fd, F_SETFD, 0);
  2247. }
  2248. +#endif
  2249. protected char *
  2250. file_strtrim(char *str)
  2251. diff -u libmagic.orig/magic.c libmagic/magic.c
  2252. --- libmagic.orig/magic.c 2021-02-23 01:49:06.000000000 +0100
  2253. +++ libmagic/magic.c 2022-06-16 13:39:41.586609800 +0200
  2254. @@ -25,11 +25,6 @@
  2255. * SUCH DAMAGE.
  2256. */
  2257. -#ifdef WIN32
  2258. -#include <windows.h>
  2259. -#include <shlwapi.h>
  2260. -#endif
  2261. -
  2262. #include "file.h"
  2263. #ifndef lint
  2264. @@ -39,10 +34,16 @@
  2265. #include "magic.h"
  2266. #include <stdlib.h>
  2267. +#ifdef PHP_WIN32
  2268. +#include "win32/unistd.h"
  2269. +#else
  2270. #include <unistd.h>
  2271. +#endif
  2272. #include <string.h>
  2273. -#ifdef QUICK
  2274. -#include <sys/mman.h>
  2275. +#include "config.h"
  2276. +
  2277. +#ifdef PHP_WIN32
  2278. +#include <shlwapi.h>
  2279. #endif
  2280. #include <limits.h> /* for PIPE_BUF */
  2281. @@ -69,194 +70,18 @@
  2282. #endif
  2283. #endif
  2284. -private void close_and_restore(const struct magic_set *, const char *, int,
  2285. - const struct stat *);
  2286. -private int unreadable_info(struct magic_set *, mode_t, const char *);
  2287. -private const char* get_default_magic(void);
  2288. -#ifndef COMPILE_ONLY
  2289. -private const char *file_or_fd(struct magic_set *, const char *, int);
  2290. +#ifdef PHP_WIN32
  2291. +# undef S_IFLNK
  2292. +# undef S_IFIFO
  2293. #endif
  2294. +private int unreadable_info(struct magic_set *, mode_t, const char *);
  2295. +private const char *file_or_stream(struct magic_set *, const char *, php_stream *);
  2296. +
  2297. #ifndef STDIN_FILENO
  2298. #define STDIN_FILENO 0
  2299. #endif
  2300. -#ifdef WIN32
  2301. -/* HINSTANCE of this shared library. Needed for get_default_magic() */
  2302. -static HINSTANCE _w32_dll_instance = NULL;
  2303. -
  2304. -static void
  2305. -_w32_append_path(char **hmagicpath, const char *fmt, ...)
  2306. -{
  2307. - char *tmppath;
  2308. - char *newpath;
  2309. - va_list ap;
  2310. -
  2311. - va_start(ap, fmt);
  2312. - if (vasprintf(&tmppath, fmt, ap) < 0) {
  2313. - va_end(ap);
  2314. - return;
  2315. - }
  2316. - va_end(ap);
  2317. -
  2318. - if (access(tmppath, R_OK) == -1)
  2319. - goto out;
  2320. -
  2321. - if (*hmagicpath == NULL) {
  2322. - *hmagicpath = tmppath;
  2323. - return;
  2324. - }
  2325. -
  2326. - if (asprintf(&newpath, "%s%c%s", *hmagicpath, PATHSEP, tmppath) < 0)
  2327. - goto out;
  2328. -
  2329. - free(*hmagicpath);
  2330. - free(tmppath);
  2331. - *hmagicpath = newpath;
  2332. - return;
  2333. -out:
  2334. - free(tmppath);
  2335. -}
  2336. -
  2337. -static void
  2338. -_w32_get_magic_relative_to(char **hmagicpath, HINSTANCE module)
  2339. -{
  2340. - static const char *trypaths[] = {
  2341. - "%s/share/misc/magic.mgc",
  2342. - "%s/magic.mgc",
  2343. - };
  2344. - LPSTR dllpath;
  2345. - size_t sp;
  2346. -
  2347. - dllpath = calloc(MAX_PATH + 1, sizeof(*dllpath));
  2348. -
  2349. - if (!GetModuleFileNameA(module, dllpath, MAX_PATH))
  2350. - goto out;
  2351. -
  2352. - PathRemoveFileSpecA(dllpath);
  2353. -
  2354. - if (module) {
  2355. - char exepath[MAX_PATH];
  2356. - GetModuleFileNameA(NULL, exepath, MAX_PATH);
  2357. - PathRemoveFileSpecA(exepath);
  2358. - if (stricmp(exepath, dllpath) == 0)
  2359. - goto out;
  2360. - }
  2361. -
  2362. - sp = strlen(dllpath);
  2363. - if (sp > 3 && stricmp(&dllpath[sp - 3], "bin") == 0) {
  2364. - _w32_append_path(hmagicpath,
  2365. - "%s/../share/misc/magic.mgc", dllpath);
  2366. - goto out;
  2367. - }
  2368. -
  2369. - for (sp = 0; sp < __arraycount(trypaths); sp++)
  2370. - _w32_append_path(hmagicpath, trypaths[sp], dllpath);
  2371. -out:
  2372. - free(dllpath);
  2373. -}
  2374. -
  2375. -/* Placate GCC by offering a sacrificial previous prototype */
  2376. -BOOL WINAPI DllMain(HINSTANCE, DWORD, LPVOID);
  2377. -
  2378. -BOOL WINAPI
  2379. -DllMain(HINSTANCE hinstDLL, DWORD fdwReason,
  2380. - LPVOID lpvReserved __attribute__((__unused__)))
  2381. -{
  2382. - if (fdwReason == DLL_PROCESS_ATTACH)
  2383. - _w32_dll_instance = hinstDLL;
  2384. - return 1;
  2385. -}
  2386. -#endif
  2387. -
  2388. -private const char *
  2389. -get_default_magic(void)
  2390. -{
  2391. - static const char hmagic[] = "/.magic/magic.mgc";
  2392. - static char *default_magic;
  2393. - char *home, *hmagicpath;
  2394. -
  2395. -#ifndef WIN32
  2396. - struct stat st;
  2397. -
  2398. - if (default_magic) {
  2399. - free(default_magic);
  2400. - default_magic = NULL;
  2401. - }
  2402. - if ((home = getenv("HOME")) == NULL)
  2403. - return MAGIC;
  2404. -
  2405. - if (asprintf(&hmagicpath, "%s/.magic.mgc", home) < 0)
  2406. - return MAGIC;
  2407. - if (stat(hmagicpath, &st) == -1) {
  2408. - free(hmagicpath);
  2409. - if (asprintf(&hmagicpath, "%s/.magic", home) < 0)
  2410. - return MAGIC;
  2411. - if (stat(hmagicpath, &st) == -1)
  2412. - goto out;
  2413. - if (S_ISDIR(st.st_mode)) {
  2414. - free(hmagicpath);
  2415. - if (asprintf(&hmagicpath, "%s/%s", home, hmagic) < 0)
  2416. - return MAGIC;
  2417. - if (access(hmagicpath, R_OK) == -1)
  2418. - goto out;
  2419. - }
  2420. - }
  2421. -
  2422. - if (asprintf(&default_magic, "%s:%s", hmagicpath, MAGIC) < 0)
  2423. - goto out;
  2424. - free(hmagicpath);
  2425. - return default_magic;
  2426. -out:
  2427. - default_magic = NULL;
  2428. - free(hmagicpath);
  2429. - return MAGIC;
  2430. -#else
  2431. - hmagicpath = NULL;
  2432. -
  2433. - if (default_magic) {
  2434. - free(default_magic);
  2435. - default_magic = NULL;
  2436. - }
  2437. -
  2438. - /* First, try to get a magic file from user-application data */
  2439. - if ((home = getenv("LOCALAPPDATA")) != NULL)
  2440. - _w32_append_path(&hmagicpath, "%s%s", home, hmagic);
  2441. -
  2442. - /* Second, try to get a magic file from the user profile data */
  2443. - if ((home = getenv("USERPROFILE")) != NULL)
  2444. - _w32_append_path(&hmagicpath,
  2445. - "%s/Local Settings/Application Data%s", home, hmagic);
  2446. -
  2447. - /* Third, try to get a magic file from Common Files */
  2448. - if ((home = getenv("COMMONPROGRAMFILES")) != NULL)
  2449. - _w32_append_path(&hmagicpath, "%s%s", home, hmagic);
  2450. -
  2451. - /* Fourth, try to get magic file relative to exe location */
  2452. - _w32_get_magic_relative_to(&hmagicpath, NULL);
  2453. -
  2454. - /* Fifth, try to get magic file relative to dll location */
  2455. - _w32_get_magic_relative_to(&hmagicpath, _w32_dll_instance);
  2456. -
  2457. - /* Avoid MAGIC constant - it likely points to a file within MSys tree */
  2458. - default_magic = hmagicpath;
  2459. - return default_magic;
  2460. -#endif
  2461. -}
  2462. -
  2463. -public const char *
  2464. -magic_getpath(const char *magicfile, int action)
  2465. -{
  2466. - if (magicfile != NULL)
  2467. - return magicfile;
  2468. -
  2469. - magicfile = getenv("MAGIC");
  2470. - if (magicfile != NULL)
  2471. - return magicfile;
  2472. -
  2473. - return action == FILE_LOAD ? get_default_magic() : MAGIC;
  2474. -}
  2475. -
  2476. public struct magic_set *
  2477. magic_open(int flags)
  2478. {
  2479. @@ -302,21 +127,6 @@
  2480. return file_apprentice(ms, magicfile, FILE_LOAD);
  2481. }
  2482. -#ifndef COMPILE_ONLY
  2483. -/*
  2484. - * Install a set of compiled magic buffers.
  2485. - */
  2486. -public int
  2487. -magic_load_buffers(struct magic_set *ms, void **bufs, size_t *sizes,
  2488. - size_t nbufs)
  2489. -{
  2490. - if (ms == NULL)
  2491. - return -1;
  2492. - return buffer_apprentice(ms, RCAST(struct magic **, bufs),
  2493. - sizes, nbufs);
  2494. -}
  2495. -#endif
  2496. -
  2497. public int
  2498. magic_compile(struct magic_set *ms, const char *magicfile)
  2499. {
  2500. @@ -341,39 +151,6 @@
  2501. return file_apprentice(ms, magicfile, FILE_LIST);
  2502. }
  2503. -private void
  2504. -close_and_restore(const struct magic_set *ms, const char *name, int fd,
  2505. - const struct stat *sb)
  2506. -{
  2507. - if (fd == STDIN_FILENO || name == NULL)
  2508. - return;
  2509. - (void) close(fd);
  2510. -
  2511. - if ((ms->flags & MAGIC_PRESERVE_ATIME) != 0) {
  2512. - /*
  2513. - * Try to restore access, modification times if read it.
  2514. - * This is really *bad* because it will modify the status
  2515. - * time of the file... And of course this will affect
  2516. - * backup programs
  2517. - */
  2518. -#ifdef HAVE_UTIMES
  2519. - struct timeval utsbuf[2];
  2520. - (void)memset(utsbuf, 0, sizeof(utsbuf));
  2521. - utsbuf[0].tv_sec = sb->st_atime;
  2522. - utsbuf[1].tv_sec = sb->st_mtime;
  2523. -
  2524. - (void) utimes(name, utsbuf); /* don't care if loses */
  2525. -#elif defined(HAVE_UTIME_H) || defined(HAVE_SYS_UTIME_H)
  2526. - struct utimbuf utbuf;
  2527. -
  2528. - (void)memset(&utbuf, 0, sizeof(utbuf));
  2529. - utbuf.actime = sb->st_atime;
  2530. - utbuf.modtime = sb->st_mtime;
  2531. - (void) utime(name, &utbuf); /* don't care if loses */
  2532. -#endif
  2533. - }
  2534. -}
  2535. -
  2536. #ifndef COMPILE_ONLY
  2537. /*
  2538. @@ -384,7 +161,7 @@
  2539. {
  2540. if (ms == NULL)
  2541. return NULL;
  2542. - return file_or_fd(ms, NULL, fd);
  2543. + return file_or_stream(ms, NULL, NULL);
  2544. }
  2545. /*
  2546. @@ -395,19 +172,25 @@
  2547. {
  2548. if (ms == NULL)
  2549. return NULL;
  2550. - return file_or_fd(ms, inname, STDIN_FILENO);
  2551. + return file_or_stream(ms, inname, NULL);
  2552. +}
  2553. +
  2554. +public const char *
  2555. +magic_stream(struct magic_set *ms, php_stream *stream)
  2556. +{
  2557. + if (ms == NULL)
  2558. + return NULL;
  2559. + return file_or_stream(ms, NULL, stream);
  2560. }
  2561. private const char *
  2562. -file_or_fd(struct magic_set *ms, const char *inname, int fd)
  2563. +file_or_stream(struct magic_set *ms, const char *inname, php_stream *stream)
  2564. {
  2565. int rv = -1;
  2566. unsigned char *buf;
  2567. - struct stat sb;
  2568. + zend_stat_t sb;
  2569. ssize_t nbytes = 0; /* number of bytes read from a datafile */
  2570. - int ispipe = 0;
  2571. - int okstat = 0;
  2572. - off_t pos = CAST(off_t, -1);
  2573. + int no_in_stream = 0;
  2574. if (file_reset(ms, 1) == -1)
  2575. goto out;
  2576. @@ -417,7 +200,7 @@
  2577. * some overlapping space for matches near EOF
  2578. */
  2579. #define SLOP (1 + sizeof(union VALUETYPE))
  2580. - if ((buf = CAST(unsigned char *, malloc(ms->bytes_max + SLOP))) == NULL)
  2581. + if ((buf = CAST(unsigned char *, emalloc(ms->bytes_max + SLOP))) == NULL)
  2582. return NULL;
  2583. switch (file_fsmagic(ms, inname, &sb)) {
  2584. @@ -430,98 +213,46 @@
  2585. goto done;
  2586. }
  2587. -#ifdef WIN32
  2588. - /* Place stdin in binary mode, so EOF (Ctrl+Z) doesn't stop early. */
  2589. - if (fd == STDIN_FILENO)
  2590. - _setmode(STDIN_FILENO, O_BINARY);
  2591. -#endif
  2592. - if (inname != NULL) {
  2593. - int flags = O_RDONLY|O_BINARY|O_NONBLOCK|O_CLOEXEC;
  2594. - errno = 0;
  2595. - if ((fd = open(inname, flags)) < 0) {
  2596. - okstat = stat(inname, &sb) == 0;
  2597. - if (okstat && S_ISFIFO(sb.st_mode))
  2598. - ispipe = 1;
  2599. -#ifdef WIN32
  2600. - /*
  2601. - * Can't stat, can't open. It may have been opened in
  2602. - * fsmagic, so if the user doesn't have read permission,
  2603. - * allow it to say so; otherwise an error was probably
  2604. - * displayed in fsmagic.
  2605. - */
  2606. - if (!okstat && errno == EACCES) {
  2607. - sb.st_mode = S_IFBLK;
  2608. - okstat = 1;
  2609. - }
  2610. -#endif
  2611. - if (okstat &&
  2612. - unreadable_info(ms, sb.st_mode, inname) == -1)
  2613. + errno = 0;
  2614. +
  2615. + if (inname && !stream) {
  2616. + no_in_stream = 1;
  2617. + stream = php_stream_open_wrapper((char *)inname, "rb", REPORT_ERRORS, NULL);
  2618. + if (!stream) {
  2619. + if (unreadable_info(ms, sb.st_mode, inname) == -1)
  2620. goto done;
  2621. - rv = 0;
  2622. + rv = -1;
  2623. goto done;
  2624. }
  2625. -#if O_CLOEXEC == 0
  2626. - (void)fcntl(fd, F_SETFD, FD_CLOEXEC);
  2627. -#endif
  2628. }
  2629. - if (fd != -1) {
  2630. - okstat = fstat(fd, &sb) == 0;
  2631. - if (okstat && S_ISFIFO(sb.st_mode))
  2632. - ispipe = 1;
  2633. - if (inname == NULL)
  2634. - pos = lseek(fd, CAST(off_t, 0), SEEK_CUR);
  2635. + php_stream_statbuf ssb;
  2636. + if (php_stream_stat(stream, &ssb) < 0) {
  2637. + if (ms->flags & MAGIC_ERROR) {
  2638. + file_error(ms, errno, "cannot stat `%s'", inname);
  2639. + rv = -1;
  2640. + goto done;
  2641. + }
  2642. }
  2643. + memcpy(&sb, &ssb.sb, sizeof(zend_stat_t));
  2644. /*
  2645. * try looking at the first ms->bytes_max bytes
  2646. */
  2647. - if (ispipe) {
  2648. - if (fd != -1) {
  2649. - ssize_t r = 0;
  2650. -
  2651. - while ((r = sread(fd, RCAST(void *, &buf[nbytes]),
  2652. - CAST(size_t, ms->bytes_max - nbytes), 1)) > 0) {
  2653. - nbytes += r;
  2654. - if (r < PIPE_BUF) break;
  2655. - }
  2656. - }
  2657. -
  2658. - if (nbytes == 0 && inname) {
  2659. - /* We can not read it, but we were able to stat it. */
  2660. - if (unreadable_info(ms, sb.st_mode, inname) == -1)
  2661. - goto done;
  2662. - rv = 0;
  2663. - goto done;
  2664. - }
  2665. -
  2666. - } else if (fd != -1) {
  2667. - /* Windows refuses to read from a big console buffer. */
  2668. - size_t howmany =
  2669. -#if defined(WIN32)
  2670. - _isatty(fd) ? 8 * 1024 :
  2671. -#endif
  2672. - ms->bytes_max;
  2673. - if ((nbytes = read(fd, RCAST(void *, buf), howmany)) == -1) {
  2674. - if (inname == NULL && fd != STDIN_FILENO)
  2675. - file_error(ms, errno, "cannot read fd %d", fd);
  2676. - else
  2677. - file_error(ms, errno, "cannot read `%s'",
  2678. - inname == NULL ? "/dev/stdin" : inname);
  2679. - goto done;
  2680. - }
  2681. + if ((nbytes = php_stream_read(stream, (char *)buf, ms->bytes_max - nbytes)) < 0) {
  2682. + file_error(ms, errno, "cannot read `%s'", inname);
  2683. + goto done;
  2684. }
  2685. (void)memset(buf + nbytes, 0, SLOP); /* NUL terminate */
  2686. - if (file_buffer(ms, fd, okstat ? &sb : NULL, inname, buf, CAST(size_t, nbytes)) == -1)
  2687. + if (file_buffer(ms, stream, &sb, inname, buf, CAST(size_t, nbytes)) == -1)
  2688. goto done;
  2689. rv = 0;
  2690. done:
  2691. - free(buf);
  2692. - if (fd != -1) {
  2693. - if (pos != CAST(off_t, -1))
  2694. - (void)lseek(fd, pos, SEEK_SET);
  2695. - close_and_restore(ms, inname, fd, &sb);
  2696. + efree(buf);
  2697. +
  2698. + if (no_in_stream && stream) {
  2699. + php_stream_close(stream);
  2700. }
  2701. out:
  2702. return rv == 0 ? file_getbuffer(ms) : NULL;
  2703. @@ -539,7 +270,7 @@
  2704. * The main work is done here!
  2705. * We have the file name and/or the data buffer to be identified.
  2706. */
  2707. - if (file_buffer(ms, -1, NULL, NULL, buf, nb) == -1) {
  2708. + if (file_buffer(ms, NULL, NULL, NULL, buf, nb) == -1) {
  2709. return NULL;
  2710. }
  2711. return file_getbuffer(ms);
  2712. diff -u libmagic.orig/magic.h libmagic/magic.h
  2713. --- libmagic.orig/magic.h 2022-06-30 17:16:06.144009900 +0200
  2714. +++ libmagic/magic.h 2022-06-16 13:39:41.586609800 +0200
  2715. @@ -126,6 +126,7 @@
  2716. const char *magic_getpath(const char *, int);
  2717. const char *magic_file(magic_t, const char *);
  2718. +const char *magic_stream(magic_t, php_stream *);
  2719. const char *magic_descriptor(magic_t, int);
  2720. const char *magic_buffer(magic_t, const void *, size_t);
  2721. diff -u libmagic.orig/print.c libmagic/print.c
  2722. --- libmagic.orig/print.c 2021-02-23 01:49:07.000000000 +0100
  2723. +++ libmagic/print.c 2021-09-21 13:27:27.998388700 +0200
  2724. @@ -28,6 +28,7 @@
  2725. /*
  2726. * print.c - debugging printout routines
  2727. */
  2728. +#include "php.h"
  2729. #include "file.h"
  2730. @@ -73,7 +74,7 @@
  2731. if (m->mask_op & FILE_OPINVERSE)
  2732. (void) fputc('~', stderr);
  2733. - if (IS_STRING(m->type)) {
  2734. + if (IS_LIBMAGIC_STRING(m->type)) {
  2735. if (m->str_flags) {
  2736. (void) fputc('/', stderr);
  2737. if (m->str_flags & STRING_COMPACT_WHITESPACE)
  2738. @@ -225,18 +226,18 @@
  2739. file_magwarn(struct magic_set *ms, const char *f, ...)
  2740. {
  2741. va_list va;
  2742. + char *expanded_format = NULL;
  2743. + int expanded_len;
  2744. - /* cuz we use stdout for most, stderr here */
  2745. - (void) fflush(stdout);
  2746. -
  2747. - if (ms->file)
  2748. - (void) fprintf(stderr, "%s, %lu: ", ms->file,
  2749. - CAST(unsigned long, ms->line));
  2750. - (void) fprintf(stderr, "Warning: ");
  2751. va_start(va, f);
  2752. - (void) vfprintf(stderr, f, va);
  2753. + expanded_len = vasprintf(&expanded_format, f, va);
  2754. va_end(va);
  2755. - (void) fputc('\n', stderr);
  2756. +
  2757. + if (expanded_len >= 0 && expanded_format) {
  2758. + php_error_docref(NULL, E_WARNING, "%s", expanded_format);
  2759. +
  2760. + free(expanded_format);
  2761. + }
  2762. }
  2763. protected const char *
  2764. @@ -257,13 +258,13 @@
  2765. }
  2766. if (flags & FILE_T_LOCAL) {
  2767. - tm = localtime_r(&t, &tmz);
  2768. + tm = php_localtime_r(&t, &tmz);
  2769. } else {
  2770. - tm = gmtime_r(&t, &tmz);
  2771. + tm = php_gmtime_r(&t, &tmz);
  2772. }
  2773. if (tm == NULL)
  2774. goto out;
  2775. - pp = asctime_r(tm, buf);
  2776. + pp = php_asctime_r(tm, buf);
  2777. if (pp == NULL)
  2778. goto out;
  2779. diff -u libmagic.orig/readcdf.c libmagic/readcdf.c
  2780. --- libmagic.orig/readcdf.c 2021-02-23 01:49:08.000000000 +0100
  2781. +++ libmagic/readcdf.c 2021-09-21 13:27:27.999369100 +0200
  2782. @@ -31,7 +31,11 @@
  2783. #include <assert.h>
  2784. #include <stdlib.h>
  2785. +#ifdef PHP_WIN32
  2786. +#include "win32/unistd.h"
  2787. +#else
  2788. #include <unistd.h>
  2789. +#endif
  2790. #include <string.h>
  2791. #include <time.h>
  2792. #include <ctype.h>
  2793. @@ -100,10 +104,6 @@
  2794. if (clsid[0] == cv[i].clsid[0] && clsid[1] == cv[i].clsid[1])
  2795. return cv[i].mime;
  2796. }
  2797. -#ifdef CDF_DEBUG
  2798. - fprintf(stderr, "unknown mime %" PRIx64 ", %" PRIx64 "\n", clsid[0],
  2799. - clsid[1]);
  2800. -#endif
  2801. return NULL;
  2802. }
  2803. @@ -112,35 +112,24 @@
  2804. {
  2805. size_t i;
  2806. const char *rv = NULL;
  2807. -#ifdef USE_C_LOCALE
  2808. - locale_t old_lc_ctype, c_lc_ctype;
  2809. + char *vbuf_lower;
  2810. - c_lc_ctype = newlocale(LC_CTYPE_MASK, "C", 0);
  2811. - assert(c_lc_ctype != NULL);
  2812. - old_lc_ctype = uselocale(c_lc_ctype);
  2813. - assert(old_lc_ctype != NULL);
  2814. -#else
  2815. - char *old_lc_ctype = setlocale(LC_CTYPE, NULL);
  2816. - assert(old_lc_ctype != NULL);
  2817. - old_lc_ctype = strdup(old_lc_ctype);
  2818. - assert(old_lc_ctype != NULL);
  2819. - (void)setlocale(LC_CTYPE, "C");
  2820. -#endif
  2821. - for (i = 0; nv[i].pattern != NULL; i++)
  2822. - if (strcasestr(vbuf, nv[i].pattern) != NULL) {
  2823. + vbuf_lower = zend_str_tolower_dup(vbuf, strlen(vbuf));
  2824. + for (i = 0; nv[i].pattern != NULL; i++) {
  2825. + char *pattern_lower;
  2826. + int found;
  2827. +
  2828. + pattern_lower = zend_str_tolower_dup(nv[i].pattern, strlen(nv[i].pattern));
  2829. + found = (strstr(vbuf_lower, pattern_lower) != NULL);
  2830. + efree(pattern_lower);
  2831. +
  2832. + if (found) {
  2833. rv = nv[i].mime;
  2834. break;
  2835. }
  2836. -#ifdef CDF_DEBUG
  2837. - fprintf(stderr, "unknown app %s\n", vbuf);
  2838. -#endif
  2839. -#ifdef USE_C_LOCALE
  2840. - (void)uselocale(old_lc_ctype);
  2841. - freelocale(c_lc_ctype);
  2842. -#else
  2843. - (void)setlocale(LC_CTYPE, old_lc_ctype);
  2844. - free(old_lc_ctype);
  2845. -#endif
  2846. + }
  2847. +
  2848. + efree(vbuf_lower);
  2849. return rv;
  2850. }
  2851. @@ -156,7 +145,9 @@
  2852. const char *s, *e;
  2853. int len;
  2854. - if (!NOTMIME(ms) && root_storage)
  2855. + memset(&ts, 0, sizeof(ts));
  2856. +
  2857. + if (!NOTMIME(ms) && root_storage)
  2858. str = cdf_clsid_to_mime(root_storage->d_storage_uuid,
  2859. clsid2mime);
  2860. @@ -282,10 +273,10 @@
  2861. if (file_printf(ms, "%s%s",
  2862. cdf_u16tos8(buf, ce[i].ce_namlen, ce[i].ce_name),
  2863. i == cat->cat_num - 1 ? "]" : ", ") == -1) {
  2864. - free(cat);
  2865. + efree(cat);
  2866. return -1;
  2867. }
  2868. - free(cat);
  2869. + efree(cat);
  2870. } else if (ms->flags & MAGIC_MIME_TYPE) {
  2871. if (file_printf(ms, "application/CDFV2") == -1)
  2872. return -1;
  2873. @@ -346,7 +337,7 @@
  2874. }
  2875. m = cdf_file_property_info(ms, info, count, root_storage);
  2876. - free(info);
  2877. + efree(info);
  2878. return m == -1 ? -2 : m;
  2879. }
  2880. @@ -656,11 +647,11 @@
  2881. cdf_zero_stream(&scn);
  2882. cdf_zero_stream(&sst);
  2883. out3:
  2884. - free(dir.dir_tab);
  2885. + efree(dir.dir_tab);
  2886. out2:
  2887. - free(ssat.sat_tab);
  2888. + efree(ssat.sat_tab);
  2889. out1:
  2890. - free(sat.sat_tab);
  2891. + efree(sat.sat_tab);
  2892. out0:
  2893. /* If we handled it already, return */
  2894. if (i != -1)
  2895. diff -u libmagic.orig/softmagic.c libmagic/softmagic.c
  2896. --- libmagic.orig/softmagic.c 2021-02-23 01:49:06.000000000 +0100
  2897. +++ libmagic/softmagic.c 2022-06-30 16:58:15.521661800 +0200
  2898. @@ -43,6 +43,10 @@
  2899. #include <time.h>
  2900. #include "der.h"
  2901. +#ifndef PREG_OFFSET_CAPTURE
  2902. +# define PREG_OFFSET_CAPTURE (1<<8)
  2903. +#endif
  2904. +
  2905. private int match(struct magic_set *, struct magic *, uint32_t,
  2906. const struct buffer *, size_t, int, int, int, uint16_t *,
  2907. uint16_t *, int *, int *, int *, int *);
  2908. @@ -139,8 +143,8 @@
  2909. return 0;
  2910. }
  2911. -#define FILE_FMTDEBUG
  2912. -#ifdef FILE_FMTDEBUG
  2913. +
  2914. +#if defined(FILE_FMTDEBUG) && defined(HAVE_FMTCHECK)
  2915. #define F(a, b, c) file_fmtcheck((a), (b), (c), __FILE__, __LINE__)
  2916. private const char * __attribute__((__format_arg__(3)))
  2917. @@ -159,10 +163,14 @@
  2918. " with `%s'", file, line, desc, def);
  2919. return ptr;
  2920. }
  2921. -#else
  2922. +#elif defined(HAVE_FMTCHECK)
  2923. #define F(a, b, c) fmtcheck((b), (c))
  2924. +#else
  2925. +#define F(a, b, c) ((b))
  2926. #endif
  2927. +/* NOTE this function has been kept an the state of 5.39 for BC. Observe
  2928. + * further as the upgrade to 5.41 or above goes. */
  2929. /*
  2930. * Go through the whole list, stopping if you find a match. Process all
  2931. * the continuations of that match before returning.
  2932. @@ -222,7 +230,7 @@
  2933. struct magic *m = &magic[magindex];
  2934. if (m->type != FILE_NAME)
  2935. - if ((IS_STRING(m->type) &&
  2936. + if ((IS_LIBMAGIC_STRING(m->type) &&
  2937. #define FLT (STRING_BINTEST | STRING_TEXTTEST)
  2938. ((text && (m->str_flags & FLT) == STRING_BINTEST) ||
  2939. (!text && (m->str_flags & FLT) == STRING_TEXTTEST))) ||
  2940. @@ -277,9 +285,11 @@
  2941. goto flush;
  2942. }
  2943. + if (*m->desc)
  2944. + *found_match = 1;
  2945. +
  2946. if ((e = handle_annotation(ms, m, firstline)) != 0)
  2947. {
  2948. - *found_match = 1;
  2949. *need_separator = 1;
  2950. *printed_something = 1;
  2951. *returnval = 1;
  2952. @@ -290,17 +300,14 @@
  2953. * If we are going to print something, we'll need to print
  2954. * a blank before we print something else.
  2955. */
  2956. - if (*m->desc) {
  2957. - *found_match = 1;
  2958. + if (print && *m->desc) {
  2959. + *need_separator = 1;
  2960. + *printed_something = 1;
  2961. *returnval = 1;
  2962. - if (print) {
  2963. - *need_separator = 1;
  2964. - *printed_something = 1;
  2965. - if (print_sep(ms, firstline) == -1)
  2966. - return -1;
  2967. - if (mprint(ms, m) == -1)
  2968. - return -1;
  2969. - }
  2970. + if (print_sep(ms, firstline) == -1)
  2971. + return -1;
  2972. + if (mprint(ms, m) == -1)
  2973. + return -1;
  2974. }
  2975. switch (moffset(ms, m, &bb, &ms->c.li[cont_level].off)) {
  2976. @@ -391,18 +398,16 @@
  2977. } else
  2978. ms->c.li[cont_level].got_match = 1;
  2979. + if (*m->desc)
  2980. + *found_match = 1;
  2981. +
  2982. if ((e = handle_annotation(ms, m, firstline))
  2983. != 0) {
  2984. - *found_match = 1;
  2985. *need_separator = 1;
  2986. *printed_something = 1;
  2987. *returnval = 1;
  2988. return e;
  2989. }
  2990. - if (*m->desc) {
  2991. - *found_match = 1;
  2992. - *returnval = 1;
  2993. - }
  2994. if (print && *m->desc) {
  2995. /*
  2996. * This continuation matched. Print
  2997. @@ -427,6 +432,7 @@
  2998. if (file_printf(ms, " ") == -1)
  2999. return -1;
  3000. }
  3001. + *returnval = 1;
  3002. *need_separator = 0;
  3003. if (mprint(ms, m) == -1)
  3004. return -1;
  3005. @@ -458,43 +464,39 @@
  3006. firstline = 0;
  3007. }
  3008. if (*found_match) {
  3009. - if ((ms->flags & MAGIC_CONTINUE) == 0)
  3010. - goto out;
  3011. - // So that we print a separator
  3012. - *printed_something = 0;
  3013. - firstline = 0;
  3014. + if ((ms->flags & MAGIC_CONTINUE) == 0)
  3015. + return *returnval; /* don't keep searching */
  3016. + // So that we print a separator
  3017. + *printed_something = 0;
  3018. + firstline = 0;
  3019. }
  3020. cont_level = 0;
  3021. }
  3022. -out:
  3023. - /*
  3024. - * If we are not printing (we are doing mime etc.)
  3025. - * and we did not find a mime entry, and we are at 0 level
  3026. - * we want to return 0 so that the default mime printer
  3027. - * takes over and prints "application/octet-stream"
  3028. - */
  3029. - if (! print && ! *printed_something && ! *name_count)
  3030. - return 0;
  3031. return *returnval; /* This is hit if -k is set or there is no match */
  3032. }
  3033. private int
  3034. check_fmt(struct magic_set *ms, const char *fmt)
  3035. {
  3036. - file_regex_t rx;
  3037. - int rc, rv = -1;
  3038. + pcre_cache_entry *pce;
  3039. + int rv = -1;
  3040. + zend_string *pattern;
  3041. if (strchr(fmt, '%') == NULL)
  3042. return 0;
  3043. - rc = file_regcomp(&rx, "%[-0-9\\.]*s", REG_EXTENDED|REG_NOSUB);
  3044. - if (rc) {
  3045. - file_regerror(&rx, rc, ms);
  3046. + pattern = zend_string_init("~%[-0-9\\.]*s~", sizeof("~%[-0-9\\.]*s~") - 1, 0);
  3047. + if ((pce = pcre_get_compiled_regex_cache_ex(pattern, 0)) == NULL) {
  3048. + rv = -1;
  3049. } else {
  3050. - rc = file_regexec(&rx, fmt, 0, 0, 0);
  3051. - rv = !rc;
  3052. + pcre2_code *re = php_pcre_pce_re(pce);
  3053. + pcre2_match_data *match_data = php_pcre_create_match_data(0, re);
  3054. + if (match_data) {
  3055. + rv = pcre2_match(re, (PCRE2_SPTR)fmt, strlen(fmt), 0, 0, match_data, php_pcre_mctx()) > 0;
  3056. + php_pcre_free_match_data(match_data);
  3057. + }
  3058. }
  3059. - file_regfree(&rx);
  3060. + zend_string_release(pattern);
  3061. return rv;
  3062. }
  3063. @@ -1531,11 +1533,7 @@
  3064. size_t len;
  3065. *c = ms->c;
  3066. len = c->len * sizeof(*c->li);
  3067. - ms->c.li = CAST(struct level_info *, malloc(len));
  3068. - if (ms->c.li == NULL) {
  3069. - ms->c = *c;
  3070. - return -1;
  3071. - }
  3072. + ms->c.li = CAST(struct level_info *, emalloc(len));
  3073. memcpy(ms->c.li, c->li, len);
  3074. return 0;
  3075. }
  3076. @@ -1543,7 +1541,7 @@
  3077. private void
  3078. restore_cont(struct magic_set *ms, struct cont *c)
  3079. {
  3080. - free(ms->c.li);
  3081. + efree(ms->c.li);
  3082. ms->c = *c;
  3083. }
  3084. @@ -1845,15 +1843,15 @@
  3085. if ((ms->flags & MAGIC_NODESC) == 0 &&
  3086. file_printf(ms, F(ms, m->desc, "%u"), offset) == -1)
  3087. {
  3088. - free(rbuf);
  3089. + if (rbuf) efree(rbuf);
  3090. return -1;
  3091. }
  3092. if (file_printf(ms, "%s", rbuf) == -1) {
  3093. - free(rbuf);
  3094. + if (rbuf) efree(rbuf);
  3095. return -1;
  3096. }
  3097. }
  3098. - free(rbuf);
  3099. + if (rbuf) efree(rbuf);
  3100. return rv;
  3101. case FILE_USE:
  3102. @@ -1958,10 +1956,13 @@
  3103. }
  3104. else if ((flags & STRING_COMPACT_WHITESPACE) &&
  3105. isspace(*a)) {
  3106. + /* XXX Dirty. The data and the pattern is what is causing this.
  3107. + Revert _i for the next port and see if it still matters. */
  3108. + uint32_t _i = 0;
  3109. a++;
  3110. if (isspace(*b++)) {
  3111. if (!isspace(*a))
  3112. - while (b < eb && isspace(*b))
  3113. + while (EXPECTED(_i++ < 2048) && b < eb && isspace(*b))
  3114. b++;
  3115. }
  3116. else {
  3117. @@ -1997,6 +1998,60 @@
  3118. return file_strncmp(a, b, len, maxlen, flags);
  3119. }
  3120. +public zend_string* convert_libmagic_pattern(const char *val, size_t len, uint32_t options)
  3121. +{
  3122. + int i, j;
  3123. + zend_string *t;
  3124. +
  3125. + for (i = j = 0; i < len; i++) {
  3126. + switch (val[i]) {
  3127. + case '~':
  3128. + j += 2;
  3129. + break;
  3130. + case '\0':
  3131. + j += 4;
  3132. + break;
  3133. + default:
  3134. + j++;
  3135. + break;
  3136. + }
  3137. + }
  3138. + t = zend_string_alloc(j + 4, 0);
  3139. +
  3140. + j = 0;
  3141. + ZSTR_VAL(t)[j++] = '~';
  3142. +
  3143. + for (i = 0; i < len; i++, j++) {
  3144. + switch (val[i]) {
  3145. + case '~':
  3146. + ZSTR_VAL(t)[j++] = '\\';
  3147. + ZSTR_VAL(t)[j] = '~';
  3148. + break;
  3149. + case '\0':
  3150. + ZSTR_VAL(t)[j++] = '\\';
  3151. + ZSTR_VAL(t)[j++] = 'x';
  3152. + ZSTR_VAL(t)[j++] = '0';
  3153. + ZSTR_VAL(t)[j] = '0';
  3154. + break;
  3155. + default:
  3156. + ZSTR_VAL(t)[j] = val[i];
  3157. + break;
  3158. + }
  3159. + }
  3160. + ZSTR_VAL(t)[j++] = '~';
  3161. +
  3162. + if (options & PCRE2_CASELESS)
  3163. + ZSTR_VAL(t)[j++] = 'i';
  3164. +
  3165. + if (options & PCRE2_MULTILINE)
  3166. + ZSTR_VAL(t)[j++] = 'm';
  3167. +
  3168. + ZSTR_VAL(t)[j]='\0';
  3169. + ZSTR_LEN(t) = j;
  3170. +
  3171. + return t;
  3172. +}
  3173. +
  3174. private int
  3175. magiccheck(struct magic_set *ms, struct magic *m)
  3176. {
  3177. @@ -2176,65 +2231,77 @@
  3178. break;
  3179. }
  3180. case FILE_REGEX: {
  3181. - int rc;
  3182. - file_regex_t rx;
  3183. - const char *search;
  3184. + zend_string *pattern;
  3185. + uint32_t options = 0;
  3186. + pcre_cache_entry *pce;
  3187. - if (ms->search.s == NULL)
  3188. - return 0;
  3189. + options |= PCRE2_MULTILINE;
  3190. - l = 0;
  3191. - rc = file_regcomp(&rx, m->value.s,
  3192. - REG_EXTENDED|REG_NEWLINE|
  3193. - ((m->str_flags & STRING_IGNORE_CASE) ? REG_ICASE : 0));
  3194. - if (rc) {
  3195. - file_regerror(&rx, rc, ms);
  3196. - v = CAST(uint64_t, -1);
  3197. + if (m->str_flags & STRING_IGNORE_CASE) {
  3198. + options |= PCRE2_CASELESS;
  3199. + }
  3200. +
  3201. + pattern = convert_libmagic_pattern((char *)m->value.s, m->vallen, options);
  3202. +
  3203. + l = v = 0;
  3204. + if ((pce = pcre_get_compiled_regex_cache(pattern)) == NULL) {
  3205. + zend_string_release(pattern);
  3206. + return -1;
  3207. } else {
  3208. - regmatch_t pmatch;
  3209. - size_t slen = ms->search.s_len;
  3210. - char *copy;
  3211. - if (slen != 0) {
  3212. - copy = CAST(char *, malloc(slen));
  3213. - if (copy == NULL) {
  3214. - file_regfree(&rx);
  3215. - file_error(ms, errno,
  3216. - "can't allocate %" SIZE_T_FORMAT "u bytes",
  3217. - slen);
  3218. + /* pce now contains the compiled regex */
  3219. + zval retval;
  3220. + zval subpats;
  3221. + zend_string *haystack;
  3222. +
  3223. + ZVAL_NULL(&retval);
  3224. + ZVAL_NULL(&subpats);
  3225. +
  3226. + /* Cut the search len from haystack, equals to REG_STARTEND */
  3227. + haystack = zend_string_init(ms->search.s, ms->search.s_len, 0);
  3228. +
  3229. + /* match v = 0, no match v = 1 */
  3230. + php_pcre_match_impl(pce, haystack, &retval, &subpats, 0, 1, PREG_OFFSET_CAPTURE, 0);
  3231. + /* Free haystack */
  3232. + zend_string_release(haystack);
  3233. +
  3234. + if (Z_LVAL(retval) < 0) {
  3235. + zval_ptr_dtor(&subpats);
  3236. + zend_string_release(pattern);
  3237. return -1;
  3238. - }
  3239. - memcpy(copy, ms->search.s, slen);
  3240. - copy[--slen] = '\0';
  3241. - search = copy;
  3242. + } else if ((Z_LVAL(retval) > 0) && (Z_TYPE(subpats) == IS_ARRAY)) {
  3243. + /* Need to fetch global match which equals pmatch[0] */
  3244. + zval *pzval;
  3245. + HashTable *ht = Z_ARRVAL(subpats);
  3246. + if ((pzval = zend_hash_index_find(ht, 0)) != NULL && Z_TYPE_P(pzval) == IS_ARRAY) {
  3247. + /* If everything goes according to the master plan
  3248. + tmpcopy now contains two elements:
  3249. + 0 = the match
  3250. + 1 = starting position of the match */
  3251. + zval *match, *offset;
  3252. + if ((match = zend_hash_index_find(Z_ARRVAL_P(pzval), 0)) &&
  3253. + (offset = zend_hash_index_find(Z_ARRVAL_P(pzval), 1))) {
  3254. + if (Z_TYPE_P(match) != IS_STRING && Z_TYPE_P(offset) != IS_LONG) {
  3255. + goto error_out;
  3256. + }
  3257. + ms->search.s += Z_LVAL_P(offset); /* this is where the match starts */
  3258. + ms->search.offset += Z_LVAL_P(offset); /* this is where the match starts as size_t */
  3259. + ms->search.rm_len = Z_STRLEN_P(match) /* This is the length of the matched pattern */;
  3260. + v = 0;
  3261. + } else {
  3262. + goto error_out;
  3263. + }
  3264. + } else {
  3265. +error_out:
  3266. + zval_ptr_dtor(&subpats);
  3267. + zend_string_release(pattern);
  3268. + return -1;
  3269. + }
  3270. } else {
  3271. - search = CCAST(char *, "");
  3272. - copy = NULL;
  3273. - }
  3274. - rc = file_regexec(&rx, RCAST(const char *, search),
  3275. - 1, &pmatch, 0);
  3276. - free(copy);
  3277. - switch (rc) {
  3278. - case 0:
  3279. - ms->search.s += CAST(int, pmatch.rm_so);
  3280. - ms->search.offset += CAST(size_t, pmatch.rm_so);
  3281. - ms->search.rm_len = CAST(size_t,
  3282. - pmatch.rm_eo - pmatch.rm_so);
  3283. - v = 0;
  3284. - break;
  3285. -
  3286. - case REG_NOMATCH:
  3287. v = 1;
  3288. - break;
  3289. -
  3290. - default:
  3291. - file_regerror(&rx, rc, ms);
  3292. - v = CAST(uint64_t, -1);
  3293. - break;
  3294. }
  3295. + zval_ptr_dtor(&subpats);
  3296. + zend_string_release(pattern);
  3297. }
  3298. - file_regfree(&rx);
  3299. - if (v == CAST(uint64_t, -1))
  3300. - return -1;
  3301. break;
  3302. }
  3303. case FILE_USE:
  3304. diff -u libmagic.orig/strcasestr.c libmagic/strcasestr.c
  3305. --- libmagic.orig/strcasestr.c 2021-02-23 01:49:12.000000000 +0100
  3306. +++ libmagic/strcasestr.c 2021-09-21 13:27:28.002306200 +0200
  3307. @@ -39,6 +39,8 @@
  3308. #include "file.h"
  3309. +#include "php_stdint.h"
  3310. +
  3311. #include <assert.h>
  3312. #include <ctype.h>
  3313. #include <string.h>