libmagic.patch 104 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277
  1. diff -u libmagic.orig/apprentice.c libmagic/apprentice.c
  2. --- libmagic.orig/apprentice.c 2018-03-11 01:46:42.000000000 +0100
  3. +++ libmagic/apprentice.c 2020-02-26 09:55:13.842042400 +0100
  4. @@ -2,7 +2,7 @@
  5. * Copyright (c) Ian F. Darwin 1986-1995.
  6. * Software written by Ian F. Darwin and others;
  7. * maintained 1995-present by Christos Zoulas and others.
  8. - *
  9. + *
  10. * Redistribution and use in source and binary forms, with or without
  11. * modification, are permitted provided that the following conditions
  12. * are met:
  13. @@ -12,7 +12,7 @@
  14. * 2. Redistributions in binary form must reproduce the above copyright
  15. * notice, this list of conditions and the following disclaimer in the
  16. * documentation and/or other materials provided with the distribution.
  17. - *
  18. + *
  19. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  20. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  21. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  22. @@ -29,6 +29,8 @@
  23. * apprentice - make one pass through /etc/magic, learning its secrets.
  24. */
  25. +#include "php.h"
  26. +
  27. #include "file.h"
  28. #ifndef lint
  29. @@ -36,24 +38,27 @@
  30. #endif /* lint */
  31. #include "magic.h"
  32. +#include "patchlevel.h"
  33. #include <stdlib.h>
  34. -#ifdef HAVE_UNISTD_H
  35. -#include <unistd.h>
  36. +
  37. +#if defined(__hpux) && !defined(HAVE_STRTOULL)
  38. +#if SIZEOF_LONG == 8
  39. +# define strtoull strtoul
  40. +#else
  41. +# define strtoull __strtoull
  42. #endif
  43. -#ifdef HAVE_STDDEF_H
  44. -#include <stddef.h>
  45. +#endif
  46. +
  47. +#ifdef PHP_WIN32
  48. +#include "win32/unistd.h"
  49. +#define strtoull _strtoui64
  50. +#else
  51. +#include <unistd.h>
  52. #endif
  53. #include <string.h>
  54. #include <assert.h>
  55. #include <ctype.h>
  56. #include <fcntl.h>
  57. -#ifdef QUICK
  58. -#include <sys/mman.h>
  59. -#endif
  60. -#include <dirent.h>
  61. -#if defined(HAVE_LIMITS_H)
  62. -#include <limits.h>
  63. -#endif
  64. #ifndef SSIZE_MAX
  65. #define MAXMAGIC_SIZE ((ssize_t)0x7fffffff)
  66. @@ -75,6 +80,10 @@
  67. #endif
  68. #endif
  69. +#ifndef offsetof
  70. +#define offsetof(STRUCTURE,FIELD) ((int)((char*)&((STRUCTURE*)0)->FIELD))
  71. +#endif
  72. +
  73. #ifndef MAP_FAILED
  74. #define MAP_FAILED (void *) -1
  75. #endif
  76. @@ -91,7 +100,7 @@
  77. #define MAP_TYPE_MMAP 2
  78. struct magic_entry {
  79. - struct magic *mp;
  80. + struct magic *mp;
  81. uint32_t cont_count;
  82. uint32_t max_count;
  83. };
  84. @@ -126,7 +135,7 @@
  85. private size_t apprentice_magic_strength(const struct magic *);
  86. private int apprentice_sort(const void *, const void *);
  87. private void apprentice_list(struct mlist *, int );
  88. -private struct magic_map *apprentice_load(struct magic_set *,
  89. +private struct magic_map *apprentice_load(struct magic_set *,
  90. const char *, int);
  91. private struct mlist *mlist_alloc(void);
  92. private void mlist_free(struct mlist *);
  93. @@ -170,38 +179,7 @@
  94. { NULL, 0, NULL }
  95. };
  96. -#ifdef COMPILE_ONLY
  97. -
  98. -int main(int, char *[]);
  99. -
  100. -int
  101. -main(int argc, char *argv[])
  102. -{
  103. - int ret;
  104. - struct magic_set *ms;
  105. - char *progname;
  106. -
  107. - if ((progname = strrchr(argv[0], '/')) != NULL)
  108. - progname++;
  109. - else
  110. - progname = argv[0];
  111. -
  112. - if (argc != 2) {
  113. - (void)fprintf(stderr, "Usage: %s file\n", progname);
  114. - return 1;
  115. - }
  116. -
  117. - if ((ms = magic_open(MAGIC_CHECK)) == NULL) {
  118. - (void)fprintf(stderr, "%s: %s\n", progname, strerror(errno));
  119. - return 1;
  120. - }
  121. - ret = magic_compile(ms, argv[1]) == -1 ? 1 : 0;
  122. - if (ret == 1)
  123. - (void)fprintf(stderr, "%s: %s\n", progname, magic_error(ms));
  124. - magic_close(ms);
  125. - return ret;
  126. -}
  127. -#endif /* COMPILE_ONLY */
  128. +#include "../data_file.c"
  129. struct type_tbl_s {
  130. const char name[16];
  131. @@ -409,7 +387,7 @@
  132. struct mlist *ml;
  133. mlp->map = NULL;
  134. - if ((ml = CAST(struct mlist *, malloc(sizeof(*ml)))) == NULL)
  135. + if ((ml = CAST(struct mlist *, emalloc(sizeof(*ml)))) == NULL)
  136. return -1;
  137. ml->map = idx == 0 ? map : NULL;
  138. @@ -430,10 +408,8 @@
  139. apprentice_1(struct magic_set *ms, const char *fn, int action)
  140. {
  141. struct magic_map *map;
  142. -#ifndef COMPILE_ONLY
  143. struct mlist *ml;
  144. size_t i;
  145. -#endif
  146. if (magicsize != FILE_MAGICSIZE) {
  147. file_error(ms, 0, "magic element size %lu != %lu",
  148. @@ -449,14 +425,15 @@
  149. return apprentice_compile(ms, map, fn);
  150. }
  151. -#ifndef COMPILE_ONLY
  152. map = apprentice_map(ms, fn);
  153. if (map == (struct magic_map *)-1)
  154. return -1;
  155. if (map == NULL) {
  156. - if (ms->flags & MAGIC_CHECK)
  157. - file_magwarn(ms, "using regular magic file `%s'", fn);
  158. - map = apprentice_load(ms, fn, action);
  159. + if (fn) {
  160. + if (ms->flags & MAGIC_CHECK)
  161. + file_magwarn(ms, "using regular magic file `%s'", fn);
  162. + map = apprentice_load(ms, fn, action);
  163. + }
  164. if (map == NULL)
  165. return -1;
  166. }
  167. @@ -478,9 +455,6 @@
  168. }
  169. }
  170. return 0;
  171. -#else
  172. - return 0;
  173. -#endif /* COMPILE_ONLY */
  174. }
  175. protected void
  176. @@ -491,10 +465,16 @@
  177. return;
  178. for (i = 0; i < MAGIC_SETS; i++)
  179. mlist_free(ms->mlist[i]);
  180. - free(ms->o.pbuf);
  181. - free(ms->o.buf);
  182. - free(ms->c.li);
  183. - free(ms);
  184. + if (ms->o.pbuf) {
  185. + efree(ms->o.pbuf);
  186. + }
  187. + if (ms->o.buf) {
  188. + efree(ms->o.buf);
  189. + }
  190. + if (ms->c.li) {
  191. + efree(ms->c.li);
  192. + }
  193. + efree(ms);
  194. }
  195. protected struct magic_set *
  196. @@ -503,7 +483,7 @@
  197. struct magic_set *ms;
  198. size_t i, len;
  199. - if ((ms = CAST(struct magic_set *, calloc((size_t)1,
  200. + if ((ms = CAST(struct magic_set *, ecalloc((size_t)1,
  201. sizeof(struct magic_set)))) == NULL)
  202. return NULL;
  203. @@ -515,7 +495,7 @@
  204. ms->o.buf = ms->o.pbuf = NULL;
  205. len = (ms->c.len = 10) * sizeof(*ms->c.li);
  206. - if ((ms->c.li = CAST(struct level_info *, malloc(len))) == NULL)
  207. + if ((ms->c.li = CAST(struct level_info *, emalloc(len))) == NULL)
  208. goto free;
  209. ms->event_flags = 0;
  210. @@ -533,48 +513,35 @@
  211. ms->bytes_max = FILE_BYTES_MAX;
  212. return ms;
  213. free:
  214. - free(ms);
  215. + efree(ms);
  216. return NULL;
  217. }
  218. private void
  219. apprentice_unmap(struct magic_map *map)
  220. {
  221. - size_t i;
  222. if (map == NULL)
  223. return;
  224. -
  225. - switch (map->type) {
  226. - case MAP_TYPE_USER:
  227. - break;
  228. - case MAP_TYPE_MALLOC:
  229. - for (i = 0; i < MAGIC_SETS; i++) {
  230. - void *b = map->magic[i];
  231. - void *p = map->p;
  232. - if (CAST(char *, b) >= CAST(char *, p) &&
  233. - CAST(char *, b) <= CAST(char *, p) + map->len)
  234. - continue;
  235. - free(map->magic[i]);
  236. + if (map->p != php_magic_database) {
  237. + if (map->p == NULL) {
  238. + int j;
  239. + for (j = 0; j < MAGIC_SETS; j++) {
  240. + if (map->magic[j]) {
  241. + efree(map->magic[j]);
  242. + }
  243. + }
  244. + } else {
  245. + efree(map->p);
  246. }
  247. - free(map->p);
  248. - break;
  249. -#ifdef QUICK
  250. - case MAP_TYPE_MMAP:
  251. - if (map->p && map->p != MAP_FAILED)
  252. - (void)munmap(map->p, map->len);
  253. - break;
  254. -#endif
  255. - default:
  256. - abort();
  257. }
  258. - free(map);
  259. + efree(map);
  260. }
  261. private struct mlist *
  262. mlist_alloc(void)
  263. {
  264. struct mlist *mlist;
  265. - if ((mlist = CAST(struct mlist *, calloc(1, sizeof(*mlist)))) == NULL) {
  266. + if ((mlist = CAST(struct mlist *, ecalloc(1, sizeof(*mlist)))) == NULL) {
  267. return NULL;
  268. }
  269. mlist->next = mlist->prev = mlist;
  270. @@ -593,60 +560,12 @@
  271. for (ml = mlist->next; (next = ml->next) != NULL; ml = next) {
  272. if (ml->map)
  273. apprentice_unmap(CAST(struct magic_map *, ml->map));
  274. - free(ml);
  275. + efree(ml);
  276. if (ml == mlist)
  277. break;
  278. }
  279. }
  280. -#ifndef COMPILE_ONLY
  281. -/* void **bufs: an array of compiled magic files */
  282. -protected int
  283. -buffer_apprentice(struct magic_set *ms, struct magic **bufs,
  284. - size_t *sizes, size_t nbufs)
  285. -{
  286. - size_t i, j;
  287. - struct mlist *ml;
  288. - struct magic_map *map;
  289. -
  290. - if (nbufs == 0)
  291. - return -1;
  292. -
  293. - (void)file_reset(ms, 0);
  294. -
  295. - init_file_tables();
  296. -
  297. - for (i = 0; i < MAGIC_SETS; i++) {
  298. - mlist_free(ms->mlist[i]);
  299. - if ((ms->mlist[i] = mlist_alloc()) == NULL) {
  300. - file_oomem(ms, sizeof(*ms->mlist[i]));
  301. - goto fail;
  302. - }
  303. - }
  304. -
  305. - for (i = 0; i < nbufs; i++) {
  306. - map = apprentice_buf(ms, bufs[i], sizes[i]);
  307. - if (map == NULL)
  308. - goto fail;
  309. -
  310. - for (j = 0; j < MAGIC_SETS; j++) {
  311. - if (add_mlist(ms->mlist[j], map, j) == -1) {
  312. - file_oomem(ms, sizeof(*ml));
  313. - goto fail;
  314. - }
  315. - }
  316. - }
  317. -
  318. - return 0;
  319. -fail:
  320. - for (i = 0; i < MAGIC_SETS; i++) {
  321. - mlist_free(ms->mlist[i]);
  322. - ms->mlist[i] = NULL;
  323. - }
  324. - return -1;
  325. -}
  326. -#endif
  327. -
  328. /* const char *fn: list of magic files and directories */
  329. protected int
  330. file_apprentice(struct magic_set *ms, const char *fn, int action)
  331. @@ -655,14 +574,31 @@
  332. int fileerr, errs = -1;
  333. size_t i;
  334. - (void)file_reset(ms, 0);
  335. + if (ms->mlist[0] != NULL)
  336. + (void)file_reset(ms, 0);
  337. +/* XXX disabling default magic loading so the compiled in data is used */
  338. +#if 0
  339. if ((fn = magic_getpath(fn, action)) == NULL)
  340. return -1;
  341. +#endif
  342. init_file_tables();
  343. - if ((mfn = strdup(fn)) == NULL) {
  344. + if (fn == NULL)
  345. + fn = getenv("MAGIC");
  346. + if (fn == NULL) {
  347. + for (i = 0; i < MAGIC_SETS; i++) {
  348. + mlist_free(ms->mlist[i]);
  349. + if ((ms->mlist[i] = mlist_alloc()) == NULL) {
  350. + file_oomem(ms, sizeof(*ms->mlist[i]));
  351. + return -1;
  352. + }
  353. + }
  354. + return apprentice_1(ms, fn, action);
  355. + }
  356. +
  357. + if ((mfn = estrdup(fn)) == NULL) {
  358. file_oomem(ms, strlen(fn));
  359. return -1;
  360. }
  361. @@ -675,7 +611,7 @@
  362. mlist_free(ms->mlist[i]);
  363. ms->mlist[i] = NULL;
  364. }
  365. - free(mfn);
  366. + efree(mfn);
  367. return -1;
  368. }
  369. }
  370. @@ -692,7 +628,7 @@
  371. fn = p;
  372. }
  373. - free(mfn);
  374. + efree(mfn);
  375. if (errs == -1) {
  376. for (i = 0; i < MAGIC_SETS; i++) {
  377. @@ -974,7 +910,7 @@
  378. return val;
  379. }
  380. -/*
  381. +/*
  382. * Sort callback for sorting entries by "strength" (basically length)
  383. */
  384. private int
  385. @@ -992,7 +928,7 @@
  386. return 1;
  387. }
  388. -/*
  389. +/*
  390. * Shows sorted patterns list in the order which is used for the matching
  391. */
  392. private void
  393. @@ -1088,7 +1024,7 @@
  394. mstart->flag |= BINTEST;
  395. if (mstart->str_flags & STRING_TEXTTEST)
  396. mstart->flag |= TEXTTEST;
  397. -
  398. +
  399. if (mstart->flag & (TEXTTEST|BINTEST))
  400. break;
  401. @@ -1120,7 +1056,7 @@
  402. mset[i].max += ALLOC_INCR;
  403. if ((mp = CAST(struct magic_entry *,
  404. - realloc(mset[i].me, sizeof(*mp) * mset[i].max))) ==
  405. + erealloc(mset[i].me, sizeof(*mp) * mset[i].max))) ==
  406. NULL) {
  407. file_oomem(ms, sizeof(*mp) * mset[i].max);
  408. return -1;
  409. @@ -1141,13 +1077,19 @@
  410. load_1(struct magic_set *ms, int action, const char *fn, int *errs,
  411. struct magic_entry_set *mset)
  412. {
  413. - size_t lineno = 0, llen = 0;
  414. + char buffer[BUFSIZ + 1];
  415. char *line = NULL;
  416. - ssize_t len;
  417. + size_t len;
  418. + size_t lineno = 0;
  419. struct magic_entry me;
  420. - FILE *f = fopen(ms->file = fn, "r");
  421. - if (f == NULL) {
  422. + php_stream *stream;
  423. +
  424. +
  425. + ms->file = fn;
  426. + stream = php_stream_open_wrapper((char *)fn, "rb", REPORT_ERRORS, NULL);
  427. +
  428. + if (stream == NULL) {
  429. if (errno != ENOENT)
  430. file_error(ms, errno, "cannot read magic file `%s'",
  431. fn);
  432. @@ -1157,8 +1099,7 @@
  433. memset(&me, 0, sizeof(me));
  434. /* read and parse this file */
  435. - for (ms->line = 1; (len = getline(&line, &llen, f)) != -1;
  436. - ms->line++) {
  437. + for (ms->line = 1; (line = php_stream_get_line(stream, buffer , BUFSIZ, &len)) != NULL; ms->line++) {
  438. if (len == 0) /* null line, garbage, etc */
  439. continue;
  440. if (line[len - 1] == '\n') {
  441. @@ -1216,8 +1157,8 @@
  442. }
  443. if (me.mp)
  444. (void)addentry(ms, &me, mset);
  445. - free(line);
  446. - (void)fclose(f);
  447. + efree(line);
  448. + php_stream_close(stream);
  449. }
  450. /*
  451. @@ -1280,7 +1221,7 @@
  452. file_magwarn(ms,
  453. "level 0 \"default\" did not sort last");
  454. }
  455. - return;
  456. + return;
  457. }
  458. }
  459. }
  460. @@ -1296,7 +1237,7 @@
  461. mentrycount += me[i].cont_count;
  462. slen = sizeof(**ma) * mentrycount;
  463. - if ((*ma = CAST(struct magic *, malloc(slen))) == NULL) {
  464. + if ((*ma = CAST(struct magic *, emalloc(slen))) == NULL) {
  465. file_oomem(ms, slen);
  466. return -1;
  467. }
  468. @@ -1318,8 +1259,8 @@
  469. if (me == NULL)
  470. return;
  471. for (i = 0; i < nme; i++)
  472. - free(me[i].mp);
  473. - free(me);
  474. + efree(me[i].mp);
  475. + efree(me);
  476. }
  477. private struct magic_map *
  478. @@ -1328,18 +1269,19 @@
  479. int errs = 0;
  480. uint32_t i, j;
  481. size_t files = 0, maxfiles = 0;
  482. - char **filearr = NULL, *mfn;
  483. - struct stat st;
  484. + char **filearr = NULL;
  485. + zend_stat_t st;
  486. struct magic_map *map;
  487. struct magic_entry_set mset[MAGIC_SETS];
  488. - DIR *dir;
  489. - struct dirent *d;
  490. + php_stream *dir;
  491. + php_stream_dirent d;
  492. +
  493. memset(mset, 0, sizeof(mset));
  494. ms->flags |= MAGIC_CHECK; /* Enable checks for parsed files */
  495. - if ((map = CAST(struct magic_map *, calloc(1, sizeof(*map)))) == NULL)
  496. + if ((map = CAST(struct magic_map *, ecalloc(1, sizeof(*map)))) == NULL)
  497. {
  498. file_oomem(ms, sizeof(*map));
  499. return NULL;
  500. @@ -1351,24 +1293,26 @@
  501. (void)fprintf(stderr, "%s\n", usg_hdr);
  502. /* load directory or file */
  503. - if (stat(fn, &st) == 0 && S_ISDIR(st.st_mode)) {
  504. - dir = opendir(fn);
  505. + /* FIXME: Read file names and sort them to prevent
  506. + non-determinism. See Debian bug #488562. */
  507. + if (php_sys_stat(fn, &st) == 0 && S_ISDIR(st.st_mode)) {
  508. + int mflen;
  509. + char mfn[MAXPATHLEN];
  510. +
  511. + dir = php_stream_opendir((char *)fn, REPORT_ERRORS, NULL);
  512. if (!dir) {
  513. errs++;
  514. goto out;
  515. }
  516. - while ((d = readdir(dir)) != NULL) {
  517. - if (d->d_name[0] == '.')
  518. - continue;
  519. - if (asprintf(&mfn, "%s/%s", fn, d->d_name) < 0) {
  520. + while (php_stream_readdir(dir, &d)) {
  521. + if ((mflen = snprintf(mfn, sizeof(mfn), "%s/%s", fn, d.d_name)) < 0) {
  522. file_oomem(ms,
  523. - strlen(fn) + strlen(d->d_name) + 2);
  524. + strlen(fn) + strlen(d.d_name) + 2);
  525. errs++;
  526. - closedir(dir);
  527. + php_stream_closedir(dir);
  528. goto out;
  529. }
  530. - if (stat(mfn, &st) == -1 || !S_ISREG(st.st_mode)) {
  531. - free(mfn);
  532. + if (zend_stat(mfn, &st) == -1 || !S_ISREG(st.st_mode)) {
  533. continue;
  534. }
  535. if (files >= maxfiles) {
  536. @@ -1376,23 +1320,22 @@
  537. maxfiles = (maxfiles + 1) * 2;
  538. mlen = maxfiles * sizeof(*filearr);
  539. if ((filearr = CAST(char **,
  540. - realloc(filearr, mlen))) == NULL) {
  541. + erealloc(filearr, mlen))) == NULL) {
  542. file_oomem(ms, mlen);
  543. - free(mfn);
  544. - closedir(dir);
  545. + php_stream_closedir(dir);
  546. errs++;
  547. goto out;
  548. }
  549. }
  550. - filearr[files++] = mfn;
  551. + filearr[files++] = estrndup(mfn, (mflen > sizeof(mfn) - 1)? sizeof(mfn) - 1: mflen);
  552. }
  553. - closedir(dir);
  554. + php_stream_closedir(dir);
  555. qsort(filearr, files, sizeof(*filearr), cmpstrp);
  556. for (i = 0; i < files; i++) {
  557. load_1(ms, action, filearr[i], &errs, mset);
  558. - free(filearr[i]);
  559. + efree(filearr[i]);
  560. }
  561. - free(filearr);
  562. + efree(filearr);
  563. } else
  564. load_1(ms, action, fn, &errs, mset);
  565. if (errs)
  566. @@ -1833,7 +1776,7 @@
  567. */
  568. while (*l == '>') {
  569. ++l; /* step over */
  570. - cont_level++;
  571. + cont_level++;
  572. }
  573. #ifdef ENABLE_CONDITIONALS
  574. if (cont_level == 0 || cont_level > last_cont_level)
  575. @@ -1859,7 +1802,7 @@
  576. if (me->cont_count == me->max_count) {
  577. struct magic *nm;
  578. size_t cnt = me->max_count + ALLOC_CHUNK;
  579. - if ((nm = CAST(struct magic *, realloc(me->mp,
  580. + if ((nm = CAST(struct magic *, erealloc(me->mp,
  581. sizeof(*nm) * cnt))) == NULL) {
  582. file_oomem(ms, sizeof(*nm) * cnt);
  583. return -1;
  584. @@ -1874,7 +1817,7 @@
  585. static const size_t len = sizeof(*m) * ALLOC_CHUNK;
  586. if (me->mp != NULL)
  587. return 1;
  588. - if ((m = CAST(struct magic *, malloc(len))) == NULL) {
  589. + if ((m = CAST(struct magic *, emalloc(len))) == NULL) {
  590. file_oomem(ms, len);
  591. return -1;
  592. }
  593. @@ -1916,17 +1859,6 @@
  594. file_magwarn(ms, "offset `%s' invalid", l);
  595. return -1;
  596. }
  597. -#if 0
  598. - if (m->offset < 0 && cont_level != 0 &&
  599. - (m->flag & (OFFADD | INDIROFFADD)) == 0) {
  600. - if (ms->flags & MAGIC_CHECK) {
  601. - file_magwarn(ms,
  602. - "negative direct offset `%s' at level %u",
  603. - l, cont_level);
  604. - }
  605. - return -1;
  606. - }
  607. -#endif
  608. l = t;
  609. if (m->flag & INDIR) {
  610. @@ -2012,7 +1944,7 @@
  611. }
  612. l = t;
  613. }
  614. - if (*l++ != ')' ||
  615. + if (*l++ != ')' ||
  616. ((m->in_op & FILE_OPINDIRECT) && *l++ != ')')) {
  617. if (ms->flags & MAGIC_CHECK)
  618. file_magwarn(ms,
  619. @@ -2037,7 +1969,7 @@
  620. /*
  621. * Try it as a keyword type prefixed by "u"; match what
  622. * follows the "u". If that fails, try it as an SUS
  623. - * integer type.
  624. + * integer type.
  625. */
  626. m->type = get_type(type_tbl, l + 1, &l);
  627. if (m->type == FILE_INVALID) {
  628. @@ -2077,7 +2009,7 @@
  629. /* Not found - try it as a special keyword. */
  630. m->type = get_type(special_tbl, l, &l);
  631. }
  632. -
  633. +
  634. if (m->type == FILE_INVALID) {
  635. if (ms->flags & MAGIC_CHECK)
  636. file_magwarn(ms, "type `%s' invalid", l);
  637. @@ -2089,7 +2021,7 @@
  638. m->mask_op = 0;
  639. if (*l == '~') {
  640. - if (!IS_STRING(m->type))
  641. + if (!IS_LIBMAGIC_STRING(m->type))
  642. m->mask_op |= FILE_OPINVERSE;
  643. else if (ms->flags & MAGIC_CHECK)
  644. file_magwarn(ms, "'~' invalid for string types");
  645. @@ -2098,7 +2030,7 @@
  646. m->str_range = 0;
  647. m->str_flags = m->type == FILE_PSTRING ? PSTRING_1_LE : 0;
  648. if ((op = get_op(*l)) != -1) {
  649. - if (IS_STRING(m->type)) {
  650. + if (IS_LIBMAGIC_STRING(m->type)) {
  651. int r;
  652. if (op != FILE_OPDIVIDE) {
  653. @@ -2124,7 +2056,7 @@
  654. * anything if mask = 0 (unless you have a better idea)
  655. */
  656. EATAB;
  657. -
  658. +
  659. switch (*l) {
  660. case '>':
  661. case '<':
  662. @@ -2156,7 +2088,7 @@
  663. break;
  664. default:
  665. m->reln = '='; /* the default relation */
  666. - if (*l == 'x' && ((isascii((unsigned char)l[1]) &&
  667. + if (*l == 'x' && ((isascii((unsigned char)l[1]) &&
  668. isspace((unsigned char)l[1])) || !l[1])) {
  669. m->reln = *l;
  670. ++l;
  671. @@ -2171,7 +2103,7 @@
  672. /*
  673. * TODO finish this macro and start using it!
  674. - * #define offsetcheck {if (offset > ms->bytes_max -1)
  675. + * #define offsetcheck {if (offset > ms->bytes_max -1)
  676. * magwarn("offset too big"); }
  677. */
  678. @@ -2203,11 +2135,6 @@
  679. if (check_format(ms, m) == -1)
  680. return -1;
  681. }
  682. -#ifndef COMPILE_ONLY
  683. - if (action == FILE_CHECK) {
  684. - file_mdump(m);
  685. - }
  686. -#endif
  687. m->mimetype[0] = '\0'; /* initialise MIME type to none */
  688. return 0;
  689. }
  690. @@ -2279,7 +2206,7 @@
  691. private int
  692. parse_extra(struct magic_set *ms, struct magic_entry *me, const char *line,
  693. - off_t off, size_t len, const char *name, const char *extra, int nt)
  694. + zend_off_t off, size_t len, const char *name, const char *extra, int nt)
  695. {
  696. size_t i;
  697. const char *l = line;
  698. @@ -2291,7 +2218,7 @@
  699. file_magwarn(ms, "Current entry already has a %s type "
  700. "`%.*s', new type `%s'", name, (int)len, buf, l);
  701. return -1;
  702. - }
  703. + }
  704. if (*m->desc == '\0') {
  705. file_magwarn(ms, "Current entry does not yet have a "
  706. @@ -2361,7 +2288,7 @@
  707. struct magic *m = &me->mp[0];
  708. return parse_extra(ms, me, line,
  709. - CAST(off_t, offsetof(struct magic, mimetype)),
  710. + CAST(zend_off_t, offsetof(struct magic, mimetype)),
  711. sizeof(m->mimetype), "MIME", "+-/.$?:{}", 1);
  712. }
  713. @@ -2428,7 +2355,7 @@
  714. if (*ptr++ != 'l')
  715. goto invalid;
  716. }
  717. -
  718. +
  719. switch (*ptr++) {
  720. #ifdef STRICT_FORMAT /* "long" formats are int formats for us */
  721. /* so don't accept the 'l' modifier */
  722. @@ -2446,7 +2373,7 @@
  723. default:
  724. goto invalid;
  725. }
  726. -
  727. +
  728. /*
  729. * Don't accept h and hh modifiers. They make writing
  730. * magic entries more complicated, for very little benefit
  731. @@ -2502,7 +2429,7 @@
  732. default:
  733. goto invalid;
  734. }
  735. -
  736. +
  737. case FILE_FMT_FLOAT:
  738. case FILE_FMT_DOUBLE:
  739. if (*ptr == '-')
  740. @@ -2521,11 +2448,11 @@
  741. case 'g':
  742. case 'G':
  743. return 0;
  744. -
  745. +
  746. default:
  747. goto invalid;
  748. }
  749. -
  750. +
  751. case FILE_FMT_STR:
  752. if (*ptr == '-')
  753. @@ -2537,14 +2464,14 @@
  754. while (isdigit((unsigned char )*ptr))
  755. ptr++;
  756. }
  757. -
  758. +
  759. switch (*ptr++) {
  760. case 's':
  761. return 0;
  762. default:
  763. goto invalid;
  764. }
  765. -
  766. +
  767. default:
  768. /* internal error */
  769. abort();
  770. @@ -2555,7 +2482,7 @@
  771. *estr = "too long";
  772. return -1;
  773. }
  774. -
  775. +
  776. /*
  777. * Check that the optional printf format in description matches
  778. * the type of the magic.
  779. @@ -2578,7 +2505,7 @@
  780. if (m->type >= file_nformats) {
  781. file_magwarn(ms, "Internal error inconsistency between "
  782. - "m->type and format strings");
  783. + "m->type and format strings");
  784. return -1;
  785. }
  786. if (file_formats[m->type] == FILE_FMT_NONE) {
  787. @@ -2598,7 +2525,7 @@
  788. file_names[m->type], m->desc);
  789. return -1;
  790. }
  791. -
  792. +
  793. for (; *ptr; ptr++) {
  794. if (*ptr == '%') {
  795. file_magwarn(ms,
  796. @@ -2611,9 +2538,9 @@
  797. return 0;
  798. }
  799. -/*
  800. - * Read a numeric value from a pointer, into the value union of a magic
  801. - * pointer, according to the magic type. Update the string pointer to point
  802. +/*
  803. + * Read a numeric value from a pointer, into the value union of a magic
  804. + * pointer, according to the magic type. Update the string pointer to point
  805. * just after the number read. Return 0 for success, non-zero for failure.
  806. */
  807. private int
  808. @@ -2640,14 +2567,19 @@
  809. return -1;
  810. }
  811. if (m->type == FILE_REGEX) {
  812. - file_regex_t rx;
  813. - int rc = file_regcomp(&rx, m->value.s, REG_EXTENDED);
  814. - if (rc) {
  815. - if (ms->flags & MAGIC_CHECK)
  816. - file_regerror(&rx, rc, ms);
  817. + zval pattern;
  818. + int options = 0;
  819. + pcre_cache_entry *pce;
  820. +
  821. + convert_libmagic_pattern(&pattern, m->value.s, strlen(m->value.s), options);
  822. +
  823. + if ((pce = pcre_get_compiled_regex_cache(Z_STR(pattern))) == NULL) {
  824. + zval_dtor(&pattern);
  825. + return -1;
  826. }
  827. - file_regfree(&rx);
  828. - return rc ? -1 : 0;
  829. + zval_dtor(&pattern);
  830. +
  831. + return 0;
  832. }
  833. return 0;
  834. default:
  835. @@ -2770,7 +2702,7 @@
  836. default:
  837. if (warn) {
  838. if (isprint((unsigned char)c)) {
  839. - /* Allow escaping of
  840. + /* Allow escaping of
  841. * ``relations'' */
  842. if (strchr("<>&^=!", c) == NULL
  843. && (m->type != FILE_REGEX ||
  844. @@ -2975,7 +2907,7 @@
  845. {
  846. const char *l = *p;
  847. - if (LOWCASE(*l) == 'u')
  848. + if (LOWCASE(*l) == 'u')
  849. l++;
  850. switch (LOWCASE(*l)) {
  851. @@ -3001,7 +2933,7 @@
  852. {
  853. struct magic_map *map;
  854. - if ((map = CAST(struct magic_map *, calloc(1, sizeof(*map)))) == NULL) {
  855. + if ((map = CAST(struct magic_map *, ecalloc(1, sizeof(*map)))) == NULL) {
  856. file_oomem(ms, sizeof(*map));
  857. return NULL;
  858. }
  859. @@ -3022,79 +2954,145 @@
  860. private struct magic_map *
  861. apprentice_map(struct magic_set *ms, const char *fn)
  862. {
  863. - int fd;
  864. - struct stat st;
  865. + uint32_t *ptr;
  866. + uint32_t version, entries, nentries;
  867. + int needsbyteswap;
  868. char *dbname = NULL;
  869. struct magic_map *map;
  870. - struct magic_map *rv = NULL;
  871. + size_t i;
  872. + php_stream *stream = NULL;
  873. + php_stream_statbuf st;
  874. +
  875. +
  876. - fd = -1;
  877. - if ((map = CAST(struct magic_map *, calloc(1, sizeof(*map)))) == NULL) {
  878. + if ((map = CAST(struct magic_map *, ecalloc(1, sizeof(*map)))) == NULL) {
  879. file_oomem(ms, sizeof(*map));
  880. - goto error;
  881. + return NULL;
  882. + }
  883. +
  884. + if (fn == NULL) {
  885. + map->p = (void *)&php_magic_database;
  886. + goto internal_loaded;
  887. }
  888. - map->type = MAP_TYPE_USER; /* unspecified */
  889. +
  890. +#ifdef PHP_WIN32
  891. + /* Don't bother on windows with php_stream_open_wrapper,
  892. + return to give apprentice_load() a chance. */
  893. + if (php_stream_stat_path_ex((char *)fn, 0, &st, NULL) == SUCCESS) {
  894. + if (st.sb.st_mode & S_IFDIR) {
  895. + return NULL;
  896. + }
  897. + }
  898. +#endif
  899. dbname = mkdbname(ms, fn, 0);
  900. if (dbname == NULL)
  901. goto error;
  902. - if ((fd = open(dbname, O_RDONLY|O_BINARY)) == -1)
  903. + stream = php_stream_open_wrapper((char *)fn, "rb", REPORT_ERRORS, NULL);
  904. +
  905. + if (!stream) {
  906. goto error;
  907. + }
  908. - if (fstat(fd, &st) == -1) {
  909. + if (php_stream_stat(stream, &st) < 0) {
  910. file_error(ms, errno, "cannot stat `%s'", dbname);
  911. goto error;
  912. }
  913. - if (st.st_size < 8 || st.st_size > MAXMAGIC_SIZE) {
  914. + if (st.sb.st_size < 8 || st.sb.st_size > MAXMAGIC_SIZE) {
  915. file_error(ms, 0, "file `%s' is too %s", dbname,
  916. - st.st_size < 8 ? "small" : "large");
  917. + st.sb.st_size < 8 ? "small" : "large");
  918. goto error;
  919. }
  920. - map->len = (size_t)st.st_size;
  921. -#ifdef QUICK
  922. - map->type = MAP_TYPE_MMAP;
  923. - if ((map->p = mmap(0, (size_t)st.st_size, PROT_READ|PROT_WRITE,
  924. - MAP_PRIVATE|MAP_FILE, fd, (off_t)0)) == MAP_FAILED) {
  925. - file_error(ms, errno, "cannot map `%s'", dbname);
  926. - goto error;
  927. - }
  928. -#else
  929. - map->type = MAP_TYPE_MALLOC;
  930. - if ((map->p = CAST(void *, malloc(map->len))) == NULL) {
  931. + map->len = (size_t)st.sb.st_size;
  932. + if ((map->p = CAST(void *, emalloc(map->len))) == NULL) {
  933. file_oomem(ms, map->len);
  934. goto error;
  935. }
  936. - if (read(fd, map->p, map->len) != (ssize_t)map->len) {
  937. + if (php_stream_read(stream, map->p, (size_t)st.sb.st_size) != (size_t)st.sb.st_size) {
  938. file_badread(ms);
  939. goto error;
  940. }
  941. + map->len = 0;
  942. #define RET 1
  943. -#endif
  944. - (void)close(fd);
  945. - fd = -1;
  946. - if (check_buffer(ms, map, dbname) != 0) {
  947. - rv = (struct magic_map *)-1;
  948. + php_stream_close(stream);
  949. + stream = NULL;
  950. +
  951. +internal_loaded:
  952. + ptr = (uint32_t *)(void *)map->p;
  953. + if (*ptr != MAGICNO) {
  954. + if (swap4(*ptr) != MAGICNO) {
  955. + file_error(ms, 0, "bad magic in `%s'", dbname);
  956. + goto error;
  957. + }
  958. + needsbyteswap = 1;
  959. + } else
  960. + needsbyteswap = 0;
  961. + if (needsbyteswap)
  962. + version = swap4(ptr[1]);
  963. + else
  964. + version = ptr[1];
  965. + if (version != VERSIONNO) {
  966. + file_error(ms, 0, "File %d.%d supports only version %d magic "
  967. + "files. `%s' is version %d", FILE_VERSION_MAJOR, patchlevel,
  968. + VERSIONNO, dbname, version);
  969. goto error;
  970. }
  971. -#ifdef QUICK
  972. - if (mprotect(map->p, (size_t)st.st_size, PROT_READ) == -1) {
  973. - file_error(ms, errno, "cannot mprotect `%s'", dbname);
  974. +
  975. + /* php_magic_database is a const, performing writes will segfault. This is for big-endian
  976. + machines only, PPC and Sparc specifically. Consider static variable or MINIT in
  977. + future. */
  978. + if (needsbyteswap && fn == NULL) {
  979. + map->p = emalloc(sizeof(php_magic_database));
  980. + map->p = memcpy(map->p, php_magic_database, sizeof(php_magic_database));
  981. + }
  982. +
  983. + if (NULL != fn) {
  984. + nentries = (uint32_t)(st.sb.st_size / sizeof(struct magic));
  985. + entries = (uint32_t)(st.sb.st_size / sizeof(struct magic));
  986. + if ((zend_off_t)(entries * sizeof(struct magic)) != st.sb.st_size) {
  987. + file_error(ms, 0, "Size of `%s' %llu is not a multiple of %zu",
  988. + dbname, (unsigned long long)st.sb.st_size,
  989. + sizeof(struct magic));
  990. + goto error;
  991. + }
  992. + }
  993. + map->magic[0] = CAST(struct magic *, map->p) + 1;
  994. + nentries = 0;
  995. + for (i = 0; i < MAGIC_SETS; i++) {
  996. + if (needsbyteswap)
  997. + map->nmagic[i] = swap4(ptr[i + 2]);
  998. + else
  999. + map->nmagic[i] = ptr[i + 2];
  1000. + if (i != MAGIC_SETS - 1)
  1001. + map->magic[i + 1] = map->magic[i] + map->nmagic[i];
  1002. + nentries += map->nmagic[i];
  1003. + }
  1004. + if (NULL != fn && entries != nentries + 1) {
  1005. + file_error(ms, 0, "Inconsistent entries in `%s' %u != %u",
  1006. + dbname, entries, nentries + 1);
  1007. goto error;
  1008. }
  1009. -#endif
  1010. + if (needsbyteswap)
  1011. + for (i = 0; i < MAGIC_SETS; i++)
  1012. + byteswap(map->magic[i], map->nmagic[i]);
  1013. - free(dbname);
  1014. + if (dbname) {
  1015. + efree(dbname);
  1016. + }
  1017. return map;
  1018. error:
  1019. - if (fd != -1)
  1020. - (void)close(fd);
  1021. + if (stream) {
  1022. + php_stream_close(stream);
  1023. + }
  1024. apprentice_unmap(map);
  1025. - free(dbname);
  1026. - return rv;
  1027. + if (dbname) {
  1028. + efree(dbname);
  1029. + }
  1030. + return NULL;
  1031. }
  1032. private int
  1033. @@ -3120,7 +3118,7 @@
  1034. version = ptr[1];
  1035. if (version != VERSIONNO) {
  1036. file_error(ms, 0, "File %s supports only version %d magic "
  1037. - "files. `%s' is version %d", VERSION,
  1038. + "files. `%s' is version %d", FILE_VERSION_MAJOR,
  1039. VERSIONNO, dbname, version);
  1040. return -1;
  1041. }
  1042. @@ -3161,7 +3159,6 @@
  1043. {
  1044. static const size_t nm = sizeof(*map->nmagic) * MAGIC_SETS;
  1045. static const size_t m = sizeof(**map->magic);
  1046. - int fd = -1;
  1047. size_t len;
  1048. char *dbname;
  1049. int rv = -1;
  1050. @@ -3170,14 +3167,17 @@
  1051. struct magic m;
  1052. uint32_t h[2 + MAGIC_SETS];
  1053. } hdr;
  1054. + php_stream *stream;
  1055. dbname = mkdbname(ms, fn, 1);
  1056. - if (dbname == NULL)
  1057. + if (dbname == NULL)
  1058. goto out;
  1059. - if ((fd = open(dbname, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0644)) == -1)
  1060. - {
  1061. + /* wb+ == O_WRONLY|O_CREAT|O_TRUNC|O_BINARY */
  1062. + stream = php_stream_open_wrapper((char *)fn, "wb+", REPORT_ERRORS, NULL);
  1063. +
  1064. + if (!stream) {
  1065. file_error(ms, errno, "cannot open `%s'", dbname);
  1066. goto out;
  1067. }
  1068. @@ -3186,26 +3186,25 @@
  1069. hdr.h[1] = VERSIONNO;
  1070. memcpy(hdr.h + 2, map->nmagic, nm);
  1071. - if (write(fd, &hdr, sizeof(hdr)) != (ssize_t)sizeof(hdr)) {
  1072. + if (php_stream_write(stream,(const char *)&hdr, sizeof(hdr)) != (ssize_t)sizeof(hdr)) {
  1073. file_error(ms, errno, "error writing `%s'", dbname);
  1074. - goto out2;
  1075. + goto out;
  1076. }
  1077. for (i = 0; i < MAGIC_SETS; i++) {
  1078. len = m * map->nmagic[i];
  1079. - if (write(fd, map->magic[i], len) != (ssize_t)len) {
  1080. + if (php_stream_write(stream, (const char *)map->magic[i], len) != (ssize_t)len) {
  1081. file_error(ms, errno, "error writing `%s'", dbname);
  1082. - goto out2;
  1083. + goto out;
  1084. }
  1085. }
  1086. + if (stream) {
  1087. + php_stream_close(stream);
  1088. + }
  1089. rv = 0;
  1090. -out2:
  1091. - if (fd != -1)
  1092. - (void)close(fd);
  1093. out:
  1094. - apprentice_unmap(map);
  1095. - free(dbname);
  1096. + efree(dbname);
  1097. return rv;
  1098. }
  1099. @@ -3239,16 +3238,18 @@
  1100. q++;
  1101. /* Compatibility with old code that looked in .mime */
  1102. if (ms->flags & MAGIC_MIME) {
  1103. - if (asprintf(&buf, "%.*s.mime%s", (int)(q - fn), fn, ext) < 0)
  1104. - return NULL;
  1105. - if (access(buf, R_OK) != -1) {
  1106. + spprintf(&buf, MAXPATHLEN, "%.*s.mime%s", (int)(q - fn), fn, ext);
  1107. +#ifdef PHP_WIN32
  1108. + if (VCWD_ACCESS(buf, R_OK) == 0) {
  1109. +#else
  1110. + if (VCWD_ACCESS(buf, R_OK) != -1) {
  1111. +#endif
  1112. ms->flags &= MAGIC_MIME_TYPE;
  1113. return buf;
  1114. }
  1115. - free(buf);
  1116. + efree(buf);
  1117. }
  1118. - if (asprintf(&buf, "%.*s%s", (int)(q - fn), fn, ext) < 0)
  1119. - return NULL;
  1120. + spprintf(&buf, MAXPATHLEN, "%.*s%s", (int)(q - fn), fn, ext);
  1121. /* Compatibility with old code that looked in .mime */
  1122. if (strstr(fn, ".mime") != NULL)
  1123. @@ -3274,8 +3275,8 @@
  1124. swap2(uint16_t sv)
  1125. {
  1126. uint16_t rv;
  1127. - uint8_t *s = (uint8_t *)(void *)&sv;
  1128. - uint8_t *d = (uint8_t *)(void *)&rv;
  1129. + uint8_t *s = (uint8_t *)(void *)&sv;
  1130. + uint8_t *d = (uint8_t *)(void *)&rv;
  1131. d[0] = s[1];
  1132. d[1] = s[0];
  1133. return rv;
  1134. @@ -3288,8 +3289,8 @@
  1135. swap4(uint32_t sv)
  1136. {
  1137. uint32_t rv;
  1138. - uint8_t *s = (uint8_t *)(void *)&sv;
  1139. - uint8_t *d = (uint8_t *)(void *)&rv;
  1140. + uint8_t *s = (uint8_t *)(void *)&sv;
  1141. + uint8_t *d = (uint8_t *)(void *)&rv;
  1142. d[0] = s[3];
  1143. d[1] = s[2];
  1144. d[2] = s[1];
  1145. @@ -3304,8 +3305,8 @@
  1146. swap8(uint64_t sv)
  1147. {
  1148. uint64_t rv;
  1149. - uint8_t *s = (uint8_t *)(void *)&sv;
  1150. - uint8_t *d = (uint8_t *)(void *)&rv;
  1151. + uint8_t *s = (uint8_t *)(void *)&sv;
  1152. + uint8_t *d = (uint8_t *)(void *)&rv;
  1153. #if 0
  1154. d[0] = s[3];
  1155. d[1] = s[2];
  1156. @@ -3338,7 +3339,7 @@
  1157. m->offset = swap4((int32_t)m->offset);
  1158. m->in_offset = swap4((uint32_t)m->in_offset);
  1159. m->lineno = swap4((uint32_t)m->lineno);
  1160. - if (IS_STRING(m->type)) {
  1161. + if (IS_LIBMAGIC_STRING(m->type)) {
  1162. m->str_range = swap4(m->str_range);
  1163. m->str_flags = swap4(m->str_flags);
  1164. }
  1165. @@ -3348,7 +3349,7 @@
  1166. }
  1167. }
  1168. -protected size_t
  1169. +protected size_t
  1170. file_pstring_length_size(const struct magic *m)
  1171. {
  1172. switch (m->str_flags & PSTRING_LEN) {
  1173. diff -u libmagic.orig/apptype.c libmagic/apptype.c
  1174. --- libmagic.orig/apptype.c 2011-09-07 23:57:15.000000000 +0200
  1175. +++ libmagic/apptype.c 2020-02-26 09:55:13.843047200 +0100
  1176. @@ -1,15 +1,15 @@
  1177. /*
  1178. * Adapted from: apptype.c, Written by Eberhard Mattes and put into the
  1179. * public domain
  1180. - *
  1181. + *
  1182. * Notes: 1. Qualify the filename so that DosQueryAppType does not do extraneous
  1183. * searches.
  1184. - *
  1185. + *
  1186. * 2. DosQueryAppType will return FAPPTYP_DOS on a file ending with ".com"
  1187. * (other than an OS/2 exe or Win exe with this name). Eberhard Mattes
  1188. * remarks Tue, 6 Apr 93: Moreover, it reports the type of the (new and very
  1189. * bug ridden) Win Emacs as "OS/2 executable".
  1190. - *
  1191. + *
  1192. * 3. apptype() uses the filename if given, otherwise a tmp file is created with
  1193. * the contents of buf. If buf is not the complete file, apptype can
  1194. * incorrectly identify the exe type. The "-z" option of "file" is the reason
  1195. @@ -18,10 +18,10 @@
  1196. /*
  1197. * amai: Darrel Hankerson did the changes described here.
  1198. - *
  1199. + *
  1200. * It remains to check the validity of comments (2.) since it's referred to an
  1201. * "old" OS/2 version.
  1202. - *
  1203. + *
  1204. */
  1205. #include "file.h"
  1206. diff -u libmagic.orig/ascmagic.c libmagic/ascmagic.c
  1207. --- libmagic.orig/ascmagic.c 2017-11-02 21:25:39.000000000 +0100
  1208. +++ libmagic/ascmagic.c 2020-02-26 09:55:13.845043300 +0100
  1209. @@ -90,7 +90,7 @@
  1210. rv = file_ascmagic_with_encoding(ms, &bb,
  1211. ubuf, ulen, code, type, text);
  1212. - free(ubuf);
  1213. + efree(ubuf);
  1214. return rv;
  1215. }
  1216. @@ -137,7 +137,7 @@
  1217. /* malloc size is a conservative overestimate; could be
  1218. improved, or at least realloced after conversion. */
  1219. mlen = ulen * 6;
  1220. - if ((utf8_buf = CAST(unsigned char *, malloc(mlen))) == NULL) {
  1221. + if ((utf8_buf = CAST(unsigned char *, emalloc(mlen))) == NULL) {
  1222. file_oomem(ms, mlen);
  1223. goto done;
  1224. }
  1225. @@ -305,7 +305,8 @@
  1226. }
  1227. rv = 1;
  1228. done:
  1229. - free(utf8_buf);
  1230. + if (utf8_buf)
  1231. + efree(utf8_buf);
  1232. return rv;
  1233. }
  1234. diff -u libmagic.orig/buffer.c libmagic/buffer.c
  1235. --- libmagic.orig/buffer.c 2018-03-11 01:46:42.000000000 +0100
  1236. +++ libmagic/buffer.c 2020-02-26 09:55:13.846042600 +0100
  1237. @@ -31,7 +31,11 @@
  1238. #endif /* lint */
  1239. #include "magic.h"
  1240. +#ifdef PHP_WIN32
  1241. +#include "win32/unistd.h"
  1242. +#else
  1243. #include <unistd.h>
  1244. +#endif
  1245. #include <string.h>
  1246. #include <stdlib.h>
  1247. #include <sys/stat.h>
  1248. @@ -40,7 +44,7 @@
  1249. buffer_init(struct buffer *b, int fd, const void *data, size_t len)
  1250. {
  1251. b->fd = fd;
  1252. - if (b->fd == -1 || fstat(b->fd, &b->st) == -1)
  1253. + if (b->fd == -1 || zend_fstat(b->fd, &b->st) == -1)
  1254. memset(&b->st, 0, sizeof(b->st));
  1255. b->fbuf = data;
  1256. b->flen = len;
  1257. @@ -52,7 +56,7 @@
  1258. void
  1259. buffer_fini(struct buffer *b)
  1260. {
  1261. - free(b->ebuf);
  1262. + efree(b->ebuf);
  1263. }
  1264. int
  1265. @@ -68,12 +72,14 @@
  1266. b->elen = (size_t)b->st.st_size < b->flen ?
  1267. (size_t)b->st.st_size : b->flen;
  1268. - if ((b->ebuf = malloc(b->elen)) == NULL)
  1269. + if ((b->ebuf = emalloc(b->elen)) == NULL)
  1270. goto out;
  1271. b->eoff = b->st.st_size - b->elen;
  1272. - if (pread(b->fd, b->ebuf, b->elen, b->eoff) == -1) {
  1273. - free(b->ebuf);
  1274. + if (FINFO_LSEEK_FUNC(b->fd, b->eoff, SEEK_SET) == (zend_off_t)-1 ||
  1275. + FINFO_READ_FUNC(b->fd, b->ebuf, b->elen) != (ssize_t)b->elen)
  1276. + {
  1277. + efree(b->ebuf);
  1278. goto out;
  1279. }
  1280. diff -u libmagic.orig/cdf.c libmagic/cdf.c
  1281. --- libmagic.orig/cdf.c 2018-03-11 01:46:42.000000000 +0100
  1282. +++ libmagic/cdf.c 2020-02-26 09:55:13.847043900 +0100
  1283. @@ -43,7 +43,17 @@
  1284. #include <err.h>
  1285. #endif
  1286. #include <stdlib.h>
  1287. +
  1288. +#ifdef PHP_WIN32
  1289. +#include "win32/unistd.h"
  1290. +#else
  1291. #include <unistd.h>
  1292. +#endif
  1293. +
  1294. +#ifndef UINT32_MAX
  1295. +# define UINT32_MAX (0xffffffff)
  1296. +#endif
  1297. +
  1298. #include <string.h>
  1299. #include <time.h>
  1300. #include <ctype.h>
  1301. @@ -80,37 +90,9 @@
  1302. CDF_TOLE8(CAST(uint64_t, x))))
  1303. #define CDF_GETUINT32(x, y) cdf_getuint32(x, y)
  1304. -#define CDF_MALLOC(n) cdf_malloc(__FILE__, __LINE__, (n))
  1305. -#define CDF_REALLOC(p, n) cdf_realloc(__FILE__, __LINE__, (p), (n))
  1306. -#define CDF_CALLOC(n, u) cdf_calloc(__FILE__, __LINE__, (n), (u))
  1307. -
  1308. -
  1309. -/*ARGSUSED*/
  1310. -static void *
  1311. -cdf_malloc(const char *file __attribute__((__unused__)),
  1312. - size_t line __attribute__((__unused__)), size_t n)
  1313. -{
  1314. - DPRINTF(("%s,%zu: %s %zu\n", file, line, __func__, n));
  1315. - return malloc(n);
  1316. -}
  1317. -
  1318. -/*ARGSUSED*/
  1319. -static void *
  1320. -cdf_realloc(const char *file __attribute__((__unused__)),
  1321. - size_t line __attribute__((__unused__)), void *p, size_t n)
  1322. -{
  1323. - DPRINTF(("%s,%zu: %s %zu\n", file, line, __func__, n));
  1324. - return realloc(p, n);
  1325. -}
  1326. -
  1327. -/*ARGSUSED*/
  1328. -static void *
  1329. -cdf_calloc(const char *file __attribute__((__unused__)),
  1330. - size_t line __attribute__((__unused__)), size_t n, size_t u)
  1331. -{
  1332. - DPRINTF(("%s,%zu: %s %zu %zu\n", file, line, __func__, n, u));
  1333. - return calloc(n, u);
  1334. -}
  1335. +#define CDF_MALLOC(n) emalloc(n)
  1336. +#define CDF_REALLOC(p, n) erealloc(p, n)
  1337. +#define CDF_CALLOC(n, u) ecalloc(n, u)
  1338. /*
  1339. * swap a short
  1340. @@ -303,7 +285,7 @@
  1341. scn->sst_len = 0;
  1342. scn->sst_dirlen = 0;
  1343. scn->sst_ss = 0;
  1344. - free(scn->sst_tab);
  1345. + efree(scn->sst_tab);
  1346. scn->sst_tab = NULL;
  1347. return -1;
  1348. }
  1349. @@ -336,12 +318,13 @@
  1350. }
  1351. static ssize_t
  1352. -cdf_read(const cdf_info_t *info, off_t off, void *buf, size_t len)
  1353. +cdf_read(const cdf_info_t *info, zend_off_t off, void *buf, size_t len)
  1354. {
  1355. size_t siz = (size_t)off + len;
  1356. - if ((off_t)(off + len) != (off_t)siz)
  1357. + if ((zend_off_t)(off + len) != (zend_off_t)siz) {
  1358. goto out;
  1359. + }
  1360. if (info->i_buf != NULL && info->i_len >= siz) {
  1361. (void)memcpy(buf, &info->i_buf[off], len);
  1362. @@ -351,7 +334,10 @@
  1363. if (info->i_fd == -1)
  1364. goto out;
  1365. - if (pread(info->i_fd, buf, len, off) != (ssize_t)len)
  1366. + if (FINFO_LSEEK_FUNC(info->i_fd, off, SEEK_SET) == (zend_off_t)-1)
  1367. + return -1;
  1368. +
  1369. + if (FINFO_READ_FUNC(info->i_fd, buf, len) != (ssize_t)len)
  1370. return -1;
  1371. return (ssize_t)len;
  1372. @@ -366,7 +352,7 @@
  1373. char buf[512];
  1374. (void)memcpy(cdf_bo.s, "\01\02\03\04", 4);
  1375. - if (cdf_read(info, (off_t)0, buf, sizeof(buf)) == -1)
  1376. + if (cdf_read(info, (zend_off_t)0, buf, sizeof(buf)) == -1)
  1377. return -1;
  1378. cdf_unpack_header(h, buf);
  1379. cdf_swap_header(h);
  1380. @@ -400,7 +386,7 @@
  1381. size_t ss = CDF_SEC_SIZE(h);
  1382. size_t pos = CDF_SEC_POS(h, id);
  1383. assert(ss == len);
  1384. - return cdf_read(info, (off_t)pos, ((char *)buf) + offs, len);
  1385. + return cdf_read(info, (zend_off_t)pos, ((char *)buf) + offs, len);
  1386. }
  1387. ssize_t
  1388. @@ -501,14 +487,14 @@
  1389. }
  1390. out:
  1391. sat->sat_len = i;
  1392. - free(msa);
  1393. + efree(msa);
  1394. return 0;
  1395. out3:
  1396. errno = EFTYPE;
  1397. out2:
  1398. - free(msa);
  1399. + efree(msa);
  1400. out1:
  1401. - free(sat->sat_tab);
  1402. + efree(sat->sat_tab);
  1403. return -1;
  1404. }
  1405. @@ -676,7 +662,7 @@
  1406. return -1;
  1407. if ((buf = CAST(char *, CDF_MALLOC(ss))) == NULL) {
  1408. - free(dir->dir_tab);
  1409. + efree(dir->dir_tab);
  1410. return -1;
  1411. }
  1412. @@ -698,11 +684,11 @@
  1413. if (NEED_SWAP)
  1414. for (i = 0; i < dir->dir_len; i++)
  1415. cdf_swap_dir(&dir->dir_tab[i]);
  1416. - free(buf);
  1417. + efree(buf);
  1418. return 0;
  1419. out:
  1420. - free(dir->dir_tab);
  1421. - free(buf);
  1422. + efree(dir->dir_tab);
  1423. + efree(buf);
  1424. errno = EFTYPE;
  1425. return -1;
  1426. }
  1427. @@ -747,7 +733,7 @@
  1428. out:
  1429. errno = EFTYPE;
  1430. out1:
  1431. - free(ssat->sat_tab);
  1432. + efree(ssat->sat_tab);
  1433. return -1;
  1434. }
  1435. @@ -859,7 +845,7 @@
  1436. }
  1437. static const uint8_t *
  1438. -cdf_get_property_info_pos(const cdf_stream_t *sst, const cdf_header_t *h,
  1439. +cdf_get_property_info_pos(const cdf_stream_t *sst, const cdf_header_t *h,
  1440. const uint8_t *p, const uint8_t *e, size_t i)
  1441. {
  1442. size_t tail = (i << 1) + 1;
  1443. @@ -874,7 +860,7 @@
  1444. __LINE__) == -1)
  1445. return NULL;
  1446. ofs = CDF_GETUINT32(p, tail);
  1447. - q = CAST(const uint8_t *, cdf_offset(CAST(const void *, p),
  1448. + q = CAST(const uint8_t *, cdf_offset(CAST(const void *, p),
  1449. ofs - 2 * sizeof(uint32_t)));
  1450. if (q < p) {
  1451. @@ -896,7 +882,7 @@
  1452. size_t newcount = *maxcount + incr;
  1453. if (newcount > CDF_PROP_LIMIT) {
  1454. - DPRINTF(("exceeded property limit %zu > %zu\n",
  1455. + DPRINTF(("exceeded property limit %zu > %zu\n",
  1456. newcount, CDF_PROP_LIMIT));
  1457. goto out;
  1458. }
  1459. @@ -909,7 +895,7 @@
  1460. *maxcount = newcount;
  1461. return inp;
  1462. out:
  1463. - free(*info);
  1464. + efree(*info);
  1465. *maxcount = 0;
  1466. *info = NULL;
  1467. return NULL;
  1468. @@ -1003,8 +989,9 @@
  1469. goto out;
  1470. }
  1471. nelements = CDF_GETUINT32(q, 1);
  1472. - if (nelements == 0) {
  1473. - DPRINTF(("CDF_VECTOR with nelements == 0\n"));
  1474. + if (nelements > CDF_ELEMENT_LIMIT || nelements == 0) {
  1475. + DPRINTF(("CDF_VECTOR with nelements == %"
  1476. + SIZE_T_FORMAT "u\n", nelements));
  1477. goto out;
  1478. }
  1479. slen = 2;
  1480. @@ -1046,8 +1033,6 @@
  1481. goto out;
  1482. inp += nelem;
  1483. }
  1484. - DPRINTF(("nelements = %" SIZE_T_FORMAT "u\n",
  1485. - nelements));
  1486. for (j = 0; j < nelements && i < sh.sh_properties;
  1487. j++, i++)
  1488. {
  1489. @@ -1092,7 +1077,7 @@
  1490. }
  1491. return 0;
  1492. out:
  1493. - free(*info);
  1494. + efree(*info);
  1495. *info = NULL;
  1496. *count = 0;
  1497. *maxcount = 0;
  1498. @@ -1383,7 +1368,7 @@
  1499. cdf_directory_t *d;
  1500. char name[__arraycount(d->d_name)];
  1501. cdf_stream_t scn;
  1502. - struct timespec ts;
  1503. + struct timeval ts;
  1504. static const char *types[] = { "empty", "user storage",
  1505. "user stream", "lockbytes", "property", "root storage" };
  1506. @@ -1425,7 +1410,7 @@
  1507. break;
  1508. }
  1509. cdf_dump_stream(&scn);
  1510. - free(scn.sst_tab);
  1511. + efree(scn.sst_tab);
  1512. break;
  1513. default:
  1514. break;
  1515. @@ -1438,7 +1423,7 @@
  1516. cdf_dump_property_info(const cdf_property_info_t *info, size_t count)
  1517. {
  1518. cdf_timestamp_t tp;
  1519. - struct timespec ts;
  1520. + struct timeval ts;
  1521. char buf[64];
  1522. size_t i, j;
  1523. @@ -1523,7 +1508,7 @@
  1524. (void)fprintf(stderr, "Class %s\n", buf);
  1525. (void)fprintf(stderr, "Count %d\n", ssi.si_count);
  1526. cdf_dump_property_info(info, count);
  1527. - free(info);
  1528. + efree(info);
  1529. }
  1530. @@ -1544,7 +1529,7 @@
  1531. cdf_u16tos8(sbuf, ce[i].ce_namlen, ce[i].ce_name),
  1532. cdf_ctime(&ts.tv_sec, tbuf));
  1533. }
  1534. - free(cat);
  1535. + efree(cat);
  1536. }
  1537. #endif
  1538. diff -u libmagic.orig/cdf.h libmagic/cdf.h
  1539. --- libmagic.orig/cdf.h 2017-03-09 17:57:17.000000000 +0100
  1540. +++ libmagic/cdf.h 2020-02-26 09:55:13.848043100 +0100
  1541. @@ -35,10 +35,10 @@
  1542. #ifndef _H_CDF_
  1543. #define _H_CDF_
  1544. -#ifdef WIN32
  1545. +#ifdef PHP_WIN32
  1546. #include <winsock2.h>
  1547. -#define timespec timeval
  1548. -#define tv_nsec tv_usec
  1549. +#define asctime_r php_asctime_r
  1550. +#define ctime_r php_ctime_r
  1551. #endif
  1552. #ifdef __DJGPP__
  1553. #define timespec timeval
  1554. @@ -48,6 +48,7 @@
  1555. typedef int32_t cdf_secid_t;
  1556. #define CDF_LOOP_LIMIT 10000
  1557. +#define CDF_ELEMENT_LIMIT 100000
  1558. #define CDF_SECID_NULL 0
  1559. #define CDF_SECID_FREE -1
  1560. @@ -272,7 +273,7 @@
  1561. typedef struct {
  1562. uint16_t ce_namlen;
  1563. uint32_t ce_num;
  1564. - uint64_t ce_timestamp;
  1565. + uint64_t ce_timestamp;
  1566. uint16_t ce_name[256];
  1567. } cdf_catalog_entry_t;
  1568. diff -u libmagic.orig/cdf_time.c libmagic/cdf_time.c
  1569. --- libmagic.orig/cdf_time.c 2017-03-29 17:57:48.000000000 +0200
  1570. +++ libmagic/cdf_time.c 2020-02-26 09:55:13.849044200 +0100
  1571. @@ -23,6 +23,7 @@
  1572. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  1573. * POSSIBILITY OF SUCH DAMAGE.
  1574. */
  1575. +#include "php.h"
  1576. #include "file.h"
  1577. @@ -56,7 +57,7 @@
  1578. for (y = CDF_BASE_YEAR; y < year; y++)
  1579. days += isleap(y) + 365;
  1580. -
  1581. +
  1582. return days;
  1583. }
  1584. @@ -77,7 +78,7 @@
  1585. return days;
  1586. }
  1587. -/*
  1588. +/*
  1589. * Return the 0...11 month number.
  1590. */
  1591. static int
  1592. @@ -152,7 +153,7 @@
  1593. #endif
  1594. #ifdef notyet
  1595. struct tm tm;
  1596. - if (gmtime_r(&ts->ts_sec, &tm) == NULL) {
  1597. + if (php_gmtime_r(&ts->ts_sec, &tm) == NULL) {
  1598. errno = EINVAL;
  1599. return -1;
  1600. }
  1601. @@ -168,7 +169,7 @@
  1602. char *
  1603. cdf_ctime(const time_t *sec, char *buf)
  1604. {
  1605. - char *ptr = ctime_r(sec, buf);
  1606. + char *ptr = php_ctime_r(sec, buf);
  1607. if (ptr != NULL)
  1608. return buf;
  1609. (void)snprintf(buf, 26, "*Bad* %#16.16" INT64_T_FORMAT "x\n",
  1610. diff -u libmagic.orig/compress.c libmagic/compress.c
  1611. --- libmagic.orig/compress.c 2017-11-02 21:25:39.000000000 +0100
  1612. +++ libmagic/compress.c 2020-02-26 09:55:13.850043300 +0100
  1613. @@ -2,7 +2,7 @@
  1614. * Copyright (c) Ian F. Darwin 1986-1995.
  1615. * Software written by Ian F. Darwin and others;
  1616. * maintained 1995-present by Christos Zoulas and others.
  1617. - *
  1618. + *
  1619. * Redistribution and use in source and binary forms, with or without
  1620. * modification, are permitted provided that the following conditions
  1621. * are met:
  1622. @@ -12,7 +12,7 @@
  1623. * 2. Redistributions in binary form must reproduce the above copyright
  1624. * notice, this list of conditions and the following disclaimer in the
  1625. * documentation and/or other materials provided with the distribution.
  1626. - *
  1627. + *
  1628. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  1629. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  1630. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  1631. @@ -29,13 +29,13 @@
  1632. * compress routines:
  1633. * zmagic() - returns 0 if not recognized, uncompresses and prints
  1634. * information if recognized
  1635. - * uncompress(method, old, n, newch) - uncompress old into new,
  1636. + * uncompress(method, old, n, newch) - uncompress old into new,
  1637. * using method, return sizeof new
  1638. */
  1639. #include "file.h"
  1640. #ifndef lint
  1641. -FILE_RCSID("@(#)$File: compress.c,v 1.106 2017/11/02 20:25:39 christos Exp $")
  1642. +FILE_RCSID("@(#)$File: compress.c,v 1.104 2017/03/29 15:57:48 christos Exp $")
  1643. #endif
  1644. #include "magic.h"
  1645. @@ -45,15 +45,13 @@
  1646. #endif
  1647. #include <string.h>
  1648. #include <errno.h>
  1649. -#include <ctype.h>
  1650. -#include <stdarg.h>
  1651. #ifdef HAVE_SIGNAL_H
  1652. #include <signal.h>
  1653. # ifndef HAVE_SIG_T
  1654. typedef void (*sig_t)(int);
  1655. # endif /* HAVE_SIG_T */
  1656. -#endif
  1657. -#if !defined(__MINGW32__) && !defined(WIN32)
  1658. +#endif
  1659. +#ifndef PHP_WIN32
  1660. #include <sys/ioctl.h>
  1661. #endif
  1662. #ifdef HAVE_SYS_WAIT_H
  1663. @@ -62,51 +60,12 @@
  1664. #if defined(HAVE_SYS_TIME_H)
  1665. #include <sys/time.h>
  1666. #endif
  1667. -#if defined(HAVE_ZLIB_H) && defined(ZLIBSUPPORT)
  1668. +#if defined(HAVE_ZLIB_H) && defined(PHP_FILEINFO_UNCOMPRESS)
  1669. #define BUILTIN_DECOMPRESS
  1670. #include <zlib.h>
  1671. #endif
  1672. -#ifdef DEBUG
  1673. -int tty = -1;
  1674. -#define DPRINTF(...) do { \
  1675. - if (tty == -1) \
  1676. - tty = open("/dev/tty", O_RDWR); \
  1677. - if (tty == -1) \
  1678. - abort(); \
  1679. - dprintf(tty, __VA_ARGS__); \
  1680. -} while (/*CONSTCOND*/0)
  1681. -#else
  1682. -#define DPRINTF(...)
  1683. -#endif
  1684. -
  1685. -#ifdef ZLIBSUPPORT
  1686. -/*
  1687. - * The following python code is not really used because ZLIBSUPPORT is only
  1688. - * defined if we have a built-in zlib, and the built-in zlib handles that.
  1689. - * That is not true for android where we have zlib.h and not -lz.
  1690. - */
  1691. -static const char zlibcode[] =
  1692. - "import sys, zlib; sys.stdout.write(zlib.decompress(sys.stdin.read()))";
  1693. -
  1694. -static const char *zlib_args[] = { "python", "-c", zlibcode, NULL };
  1695. -static int
  1696. -zlibcmp(const unsigned char *buf)
  1697. -{
  1698. - unsigned short x = 1;
  1699. - unsigned char *s = CAST(unsigned char *, CAST(void *, &x));
  1700. -
  1701. - if ((buf[0] & 0xf) != 8 || (buf[0] & 0x80) != 0)
  1702. - return 0;
  1703. - if (s[0] != 1) /* endianness test */
  1704. - x = buf[0] | (buf[1] << 8);
  1705. - else
  1706. - x = buf[1] | (buf[0] << 8);
  1707. - if (x % 31)
  1708. - return 0;
  1709. - return 1;
  1710. -}
  1711. -#endif
  1712. +#undef FIONREAD
  1713. #define gzip_flags "-cd"
  1714. #define lrzip_flags "-do"
  1715. @@ -169,7 +128,7 @@
  1716. #define ERRDATA 2
  1717. private ssize_t swrite(int, const void *, size_t);
  1718. -#if HAVE_FORK
  1719. +#ifdef PHP_FILEINFO_UNCOMPRESS
  1720. private size_t ncompr = sizeof(compr) / sizeof(compr[0]);
  1721. private int uncompressbuf(int, size_t, size_t, const unsigned char *,
  1722. unsigned char **, size_t *);
  1723. @@ -179,12 +138,12 @@
  1724. private int uncompressgzipped(const unsigned char *, unsigned char **, size_t,
  1725. size_t *);
  1726. #endif
  1727. -static int makeerror(unsigned char **, size_t *, const char *, ...)
  1728. - __attribute__((__format__(__printf__, 3, 4)));
  1729. +static int makeerror(unsigned char **, size_t *, const char *, ...);
  1730. private const char *methodname(size_t);
  1731. protected int
  1732. -file_zmagic(struct magic_set *ms, const struct buffer *b, const char *name)
  1733. +file_zmagic(struct magic_set *ms, int fd, const char *name,
  1734. + const unsigned char *buf, size_t nbytes)
  1735. {
  1736. unsigned char *newbuf = NULL;
  1737. size_t i, nsz;
  1738. @@ -192,9 +151,6 @@
  1739. file_pushbuf_t *pb;
  1740. int urv, prv, rv = 0;
  1741. int mime = ms->flags & MAGIC_MIME;
  1742. - int fd = b->fd;
  1743. - const unsigned char *buf = b->fbuf;
  1744. - size_t nbytes = b->flen;
  1745. #ifdef HAVE_SIGNAL_H
  1746. sig_t osigpipe;
  1747. #endif
  1748. @@ -226,7 +182,7 @@
  1749. switch (urv) {
  1750. case OKDATA:
  1751. case ERRDATA:
  1752. -
  1753. +
  1754. ms->flags &= ~MAGIC_COMPRESS;
  1755. if (urv == ERRDATA)
  1756. prv = file_printf(ms, "%s ERROR: %s",
  1757. @@ -253,10 +209,10 @@
  1758. goto error;
  1759. if ((rbuf = file_pop_buffer(ms, pb)) != NULL) {
  1760. if (file_printf(ms, "%s", rbuf) == -1) {
  1761. - free(rbuf);
  1762. + efree(rbuf);
  1763. goto error;
  1764. }
  1765. - free(rbuf);
  1766. + efree(rbuf);
  1767. }
  1768. if (!mime && file_printf(ms, ")") == -1)
  1769. goto error;
  1770. @@ -277,7 +233,8 @@
  1771. #ifdef HAVE_SIGNAL_H
  1772. (void)signal(SIGPIPE, osigpipe);
  1773. #endif
  1774. - free(newbuf);
  1775. + if (newbuf)
  1776. + efree(newbuf);
  1777. ms->flags |= MAGIC_COMPRESS;
  1778. DPRINTF("Zmagic returns %d\n", rv);
  1779. return rv;
  1780. @@ -312,7 +269,7 @@
  1781. * `safe' read for sockets and pipes.
  1782. */
  1783. protected ssize_t
  1784. -sread(int fd, void *buf, size_t n, int canbepipe __attribute__((__unused__)))
  1785. +sread(int fd, void *buf, size_t n, int canbepipe)
  1786. {
  1787. ssize_t rv;
  1788. #ifdef FIONREAD
  1789. @@ -360,7 +317,7 @@
  1790. nocheck:
  1791. do
  1792. - switch ((rv = read(fd, buf, n))) {
  1793. + switch ((rv = FINFO_READ_FUNC(fd, buf, n))) {
  1794. case -1:
  1795. if (errno == EINTR)
  1796. continue;
  1797. @@ -437,13 +394,14 @@
  1798. return -1;
  1799. }
  1800. (void)close(tfd);
  1801. - if (lseek(fd, (off_t)0, SEEK_SET) == (off_t)-1) {
  1802. + if (FINFO_LSEEK_FUNC(fd, (zend_off_t)0, SEEK_SET) == (zend_off_t)-1) {
  1803. file_badseek(ms);
  1804. return -1;
  1805. }
  1806. return fd;
  1807. }
  1808. -#if HAVE_FORK
  1809. +
  1810. +#ifdef PHP_FILEINFO_UNCOMPRESS
  1811. #ifdef BUILTIN_DECOMPRESS
  1812. #define FHCRC (1 << 1)
  1813. @@ -494,7 +452,7 @@
  1814. int rc;
  1815. z_stream z;
  1816. - if ((*newch = CAST(unsigned char *, malloc(bytes_max + 1))) == NULL)
  1817. + if ((*newch = CAST(unsigned char *, emalloc(bytes_max + 1))) == NULL)
  1818. return makeerror(newch, n, "No buffer, %s", strerror(errno));
  1819. z.next_in = CCAST(Bytef *, old);
  1820. @@ -518,7 +476,7 @@
  1821. rc = inflateEnd(&z);
  1822. if (rc != Z_OK)
  1823. goto err;
  1824. -
  1825. +
  1826. /* let's keep the nul-terminate tradition */
  1827. (*newch)[*n] = '\0';
  1828. @@ -586,7 +544,7 @@
  1829. int status;
  1830. closefd(fdp[STDIN_FILENO], 0);
  1831. - /*
  1832. + /*
  1833. * fork again, to avoid blocking because both
  1834. * pipes filled
  1835. */
  1836. @@ -689,13 +647,13 @@
  1837. fdp[STDIN_FILENO][0] = fd;
  1838. (void) lseek(fd, (off_t)0, SEEK_SET);
  1839. }
  1840. -
  1841. +
  1842. for (i = 0; i < __arraycount(fdp); i++)
  1843. copydesc(CAST(int, i), fdp[i]);
  1844. (void)execvp(compr[method].argv[0],
  1845. (char *const *)(intptr_t)compr[method].argv);
  1846. - dprintf(STDERR_FILENO, "exec `%s' failed, %s",
  1847. + dprintf(STDERR_FILENO, "exec `%s' failed, %s",
  1848. compr[method].argv[0], strerror(errno));
  1849. exit(1);
  1850. /*NOTREACHED*/
  1851. @@ -711,7 +669,7 @@
  1852. if (fd == -1)
  1853. writechild(fdp, old, *n);
  1854. - *newch = CAST(unsigned char *, malloc(bytes_max + 1));
  1855. + *newch = CAST(unsigned char *, emalloc(bytes_max + 1));
  1856. if (*newch == NULL) {
  1857. rv = makeerror(newch, n, "No buffer, %s",
  1858. strerror(errno));
  1859. @@ -730,7 +688,7 @@
  1860. r = filter_error(*newch, r);
  1861. break;
  1862. }
  1863. - free(*newch);
  1864. + efree(*newch);
  1865. if (r == 0)
  1866. rv = makeerror(newch, n, "Read failed, %s",
  1867. strerror(errno));
  1868. @@ -738,27 +696,5 @@
  1869. rv = makeerror(newch, n, "No data");
  1870. goto err;
  1871. }
  1872. -
  1873. - *n = r;
  1874. - /* NUL terminate, as every buffer is handled here. */
  1875. - (*newch)[*n] = '\0';
  1876. -err:
  1877. - closefd(fdp[STDIN_FILENO], 1);
  1878. - closefd(fdp[STDOUT_FILENO], 0);
  1879. - closefd(fdp[STDERR_FILENO], 0);
  1880. - if (wait(&status) == -1) {
  1881. - free(*newch);
  1882. - rv = makeerror(newch, n, "Wait failed, %s", strerror(errno));
  1883. - DPRINTF("Child wait return %#x\n", status);
  1884. - } else if (!WIFEXITED(status)) {
  1885. - DPRINTF("Child not exited (%#x)\n", status);
  1886. - } else if (WEXITSTATUS(status) != 0) {
  1887. - DPRINTF("Child exited (%#x)\n", WEXITSTATUS(status));
  1888. - }
  1889. -
  1890. - closefd(fdp[STDIN_FILENO], 0);
  1891. - DPRINTF("Returning %p n=%zu rv=%d\n", *newch, *n, rv);
  1892. -
  1893. - return rv;
  1894. }
  1895. -#endif
  1896. +#endif /* if PHP_FILEINFO_UNCOMPRESS */
  1897. diff -u libmagic.orig/der.c libmagic/der.c
  1898. --- libmagic.orig/der.c 2017-02-10 19:14:01.000000000 +0100
  1899. +++ libmagic/der.c 2020-02-26 09:55:13.851044000 +0100
  1900. @@ -51,7 +51,9 @@
  1901. #include "magic.h"
  1902. #include "der.h"
  1903. #else
  1904. +#ifndef PHP_WIN32
  1905. #include <sys/mman.h>
  1906. +#endif
  1907. #include <sys/stat.h>
  1908. #include <err.h>
  1909. #endif
  1910. @@ -207,7 +209,7 @@
  1911. static const char *
  1912. der_tag(char *buf, size_t len, uint32_t tag)
  1913. {
  1914. - if (tag < DER_TAG_LONG)
  1915. + if (tag < DER_TAG_LONG)
  1916. strlcpy(buf, der__tag[tag], len);
  1917. else
  1918. snprintf(buf, len, "%#x", tag);
  1919. @@ -218,6 +220,7 @@
  1920. static int
  1921. der_data(char *buf, size_t blen, uint32_t tag, const void *q, uint32_t len)
  1922. {
  1923. + uint32_t i = 0;
  1924. const uint8_t *d = CAST(const uint8_t *, q);
  1925. switch (tag) {
  1926. case DER_TAG_PRINTABLE_STRING:
  1927. @@ -229,7 +232,7 @@
  1928. break;
  1929. }
  1930. - for (uint32_t i = 0; i < len; i++) {
  1931. + for (; i < len; i++) {
  1932. uint32_t z = i << 1;
  1933. if (z < blen - 2)
  1934. snprintf(buf + z, blen - z, "%.2x", d[i]);
  1935. @@ -343,7 +346,7 @@
  1936. default:
  1937. break;
  1938. }
  1939. -
  1940. +
  1941. for (uint32_t i = 0; i < len; i++)
  1942. printf("%.2x", d[i]);
  1943. printf("\n");
  1944. @@ -367,7 +370,7 @@
  1945. if (p + x >= ep)
  1946. break;
  1947. uint32_t len = getlength(p, &x, ep - p + x);
  1948. -
  1949. +
  1950. printf("%zu %zu-%zu %c,%c,%s,%u:", level, ox, x,
  1951. der_class[c], der_type[t],
  1952. der_tag(buf, sizeof(buf), tag), len);
  1953. diff -u libmagic.orig/elfclass.h libmagic/elfclass.h
  1954. --- libmagic.orig/elfclass.h 2014-12-17 00:18:40.000000000 +0100
  1955. +++ libmagic/elfclass.h 2020-02-26 09:55:13.852043400 +0100
  1956. @@ -1,7 +1,7 @@
  1957. /*
  1958. * Copyright (c) Christos Zoulas 2008.
  1959. * All Rights Reserved.
  1960. - *
  1961. + *
  1962. * Redistribution and use in source and binary forms, with or without
  1963. * modification, are permitted provided that the following conditions
  1964. * are met:
  1965. @@ -11,7 +11,7 @@
  1966. * 2. Redistributions in binary form must reproduce the above copyright
  1967. * notice, this list of conditions and the following disclaimer in the
  1968. * documentation and/or other materials provided with the distribution.
  1969. - *
  1970. + *
  1971. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  1972. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  1973. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  1974. @@ -41,7 +41,7 @@
  1975. return toomany(ms, "program headers", phnum);
  1976. flags |= FLAGS_IS_CORE;
  1977. if (dophn_core(ms, clazz, swap, fd,
  1978. - (off_t)elf_getu(swap, elfhdr.e_phoff), phnum,
  1979. + (zend_off_t)elf_getu(swap, elfhdr.e_phoff), phnum,
  1980. (size_t)elf_getu16(swap, elfhdr.e_phentsize),
  1981. fsize, &flags, &notecount) == -1)
  1982. return -1;
  1983. @@ -56,7 +56,7 @@
  1984. if (shnum > ms->elf_shnum_max)
  1985. return toomany(ms, "section", shnum);
  1986. if (dophn_exec(ms, clazz, swap, fd,
  1987. - (off_t)elf_getu(swap, elfhdr.e_phoff), phnum,
  1988. + (zend_off_t)elf_getu(swap, elfhdr.e_phoff), phnum,
  1989. (size_t)elf_getu16(swap, elfhdr.e_phentsize),
  1990. fsize, shnum, &flags, &notecount) == -1)
  1991. return -1;
  1992. @@ -66,7 +66,7 @@
  1993. if (shnum > ms->elf_shnum_max)
  1994. return toomany(ms, "section headers", shnum);
  1995. if (doshn(ms, clazz, swap, fd,
  1996. - (off_t)elf_getu(swap, elfhdr.e_shoff), shnum,
  1997. + (zend_off_t)elf_getu(swap, elfhdr.e_shoff), shnum,
  1998. (size_t)elf_getu16(swap, elfhdr.e_shentsize),
  1999. fsize, elf_getu16(swap, elfhdr.e_machine),
  2000. (int)elf_getu16(swap, elfhdr.e_shstrndx),
  2001. diff -u libmagic.orig/encoding.c libmagic/encoding.c
  2002. --- libmagic.orig/encoding.c 2017-11-02 21:25:39.000000000 +0100
  2003. +++ libmagic/encoding.c 2020-02-26 09:55:13.854045100 +0100
  2004. @@ -88,12 +88,12 @@
  2005. *code_mime = "binary";
  2006. mlen = (nbytes + 1) * sizeof((*ubuf)[0]);
  2007. - if ((*ubuf = CAST(unichar *, calloc((size_t)1, mlen))) == NULL) {
  2008. + if ((*ubuf = CAST(unichar *, ecalloc((size_t)1, mlen))) == NULL) {
  2009. file_oomem(ms, mlen);
  2010. goto done;
  2011. }
  2012. mlen = (nbytes + 1) * sizeof(nbuf[0]);
  2013. - if ((nbuf = CAST(unsigned char *, calloc((size_t)1, mlen))) == NULL) {
  2014. + if ((nbuf = CAST(unsigned char *, ecalloc((size_t)1, mlen))) == NULL) {
  2015. file_oomem(ms, mlen);
  2016. goto done;
  2017. }
  2018. @@ -153,9 +153,9 @@
  2019. }
  2020. done:
  2021. - free(nbuf);
  2022. + efree(nbuf);
  2023. if (ubuf == &udefbuf)
  2024. - free(udefbuf);
  2025. + efree(udefbuf);
  2026. return rv;
  2027. }
  2028. diff -u libmagic.orig/file.h libmagic/file.h
  2029. --- libmagic.orig/file.h 2018-03-11 01:46:42.000000000 +0100
  2030. +++ libmagic/file.h 2020-02-26 09:55:13.856043400 +0100
  2031. @@ -27,21 +27,15 @@
  2032. */
  2033. /*
  2034. * file.h - definitions for file(1) program
  2035. - * @(#)$File: file.h,v 1.191 2018/02/21 21:26:00 christos Exp $
  2036. + * @(#)$File: file.h,v 1.182 2017/04/07 19:46:44 christos Exp $
  2037. */
  2038. #ifndef __file_h__
  2039. #define __file_h__
  2040. -#ifdef HAVE_CONFIG_H
  2041. -#include <config.h>
  2042. -#endif
  2043. -#ifdef HAVE_STDINT_H
  2044. -#ifndef __STDC_LIMIT_MACROS
  2045. -#define __STDC_LIMIT_MACROS
  2046. -#endif
  2047. +#include "config.h"
  2048. -#ifdef WIN32
  2049. +#ifdef PHP_WIN32
  2050. #ifdef _WIN64
  2051. #define SIZE_T_FORMAT "I64"
  2052. #else
  2053. @@ -54,19 +48,31 @@
  2054. #define INT64_T_FORMAT "ll"
  2055. #define INTMAX_T_FORMAT "j"
  2056. #endif
  2057. -#include <stdint.h>
  2058. -#endif
  2059. #include <stdio.h> /* Include that here, to make sure __P gets defined */
  2060. #include <errno.h>
  2061. #include <fcntl.h> /* For open and flags */
  2062. +#ifdef HAVE_STDINT_H
  2063. +#ifndef __STDC_LIMIT_MACROS
  2064. +#define __STDC_LIMIT_MACROS
  2065. +#endif
  2066. +#include <stdint.h>
  2067. +#endif
  2068. #ifdef HAVE_INTTYPES_H
  2069. #include <inttypes.h>
  2070. #endif
  2071. -#include <regex.h>
  2072. -#include <time.h>
  2073. +#ifdef PHP_WIN32
  2074. +#include "win32/php_stdint.h"
  2075. +#endif
  2076. +
  2077. +#include "php.h"
  2078. +#include "ext/standard/php_string.h"
  2079. +#include "ext/pcre/php_pcre.h"
  2080. +
  2081. #include <sys/types.h>
  2082. -#ifndef WIN32
  2083. +#ifdef PHP_WIN32
  2084. +#include "win32/param.h"
  2085. +#else
  2086. #include <sys/param.h>
  2087. #endif
  2088. /* Do this here and now, because struct stat gets re-defined on solaris */
  2089. @@ -79,7 +85,7 @@
  2090. #define MAGIC "/etc/magic"
  2091. #endif
  2092. -#if defined(__EMX__) || defined (WIN32)
  2093. +#if defined(__EMX__) || defined(PHP_WIN32)
  2094. #define PATHSEP ';'
  2095. #else
  2096. #define PATHSEP ':'
  2097. @@ -113,12 +119,6 @@
  2098. #endif
  2099. #endif
  2100. -#ifndef __GNUC__
  2101. -#ifndef __attribute__
  2102. -#define __attribute__(a)
  2103. -#endif
  2104. -#endif
  2105. -
  2106. #ifndef MIN
  2107. #define MIN(a,b) (((a) < (b)) ? (a) : (b))
  2108. #endif
  2109. @@ -147,10 +147,10 @@
  2110. struct buffer {
  2111. int fd;
  2112. - struct stat st;
  2113. + zend_stat_t st;
  2114. const void *fbuf;
  2115. size_t flen;
  2116. - off_t eoff;
  2117. + zend_off_t eoff;
  2118. void *ebuf;
  2119. size_t elen;
  2120. };
  2121. @@ -240,7 +240,7 @@
  2122. #define FILE_DER 48
  2123. #define FILE_NAMES_SIZE 49 /* size of array to contain all names */
  2124. -#define IS_STRING(t) \
  2125. +#define IS_LIBMAGIC_STRING(t) \
  2126. ((t) == FILE_STRING || \
  2127. (t) == FILE_PSTRING || \
  2128. (t) == FILE_BESTRING16 || \
  2129. @@ -443,26 +443,22 @@
  2130. /* Type for Unicode characters */
  2131. typedef unsigned long unichar;
  2132. -struct stat;
  2133. #define FILE_T_LOCAL 1
  2134. #define FILE_T_WINDOWS 2
  2135. protected const char *file_fmttime(uint64_t, int, char *);
  2136. protected struct magic_set *file_ms_alloc(int);
  2137. protected void file_ms_free(struct magic_set *);
  2138. -protected int file_buffer(struct magic_set *, int, const char *, const void *,
  2139. +protected int file_buffer(struct magic_set *, php_stream *, const char *, const void *,
  2140. size_t);
  2141. -protected int file_fsmagic(struct magic_set *, const char *, struct stat *);
  2142. +protected int file_fsmagic(struct magic_set *, const char *, zend_stat_t *, php_stream *);
  2143. protected int file_pipe2file(struct magic_set *, int, const void *, size_t);
  2144. -protected int file_vprintf(struct magic_set *, const char *, va_list)
  2145. - __attribute__((__format__(__printf__, 2, 0)));
  2146. protected size_t file_printedlen(const struct magic_set *);
  2147. protected int file_replace(struct magic_set *, const char *, const char *);
  2148. -protected int file_printf(struct magic_set *, const char *, ...)
  2149. - __attribute__((__format__(__printf__, 2, 3)));
  2150. +protected int file_printf(struct magic_set *, const char *, ...);
  2151. protected int file_reset(struct magic_set *, int);
  2152. protected int file_tryelf(struct magic_set *, const struct buffer *);
  2153. protected int file_trycdf(struct magic_set *, const struct buffer *);
  2154. -#if HAVE_FORK
  2155. +#ifdef PHP_FILEINFO_UNCOMPRESS
  2156. protected int file_zmagic(struct magic_set *, const struct buffer *,
  2157. const char *);
  2158. #endif
  2159. @@ -484,13 +480,9 @@
  2160. protected void file_badread(struct magic_set *);
  2161. protected void file_badseek(struct magic_set *);
  2162. protected void file_oomem(struct magic_set *, size_t);
  2163. -protected void file_error(struct magic_set *, int, const char *, ...)
  2164. - __attribute__((__format__(__printf__, 3, 4)));
  2165. -protected void file_magerror(struct magic_set *, const char *, ...)
  2166. - __attribute__((__format__(__printf__, 2, 3)));
  2167. -protected void file_magwarn(struct magic_set *, const char *, ...)
  2168. - __attribute__((__format__(__printf__, 2, 3)));
  2169. -protected void file_mdump(struct magic *);
  2170. +protected void file_error(struct magic_set *, int, const char *, ...);
  2171. +protected void file_magerror(struct magic_set *, const char *, ...);
  2172. +protected void file_magwarn(struct magic_set *, const char *, ...);
  2173. protected void file_showstr(FILE *, const char *, size_t);
  2174. protected size_t file_mbswidth(const char *);
  2175. protected const char *file_getbuffer(struct magic_set *);
  2176. @@ -510,31 +502,8 @@
  2177. protected void buffer_fini(struct buffer *);
  2178. protected int buffer_fill(const struct buffer *);
  2179. -#if defined(HAVE_LOCALE_H)
  2180. -#include <locale.h>
  2181. -#endif
  2182. -#if defined(HAVE_XLOCALE_H)
  2183. -#include <xlocale.h>
  2184. -#endif
  2185. -
  2186. -typedef struct {
  2187. - const char *pat;
  2188. -#if defined(HAVE_NEWLOCALE) && defined(HAVE_USELOCALE) && defined(HAVE_FREELOCALE)
  2189. -#define USE_C_LOCALE
  2190. - locale_t old_lc_ctype;
  2191. - locale_t c_lc_ctype;
  2192. -#else
  2193. - char *old_lc_ctype;
  2194. -#endif
  2195. - int rc;
  2196. - regex_t rx;
  2197. -} file_regex_t;
  2198. -
  2199. -protected int file_regcomp(file_regex_t *, const char *, int);
  2200. -protected int file_regexec(file_regex_t *, const char *, size_t, regmatch_t *,
  2201. - int);
  2202. -protected void file_regfree(file_regex_t *);
  2203. -protected void file_regerror(file_regex_t *, int, struct magic_set *);
  2204. +public void
  2205. +convert_libmagic_pattern(zval *pattern, char *val, size_t len, uint32_t options);
  2206. typedef struct {
  2207. char *buf;
  2208. @@ -544,10 +513,8 @@
  2209. protected file_pushbuf_t *file_push_buffer(struct magic_set *);
  2210. protected char *file_pop_buffer(struct magic_set *, file_pushbuf_t *);
  2211. -#ifndef COMPILE_ONLY
  2212. extern const char *file_names[];
  2213. extern const size_t file_nnames;
  2214. -#endif
  2215. #ifndef HAVE_STRERROR
  2216. extern int sys_nerr;
  2217. @@ -560,23 +527,10 @@
  2218. #define strtoul(a, b, c) strtol(a, b, c)
  2219. #endif
  2220. -#ifndef HAVE_PREAD
  2221. -ssize_t pread(int, void *, size_t, off_t);
  2222. -#endif
  2223. -#ifndef HAVE_VASPRINTF
  2224. -int vasprintf(char **, const char *, va_list);
  2225. -#endif
  2226. -#ifndef HAVE_ASPRINTF
  2227. -int asprintf(char **, const char *, ...);
  2228. -#endif
  2229. -#ifndef HAVE_DPRINTF
  2230. -int dprintf(int, const char *, ...);
  2231. -#endif
  2232. -
  2233. -#ifndef HAVE_STRLCPY
  2234. +#ifndef strlcpy
  2235. size_t strlcpy(char *, const char *, size_t);
  2236. #endif
  2237. -#ifndef HAVE_STRLCAT
  2238. +#ifndef strlcat
  2239. size_t strlcat(char *, const char *, size_t);
  2240. #endif
  2241. #ifndef HAVE_STRCASESTR
  2242. @@ -592,39 +546,6 @@
  2243. #ifndef HAVE_ASCTIME_R
  2244. char *asctime_r(const struct tm *, char *);
  2245. #endif
  2246. -#ifndef HAVE_GMTIME_R
  2247. -struct tm *gmtime_r(const time_t *, struct tm *);
  2248. -#endif
  2249. -#ifndef HAVE_LOCALTIME_R
  2250. -struct tm *localtime_r(const time_t *, struct tm *);
  2251. -#endif
  2252. -#ifndef HAVE_FMTCHECK
  2253. -const char *fmtcheck(const char *, const char *)
  2254. - __attribute__((__format_arg__(2)));
  2255. -#endif
  2256. -
  2257. -#ifdef HAVE_LIBSECCOMP
  2258. -// basic filter
  2259. -// this mode should not interfere with normal operations
  2260. -// only some dangerous syscalls are blacklisted
  2261. -int enable_sandbox_basic(void);
  2262. -
  2263. -// enhanced filter
  2264. -// this mode allows only the necessary syscalls used during normal operation
  2265. -// extensive testing required !!!
  2266. -int enable_sandbox_full(void);
  2267. -#endif
  2268. -
  2269. -protected const char *file_getprogname(void);
  2270. -protected void file_setprogname(const char *);
  2271. -protected void file_err(int, const char *, ...)
  2272. - __attribute__((__format__(__printf__, 2, 3)));
  2273. -protected void file_errx(int, const char *, ...)
  2274. - __attribute__((__format__(__printf__, 2, 3)));
  2275. -protected void file_warn(const char *, ...)
  2276. - __attribute__((__format__(__printf__, 1, 2)));
  2277. -protected void file_warnx(const char *, ...)
  2278. - __attribute__((__format__(__printf__, 1, 2)));
  2279. #if defined(HAVE_MMAP) && defined(HAVE_SYS_MMAN_H) && !defined(QUICK)
  2280. #define QUICK
  2281. @@ -647,6 +568,18 @@
  2282. #else
  2283. #define FILE_RCSID(id)
  2284. #endif
  2285. +
  2286. +#ifdef PHP_WIN32
  2287. +#ifdef _WIN64
  2288. +#define FINFO_LSEEK_FUNC _lseeki64
  2289. +#else
  2290. +#define FINFO_LSEEK_FUNC _lseek
  2291. +#endif
  2292. +#define FINFO_READ_FUNC _read
  2293. +#else
  2294. +#define FINFO_LSEEK_FUNC lseek
  2295. +#define FINFO_READ_FUNC read
  2296. +#endif
  2297. #ifndef __RCSID
  2298. #define __RCSID(a)
  2299. #endif
  2300. diff -u libmagic.orig/fsmagic.c libmagic/fsmagic.c
  2301. --- libmagic.orig/fsmagic.c 2017-05-24 21:17:50.000000000 +0200
  2302. +++ libmagic/fsmagic.c 2020-02-26 09:55:13.857043000 +0100
  2303. @@ -2,7 +2,7 @@
  2304. * Copyright (c) Ian F. Darwin 1986-1995.
  2305. * Software written by Ian F. Darwin and others;
  2306. * maintained 1995-present by Christos Zoulas and others.
  2307. - *
  2308. + *
  2309. * Redistribution and use in source and binary forms, with or without
  2310. * modification, are permitted provided that the following conditions
  2311. * are met:
  2312. @@ -12,7 +12,7 @@
  2313. * 2. Redistributions in binary form must reproduce the above copyright
  2314. * notice, this list of conditions and the following disclaimer in the
  2315. * documentation and/or other materials provided with the distribution.
  2316. - *
  2317. + *
  2318. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  2319. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  2320. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  2321. @@ -63,26 +63,10 @@
  2322. # define minor(dev) ((dev) & 0xff)
  2323. #endif
  2324. #undef HAVE_MAJOR
  2325. -#ifdef S_IFLNK
  2326. -private int
  2327. -bad_link(struct magic_set *ms, int err, char *buf)
  2328. -{
  2329. - int mime = ms->flags & MAGIC_MIME;
  2330. - if ((mime & MAGIC_MIME_TYPE) &&
  2331. - file_printf(ms, "inode/symlink")
  2332. - == -1)
  2333. - return -1;
  2334. - else if (!mime) {
  2335. - if (ms->flags & MAGIC_ERROR) {
  2336. - file_error(ms, err,
  2337. - "broken symbolic link to %s", buf);
  2338. - return -1;
  2339. - }
  2340. - if (file_printf(ms, "broken symbolic link to %s", buf) == -1)
  2341. - return -1;
  2342. - }
  2343. - return 1;
  2344. -}
  2345. +
  2346. +#ifdef PHP_WIN32
  2347. +
  2348. +# undef S_IFIFO
  2349. #endif
  2350. private int
  2351. handle_mime(struct magic_set *ms, int mime, const char *str)
  2352. @@ -100,70 +84,39 @@
  2353. }
  2354. protected int
  2355. -file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb)
  2356. +file_fsmagic(struct magic_set *ms, const char *fn, zend_stat_t *sb, php_stream *stream)
  2357. {
  2358. int ret, did = 0;
  2359. int mime = ms->flags & MAGIC_MIME;
  2360. int silent = ms->flags & (MAGIC_APPLE|MAGIC_EXTENSION);
  2361. -#ifdef S_IFLNK
  2362. - char buf[BUFSIZ+4];
  2363. - ssize_t nch;
  2364. - struct stat tstatbuf;
  2365. -#endif
  2366. - if (fn == NULL)
  2367. + if (ms->flags & (MAGIC_APPLE|MAGIC_EXTENSION))
  2368. + return 0;
  2369. +
  2370. + if (fn == NULL && !stream) {
  2371. return 0;
  2372. + }
  2373. #define COMMA (did++ ? ", " : "")
  2374. - /*
  2375. - * Fstat is cheaper but fails for files you don't have read perms on.
  2376. - * On 4.2BSD and similar systems, use lstat() to identify symlinks.
  2377. - */
  2378. -#ifdef S_IFLNK
  2379. - if ((ms->flags & MAGIC_SYMLINK) == 0)
  2380. - ret = lstat(fn, sb);
  2381. - else
  2382. -#endif
  2383. - ret = stat(fn, sb); /* don't merge into if; see "ret =" above */
  2384. -#ifdef WIN32
  2385. - {
  2386. - HANDLE hFile = CreateFile((LPCSTR)fn, 0, FILE_SHARE_DELETE |
  2387. - FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0,
  2388. - NULL);
  2389. - if (hFile != INVALID_HANDLE_VALUE) {
  2390. - /*
  2391. - * Stat failed, but we can still open it - assume it's
  2392. - * a block device, if nothing else.
  2393. - */
  2394. - if (ret) {
  2395. - sb->st_mode = S_IFBLK;
  2396. - ret = 0;
  2397. - }
  2398. - switch (GetFileType(hFile)) {
  2399. - case FILE_TYPE_CHAR:
  2400. - sb->st_mode |= S_IFCHR;
  2401. - sb->st_mode &= ~S_IFREG;
  2402. - break;
  2403. - case FILE_TYPE_PIPE:
  2404. - sb->st_mode |= S_IFIFO;
  2405. - sb->st_mode &= ~S_IFREG;
  2406. - break;
  2407. + if (stream) {
  2408. + php_stream_statbuf ssb;
  2409. + if (php_stream_stat(stream, &ssb) < 0) {
  2410. + if (ms->flags & MAGIC_ERROR) {
  2411. + file_error(ms, errno, "cannot stat `%s'", fn);
  2412. + return -1;
  2413. }
  2414. - CloseHandle(hFile);
  2415. + return 0;
  2416. }
  2417. - }
  2418. -#endif
  2419. -
  2420. - if (ret) {
  2421. - if (ms->flags & MAGIC_ERROR) {
  2422. - file_error(ms, errno, "cannot stat `%s'", fn);
  2423. - return -1;
  2424. + memcpy(sb, &ssb.sb, sizeof(struct stat));
  2425. + } else {
  2426. + if (php_sys_stat(fn, sb) != 0) {
  2427. + if (ms->flags & MAGIC_ERROR) {
  2428. + file_error(ms, errno, "cannot stat `%s'", fn);
  2429. + return -1;
  2430. + }
  2431. + return 0;
  2432. }
  2433. - if (file_printf(ms, "cannot open `%s' (%s)",
  2434. - fn, strerror(errno)) == -1)
  2435. - return -1;
  2436. - return 0;
  2437. }
  2438. ret = 1;
  2439. @@ -174,44 +127,36 @@
  2440. return -1;
  2441. #endif
  2442. #ifdef S_ISGID
  2443. - if (sb->st_mode & S_ISGID)
  2444. + if (sb->st_mode & S_ISGID)
  2445. if (file_printf(ms, "%ssetgid", COMMA) == -1)
  2446. return -1;
  2447. #endif
  2448. #ifdef S_ISVTX
  2449. - if (sb->st_mode & S_ISVTX)
  2450. + if (sb->st_mode & S_ISVTX)
  2451. if (file_printf(ms, "%ssticky", COMMA) == -1)
  2452. return -1;
  2453. #endif
  2454. }
  2455. -
  2456. +
  2457. switch (sb->st_mode & S_IFMT) {
  2458. - case S_IFDIR:
  2459. - if (mime) {
  2460. - if (handle_mime(ms, mime, "directory") == -1)
  2461. - return -1;
  2462. - } else if (silent) {
  2463. - } else if (file_printf(ms, "%sdirectory", COMMA) == -1)
  2464. - return -1;
  2465. - break;
  2466. -#ifdef S_IFCHR
  2467. - case S_IFCHR:
  2468. - /*
  2469. - * If -s has been specified, treat character special files
  2470. - * like ordinary files. Otherwise, just report that they
  2471. - * are block special files and go on to the next file.
  2472. - */
  2473. - if ((ms->flags & MAGIC_DEVICES) != 0) {
  2474. - ret = 0;
  2475. - break;
  2476. - }
  2477. - if (mime) {
  2478. - if (handle_mime(ms, mime, "chardevice") == -1)
  2479. - return -1;
  2480. - } else if (silent) {
  2481. - } else {
  2482. -#ifdef HAVE_STRUCT_STAT_ST_RDEV
  2483. -# ifdef dv_unit
  2484. +#ifndef PHP_WIN32
  2485. +# ifdef S_IFCHR
  2486. + case S_IFCHR:
  2487. + /*
  2488. + * If -s has been specified, treat character special files
  2489. + * like ordinary files. Otherwise, just report that they
  2490. + * are block special files and go on to the next file.
  2491. + */
  2492. + if ((ms->flags & MAGIC_DEVICES) != 0) {
  2493. + ret = 0;
  2494. + break;
  2495. + }
  2496. + if (mime) {
  2497. + if (handle_mime(ms, mime, "chardevice") == -1)
  2498. + return -1;
  2499. + } else {
  2500. +# ifdef HAVE_STAT_ST_RDEV
  2501. +# ifdef dv_unit
  2502. if (file_printf(ms, "%scharacter special (%d/%d/%d)",
  2503. COMMA, major(sb->st_rdev), dv_unit(sb->st_rdev),
  2504. dv_subunit(sb->st_rdev)) == -1)
  2505. @@ -226,45 +171,11 @@
  2506. if (file_printf(ms, "%scharacter special", COMMA) == -1)
  2507. return -1;
  2508. #endif
  2509. - }
  2510. - break;
  2511. -#endif
  2512. -#ifdef S_IFBLK
  2513. - case S_IFBLK:
  2514. - /*
  2515. - * If -s has been specified, treat block special files
  2516. - * like ordinary files. Otherwise, just report that they
  2517. - * are block special files and go on to the next file.
  2518. - */
  2519. - if ((ms->flags & MAGIC_DEVICES) != 0) {
  2520. - ret = 0;
  2521. - break;
  2522. - }
  2523. - if (mime) {
  2524. - if (handle_mime(ms, mime, "blockdevice") == -1)
  2525. - return -1;
  2526. - } else if (silent) {
  2527. - } else {
  2528. -#ifdef HAVE_STRUCT_STAT_ST_RDEV
  2529. -# ifdef dv_unit
  2530. - if (file_printf(ms, "%sblock special (%d/%d/%d)",
  2531. - COMMA, major(sb->st_rdev), dv_unit(sb->st_rdev),
  2532. - dv_subunit(sb->st_rdev)) == -1)
  2533. - return -1;
  2534. -# else
  2535. - if (file_printf(ms, "%sblock special (%ld/%ld)",
  2536. - COMMA, (long)major(sb->st_rdev),
  2537. - (long)minor(sb->st_rdev)) == -1)
  2538. - return -1;
  2539. + }
  2540. + return 1;
  2541. # endif
  2542. -#else
  2543. - if (file_printf(ms, "%sblock special", COMMA) == -1)
  2544. - return -1;
  2545. #endif
  2546. - }
  2547. - break;
  2548. -#endif
  2549. - /* TODO add code to handle V7 MUX and Blit MUX files */
  2550. +
  2551. #ifdef S_IFIFO
  2552. case S_IFIFO:
  2553. if((ms->flags & MAGIC_DEVICES) != 0)
  2554. @@ -272,7 +183,6 @@
  2555. if (mime) {
  2556. if (handle_mime(ms, mime, "fifo") == -1)
  2557. return -1;
  2558. - } else if (silent) {
  2559. } else if (file_printf(ms, "%sfifo (named pipe)", COMMA) == -1)
  2560. return -1;
  2561. break;
  2562. @@ -282,89 +192,20 @@
  2563. if (mime) {
  2564. if (handle_mime(ms, mime, "door") == -1)
  2565. return -1;
  2566. - } else if (silent) {
  2567. } else if (file_printf(ms, "%sdoor", COMMA) == -1)
  2568. return -1;
  2569. break;
  2570. #endif
  2571. #ifdef S_IFLNK
  2572. case S_IFLNK:
  2573. - if ((nch = readlink(fn, buf, BUFSIZ-1)) <= 0) {
  2574. + /* stat is used, if it made here then the link is broken */
  2575. if (ms->flags & MAGIC_ERROR) {
  2576. - file_error(ms, errno, "unreadable symlink `%s'",
  2577. - fn);
  2578. + file_error(ms, errno, "unreadable symlink `%s'", fn);
  2579. return -1;
  2580. }
  2581. - if (mime) {
  2582. - if (handle_mime(ms, mime, "symlink") == -1)
  2583. - return -1;
  2584. - } else if (silent) {
  2585. - } else if (file_printf(ms,
  2586. - "%sunreadable symlink `%s' (%s)", COMMA, fn,
  2587. - strerror(errno)) == -1)
  2588. - return -1;
  2589. - break;
  2590. - }
  2591. - buf[nch] = '\0'; /* readlink(2) does not do this */
  2592. -
  2593. - /* If broken symlink, say so and quit early. */
  2594. - if (*buf == '/') {
  2595. - if (stat(buf, &tstatbuf) < 0)
  2596. - return bad_link(ms, errno, buf);
  2597. - } else {
  2598. - char *tmp;
  2599. - char buf2[BUFSIZ+BUFSIZ+4];
  2600. -
  2601. - if ((tmp = strrchr(fn, '/')) == NULL) {
  2602. - tmp = buf; /* in current directory anyway */
  2603. - } else {
  2604. - if (tmp - fn + 1 > BUFSIZ) {
  2605. - if (ms->flags & MAGIC_ERROR) {
  2606. - file_error(ms, 0,
  2607. - "path too long: `%s'", buf);
  2608. - return -1;
  2609. - }
  2610. - if (mime) {
  2611. - if (handle_mime(ms, mime,
  2612. - "x-path-too-long") == -1)
  2613. - return -1;
  2614. - } else if (silent) {
  2615. - } else if (file_printf(ms,
  2616. - "%spath too long: `%s'", COMMA,
  2617. - fn) == -1)
  2618. - return -1;
  2619. - break;
  2620. - }
  2621. - /* take dir part */
  2622. - (void)strlcpy(buf2, fn, sizeof buf2);
  2623. - buf2[tmp - fn + 1] = '\0';
  2624. - /* plus (rel) link */
  2625. - (void)strlcat(buf2, buf, sizeof buf2);
  2626. - tmp = buf2;
  2627. - }
  2628. - if (stat(tmp, &tstatbuf) < 0)
  2629. - return bad_link(ms, errno, buf);
  2630. - }
  2631. -
  2632. - /* Otherwise, handle it. */
  2633. - if ((ms->flags & MAGIC_SYMLINK) != 0) {
  2634. - const char *p;
  2635. - ms->flags &= MAGIC_SYMLINK;
  2636. - p = magic_file(ms, buf);
  2637. - ms->flags |= MAGIC_SYMLINK;
  2638. - if (p == NULL)
  2639. - return -1;
  2640. - } else { /* just print what it points to */
  2641. - if (mime) {
  2642. - if (handle_mime(ms, mime, "symlink") == -1)
  2643. - return -1;
  2644. - } else if (silent) {
  2645. - } else if (file_printf(ms, "%ssymbolic link to %s",
  2646. - COMMA, buf) == -1)
  2647. - return -1;
  2648. - }
  2649. - break;
  2650. + return 1;
  2651. #endif
  2652. +
  2653. #ifdef S_IFSOCK
  2654. #ifndef __COHERENT__
  2655. case S_IFSOCK:
  2656. diff -u libmagic.orig/funcs.c libmagic/funcs.c
  2657. --- libmagic.orig/funcs.c 2017-11-02 21:25:39.000000000 +0100
  2658. +++ libmagic/funcs.c 2020-02-26 09:55:13.859042500 +0100
  2659. @@ -31,7 +31,6 @@
  2660. #endif /* lint */
  2661. #include "magic.h"
  2662. -#include <assert.h>
  2663. #include <stdarg.h>
  2664. #include <stdlib.h>
  2665. #include <string.h>
  2666. @@ -42,78 +41,77 @@
  2667. #if defined(HAVE_WCTYPE_H)
  2668. #include <wctype.h>
  2669. #endif
  2670. -#if defined(HAVE_LIMITS_H)
  2671. -#include <limits.h>
  2672. +#if defined(HAVE_LOCALE_H)
  2673. +#include <locale.h>
  2674. #endif
  2675. #ifndef SIZE_MAX
  2676. #define SIZE_MAX ((size_t)~0)
  2677. #endif
  2678. -/*
  2679. - * Like printf, only we append to a buffer.
  2680. - */
  2681. -protected int
  2682. -file_vprintf(struct magic_set *ms, const char *fmt, va_list ap)
  2683. -{
  2684. - int len;
  2685. - char *buf, *newstr;
  2686. +#include "php.h"
  2687. +#include "main/php_network.h"
  2688. - if (ms->event_flags & EVENT_HAD_ERR)
  2689. - return 0;
  2690. - len = vasprintf(&buf, fmt, ap);
  2691. - if (len < 0)
  2692. - goto out;
  2693. -
  2694. - if (ms->o.buf != NULL) {
  2695. - len = asprintf(&newstr, "%s%s", ms->o.buf, buf);
  2696. - free(buf);
  2697. - if (len < 0)
  2698. - goto out;
  2699. - free(ms->o.buf);
  2700. - buf = newstr;
  2701. - }
  2702. - ms->o.buf = buf;
  2703. - return 0;
  2704. -out:
  2705. - fprintf(stderr, "vasprintf failed (%s)", strerror(errno));
  2706. - return -1;
  2707. -}
  2708. +#ifndef PREG_OFFSET_CAPTURE
  2709. +# define PREG_OFFSET_CAPTURE (1<<8)
  2710. +#endif
  2711. protected int
  2712. file_printf(struct magic_set *ms, const char *fmt, ...)
  2713. {
  2714. - int rv;
  2715. va_list ap;
  2716. + size_t len;
  2717. + char *buf = NULL, *newstr;
  2718. va_start(ap, fmt);
  2719. - rv = file_vprintf(ms, fmt, ap);
  2720. + len = vspprintf(&buf, 0, fmt, ap);
  2721. va_end(ap);
  2722. - return rv;
  2723. +
  2724. + if (ms->o.buf != NULL) {
  2725. + len = spprintf(&newstr, 0, "%s%s", ms->o.buf, (buf ? buf : ""));
  2726. + if (buf) {
  2727. + efree(buf);
  2728. + }
  2729. + efree(ms->o.buf);
  2730. + ms->o.buf = newstr;
  2731. + } else {
  2732. + ms->o.buf = buf;
  2733. + }
  2734. + return 0;
  2735. }
  2736. /*
  2737. * error - print best error message possible
  2738. */
  2739. /*VARARGS*/
  2740. -__attribute__((__format__(__printf__, 3, 0)))
  2741. private void
  2742. file_error_core(struct magic_set *ms, int error, const char *f, va_list va,
  2743. size_t lineno)
  2744. {
  2745. + char *buf = NULL;
  2746. +
  2747. /* Only the first error is ok */
  2748. if (ms->event_flags & EVENT_HAD_ERR)
  2749. return;
  2750. if (lineno != 0) {
  2751. - free(ms->o.buf);
  2752. + efree(ms->o.buf);
  2753. ms->o.buf = NULL;
  2754. file_printf(ms, "line %" SIZE_T_FORMAT "u:", lineno);
  2755. }
  2756. - if (ms->o.buf && *ms->o.buf)
  2757. - file_printf(ms, " ");
  2758. - file_vprintf(ms, f, va);
  2759. - if (error > 0)
  2760. - file_printf(ms, " (%s)", strerror(error));
  2761. +
  2762. + vspprintf(&buf, 0, f, va);
  2763. + va_end(va);
  2764. +
  2765. + if (error > 0) {
  2766. + file_printf(ms, "%s (%s)", (*buf ? buf : ""), strerror(error));
  2767. + } else if (*buf) {
  2768. + file_printf(ms, "%s", buf);
  2769. + }
  2770. +
  2771. + if (buf) {
  2772. + efree(buf);
  2773. + }
  2774. +
  2775. ms->event_flags |= EVENT_HAD_ERR;
  2776. ms->error = error;
  2777. }
  2778. @@ -160,7 +158,6 @@
  2779. file_error(ms, errno, "error reading");
  2780. }
  2781. -#ifndef COMPILE_ONLY
  2782. static int
  2783. checkdone(struct magic_set *ms, int *rv)
  2784. @@ -174,8 +171,8 @@
  2785. /*ARGSUSED*/
  2786. protected int
  2787. -file_buffer(struct magic_set *ms, int fd, const char *inname __attribute__ ((__unused__)),
  2788. - const void *buf, size_t nb)
  2789. +file_buffer(struct magic_set *ms, php_stream *stream, const char *inname, const void *buf,
  2790. + size_t nb)
  2791. {
  2792. int m = 0, rv = 0, looks_text = 0;
  2793. const char *code = NULL;
  2794. @@ -184,7 +181,8 @@
  2795. const char *def = "data";
  2796. const char *ftype = NULL;
  2797. struct buffer b;
  2798. -
  2799. + int fd = -1;
  2800. +
  2801. buffer_init(&b, fd, buf, nb);
  2802. if (nb == 0) {
  2803. @@ -216,8 +214,8 @@
  2804. }
  2805. }
  2806. #endif
  2807. -#if HAVE_FORK
  2808. - /* try compression stuff */
  2809. +
  2810. +#if PHP_FILEINFO_UNCOMPRESS
  2811. if ((ms->flags & MAGIC_NO_CHECK_COMPRESS) == 0) {
  2812. m = file_zmagic(ms, &b, inname);
  2813. if ((ms->flags & MAGIC_DEBUG) != 0)
  2814. @@ -239,13 +237,22 @@
  2815. }
  2816. /* Check if we have a CDF file */
  2817. - if ((ms->flags & MAGIC_NO_CHECK_CDF) == 0) {
  2818. - m = file_trycdf(ms, &b);
  2819. - if ((ms->flags & MAGIC_DEBUG) != 0)
  2820. - (void)fprintf(stderr, "[try cdf %d]\n", m);
  2821. - if (m) {
  2822. - if (checkdone(ms, &rv))
  2823. - goto done;
  2824. + if ((ms->flags & MAGIC_NO_CHECK_CDF) == 0 && stream) {
  2825. +#ifdef _WIN64
  2826. + php_socket_t _fd = fd;
  2827. + int _ret = php_stream_cast(stream, PHP_STREAM_AS_FD, (void **)&_fd, 0);
  2828. + fd = (int)_fd;
  2829. +#else
  2830. + int _ret = php_stream_cast(stream, PHP_STREAM_AS_FD, (void **)&fd, 0);
  2831. +#endif
  2832. + if (SUCCESS == _ret) {
  2833. + m = file_trycdf(ms, &b);
  2834. + if ((ms->flags & MAGIC_DEBUG) != 0)
  2835. + (void)fprintf(stderr, "[try cdf %d]\n", m);
  2836. + if (m) {
  2837. + if (checkdone(ms, &rv))
  2838. + goto done;
  2839. + }
  2840. }
  2841. }
  2842. @@ -315,7 +322,7 @@
  2843. if (file_printf(ms, "%s", code_mime) == -1)
  2844. rv = -1;
  2845. }
  2846. -#if HAVE_FORK
  2847. +#if PHP_FILEINFO_UNCOMPRESS
  2848. done_encoding:
  2849. #endif
  2850. buffer_fini(&b);
  2851. @@ -324,7 +331,6 @@
  2852. return m;
  2853. }
  2854. -#endif
  2855. protected int
  2856. file_reset(struct magic_set *ms, int checkloaded)
  2857. @@ -334,11 +340,11 @@
  2858. return -1;
  2859. }
  2860. if (ms->o.buf) {
  2861. - free(ms->o.buf);
  2862. + efree(ms->o.buf);
  2863. ms->o.buf = NULL;
  2864. }
  2865. if (ms->o.pbuf) {
  2866. - free(ms->o.pbuf);
  2867. + efree(ms->o.pbuf);
  2868. ms->o.pbuf = NULL;
  2869. }
  2870. ms->event_flags &= ~EVENT_HAD_ERR;
  2871. @@ -376,7 +382,7 @@
  2872. return NULL;
  2873. }
  2874. psize = len * 4 + 1;
  2875. - if ((pbuf = CAST(char *, realloc(ms->o.pbuf, psize))) == NULL) {
  2876. + if ((pbuf = CAST(char *, erealloc(ms->o.pbuf, psize))) == NULL) {
  2877. file_oomem(ms, psize);
  2878. return NULL;
  2879. }
  2880. @@ -440,8 +446,8 @@
  2881. if (level >= ms->c.len) {
  2882. len = (ms->c.len = 20 + level) * sizeof(*ms->c.li);
  2883. ms->c.li = CAST(struct level_info *, (ms->c.li == NULL) ?
  2884. - malloc(len) :
  2885. - realloc(ms->c.li, len));
  2886. + emalloc(len) :
  2887. + erealloc(ms->c.li, len));
  2888. if (ms->c.li == NULL) {
  2889. file_oomem(ms, len);
  2890. return -1;
  2891. @@ -464,76 +470,38 @@
  2892. protected int
  2893. file_replace(struct magic_set *ms, const char *pat, const char *rep)
  2894. {
  2895. - file_regex_t rx;
  2896. - int rc, rv = -1;
  2897. -
  2898. - rc = file_regcomp(&rx, pat, REG_EXTENDED);
  2899. - if (rc) {
  2900. - file_regerror(&rx, rc, ms);
  2901. - } else {
  2902. - regmatch_t rm;
  2903. - int nm = 0;
  2904. - while (file_regexec(&rx, ms->o.buf, 1, &rm, 0) == 0) {
  2905. - ms->o.buf[rm.rm_so] = '\0';
  2906. - if (file_printf(ms, "%s%s", rep,
  2907. - rm.rm_eo != 0 ? ms->o.buf + rm.rm_eo : "") == -1)
  2908. - goto out;
  2909. - nm++;
  2910. - }
  2911. - rv = nm;
  2912. + zval patt;
  2913. + uint32_t opts = 0;
  2914. + pcre_cache_entry *pce;
  2915. + zend_string *res;
  2916. + zend_string *repl;
  2917. + size_t rep_cnt = 0;
  2918. +
  2919. + opts |= PCRE2_MULTILINE;
  2920. + convert_libmagic_pattern(&patt, (char*)pat, strlen(pat), opts);
  2921. + if ((pce = pcre_get_compiled_regex_cache_ex(Z_STR(patt), 0)) == NULL) {
  2922. + zval_ptr_dtor(&patt);
  2923. + rep_cnt = -1;
  2924. + goto out;
  2925. }
  2926. -out:
  2927. - file_regfree(&rx);
  2928. - return rv;
  2929. -}
  2930. + zval_ptr_dtor(&patt);
  2931. -protected int
  2932. -file_regcomp(file_regex_t *rx, const char *pat, int flags)
  2933. -{
  2934. -#ifdef USE_C_LOCALE
  2935. - rx->c_lc_ctype = newlocale(LC_CTYPE_MASK, "C", 0);
  2936. - assert(rx->c_lc_ctype != NULL);
  2937. - rx->old_lc_ctype = uselocale(rx->c_lc_ctype);
  2938. - assert(rx->old_lc_ctype != NULL);
  2939. -#else
  2940. - rx->old_lc_ctype = setlocale(LC_CTYPE, "C");
  2941. -#endif
  2942. - rx->pat = pat;
  2943. + repl = zend_string_init(rep, strlen(rep), 0);
  2944. + res = php_pcre_replace_impl(pce, NULL, ms->o.buf, strlen(ms->o.buf), repl, -1, &rep_cnt);
  2945. - return rx->rc = regcomp(&rx->rx, pat, flags);
  2946. -}
  2947. + zend_string_release_ex(repl, 0);
  2948. + if (NULL == res) {
  2949. + rep_cnt = -1;
  2950. + goto out;
  2951. + }
  2952. -protected int
  2953. -file_regexec(file_regex_t *rx, const char *str, size_t nmatch,
  2954. - regmatch_t* pmatch, int eflags)
  2955. -{
  2956. - assert(rx->rc == 0);
  2957. - /* XXX: force initialization because glibc does not always do this */
  2958. - memset(pmatch, 0, nmatch * sizeof(*pmatch));
  2959. - return regexec(&rx->rx, str, nmatch, pmatch, eflags);
  2960. -}
  2961. + strncpy(ms->o.buf, ZSTR_VAL(res), ZSTR_LEN(res));
  2962. + ms->o.buf[ZSTR_LEN(res)] = '\0';
  2963. -protected void
  2964. -file_regfree(file_regex_t *rx)
  2965. -{
  2966. - if (rx->rc == 0)
  2967. - regfree(&rx->rx);
  2968. -#ifdef USE_C_LOCALE
  2969. - (void)uselocale(rx->old_lc_ctype);
  2970. - freelocale(rx->c_lc_ctype);
  2971. -#else
  2972. - (void)setlocale(LC_CTYPE, rx->old_lc_ctype);
  2973. -#endif
  2974. -}
  2975. + zend_string_release_ex(res, 0);
  2976. -protected void
  2977. -file_regerror(file_regex_t *rx, int rc, struct magic_set *ms)
  2978. -{
  2979. - char errmsg[512];
  2980. -
  2981. - (void)regerror(rc, &rx->rx, errmsg, sizeof(errmsg));
  2982. - file_magerror(ms, "regex error %d for `%s', (%s)", rc, rx->pat,
  2983. - errmsg);
  2984. +out:
  2985. + return rep_cnt;
  2986. }
  2987. protected file_pushbuf_t *
  2988. @@ -544,7 +512,7 @@
  2989. if (ms->event_flags & EVENT_HAD_ERR)
  2990. return NULL;
  2991. - if ((pb = (CAST(file_pushbuf_t *, malloc(sizeof(*pb))))) == NULL)
  2992. + if ((pb = (CAST(file_pushbuf_t *, emalloc(sizeof(*pb))))) == NULL)
  2993. return NULL;
  2994. pb->buf = ms->o.buf;
  2995. @@ -562,8 +530,8 @@
  2996. char *rbuf;
  2997. if (ms->event_flags & EVENT_HAD_ERR) {
  2998. - free(pb->buf);
  2999. - free(pb);
  3000. + efree(pb->buf);
  3001. + efree(pb);
  3002. return NULL;
  3003. }
  3004. @@ -572,7 +540,7 @@
  3005. ms->o.buf = pb->buf;
  3006. ms->offset = pb->offset;
  3007. - free(pb);
  3008. + efree(pb);
  3009. return rbuf;
  3010. }
  3011. diff -u libmagic.orig/magic.c libmagic/magic.c
  3012. --- libmagic.orig/magic.c 2017-08-28 15:39:18.000000000 +0200
  3013. +++ libmagic/magic.c 2020-02-26 09:55:13.861044300 +0100
  3014. @@ -25,11 +25,6 @@
  3015. * SUCH DAMAGE.
  3016. */
  3017. -#ifdef WIN32
  3018. -#include <windows.h>
  3019. -#include <shlwapi.h>
  3020. -#endif
  3021. -
  3022. #include "file.h"
  3023. #ifndef lint
  3024. @@ -39,14 +34,19 @@
  3025. #include "magic.h"
  3026. #include <stdlib.h>
  3027. +#ifdef PHP_WIN32
  3028. +#include "win32/unistd.h"
  3029. +#else
  3030. #include <unistd.h>
  3031. +#endif
  3032. #include <string.h>
  3033. -#ifdef QUICK
  3034. -#include <sys/mman.h>
  3035. +#include "config.h"
  3036. +
  3037. +#ifdef PHP_WIN32
  3038. +#include <shlwapi.h>
  3039. #endif
  3040. -#ifdef HAVE_LIMITS_H
  3041. +
  3042. #include <limits.h> /* for PIPE_BUF */
  3043. -#endif
  3044. #if defined(HAVE_UTIMES)
  3045. # include <sys/time.h>
  3046. @@ -71,194 +71,23 @@
  3047. #endif
  3048. #endif
  3049. +#ifdef PHP_WIN32
  3050. +# undef S_IFLNK
  3051. +# undef S_IFIFO
  3052. +#endif
  3053. +
  3054. private void close_and_restore(const struct magic_set *, const char *, int,
  3055. - const struct stat *);
  3056. + const zend_stat_t *);
  3057. private int unreadable_info(struct magic_set *, mode_t, const char *);
  3058. +#if 0
  3059. private const char* get_default_magic(void);
  3060. -#ifndef COMPILE_ONLY
  3061. -private const char *file_or_fd(struct magic_set *, const char *, int);
  3062. #endif
  3063. +private const char *file_or_stream(struct magic_set *, const char *, php_stream *);
  3064. #ifndef STDIN_FILENO
  3065. #define STDIN_FILENO 0
  3066. #endif
  3067. -#ifdef WIN32
  3068. -/* HINSTANCE of this shared library. Needed for get_default_magic() */
  3069. -static HINSTANCE _w32_dll_instance = NULL;
  3070. -
  3071. -static void
  3072. -_w32_append_path(char **hmagicpath, const char *fmt, ...)
  3073. -{
  3074. - char *tmppath;
  3075. - char *newpath;
  3076. - va_list ap;
  3077. -
  3078. - va_start(ap, fmt);
  3079. - if (vasprintf(&tmppath, fmt, ap) < 0) {
  3080. - va_end(ap);
  3081. - return;
  3082. - }
  3083. - va_end(ap);
  3084. -
  3085. - if (access(tmppath, R_OK) == -1)
  3086. - goto out;
  3087. -
  3088. - if (*hmagicpath == NULL) {
  3089. - *hmagicpath = tmppath;
  3090. - return;
  3091. - }
  3092. -
  3093. - if (asprintf(&newpath, "%s%c%s", *hmagicpath, PATHSEP, tmppath) < 0)
  3094. - goto out;
  3095. -
  3096. - free(*hmagicpath);
  3097. - free(tmppath);
  3098. - *hmagicpath = newpath;
  3099. - return;
  3100. -out:
  3101. - free(tmppath);
  3102. -}
  3103. -
  3104. -static void
  3105. -_w32_get_magic_relative_to(char **hmagicpath, HINSTANCE module)
  3106. -{
  3107. - static const char *trypaths[] = {
  3108. - "%s/share/misc/magic.mgc",
  3109. - "%s/magic.mgc",
  3110. - };
  3111. - LPSTR dllpath;
  3112. - size_t sp;
  3113. -
  3114. - dllpath = calloc(MAX_PATH + 1, sizeof(*dllpath));
  3115. -
  3116. - if (!GetModuleFileNameA(module, dllpath, MAX_PATH))
  3117. - goto out;
  3118. -
  3119. - PathRemoveFileSpecA(dllpath);
  3120. -
  3121. - if (module) {
  3122. - char exepath[MAX_PATH];
  3123. - GetModuleFileNameA(NULL, exepath, MAX_PATH);
  3124. - PathRemoveFileSpecA(exepath);
  3125. - if (stricmp(exepath, dllpath) == 0)
  3126. - goto out;
  3127. - }
  3128. -
  3129. - sp = strlen(dllpath);
  3130. - if (sp > 3 && stricmp(&dllpath[sp - 3], "bin") == 0) {
  3131. - _w32_append_path(hmagicpath,
  3132. - "%s/../share/misc/magic.mgc", dllpath);
  3133. - goto out;
  3134. - }
  3135. -
  3136. - for (sp = 0; sp < __arraycount(trypaths); sp++)
  3137. - _w32_append_path(hmagicpath, trypaths[sp], dllpath);
  3138. -out:
  3139. - free(dllpath);
  3140. -}
  3141. -
  3142. -/* Placate GCC by offering a sacrificial previous prototype */
  3143. -BOOL WINAPI DllMain(HINSTANCE, DWORD, LPVOID);
  3144. -
  3145. -BOOL WINAPI
  3146. -DllMain(HINSTANCE hinstDLL, DWORD fdwReason,
  3147. - LPVOID lpvReserved __attribute__((__unused__)))
  3148. -{
  3149. - if (fdwReason == DLL_PROCESS_ATTACH)
  3150. - _w32_dll_instance = hinstDLL;
  3151. - return 1;
  3152. -}
  3153. -#endif
  3154. -
  3155. -private const char *
  3156. -get_default_magic(void)
  3157. -{
  3158. - static const char hmagic[] = "/.magic/magic.mgc";
  3159. - static char *default_magic;
  3160. - char *home, *hmagicpath;
  3161. -
  3162. -#ifndef WIN32
  3163. - struct stat st;
  3164. -
  3165. - if (default_magic) {
  3166. - free(default_magic);
  3167. - default_magic = NULL;
  3168. - }
  3169. - if ((home = getenv("HOME")) == NULL)
  3170. - return MAGIC;
  3171. -
  3172. - if (asprintf(&hmagicpath, "%s/.magic.mgc", home) < 0)
  3173. - return MAGIC;
  3174. - if (stat(hmagicpath, &st) == -1) {
  3175. - free(hmagicpath);
  3176. - if (asprintf(&hmagicpath, "%s/.magic", home) < 0)
  3177. - return MAGIC;
  3178. - if (stat(hmagicpath, &st) == -1)
  3179. - goto out;
  3180. - if (S_ISDIR(st.st_mode)) {
  3181. - free(hmagicpath);
  3182. - if (asprintf(&hmagicpath, "%s/%s", home, hmagic) < 0)
  3183. - return MAGIC;
  3184. - if (access(hmagicpath, R_OK) == -1)
  3185. - goto out;
  3186. - }
  3187. - }
  3188. -
  3189. - if (asprintf(&default_magic, "%s:%s", hmagicpath, MAGIC) < 0)
  3190. - goto out;
  3191. - free(hmagicpath);
  3192. - return default_magic;
  3193. -out:
  3194. - default_magic = NULL;
  3195. - free(hmagicpath);
  3196. - return MAGIC;
  3197. -#else
  3198. - hmagicpath = NULL;
  3199. -
  3200. - if (default_magic) {
  3201. - free(default_magic);
  3202. - default_magic = NULL;
  3203. - }
  3204. -
  3205. - /* First, try to get a magic file from user-application data */
  3206. - if ((home = getenv("LOCALAPPDATA")) != NULL)
  3207. - _w32_append_path(&hmagicpath, "%s%s", home, hmagic);
  3208. -
  3209. - /* Second, try to get a magic file from the user profile data */
  3210. - if ((home = getenv("USERPROFILE")) != NULL)
  3211. - _w32_append_path(&hmagicpath,
  3212. - "%s/Local Settings/Application Data%s", home, hmagic);
  3213. -
  3214. - /* Third, try to get a magic file from Common Files */
  3215. - if ((home = getenv("COMMONPROGRAMFILES")) != NULL)
  3216. - _w32_append_path(&hmagicpath, "%s%s", home, hmagic);
  3217. -
  3218. - /* Fourth, try to get magic file relative to exe location */
  3219. - _w32_get_magic_relative_to(&hmagicpath, NULL);
  3220. -
  3221. - /* Fifth, try to get magic file relative to dll location */
  3222. - _w32_get_magic_relative_to(&hmagicpath, _w32_dll_instance);
  3223. -
  3224. - /* Avoid MAGIC constant - it likely points to a file within MSys tree */
  3225. - default_magic = hmagicpath;
  3226. - return default_magic;
  3227. -#endif
  3228. -}
  3229. -
  3230. -public const char *
  3231. -magic_getpath(const char *magicfile, int action)
  3232. -{
  3233. - if (magicfile != NULL)
  3234. - return magicfile;
  3235. -
  3236. - magicfile = getenv("MAGIC");
  3237. - if (magicfile != NULL)
  3238. - return magicfile;
  3239. -
  3240. - return action == FILE_LOAD ? get_default_magic() : MAGIC;
  3241. -}
  3242. -
  3243. public struct magic_set *
  3244. magic_open(int flags)
  3245. {
  3246. @@ -304,20 +133,6 @@
  3247. return file_apprentice(ms, magicfile, FILE_LOAD);
  3248. }
  3249. -#ifndef COMPILE_ONLY
  3250. -/*
  3251. - * Install a set of compiled magic buffers.
  3252. - */
  3253. -public int
  3254. -magic_load_buffers(struct magic_set *ms, void **bufs, size_t *sizes,
  3255. - size_t nbufs)
  3256. -{
  3257. - if (ms == NULL)
  3258. - return -1;
  3259. - return buffer_apprentice(ms, (struct magic **)bufs, sizes, nbufs);
  3260. -}
  3261. -#endif
  3262. -
  3263. public int
  3264. magic_compile(struct magic_set *ms, const char *magicfile)
  3265. {
  3266. @@ -344,7 +159,7 @@
  3267. private void
  3268. close_and_restore(const struct magic_set *ms, const char *name, int fd,
  3269. - const struct stat *sb)
  3270. + const zend_stat_t *sb)
  3271. {
  3272. if (fd == STDIN_FILENO || name == NULL)
  3273. return;
  3274. @@ -375,7 +190,6 @@
  3275. }
  3276. }
  3277. -#ifndef COMPILE_ONLY
  3278. /*
  3279. * find type of descriptor
  3280. @@ -385,7 +199,7 @@
  3281. {
  3282. if (ms == NULL)
  3283. return NULL;
  3284. - return file_or_fd(ms, NULL, fd);
  3285. + return file_or_stream(ms, NULL, NULL);
  3286. }
  3287. /*
  3288. @@ -396,31 +210,42 @@
  3289. {
  3290. if (ms == NULL)
  3291. return NULL;
  3292. - return file_or_fd(ms, inname, STDIN_FILENO);
  3293. + return file_or_stream(ms, inname, NULL);
  3294. +}
  3295. +
  3296. +public const char *
  3297. +magic_stream(struct magic_set *ms, php_stream *stream)
  3298. +{
  3299. + if (ms == NULL)
  3300. + return NULL;
  3301. + return file_or_stream(ms, NULL, stream);
  3302. }
  3303. private const char *
  3304. -file_or_fd(struct magic_set *ms, const char *inname, int fd)
  3305. +file_or_stream(struct magic_set *ms, const char *inname, php_stream *stream)
  3306. {
  3307. int rv = -1;
  3308. unsigned char *buf;
  3309. - struct stat sb;
  3310. + zend_stat_t sb;
  3311. ssize_t nbytes = 0; /* number of bytes read from a datafile */
  3312. - int ispipe = 0;
  3313. - off_t pos = (off_t)-1;
  3314. + int no_in_stream = 0;
  3315. if (file_reset(ms, 1) == -1)
  3316. goto out;
  3317. + if (!inname && !stream) {
  3318. + return NULL;
  3319. + }
  3320. +
  3321. /*
  3322. * one extra for terminating '\0', and
  3323. * some overlapping space for matches near EOF
  3324. */
  3325. #define SLOP (1 + sizeof(union VALUETYPE))
  3326. - if ((buf = CAST(unsigned char *, malloc(ms->bytes_max + SLOP))) == NULL)
  3327. + if ((buf = CAST(unsigned char *, emalloc(ms->bytes_max + SLOP))) == NULL)
  3328. return NULL;
  3329. - switch (file_fsmagic(ms, inname, &sb)) {
  3330. + switch (file_fsmagic(ms, inname, &sb, stream)) {
  3331. case -1: /* error */
  3332. goto done;
  3333. case 0: /* nothing found */
  3334. @@ -430,103 +255,41 @@
  3335. goto done;
  3336. }
  3337. -#ifdef WIN32
  3338. - /* Place stdin in binary mode, so EOF (Ctrl+Z) doesn't stop early. */
  3339. - if (fd == STDIN_FILENO)
  3340. - _setmode(STDIN_FILENO, O_BINARY);
  3341. -#endif
  3342. -
  3343. - if (inname == NULL) {
  3344. - if (fstat(fd, &sb) == 0 && S_ISFIFO(sb.st_mode))
  3345. - ispipe = 1;
  3346. - else
  3347. - pos = lseek(fd, (off_t)0, SEEK_CUR);
  3348. - } else {
  3349. - int flags = O_RDONLY|O_BINARY;
  3350. - int okstat = stat(inname, &sb) == 0;
  3351. + errno = 0;
  3352. - if (okstat && S_ISFIFO(sb.st_mode)) {
  3353. -#ifdef O_NONBLOCK
  3354. - flags |= O_NONBLOCK;
  3355. -#endif
  3356. - ispipe = 1;
  3357. - }
  3358. + if (!stream && inname) {
  3359. + no_in_stream = 1;
  3360. + stream = php_stream_open_wrapper((char *)inname, "rb", REPORT_ERRORS, NULL);
  3361. + }
  3362. - errno = 0;
  3363. - if ((fd = open(inname, flags)) < 0) {
  3364. -#ifdef WIN32
  3365. - /*
  3366. - * Can't stat, can't open. It may have been opened in
  3367. - * fsmagic, so if the user doesn't have read permission,
  3368. - * allow it to say so; otherwise an error was probably
  3369. - * displayed in fsmagic.
  3370. - */
  3371. - if (!okstat && errno == EACCES) {
  3372. - sb.st_mode = S_IFBLK;
  3373. - okstat = 1;
  3374. - }
  3375. -#endif
  3376. - if (okstat &&
  3377. - unreadable_info(ms, sb.st_mode, inname) == -1)
  3378. - goto done;
  3379. - rv = 0;
  3380. + if (!stream) {
  3381. + if (unreadable_info(ms, sb.st_mode, inname) == -1)
  3382. goto done;
  3383. - }
  3384. + rv = 0;
  3385. + goto done;
  3386. + }
  3387. +
  3388. #ifdef O_NONBLOCK
  3389. - if ((flags = fcntl(fd, F_GETFL)) != -1) {
  3390. - flags &= ~O_NONBLOCK;
  3391. - (void)fcntl(fd, F_SETFL, flags);
  3392. - }
  3393. +/* we should be already be in non blocking mode for network socket */
  3394. #endif
  3395. - }
  3396. /*
  3397. * try looking at the first ms->bytes_max bytes
  3398. */
  3399. - if (ispipe) {
  3400. - ssize_t r = 0;
  3401. -
  3402. - while ((r = sread(fd, (void *)&buf[nbytes],
  3403. - (size_t)(ms->bytes_max - nbytes), 1)) > 0) {
  3404. - nbytes += r;
  3405. - if (r < PIPE_BUF) break;
  3406. - }
  3407. -
  3408. - if (nbytes == 0 && inname) {
  3409. - /* We can not read it, but we were able to stat it. */
  3410. - if (unreadable_info(ms, sb.st_mode, inname) == -1)
  3411. - goto done;
  3412. - rv = 0;
  3413. - goto done;
  3414. - }
  3415. -
  3416. - } else {
  3417. - /* Windows refuses to read from a big console buffer. */
  3418. - size_t howmany =
  3419. -#if defined(WIN32)
  3420. - _isatty(fd) ? 8 * 1024 :
  3421. -#endif
  3422. - ms->bytes_max;
  3423. - if ((nbytes = read(fd, (char *)buf, howmany)) == -1) {
  3424. - if (inname == NULL && fd != STDIN_FILENO)
  3425. - file_error(ms, errno, "cannot read fd %d", fd);
  3426. - else
  3427. - file_error(ms, errno, "cannot read `%s'",
  3428. - inname == NULL ? "/dev/stdin" : inname);
  3429. - goto done;
  3430. - }
  3431. + if ((nbytes = php_stream_read(stream, (char *)buf, ms->bytes_max - nbytes)) < 0) {
  3432. + file_error(ms, errno, "cannot read `%s'", inname);
  3433. + goto done;
  3434. }
  3435. (void)memset(buf + nbytes, 0, SLOP); /* NUL terminate */
  3436. - if (file_buffer(ms, fd, inname, buf, (size_t)nbytes) == -1)
  3437. + if (file_buffer(ms, stream, inname, buf, (size_t)nbytes) == -1)
  3438. goto done;
  3439. rv = 0;
  3440. done:
  3441. - free(buf);
  3442. - if (fd != -1) {
  3443. - if (pos != (off_t)-1)
  3444. - (void)lseek(fd, pos, SEEK_SET);
  3445. - close_and_restore(ms, inname, fd, &sb);
  3446. + efree(buf);
  3447. +
  3448. + if (no_in_stream && stream) {
  3449. + php_stream_close(stream);
  3450. }
  3451. out:
  3452. return rv == 0 ? file_getbuffer(ms) : NULL;
  3453. @@ -544,12 +307,11 @@
  3454. * The main work is done here!
  3455. * We have the file name and/or the data buffer to be identified.
  3456. */
  3457. - if (file_buffer(ms, -1, NULL, buf, nb) == -1) {
  3458. + if (file_buffer(ms, NULL, NULL, buf, nb) == -1) {
  3459. return NULL;
  3460. }
  3461. return file_getbuffer(ms);
  3462. }
  3463. -#endif
  3464. public const char *
  3465. magic_error(struct magic_set *ms)
  3466. diff -u libmagic.orig/magic.h libmagic/magic.h
  3467. --- libmagic.orig/magic.h 2020-02-26 09:56:58.945274100 +0100
  3468. +++ libmagic/magic.h 2020-02-26 09:55:13.862044300 +0100
  3469. @@ -122,6 +122,7 @@
  3470. const char *magic_getpath(const char *, int);
  3471. const char *magic_file(magic_t, const char *);
  3472. +const char *magic_stream(magic_t, php_stream *);
  3473. const char *magic_descriptor(magic_t, int);
  3474. const char *magic_buffer(magic_t, const void *, size_t);
  3475. diff -u libmagic.orig/print.c libmagic/print.c
  3476. --- libmagic.orig/print.c 2017-02-10 19:14:01.000000000 +0100
  3477. +++ libmagic/print.c 2020-02-26 09:55:13.864043900 +0100
  3478. @@ -2,7 +2,7 @@
  3479. * Copyright (c) Ian F. Darwin 1986-1995.
  3480. * Software written by Ian F. Darwin and others;
  3481. * maintained 1995-present by Christos Zoulas and others.
  3482. - *
  3483. + *
  3484. * Redistribution and use in source and binary forms, with or without
  3485. * modification, are permitted provided that the following conditions
  3486. * are met:
  3487. @@ -12,7 +12,7 @@
  3488. * 2. Redistributions in binary form must reproduce the above copyright
  3489. * notice, this list of conditions and the following disclaimer in the
  3490. * documentation and/or other materials provided with the distribution.
  3491. - *
  3492. + *
  3493. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  3494. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  3495. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  3496. @@ -28,6 +28,7 @@
  3497. /*
  3498. * print.c - debugging printout routines
  3499. */
  3500. +#include "php.h"
  3501. #include "file.h"
  3502. @@ -75,7 +76,7 @@
  3503. if (m->mask_op & FILE_OPINVERSE)
  3504. (void) fputc('~', stderr);
  3505. - if (IS_STRING(m->type)) {
  3506. + if (IS_LIBMAGIC_STRING(m->type)) {
  3507. if (m->str_flags) {
  3508. (void) fputc('/', stderr);
  3509. if (m->str_flags & STRING_COMPACT_WHITESPACE)
  3510. @@ -215,18 +216,18 @@
  3511. file_magwarn(struct magic_set *ms, const char *f, ...)
  3512. {
  3513. va_list va;
  3514. + char *expanded_format = NULL;
  3515. + int expanded_len;
  3516. - /* cuz we use stdout for most, stderr here */
  3517. - (void) fflush(stdout);
  3518. -
  3519. - if (ms->file)
  3520. - (void) fprintf(stderr, "%s, %lu: ", ms->file,
  3521. - (unsigned long)ms->line);
  3522. - (void) fprintf(stderr, "Warning: ");
  3523. va_start(va, f);
  3524. - (void) vfprintf(stderr, f, va);
  3525. + expanded_len = vasprintf(&expanded_format, f, va);
  3526. va_end(va);
  3527. - (void) fputc('\n', stderr);
  3528. +
  3529. + if (expanded_len >= 0 && expanded_format) {
  3530. + php_error_docref(NULL, E_NOTICE, "Warning: %s", expanded_format);
  3531. +
  3532. + free(expanded_format);
  3533. + }
  3534. }
  3535. protected const char *
  3536. @@ -247,13 +248,13 @@
  3537. }
  3538. if (flags & FILE_T_LOCAL) {
  3539. - tm = localtime_r(&t, &tmz);
  3540. + tm = php_localtime_r(&t, &tmz);
  3541. } else {
  3542. - tm = gmtime_r(&t, &tmz);
  3543. + tm = php_gmtime_r(&t, &tmz);
  3544. }
  3545. if (tm == NULL)
  3546. goto out;
  3547. - pp = asctime_r(tm, buf);
  3548. + pp = php_asctime_r(tm, buf);
  3549. if (pp == NULL)
  3550. goto out;
  3551. diff -u libmagic.orig/readcdf.c libmagic/readcdf.c
  3552. --- libmagic.orig/readcdf.c 2017-11-02 21:25:39.000000000 +0100
  3553. +++ libmagic/readcdf.c 2020-02-26 09:55:13.865044100 +0100
  3554. @@ -31,7 +31,11 @@
  3555. #include <assert.h>
  3556. #include <stdlib.h>
  3557. +#ifdef PHP_WIN32
  3558. +#include "win32/unistd.h"
  3559. +#else
  3560. #include <unistd.h>
  3561. +#endif
  3562. #include <string.h>
  3563. #include <time.h>
  3564. #include <ctype.h>
  3565. @@ -104,10 +108,6 @@
  3566. if (clsid[0] == cv[i].clsid[0] && clsid[1] == cv[i].clsid[1])
  3567. return cv[i].mime;
  3568. }
  3569. -#ifdef CDF_DEBUG
  3570. - fprintf(stderr, "unknown mime %" PRIx64 ", %" PRIx64 "\n", clsid[0],
  3571. - clsid[1]);
  3572. -#endif
  3573. return NULL;
  3574. }
  3575. @@ -116,30 +116,24 @@
  3576. {
  3577. size_t i;
  3578. const char *rv = NULL;
  3579. -#ifdef USE_C_LOCALE
  3580. - locale_t old_lc_ctype, c_lc_ctype;
  3581. + char *vbuf_lower;
  3582. - c_lc_ctype = newlocale(LC_CTYPE_MASK, "C", 0);
  3583. - assert(c_lc_ctype != NULL);
  3584. - old_lc_ctype = uselocale(c_lc_ctype);
  3585. - assert(old_lc_ctype != NULL);
  3586. -#else
  3587. - char *old_lc_ctype = setlocale(LC_CTYPE, "C");
  3588. -#endif
  3589. - for (i = 0; nv[i].pattern != NULL; i++)
  3590. - if (strcasestr(vbuf, nv[i].pattern) != NULL) {
  3591. + vbuf_lower = zend_str_tolower_dup(vbuf, strlen(vbuf));
  3592. + for (i = 0; nv[i].pattern != NULL; i++) {
  3593. + char *pattern_lower;
  3594. + int found;
  3595. +
  3596. + pattern_lower = zend_str_tolower_dup(nv[i].pattern, strlen(nv[i].pattern));
  3597. + found = (strstr(vbuf_lower, pattern_lower) != NULL);
  3598. + efree(pattern_lower);
  3599. +
  3600. + if (found) {
  3601. rv = nv[i].mime;
  3602. break;
  3603. }
  3604. -#ifdef CDF_DEBUG
  3605. - fprintf(stderr, "unknown app %s\n", vbuf);
  3606. -#endif
  3607. -#ifdef USE_C_LOCALE
  3608. - (void)uselocale(old_lc_ctype);
  3609. - freelocale(c_lc_ctype);
  3610. -#else
  3611. - setlocale(LC_CTYPE, old_lc_ctype);
  3612. -#endif
  3613. + }
  3614. +
  3615. + efree(vbuf_lower);
  3616. return rv;
  3617. }
  3618. @@ -155,6 +149,8 @@
  3619. const char *s, *e;
  3620. int len;
  3621. + memset(&ts, 0, sizeof(ts));
  3622. +
  3623. if (!NOTMIME(ms) && root_storage)
  3624. str = cdf_clsid_to_mime(root_storage->d_storage_uuid,
  3625. clsid2mime);
  3626. @@ -281,10 +277,10 @@
  3627. if (file_printf(ms, "%s%s",
  3628. cdf_u16tos8(buf, ce[i].ce_namlen, ce[i].ce_name),
  3629. i == cat->cat_num - 1 ? "]" : ", ") == -1) {
  3630. - free(cat);
  3631. + efree(cat);
  3632. return -1;
  3633. }
  3634. - free(cat);
  3635. + efree(cat);
  3636. } else {
  3637. if (file_printf(ms, "application/CDFV2") == -1)
  3638. return -1;
  3639. @@ -345,7 +341,7 @@
  3640. }
  3641. m = cdf_file_property_info(ms, info, count, root_storage);
  3642. - free(info);
  3643. + efree(info);
  3644. return m == -1 ? -2 : m;
  3645. }
  3646. @@ -353,11 +349,11 @@
  3647. #ifdef notdef
  3648. private char *
  3649. format_clsid(char *buf, size_t len, const uint64_t uuid[2]) {
  3650. - snprintf(buf, len, "%.8" PRIx64 "-%.4" PRIx64 "-%.4" PRIx64 "-%.4"
  3651. + snprintf(buf, len, "%.8" PRIx64 "-%.4" PRIx64 "-%.4" PRIx64 "-%.4"
  3652. PRIx64 "-%.12" PRIx64,
  3653. (uuid[0] >> 32) & (uint64_t)0x000000000ffffffffULL,
  3654. (uuid[0] >> 16) & (uint64_t)0x0000000000000ffffULL,
  3655. - (uuid[0] >> 0) & (uint64_t)0x0000000000000ffffULL,
  3656. + (uuid[0] >> 0) & (uint64_t)0x0000000000000ffffULL,
  3657. (uuid[1] >> 48) & (uint64_t)0x0000000000000ffffULL,
  3658. (uuid[1] >> 0) & (uint64_t)0x0000fffffffffffffULL);
  3659. return buf;
  3660. @@ -436,7 +432,7 @@
  3661. const char *sections[5];
  3662. const int types[5];
  3663. } sectioninfo[] = {
  3664. - { "Encrypted", "encrypted",
  3665. + { "Encrypted", "encrypted",
  3666. {
  3667. "EncryptedPackage", "EncryptedSummary",
  3668. NULL, NULL, NULL,
  3669. @@ -448,7 +444,7 @@
  3670. },
  3671. },
  3672. - { "QuickBooks", "quickbooks",
  3673. + { "QuickBooks", "quickbooks",
  3674. {
  3675. #if 0
  3676. "TaxForms", "PDFTaxForms", "modulesInBackup",
  3677. @@ -655,11 +651,11 @@
  3678. cdf_zero_stream(&scn);
  3679. cdf_zero_stream(&sst);
  3680. out3:
  3681. - free(dir.dir_tab);
  3682. + efree(dir.dir_tab);
  3683. out2:
  3684. - free(ssat.sat_tab);
  3685. + efree(ssat.sat_tab);
  3686. out1:
  3687. - free(sat.sat_tab);
  3688. + efree(sat.sat_tab);
  3689. out0:
  3690. if (i == -1) {
  3691. if (NOTMIME(ms)) {
  3692. diff -u libmagic.orig/softmagic.c libmagic/softmagic.c
  3693. --- libmagic.orig/softmagic.c 2018-04-15 20:49:15.000000000 +0200
  3694. +++ libmagic/softmagic.c 2020-02-26 09:55:13.866043500 +0100
  3695. @@ -43,6 +43,10 @@
  3696. #include <time.h>
  3697. #include "der.h"
  3698. +#ifndef PREG_OFFSET_CAPTURE
  3699. +# define PREG_OFFSET_CAPTURE (1<<8)
  3700. +#endif
  3701. +
  3702. private int match(struct magic_set *, struct magic *, uint32_t,
  3703. const struct buffer *, size_t, int, int, int, uint16_t *,
  3704. uint16_t *, int *, int *, int *);
  3705. @@ -119,8 +123,8 @@
  3706. return 0;
  3707. }
  3708. -#define FILE_FMTDEBUG
  3709. -#ifdef FILE_FMTDEBUG
  3710. +
  3711. +#if defined(FILE_FMTDEBUG) && defined(HAVE_FMTCHECK)
  3712. #define F(a, b, c) file_fmtcheck((a), (b), (c), __FILE__, __LINE__)
  3713. private const char * __attribute__((__format_arg__(3)))
  3714. @@ -134,8 +138,10 @@
  3715. " with `%s'", file, line, desc, def);
  3716. return ptr;
  3717. }
  3718. -#else
  3719. +#elif defined(HAVE_FMTCHECK)
  3720. #define F(a, b, c) fmtcheck((b), (c))
  3721. +#else
  3722. +#define F(a, b, c) ((b))
  3723. #endif
  3724. /*
  3725. @@ -189,7 +195,7 @@
  3726. struct magic *m = &magic[magindex];
  3727. if (m->type != FILE_NAME)
  3728. - if ((IS_STRING(m->type) &&
  3729. + if ((IS_LIBMAGIC_STRING(m->type) &&
  3730. #define FLT (STRING_BINTEST | STRING_TEXTTEST)
  3731. ((text && (m->str_flags & FLT) == STRING_BINTEST) ||
  3732. (!text && (m->str_flags & FLT) == STRING_TEXTTEST))) ||
  3733. @@ -416,42 +422,28 @@
  3734. private int
  3735. check_fmt(struct magic_set *ms, const char *fmt)
  3736. {
  3737. - file_regex_t rx;
  3738. - int rc, rv = -1;
  3739. + pcre_cache_entry *pce;
  3740. + int rv = -1;
  3741. + zend_string *pattern;
  3742. if (strchr(fmt, '%') == NULL)
  3743. return 0;
  3744. - rc = file_regcomp(&rx, "%[-0-9\\.]*s", REG_EXTENDED|REG_NOSUB);
  3745. - if (rc) {
  3746. - file_regerror(&rx, rc, ms);
  3747. + pattern = zend_string_init("~%[-0-9\\.]*s~", sizeof("~%[-0-9\\.]*s~") - 1, 0);
  3748. + if ((pce = pcre_get_compiled_regex_cache_ex(pattern, 0)) == NULL) {
  3749. + rv = -1;
  3750. } else {
  3751. - rc = file_regexec(&rx, fmt, 0, 0, 0);
  3752. - rv = !rc;
  3753. + pcre2_code *re = php_pcre_pce_re(pce);
  3754. + pcre2_match_data *match_data = php_pcre_create_match_data(0, re);
  3755. + if (match_data) {
  3756. + rv = pcre2_match(re, (PCRE2_SPTR)fmt, strlen(fmt), 0, 0, match_data, php_pcre_mctx()) > 0;
  3757. + php_pcre_free_match_data(match_data);
  3758. + }
  3759. }
  3760. - file_regfree(&rx);
  3761. + zend_string_release(pattern);
  3762. return rv;
  3763. }
  3764. -#ifndef HAVE_STRNDUP
  3765. -char * strndup(const char *, size_t);
  3766. -
  3767. -char *
  3768. -strndup(const char *str, size_t n)
  3769. -{
  3770. - size_t len;
  3771. - char *copy;
  3772. -
  3773. - for (len = 0; len < n && str[len]; len++)
  3774. - continue;
  3775. - if ((copy = malloc(len + 1)) == NULL)
  3776. - return NULL;
  3777. - (void)memcpy(copy, str, len);
  3778. - copy[len] = '\0';
  3779. - return copy;
  3780. -}
  3781. -#endif /* HAVE_STRNDUP */
  3782. -
  3783. static int
  3784. varexpand(char *buf, size_t len, const struct buffer *b, const char *str)
  3785. {
  3786. @@ -743,14 +735,10 @@
  3787. char *cp;
  3788. int rval;
  3789. - cp = strndup((const char *)ms->search.s, ms->search.rm_len);
  3790. - if (cp == NULL) {
  3791. - file_oomem(ms, ms->search.rm_len);
  3792. - return -1;
  3793. - }
  3794. + cp = estrndup((const char *)ms->search.s, ms->search.rm_len);
  3795. rval = file_printf(ms, F(ms, desc, "%s"),
  3796. file_printable(sbuf, sizeof(sbuf), cp));
  3797. - free(cp);
  3798. + efree(cp);
  3799. if (rval == -1)
  3800. return -1;
  3801. @@ -1135,7 +1123,7 @@
  3802. * string by p->s, so we need to deduct sz.
  3803. * Because we can use one of the bytes of the length
  3804. * after we shifted as NUL termination.
  3805. - */
  3806. + */
  3807. len = sz;
  3808. }
  3809. while (len--)
  3810. @@ -1209,7 +1197,7 @@
  3811. goto out;
  3812. return 1;
  3813. case FILE_BEDOUBLE:
  3814. - p->q = BE64(p);
  3815. + p->q = BE64(p);
  3816. if (cvt_double(p, m) == -1)
  3817. goto out;
  3818. return 1;
  3819. @@ -1481,8 +1469,6 @@
  3820. return -1;
  3821. }
  3822. -
  3823. -
  3824. if (mcopy(ms, p, m->type, m->flag & INDIR, s, (uint32_t)(offset + o),
  3825. (uint32_t)nbytes, m) == -1)
  3826. return -1;
  3827. @@ -1494,9 +1480,6 @@
  3828. m->type, m->flag, offset, o, nbytes,
  3829. *indir_count, *name_count);
  3830. mdebug(offset, (char *)(void *)p, sizeof(union VALUETYPE));
  3831. -#ifndef COMPILE_ONLY
  3832. - file_mdump(m);
  3833. -#endif
  3834. }
  3835. if (m->flag & INDIR) {
  3836. @@ -1609,9 +1592,6 @@
  3837. if ((ms->flags & MAGIC_DEBUG) != 0) {
  3838. mdebug(offset, (char *)(void *)p,
  3839. sizeof(union VALUETYPE));
  3840. -#ifndef COMPILE_ONLY
  3841. - file_mdump(m);
  3842. -#endif
  3843. }
  3844. }
  3845. @@ -1696,15 +1676,15 @@
  3846. if (rv == 1) {
  3847. if ((ms->flags & MAGIC_NODESC) == 0 &&
  3848. file_printf(ms, F(ms, m->desc, "%u"), offset) == -1) {
  3849. - free(rbuf);
  3850. + if (rbuf) efree(rbuf);
  3851. return -1;
  3852. }
  3853. if (file_printf(ms, "%s", rbuf) == -1) {
  3854. - free(rbuf);
  3855. + if (rbuf) efree(rbuf);
  3856. return -1;
  3857. }
  3858. }
  3859. - free(rbuf);
  3860. + if (rbuf) efree(rbuf);
  3861. return rv;
  3862. case FILE_USE:
  3863. @@ -1827,6 +1807,41 @@
  3864. return file_strncmp(a, b, len, flags);
  3865. }
  3866. +public void
  3867. +convert_libmagic_pattern(zval *pattern, char *val, size_t len, uint32_t options)
  3868. +{
  3869. + int i, j=0;
  3870. + zend_string *t;
  3871. +
  3872. + t = zend_string_alloc(len * 2 + 4, 0);
  3873. +
  3874. + ZSTR_VAL(t)[j++] = '~';
  3875. +
  3876. + for (i = 0; i < len; i++, j++) {
  3877. + switch (val[i]) {
  3878. + case '~':
  3879. + ZSTR_VAL(t)[j++] = '\\';
  3880. + ZSTR_VAL(t)[j] = '~';
  3881. + break;
  3882. + default:
  3883. + ZSTR_VAL(t)[j] = val[i];
  3884. + break;
  3885. + }
  3886. + }
  3887. + ZSTR_VAL(t)[j++] = '~';
  3888. +
  3889. + if (options & PCRE2_CASELESS)
  3890. + ZSTR_VAL(t)[j++] = 'i';
  3891. +
  3892. + if (options & PCRE2_MULTILINE)
  3893. + ZSTR_VAL(t)[j++] = 'm';
  3894. +
  3895. + ZSTR_VAL(t)[j]='\0';
  3896. + ZSTR_LEN(t) = j;
  3897. +
  3898. + ZVAL_NEW_STR(pattern, t);
  3899. +}
  3900. +
  3901. private int
  3902. magiccheck(struct magic_set *ms, struct magic *m)
  3903. {
  3904. @@ -1987,65 +2002,77 @@
  3905. break;
  3906. }
  3907. case FILE_REGEX: {
  3908. - int rc;
  3909. - file_regex_t rx;
  3910. - const char *search;
  3911. + zval pattern;
  3912. + uint32_t options = 0;
  3913. + pcre_cache_entry *pce;
  3914. - if (ms->search.s == NULL)
  3915. - return 0;
  3916. + options |= PCRE2_MULTILINE;
  3917. - l = 0;
  3918. - rc = file_regcomp(&rx, m->value.s,
  3919. - REG_EXTENDED|REG_NEWLINE|
  3920. - ((m->str_flags & STRING_IGNORE_CASE) ? REG_ICASE : 0));
  3921. - if (rc) {
  3922. - file_regerror(&rx, rc, ms);
  3923. - v = (uint64_t)-1;
  3924. + if (m->str_flags & STRING_IGNORE_CASE) {
  3925. + options |= PCRE2_CASELESS;
  3926. + }
  3927. +
  3928. + convert_libmagic_pattern(&pattern, (char *)m->value.s, m->vallen, options);
  3929. +
  3930. + l = v = 0;
  3931. + if ((pce = pcre_get_compiled_regex_cache(Z_STR(pattern))) == NULL) {
  3932. + zval_ptr_dtor(&pattern);
  3933. + return -1;
  3934. } else {
  3935. - regmatch_t pmatch;
  3936. - size_t slen = ms->search.s_len;
  3937. - char *copy;
  3938. - if (slen != 0) {
  3939. - copy = CAST(char *, malloc(slen));
  3940. - if (copy == NULL) {
  3941. - file_regfree(&rx);
  3942. - file_error(ms, errno,
  3943. - "can't allocate %" SIZE_T_FORMAT "u bytes",
  3944. - slen);
  3945. - return -1;
  3946. - }
  3947. - memcpy(copy, ms->search.s, slen);
  3948. - copy[--slen] = '\0';
  3949. - search = copy;
  3950. + /* pce now contains the compiled regex */
  3951. + zval retval;
  3952. + zval subpats;
  3953. + char *haystack;
  3954. +
  3955. + ZVAL_NULL(&retval);
  3956. + ZVAL_NULL(&subpats);
  3957. +
  3958. + /* Cut the search len from haystack, equals to REG_STARTEND */
  3959. + haystack = estrndup(ms->search.s, ms->search.s_len);
  3960. +
  3961. + /* match v = 0, no match v = 1 */
  3962. + php_pcre_match_impl(pce, haystack, ms->search.s_len, &retval, &subpats, 0, 1, PREG_OFFSET_CAPTURE, 0);
  3963. + /* Free haystack */
  3964. + efree(haystack);
  3965. +
  3966. + if (Z_LVAL(retval) < 0) {
  3967. + zval_ptr_dtor(&subpats);
  3968. + zval_ptr_dtor(&pattern);
  3969. + return -1;
  3970. + } else if ((Z_LVAL(retval) > 0) && (Z_TYPE(subpats) == IS_ARRAY)) {
  3971. + /* Need to fetch global match which equals pmatch[0] */
  3972. + zval *pzval;
  3973. + HashTable *ht = Z_ARRVAL(subpats);
  3974. + if ((pzval = zend_hash_index_find(ht, 0)) != NULL && Z_TYPE_P(pzval) == IS_ARRAY) {
  3975. + /* If everything goes according to the master plan
  3976. + tmpcopy now contains two elements:
  3977. + 0 = the match
  3978. + 1 = starting position of the match */
  3979. + zval *match, *offset;
  3980. + if ((match = zend_hash_index_find(Z_ARRVAL_P(pzval), 0)) &&
  3981. + (offset = zend_hash_index_find(Z_ARRVAL_P(pzval), 1))) {
  3982. + if (Z_TYPE_P(match) != IS_STRING && Z_TYPE_P(offset) != IS_LONG) {
  3983. + goto error_out;
  3984. + }
  3985. + ms->search.s += Z_LVAL_P(offset); /* this is where the match starts */
  3986. + ms->search.offset += Z_LVAL_P(offset); /* this is where the match starts as size_t */
  3987. + ms->search.rm_len = Z_STRLEN_P(match) /* This is the length of the matched pattern */;
  3988. + v = 0;
  3989. + } else {
  3990. + goto error_out;
  3991. + }
  3992. + } else {
  3993. +error_out:
  3994. + zval_ptr_dtor(&subpats);
  3995. + zval_ptr_dtor(&pattern);
  3996. + return -1;
  3997. + }
  3998. } else {
  3999. - search = CCAST(char *, "");
  4000. - copy = NULL;
  4001. - }
  4002. - rc = file_regexec(&rx, (const char *)search,
  4003. - 1, &pmatch, 0);
  4004. - free(copy);
  4005. - switch (rc) {
  4006. - case 0:
  4007. - ms->search.s += (int)pmatch.rm_so;
  4008. - ms->search.offset += (size_t)pmatch.rm_so;
  4009. - ms->search.rm_len =
  4010. - (size_t)(pmatch.rm_eo - pmatch.rm_so);
  4011. - v = 0;
  4012. - break;
  4013. -
  4014. - case REG_NOMATCH:
  4015. v = 1;
  4016. - break;
  4017. -
  4018. - default:
  4019. - file_regerror(&rx, rc, ms);
  4020. - v = (uint64_t)-1;
  4021. - break;
  4022. }
  4023. + zval_ptr_dtor(&subpats);
  4024. + zval_ptr_dtor(&pattern);
  4025. }
  4026. - file_regfree(&rx);
  4027. - if (v == (uint64_t)-1)
  4028. - return -1;
  4029. break;
  4030. }
  4031. case FILE_INDIRECT:
  4032. diff -u libmagic.orig/strcasestr.c libmagic/strcasestr.c
  4033. --- libmagic.orig/strcasestr.c 2014-05-13 18:48:12.000000000 +0200
  4034. +++ libmagic/strcasestr.c 2019-04-02 11:56:06.853152400 +0200
  4035. @@ -39,6 +39,8 @@
  4036. #include "file.h"
  4037. +#include "php_stdint.h"
  4038. +
  4039. #include <assert.h>
  4040. #include <ctype.h>
  4041. #include <string.h>