12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277 |
- diff -u libmagic.orig/apprentice.c libmagic/apprentice.c
- --- libmagic.orig/apprentice.c 2018-03-11 01:46:42.000000000 +0100
- +++ libmagic/apprentice.c 2020-02-26 09:55:13.842042400 +0100
- @@ -2,7 +2,7 @@
- * Copyright (c) Ian F. Darwin 1986-1995.
- * Software written by Ian F. Darwin and others;
- * maintained 1995-present by Christos Zoulas and others.
- - *
- + *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- @@ -12,7 +12,7 @@
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- - *
- + *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- @@ -29,6 +29,8 @@
- * apprentice - make one pass through /etc/magic, learning its secrets.
- */
-
- +#include "php.h"
- +
- #include "file.h"
-
- #ifndef lint
- @@ -36,24 +38,27 @@
- #endif /* lint */
-
- #include "magic.h"
- +#include "patchlevel.h"
- #include <stdlib.h>
- -#ifdef HAVE_UNISTD_H
- -#include <unistd.h>
- +
- +#if defined(__hpux) && !defined(HAVE_STRTOULL)
- +#if SIZEOF_LONG == 8
- +# define strtoull strtoul
- +#else
- +# define strtoull __strtoull
- #endif
- -#ifdef HAVE_STDDEF_H
- -#include <stddef.h>
- +#endif
- +
- +#ifdef PHP_WIN32
- +#include "win32/unistd.h"
- +#define strtoull _strtoui64
- +#else
- +#include <unistd.h>
- #endif
- #include <string.h>
- #include <assert.h>
- #include <ctype.h>
- #include <fcntl.h>
- -#ifdef QUICK
- -#include <sys/mman.h>
- -#endif
- -#include <dirent.h>
- -#if defined(HAVE_LIMITS_H)
- -#include <limits.h>
- -#endif
-
- #ifndef SSIZE_MAX
- #define MAXMAGIC_SIZE ((ssize_t)0x7fffffff)
- @@ -75,6 +80,10 @@
- #endif
- #endif
-
- +#ifndef offsetof
- +#define offsetof(STRUCTURE,FIELD) ((int)((char*)&((STRUCTURE*)0)->FIELD))
- +#endif
- +
- #ifndef MAP_FAILED
- #define MAP_FAILED (void *) -1
- #endif
- @@ -91,7 +100,7 @@
- #define MAP_TYPE_MMAP 2
-
- struct magic_entry {
- - struct magic *mp;
- + struct magic *mp;
- uint32_t cont_count;
- uint32_t max_count;
- };
- @@ -126,7 +135,7 @@
- private size_t apprentice_magic_strength(const struct magic *);
- private int apprentice_sort(const void *, const void *);
- private void apprentice_list(struct mlist *, int );
- -private struct magic_map *apprentice_load(struct magic_set *,
- +private struct magic_map *apprentice_load(struct magic_set *,
- const char *, int);
- private struct mlist *mlist_alloc(void);
- private void mlist_free(struct mlist *);
- @@ -170,38 +179,7 @@
- { NULL, 0, NULL }
- };
-
- -#ifdef COMPILE_ONLY
- -
- -int main(int, char *[]);
- -
- -int
- -main(int argc, char *argv[])
- -{
- - int ret;
- - struct magic_set *ms;
- - char *progname;
- -
- - if ((progname = strrchr(argv[0], '/')) != NULL)
- - progname++;
- - else
- - progname = argv[0];
- -
- - if (argc != 2) {
- - (void)fprintf(stderr, "Usage: %s file\n", progname);
- - return 1;
- - }
- -
- - if ((ms = magic_open(MAGIC_CHECK)) == NULL) {
- - (void)fprintf(stderr, "%s: %s\n", progname, strerror(errno));
- - return 1;
- - }
- - ret = magic_compile(ms, argv[1]) == -1 ? 1 : 0;
- - if (ret == 1)
- - (void)fprintf(stderr, "%s: %s\n", progname, magic_error(ms));
- - magic_close(ms);
- - return ret;
- -}
- -#endif /* COMPILE_ONLY */
- +#include "../data_file.c"
-
- struct type_tbl_s {
- const char name[16];
- @@ -409,7 +387,7 @@
- struct mlist *ml;
-
- mlp->map = NULL;
- - if ((ml = CAST(struct mlist *, malloc(sizeof(*ml)))) == NULL)
- + if ((ml = CAST(struct mlist *, emalloc(sizeof(*ml)))) == NULL)
- return -1;
-
- ml->map = idx == 0 ? map : NULL;
- @@ -430,10 +408,8 @@
- apprentice_1(struct magic_set *ms, const char *fn, int action)
- {
- struct magic_map *map;
- -#ifndef COMPILE_ONLY
- struct mlist *ml;
- size_t i;
- -#endif
-
- if (magicsize != FILE_MAGICSIZE) {
- file_error(ms, 0, "magic element size %lu != %lu",
- @@ -449,14 +425,15 @@
- return apprentice_compile(ms, map, fn);
- }
-
- -#ifndef COMPILE_ONLY
- map = apprentice_map(ms, fn);
- if (map == (struct magic_map *)-1)
- return -1;
- if (map == NULL) {
- - if (ms->flags & MAGIC_CHECK)
- - file_magwarn(ms, "using regular magic file `%s'", fn);
- - map = apprentice_load(ms, fn, action);
- + if (fn) {
- + if (ms->flags & MAGIC_CHECK)
- + file_magwarn(ms, "using regular magic file `%s'", fn);
- + map = apprentice_load(ms, fn, action);
- + }
- if (map == NULL)
- return -1;
- }
- @@ -478,9 +455,6 @@
- }
- }
- return 0;
- -#else
- - return 0;
- -#endif /* COMPILE_ONLY */
- }
-
- protected void
- @@ -491,10 +465,16 @@
- return;
- for (i = 0; i < MAGIC_SETS; i++)
- mlist_free(ms->mlist[i]);
- - free(ms->o.pbuf);
- - free(ms->o.buf);
- - free(ms->c.li);
- - free(ms);
- + if (ms->o.pbuf) {
- + efree(ms->o.pbuf);
- + }
- + if (ms->o.buf) {
- + efree(ms->o.buf);
- + }
- + if (ms->c.li) {
- + efree(ms->c.li);
- + }
- + efree(ms);
- }
-
- protected struct magic_set *
- @@ -503,7 +483,7 @@
- struct magic_set *ms;
- size_t i, len;
-
- - if ((ms = CAST(struct magic_set *, calloc((size_t)1,
- + if ((ms = CAST(struct magic_set *, ecalloc((size_t)1,
- sizeof(struct magic_set)))) == NULL)
- return NULL;
-
- @@ -515,7 +495,7 @@
- ms->o.buf = ms->o.pbuf = NULL;
- len = (ms->c.len = 10) * sizeof(*ms->c.li);
-
- - if ((ms->c.li = CAST(struct level_info *, malloc(len))) == NULL)
- + if ((ms->c.li = CAST(struct level_info *, emalloc(len))) == NULL)
- goto free;
-
- ms->event_flags = 0;
- @@ -533,48 +513,35 @@
- ms->bytes_max = FILE_BYTES_MAX;
- return ms;
- free:
- - free(ms);
- + efree(ms);
- return NULL;
- }
-
- private void
- apprentice_unmap(struct magic_map *map)
- {
- - size_t i;
- if (map == NULL)
- return;
- -
- - switch (map->type) {
- - case MAP_TYPE_USER:
- - break;
- - case MAP_TYPE_MALLOC:
- - for (i = 0; i < MAGIC_SETS; i++) {
- - void *b = map->magic[i];
- - void *p = map->p;
- - if (CAST(char *, b) >= CAST(char *, p) &&
- - CAST(char *, b) <= CAST(char *, p) + map->len)
- - continue;
- - free(map->magic[i]);
- + if (map->p != php_magic_database) {
- + if (map->p == NULL) {
- + int j;
- + for (j = 0; j < MAGIC_SETS; j++) {
- + if (map->magic[j]) {
- + efree(map->magic[j]);
- + }
- + }
- + } else {
- + efree(map->p);
- }
- - free(map->p);
- - break;
- -#ifdef QUICK
- - case MAP_TYPE_MMAP:
- - if (map->p && map->p != MAP_FAILED)
- - (void)munmap(map->p, map->len);
- - break;
- -#endif
- - default:
- - abort();
- }
- - free(map);
- + efree(map);
- }
-
- private struct mlist *
- mlist_alloc(void)
- {
- struct mlist *mlist;
- - if ((mlist = CAST(struct mlist *, calloc(1, sizeof(*mlist)))) == NULL) {
- + if ((mlist = CAST(struct mlist *, ecalloc(1, sizeof(*mlist)))) == NULL) {
- return NULL;
- }
- mlist->next = mlist->prev = mlist;
- @@ -593,60 +560,12 @@
- for (ml = mlist->next; (next = ml->next) != NULL; ml = next) {
- if (ml->map)
- apprentice_unmap(CAST(struct magic_map *, ml->map));
- - free(ml);
- + efree(ml);
- if (ml == mlist)
- break;
- }
- }
-
- -#ifndef COMPILE_ONLY
- -/* void **bufs: an array of compiled magic files */
- -protected int
- -buffer_apprentice(struct magic_set *ms, struct magic **bufs,
- - size_t *sizes, size_t nbufs)
- -{
- - size_t i, j;
- - struct mlist *ml;
- - struct magic_map *map;
- -
- - if (nbufs == 0)
- - return -1;
- -
- - (void)file_reset(ms, 0);
- -
- - init_file_tables();
- -
- - for (i = 0; i < MAGIC_SETS; i++) {
- - mlist_free(ms->mlist[i]);
- - if ((ms->mlist[i] = mlist_alloc()) == NULL) {
- - file_oomem(ms, sizeof(*ms->mlist[i]));
- - goto fail;
- - }
- - }
- -
- - for (i = 0; i < nbufs; i++) {
- - map = apprentice_buf(ms, bufs[i], sizes[i]);
- - if (map == NULL)
- - goto fail;
- -
- - for (j = 0; j < MAGIC_SETS; j++) {
- - if (add_mlist(ms->mlist[j], map, j) == -1) {
- - file_oomem(ms, sizeof(*ml));
- - goto fail;
- - }
- - }
- - }
- -
- - return 0;
- -fail:
- - for (i = 0; i < MAGIC_SETS; i++) {
- - mlist_free(ms->mlist[i]);
- - ms->mlist[i] = NULL;
- - }
- - return -1;
- -}
- -#endif
- -
- /* const char *fn: list of magic files and directories */
- protected int
- file_apprentice(struct magic_set *ms, const char *fn, int action)
- @@ -655,14 +574,31 @@
- int fileerr, errs = -1;
- size_t i;
-
- - (void)file_reset(ms, 0);
- + if (ms->mlist[0] != NULL)
- + (void)file_reset(ms, 0);
-
- +/* XXX disabling default magic loading so the compiled in data is used */
- +#if 0
- if ((fn = magic_getpath(fn, action)) == NULL)
- return -1;
- +#endif
-
- init_file_tables();
-
- - if ((mfn = strdup(fn)) == NULL) {
- + if (fn == NULL)
- + fn = getenv("MAGIC");
- + if (fn == NULL) {
- + for (i = 0; i < MAGIC_SETS; i++) {
- + mlist_free(ms->mlist[i]);
- + if ((ms->mlist[i] = mlist_alloc()) == NULL) {
- + file_oomem(ms, sizeof(*ms->mlist[i]));
- + return -1;
- + }
- + }
- + return apprentice_1(ms, fn, action);
- + }
- +
- + if ((mfn = estrdup(fn)) == NULL) {
- file_oomem(ms, strlen(fn));
- return -1;
- }
- @@ -675,7 +611,7 @@
- mlist_free(ms->mlist[i]);
- ms->mlist[i] = NULL;
- }
- - free(mfn);
- + efree(mfn);
- return -1;
- }
- }
- @@ -692,7 +628,7 @@
- fn = p;
- }
-
- - free(mfn);
- + efree(mfn);
-
- if (errs == -1) {
- for (i = 0; i < MAGIC_SETS; i++) {
- @@ -974,7 +910,7 @@
- return val;
- }
-
- -/*
- +/*
- * Sort callback for sorting entries by "strength" (basically length)
- */
- private int
- @@ -992,7 +928,7 @@
- return 1;
- }
-
- -/*
- +/*
- * Shows sorted patterns list in the order which is used for the matching
- */
- private void
- @@ -1088,7 +1024,7 @@
- mstart->flag |= BINTEST;
- if (mstart->str_flags & STRING_TEXTTEST)
- mstart->flag |= TEXTTEST;
- -
- +
- if (mstart->flag & (TEXTTEST|BINTEST))
- break;
-
- @@ -1120,7 +1056,7 @@
-
- mset[i].max += ALLOC_INCR;
- if ((mp = CAST(struct magic_entry *,
- - realloc(mset[i].me, sizeof(*mp) * mset[i].max))) ==
- + erealloc(mset[i].me, sizeof(*mp) * mset[i].max))) ==
- NULL) {
- file_oomem(ms, sizeof(*mp) * mset[i].max);
- return -1;
- @@ -1141,13 +1077,19 @@
- load_1(struct magic_set *ms, int action, const char *fn, int *errs,
- struct magic_entry_set *mset)
- {
- - size_t lineno = 0, llen = 0;
- + char buffer[BUFSIZ + 1];
- char *line = NULL;
- - ssize_t len;
- + size_t len;
- + size_t lineno = 0;
- struct magic_entry me;
-
- - FILE *f = fopen(ms->file = fn, "r");
- - if (f == NULL) {
- + php_stream *stream;
- +
- +
- + ms->file = fn;
- + stream = php_stream_open_wrapper((char *)fn, "rb", REPORT_ERRORS, NULL);
- +
- + if (stream == NULL) {
- if (errno != ENOENT)
- file_error(ms, errno, "cannot read magic file `%s'",
- fn);
- @@ -1157,8 +1099,7 @@
-
- memset(&me, 0, sizeof(me));
- /* read and parse this file */
- - for (ms->line = 1; (len = getline(&line, &llen, f)) != -1;
- - ms->line++) {
- + for (ms->line = 1; (line = php_stream_get_line(stream, buffer , BUFSIZ, &len)) != NULL; ms->line++) {
- if (len == 0) /* null line, garbage, etc */
- continue;
- if (line[len - 1] == '\n') {
- @@ -1216,8 +1157,8 @@
- }
- if (me.mp)
- (void)addentry(ms, &me, mset);
- - free(line);
- - (void)fclose(f);
- + efree(line);
- + php_stream_close(stream);
- }
-
- /*
- @@ -1280,7 +1221,7 @@
- file_magwarn(ms,
- "level 0 \"default\" did not sort last");
- }
- - return;
- + return;
- }
- }
- }
- @@ -1296,7 +1237,7 @@
- mentrycount += me[i].cont_count;
-
- slen = sizeof(**ma) * mentrycount;
- - if ((*ma = CAST(struct magic *, malloc(slen))) == NULL) {
- + if ((*ma = CAST(struct magic *, emalloc(slen))) == NULL) {
- file_oomem(ms, slen);
- return -1;
- }
- @@ -1318,8 +1259,8 @@
- if (me == NULL)
- return;
- for (i = 0; i < nme; i++)
- - free(me[i].mp);
- - free(me);
- + efree(me[i].mp);
- + efree(me);
- }
-
- private struct magic_map *
- @@ -1328,18 +1269,19 @@
- int errs = 0;
- uint32_t i, j;
- size_t files = 0, maxfiles = 0;
- - char **filearr = NULL, *mfn;
- - struct stat st;
- + char **filearr = NULL;
- + zend_stat_t st;
- struct magic_map *map;
- struct magic_entry_set mset[MAGIC_SETS];
- - DIR *dir;
- - struct dirent *d;
- + php_stream *dir;
- + php_stream_dirent d;
- +
-
- memset(mset, 0, sizeof(mset));
- ms->flags |= MAGIC_CHECK; /* Enable checks for parsed files */
-
-
- - if ((map = CAST(struct magic_map *, calloc(1, sizeof(*map)))) == NULL)
- + if ((map = CAST(struct magic_map *, ecalloc(1, sizeof(*map)))) == NULL)
- {
- file_oomem(ms, sizeof(*map));
- return NULL;
- @@ -1351,24 +1293,26 @@
- (void)fprintf(stderr, "%s\n", usg_hdr);
-
- /* load directory or file */
- - if (stat(fn, &st) == 0 && S_ISDIR(st.st_mode)) {
- - dir = opendir(fn);
- + /* FIXME: Read file names and sort them to prevent
- + non-determinism. See Debian bug #488562. */
- + if (php_sys_stat(fn, &st) == 0 && S_ISDIR(st.st_mode)) {
- + int mflen;
- + char mfn[MAXPATHLEN];
- +
- + dir = php_stream_opendir((char *)fn, REPORT_ERRORS, NULL);
- if (!dir) {
- errs++;
- goto out;
- }
- - while ((d = readdir(dir)) != NULL) {
- - if (d->d_name[0] == '.')
- - continue;
- - if (asprintf(&mfn, "%s/%s", fn, d->d_name) < 0) {
- + while (php_stream_readdir(dir, &d)) {
- + if ((mflen = snprintf(mfn, sizeof(mfn), "%s/%s", fn, d.d_name)) < 0) {
- file_oomem(ms,
- - strlen(fn) + strlen(d->d_name) + 2);
- + strlen(fn) + strlen(d.d_name) + 2);
- errs++;
- - closedir(dir);
- + php_stream_closedir(dir);
- goto out;
- }
- - if (stat(mfn, &st) == -1 || !S_ISREG(st.st_mode)) {
- - free(mfn);
- + if (zend_stat(mfn, &st) == -1 || !S_ISREG(st.st_mode)) {
- continue;
- }
- if (files >= maxfiles) {
- @@ -1376,23 +1320,22 @@
- maxfiles = (maxfiles + 1) * 2;
- mlen = maxfiles * sizeof(*filearr);
- if ((filearr = CAST(char **,
- - realloc(filearr, mlen))) == NULL) {
- + erealloc(filearr, mlen))) == NULL) {
- file_oomem(ms, mlen);
- - free(mfn);
- - closedir(dir);
- + php_stream_closedir(dir);
- errs++;
- goto out;
- }
- }
- - filearr[files++] = mfn;
- + filearr[files++] = estrndup(mfn, (mflen > sizeof(mfn) - 1)? sizeof(mfn) - 1: mflen);
- }
- - closedir(dir);
- + php_stream_closedir(dir);
- qsort(filearr, files, sizeof(*filearr), cmpstrp);
- for (i = 0; i < files; i++) {
- load_1(ms, action, filearr[i], &errs, mset);
- - free(filearr[i]);
- + efree(filearr[i]);
- }
- - free(filearr);
- + efree(filearr);
- } else
- load_1(ms, action, fn, &errs, mset);
- if (errs)
- @@ -1833,7 +1776,7 @@
- */
- while (*l == '>') {
- ++l; /* step over */
- - cont_level++;
- + cont_level++;
- }
- #ifdef ENABLE_CONDITIONALS
- if (cont_level == 0 || cont_level > last_cont_level)
- @@ -1859,7 +1802,7 @@
- if (me->cont_count == me->max_count) {
- struct magic *nm;
- size_t cnt = me->max_count + ALLOC_CHUNK;
- - if ((nm = CAST(struct magic *, realloc(me->mp,
- + if ((nm = CAST(struct magic *, erealloc(me->mp,
- sizeof(*nm) * cnt))) == NULL) {
- file_oomem(ms, sizeof(*nm) * cnt);
- return -1;
- @@ -1874,7 +1817,7 @@
- static const size_t len = sizeof(*m) * ALLOC_CHUNK;
- if (me->mp != NULL)
- return 1;
- - if ((m = CAST(struct magic *, malloc(len))) == NULL) {
- + if ((m = CAST(struct magic *, emalloc(len))) == NULL) {
- file_oomem(ms, len);
- return -1;
- }
- @@ -1916,17 +1859,6 @@
- file_magwarn(ms, "offset `%s' invalid", l);
- return -1;
- }
- -#if 0
- - if (m->offset < 0 && cont_level != 0 &&
- - (m->flag & (OFFADD | INDIROFFADD)) == 0) {
- - if (ms->flags & MAGIC_CHECK) {
- - file_magwarn(ms,
- - "negative direct offset `%s' at level %u",
- - l, cont_level);
- - }
- - return -1;
- - }
- -#endif
- l = t;
-
- if (m->flag & INDIR) {
- @@ -2012,7 +1944,7 @@
- }
- l = t;
- }
- - if (*l++ != ')' ||
- + if (*l++ != ')' ||
- ((m->in_op & FILE_OPINDIRECT) && *l++ != ')')) {
- if (ms->flags & MAGIC_CHECK)
- file_magwarn(ms,
- @@ -2037,7 +1969,7 @@
- /*
- * Try it as a keyword type prefixed by "u"; match what
- * follows the "u". If that fails, try it as an SUS
- - * integer type.
- + * integer type.
- */
- m->type = get_type(type_tbl, l + 1, &l);
- if (m->type == FILE_INVALID) {
- @@ -2077,7 +2009,7 @@
- /* Not found - try it as a special keyword. */
- m->type = get_type(special_tbl, l, &l);
- }
- -
- +
- if (m->type == FILE_INVALID) {
- if (ms->flags & MAGIC_CHECK)
- file_magwarn(ms, "type `%s' invalid", l);
- @@ -2089,7 +2021,7 @@
-
- m->mask_op = 0;
- if (*l == '~') {
- - if (!IS_STRING(m->type))
- + if (!IS_LIBMAGIC_STRING(m->type))
- m->mask_op |= FILE_OPINVERSE;
- else if (ms->flags & MAGIC_CHECK)
- file_magwarn(ms, "'~' invalid for string types");
- @@ -2098,7 +2030,7 @@
- m->str_range = 0;
- m->str_flags = m->type == FILE_PSTRING ? PSTRING_1_LE : 0;
- if ((op = get_op(*l)) != -1) {
- - if (IS_STRING(m->type)) {
- + if (IS_LIBMAGIC_STRING(m->type)) {
- int r;
-
- if (op != FILE_OPDIVIDE) {
- @@ -2124,7 +2056,7 @@
- * anything if mask = 0 (unless you have a better idea)
- */
- EATAB;
- -
- +
- switch (*l) {
- case '>':
- case '<':
- @@ -2156,7 +2088,7 @@
- break;
- default:
- m->reln = '='; /* the default relation */
- - if (*l == 'x' && ((isascii((unsigned char)l[1]) &&
- + if (*l == 'x' && ((isascii((unsigned char)l[1]) &&
- isspace((unsigned char)l[1])) || !l[1])) {
- m->reln = *l;
- ++l;
- @@ -2171,7 +2103,7 @@
-
- /*
- * TODO finish this macro and start using it!
- - * #define offsetcheck {if (offset > ms->bytes_max -1)
- + * #define offsetcheck {if (offset > ms->bytes_max -1)
- * magwarn("offset too big"); }
- */
-
- @@ -2203,11 +2135,6 @@
- if (check_format(ms, m) == -1)
- return -1;
- }
- -#ifndef COMPILE_ONLY
- - if (action == FILE_CHECK) {
- - file_mdump(m);
- - }
- -#endif
- m->mimetype[0] = '\0'; /* initialise MIME type to none */
- return 0;
- }
- @@ -2279,7 +2206,7 @@
-
- private int
- parse_extra(struct magic_set *ms, struct magic_entry *me, const char *line,
- - off_t off, size_t len, const char *name, const char *extra, int nt)
- + zend_off_t off, size_t len, const char *name, const char *extra, int nt)
- {
- size_t i;
- const char *l = line;
- @@ -2291,7 +2218,7 @@
- file_magwarn(ms, "Current entry already has a %s type "
- "`%.*s', new type `%s'", name, (int)len, buf, l);
- return -1;
- - }
- + }
-
- if (*m->desc == '\0') {
- file_magwarn(ms, "Current entry does not yet have a "
- @@ -2361,7 +2288,7 @@
- struct magic *m = &me->mp[0];
-
- return parse_extra(ms, me, line,
- - CAST(off_t, offsetof(struct magic, mimetype)),
- + CAST(zend_off_t, offsetof(struct magic, mimetype)),
- sizeof(m->mimetype), "MIME", "+-/.$?:{}", 1);
- }
-
- @@ -2428,7 +2355,7 @@
- if (*ptr++ != 'l')
- goto invalid;
- }
- -
- +
- switch (*ptr++) {
- #ifdef STRICT_FORMAT /* "long" formats are int formats for us */
- /* so don't accept the 'l' modifier */
- @@ -2446,7 +2373,7 @@
- default:
- goto invalid;
- }
- -
- +
- /*
- * Don't accept h and hh modifiers. They make writing
- * magic entries more complicated, for very little benefit
- @@ -2502,7 +2429,7 @@
- default:
- goto invalid;
- }
- -
- +
- case FILE_FMT_FLOAT:
- case FILE_FMT_DOUBLE:
- if (*ptr == '-')
- @@ -2521,11 +2448,11 @@
- case 'g':
- case 'G':
- return 0;
- -
- +
- default:
- goto invalid;
- }
- -
- +
-
- case FILE_FMT_STR:
- if (*ptr == '-')
- @@ -2537,14 +2464,14 @@
- while (isdigit((unsigned char )*ptr))
- ptr++;
- }
- -
- +
- switch (*ptr++) {
- case 's':
- return 0;
- default:
- goto invalid;
- }
- -
- +
- default:
- /* internal error */
- abort();
- @@ -2555,7 +2482,7 @@
- *estr = "too long";
- return -1;
- }
- -
- +
- /*
- * Check that the optional printf format in description matches
- * the type of the magic.
- @@ -2578,7 +2505,7 @@
-
- if (m->type >= file_nformats) {
- file_magwarn(ms, "Internal error inconsistency between "
- - "m->type and format strings");
- + "m->type and format strings");
- return -1;
- }
- if (file_formats[m->type] == FILE_FMT_NONE) {
- @@ -2598,7 +2525,7 @@
- file_names[m->type], m->desc);
- return -1;
- }
- -
- +
- for (; *ptr; ptr++) {
- if (*ptr == '%') {
- file_magwarn(ms,
- @@ -2611,9 +2538,9 @@
- return 0;
- }
-
- -/*
- - * Read a numeric value from a pointer, into the value union of a magic
- - * pointer, according to the magic type. Update the string pointer to point
- +/*
- + * Read a numeric value from a pointer, into the value union of a magic
- + * pointer, according to the magic type. Update the string pointer to point
- * just after the number read. Return 0 for success, non-zero for failure.
- */
- private int
- @@ -2640,14 +2567,19 @@
- return -1;
- }
- if (m->type == FILE_REGEX) {
- - file_regex_t rx;
- - int rc = file_regcomp(&rx, m->value.s, REG_EXTENDED);
- - if (rc) {
- - if (ms->flags & MAGIC_CHECK)
- - file_regerror(&rx, rc, ms);
- + zval pattern;
- + int options = 0;
- + pcre_cache_entry *pce;
- +
- + convert_libmagic_pattern(&pattern, m->value.s, strlen(m->value.s), options);
- +
- + if ((pce = pcre_get_compiled_regex_cache(Z_STR(pattern))) == NULL) {
- + zval_dtor(&pattern);
- + return -1;
- }
- - file_regfree(&rx);
- - return rc ? -1 : 0;
- + zval_dtor(&pattern);
- +
- + return 0;
- }
- return 0;
- default:
- @@ -2770,7 +2702,7 @@
- default:
- if (warn) {
- if (isprint((unsigned char)c)) {
- - /* Allow escaping of
- + /* Allow escaping of
- * ``relations'' */
- if (strchr("<>&^=!", c) == NULL
- && (m->type != FILE_REGEX ||
- @@ -2975,7 +2907,7 @@
- {
- const char *l = *p;
-
- - if (LOWCASE(*l) == 'u')
- + if (LOWCASE(*l) == 'u')
- l++;
-
- switch (LOWCASE(*l)) {
- @@ -3001,7 +2933,7 @@
- {
- struct magic_map *map;
-
- - if ((map = CAST(struct magic_map *, calloc(1, sizeof(*map)))) == NULL) {
- + if ((map = CAST(struct magic_map *, ecalloc(1, sizeof(*map)))) == NULL) {
- file_oomem(ms, sizeof(*map));
- return NULL;
- }
- @@ -3022,79 +2954,145 @@
- private struct magic_map *
- apprentice_map(struct magic_set *ms, const char *fn)
- {
- - int fd;
- - struct stat st;
- + uint32_t *ptr;
- + uint32_t version, entries, nentries;
- + int needsbyteswap;
- char *dbname = NULL;
- struct magic_map *map;
- - struct magic_map *rv = NULL;
- + size_t i;
- + php_stream *stream = NULL;
- + php_stream_statbuf st;
- +
- +
-
- - fd = -1;
- - if ((map = CAST(struct magic_map *, calloc(1, sizeof(*map)))) == NULL) {
- + if ((map = CAST(struct magic_map *, ecalloc(1, sizeof(*map)))) == NULL) {
- file_oomem(ms, sizeof(*map));
- - goto error;
- + return NULL;
- + }
- +
- + if (fn == NULL) {
- + map->p = (void *)&php_magic_database;
- + goto internal_loaded;
- }
- - map->type = MAP_TYPE_USER; /* unspecified */
- +
- +#ifdef PHP_WIN32
- + /* Don't bother on windows with php_stream_open_wrapper,
- + return to give apprentice_load() a chance. */
- + if (php_stream_stat_path_ex((char *)fn, 0, &st, NULL) == SUCCESS) {
- + if (st.sb.st_mode & S_IFDIR) {
- + return NULL;
- + }
- + }
- +#endif
-
- dbname = mkdbname(ms, fn, 0);
- if (dbname == NULL)
- goto error;
-
- - if ((fd = open(dbname, O_RDONLY|O_BINARY)) == -1)
- + stream = php_stream_open_wrapper((char *)fn, "rb", REPORT_ERRORS, NULL);
- +
- + if (!stream) {
- goto error;
- + }
-
- - if (fstat(fd, &st) == -1) {
- + if (php_stream_stat(stream, &st) < 0) {
- file_error(ms, errno, "cannot stat `%s'", dbname);
- goto error;
- }
- - if (st.st_size < 8 || st.st_size > MAXMAGIC_SIZE) {
- + if (st.sb.st_size < 8 || st.sb.st_size > MAXMAGIC_SIZE) {
- file_error(ms, 0, "file `%s' is too %s", dbname,
- - st.st_size < 8 ? "small" : "large");
- + st.sb.st_size < 8 ? "small" : "large");
- goto error;
- }
-
- - map->len = (size_t)st.st_size;
- -#ifdef QUICK
- - map->type = MAP_TYPE_MMAP;
- - if ((map->p = mmap(0, (size_t)st.st_size, PROT_READ|PROT_WRITE,
- - MAP_PRIVATE|MAP_FILE, fd, (off_t)0)) == MAP_FAILED) {
- - file_error(ms, errno, "cannot map `%s'", dbname);
- - goto error;
- - }
- -#else
- - map->type = MAP_TYPE_MALLOC;
- - if ((map->p = CAST(void *, malloc(map->len))) == NULL) {
- + map->len = (size_t)st.sb.st_size;
- + if ((map->p = CAST(void *, emalloc(map->len))) == NULL) {
- file_oomem(ms, map->len);
- goto error;
- }
- - if (read(fd, map->p, map->len) != (ssize_t)map->len) {
- + if (php_stream_read(stream, map->p, (size_t)st.sb.st_size) != (size_t)st.sb.st_size) {
- file_badread(ms);
- goto error;
- }
- + map->len = 0;
- #define RET 1
- -#endif
- - (void)close(fd);
- - fd = -1;
-
- - if (check_buffer(ms, map, dbname) != 0) {
- - rv = (struct magic_map *)-1;
- + php_stream_close(stream);
- + stream = NULL;
- +
- +internal_loaded:
- + ptr = (uint32_t *)(void *)map->p;
- + if (*ptr != MAGICNO) {
- + if (swap4(*ptr) != MAGICNO) {
- + file_error(ms, 0, "bad magic in `%s'", dbname);
- + goto error;
- + }
- + needsbyteswap = 1;
- + } else
- + needsbyteswap = 0;
- + if (needsbyteswap)
- + version = swap4(ptr[1]);
- + else
- + version = ptr[1];
- + if (version != VERSIONNO) {
- + file_error(ms, 0, "File %d.%d supports only version %d magic "
- + "files. `%s' is version %d", FILE_VERSION_MAJOR, patchlevel,
- + VERSIONNO, dbname, version);
- goto error;
- }
- -#ifdef QUICK
- - if (mprotect(map->p, (size_t)st.st_size, PROT_READ) == -1) {
- - file_error(ms, errno, "cannot mprotect `%s'", dbname);
- +
- + /* php_magic_database is a const, performing writes will segfault. This is for big-endian
- + machines only, PPC and Sparc specifically. Consider static variable or MINIT in
- + future. */
- + if (needsbyteswap && fn == NULL) {
- + map->p = emalloc(sizeof(php_magic_database));
- + map->p = memcpy(map->p, php_magic_database, sizeof(php_magic_database));
- + }
- +
- + if (NULL != fn) {
- + nentries = (uint32_t)(st.sb.st_size / sizeof(struct magic));
- + entries = (uint32_t)(st.sb.st_size / sizeof(struct magic));
- + if ((zend_off_t)(entries * sizeof(struct magic)) != st.sb.st_size) {
- + file_error(ms, 0, "Size of `%s' %llu is not a multiple of %zu",
- + dbname, (unsigned long long)st.sb.st_size,
- + sizeof(struct magic));
- + goto error;
- + }
- + }
- + map->magic[0] = CAST(struct magic *, map->p) + 1;
- + nentries = 0;
- + for (i = 0; i < MAGIC_SETS; i++) {
- + if (needsbyteswap)
- + map->nmagic[i] = swap4(ptr[i + 2]);
- + else
- + map->nmagic[i] = ptr[i + 2];
- + if (i != MAGIC_SETS - 1)
- + map->magic[i + 1] = map->magic[i] + map->nmagic[i];
- + nentries += map->nmagic[i];
- + }
- + if (NULL != fn && entries != nentries + 1) {
- + file_error(ms, 0, "Inconsistent entries in `%s' %u != %u",
- + dbname, entries, nentries + 1);
- goto error;
- }
- -#endif
- + if (needsbyteswap)
- + for (i = 0; i < MAGIC_SETS; i++)
- + byteswap(map->magic[i], map->nmagic[i]);
-
- - free(dbname);
- + if (dbname) {
- + efree(dbname);
- + }
- return map;
-
- error:
- - if (fd != -1)
- - (void)close(fd);
- + if (stream) {
- + php_stream_close(stream);
- + }
- apprentice_unmap(map);
- - free(dbname);
- - return rv;
- + if (dbname) {
- + efree(dbname);
- + }
- + return NULL;
- }
-
- private int
- @@ -3120,7 +3118,7 @@
- version = ptr[1];
- if (version != VERSIONNO) {
- file_error(ms, 0, "File %s supports only version %d magic "
- - "files. `%s' is version %d", VERSION,
- + "files. `%s' is version %d", FILE_VERSION_MAJOR,
- VERSIONNO, dbname, version);
- return -1;
- }
- @@ -3161,7 +3159,6 @@
- {
- static const size_t nm = sizeof(*map->nmagic) * MAGIC_SETS;
- static const size_t m = sizeof(**map->magic);
- - int fd = -1;
- size_t len;
- char *dbname;
- int rv = -1;
- @@ -3170,14 +3167,17 @@
- struct magic m;
- uint32_t h[2 + MAGIC_SETS];
- } hdr;
- + php_stream *stream;
-
- dbname = mkdbname(ms, fn, 1);
-
- - if (dbname == NULL)
- + if (dbname == NULL)
- goto out;
-
- - if ((fd = open(dbname, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0644)) == -1)
- - {
- + /* wb+ == O_WRONLY|O_CREAT|O_TRUNC|O_BINARY */
- + stream = php_stream_open_wrapper((char *)fn, "wb+", REPORT_ERRORS, NULL);
- +
- + if (!stream) {
- file_error(ms, errno, "cannot open `%s'", dbname);
- goto out;
- }
- @@ -3186,26 +3186,25 @@
- hdr.h[1] = VERSIONNO;
- memcpy(hdr.h + 2, map->nmagic, nm);
-
- - if (write(fd, &hdr, sizeof(hdr)) != (ssize_t)sizeof(hdr)) {
- + if (php_stream_write(stream,(const char *)&hdr, sizeof(hdr)) != (ssize_t)sizeof(hdr)) {
- file_error(ms, errno, "error writing `%s'", dbname);
- - goto out2;
- + goto out;
- }
-
- for (i = 0; i < MAGIC_SETS; i++) {
- len = m * map->nmagic[i];
- - if (write(fd, map->magic[i], len) != (ssize_t)len) {
- + if (php_stream_write(stream, (const char *)map->magic[i], len) != (ssize_t)len) {
- file_error(ms, errno, "error writing `%s'", dbname);
- - goto out2;
- + goto out;
- }
- }
-
- + if (stream) {
- + php_stream_close(stream);
- + }
- rv = 0;
- -out2:
- - if (fd != -1)
- - (void)close(fd);
- out:
- - apprentice_unmap(map);
- - free(dbname);
- + efree(dbname);
- return rv;
- }
-
- @@ -3239,16 +3238,18 @@
- q++;
- /* Compatibility with old code that looked in .mime */
- if (ms->flags & MAGIC_MIME) {
- - if (asprintf(&buf, "%.*s.mime%s", (int)(q - fn), fn, ext) < 0)
- - return NULL;
- - if (access(buf, R_OK) != -1) {
- + spprintf(&buf, MAXPATHLEN, "%.*s.mime%s", (int)(q - fn), fn, ext);
- +#ifdef PHP_WIN32
- + if (VCWD_ACCESS(buf, R_OK) == 0) {
- +#else
- + if (VCWD_ACCESS(buf, R_OK) != -1) {
- +#endif
- ms->flags &= MAGIC_MIME_TYPE;
- return buf;
- }
- - free(buf);
- + efree(buf);
- }
- - if (asprintf(&buf, "%.*s%s", (int)(q - fn), fn, ext) < 0)
- - return NULL;
- + spprintf(&buf, MAXPATHLEN, "%.*s%s", (int)(q - fn), fn, ext);
-
- /* Compatibility with old code that looked in .mime */
- if (strstr(fn, ".mime") != NULL)
- @@ -3274,8 +3275,8 @@
- swap2(uint16_t sv)
- {
- uint16_t rv;
- - uint8_t *s = (uint8_t *)(void *)&sv;
- - uint8_t *d = (uint8_t *)(void *)&rv;
- + uint8_t *s = (uint8_t *)(void *)&sv;
- + uint8_t *d = (uint8_t *)(void *)&rv;
- d[0] = s[1];
- d[1] = s[0];
- return rv;
- @@ -3288,8 +3289,8 @@
- swap4(uint32_t sv)
- {
- uint32_t rv;
- - uint8_t *s = (uint8_t *)(void *)&sv;
- - uint8_t *d = (uint8_t *)(void *)&rv;
- + uint8_t *s = (uint8_t *)(void *)&sv;
- + uint8_t *d = (uint8_t *)(void *)&rv;
- d[0] = s[3];
- d[1] = s[2];
- d[2] = s[1];
- @@ -3304,8 +3305,8 @@
- swap8(uint64_t sv)
- {
- uint64_t rv;
- - uint8_t *s = (uint8_t *)(void *)&sv;
- - uint8_t *d = (uint8_t *)(void *)&rv;
- + uint8_t *s = (uint8_t *)(void *)&sv;
- + uint8_t *d = (uint8_t *)(void *)&rv;
- #if 0
- d[0] = s[3];
- d[1] = s[2];
- @@ -3338,7 +3339,7 @@
- m->offset = swap4((int32_t)m->offset);
- m->in_offset = swap4((uint32_t)m->in_offset);
- m->lineno = swap4((uint32_t)m->lineno);
- - if (IS_STRING(m->type)) {
- + if (IS_LIBMAGIC_STRING(m->type)) {
- m->str_range = swap4(m->str_range);
- m->str_flags = swap4(m->str_flags);
- }
- @@ -3348,7 +3349,7 @@
- }
- }
-
- -protected size_t
- +protected size_t
- file_pstring_length_size(const struct magic *m)
- {
- switch (m->str_flags & PSTRING_LEN) {
- diff -u libmagic.orig/apptype.c libmagic/apptype.c
- --- libmagic.orig/apptype.c 2011-09-07 23:57:15.000000000 +0200
- +++ libmagic/apptype.c 2020-02-26 09:55:13.843047200 +0100
- @@ -1,15 +1,15 @@
- /*
- * Adapted from: apptype.c, Written by Eberhard Mattes and put into the
- * public domain
- - *
- + *
- * Notes: 1. Qualify the filename so that DosQueryAppType does not do extraneous
- * searches.
- - *
- + *
- * 2. DosQueryAppType will return FAPPTYP_DOS on a file ending with ".com"
- * (other than an OS/2 exe or Win exe with this name). Eberhard Mattes
- * remarks Tue, 6 Apr 93: Moreover, it reports the type of the (new and very
- * bug ridden) Win Emacs as "OS/2 executable".
- - *
- + *
- * 3. apptype() uses the filename if given, otherwise a tmp file is created with
- * the contents of buf. If buf is not the complete file, apptype can
- * incorrectly identify the exe type. The "-z" option of "file" is the reason
- @@ -18,10 +18,10 @@
-
- /*
- * amai: Darrel Hankerson did the changes described here.
- - *
- + *
- * It remains to check the validity of comments (2.) since it's referred to an
- * "old" OS/2 version.
- - *
- + *
- */
-
- #include "file.h"
- diff -u libmagic.orig/ascmagic.c libmagic/ascmagic.c
- --- libmagic.orig/ascmagic.c 2017-11-02 21:25:39.000000000 +0100
- +++ libmagic/ascmagic.c 2020-02-26 09:55:13.845043300 +0100
- @@ -90,7 +90,7 @@
- rv = file_ascmagic_with_encoding(ms, &bb,
- ubuf, ulen, code, type, text);
-
- - free(ubuf);
- + efree(ubuf);
-
- return rv;
- }
- @@ -137,7 +137,7 @@
- /* malloc size is a conservative overestimate; could be
- improved, or at least realloced after conversion. */
- mlen = ulen * 6;
- - if ((utf8_buf = CAST(unsigned char *, malloc(mlen))) == NULL) {
- + if ((utf8_buf = CAST(unsigned char *, emalloc(mlen))) == NULL) {
- file_oomem(ms, mlen);
- goto done;
- }
- @@ -305,7 +305,8 @@
- }
- rv = 1;
- done:
- - free(utf8_buf);
- + if (utf8_buf)
- + efree(utf8_buf);
-
- return rv;
- }
- diff -u libmagic.orig/buffer.c libmagic/buffer.c
- --- libmagic.orig/buffer.c 2018-03-11 01:46:42.000000000 +0100
- +++ libmagic/buffer.c 2020-02-26 09:55:13.846042600 +0100
- @@ -31,7 +31,11 @@
- #endif /* lint */
-
- #include "magic.h"
- +#ifdef PHP_WIN32
- +#include "win32/unistd.h"
- +#else
- #include <unistd.h>
- +#endif
- #include <string.h>
- #include <stdlib.h>
- #include <sys/stat.h>
- @@ -40,7 +44,7 @@
- buffer_init(struct buffer *b, int fd, const void *data, size_t len)
- {
- b->fd = fd;
- - if (b->fd == -1 || fstat(b->fd, &b->st) == -1)
- + if (b->fd == -1 || zend_fstat(b->fd, &b->st) == -1)
- memset(&b->st, 0, sizeof(b->st));
- b->fbuf = data;
- b->flen = len;
- @@ -52,7 +56,7 @@
- void
- buffer_fini(struct buffer *b)
- {
- - free(b->ebuf);
- + efree(b->ebuf);
- }
-
- int
- @@ -68,12 +72,14 @@
-
- b->elen = (size_t)b->st.st_size < b->flen ?
- (size_t)b->st.st_size : b->flen;
- - if ((b->ebuf = malloc(b->elen)) == NULL)
- + if ((b->ebuf = emalloc(b->elen)) == NULL)
- goto out;
-
- b->eoff = b->st.st_size - b->elen;
- - if (pread(b->fd, b->ebuf, b->elen, b->eoff) == -1) {
- - free(b->ebuf);
- + if (FINFO_LSEEK_FUNC(b->fd, b->eoff, SEEK_SET) == (zend_off_t)-1 ||
- + FINFO_READ_FUNC(b->fd, b->ebuf, b->elen) != (ssize_t)b->elen)
- + {
- + efree(b->ebuf);
- goto out;
- }
-
- diff -u libmagic.orig/cdf.c libmagic/cdf.c
- --- libmagic.orig/cdf.c 2018-03-11 01:46:42.000000000 +0100
- +++ libmagic/cdf.c 2020-02-26 09:55:13.847043900 +0100
- @@ -43,7 +43,17 @@
- #include <err.h>
- #endif
- #include <stdlib.h>
- +
- +#ifdef PHP_WIN32
- +#include "win32/unistd.h"
- +#else
- #include <unistd.h>
- +#endif
- +
- +#ifndef UINT32_MAX
- +# define UINT32_MAX (0xffffffff)
- +#endif
- +
- #include <string.h>
- #include <time.h>
- #include <ctype.h>
- @@ -80,37 +90,9 @@
- CDF_TOLE8(CAST(uint64_t, x))))
- #define CDF_GETUINT32(x, y) cdf_getuint32(x, y)
-
- -#define CDF_MALLOC(n) cdf_malloc(__FILE__, __LINE__, (n))
- -#define CDF_REALLOC(p, n) cdf_realloc(__FILE__, __LINE__, (p), (n))
- -#define CDF_CALLOC(n, u) cdf_calloc(__FILE__, __LINE__, (n), (u))
- -
- -
- -/*ARGSUSED*/
- -static void *
- -cdf_malloc(const char *file __attribute__((__unused__)),
- - size_t line __attribute__((__unused__)), size_t n)
- -{
- - DPRINTF(("%s,%zu: %s %zu\n", file, line, __func__, n));
- - return malloc(n);
- -}
- -
- -/*ARGSUSED*/
- -static void *
- -cdf_realloc(const char *file __attribute__((__unused__)),
- - size_t line __attribute__((__unused__)), void *p, size_t n)
- -{
- - DPRINTF(("%s,%zu: %s %zu\n", file, line, __func__, n));
- - return realloc(p, n);
- -}
- -
- -/*ARGSUSED*/
- -static void *
- -cdf_calloc(const char *file __attribute__((__unused__)),
- - size_t line __attribute__((__unused__)), size_t n, size_t u)
- -{
- - DPRINTF(("%s,%zu: %s %zu %zu\n", file, line, __func__, n, u));
- - return calloc(n, u);
- -}
- +#define CDF_MALLOC(n) emalloc(n)
- +#define CDF_REALLOC(p, n) erealloc(p, n)
- +#define CDF_CALLOC(n, u) ecalloc(n, u)
-
- /*
- * swap a short
- @@ -303,7 +285,7 @@
- scn->sst_len = 0;
- scn->sst_dirlen = 0;
- scn->sst_ss = 0;
- - free(scn->sst_tab);
- + efree(scn->sst_tab);
- scn->sst_tab = NULL;
- return -1;
- }
- @@ -336,12 +318,13 @@
- }
-
- static ssize_t
- -cdf_read(const cdf_info_t *info, off_t off, void *buf, size_t len)
- +cdf_read(const cdf_info_t *info, zend_off_t off, void *buf, size_t len)
- {
- size_t siz = (size_t)off + len;
-
- - if ((off_t)(off + len) != (off_t)siz)
- + if ((zend_off_t)(off + len) != (zend_off_t)siz) {
- goto out;
- + }
-
- if (info->i_buf != NULL && info->i_len >= siz) {
- (void)memcpy(buf, &info->i_buf[off], len);
- @@ -351,7 +334,10 @@
- if (info->i_fd == -1)
- goto out;
-
- - if (pread(info->i_fd, buf, len, off) != (ssize_t)len)
- + if (FINFO_LSEEK_FUNC(info->i_fd, off, SEEK_SET) == (zend_off_t)-1)
- + return -1;
- +
- + if (FINFO_READ_FUNC(info->i_fd, buf, len) != (ssize_t)len)
- return -1;
-
- return (ssize_t)len;
- @@ -366,7 +352,7 @@
- char buf[512];
-
- (void)memcpy(cdf_bo.s, "\01\02\03\04", 4);
- - if (cdf_read(info, (off_t)0, buf, sizeof(buf)) == -1)
- + if (cdf_read(info, (zend_off_t)0, buf, sizeof(buf)) == -1)
- return -1;
- cdf_unpack_header(h, buf);
- cdf_swap_header(h);
- @@ -400,7 +386,7 @@
- size_t ss = CDF_SEC_SIZE(h);
- size_t pos = CDF_SEC_POS(h, id);
- assert(ss == len);
- - return cdf_read(info, (off_t)pos, ((char *)buf) + offs, len);
- + return cdf_read(info, (zend_off_t)pos, ((char *)buf) + offs, len);
- }
-
- ssize_t
- @@ -501,14 +487,14 @@
- }
- out:
- sat->sat_len = i;
- - free(msa);
- + efree(msa);
- return 0;
- out3:
- errno = EFTYPE;
- out2:
- - free(msa);
- + efree(msa);
- out1:
- - free(sat->sat_tab);
- + efree(sat->sat_tab);
- return -1;
- }
-
- @@ -676,7 +662,7 @@
- return -1;
-
- if ((buf = CAST(char *, CDF_MALLOC(ss))) == NULL) {
- - free(dir->dir_tab);
- + efree(dir->dir_tab);
- return -1;
- }
-
- @@ -698,11 +684,11 @@
- if (NEED_SWAP)
- for (i = 0; i < dir->dir_len; i++)
- cdf_swap_dir(&dir->dir_tab[i]);
- - free(buf);
- + efree(buf);
- return 0;
- out:
- - free(dir->dir_tab);
- - free(buf);
- + efree(dir->dir_tab);
- + efree(buf);
- errno = EFTYPE;
- return -1;
- }
- @@ -747,7 +733,7 @@
- out:
- errno = EFTYPE;
- out1:
- - free(ssat->sat_tab);
- + efree(ssat->sat_tab);
- return -1;
- }
-
- @@ -859,7 +845,7 @@
- }
-
- static const uint8_t *
- -cdf_get_property_info_pos(const cdf_stream_t *sst, const cdf_header_t *h,
- +cdf_get_property_info_pos(const cdf_stream_t *sst, const cdf_header_t *h,
- const uint8_t *p, const uint8_t *e, size_t i)
- {
- size_t tail = (i << 1) + 1;
- @@ -874,7 +860,7 @@
- __LINE__) == -1)
- return NULL;
- ofs = CDF_GETUINT32(p, tail);
- - q = CAST(const uint8_t *, cdf_offset(CAST(const void *, p),
- + q = CAST(const uint8_t *, cdf_offset(CAST(const void *, p),
- ofs - 2 * sizeof(uint32_t)));
-
- if (q < p) {
- @@ -896,7 +882,7 @@
- size_t newcount = *maxcount + incr;
-
- if (newcount > CDF_PROP_LIMIT) {
- - DPRINTF(("exceeded property limit %zu > %zu\n",
- + DPRINTF(("exceeded property limit %zu > %zu\n",
- newcount, CDF_PROP_LIMIT));
- goto out;
- }
- @@ -909,7 +895,7 @@
- *maxcount = newcount;
- return inp;
- out:
- - free(*info);
- + efree(*info);
- *maxcount = 0;
- *info = NULL;
- return NULL;
- @@ -1003,8 +989,9 @@
- goto out;
- }
- nelements = CDF_GETUINT32(q, 1);
- - if (nelements == 0) {
- - DPRINTF(("CDF_VECTOR with nelements == 0\n"));
- + if (nelements > CDF_ELEMENT_LIMIT || nelements == 0) {
- + DPRINTF(("CDF_VECTOR with nelements == %"
- + SIZE_T_FORMAT "u\n", nelements));
- goto out;
- }
- slen = 2;
- @@ -1046,8 +1033,6 @@
- goto out;
- inp += nelem;
- }
- - DPRINTF(("nelements = %" SIZE_T_FORMAT "u\n",
- - nelements));
- for (j = 0; j < nelements && i < sh.sh_properties;
- j++, i++)
- {
- @@ -1092,7 +1077,7 @@
- }
- return 0;
- out:
- - free(*info);
- + efree(*info);
- *info = NULL;
- *count = 0;
- *maxcount = 0;
- @@ -1383,7 +1368,7 @@
- cdf_directory_t *d;
- char name[__arraycount(d->d_name)];
- cdf_stream_t scn;
- - struct timespec ts;
- + struct timeval ts;
-
- static const char *types[] = { "empty", "user storage",
- "user stream", "lockbytes", "property", "root storage" };
- @@ -1425,7 +1410,7 @@
- break;
- }
- cdf_dump_stream(&scn);
- - free(scn.sst_tab);
- + efree(scn.sst_tab);
- break;
- default:
- break;
- @@ -1438,7 +1423,7 @@
- cdf_dump_property_info(const cdf_property_info_t *info, size_t count)
- {
- cdf_timestamp_t tp;
- - struct timespec ts;
- + struct timeval ts;
- char buf[64];
- size_t i, j;
-
- @@ -1523,7 +1508,7 @@
- (void)fprintf(stderr, "Class %s\n", buf);
- (void)fprintf(stderr, "Count %d\n", ssi.si_count);
- cdf_dump_property_info(info, count);
- - free(info);
- + efree(info);
- }
-
-
- @@ -1544,7 +1529,7 @@
- cdf_u16tos8(sbuf, ce[i].ce_namlen, ce[i].ce_name),
- cdf_ctime(&ts.tv_sec, tbuf));
- }
- - free(cat);
- + efree(cat);
- }
-
- #endif
- diff -u libmagic.orig/cdf.h libmagic/cdf.h
- --- libmagic.orig/cdf.h 2017-03-09 17:57:17.000000000 +0100
- +++ libmagic/cdf.h 2020-02-26 09:55:13.848043100 +0100
- @@ -35,10 +35,10 @@
- #ifndef _H_CDF_
- #define _H_CDF_
-
- -#ifdef WIN32
- +#ifdef PHP_WIN32
- #include <winsock2.h>
- -#define timespec timeval
- -#define tv_nsec tv_usec
- +#define asctime_r php_asctime_r
- +#define ctime_r php_ctime_r
- #endif
- #ifdef __DJGPP__
- #define timespec timeval
- @@ -48,6 +48,7 @@
- typedef int32_t cdf_secid_t;
-
- #define CDF_LOOP_LIMIT 10000
- +#define CDF_ELEMENT_LIMIT 100000
-
- #define CDF_SECID_NULL 0
- #define CDF_SECID_FREE -1
- @@ -272,7 +273,7 @@
- typedef struct {
- uint16_t ce_namlen;
- uint32_t ce_num;
- - uint64_t ce_timestamp;
- + uint64_t ce_timestamp;
- uint16_t ce_name[256];
- } cdf_catalog_entry_t;
-
- diff -u libmagic.orig/cdf_time.c libmagic/cdf_time.c
- --- libmagic.orig/cdf_time.c 2017-03-29 17:57:48.000000000 +0200
- +++ libmagic/cdf_time.c 2020-02-26 09:55:13.849044200 +0100
- @@ -23,6 +23,7 @@
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
- +#include "php.h"
-
- #include "file.h"
-
- @@ -56,7 +57,7 @@
-
- for (y = CDF_BASE_YEAR; y < year; y++)
- days += isleap(y) + 365;
- -
- +
- return days;
- }
-
- @@ -77,7 +78,7 @@
- return days;
- }
-
- -/*
- +/*
- * Return the 0...11 month number.
- */
- static int
- @@ -152,7 +153,7 @@
- #endif
- #ifdef notyet
- struct tm tm;
- - if (gmtime_r(&ts->ts_sec, &tm) == NULL) {
- + if (php_gmtime_r(&ts->ts_sec, &tm) == NULL) {
- errno = EINVAL;
- return -1;
- }
- @@ -168,7 +169,7 @@
- char *
- cdf_ctime(const time_t *sec, char *buf)
- {
- - char *ptr = ctime_r(sec, buf);
- + char *ptr = php_ctime_r(sec, buf);
- if (ptr != NULL)
- return buf;
- (void)snprintf(buf, 26, "*Bad* %#16.16" INT64_T_FORMAT "x\n",
- diff -u libmagic.orig/compress.c libmagic/compress.c
- --- libmagic.orig/compress.c 2017-11-02 21:25:39.000000000 +0100
- +++ libmagic/compress.c 2020-02-26 09:55:13.850043300 +0100
- @@ -2,7 +2,7 @@
- * Copyright (c) Ian F. Darwin 1986-1995.
- * Software written by Ian F. Darwin and others;
- * maintained 1995-present by Christos Zoulas and others.
- - *
- + *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- @@ -12,7 +12,7 @@
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- - *
- + *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- @@ -29,13 +29,13 @@
- * compress routines:
- * zmagic() - returns 0 if not recognized, uncompresses and prints
- * information if recognized
- - * uncompress(method, old, n, newch) - uncompress old into new,
- + * uncompress(method, old, n, newch) - uncompress old into new,
- * using method, return sizeof new
- */
- #include "file.h"
-
- #ifndef lint
- -FILE_RCSID("@(#)$File: compress.c,v 1.106 2017/11/02 20:25:39 christos Exp $")
- +FILE_RCSID("@(#)$File: compress.c,v 1.104 2017/03/29 15:57:48 christos Exp $")
- #endif
-
- #include "magic.h"
- @@ -45,15 +45,13 @@
- #endif
- #include <string.h>
- #include <errno.h>
- -#include <ctype.h>
- -#include <stdarg.h>
- #ifdef HAVE_SIGNAL_H
- #include <signal.h>
- # ifndef HAVE_SIG_T
- typedef void (*sig_t)(int);
- # endif /* HAVE_SIG_T */
- -#endif
- -#if !defined(__MINGW32__) && !defined(WIN32)
- +#endif
- +#ifndef PHP_WIN32
- #include <sys/ioctl.h>
- #endif
- #ifdef HAVE_SYS_WAIT_H
- @@ -62,51 +60,12 @@
- #if defined(HAVE_SYS_TIME_H)
- #include <sys/time.h>
- #endif
- -#if defined(HAVE_ZLIB_H) && defined(ZLIBSUPPORT)
- +#if defined(HAVE_ZLIB_H) && defined(PHP_FILEINFO_UNCOMPRESS)
- #define BUILTIN_DECOMPRESS
- #include <zlib.h>
- #endif
- -#ifdef DEBUG
- -int tty = -1;
- -#define DPRINTF(...) do { \
- - if (tty == -1) \
- - tty = open("/dev/tty", O_RDWR); \
- - if (tty == -1) \
- - abort(); \
- - dprintf(tty, __VA_ARGS__); \
- -} while (/*CONSTCOND*/0)
- -#else
- -#define DPRINTF(...)
- -#endif
- -
- -#ifdef ZLIBSUPPORT
- -/*
- - * The following python code is not really used because ZLIBSUPPORT is only
- - * defined if we have a built-in zlib, and the built-in zlib handles that.
- - * That is not true for android where we have zlib.h and not -lz.
- - */
- -static const char zlibcode[] =
- - "import sys, zlib; sys.stdout.write(zlib.decompress(sys.stdin.read()))";
- -
- -static const char *zlib_args[] = { "python", "-c", zlibcode, NULL };
-
- -static int
- -zlibcmp(const unsigned char *buf)
- -{
- - unsigned short x = 1;
- - unsigned char *s = CAST(unsigned char *, CAST(void *, &x));
- -
- - if ((buf[0] & 0xf) != 8 || (buf[0] & 0x80) != 0)
- - return 0;
- - if (s[0] != 1) /* endianness test */
- - x = buf[0] | (buf[1] << 8);
- - else
- - x = buf[1] | (buf[0] << 8);
- - if (x % 31)
- - return 0;
- - return 1;
- -}
- -#endif
- +#undef FIONREAD
-
- #define gzip_flags "-cd"
- #define lrzip_flags "-do"
- @@ -169,7 +128,7 @@
- #define ERRDATA 2
-
- private ssize_t swrite(int, const void *, size_t);
- -#if HAVE_FORK
- +#ifdef PHP_FILEINFO_UNCOMPRESS
- private size_t ncompr = sizeof(compr) / sizeof(compr[0]);
- private int uncompressbuf(int, size_t, size_t, const unsigned char *,
- unsigned char **, size_t *);
- @@ -179,12 +138,12 @@
- private int uncompressgzipped(const unsigned char *, unsigned char **, size_t,
- size_t *);
- #endif
- -static int makeerror(unsigned char **, size_t *, const char *, ...)
- - __attribute__((__format__(__printf__, 3, 4)));
- +static int makeerror(unsigned char **, size_t *, const char *, ...);
- private const char *methodname(size_t);
-
- protected int
- -file_zmagic(struct magic_set *ms, const struct buffer *b, const char *name)
- +file_zmagic(struct magic_set *ms, int fd, const char *name,
- + const unsigned char *buf, size_t nbytes)
- {
- unsigned char *newbuf = NULL;
- size_t i, nsz;
- @@ -192,9 +151,6 @@
- file_pushbuf_t *pb;
- int urv, prv, rv = 0;
- int mime = ms->flags & MAGIC_MIME;
- - int fd = b->fd;
- - const unsigned char *buf = b->fbuf;
- - size_t nbytes = b->flen;
- #ifdef HAVE_SIGNAL_H
- sig_t osigpipe;
- #endif
- @@ -226,7 +182,7 @@
- switch (urv) {
- case OKDATA:
- case ERRDATA:
- -
- +
- ms->flags &= ~MAGIC_COMPRESS;
- if (urv == ERRDATA)
- prv = file_printf(ms, "%s ERROR: %s",
- @@ -253,10 +209,10 @@
- goto error;
- if ((rbuf = file_pop_buffer(ms, pb)) != NULL) {
- if (file_printf(ms, "%s", rbuf) == -1) {
- - free(rbuf);
- + efree(rbuf);
- goto error;
- }
- - free(rbuf);
- + efree(rbuf);
- }
- if (!mime && file_printf(ms, ")") == -1)
- goto error;
- @@ -277,7 +233,8 @@
- #ifdef HAVE_SIGNAL_H
- (void)signal(SIGPIPE, osigpipe);
- #endif
- - free(newbuf);
- + if (newbuf)
- + efree(newbuf);
- ms->flags |= MAGIC_COMPRESS;
- DPRINTF("Zmagic returns %d\n", rv);
- return rv;
- @@ -312,7 +269,7 @@
- * `safe' read for sockets and pipes.
- */
- protected ssize_t
- -sread(int fd, void *buf, size_t n, int canbepipe __attribute__((__unused__)))
- +sread(int fd, void *buf, size_t n, int canbepipe)
- {
- ssize_t rv;
- #ifdef FIONREAD
- @@ -360,7 +317,7 @@
-
- nocheck:
- do
- - switch ((rv = read(fd, buf, n))) {
- + switch ((rv = FINFO_READ_FUNC(fd, buf, n))) {
- case -1:
- if (errno == EINTR)
- continue;
- @@ -437,13 +394,14 @@
- return -1;
- }
- (void)close(tfd);
- - if (lseek(fd, (off_t)0, SEEK_SET) == (off_t)-1) {
- + if (FINFO_LSEEK_FUNC(fd, (zend_off_t)0, SEEK_SET) == (zend_off_t)-1) {
- file_badseek(ms);
- return -1;
- }
- return fd;
- }
- -#if HAVE_FORK
- +
- +#ifdef PHP_FILEINFO_UNCOMPRESS
- #ifdef BUILTIN_DECOMPRESS
-
- #define FHCRC (1 << 1)
- @@ -494,7 +452,7 @@
- int rc;
- z_stream z;
-
- - if ((*newch = CAST(unsigned char *, malloc(bytes_max + 1))) == NULL)
- + if ((*newch = CAST(unsigned char *, emalloc(bytes_max + 1))) == NULL)
- return makeerror(newch, n, "No buffer, %s", strerror(errno));
-
- z.next_in = CCAST(Bytef *, old);
- @@ -518,7 +476,7 @@
- rc = inflateEnd(&z);
- if (rc != Z_OK)
- goto err;
- -
- +
- /* let's keep the nul-terminate tradition */
- (*newch)[*n] = '\0';
-
- @@ -586,7 +544,7 @@
- int status;
-
- closefd(fdp[STDIN_FILENO], 0);
- - /*
- + /*
- * fork again, to avoid blocking because both
- * pipes filled
- */
- @@ -689,13 +647,13 @@
- fdp[STDIN_FILENO][0] = fd;
- (void) lseek(fd, (off_t)0, SEEK_SET);
- }
- -
- +
- for (i = 0; i < __arraycount(fdp); i++)
- copydesc(CAST(int, i), fdp[i]);
-
- (void)execvp(compr[method].argv[0],
- (char *const *)(intptr_t)compr[method].argv);
- - dprintf(STDERR_FILENO, "exec `%s' failed, %s",
- + dprintf(STDERR_FILENO, "exec `%s' failed, %s",
- compr[method].argv[0], strerror(errno));
- exit(1);
- /*NOTREACHED*/
- @@ -711,7 +669,7 @@
- if (fd == -1)
- writechild(fdp, old, *n);
-
- - *newch = CAST(unsigned char *, malloc(bytes_max + 1));
- + *newch = CAST(unsigned char *, emalloc(bytes_max + 1));
- if (*newch == NULL) {
- rv = makeerror(newch, n, "No buffer, %s",
- strerror(errno));
- @@ -730,7 +688,7 @@
- r = filter_error(*newch, r);
- break;
- }
- - free(*newch);
- + efree(*newch);
- if (r == 0)
- rv = makeerror(newch, n, "Read failed, %s",
- strerror(errno));
- @@ -738,27 +696,5 @@
- rv = makeerror(newch, n, "No data");
- goto err;
- }
- -
- - *n = r;
- - /* NUL terminate, as every buffer is handled here. */
- - (*newch)[*n] = '\0';
- -err:
- - closefd(fdp[STDIN_FILENO], 1);
- - closefd(fdp[STDOUT_FILENO], 0);
- - closefd(fdp[STDERR_FILENO], 0);
- - if (wait(&status) == -1) {
- - free(*newch);
- - rv = makeerror(newch, n, "Wait failed, %s", strerror(errno));
- - DPRINTF("Child wait return %#x\n", status);
- - } else if (!WIFEXITED(status)) {
- - DPRINTF("Child not exited (%#x)\n", status);
- - } else if (WEXITSTATUS(status) != 0) {
- - DPRINTF("Child exited (%#x)\n", WEXITSTATUS(status));
- - }
- -
- - closefd(fdp[STDIN_FILENO], 0);
- - DPRINTF("Returning %p n=%zu rv=%d\n", *newch, *n, rv);
- -
- - return rv;
- }
- -#endif
- +#endif /* if PHP_FILEINFO_UNCOMPRESS */
- diff -u libmagic.orig/der.c libmagic/der.c
- --- libmagic.orig/der.c 2017-02-10 19:14:01.000000000 +0100
- +++ libmagic/der.c 2020-02-26 09:55:13.851044000 +0100
- @@ -51,7 +51,9 @@
- #include "magic.h"
- #include "der.h"
- #else
- +#ifndef PHP_WIN32
- #include <sys/mman.h>
- +#endif
- #include <sys/stat.h>
- #include <err.h>
- #endif
- @@ -207,7 +209,7 @@
- static const char *
- der_tag(char *buf, size_t len, uint32_t tag)
- {
- - if (tag < DER_TAG_LONG)
- + if (tag < DER_TAG_LONG)
- strlcpy(buf, der__tag[tag], len);
- else
- snprintf(buf, len, "%#x", tag);
- @@ -218,6 +220,7 @@
- static int
- der_data(char *buf, size_t blen, uint32_t tag, const void *q, uint32_t len)
- {
- + uint32_t i = 0;
- const uint8_t *d = CAST(const uint8_t *, q);
- switch (tag) {
- case DER_TAG_PRINTABLE_STRING:
- @@ -229,7 +232,7 @@
- break;
- }
-
- - for (uint32_t i = 0; i < len; i++) {
- + for (; i < len; i++) {
- uint32_t z = i << 1;
- if (z < blen - 2)
- snprintf(buf + z, blen - z, "%.2x", d[i]);
- @@ -343,7 +346,7 @@
- default:
- break;
- }
- -
- +
- for (uint32_t i = 0; i < len; i++)
- printf("%.2x", d[i]);
- printf("\n");
- @@ -367,7 +370,7 @@
- if (p + x >= ep)
- break;
- uint32_t len = getlength(p, &x, ep - p + x);
- -
- +
- printf("%zu %zu-%zu %c,%c,%s,%u:", level, ox, x,
- der_class[c], der_type[t],
- der_tag(buf, sizeof(buf), tag), len);
- diff -u libmagic.orig/elfclass.h libmagic/elfclass.h
- --- libmagic.orig/elfclass.h 2014-12-17 00:18:40.000000000 +0100
- +++ libmagic/elfclass.h 2020-02-26 09:55:13.852043400 +0100
- @@ -1,7 +1,7 @@
- /*
- * Copyright (c) Christos Zoulas 2008.
- * All Rights Reserved.
- - *
- + *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- @@ -11,7 +11,7 @@
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- - *
- + *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- @@ -41,7 +41,7 @@
- return toomany(ms, "program headers", phnum);
- flags |= FLAGS_IS_CORE;
- if (dophn_core(ms, clazz, swap, fd,
- - (off_t)elf_getu(swap, elfhdr.e_phoff), phnum,
- + (zend_off_t)elf_getu(swap, elfhdr.e_phoff), phnum,
- (size_t)elf_getu16(swap, elfhdr.e_phentsize),
- fsize, &flags, ¬ecount) == -1)
- return -1;
- @@ -56,7 +56,7 @@
- if (shnum > ms->elf_shnum_max)
- return toomany(ms, "section", shnum);
- if (dophn_exec(ms, clazz, swap, fd,
- - (off_t)elf_getu(swap, elfhdr.e_phoff), phnum,
- + (zend_off_t)elf_getu(swap, elfhdr.e_phoff), phnum,
- (size_t)elf_getu16(swap, elfhdr.e_phentsize),
- fsize, shnum, &flags, ¬ecount) == -1)
- return -1;
- @@ -66,7 +66,7 @@
- if (shnum > ms->elf_shnum_max)
- return toomany(ms, "section headers", shnum);
- if (doshn(ms, clazz, swap, fd,
- - (off_t)elf_getu(swap, elfhdr.e_shoff), shnum,
- + (zend_off_t)elf_getu(swap, elfhdr.e_shoff), shnum,
- (size_t)elf_getu16(swap, elfhdr.e_shentsize),
- fsize, elf_getu16(swap, elfhdr.e_machine),
- (int)elf_getu16(swap, elfhdr.e_shstrndx),
- diff -u libmagic.orig/encoding.c libmagic/encoding.c
- --- libmagic.orig/encoding.c 2017-11-02 21:25:39.000000000 +0100
- +++ libmagic/encoding.c 2020-02-26 09:55:13.854045100 +0100
- @@ -88,12 +88,12 @@
- *code_mime = "binary";
-
- mlen = (nbytes + 1) * sizeof((*ubuf)[0]);
- - if ((*ubuf = CAST(unichar *, calloc((size_t)1, mlen))) == NULL) {
- + if ((*ubuf = CAST(unichar *, ecalloc((size_t)1, mlen))) == NULL) {
- file_oomem(ms, mlen);
- goto done;
- }
- mlen = (nbytes + 1) * sizeof(nbuf[0]);
- - if ((nbuf = CAST(unsigned char *, calloc((size_t)1, mlen))) == NULL) {
- + if ((nbuf = CAST(unsigned char *, ecalloc((size_t)1, mlen))) == NULL) {
- file_oomem(ms, mlen);
- goto done;
- }
- @@ -153,9 +153,9 @@
- }
-
- done:
- - free(nbuf);
- + efree(nbuf);
- if (ubuf == &udefbuf)
- - free(udefbuf);
- + efree(udefbuf);
-
- return rv;
- }
- diff -u libmagic.orig/file.h libmagic/file.h
- --- libmagic.orig/file.h 2018-03-11 01:46:42.000000000 +0100
- +++ libmagic/file.h 2020-02-26 09:55:13.856043400 +0100
- @@ -27,21 +27,15 @@
- */
- /*
- * file.h - definitions for file(1) program
- - * @(#)$File: file.h,v 1.191 2018/02/21 21:26:00 christos Exp $
- + * @(#)$File: file.h,v 1.182 2017/04/07 19:46:44 christos Exp $
- */
-
- #ifndef __file_h__
- #define __file_h__
-
- -#ifdef HAVE_CONFIG_H
- -#include <config.h>
- -#endif
- -#ifdef HAVE_STDINT_H
- -#ifndef __STDC_LIMIT_MACROS
- -#define __STDC_LIMIT_MACROS
- -#endif
- +#include "config.h"
-
- -#ifdef WIN32
- +#ifdef PHP_WIN32
- #ifdef _WIN64
- #define SIZE_T_FORMAT "I64"
- #else
- @@ -54,19 +48,31 @@
- #define INT64_T_FORMAT "ll"
- #define INTMAX_T_FORMAT "j"
- #endif
- -#include <stdint.h>
- -#endif
-
- #include <stdio.h> /* Include that here, to make sure __P gets defined */
- #include <errno.h>
- #include <fcntl.h> /* For open and flags */
- +#ifdef HAVE_STDINT_H
- +#ifndef __STDC_LIMIT_MACROS
- +#define __STDC_LIMIT_MACROS
- +#endif
- +#include <stdint.h>
- +#endif
- #ifdef HAVE_INTTYPES_H
- #include <inttypes.h>
- #endif
- -#include <regex.h>
- -#include <time.h>
- +#ifdef PHP_WIN32
- +#include "win32/php_stdint.h"
- +#endif
- +
- +#include "php.h"
- +#include "ext/standard/php_string.h"
- +#include "ext/pcre/php_pcre.h"
- +
- #include <sys/types.h>
- -#ifndef WIN32
- +#ifdef PHP_WIN32
- +#include "win32/param.h"
- +#else
- #include <sys/param.h>
- #endif
- /* Do this here and now, because struct stat gets re-defined on solaris */
- @@ -79,7 +85,7 @@
- #define MAGIC "/etc/magic"
- #endif
-
- -#if defined(__EMX__) || defined (WIN32)
- +#if defined(__EMX__) || defined(PHP_WIN32)
- #define PATHSEP ';'
- #else
- #define PATHSEP ':'
- @@ -113,12 +119,6 @@
- #endif
- #endif
-
- -#ifndef __GNUC__
- -#ifndef __attribute__
- -#define __attribute__(a)
- -#endif
- -#endif
- -
- #ifndef MIN
- #define MIN(a,b) (((a) < (b)) ? (a) : (b))
- #endif
- @@ -147,10 +147,10 @@
-
- struct buffer {
- int fd;
- - struct stat st;
- + zend_stat_t st;
- const void *fbuf;
- size_t flen;
- - off_t eoff;
- + zend_off_t eoff;
- void *ebuf;
- size_t elen;
- };
- @@ -240,7 +240,7 @@
- #define FILE_DER 48
- #define FILE_NAMES_SIZE 49 /* size of array to contain all names */
-
- -#define IS_STRING(t) \
- +#define IS_LIBMAGIC_STRING(t) \
- ((t) == FILE_STRING || \
- (t) == FILE_PSTRING || \
- (t) == FILE_BESTRING16 || \
- @@ -443,26 +443,22 @@
- /* Type for Unicode characters */
- typedef unsigned long unichar;
-
- -struct stat;
- #define FILE_T_LOCAL 1
- #define FILE_T_WINDOWS 2
- protected const char *file_fmttime(uint64_t, int, char *);
- protected struct magic_set *file_ms_alloc(int);
- protected void file_ms_free(struct magic_set *);
- -protected int file_buffer(struct magic_set *, int, const char *, const void *,
- +protected int file_buffer(struct magic_set *, php_stream *, const char *, const void *,
- size_t);
- -protected int file_fsmagic(struct magic_set *, const char *, struct stat *);
- +protected int file_fsmagic(struct magic_set *, const char *, zend_stat_t *, php_stream *);
- protected int file_pipe2file(struct magic_set *, int, const void *, size_t);
- -protected int file_vprintf(struct magic_set *, const char *, va_list)
- - __attribute__((__format__(__printf__, 2, 0)));
- protected size_t file_printedlen(const struct magic_set *);
- protected int file_replace(struct magic_set *, const char *, const char *);
- -protected int file_printf(struct magic_set *, const char *, ...)
- - __attribute__((__format__(__printf__, 2, 3)));
- +protected int file_printf(struct magic_set *, const char *, ...);
- protected int file_reset(struct magic_set *, int);
- protected int file_tryelf(struct magic_set *, const struct buffer *);
- protected int file_trycdf(struct magic_set *, const struct buffer *);
- -#if HAVE_FORK
- +#ifdef PHP_FILEINFO_UNCOMPRESS
- protected int file_zmagic(struct magic_set *, const struct buffer *,
- const char *);
- #endif
- @@ -484,13 +480,9 @@
- protected void file_badread(struct magic_set *);
- protected void file_badseek(struct magic_set *);
- protected void file_oomem(struct magic_set *, size_t);
- -protected void file_error(struct magic_set *, int, const char *, ...)
- - __attribute__((__format__(__printf__, 3, 4)));
- -protected void file_magerror(struct magic_set *, const char *, ...)
- - __attribute__((__format__(__printf__, 2, 3)));
- -protected void file_magwarn(struct magic_set *, const char *, ...)
- - __attribute__((__format__(__printf__, 2, 3)));
- -protected void file_mdump(struct magic *);
- +protected void file_error(struct magic_set *, int, const char *, ...);
- +protected void file_magerror(struct magic_set *, const char *, ...);
- +protected void file_magwarn(struct magic_set *, const char *, ...);
- protected void file_showstr(FILE *, const char *, size_t);
- protected size_t file_mbswidth(const char *);
- protected const char *file_getbuffer(struct magic_set *);
- @@ -510,31 +502,8 @@
- protected void buffer_fini(struct buffer *);
- protected int buffer_fill(const struct buffer *);
-
- -#if defined(HAVE_LOCALE_H)
- -#include <locale.h>
- -#endif
- -#if defined(HAVE_XLOCALE_H)
- -#include <xlocale.h>
- -#endif
- -
- -typedef struct {
- - const char *pat;
- -#if defined(HAVE_NEWLOCALE) && defined(HAVE_USELOCALE) && defined(HAVE_FREELOCALE)
- -#define USE_C_LOCALE
- - locale_t old_lc_ctype;
- - locale_t c_lc_ctype;
- -#else
- - char *old_lc_ctype;
- -#endif
- - int rc;
- - regex_t rx;
- -} file_regex_t;
- -
- -protected int file_regcomp(file_regex_t *, const char *, int);
- -protected int file_regexec(file_regex_t *, const char *, size_t, regmatch_t *,
- - int);
- -protected void file_regfree(file_regex_t *);
- -protected void file_regerror(file_regex_t *, int, struct magic_set *);
- +public void
- +convert_libmagic_pattern(zval *pattern, char *val, size_t len, uint32_t options);
-
- typedef struct {
- char *buf;
- @@ -544,10 +513,8 @@
- protected file_pushbuf_t *file_push_buffer(struct magic_set *);
- protected char *file_pop_buffer(struct magic_set *, file_pushbuf_t *);
-
- -#ifndef COMPILE_ONLY
- extern const char *file_names[];
- extern const size_t file_nnames;
- -#endif
-
- #ifndef HAVE_STRERROR
- extern int sys_nerr;
- @@ -560,23 +527,10 @@
- #define strtoul(a, b, c) strtol(a, b, c)
- #endif
-
- -#ifndef HAVE_PREAD
- -ssize_t pread(int, void *, size_t, off_t);
- -#endif
- -#ifndef HAVE_VASPRINTF
- -int vasprintf(char **, const char *, va_list);
- -#endif
- -#ifndef HAVE_ASPRINTF
- -int asprintf(char **, const char *, ...);
- -#endif
- -#ifndef HAVE_DPRINTF
- -int dprintf(int, const char *, ...);
- -#endif
- -
- -#ifndef HAVE_STRLCPY
- +#ifndef strlcpy
- size_t strlcpy(char *, const char *, size_t);
- #endif
- -#ifndef HAVE_STRLCAT
- +#ifndef strlcat
- size_t strlcat(char *, const char *, size_t);
- #endif
- #ifndef HAVE_STRCASESTR
- @@ -592,39 +546,6 @@
- #ifndef HAVE_ASCTIME_R
- char *asctime_r(const struct tm *, char *);
- #endif
- -#ifndef HAVE_GMTIME_R
- -struct tm *gmtime_r(const time_t *, struct tm *);
- -#endif
- -#ifndef HAVE_LOCALTIME_R
- -struct tm *localtime_r(const time_t *, struct tm *);
- -#endif
- -#ifndef HAVE_FMTCHECK
- -const char *fmtcheck(const char *, const char *)
- - __attribute__((__format_arg__(2)));
- -#endif
- -
- -#ifdef HAVE_LIBSECCOMP
- -// basic filter
- -// this mode should not interfere with normal operations
- -// only some dangerous syscalls are blacklisted
- -int enable_sandbox_basic(void);
- -
- -// enhanced filter
- -// this mode allows only the necessary syscalls used during normal operation
- -// extensive testing required !!!
- -int enable_sandbox_full(void);
- -#endif
- -
- -protected const char *file_getprogname(void);
- -protected void file_setprogname(const char *);
- -protected void file_err(int, const char *, ...)
- - __attribute__((__format__(__printf__, 2, 3)));
- -protected void file_errx(int, const char *, ...)
- - __attribute__((__format__(__printf__, 2, 3)));
- -protected void file_warn(const char *, ...)
- - __attribute__((__format__(__printf__, 1, 2)));
- -protected void file_warnx(const char *, ...)
- - __attribute__((__format__(__printf__, 1, 2)));
-
- #if defined(HAVE_MMAP) && defined(HAVE_SYS_MMAN_H) && !defined(QUICK)
- #define QUICK
- @@ -647,6 +568,18 @@
- #else
- #define FILE_RCSID(id)
- #endif
- +
- +#ifdef PHP_WIN32
- +#ifdef _WIN64
- +#define FINFO_LSEEK_FUNC _lseeki64
- +#else
- +#define FINFO_LSEEK_FUNC _lseek
- +#endif
- +#define FINFO_READ_FUNC _read
- +#else
- +#define FINFO_LSEEK_FUNC lseek
- +#define FINFO_READ_FUNC read
- +#endif
- #ifndef __RCSID
- #define __RCSID(a)
- #endif
- diff -u libmagic.orig/fsmagic.c libmagic/fsmagic.c
- --- libmagic.orig/fsmagic.c 2017-05-24 21:17:50.000000000 +0200
- +++ libmagic/fsmagic.c 2020-02-26 09:55:13.857043000 +0100
- @@ -2,7 +2,7 @@
- * Copyright (c) Ian F. Darwin 1986-1995.
- * Software written by Ian F. Darwin and others;
- * maintained 1995-present by Christos Zoulas and others.
- - *
- + *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- @@ -12,7 +12,7 @@
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- - *
- + *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- @@ -63,26 +63,10 @@
- # define minor(dev) ((dev) & 0xff)
- #endif
- #undef HAVE_MAJOR
- -#ifdef S_IFLNK
- -private int
- -bad_link(struct magic_set *ms, int err, char *buf)
- -{
- - int mime = ms->flags & MAGIC_MIME;
- - if ((mime & MAGIC_MIME_TYPE) &&
- - file_printf(ms, "inode/symlink")
- - == -1)
- - return -1;
- - else if (!mime) {
- - if (ms->flags & MAGIC_ERROR) {
- - file_error(ms, err,
- - "broken symbolic link to %s", buf);
- - return -1;
- - }
- - if (file_printf(ms, "broken symbolic link to %s", buf) == -1)
- - return -1;
- - }
- - return 1;
- -}
- +
- +#ifdef PHP_WIN32
- +
- +# undef S_IFIFO
- #endif
- private int
- handle_mime(struct magic_set *ms, int mime, const char *str)
- @@ -100,70 +84,39 @@
- }
-
- protected int
- -file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb)
- +file_fsmagic(struct magic_set *ms, const char *fn, zend_stat_t *sb, php_stream *stream)
- {
- int ret, did = 0;
- int mime = ms->flags & MAGIC_MIME;
- int silent = ms->flags & (MAGIC_APPLE|MAGIC_EXTENSION);
- -#ifdef S_IFLNK
- - char buf[BUFSIZ+4];
- - ssize_t nch;
- - struct stat tstatbuf;
- -#endif
-
- - if (fn == NULL)
- + if (ms->flags & (MAGIC_APPLE|MAGIC_EXTENSION))
- + return 0;
- +
- + if (fn == NULL && !stream) {
- return 0;
- + }
-
- #define COMMA (did++ ? ", " : "")
- - /*
- - * Fstat is cheaper but fails for files you don't have read perms on.
- - * On 4.2BSD and similar systems, use lstat() to identify symlinks.
- - */
- -#ifdef S_IFLNK
- - if ((ms->flags & MAGIC_SYMLINK) == 0)
- - ret = lstat(fn, sb);
- - else
- -#endif
- - ret = stat(fn, sb); /* don't merge into if; see "ret =" above */
-
- -#ifdef WIN32
- - {
- - HANDLE hFile = CreateFile((LPCSTR)fn, 0, FILE_SHARE_DELETE |
- - FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0,
- - NULL);
- - if (hFile != INVALID_HANDLE_VALUE) {
- - /*
- - * Stat failed, but we can still open it - assume it's
- - * a block device, if nothing else.
- - */
- - if (ret) {
- - sb->st_mode = S_IFBLK;
- - ret = 0;
- - }
- - switch (GetFileType(hFile)) {
- - case FILE_TYPE_CHAR:
- - sb->st_mode |= S_IFCHR;
- - sb->st_mode &= ~S_IFREG;
- - break;
- - case FILE_TYPE_PIPE:
- - sb->st_mode |= S_IFIFO;
- - sb->st_mode &= ~S_IFREG;
- - break;
- + if (stream) {
- + php_stream_statbuf ssb;
- + if (php_stream_stat(stream, &ssb) < 0) {
- + if (ms->flags & MAGIC_ERROR) {
- + file_error(ms, errno, "cannot stat `%s'", fn);
- + return -1;
- }
- - CloseHandle(hFile);
- + return 0;
- }
- - }
- -#endif
- -
- - if (ret) {
- - if (ms->flags & MAGIC_ERROR) {
- - file_error(ms, errno, "cannot stat `%s'", fn);
- - return -1;
- + memcpy(sb, &ssb.sb, sizeof(struct stat));
- + } else {
- + if (php_sys_stat(fn, sb) != 0) {
- + if (ms->flags & MAGIC_ERROR) {
- + file_error(ms, errno, "cannot stat `%s'", fn);
- + return -1;
- + }
- + return 0;
- }
- - if (file_printf(ms, "cannot open `%s' (%s)",
- - fn, strerror(errno)) == -1)
- - return -1;
- - return 0;
- }
-
- ret = 1;
- @@ -174,44 +127,36 @@
- return -1;
- #endif
- #ifdef S_ISGID
- - if (sb->st_mode & S_ISGID)
- + if (sb->st_mode & S_ISGID)
- if (file_printf(ms, "%ssetgid", COMMA) == -1)
- return -1;
- #endif
- #ifdef S_ISVTX
- - if (sb->st_mode & S_ISVTX)
- + if (sb->st_mode & S_ISVTX)
- if (file_printf(ms, "%ssticky", COMMA) == -1)
- return -1;
- #endif
- }
- -
- +
- switch (sb->st_mode & S_IFMT) {
- - case S_IFDIR:
- - if (mime) {
- - if (handle_mime(ms, mime, "directory") == -1)
- - return -1;
- - } else if (silent) {
- - } else if (file_printf(ms, "%sdirectory", COMMA) == -1)
- - return -1;
- - break;
- -#ifdef S_IFCHR
- - case S_IFCHR:
- - /*
- - * If -s has been specified, treat character special files
- - * like ordinary files. Otherwise, just report that they
- - * are block special files and go on to the next file.
- - */
- - if ((ms->flags & MAGIC_DEVICES) != 0) {
- - ret = 0;
- - break;
- - }
- - if (mime) {
- - if (handle_mime(ms, mime, "chardevice") == -1)
- - return -1;
- - } else if (silent) {
- - } else {
- -#ifdef HAVE_STRUCT_STAT_ST_RDEV
- -# ifdef dv_unit
- +#ifndef PHP_WIN32
- +# ifdef S_IFCHR
- + case S_IFCHR:
- + /*
- + * If -s has been specified, treat character special files
- + * like ordinary files. Otherwise, just report that they
- + * are block special files and go on to the next file.
- + */
- + if ((ms->flags & MAGIC_DEVICES) != 0) {
- + ret = 0;
- + break;
- + }
- + if (mime) {
- + if (handle_mime(ms, mime, "chardevice") == -1)
- + return -1;
- + } else {
- +# ifdef HAVE_STAT_ST_RDEV
- +# ifdef dv_unit
- if (file_printf(ms, "%scharacter special (%d/%d/%d)",
- COMMA, major(sb->st_rdev), dv_unit(sb->st_rdev),
- dv_subunit(sb->st_rdev)) == -1)
- @@ -226,45 +171,11 @@
- if (file_printf(ms, "%scharacter special", COMMA) == -1)
- return -1;
- #endif
- - }
- - break;
- -#endif
- -#ifdef S_IFBLK
- - case S_IFBLK:
- - /*
- - * If -s has been specified, treat block special files
- - * like ordinary files. Otherwise, just report that they
- - * are block special files and go on to the next file.
- - */
- - if ((ms->flags & MAGIC_DEVICES) != 0) {
- - ret = 0;
- - break;
- - }
- - if (mime) {
- - if (handle_mime(ms, mime, "blockdevice") == -1)
- - return -1;
- - } else if (silent) {
- - } else {
- -#ifdef HAVE_STRUCT_STAT_ST_RDEV
- -# ifdef dv_unit
- - if (file_printf(ms, "%sblock special (%d/%d/%d)",
- - COMMA, major(sb->st_rdev), dv_unit(sb->st_rdev),
- - dv_subunit(sb->st_rdev)) == -1)
- - return -1;
- -# else
- - if (file_printf(ms, "%sblock special (%ld/%ld)",
- - COMMA, (long)major(sb->st_rdev),
- - (long)minor(sb->st_rdev)) == -1)
- - return -1;
- + }
- + return 1;
- # endif
- -#else
- - if (file_printf(ms, "%sblock special", COMMA) == -1)
- - return -1;
- #endif
- - }
- - break;
- -#endif
- - /* TODO add code to handle V7 MUX and Blit MUX files */
- +
- #ifdef S_IFIFO
- case S_IFIFO:
- if((ms->flags & MAGIC_DEVICES) != 0)
- @@ -272,7 +183,6 @@
- if (mime) {
- if (handle_mime(ms, mime, "fifo") == -1)
- return -1;
- - } else if (silent) {
- } else if (file_printf(ms, "%sfifo (named pipe)", COMMA) == -1)
- return -1;
- break;
- @@ -282,89 +192,20 @@
- if (mime) {
- if (handle_mime(ms, mime, "door") == -1)
- return -1;
- - } else if (silent) {
- } else if (file_printf(ms, "%sdoor", COMMA) == -1)
- return -1;
- break;
- #endif
- #ifdef S_IFLNK
- case S_IFLNK:
- - if ((nch = readlink(fn, buf, BUFSIZ-1)) <= 0) {
- + /* stat is used, if it made here then the link is broken */
- if (ms->flags & MAGIC_ERROR) {
- - file_error(ms, errno, "unreadable symlink `%s'",
- - fn);
- + file_error(ms, errno, "unreadable symlink `%s'", fn);
- return -1;
- }
- - if (mime) {
- - if (handle_mime(ms, mime, "symlink") == -1)
- - return -1;
- - } else if (silent) {
- - } else if (file_printf(ms,
- - "%sunreadable symlink `%s' (%s)", COMMA, fn,
- - strerror(errno)) == -1)
- - return -1;
- - break;
- - }
- - buf[nch] = '\0'; /* readlink(2) does not do this */
- -
- - /* If broken symlink, say so and quit early. */
- - if (*buf == '/') {
- - if (stat(buf, &tstatbuf) < 0)
- - return bad_link(ms, errno, buf);
- - } else {
- - char *tmp;
- - char buf2[BUFSIZ+BUFSIZ+4];
- -
- - if ((tmp = strrchr(fn, '/')) == NULL) {
- - tmp = buf; /* in current directory anyway */
- - } else {
- - if (tmp - fn + 1 > BUFSIZ) {
- - if (ms->flags & MAGIC_ERROR) {
- - file_error(ms, 0,
- - "path too long: `%s'", buf);
- - return -1;
- - }
- - if (mime) {
- - if (handle_mime(ms, mime,
- - "x-path-too-long") == -1)
- - return -1;
- - } else if (silent) {
- - } else if (file_printf(ms,
- - "%spath too long: `%s'", COMMA,
- - fn) == -1)
- - return -1;
- - break;
- - }
- - /* take dir part */
- - (void)strlcpy(buf2, fn, sizeof buf2);
- - buf2[tmp - fn + 1] = '\0';
- - /* plus (rel) link */
- - (void)strlcat(buf2, buf, sizeof buf2);
- - tmp = buf2;
- - }
- - if (stat(tmp, &tstatbuf) < 0)
- - return bad_link(ms, errno, buf);
- - }
- -
- - /* Otherwise, handle it. */
- - if ((ms->flags & MAGIC_SYMLINK) != 0) {
- - const char *p;
- - ms->flags &= MAGIC_SYMLINK;
- - p = magic_file(ms, buf);
- - ms->flags |= MAGIC_SYMLINK;
- - if (p == NULL)
- - return -1;
- - } else { /* just print what it points to */
- - if (mime) {
- - if (handle_mime(ms, mime, "symlink") == -1)
- - return -1;
- - } else if (silent) {
- - } else if (file_printf(ms, "%ssymbolic link to %s",
- - COMMA, buf) == -1)
- - return -1;
- - }
- - break;
- + return 1;
- #endif
- +
- #ifdef S_IFSOCK
- #ifndef __COHERENT__
- case S_IFSOCK:
- diff -u libmagic.orig/funcs.c libmagic/funcs.c
- --- libmagic.orig/funcs.c 2017-11-02 21:25:39.000000000 +0100
- +++ libmagic/funcs.c 2020-02-26 09:55:13.859042500 +0100
- @@ -31,7 +31,6 @@
- #endif /* lint */
-
- #include "magic.h"
- -#include <assert.h>
- #include <stdarg.h>
- #include <stdlib.h>
- #include <string.h>
- @@ -42,78 +41,77 @@
- #if defined(HAVE_WCTYPE_H)
- #include <wctype.h>
- #endif
- -#if defined(HAVE_LIMITS_H)
- -#include <limits.h>
- +#if defined(HAVE_LOCALE_H)
- +#include <locale.h>
- #endif
-
- #ifndef SIZE_MAX
- #define SIZE_MAX ((size_t)~0)
- #endif
-
- -/*
- - * Like printf, only we append to a buffer.
- - */
- -protected int
- -file_vprintf(struct magic_set *ms, const char *fmt, va_list ap)
- -{
- - int len;
- - char *buf, *newstr;
- +#include "php.h"
- +#include "main/php_network.h"
-
- - if (ms->event_flags & EVENT_HAD_ERR)
- - return 0;
- - len = vasprintf(&buf, fmt, ap);
- - if (len < 0)
- - goto out;
- -
- - if (ms->o.buf != NULL) {
- - len = asprintf(&newstr, "%s%s", ms->o.buf, buf);
- - free(buf);
- - if (len < 0)
- - goto out;
- - free(ms->o.buf);
- - buf = newstr;
- - }
- - ms->o.buf = buf;
- - return 0;
- -out:
- - fprintf(stderr, "vasprintf failed (%s)", strerror(errno));
- - return -1;
- -}
- +#ifndef PREG_OFFSET_CAPTURE
- +# define PREG_OFFSET_CAPTURE (1<<8)
- +#endif
-
- protected int
- file_printf(struct magic_set *ms, const char *fmt, ...)
- {
- - int rv;
- va_list ap;
- + size_t len;
- + char *buf = NULL, *newstr;
-
- va_start(ap, fmt);
- - rv = file_vprintf(ms, fmt, ap);
- + len = vspprintf(&buf, 0, fmt, ap);
- va_end(ap);
- - return rv;
- +
- + if (ms->o.buf != NULL) {
- + len = spprintf(&newstr, 0, "%s%s", ms->o.buf, (buf ? buf : ""));
- + if (buf) {
- + efree(buf);
- + }
- + efree(ms->o.buf);
- + ms->o.buf = newstr;
- + } else {
- + ms->o.buf = buf;
- + }
- + return 0;
- }
-
- /*
- * error - print best error message possible
- */
- /*VARARGS*/
- -__attribute__((__format__(__printf__, 3, 0)))
- private void
- file_error_core(struct magic_set *ms, int error, const char *f, va_list va,
- size_t lineno)
- {
- + char *buf = NULL;
- +
- /* Only the first error is ok */
- if (ms->event_flags & EVENT_HAD_ERR)
- return;
- if (lineno != 0) {
- - free(ms->o.buf);
- + efree(ms->o.buf);
- ms->o.buf = NULL;
- file_printf(ms, "line %" SIZE_T_FORMAT "u:", lineno);
- }
- - if (ms->o.buf && *ms->o.buf)
- - file_printf(ms, " ");
- - file_vprintf(ms, f, va);
- - if (error > 0)
- - file_printf(ms, " (%s)", strerror(error));
- +
- + vspprintf(&buf, 0, f, va);
- + va_end(va);
- +
- + if (error > 0) {
- + file_printf(ms, "%s (%s)", (*buf ? buf : ""), strerror(error));
- + } else if (*buf) {
- + file_printf(ms, "%s", buf);
- + }
- +
- + if (buf) {
- + efree(buf);
- + }
- +
- ms->event_flags |= EVENT_HAD_ERR;
- ms->error = error;
- }
- @@ -160,7 +158,6 @@
- file_error(ms, errno, "error reading");
- }
-
- -#ifndef COMPILE_ONLY
-
- static int
- checkdone(struct magic_set *ms, int *rv)
- @@ -174,8 +171,8 @@
-
- /*ARGSUSED*/
- protected int
- -file_buffer(struct magic_set *ms, int fd, const char *inname __attribute__ ((__unused__)),
- - const void *buf, size_t nb)
- +file_buffer(struct magic_set *ms, php_stream *stream, const char *inname, const void *buf,
- + size_t nb)
- {
- int m = 0, rv = 0, looks_text = 0;
- const char *code = NULL;
- @@ -184,7 +181,8 @@
- const char *def = "data";
- const char *ftype = NULL;
- struct buffer b;
- -
- + int fd = -1;
- +
- buffer_init(&b, fd, buf, nb);
-
- if (nb == 0) {
- @@ -216,8 +214,8 @@
- }
- }
- #endif
- -#if HAVE_FORK
- - /* try compression stuff */
- +
- +#if PHP_FILEINFO_UNCOMPRESS
- if ((ms->flags & MAGIC_NO_CHECK_COMPRESS) == 0) {
- m = file_zmagic(ms, &b, inname);
- if ((ms->flags & MAGIC_DEBUG) != 0)
- @@ -239,13 +237,22 @@
- }
-
- /* Check if we have a CDF file */
- - if ((ms->flags & MAGIC_NO_CHECK_CDF) == 0) {
- - m = file_trycdf(ms, &b);
- - if ((ms->flags & MAGIC_DEBUG) != 0)
- - (void)fprintf(stderr, "[try cdf %d]\n", m);
- - if (m) {
- - if (checkdone(ms, &rv))
- - goto done;
- + if ((ms->flags & MAGIC_NO_CHECK_CDF) == 0 && stream) {
- +#ifdef _WIN64
- + php_socket_t _fd = fd;
- + int _ret = php_stream_cast(stream, PHP_STREAM_AS_FD, (void **)&_fd, 0);
- + fd = (int)_fd;
- +#else
- + int _ret = php_stream_cast(stream, PHP_STREAM_AS_FD, (void **)&fd, 0);
- +#endif
- + if (SUCCESS == _ret) {
- + m = file_trycdf(ms, &b);
- + if ((ms->flags & MAGIC_DEBUG) != 0)
- + (void)fprintf(stderr, "[try cdf %d]\n", m);
- + if (m) {
- + if (checkdone(ms, &rv))
- + goto done;
- + }
- }
- }
-
- @@ -315,7 +322,7 @@
- if (file_printf(ms, "%s", code_mime) == -1)
- rv = -1;
- }
- -#if HAVE_FORK
- +#if PHP_FILEINFO_UNCOMPRESS
- done_encoding:
- #endif
- buffer_fini(&b);
- @@ -324,7 +331,6 @@
-
- return m;
- }
- -#endif
-
- protected int
- file_reset(struct magic_set *ms, int checkloaded)
- @@ -334,11 +340,11 @@
- return -1;
- }
- if (ms->o.buf) {
- - free(ms->o.buf);
- + efree(ms->o.buf);
- ms->o.buf = NULL;
- }
- if (ms->o.pbuf) {
- - free(ms->o.pbuf);
- + efree(ms->o.pbuf);
- ms->o.pbuf = NULL;
- }
- ms->event_flags &= ~EVENT_HAD_ERR;
- @@ -376,7 +382,7 @@
- return NULL;
- }
- psize = len * 4 + 1;
- - if ((pbuf = CAST(char *, realloc(ms->o.pbuf, psize))) == NULL) {
- + if ((pbuf = CAST(char *, erealloc(ms->o.pbuf, psize))) == NULL) {
- file_oomem(ms, psize);
- return NULL;
- }
- @@ -440,8 +446,8 @@
- if (level >= ms->c.len) {
- len = (ms->c.len = 20 + level) * sizeof(*ms->c.li);
- ms->c.li = CAST(struct level_info *, (ms->c.li == NULL) ?
- - malloc(len) :
- - realloc(ms->c.li, len));
- + emalloc(len) :
- + erealloc(ms->c.li, len));
- if (ms->c.li == NULL) {
- file_oomem(ms, len);
- return -1;
- @@ -464,76 +470,38 @@
- protected int
- file_replace(struct magic_set *ms, const char *pat, const char *rep)
- {
- - file_regex_t rx;
- - int rc, rv = -1;
- -
- - rc = file_regcomp(&rx, pat, REG_EXTENDED);
- - if (rc) {
- - file_regerror(&rx, rc, ms);
- - } else {
- - regmatch_t rm;
- - int nm = 0;
- - while (file_regexec(&rx, ms->o.buf, 1, &rm, 0) == 0) {
- - ms->o.buf[rm.rm_so] = '\0';
- - if (file_printf(ms, "%s%s", rep,
- - rm.rm_eo != 0 ? ms->o.buf + rm.rm_eo : "") == -1)
- - goto out;
- - nm++;
- - }
- - rv = nm;
- + zval patt;
- + uint32_t opts = 0;
- + pcre_cache_entry *pce;
- + zend_string *res;
- + zend_string *repl;
- + size_t rep_cnt = 0;
- +
- + opts |= PCRE2_MULTILINE;
- + convert_libmagic_pattern(&patt, (char*)pat, strlen(pat), opts);
- + if ((pce = pcre_get_compiled_regex_cache_ex(Z_STR(patt), 0)) == NULL) {
- + zval_ptr_dtor(&patt);
- + rep_cnt = -1;
- + goto out;
- }
- -out:
- - file_regfree(&rx);
- - return rv;
- -}
- + zval_ptr_dtor(&patt);
-
- -protected int
- -file_regcomp(file_regex_t *rx, const char *pat, int flags)
- -{
- -#ifdef USE_C_LOCALE
- - rx->c_lc_ctype = newlocale(LC_CTYPE_MASK, "C", 0);
- - assert(rx->c_lc_ctype != NULL);
- - rx->old_lc_ctype = uselocale(rx->c_lc_ctype);
- - assert(rx->old_lc_ctype != NULL);
- -#else
- - rx->old_lc_ctype = setlocale(LC_CTYPE, "C");
- -#endif
- - rx->pat = pat;
- + repl = zend_string_init(rep, strlen(rep), 0);
- + res = php_pcre_replace_impl(pce, NULL, ms->o.buf, strlen(ms->o.buf), repl, -1, &rep_cnt);
-
- - return rx->rc = regcomp(&rx->rx, pat, flags);
- -}
- + zend_string_release_ex(repl, 0);
- + if (NULL == res) {
- + rep_cnt = -1;
- + goto out;
- + }
-
- -protected int
- -file_regexec(file_regex_t *rx, const char *str, size_t nmatch,
- - regmatch_t* pmatch, int eflags)
- -{
- - assert(rx->rc == 0);
- - /* XXX: force initialization because glibc does not always do this */
- - memset(pmatch, 0, nmatch * sizeof(*pmatch));
- - return regexec(&rx->rx, str, nmatch, pmatch, eflags);
- -}
- + strncpy(ms->o.buf, ZSTR_VAL(res), ZSTR_LEN(res));
- + ms->o.buf[ZSTR_LEN(res)] = '\0';
-
- -protected void
- -file_regfree(file_regex_t *rx)
- -{
- - if (rx->rc == 0)
- - regfree(&rx->rx);
- -#ifdef USE_C_LOCALE
- - (void)uselocale(rx->old_lc_ctype);
- - freelocale(rx->c_lc_ctype);
- -#else
- - (void)setlocale(LC_CTYPE, rx->old_lc_ctype);
- -#endif
- -}
- + zend_string_release_ex(res, 0);
-
- -protected void
- -file_regerror(file_regex_t *rx, int rc, struct magic_set *ms)
- -{
- - char errmsg[512];
- -
- - (void)regerror(rc, &rx->rx, errmsg, sizeof(errmsg));
- - file_magerror(ms, "regex error %d for `%s', (%s)", rc, rx->pat,
- - errmsg);
- +out:
- + return rep_cnt;
- }
-
- protected file_pushbuf_t *
- @@ -544,7 +512,7 @@
- if (ms->event_flags & EVENT_HAD_ERR)
- return NULL;
-
- - if ((pb = (CAST(file_pushbuf_t *, malloc(sizeof(*pb))))) == NULL)
- + if ((pb = (CAST(file_pushbuf_t *, emalloc(sizeof(*pb))))) == NULL)
- return NULL;
-
- pb->buf = ms->o.buf;
- @@ -562,8 +530,8 @@
- char *rbuf;
-
- if (ms->event_flags & EVENT_HAD_ERR) {
- - free(pb->buf);
- - free(pb);
- + efree(pb->buf);
- + efree(pb);
- return NULL;
- }
-
- @@ -572,7 +540,7 @@
- ms->o.buf = pb->buf;
- ms->offset = pb->offset;
-
- - free(pb);
- + efree(pb);
- return rbuf;
- }
-
- diff -u libmagic.orig/magic.c libmagic/magic.c
- --- libmagic.orig/magic.c 2017-08-28 15:39:18.000000000 +0200
- +++ libmagic/magic.c 2020-02-26 09:55:13.861044300 +0100
- @@ -25,11 +25,6 @@
- * SUCH DAMAGE.
- */
-
- -#ifdef WIN32
- -#include <windows.h>
- -#include <shlwapi.h>
- -#endif
- -
- #include "file.h"
-
- #ifndef lint
- @@ -39,14 +34,19 @@
- #include "magic.h"
-
- #include <stdlib.h>
- +#ifdef PHP_WIN32
- +#include "win32/unistd.h"
- +#else
- #include <unistd.h>
- +#endif
- #include <string.h>
- -#ifdef QUICK
- -#include <sys/mman.h>
- +#include "config.h"
- +
- +#ifdef PHP_WIN32
- +#include <shlwapi.h>
- #endif
- -#ifdef HAVE_LIMITS_H
- +
- #include <limits.h> /* for PIPE_BUF */
- -#endif
-
- #if defined(HAVE_UTIMES)
- # include <sys/time.h>
- @@ -71,194 +71,23 @@
- #endif
- #endif
-
- +#ifdef PHP_WIN32
- +# undef S_IFLNK
- +# undef S_IFIFO
- +#endif
- +
- private void close_and_restore(const struct magic_set *, const char *, int,
- - const struct stat *);
- + const zend_stat_t *);
- private int unreadable_info(struct magic_set *, mode_t, const char *);
- +#if 0
- private const char* get_default_magic(void);
- -#ifndef COMPILE_ONLY
- -private const char *file_or_fd(struct magic_set *, const char *, int);
- #endif
- +private const char *file_or_stream(struct magic_set *, const char *, php_stream *);
-
- #ifndef STDIN_FILENO
- #define STDIN_FILENO 0
- #endif
-
- -#ifdef WIN32
- -/* HINSTANCE of this shared library. Needed for get_default_magic() */
- -static HINSTANCE _w32_dll_instance = NULL;
- -
- -static void
- -_w32_append_path(char **hmagicpath, const char *fmt, ...)
- -{
- - char *tmppath;
- - char *newpath;
- - va_list ap;
- -
- - va_start(ap, fmt);
- - if (vasprintf(&tmppath, fmt, ap) < 0) {
- - va_end(ap);
- - return;
- - }
- - va_end(ap);
- -
- - if (access(tmppath, R_OK) == -1)
- - goto out;
- -
- - if (*hmagicpath == NULL) {
- - *hmagicpath = tmppath;
- - return;
- - }
- -
- - if (asprintf(&newpath, "%s%c%s", *hmagicpath, PATHSEP, tmppath) < 0)
- - goto out;
- -
- - free(*hmagicpath);
- - free(tmppath);
- - *hmagicpath = newpath;
- - return;
- -out:
- - free(tmppath);
- -}
- -
- -static void
- -_w32_get_magic_relative_to(char **hmagicpath, HINSTANCE module)
- -{
- - static const char *trypaths[] = {
- - "%s/share/misc/magic.mgc",
- - "%s/magic.mgc",
- - };
- - LPSTR dllpath;
- - size_t sp;
- -
- - dllpath = calloc(MAX_PATH + 1, sizeof(*dllpath));
- -
- - if (!GetModuleFileNameA(module, dllpath, MAX_PATH))
- - goto out;
- -
- - PathRemoveFileSpecA(dllpath);
- -
- - if (module) {
- - char exepath[MAX_PATH];
- - GetModuleFileNameA(NULL, exepath, MAX_PATH);
- - PathRemoveFileSpecA(exepath);
- - if (stricmp(exepath, dllpath) == 0)
- - goto out;
- - }
- -
- - sp = strlen(dllpath);
- - if (sp > 3 && stricmp(&dllpath[sp - 3], "bin") == 0) {
- - _w32_append_path(hmagicpath,
- - "%s/../share/misc/magic.mgc", dllpath);
- - goto out;
- - }
- -
- - for (sp = 0; sp < __arraycount(trypaths); sp++)
- - _w32_append_path(hmagicpath, trypaths[sp], dllpath);
- -out:
- - free(dllpath);
- -}
- -
- -/* Placate GCC by offering a sacrificial previous prototype */
- -BOOL WINAPI DllMain(HINSTANCE, DWORD, LPVOID);
- -
- -BOOL WINAPI
- -DllMain(HINSTANCE hinstDLL, DWORD fdwReason,
- - LPVOID lpvReserved __attribute__((__unused__)))
- -{
- - if (fdwReason == DLL_PROCESS_ATTACH)
- - _w32_dll_instance = hinstDLL;
- - return 1;
- -}
- -#endif
- -
- -private const char *
- -get_default_magic(void)
- -{
- - static const char hmagic[] = "/.magic/magic.mgc";
- - static char *default_magic;
- - char *home, *hmagicpath;
- -
- -#ifndef WIN32
- - struct stat st;
- -
- - if (default_magic) {
- - free(default_magic);
- - default_magic = NULL;
- - }
- - if ((home = getenv("HOME")) == NULL)
- - return MAGIC;
- -
- - if (asprintf(&hmagicpath, "%s/.magic.mgc", home) < 0)
- - return MAGIC;
- - if (stat(hmagicpath, &st) == -1) {
- - free(hmagicpath);
- - if (asprintf(&hmagicpath, "%s/.magic", home) < 0)
- - return MAGIC;
- - if (stat(hmagicpath, &st) == -1)
- - goto out;
- - if (S_ISDIR(st.st_mode)) {
- - free(hmagicpath);
- - if (asprintf(&hmagicpath, "%s/%s", home, hmagic) < 0)
- - return MAGIC;
- - if (access(hmagicpath, R_OK) == -1)
- - goto out;
- - }
- - }
- -
- - if (asprintf(&default_magic, "%s:%s", hmagicpath, MAGIC) < 0)
- - goto out;
- - free(hmagicpath);
- - return default_magic;
- -out:
- - default_magic = NULL;
- - free(hmagicpath);
- - return MAGIC;
- -#else
- - hmagicpath = NULL;
- -
- - if (default_magic) {
- - free(default_magic);
- - default_magic = NULL;
- - }
- -
- - /* First, try to get a magic file from user-application data */
- - if ((home = getenv("LOCALAPPDATA")) != NULL)
- - _w32_append_path(&hmagicpath, "%s%s", home, hmagic);
- -
- - /* Second, try to get a magic file from the user profile data */
- - if ((home = getenv("USERPROFILE")) != NULL)
- - _w32_append_path(&hmagicpath,
- - "%s/Local Settings/Application Data%s", home, hmagic);
- -
- - /* Third, try to get a magic file from Common Files */
- - if ((home = getenv("COMMONPROGRAMFILES")) != NULL)
- - _w32_append_path(&hmagicpath, "%s%s", home, hmagic);
- -
- - /* Fourth, try to get magic file relative to exe location */
- - _w32_get_magic_relative_to(&hmagicpath, NULL);
- -
- - /* Fifth, try to get magic file relative to dll location */
- - _w32_get_magic_relative_to(&hmagicpath, _w32_dll_instance);
- -
- - /* Avoid MAGIC constant - it likely points to a file within MSys tree */
- - default_magic = hmagicpath;
- - return default_magic;
- -#endif
- -}
- -
- -public const char *
- -magic_getpath(const char *magicfile, int action)
- -{
- - if (magicfile != NULL)
- - return magicfile;
- -
- - magicfile = getenv("MAGIC");
- - if (magicfile != NULL)
- - return magicfile;
- -
- - return action == FILE_LOAD ? get_default_magic() : MAGIC;
- -}
- -
- public struct magic_set *
- magic_open(int flags)
- {
- @@ -304,20 +133,6 @@
- return file_apprentice(ms, magicfile, FILE_LOAD);
- }
-
- -#ifndef COMPILE_ONLY
- -/*
- - * Install a set of compiled magic buffers.
- - */
- -public int
- -magic_load_buffers(struct magic_set *ms, void **bufs, size_t *sizes,
- - size_t nbufs)
- -{
- - if (ms == NULL)
- - return -1;
- - return buffer_apprentice(ms, (struct magic **)bufs, sizes, nbufs);
- -}
- -#endif
- -
- public int
- magic_compile(struct magic_set *ms, const char *magicfile)
- {
- @@ -344,7 +159,7 @@
-
- private void
- close_and_restore(const struct magic_set *ms, const char *name, int fd,
- - const struct stat *sb)
- + const zend_stat_t *sb)
- {
- if (fd == STDIN_FILENO || name == NULL)
- return;
- @@ -375,7 +190,6 @@
- }
- }
-
- -#ifndef COMPILE_ONLY
-
- /*
- * find type of descriptor
- @@ -385,7 +199,7 @@
- {
- if (ms == NULL)
- return NULL;
- - return file_or_fd(ms, NULL, fd);
- + return file_or_stream(ms, NULL, NULL);
- }
-
- /*
- @@ -396,31 +210,42 @@
- {
- if (ms == NULL)
- return NULL;
- - return file_or_fd(ms, inname, STDIN_FILENO);
- + return file_or_stream(ms, inname, NULL);
- +}
- +
- +public const char *
- +magic_stream(struct magic_set *ms, php_stream *stream)
- +{
- + if (ms == NULL)
- + return NULL;
- + return file_or_stream(ms, NULL, stream);
- }
-
- private const char *
- -file_or_fd(struct magic_set *ms, const char *inname, int fd)
- +file_or_stream(struct magic_set *ms, const char *inname, php_stream *stream)
- {
- int rv = -1;
- unsigned char *buf;
- - struct stat sb;
- + zend_stat_t sb;
- ssize_t nbytes = 0; /* number of bytes read from a datafile */
- - int ispipe = 0;
- - off_t pos = (off_t)-1;
- + int no_in_stream = 0;
-
- if (file_reset(ms, 1) == -1)
- goto out;
-
- + if (!inname && !stream) {
- + return NULL;
- + }
- +
- /*
- * one extra for terminating '\0', and
- * some overlapping space for matches near EOF
- */
- #define SLOP (1 + sizeof(union VALUETYPE))
- - if ((buf = CAST(unsigned char *, malloc(ms->bytes_max + SLOP))) == NULL)
- + if ((buf = CAST(unsigned char *, emalloc(ms->bytes_max + SLOP))) == NULL)
- return NULL;
-
- - switch (file_fsmagic(ms, inname, &sb)) {
- + switch (file_fsmagic(ms, inname, &sb, stream)) {
- case -1: /* error */
- goto done;
- case 0: /* nothing found */
- @@ -430,103 +255,41 @@
- goto done;
- }
-
- -#ifdef WIN32
- - /* Place stdin in binary mode, so EOF (Ctrl+Z) doesn't stop early. */
- - if (fd == STDIN_FILENO)
- - _setmode(STDIN_FILENO, O_BINARY);
- -#endif
- -
- - if (inname == NULL) {
- - if (fstat(fd, &sb) == 0 && S_ISFIFO(sb.st_mode))
- - ispipe = 1;
- - else
- - pos = lseek(fd, (off_t)0, SEEK_CUR);
- - } else {
- - int flags = O_RDONLY|O_BINARY;
- - int okstat = stat(inname, &sb) == 0;
- + errno = 0;
-
- - if (okstat && S_ISFIFO(sb.st_mode)) {
- -#ifdef O_NONBLOCK
- - flags |= O_NONBLOCK;
- -#endif
- - ispipe = 1;
- - }
- + if (!stream && inname) {
- + no_in_stream = 1;
- + stream = php_stream_open_wrapper((char *)inname, "rb", REPORT_ERRORS, NULL);
- + }
-
- - errno = 0;
- - if ((fd = open(inname, flags)) < 0) {
- -#ifdef WIN32
- - /*
- - * Can't stat, can't open. It may have been opened in
- - * fsmagic, so if the user doesn't have read permission,
- - * allow it to say so; otherwise an error was probably
- - * displayed in fsmagic.
- - */
- - if (!okstat && errno == EACCES) {
- - sb.st_mode = S_IFBLK;
- - okstat = 1;
- - }
- -#endif
- - if (okstat &&
- - unreadable_info(ms, sb.st_mode, inname) == -1)
- - goto done;
- - rv = 0;
- + if (!stream) {
- + if (unreadable_info(ms, sb.st_mode, inname) == -1)
- goto done;
- - }
- + rv = 0;
- + goto done;
- + }
- +
- #ifdef O_NONBLOCK
- - if ((flags = fcntl(fd, F_GETFL)) != -1) {
- - flags &= ~O_NONBLOCK;
- - (void)fcntl(fd, F_SETFL, flags);
- - }
- +/* we should be already be in non blocking mode for network socket */
- #endif
- - }
-
- /*
- * try looking at the first ms->bytes_max bytes
- */
- - if (ispipe) {
- - ssize_t r = 0;
- -
- - while ((r = sread(fd, (void *)&buf[nbytes],
- - (size_t)(ms->bytes_max - nbytes), 1)) > 0) {
- - nbytes += r;
- - if (r < PIPE_BUF) break;
- - }
- -
- - if (nbytes == 0 && inname) {
- - /* We can not read it, but we were able to stat it. */
- - if (unreadable_info(ms, sb.st_mode, inname) == -1)
- - goto done;
- - rv = 0;
- - goto done;
- - }
- -
- - } else {
- - /* Windows refuses to read from a big console buffer. */
- - size_t howmany =
- -#if defined(WIN32)
- - _isatty(fd) ? 8 * 1024 :
- -#endif
- - ms->bytes_max;
- - if ((nbytes = read(fd, (char *)buf, howmany)) == -1) {
- - if (inname == NULL && fd != STDIN_FILENO)
- - file_error(ms, errno, "cannot read fd %d", fd);
- - else
- - file_error(ms, errno, "cannot read `%s'",
- - inname == NULL ? "/dev/stdin" : inname);
- - goto done;
- - }
- + if ((nbytes = php_stream_read(stream, (char *)buf, ms->bytes_max - nbytes)) < 0) {
- + file_error(ms, errno, "cannot read `%s'", inname);
- + goto done;
- }
-
- (void)memset(buf + nbytes, 0, SLOP); /* NUL terminate */
- - if (file_buffer(ms, fd, inname, buf, (size_t)nbytes) == -1)
- + if (file_buffer(ms, stream, inname, buf, (size_t)nbytes) == -1)
- goto done;
- rv = 0;
- done:
- - free(buf);
- - if (fd != -1) {
- - if (pos != (off_t)-1)
- - (void)lseek(fd, pos, SEEK_SET);
- - close_and_restore(ms, inname, fd, &sb);
- + efree(buf);
- +
- + if (no_in_stream && stream) {
- + php_stream_close(stream);
- }
- out:
- return rv == 0 ? file_getbuffer(ms) : NULL;
- @@ -544,12 +307,11 @@
- * The main work is done here!
- * We have the file name and/or the data buffer to be identified.
- */
- - if (file_buffer(ms, -1, NULL, buf, nb) == -1) {
- + if (file_buffer(ms, NULL, NULL, buf, nb) == -1) {
- return NULL;
- }
- return file_getbuffer(ms);
- }
- -#endif
-
- public const char *
- magic_error(struct magic_set *ms)
- diff -u libmagic.orig/magic.h libmagic/magic.h
- --- libmagic.orig/magic.h 2020-02-26 09:56:58.945274100 +0100
- +++ libmagic/magic.h 2020-02-26 09:55:13.862044300 +0100
- @@ -122,6 +122,7 @@
-
- const char *magic_getpath(const char *, int);
- const char *magic_file(magic_t, const char *);
- +const char *magic_stream(magic_t, php_stream *);
- const char *magic_descriptor(magic_t, int);
- const char *magic_buffer(magic_t, const void *, size_t);
-
- diff -u libmagic.orig/print.c libmagic/print.c
- --- libmagic.orig/print.c 2017-02-10 19:14:01.000000000 +0100
- +++ libmagic/print.c 2020-02-26 09:55:13.864043900 +0100
- @@ -2,7 +2,7 @@
- * Copyright (c) Ian F. Darwin 1986-1995.
- * Software written by Ian F. Darwin and others;
- * maintained 1995-present by Christos Zoulas and others.
- - *
- + *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- @@ -12,7 +12,7 @@
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- - *
- + *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- @@ -28,6 +28,7 @@
- /*
- * print.c - debugging printout routines
- */
- +#include "php.h"
-
- #include "file.h"
-
- @@ -75,7 +76,7 @@
- if (m->mask_op & FILE_OPINVERSE)
- (void) fputc('~', stderr);
-
- - if (IS_STRING(m->type)) {
- + if (IS_LIBMAGIC_STRING(m->type)) {
- if (m->str_flags) {
- (void) fputc('/', stderr);
- if (m->str_flags & STRING_COMPACT_WHITESPACE)
- @@ -215,18 +216,18 @@
- file_magwarn(struct magic_set *ms, const char *f, ...)
- {
- va_list va;
- + char *expanded_format = NULL;
- + int expanded_len;
-
- - /* cuz we use stdout for most, stderr here */
- - (void) fflush(stdout);
- -
- - if (ms->file)
- - (void) fprintf(stderr, "%s, %lu: ", ms->file,
- - (unsigned long)ms->line);
- - (void) fprintf(stderr, "Warning: ");
- va_start(va, f);
- - (void) vfprintf(stderr, f, va);
- + expanded_len = vasprintf(&expanded_format, f, va);
- va_end(va);
- - (void) fputc('\n', stderr);
- +
- + if (expanded_len >= 0 && expanded_format) {
- + php_error_docref(NULL, E_NOTICE, "Warning: %s", expanded_format);
- +
- + free(expanded_format);
- + }
- }
-
- protected const char *
- @@ -247,13 +248,13 @@
- }
-
- if (flags & FILE_T_LOCAL) {
- - tm = localtime_r(&t, &tmz);
- + tm = php_localtime_r(&t, &tmz);
- } else {
- - tm = gmtime_r(&t, &tmz);
- + tm = php_gmtime_r(&t, &tmz);
- }
- if (tm == NULL)
- goto out;
- - pp = asctime_r(tm, buf);
- + pp = php_asctime_r(tm, buf);
-
- if (pp == NULL)
- goto out;
- diff -u libmagic.orig/readcdf.c libmagic/readcdf.c
- --- libmagic.orig/readcdf.c 2017-11-02 21:25:39.000000000 +0100
- +++ libmagic/readcdf.c 2020-02-26 09:55:13.865044100 +0100
- @@ -31,7 +31,11 @@
-
- #include <assert.h>
- #include <stdlib.h>
- +#ifdef PHP_WIN32
- +#include "win32/unistd.h"
- +#else
- #include <unistd.h>
- +#endif
- #include <string.h>
- #include <time.h>
- #include <ctype.h>
- @@ -104,10 +108,6 @@
- if (clsid[0] == cv[i].clsid[0] && clsid[1] == cv[i].clsid[1])
- return cv[i].mime;
- }
- -#ifdef CDF_DEBUG
- - fprintf(stderr, "unknown mime %" PRIx64 ", %" PRIx64 "\n", clsid[0],
- - clsid[1]);
- -#endif
- return NULL;
- }
-
- @@ -116,30 +116,24 @@
- {
- size_t i;
- const char *rv = NULL;
- -#ifdef USE_C_LOCALE
- - locale_t old_lc_ctype, c_lc_ctype;
- + char *vbuf_lower;
-
- - c_lc_ctype = newlocale(LC_CTYPE_MASK, "C", 0);
- - assert(c_lc_ctype != NULL);
- - old_lc_ctype = uselocale(c_lc_ctype);
- - assert(old_lc_ctype != NULL);
- -#else
- - char *old_lc_ctype = setlocale(LC_CTYPE, "C");
- -#endif
- - for (i = 0; nv[i].pattern != NULL; i++)
- - if (strcasestr(vbuf, nv[i].pattern) != NULL) {
- + vbuf_lower = zend_str_tolower_dup(vbuf, strlen(vbuf));
- + for (i = 0; nv[i].pattern != NULL; i++) {
- + char *pattern_lower;
- + int found;
- +
- + pattern_lower = zend_str_tolower_dup(nv[i].pattern, strlen(nv[i].pattern));
- + found = (strstr(vbuf_lower, pattern_lower) != NULL);
- + efree(pattern_lower);
- +
- + if (found) {
- rv = nv[i].mime;
- break;
- }
- -#ifdef CDF_DEBUG
- - fprintf(stderr, "unknown app %s\n", vbuf);
- -#endif
- -#ifdef USE_C_LOCALE
- - (void)uselocale(old_lc_ctype);
- - freelocale(c_lc_ctype);
- -#else
- - setlocale(LC_CTYPE, old_lc_ctype);
- -#endif
- + }
- +
- + efree(vbuf_lower);
- return rv;
- }
-
- @@ -155,6 +149,8 @@
- const char *s, *e;
- int len;
-
- + memset(&ts, 0, sizeof(ts));
- +
- if (!NOTMIME(ms) && root_storage)
- str = cdf_clsid_to_mime(root_storage->d_storage_uuid,
- clsid2mime);
- @@ -281,10 +277,10 @@
- if (file_printf(ms, "%s%s",
- cdf_u16tos8(buf, ce[i].ce_namlen, ce[i].ce_name),
- i == cat->cat_num - 1 ? "]" : ", ") == -1) {
- - free(cat);
- + efree(cat);
- return -1;
- }
- - free(cat);
- + efree(cat);
- } else {
- if (file_printf(ms, "application/CDFV2") == -1)
- return -1;
- @@ -345,7 +341,7 @@
- }
-
- m = cdf_file_property_info(ms, info, count, root_storage);
- - free(info);
- + efree(info);
-
- return m == -1 ? -2 : m;
- }
- @@ -353,11 +349,11 @@
- #ifdef notdef
- private char *
- format_clsid(char *buf, size_t len, const uint64_t uuid[2]) {
- - snprintf(buf, len, "%.8" PRIx64 "-%.4" PRIx64 "-%.4" PRIx64 "-%.4"
- + snprintf(buf, len, "%.8" PRIx64 "-%.4" PRIx64 "-%.4" PRIx64 "-%.4"
- PRIx64 "-%.12" PRIx64,
- (uuid[0] >> 32) & (uint64_t)0x000000000ffffffffULL,
- (uuid[0] >> 16) & (uint64_t)0x0000000000000ffffULL,
- - (uuid[0] >> 0) & (uint64_t)0x0000000000000ffffULL,
- + (uuid[0] >> 0) & (uint64_t)0x0000000000000ffffULL,
- (uuid[1] >> 48) & (uint64_t)0x0000000000000ffffULL,
- (uuid[1] >> 0) & (uint64_t)0x0000fffffffffffffULL);
- return buf;
- @@ -436,7 +432,7 @@
- const char *sections[5];
- const int types[5];
- } sectioninfo[] = {
- - { "Encrypted", "encrypted",
- + { "Encrypted", "encrypted",
- {
- "EncryptedPackage", "EncryptedSummary",
- NULL, NULL, NULL,
- @@ -448,7 +444,7 @@
-
- },
- },
- - { "QuickBooks", "quickbooks",
- + { "QuickBooks", "quickbooks",
- {
- #if 0
- "TaxForms", "PDFTaxForms", "modulesInBackup",
- @@ -655,11 +651,11 @@
- cdf_zero_stream(&scn);
- cdf_zero_stream(&sst);
- out3:
- - free(dir.dir_tab);
- + efree(dir.dir_tab);
- out2:
- - free(ssat.sat_tab);
- + efree(ssat.sat_tab);
- out1:
- - free(sat.sat_tab);
- + efree(sat.sat_tab);
- out0:
- if (i == -1) {
- if (NOTMIME(ms)) {
- diff -u libmagic.orig/softmagic.c libmagic/softmagic.c
- --- libmagic.orig/softmagic.c 2018-04-15 20:49:15.000000000 +0200
- +++ libmagic/softmagic.c 2020-02-26 09:55:13.866043500 +0100
- @@ -43,6 +43,10 @@
- #include <time.h>
- #include "der.h"
-
- +#ifndef PREG_OFFSET_CAPTURE
- +# define PREG_OFFSET_CAPTURE (1<<8)
- +#endif
- +
- private int match(struct magic_set *, struct magic *, uint32_t,
- const struct buffer *, size_t, int, int, int, uint16_t *,
- uint16_t *, int *, int *, int *);
- @@ -119,8 +123,8 @@
- return 0;
- }
-
- -#define FILE_FMTDEBUG
- -#ifdef FILE_FMTDEBUG
- +
- +#if defined(FILE_FMTDEBUG) && defined(HAVE_FMTCHECK)
- #define F(a, b, c) file_fmtcheck((a), (b), (c), __FILE__, __LINE__)
-
- private const char * __attribute__((__format_arg__(3)))
- @@ -134,8 +138,10 @@
- " with `%s'", file, line, desc, def);
- return ptr;
- }
- -#else
- +#elif defined(HAVE_FMTCHECK)
- #define F(a, b, c) fmtcheck((b), (c))
- +#else
- +#define F(a, b, c) ((b))
- #endif
-
- /*
- @@ -189,7 +195,7 @@
- struct magic *m = &magic[magindex];
-
- if (m->type != FILE_NAME)
- - if ((IS_STRING(m->type) &&
- + if ((IS_LIBMAGIC_STRING(m->type) &&
- #define FLT (STRING_BINTEST | STRING_TEXTTEST)
- ((text && (m->str_flags & FLT) == STRING_BINTEST) ||
- (!text && (m->str_flags & FLT) == STRING_TEXTTEST))) ||
- @@ -416,42 +422,28 @@
- private int
- check_fmt(struct magic_set *ms, const char *fmt)
- {
- - file_regex_t rx;
- - int rc, rv = -1;
- + pcre_cache_entry *pce;
- + int rv = -1;
- + zend_string *pattern;
-
- if (strchr(fmt, '%') == NULL)
- return 0;
-
- - rc = file_regcomp(&rx, "%[-0-9\\.]*s", REG_EXTENDED|REG_NOSUB);
- - if (rc) {
- - file_regerror(&rx, rc, ms);
- + pattern = zend_string_init("~%[-0-9\\.]*s~", sizeof("~%[-0-9\\.]*s~") - 1, 0);
- + if ((pce = pcre_get_compiled_regex_cache_ex(pattern, 0)) == NULL) {
- + rv = -1;
- } else {
- - rc = file_regexec(&rx, fmt, 0, 0, 0);
- - rv = !rc;
- + pcre2_code *re = php_pcre_pce_re(pce);
- + pcre2_match_data *match_data = php_pcre_create_match_data(0, re);
- + if (match_data) {
- + rv = pcre2_match(re, (PCRE2_SPTR)fmt, strlen(fmt), 0, 0, match_data, php_pcre_mctx()) > 0;
- + php_pcre_free_match_data(match_data);
- + }
- }
- - file_regfree(&rx);
- + zend_string_release(pattern);
- return rv;
- }
-
- -#ifndef HAVE_STRNDUP
- -char * strndup(const char *, size_t);
- -
- -char *
- -strndup(const char *str, size_t n)
- -{
- - size_t len;
- - char *copy;
- -
- - for (len = 0; len < n && str[len]; len++)
- - continue;
- - if ((copy = malloc(len + 1)) == NULL)
- - return NULL;
- - (void)memcpy(copy, str, len);
- - copy[len] = '\0';
- - return copy;
- -}
- -#endif /* HAVE_STRNDUP */
- -
- static int
- varexpand(char *buf, size_t len, const struct buffer *b, const char *str)
- {
- @@ -743,14 +735,10 @@
- char *cp;
- int rval;
-
- - cp = strndup((const char *)ms->search.s, ms->search.rm_len);
- - if (cp == NULL) {
- - file_oomem(ms, ms->search.rm_len);
- - return -1;
- - }
- + cp = estrndup((const char *)ms->search.s, ms->search.rm_len);
- rval = file_printf(ms, F(ms, desc, "%s"),
- file_printable(sbuf, sizeof(sbuf), cp));
- - free(cp);
- + efree(cp);
-
- if (rval == -1)
- return -1;
- @@ -1135,7 +1123,7 @@
- * string by p->s, so we need to deduct sz.
- * Because we can use one of the bytes of the length
- * after we shifted as NUL termination.
- - */
- + */
- len = sz;
- }
- while (len--)
- @@ -1209,7 +1197,7 @@
- goto out;
- return 1;
- case FILE_BEDOUBLE:
- - p->q = BE64(p);
- + p->q = BE64(p);
- if (cvt_double(p, m) == -1)
- goto out;
- return 1;
- @@ -1481,8 +1469,6 @@
- return -1;
- }
-
- -
- -
- if (mcopy(ms, p, m->type, m->flag & INDIR, s, (uint32_t)(offset + o),
- (uint32_t)nbytes, m) == -1)
- return -1;
- @@ -1494,9 +1480,6 @@
- m->type, m->flag, offset, o, nbytes,
- *indir_count, *name_count);
- mdebug(offset, (char *)(void *)p, sizeof(union VALUETYPE));
- -#ifndef COMPILE_ONLY
- - file_mdump(m);
- -#endif
- }
-
- if (m->flag & INDIR) {
- @@ -1609,9 +1592,6 @@
- if ((ms->flags & MAGIC_DEBUG) != 0) {
- mdebug(offset, (char *)(void *)p,
- sizeof(union VALUETYPE));
- -#ifndef COMPILE_ONLY
- - file_mdump(m);
- -#endif
- }
- }
-
- @@ -1696,15 +1676,15 @@
- if (rv == 1) {
- if ((ms->flags & MAGIC_NODESC) == 0 &&
- file_printf(ms, F(ms, m->desc, "%u"), offset) == -1) {
- - free(rbuf);
- + if (rbuf) efree(rbuf);
- return -1;
- }
- if (file_printf(ms, "%s", rbuf) == -1) {
- - free(rbuf);
- + if (rbuf) efree(rbuf);
- return -1;
- }
- }
- - free(rbuf);
- + if (rbuf) efree(rbuf);
- return rv;
-
- case FILE_USE:
- @@ -1827,6 +1807,41 @@
- return file_strncmp(a, b, len, flags);
- }
-
- +public void
- +convert_libmagic_pattern(zval *pattern, char *val, size_t len, uint32_t options)
- +{
- + int i, j=0;
- + zend_string *t;
- +
- + t = zend_string_alloc(len * 2 + 4, 0);
- +
- + ZSTR_VAL(t)[j++] = '~';
- +
- + for (i = 0; i < len; i++, j++) {
- + switch (val[i]) {
- + case '~':
- + ZSTR_VAL(t)[j++] = '\\';
- + ZSTR_VAL(t)[j] = '~';
- + break;
- + default:
- + ZSTR_VAL(t)[j] = val[i];
- + break;
- + }
- + }
- + ZSTR_VAL(t)[j++] = '~';
- +
- + if (options & PCRE2_CASELESS)
- + ZSTR_VAL(t)[j++] = 'i';
- +
- + if (options & PCRE2_MULTILINE)
- + ZSTR_VAL(t)[j++] = 'm';
- +
- + ZSTR_VAL(t)[j]='\0';
- + ZSTR_LEN(t) = j;
- +
- + ZVAL_NEW_STR(pattern, t);
- +}
- +
- private int
- magiccheck(struct magic_set *ms, struct magic *m)
- {
- @@ -1987,65 +2002,77 @@
- break;
- }
- case FILE_REGEX: {
- - int rc;
- - file_regex_t rx;
- - const char *search;
- + zval pattern;
- + uint32_t options = 0;
- + pcre_cache_entry *pce;
-
- - if (ms->search.s == NULL)
- - return 0;
- + options |= PCRE2_MULTILINE;
-
- - l = 0;
- - rc = file_regcomp(&rx, m->value.s,
- - REG_EXTENDED|REG_NEWLINE|
- - ((m->str_flags & STRING_IGNORE_CASE) ? REG_ICASE : 0));
- - if (rc) {
- - file_regerror(&rx, rc, ms);
- - v = (uint64_t)-1;
- + if (m->str_flags & STRING_IGNORE_CASE) {
- + options |= PCRE2_CASELESS;
- + }
- +
- + convert_libmagic_pattern(&pattern, (char *)m->value.s, m->vallen, options);
- +
- + l = v = 0;
- + if ((pce = pcre_get_compiled_regex_cache(Z_STR(pattern))) == NULL) {
- + zval_ptr_dtor(&pattern);
- + return -1;
- } else {
- - regmatch_t pmatch;
- - size_t slen = ms->search.s_len;
- - char *copy;
- - if (slen != 0) {
- - copy = CAST(char *, malloc(slen));
- - if (copy == NULL) {
- - file_regfree(&rx);
- - file_error(ms, errno,
- - "can't allocate %" SIZE_T_FORMAT "u bytes",
- - slen);
- - return -1;
- - }
- - memcpy(copy, ms->search.s, slen);
- - copy[--slen] = '\0';
- - search = copy;
- + /* pce now contains the compiled regex */
- + zval retval;
- + zval subpats;
- + char *haystack;
- +
- + ZVAL_NULL(&retval);
- + ZVAL_NULL(&subpats);
- +
- + /* Cut the search len from haystack, equals to REG_STARTEND */
- + haystack = estrndup(ms->search.s, ms->search.s_len);
- +
- + /* match v = 0, no match v = 1 */
- + php_pcre_match_impl(pce, haystack, ms->search.s_len, &retval, &subpats, 0, 1, PREG_OFFSET_CAPTURE, 0);
- + /* Free haystack */
- + efree(haystack);
- +
- + if (Z_LVAL(retval) < 0) {
- + zval_ptr_dtor(&subpats);
- + zval_ptr_dtor(&pattern);
- + return -1;
- + } else if ((Z_LVAL(retval) > 0) && (Z_TYPE(subpats) == IS_ARRAY)) {
- + /* Need to fetch global match which equals pmatch[0] */
- + zval *pzval;
- + HashTable *ht = Z_ARRVAL(subpats);
- + if ((pzval = zend_hash_index_find(ht, 0)) != NULL && Z_TYPE_P(pzval) == IS_ARRAY) {
- + /* If everything goes according to the master plan
- + tmpcopy now contains two elements:
- + 0 = the match
- + 1 = starting position of the match */
- + zval *match, *offset;
- + if ((match = zend_hash_index_find(Z_ARRVAL_P(pzval), 0)) &&
- + (offset = zend_hash_index_find(Z_ARRVAL_P(pzval), 1))) {
- + if (Z_TYPE_P(match) != IS_STRING && Z_TYPE_P(offset) != IS_LONG) {
- + goto error_out;
- + }
- + ms->search.s += Z_LVAL_P(offset); /* this is where the match starts */
- + ms->search.offset += Z_LVAL_P(offset); /* this is where the match starts as size_t */
- + ms->search.rm_len = Z_STRLEN_P(match) /* This is the length of the matched pattern */;
- + v = 0;
- + } else {
- + goto error_out;
- + }
- + } else {
- +error_out:
- + zval_ptr_dtor(&subpats);
- + zval_ptr_dtor(&pattern);
- + return -1;
- + }
- } else {
- - search = CCAST(char *, "");
- - copy = NULL;
- - }
- - rc = file_regexec(&rx, (const char *)search,
- - 1, &pmatch, 0);
- - free(copy);
- - switch (rc) {
- - case 0:
- - ms->search.s += (int)pmatch.rm_so;
- - ms->search.offset += (size_t)pmatch.rm_so;
- - ms->search.rm_len =
- - (size_t)(pmatch.rm_eo - pmatch.rm_so);
- - v = 0;
- - break;
- -
- - case REG_NOMATCH:
- v = 1;
- - break;
- -
- - default:
- - file_regerror(&rx, rc, ms);
- - v = (uint64_t)-1;
- - break;
- }
- + zval_ptr_dtor(&subpats);
- + zval_ptr_dtor(&pattern);
- }
- - file_regfree(&rx);
- - if (v == (uint64_t)-1)
- - return -1;
- break;
- }
- case FILE_INDIRECT:
- diff -u libmagic.orig/strcasestr.c libmagic/strcasestr.c
- --- libmagic.orig/strcasestr.c 2014-05-13 18:48:12.000000000 +0200
- +++ libmagic/strcasestr.c 2019-04-02 11:56:06.853152400 +0200
- @@ -39,6 +39,8 @@
-
- #include "file.h"
-
- +#include "php_stdint.h"
- +
- #include <assert.h>
- #include <ctype.h>
- #include <string.h>
|