softmagic.c 50 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226
  1. /*
  2. * Copyright (c) Ian F. Darwin 1986-1995.
  3. * Software written by Ian F. Darwin and others;
  4. * maintained 1995-present by Christos Zoulas and others.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions
  8. * are met:
  9. * 1. Redistributions of source code must retain the above copyright
  10. * notice immediately at the beginning of the file, without modification,
  11. * this list of conditions, and the following disclaimer.
  12. * 2. Redistributions in binary form must reproduce the above copyright
  13. * notice, this list of conditions and the following disclaimer in the
  14. * documentation and/or other materials provided with the distribution.
  15. *
  16. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  17. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  18. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  19. * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
  20. * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  21. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  22. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  23. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  24. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  25. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  26. * SUCH DAMAGE.
  27. */
  28. /*
  29. * softmagic - interpret variable magic from MAGIC
  30. */
  31. #include "file.h"
  32. #ifndef lint
  33. FILE_RCSID("@(#)$File: softmagic.c,v 1.174 2014/02/12 23:20:53 christos Exp $")
  34. #endif /* lint */
  35. #include "magic.h"
  36. #ifdef HAVE_FMTCHECK
  37. #include <stdio.h>
  38. #define F(a, b) fmtcheck((a), (b))
  39. #else
  40. #define F(a, b) (a)
  41. #endif
  42. #include <string.h>
  43. #include <ctype.h>
  44. #include <stdlib.h>
  45. #include <time.h>
  46. #if defined(HAVE_LOCALE_H)
  47. #include <locale.h>
  48. #endif
  49. private int match(struct magic_set *, struct magic *, uint32_t,
  50. const unsigned char *, size_t, size_t, int, int, int, int, int *, int *,
  51. int *);
  52. private int mget(struct magic_set *, const unsigned char *,
  53. struct magic *, size_t, size_t, unsigned int, int, int, int, int, int *,
  54. int *, int *);
  55. private int magiccheck(struct magic_set *, struct magic *);
  56. private int32_t mprint(struct magic_set *, struct magic *);
  57. private int32_t moffset(struct magic_set *, struct magic *);
  58. private void mdebug(uint32_t, const char *, size_t);
  59. private int mcopy(struct magic_set *, union VALUETYPE *, int, int,
  60. const unsigned char *, uint32_t, size_t, size_t);
  61. private int mconvert(struct magic_set *, struct magic *, int);
  62. private int print_sep(struct magic_set *, int);
  63. private int handle_annotation(struct magic_set *, struct magic *);
  64. private void cvt_8(union VALUETYPE *, const struct magic *);
  65. private void cvt_16(union VALUETYPE *, const struct magic *);
  66. private void cvt_32(union VALUETYPE *, const struct magic *);
  67. private void cvt_64(union VALUETYPE *, const struct magic *);
  68. #define OFFSET_OOB(n, o, i) ((n) < (o) || (i) >= ((n) - (o)))
  69. /*
  70. * softmagic - lookup one file in parsed, in-memory copy of database
  71. * Passed the name and FILE * of one file to be typed.
  72. */
  73. /*ARGSUSED1*/ /* nbytes passed for regularity, maybe need later */
  74. protected int
  75. file_softmagic(struct magic_set *ms, const unsigned char *buf, size_t nbytes,
  76. size_t level, int mode, int text)
  77. {
  78. struct mlist *ml;
  79. int rv, printed_something = 0, need_separator = 0;
  80. for (ml = ms->mlist[0]->next; ml != ms->mlist[0]; ml = ml->next)
  81. if ((rv = match(ms, ml->magic, ml->nmagic, buf, nbytes, 0, mode,
  82. text, 0, level, &printed_something, &need_separator,
  83. NULL)) != 0)
  84. return rv;
  85. return 0;
  86. }
  87. /*
  88. * Go through the whole list, stopping if you find a match. Process all
  89. * the continuations of that match before returning.
  90. *
  91. * We support multi-level continuations:
  92. *
  93. * At any time when processing a successful top-level match, there is a
  94. * current continuation level; it represents the level of the last
  95. * successfully matched continuation.
  96. *
  97. * Continuations above that level are skipped as, if we see one, it
  98. * means that the continuation that controls them - i.e, the
  99. * lower-level continuation preceding them - failed to match.
  100. *
  101. * Continuations below that level are processed as, if we see one,
  102. * it means we've finished processing or skipping higher-level
  103. * continuations under the control of a successful or unsuccessful
  104. * lower-level continuation, and are now seeing the next lower-level
  105. * continuation and should process it. The current continuation
  106. * level reverts to the level of the one we're seeing.
  107. *
  108. * Continuations at the current level are processed as, if we see
  109. * one, there's no lower-level continuation that may have failed.
  110. *
  111. * If a continuation matches, we bump the current continuation level
  112. * so that higher-level continuations are processed.
  113. */
  114. private int
  115. match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
  116. const unsigned char *s, size_t nbytes, size_t offset, int mode, int text,
  117. int flip, int recursion_level, int *printed_something, int *need_separator,
  118. int *returnval)
  119. {
  120. uint32_t magindex = 0;
  121. unsigned int cont_level = 0;
  122. int returnvalv = 0, e; /* if a match is found it is set to 1*/
  123. int firstline = 1; /* a flag to print X\n X\n- X */
  124. int print = (ms->flags & (MAGIC_MIME|MAGIC_APPLE)) == 0;
  125. if (returnval == NULL)
  126. returnval = &returnvalv;
  127. if (file_check_mem(ms, cont_level) == -1)
  128. return -1;
  129. for (magindex = 0; magindex < nmagic; magindex++) {
  130. int flush = 0;
  131. struct magic *m = &magic[magindex];
  132. if (m->type != FILE_NAME)
  133. if ((IS_STRING(m->type) &&
  134. #define FLT (STRING_BINTEST | STRING_TEXTTEST)
  135. ((text && (m->str_flags & FLT) == STRING_BINTEST) ||
  136. (!text && (m->str_flags & FLT) == STRING_TEXTTEST))) ||
  137. (m->flag & mode) != mode) {
  138. /* Skip sub-tests */
  139. while (magindex + 1 < nmagic &&
  140. magic[magindex + 1].cont_level != 0 &&
  141. ++magindex)
  142. continue;
  143. continue; /* Skip to next top-level test*/
  144. }
  145. ms->offset = m->offset;
  146. ms->line = m->lineno;
  147. /* if main entry matches, print it... */
  148. switch (mget(ms, s, m, nbytes, offset, cont_level, mode, text,
  149. flip, recursion_level + 1, printed_something,
  150. need_separator, returnval)) {
  151. case -1:
  152. return -1;
  153. case 0:
  154. flush = m->reln != '!';
  155. break;
  156. default:
  157. if (m->type == FILE_INDIRECT)
  158. *returnval = 1;
  159. switch (magiccheck(ms, m)) {
  160. case -1:
  161. return -1;
  162. case 0:
  163. flush++;
  164. break;
  165. default:
  166. flush = 0;
  167. break;
  168. }
  169. break;
  170. }
  171. if (flush) {
  172. /*
  173. * main entry didn't match,
  174. * flush its continuations
  175. */
  176. while (magindex < nmagic - 1 &&
  177. magic[magindex + 1].cont_level != 0)
  178. magindex++;
  179. continue;
  180. }
  181. if ((e = handle_annotation(ms, m)) != 0) {
  182. *need_separator = 1;
  183. *printed_something = 1;
  184. *returnval = 1;
  185. return e;
  186. }
  187. /*
  188. * If we are going to print something, we'll need to print
  189. * a blank before we print something else.
  190. */
  191. if (*m->desc) {
  192. *need_separator = 1;
  193. *printed_something = 1;
  194. if (print_sep(ms, firstline) == -1)
  195. return -1;
  196. }
  197. if (print && mprint(ms, m) == -1)
  198. return -1;
  199. ms->c.li[cont_level].off = moffset(ms, m);
  200. /* and any continuations that match */
  201. if (file_check_mem(ms, ++cont_level) == -1)
  202. return -1;
  203. while (magic[magindex+1].cont_level != 0 &&
  204. ++magindex < nmagic) {
  205. m = &magic[magindex];
  206. ms->line = m->lineno; /* for messages */
  207. if (cont_level < m->cont_level)
  208. continue;
  209. if (cont_level > m->cont_level) {
  210. /*
  211. * We're at the end of the level
  212. * "cont_level" continuations.
  213. */
  214. cont_level = m->cont_level;
  215. }
  216. ms->offset = m->offset;
  217. if (m->flag & OFFADD) {
  218. ms->offset +=
  219. ms->c.li[cont_level - 1].off;
  220. }
  221. #ifdef ENABLE_CONDITIONALS
  222. if (m->cond == COND_ELSE ||
  223. m->cond == COND_ELIF) {
  224. if (ms->c.li[cont_level].last_match == 1)
  225. continue;
  226. }
  227. #endif
  228. switch (mget(ms, s, m, nbytes, offset, cont_level, mode,
  229. text, flip, recursion_level + 1, printed_something,
  230. need_separator, returnval)) {
  231. case -1:
  232. return -1;
  233. case 0:
  234. if (m->reln != '!')
  235. continue;
  236. flush = 1;
  237. break;
  238. default:
  239. if (m->type == FILE_INDIRECT)
  240. *returnval = 1;
  241. flush = 0;
  242. break;
  243. }
  244. switch (flush ? 1 : magiccheck(ms, m)) {
  245. case -1:
  246. return -1;
  247. case 0:
  248. #ifdef ENABLE_CONDITIONALS
  249. ms->c.li[cont_level].last_match = 0;
  250. #endif
  251. break;
  252. default:
  253. #ifdef ENABLE_CONDITIONALS
  254. ms->c.li[cont_level].last_match = 1;
  255. #endif
  256. if (m->type == FILE_CLEAR)
  257. ms->c.li[cont_level].got_match = 0;
  258. else if (ms->c.li[cont_level].got_match) {
  259. if (m->type == FILE_DEFAULT)
  260. break;
  261. } else
  262. ms->c.li[cont_level].got_match = 1;
  263. if ((e = handle_annotation(ms, m)) != 0) {
  264. *need_separator = 1;
  265. *printed_something = 1;
  266. *returnval = 1;
  267. return e;
  268. }
  269. /*
  270. * If we are going to print something,
  271. * make sure that we have a separator first.
  272. */
  273. if (*m->desc) {
  274. if (!*printed_something) {
  275. *printed_something = 1;
  276. if (print_sep(ms, firstline)
  277. == -1)
  278. return -1;
  279. }
  280. }
  281. /*
  282. * This continuation matched. Print
  283. * its message, with a blank before it
  284. * if the previous item printed and
  285. * this item isn't empty.
  286. */
  287. /* space if previous printed */
  288. if (*need_separator
  289. && ((m->flag & NOSPACE) == 0)
  290. && *m->desc) {
  291. if (print &&
  292. file_printf(ms, " ") == -1)
  293. return -1;
  294. *need_separator = 0;
  295. }
  296. if (print && mprint(ms, m) == -1)
  297. return -1;
  298. ms->c.li[cont_level].off = moffset(ms, m);
  299. if (*m->desc)
  300. *need_separator = 1;
  301. /*
  302. * If we see any continuations
  303. * at a higher level,
  304. * process them.
  305. */
  306. if (file_check_mem(ms, ++cont_level) == -1)
  307. return -1;
  308. break;
  309. }
  310. }
  311. if (*printed_something) {
  312. firstline = 0;
  313. if (print)
  314. *returnval = 1;
  315. }
  316. if ((ms->flags & MAGIC_CONTINUE) == 0 && *printed_something) {
  317. return *returnval; /* don't keep searching */
  318. }
  319. }
  320. return *returnval; /* This is hit if -k is set or there is no match */
  321. }
  322. private int
  323. check_fmt(struct magic_set *ms, struct magic *m)
  324. {
  325. regex_t rx;
  326. int rc, rv = -1;
  327. if (strchr(m->desc, '%') == NULL)
  328. return 0;
  329. (void)setlocale(LC_CTYPE, "C");
  330. rc = regcomp(&rx, "%[-0-9\\.]*s", REG_EXTENDED|REG_NOSUB);
  331. if (rc) {
  332. char errmsg[512];
  333. (void)regerror(rc, &rx, errmsg, sizeof(errmsg));
  334. file_magerror(ms, "regex error %d, (%s)", rc, errmsg);
  335. } else {
  336. rc = regexec(&rx, m->desc, 0, 0, 0);
  337. regfree(&rx);
  338. rv = !rc;
  339. }
  340. (void)setlocale(LC_CTYPE, "");
  341. return rv;
  342. }
  343. #ifndef HAVE_STRNDUP
  344. char * strndup(const char *, size_t);
  345. char *
  346. strndup(const char *str, size_t n)
  347. {
  348. size_t len;
  349. char *copy;
  350. for (len = 0; len < n && str[len]; len++)
  351. continue;
  352. if ((copy = malloc(len + 1)) == NULL)
  353. return NULL;
  354. (void)memcpy(copy, str, len);
  355. copy[len] = '\0';
  356. return copy;
  357. }
  358. #endif /* HAVE_STRNDUP */
  359. private int32_t
  360. mprint(struct magic_set *ms, struct magic *m)
  361. {
  362. uint64_t v;
  363. float vf;
  364. double vd;
  365. int64_t t = 0;
  366. char buf[128], tbuf[26];
  367. union VALUETYPE *p = &ms->ms_value;
  368. switch (m->type) {
  369. case FILE_BYTE:
  370. v = file_signextend(ms, m, (uint64_t)p->b);
  371. switch (check_fmt(ms, m)) {
  372. case -1:
  373. return -1;
  374. case 1:
  375. (void)snprintf(buf, sizeof(buf), "%c",
  376. (unsigned char)v);
  377. if (file_printf(ms, F(m->desc, "%s"), buf) == -1)
  378. return -1;
  379. break;
  380. default:
  381. if (file_printf(ms, F(m->desc, "%c"),
  382. (unsigned char) v) == -1)
  383. return -1;
  384. break;
  385. }
  386. t = ms->offset + sizeof(char);
  387. break;
  388. case FILE_SHORT:
  389. case FILE_BESHORT:
  390. case FILE_LESHORT:
  391. v = file_signextend(ms, m, (uint64_t)p->h);
  392. switch (check_fmt(ms, m)) {
  393. case -1:
  394. return -1;
  395. case 1:
  396. (void)snprintf(buf, sizeof(buf), "%hu",
  397. (unsigned short)v);
  398. if (file_printf(ms, F(m->desc, "%s"), buf) == -1)
  399. return -1;
  400. break;
  401. default:
  402. if (file_printf(ms, F(m->desc, "%hu"),
  403. (unsigned short) v) == -1)
  404. return -1;
  405. break;
  406. }
  407. t = ms->offset + sizeof(short);
  408. break;
  409. case FILE_LONG:
  410. case FILE_BELONG:
  411. case FILE_LELONG:
  412. case FILE_MELONG:
  413. v = file_signextend(ms, m, (uint64_t)p->l);
  414. switch (check_fmt(ms, m)) {
  415. case -1:
  416. return -1;
  417. case 1:
  418. (void)snprintf(buf, sizeof(buf), "%u", (uint32_t)v);
  419. if (file_printf(ms, F(m->desc, "%s"), buf) == -1)
  420. return -1;
  421. break;
  422. default:
  423. if (file_printf(ms, F(m->desc, "%u"),
  424. (uint32_t) v) == -1)
  425. return -1;
  426. break;
  427. }
  428. t = ms->offset + sizeof(int32_t);
  429. break;
  430. case FILE_QUAD:
  431. case FILE_BEQUAD:
  432. case FILE_LEQUAD:
  433. v = file_signextend(ms, m, p->q);
  434. switch (check_fmt(ms, m)) {
  435. case -1:
  436. return -1;
  437. case 1:
  438. (void)snprintf(buf, sizeof(buf), "%llu",
  439. (unsigned long long)v);
  440. if (file_printf(ms, F(m->desc, "%s"), buf) == -1)
  441. return -1;
  442. break;
  443. default:
  444. if (file_printf(ms, F(m->desc, "%llu"),
  445. (unsigned long long) v) == -1)
  446. return -1;
  447. break;
  448. }
  449. t = ms->offset + sizeof(int64_t);
  450. break;
  451. case FILE_STRING:
  452. case FILE_PSTRING:
  453. case FILE_BESTRING16:
  454. case FILE_LESTRING16:
  455. if (m->reln == '=' || m->reln == '!') {
  456. if (file_printf(ms, F(m->desc, "%s"), m->value.s) == -1)
  457. return -1;
  458. t = ms->offset + m->vallen;
  459. }
  460. else {
  461. char *str = p->s;
  462. /* compute t before we mangle the string? */
  463. t = ms->offset + strlen(str);
  464. if (*m->value.s == '\0')
  465. str[strcspn(str, "\n")] = '\0';
  466. if (m->str_flags & STRING_TRIM) {
  467. char *last;
  468. while (isspace((unsigned char)*str))
  469. str++;
  470. last = str;
  471. while (*last)
  472. last++;
  473. --last;
  474. while (isspace((unsigned char)*last))
  475. last--;
  476. *++last = '\0';
  477. }
  478. if (file_printf(ms, F(m->desc, "%s"), str) == -1)
  479. return -1;
  480. if (m->type == FILE_PSTRING)
  481. t += file_pstring_length_size(m);
  482. }
  483. break;
  484. case FILE_DATE:
  485. case FILE_BEDATE:
  486. case FILE_LEDATE:
  487. case FILE_MEDATE:
  488. if (file_printf(ms, F(m->desc, "%s"),
  489. file_fmttime(p->l, FILE_T_LOCAL,
  490. tbuf)) == -1)
  491. return -1;
  492. t = ms->offset + sizeof(uint32_t);
  493. break;
  494. case FILE_LDATE:
  495. case FILE_BELDATE:
  496. case FILE_LELDATE:
  497. case FILE_MELDATE:
  498. if (file_printf(ms, F(m->desc, "%s"),
  499. file_fmttime(p->l, 0, tbuf)) == -1)
  500. return -1;
  501. t = ms->offset + sizeof(uint32_t);
  502. break;
  503. case FILE_QDATE:
  504. case FILE_BEQDATE:
  505. case FILE_LEQDATE:
  506. if (file_printf(ms, F(m->desc, "%s"),
  507. file_fmttime(p->q, FILE_T_LOCAL, tbuf)) == -1)
  508. return -1;
  509. t = ms->offset + sizeof(uint64_t);
  510. break;
  511. case FILE_QLDATE:
  512. case FILE_BEQLDATE:
  513. case FILE_LEQLDATE:
  514. if (file_printf(ms, F(m->desc, "%s"),
  515. file_fmttime(p->q, 0, tbuf)) == -1)
  516. return -1;
  517. t = ms->offset + sizeof(uint64_t);
  518. break;
  519. case FILE_QWDATE:
  520. case FILE_BEQWDATE:
  521. case FILE_LEQWDATE:
  522. if (file_printf(ms, F(m->desc, "%s"),
  523. file_fmttime(p->q, FILE_T_WINDOWS, tbuf)) == -1)
  524. return -1;
  525. t = ms->offset + sizeof(uint64_t);
  526. break;
  527. case FILE_FLOAT:
  528. case FILE_BEFLOAT:
  529. case FILE_LEFLOAT:
  530. vf = p->f;
  531. switch (check_fmt(ms, m)) {
  532. case -1:
  533. return -1;
  534. case 1:
  535. (void)snprintf(buf, sizeof(buf), "%g", vf);
  536. if (file_printf(ms, F(m->desc, "%s"), buf) == -1)
  537. return -1;
  538. break;
  539. default:
  540. if (file_printf(ms, F(m->desc, "%g"), vf) == -1)
  541. return -1;
  542. break;
  543. }
  544. t = ms->offset + sizeof(float);
  545. break;
  546. case FILE_DOUBLE:
  547. case FILE_BEDOUBLE:
  548. case FILE_LEDOUBLE:
  549. vd = p->d;
  550. switch (check_fmt(ms, m)) {
  551. case -1:
  552. return -1;
  553. case 1:
  554. (void)snprintf(buf, sizeof(buf), "%g", vd);
  555. if (file_printf(ms, F(m->desc, "%s"), buf) == -1)
  556. return -1;
  557. break;
  558. default:
  559. if (file_printf(ms, F(m->desc, "%g"), vd) == -1)
  560. return -1;
  561. break;
  562. }
  563. t = ms->offset + sizeof(double);
  564. break;
  565. case FILE_REGEX: {
  566. char *cp;
  567. int rval;
  568. cp = strndup((const char *)ms->search.s, ms->search.rm_len);
  569. if (cp == NULL) {
  570. file_oomem(ms, ms->search.rm_len);
  571. return -1;
  572. }
  573. rval = file_printf(ms, F(m->desc, "%s"), cp);
  574. free(cp);
  575. if (rval == -1)
  576. return -1;
  577. if ((m->str_flags & REGEX_OFFSET_START))
  578. t = ms->search.offset;
  579. else
  580. t = ms->search.offset + ms->search.rm_len;
  581. break;
  582. }
  583. case FILE_SEARCH:
  584. if (file_printf(ms, F(m->desc, "%s"), m->value.s) == -1)
  585. return -1;
  586. if ((m->str_flags & REGEX_OFFSET_START))
  587. t = ms->search.offset;
  588. else
  589. t = ms->search.offset + m->vallen;
  590. break;
  591. case FILE_DEFAULT:
  592. case FILE_CLEAR:
  593. if (file_printf(ms, "%s", m->desc) == -1)
  594. return -1;
  595. t = ms->offset;
  596. break;
  597. case FILE_INDIRECT:
  598. case FILE_USE:
  599. case FILE_NAME:
  600. t = ms->offset;
  601. break;
  602. default:
  603. file_magerror(ms, "invalid m->type (%d) in mprint()", m->type);
  604. return -1;
  605. }
  606. return (int32_t)t;
  607. }
  608. private int32_t
  609. moffset(struct magic_set *ms, struct magic *m)
  610. {
  611. switch (m->type) {
  612. case FILE_BYTE:
  613. return CAST(int32_t, (ms->offset + sizeof(char)));
  614. case FILE_SHORT:
  615. case FILE_BESHORT:
  616. case FILE_LESHORT:
  617. return CAST(int32_t, (ms->offset + sizeof(short)));
  618. case FILE_LONG:
  619. case FILE_BELONG:
  620. case FILE_LELONG:
  621. case FILE_MELONG:
  622. return CAST(int32_t, (ms->offset + sizeof(int32_t)));
  623. case FILE_QUAD:
  624. case FILE_BEQUAD:
  625. case FILE_LEQUAD:
  626. return CAST(int32_t, (ms->offset + sizeof(int64_t)));
  627. case FILE_STRING:
  628. case FILE_PSTRING:
  629. case FILE_BESTRING16:
  630. case FILE_LESTRING16:
  631. if (m->reln == '=' || m->reln == '!')
  632. return ms->offset + m->vallen;
  633. else {
  634. union VALUETYPE *p = &ms->ms_value;
  635. uint32_t t;
  636. if (*m->value.s == '\0')
  637. p->s[strcspn(p->s, "\n")] = '\0';
  638. t = CAST(uint32_t, (ms->offset + strlen(p->s)));
  639. if (m->type == FILE_PSTRING)
  640. t += (uint32_t)file_pstring_length_size(m);
  641. return t;
  642. }
  643. case FILE_DATE:
  644. case FILE_BEDATE:
  645. case FILE_LEDATE:
  646. case FILE_MEDATE:
  647. return CAST(int32_t, (ms->offset + sizeof(uint32_t)));
  648. case FILE_LDATE:
  649. case FILE_BELDATE:
  650. case FILE_LELDATE:
  651. case FILE_MELDATE:
  652. return CAST(int32_t, (ms->offset + sizeof(uint32_t)));
  653. case FILE_QDATE:
  654. case FILE_BEQDATE:
  655. case FILE_LEQDATE:
  656. return CAST(int32_t, (ms->offset + sizeof(uint64_t)));
  657. case FILE_QLDATE:
  658. case FILE_BEQLDATE:
  659. case FILE_LEQLDATE:
  660. return CAST(int32_t, (ms->offset + sizeof(uint64_t)));
  661. case FILE_FLOAT:
  662. case FILE_BEFLOAT:
  663. case FILE_LEFLOAT:
  664. return CAST(int32_t, (ms->offset + sizeof(float)));
  665. case FILE_DOUBLE:
  666. case FILE_BEDOUBLE:
  667. case FILE_LEDOUBLE:
  668. return CAST(int32_t, (ms->offset + sizeof(double)));
  669. case FILE_REGEX:
  670. if ((m->str_flags & REGEX_OFFSET_START) != 0)
  671. return CAST(int32_t, ms->search.offset);
  672. else
  673. return CAST(int32_t, (ms->search.offset +
  674. ms->search.rm_len));
  675. case FILE_SEARCH:
  676. if ((m->str_flags & REGEX_OFFSET_START) != 0)
  677. return CAST(int32_t, ms->search.offset);
  678. else
  679. return CAST(int32_t, (ms->search.offset + m->vallen));
  680. case FILE_CLEAR:
  681. case FILE_DEFAULT:
  682. case FILE_INDIRECT:
  683. return ms->offset;
  684. default:
  685. return 0;
  686. }
  687. }
  688. private int
  689. cvt_flip(int type, int flip)
  690. {
  691. if (flip == 0)
  692. return type;
  693. switch (type) {
  694. case FILE_BESHORT:
  695. return FILE_LESHORT;
  696. case FILE_BELONG:
  697. return FILE_LELONG;
  698. case FILE_BEDATE:
  699. return FILE_LEDATE;
  700. case FILE_BELDATE:
  701. return FILE_LELDATE;
  702. case FILE_BEQUAD:
  703. return FILE_LEQUAD;
  704. case FILE_BEQDATE:
  705. return FILE_LEQDATE;
  706. case FILE_BEQLDATE:
  707. return FILE_LEQLDATE;
  708. case FILE_BEQWDATE:
  709. return FILE_LEQWDATE;
  710. case FILE_LESHORT:
  711. return FILE_BESHORT;
  712. case FILE_LELONG:
  713. return FILE_BELONG;
  714. case FILE_LEDATE:
  715. return FILE_BEDATE;
  716. case FILE_LELDATE:
  717. return FILE_BELDATE;
  718. case FILE_LEQUAD:
  719. return FILE_BEQUAD;
  720. case FILE_LEQDATE:
  721. return FILE_BEQDATE;
  722. case FILE_LEQLDATE:
  723. return FILE_BEQLDATE;
  724. case FILE_LEQWDATE:
  725. return FILE_BEQWDATE;
  726. case FILE_BEFLOAT:
  727. return FILE_LEFLOAT;
  728. case FILE_LEFLOAT:
  729. return FILE_BEFLOAT;
  730. case FILE_BEDOUBLE:
  731. return FILE_LEDOUBLE;
  732. case FILE_LEDOUBLE:
  733. return FILE_BEDOUBLE;
  734. default:
  735. return type;
  736. }
  737. }
  738. #define DO_CVT(fld, cast) \
  739. if (m->num_mask) \
  740. switch (m->mask_op & FILE_OPS_MASK) { \
  741. case FILE_OPAND: \
  742. p->fld &= cast m->num_mask; \
  743. break; \
  744. case FILE_OPOR: \
  745. p->fld |= cast m->num_mask; \
  746. break; \
  747. case FILE_OPXOR: \
  748. p->fld ^= cast m->num_mask; \
  749. break; \
  750. case FILE_OPADD: \
  751. p->fld += cast m->num_mask; \
  752. break; \
  753. case FILE_OPMINUS: \
  754. p->fld -= cast m->num_mask; \
  755. break; \
  756. case FILE_OPMULTIPLY: \
  757. p->fld *= cast m->num_mask; \
  758. break; \
  759. case FILE_OPDIVIDE: \
  760. p->fld /= cast m->num_mask; \
  761. break; \
  762. case FILE_OPMODULO: \
  763. p->fld %= cast m->num_mask; \
  764. break; \
  765. } \
  766. if (m->mask_op & FILE_OPINVERSE) \
  767. p->fld = ~p->fld \
  768. private void
  769. cvt_8(union VALUETYPE *p, const struct magic *m)
  770. {
  771. DO_CVT(b, (uint8_t));
  772. }
  773. private void
  774. cvt_16(union VALUETYPE *p, const struct magic *m)
  775. {
  776. DO_CVT(h, (uint16_t));
  777. }
  778. private void
  779. cvt_32(union VALUETYPE *p, const struct magic *m)
  780. {
  781. DO_CVT(l, (uint32_t));
  782. }
  783. private void
  784. cvt_64(union VALUETYPE *p, const struct magic *m)
  785. {
  786. DO_CVT(q, (uint64_t));
  787. }
  788. #define DO_CVT2(fld, cast) \
  789. if (m->num_mask) \
  790. switch (m->mask_op & FILE_OPS_MASK) { \
  791. case FILE_OPADD: \
  792. p->fld += cast m->num_mask; \
  793. break; \
  794. case FILE_OPMINUS: \
  795. p->fld -= cast m->num_mask; \
  796. break; \
  797. case FILE_OPMULTIPLY: \
  798. p->fld *= cast m->num_mask; \
  799. break; \
  800. case FILE_OPDIVIDE: \
  801. p->fld /= cast m->num_mask; \
  802. break; \
  803. } \
  804. private void
  805. cvt_float(union VALUETYPE *p, const struct magic *m)
  806. {
  807. DO_CVT2(f, (float));
  808. }
  809. private void
  810. cvt_double(union VALUETYPE *p, const struct magic *m)
  811. {
  812. DO_CVT2(d, (double));
  813. }
  814. /*
  815. * Convert the byte order of the data we are looking at
  816. * While we're here, let's apply the mask operation
  817. * (unless you have a better idea)
  818. */
  819. private int
  820. mconvert(struct magic_set *ms, struct magic *m, int flip)
  821. {
  822. union VALUETYPE *p = &ms->ms_value;
  823. switch (cvt_flip(m->type, flip)) {
  824. case FILE_BYTE:
  825. cvt_8(p, m);
  826. return 1;
  827. case FILE_SHORT:
  828. cvt_16(p, m);
  829. return 1;
  830. case FILE_LONG:
  831. case FILE_DATE:
  832. case FILE_LDATE:
  833. cvt_32(p, m);
  834. return 1;
  835. case FILE_QUAD:
  836. case FILE_QDATE:
  837. case FILE_QLDATE:
  838. case FILE_QWDATE:
  839. cvt_64(p, m);
  840. return 1;
  841. case FILE_STRING:
  842. case FILE_BESTRING16:
  843. case FILE_LESTRING16: {
  844. /* Null terminate and eat *trailing* return */
  845. p->s[sizeof(p->s) - 1] = '\0';
  846. return 1;
  847. }
  848. case FILE_PSTRING: {
  849. char *ptr1 = p->s, *ptr2 = ptr1 + file_pstring_length_size(m);
  850. size_t len = file_pstring_get_length(m, ptr1);
  851. if (len >= sizeof(p->s))
  852. len = sizeof(p->s) - 1;
  853. while (len--)
  854. *ptr1++ = *ptr2++;
  855. *ptr1 = '\0';
  856. return 1;
  857. }
  858. case FILE_BESHORT:
  859. p->h = (short)((p->hs[0]<<8)|(p->hs[1]));
  860. cvt_16(p, m);
  861. return 1;
  862. case FILE_BELONG:
  863. case FILE_BEDATE:
  864. case FILE_BELDATE:
  865. p->l = (int32_t)
  866. ((p->hl[0]<<24)|(p->hl[1]<<16)|(p->hl[2]<<8)|(p->hl[3]));
  867. cvt_32(p, m);
  868. return 1;
  869. case FILE_BEQUAD:
  870. case FILE_BEQDATE:
  871. case FILE_BEQLDATE:
  872. case FILE_BEQWDATE:
  873. p->q = (uint64_t)
  874. (((uint64_t)p->hq[0]<<56)|((uint64_t)p->hq[1]<<48)|
  875. ((uint64_t)p->hq[2]<<40)|((uint64_t)p->hq[3]<<32)|
  876. ((uint64_t)p->hq[4]<<24)|((uint64_t)p->hq[5]<<16)|
  877. ((uint64_t)p->hq[6]<<8)|((uint64_t)p->hq[7]));
  878. cvt_64(p, m);
  879. return 1;
  880. case FILE_LESHORT:
  881. p->h = (short)((p->hs[1]<<8)|(p->hs[0]));
  882. cvt_16(p, m);
  883. return 1;
  884. case FILE_LELONG:
  885. case FILE_LEDATE:
  886. case FILE_LELDATE:
  887. p->l = (int32_t)
  888. ((p->hl[3]<<24)|(p->hl[2]<<16)|(p->hl[1]<<8)|(p->hl[0]));
  889. cvt_32(p, m);
  890. return 1;
  891. case FILE_LEQUAD:
  892. case FILE_LEQDATE:
  893. case FILE_LEQLDATE:
  894. case FILE_LEQWDATE:
  895. p->q = (uint64_t)
  896. (((uint64_t)p->hq[7]<<56)|((uint64_t)p->hq[6]<<48)|
  897. ((uint64_t)p->hq[5]<<40)|((uint64_t)p->hq[4]<<32)|
  898. ((uint64_t)p->hq[3]<<24)|((uint64_t)p->hq[2]<<16)|
  899. ((uint64_t)p->hq[1]<<8)|((uint64_t)p->hq[0]));
  900. cvt_64(p, m);
  901. return 1;
  902. case FILE_MELONG:
  903. case FILE_MEDATE:
  904. case FILE_MELDATE:
  905. p->l = (int32_t)
  906. ((p->hl[1]<<24)|(p->hl[0]<<16)|(p->hl[3]<<8)|(p->hl[2]));
  907. cvt_32(p, m);
  908. return 1;
  909. case FILE_FLOAT:
  910. cvt_float(p, m);
  911. return 1;
  912. case FILE_BEFLOAT:
  913. p->l = ((uint32_t)p->hl[0]<<24)|((uint32_t)p->hl[1]<<16)|
  914. ((uint32_t)p->hl[2]<<8) |((uint32_t)p->hl[3]);
  915. cvt_float(p, m);
  916. return 1;
  917. case FILE_LEFLOAT:
  918. p->l = ((uint32_t)p->hl[3]<<24)|((uint32_t)p->hl[2]<<16)|
  919. ((uint32_t)p->hl[1]<<8) |((uint32_t)p->hl[0]);
  920. cvt_float(p, m);
  921. return 1;
  922. case FILE_DOUBLE:
  923. cvt_double(p, m);
  924. return 1;
  925. case FILE_BEDOUBLE:
  926. p->q = ((uint64_t)p->hq[0]<<56)|((uint64_t)p->hq[1]<<48)|
  927. ((uint64_t)p->hq[2]<<40)|((uint64_t)p->hq[3]<<32)|
  928. ((uint64_t)p->hq[4]<<24)|((uint64_t)p->hq[5]<<16)|
  929. ((uint64_t)p->hq[6]<<8) |((uint64_t)p->hq[7]);
  930. cvt_double(p, m);
  931. return 1;
  932. case FILE_LEDOUBLE:
  933. p->q = ((uint64_t)p->hq[7]<<56)|((uint64_t)p->hq[6]<<48)|
  934. ((uint64_t)p->hq[5]<<40)|((uint64_t)p->hq[4]<<32)|
  935. ((uint64_t)p->hq[3]<<24)|((uint64_t)p->hq[2]<<16)|
  936. ((uint64_t)p->hq[1]<<8) |((uint64_t)p->hq[0]);
  937. cvt_double(p, m);
  938. return 1;
  939. case FILE_REGEX:
  940. case FILE_SEARCH:
  941. case FILE_DEFAULT:
  942. case FILE_CLEAR:
  943. case FILE_NAME:
  944. case FILE_USE:
  945. return 1;
  946. default:
  947. file_magerror(ms, "invalid type %d in mconvert()", m->type);
  948. return 0;
  949. }
  950. }
  951. private void
  952. mdebug(uint32_t offset, const char *str, size_t len)
  953. {
  954. (void) fprintf(stderr, "mget/%zu @%d: ", len, offset);
  955. file_showstr(stderr, str, len);
  956. (void) fputc('\n', stderr);
  957. (void) fputc('\n', stderr);
  958. }
  959. private int
  960. mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir,
  961. const unsigned char *s, uint32_t offset, size_t nbytes, size_t linecnt)
  962. {
  963. /*
  964. * Note: FILE_SEARCH and FILE_REGEX do not actually copy
  965. * anything, but setup pointers into the source
  966. */
  967. if (indir == 0) {
  968. switch (type) {
  969. case FILE_SEARCH:
  970. ms->search.s = RCAST(const char *, s) + offset;
  971. ms->search.s_len = nbytes - offset;
  972. ms->search.offset = offset;
  973. return 0;
  974. case FILE_REGEX: {
  975. const char *b;
  976. const char *c;
  977. const char *last; /* end of search region */
  978. const char *buf; /* start of search region */
  979. const char *end;
  980. size_t lines;
  981. if (s == NULL) {
  982. ms->search.s_len = 0;
  983. ms->search.s = NULL;
  984. return 0;
  985. }
  986. buf = RCAST(const char *, s) + offset;
  987. end = last = RCAST(const char *, s) + nbytes;
  988. /* mget() guarantees buf <= last */
  989. for (lines = linecnt, b = buf; lines && b < end &&
  990. ((b = CAST(const char *,
  991. memchr(c = b, '\n', CAST(size_t, (end - b)))))
  992. || (b = CAST(const char *,
  993. memchr(c, '\r', CAST(size_t, (end - c))))));
  994. lines--, b++) {
  995. last = b;
  996. if (b[0] == '\r' && b[1] == '\n')
  997. b++;
  998. }
  999. if (lines)
  1000. last = RCAST(const char *, s) + nbytes;
  1001. ms->search.s = buf;
  1002. ms->search.s_len = last - buf;
  1003. ms->search.offset = offset;
  1004. ms->search.rm_len = 0;
  1005. return 0;
  1006. }
  1007. case FILE_BESTRING16:
  1008. case FILE_LESTRING16: {
  1009. const unsigned char *src = s + offset;
  1010. const unsigned char *esrc = s + nbytes;
  1011. char *dst = p->s;
  1012. char *edst = &p->s[sizeof(p->s) - 1];
  1013. if (type == FILE_BESTRING16)
  1014. src++;
  1015. /* check that offset is within range */
  1016. if (offset >= nbytes)
  1017. break;
  1018. for (/*EMPTY*/; src < esrc; src += 2, dst++) {
  1019. if (dst < edst)
  1020. *dst = *src;
  1021. else
  1022. break;
  1023. if (*dst == '\0') {
  1024. if (type == FILE_BESTRING16 ?
  1025. *(src - 1) != '\0' :
  1026. *(src + 1) != '\0')
  1027. *dst = ' ';
  1028. }
  1029. }
  1030. *edst = '\0';
  1031. return 0;
  1032. }
  1033. case FILE_STRING: /* XXX - these two should not need */
  1034. case FILE_PSTRING: /* to copy anything, but do anyway. */
  1035. default:
  1036. break;
  1037. }
  1038. }
  1039. if (offset >= nbytes) {
  1040. (void)memset(p, '\0', sizeof(*p));
  1041. return 0;
  1042. }
  1043. if (nbytes - offset < sizeof(*p))
  1044. nbytes = nbytes - offset;
  1045. else
  1046. nbytes = sizeof(*p);
  1047. (void)memcpy(p, s + offset, nbytes);
  1048. /*
  1049. * the usefulness of padding with zeroes eludes me, it
  1050. * might even cause problems
  1051. */
  1052. if (nbytes < sizeof(*p))
  1053. (void)memset(((char *)(void *)p) + nbytes, '\0',
  1054. sizeof(*p) - nbytes);
  1055. return 0;
  1056. }
  1057. private int
  1058. mget(struct magic_set *ms, const unsigned char *s, struct magic *m,
  1059. size_t nbytes, size_t o, unsigned int cont_level, int mode, int text,
  1060. int flip, int recursion_level, int *printed_something,
  1061. int *need_separator, int *returnval)
  1062. {
  1063. uint32_t soffset, offset = ms->offset;
  1064. uint32_t count = m->str_range;
  1065. int rv, oneed_separator, in_type;
  1066. char *sbuf, *rbuf;
  1067. union VALUETYPE *p = &ms->ms_value;
  1068. struct mlist ml;
  1069. if (recursion_level >= 20) {
  1070. file_error(ms, 0, "recursion nesting exceeded");
  1071. return -1;
  1072. }
  1073. if (mcopy(ms, p, m->type, m->flag & INDIR, s, (uint32_t)(offset + o),
  1074. (uint32_t)nbytes, count) == -1)
  1075. return -1;
  1076. if ((ms->flags & MAGIC_DEBUG) != 0) {
  1077. fprintf(stderr, "mget(type=%d, flag=%x, offset=%u, o=%zu, "
  1078. "nbytes=%zu, count=%u)\n", m->type, m->flag, offset, o,
  1079. nbytes, count);
  1080. mdebug(offset, (char *)(void *)p, sizeof(union VALUETYPE));
  1081. #ifndef COMPILE_ONLY
  1082. file_mdump(m);
  1083. #endif
  1084. }
  1085. if (m->flag & INDIR) {
  1086. int off = m->in_offset;
  1087. if (m->in_op & FILE_OPINDIRECT) {
  1088. const union VALUETYPE *q = CAST(const union VALUETYPE *,
  1089. ((const void *)(s + offset + off)));
  1090. switch (cvt_flip(m->in_type, flip)) {
  1091. case FILE_BYTE:
  1092. off = q->b;
  1093. break;
  1094. case FILE_SHORT:
  1095. off = q->h;
  1096. break;
  1097. case FILE_BESHORT:
  1098. off = (short)((q->hs[0]<<8)|(q->hs[1]));
  1099. break;
  1100. case FILE_LESHORT:
  1101. off = (short)((q->hs[1]<<8)|(q->hs[0]));
  1102. break;
  1103. case FILE_LONG:
  1104. off = q->l;
  1105. break;
  1106. case FILE_BELONG:
  1107. case FILE_BEID3:
  1108. off = (int32_t)((q->hl[0]<<24)|(q->hl[1]<<16)|
  1109. (q->hl[2]<<8)|(q->hl[3]));
  1110. break;
  1111. case FILE_LEID3:
  1112. case FILE_LELONG:
  1113. off = (int32_t)((q->hl[3]<<24)|(q->hl[2]<<16)|
  1114. (q->hl[1]<<8)|(q->hl[0]));
  1115. break;
  1116. case FILE_MELONG:
  1117. off = (int32_t)((q->hl[1]<<24)|(q->hl[0]<<16)|
  1118. (q->hl[3]<<8)|(q->hl[2]));
  1119. break;
  1120. }
  1121. if ((ms->flags & MAGIC_DEBUG) != 0)
  1122. fprintf(stderr, "indirect offs=%u\n", off);
  1123. }
  1124. switch (in_type = cvt_flip(m->in_type, flip)) {
  1125. case FILE_BYTE:
  1126. if (OFFSET_OOB(nbytes, offset, 1))
  1127. return 0;
  1128. if (off) {
  1129. switch (m->in_op & FILE_OPS_MASK) {
  1130. case FILE_OPAND:
  1131. offset = p->b & off;
  1132. break;
  1133. case FILE_OPOR:
  1134. offset = p->b | off;
  1135. break;
  1136. case FILE_OPXOR:
  1137. offset = p->b ^ off;
  1138. break;
  1139. case FILE_OPADD:
  1140. offset = p->b + off;
  1141. break;
  1142. case FILE_OPMINUS:
  1143. offset = p->b - off;
  1144. break;
  1145. case FILE_OPMULTIPLY:
  1146. offset = p->b * off;
  1147. break;
  1148. case FILE_OPDIVIDE:
  1149. offset = p->b / off;
  1150. break;
  1151. case FILE_OPMODULO:
  1152. offset = p->b % off;
  1153. break;
  1154. }
  1155. } else
  1156. offset = p->b;
  1157. if (m->in_op & FILE_OPINVERSE)
  1158. offset = ~offset;
  1159. break;
  1160. case FILE_BESHORT:
  1161. if (OFFSET_OOB(nbytes, offset, 2))
  1162. return 0;
  1163. if (off) {
  1164. switch (m->in_op & FILE_OPS_MASK) {
  1165. case FILE_OPAND:
  1166. offset = (short)((p->hs[0]<<8)|
  1167. (p->hs[1])) &
  1168. off;
  1169. break;
  1170. case FILE_OPOR:
  1171. offset = (short)((p->hs[0]<<8)|
  1172. (p->hs[1])) |
  1173. off;
  1174. break;
  1175. case FILE_OPXOR:
  1176. offset = (short)((p->hs[0]<<8)|
  1177. (p->hs[1])) ^
  1178. off;
  1179. break;
  1180. case FILE_OPADD:
  1181. offset = (short)((p->hs[0]<<8)|
  1182. (p->hs[1])) +
  1183. off;
  1184. break;
  1185. case FILE_OPMINUS:
  1186. offset = (short)((p->hs[0]<<8)|
  1187. (p->hs[1])) -
  1188. off;
  1189. break;
  1190. case FILE_OPMULTIPLY:
  1191. offset = (short)((p->hs[0]<<8)|
  1192. (p->hs[1])) *
  1193. off;
  1194. break;
  1195. case FILE_OPDIVIDE:
  1196. offset = (short)((p->hs[0]<<8)|
  1197. (p->hs[1])) /
  1198. off;
  1199. break;
  1200. case FILE_OPMODULO:
  1201. offset = (short)((p->hs[0]<<8)|
  1202. (p->hs[1])) %
  1203. off;
  1204. break;
  1205. }
  1206. } else
  1207. offset = (short)((p->hs[0]<<8)|
  1208. (p->hs[1]));
  1209. if (m->in_op & FILE_OPINVERSE)
  1210. offset = ~offset;
  1211. break;
  1212. case FILE_LESHORT:
  1213. if (OFFSET_OOB(nbytes, offset, 2))
  1214. return 0;
  1215. if (off) {
  1216. switch (m->in_op & FILE_OPS_MASK) {
  1217. case FILE_OPAND:
  1218. offset = (short)((p->hs[1]<<8)|
  1219. (p->hs[0])) &
  1220. off;
  1221. break;
  1222. case FILE_OPOR:
  1223. offset = (short)((p->hs[1]<<8)|
  1224. (p->hs[0])) |
  1225. off;
  1226. break;
  1227. case FILE_OPXOR:
  1228. offset = (short)((p->hs[1]<<8)|
  1229. (p->hs[0])) ^
  1230. off;
  1231. break;
  1232. case FILE_OPADD:
  1233. offset = (short)((p->hs[1]<<8)|
  1234. (p->hs[0])) +
  1235. off;
  1236. break;
  1237. case FILE_OPMINUS:
  1238. offset = (short)((p->hs[1]<<8)|
  1239. (p->hs[0])) -
  1240. off;
  1241. break;
  1242. case FILE_OPMULTIPLY:
  1243. offset = (short)((p->hs[1]<<8)|
  1244. (p->hs[0])) *
  1245. off;
  1246. break;
  1247. case FILE_OPDIVIDE:
  1248. offset = (short)((p->hs[1]<<8)|
  1249. (p->hs[0])) /
  1250. off;
  1251. break;
  1252. case FILE_OPMODULO:
  1253. offset = (short)((p->hs[1]<<8)|
  1254. (p->hs[0])) %
  1255. off;
  1256. break;
  1257. }
  1258. } else
  1259. offset = (short)((p->hs[1]<<8)|
  1260. (p->hs[0]));
  1261. if (m->in_op & FILE_OPINVERSE)
  1262. offset = ~offset;
  1263. break;
  1264. case FILE_SHORT:
  1265. if (OFFSET_OOB(nbytes, offset, 2))
  1266. return 0;
  1267. if (off) {
  1268. switch (m->in_op & FILE_OPS_MASK) {
  1269. case FILE_OPAND:
  1270. offset = p->h & off;
  1271. break;
  1272. case FILE_OPOR:
  1273. offset = p->h | off;
  1274. break;
  1275. case FILE_OPXOR:
  1276. offset = p->h ^ off;
  1277. break;
  1278. case FILE_OPADD:
  1279. offset = p->h + off;
  1280. break;
  1281. case FILE_OPMINUS:
  1282. offset = p->h - off;
  1283. break;
  1284. case FILE_OPMULTIPLY:
  1285. offset = p->h * off;
  1286. break;
  1287. case FILE_OPDIVIDE:
  1288. offset = p->h / off;
  1289. break;
  1290. case FILE_OPMODULO:
  1291. offset = p->h % off;
  1292. break;
  1293. }
  1294. }
  1295. else
  1296. offset = p->h;
  1297. if (m->in_op & FILE_OPINVERSE)
  1298. offset = ~offset;
  1299. break;
  1300. case FILE_BELONG:
  1301. case FILE_BEID3:
  1302. if (OFFSET_OOB(nbytes, offset, 4))
  1303. return 0;
  1304. if (off) {
  1305. switch (m->in_op & FILE_OPS_MASK) {
  1306. case FILE_OPAND:
  1307. offset = (int32_t)((p->hl[0]<<24)|
  1308. (p->hl[1]<<16)|
  1309. (p->hl[2]<<8)|
  1310. (p->hl[3])) &
  1311. off;
  1312. break;
  1313. case FILE_OPOR:
  1314. offset = (int32_t)((p->hl[0]<<24)|
  1315. (p->hl[1]<<16)|
  1316. (p->hl[2]<<8)|
  1317. (p->hl[3])) |
  1318. off;
  1319. break;
  1320. case FILE_OPXOR:
  1321. offset = (int32_t)((p->hl[0]<<24)|
  1322. (p->hl[1]<<16)|
  1323. (p->hl[2]<<8)|
  1324. (p->hl[3])) ^
  1325. off;
  1326. break;
  1327. case FILE_OPADD:
  1328. offset = (int32_t)((p->hl[0]<<24)|
  1329. (p->hl[1]<<16)|
  1330. (p->hl[2]<<8)|
  1331. (p->hl[3])) +
  1332. off;
  1333. break;
  1334. case FILE_OPMINUS:
  1335. offset = (int32_t)((p->hl[0]<<24)|
  1336. (p->hl[1]<<16)|
  1337. (p->hl[2]<<8)|
  1338. (p->hl[3])) -
  1339. off;
  1340. break;
  1341. case FILE_OPMULTIPLY:
  1342. offset = (int32_t)((p->hl[0]<<24)|
  1343. (p->hl[1]<<16)|
  1344. (p->hl[2]<<8)|
  1345. (p->hl[3])) *
  1346. off;
  1347. break;
  1348. case FILE_OPDIVIDE:
  1349. offset = (int32_t)((p->hl[0]<<24)|
  1350. (p->hl[1]<<16)|
  1351. (p->hl[2]<<8)|
  1352. (p->hl[3])) /
  1353. off;
  1354. break;
  1355. case FILE_OPMODULO:
  1356. offset = (int32_t)((p->hl[0]<<24)|
  1357. (p->hl[1]<<16)|
  1358. (p->hl[2]<<8)|
  1359. (p->hl[3])) %
  1360. off;
  1361. break;
  1362. }
  1363. } else
  1364. offset = (int32_t)((p->hl[0]<<24)|
  1365. (p->hl[1]<<16)|
  1366. (p->hl[2]<<8)|
  1367. (p->hl[3]));
  1368. if (m->in_op & FILE_OPINVERSE)
  1369. offset = ~offset;
  1370. break;
  1371. case FILE_LELONG:
  1372. case FILE_LEID3:
  1373. if (OFFSET_OOB(nbytes, offset, 4))
  1374. return 0;
  1375. if (off) {
  1376. switch (m->in_op & FILE_OPS_MASK) {
  1377. case FILE_OPAND:
  1378. offset = (int32_t)((p->hl[3]<<24)|
  1379. (p->hl[2]<<16)|
  1380. (p->hl[1]<<8)|
  1381. (p->hl[0])) &
  1382. off;
  1383. break;
  1384. case FILE_OPOR:
  1385. offset = (int32_t)((p->hl[3]<<24)|
  1386. (p->hl[2]<<16)|
  1387. (p->hl[1]<<8)|
  1388. (p->hl[0])) |
  1389. off;
  1390. break;
  1391. case FILE_OPXOR:
  1392. offset = (int32_t)((p->hl[3]<<24)|
  1393. (p->hl[2]<<16)|
  1394. (p->hl[1]<<8)|
  1395. (p->hl[0])) ^
  1396. off;
  1397. break;
  1398. case FILE_OPADD:
  1399. offset = (int32_t)((p->hl[3]<<24)|
  1400. (p->hl[2]<<16)|
  1401. (p->hl[1]<<8)|
  1402. (p->hl[0])) +
  1403. off;
  1404. break;
  1405. case FILE_OPMINUS:
  1406. offset = (int32_t)((p->hl[3]<<24)|
  1407. (p->hl[2]<<16)|
  1408. (p->hl[1]<<8)|
  1409. (p->hl[0])) -
  1410. off;
  1411. break;
  1412. case FILE_OPMULTIPLY:
  1413. offset = (int32_t)((p->hl[3]<<24)|
  1414. (p->hl[2]<<16)|
  1415. (p->hl[1]<<8)|
  1416. (p->hl[0])) *
  1417. off;
  1418. break;
  1419. case FILE_OPDIVIDE:
  1420. offset = (int32_t)((p->hl[3]<<24)|
  1421. (p->hl[2]<<16)|
  1422. (p->hl[1]<<8)|
  1423. (p->hl[0])) /
  1424. off;
  1425. break;
  1426. case FILE_OPMODULO:
  1427. offset = (int32_t)((p->hl[3]<<24)|
  1428. (p->hl[2]<<16)|
  1429. (p->hl[1]<<8)|
  1430. (p->hl[0])) %
  1431. off;
  1432. break;
  1433. }
  1434. } else
  1435. offset = (int32_t)((p->hl[3]<<24)|
  1436. (p->hl[2]<<16)|
  1437. (p->hl[1]<<8)|
  1438. (p->hl[0]));
  1439. if (m->in_op & FILE_OPINVERSE)
  1440. offset = ~offset;
  1441. break;
  1442. case FILE_MELONG:
  1443. if (OFFSET_OOB(nbytes, offset, 4))
  1444. return 0;
  1445. if (off) {
  1446. switch (m->in_op & FILE_OPS_MASK) {
  1447. case FILE_OPAND:
  1448. offset = (int32_t)((p->hl[1]<<24)|
  1449. (p->hl[0]<<16)|
  1450. (p->hl[3]<<8)|
  1451. (p->hl[2])) &
  1452. off;
  1453. break;
  1454. case FILE_OPOR:
  1455. offset = (int32_t)((p->hl[1]<<24)|
  1456. (p->hl[0]<<16)|
  1457. (p->hl[3]<<8)|
  1458. (p->hl[2])) |
  1459. off;
  1460. break;
  1461. case FILE_OPXOR:
  1462. offset = (int32_t)((p->hl[1]<<24)|
  1463. (p->hl[0]<<16)|
  1464. (p->hl[3]<<8)|
  1465. (p->hl[2])) ^
  1466. off;
  1467. break;
  1468. case FILE_OPADD:
  1469. offset = (int32_t)((p->hl[1]<<24)|
  1470. (p->hl[0]<<16)|
  1471. (p->hl[3]<<8)|
  1472. (p->hl[2])) +
  1473. off;
  1474. break;
  1475. case FILE_OPMINUS:
  1476. offset = (int32_t)((p->hl[1]<<24)|
  1477. (p->hl[0]<<16)|
  1478. (p->hl[3]<<8)|
  1479. (p->hl[2])) -
  1480. off;
  1481. break;
  1482. case FILE_OPMULTIPLY:
  1483. offset = (int32_t)((p->hl[1]<<24)|
  1484. (p->hl[0]<<16)|
  1485. (p->hl[3]<<8)|
  1486. (p->hl[2])) *
  1487. off;
  1488. break;
  1489. case FILE_OPDIVIDE:
  1490. offset = (int32_t)((p->hl[1]<<24)|
  1491. (p->hl[0]<<16)|
  1492. (p->hl[3]<<8)|
  1493. (p->hl[2])) /
  1494. off;
  1495. break;
  1496. case FILE_OPMODULO:
  1497. offset = (int32_t)((p->hl[1]<<24)|
  1498. (p->hl[0]<<16)|
  1499. (p->hl[3]<<8)|
  1500. (p->hl[2])) %
  1501. off;
  1502. break;
  1503. }
  1504. } else
  1505. offset = (int32_t)((p->hl[1]<<24)|
  1506. (p->hl[0]<<16)|
  1507. (p->hl[3]<<8)|
  1508. (p->hl[2]));
  1509. if (m->in_op & FILE_OPINVERSE)
  1510. offset = ~offset;
  1511. break;
  1512. case FILE_LONG:
  1513. if (OFFSET_OOB(nbytes, offset, 4))
  1514. return 0;
  1515. if (off) {
  1516. switch (m->in_op & FILE_OPS_MASK) {
  1517. case FILE_OPAND:
  1518. offset = p->l & off;
  1519. break;
  1520. case FILE_OPOR:
  1521. offset = p->l | off;
  1522. break;
  1523. case FILE_OPXOR:
  1524. offset = p->l ^ off;
  1525. break;
  1526. case FILE_OPADD:
  1527. offset = p->l + off;
  1528. break;
  1529. case FILE_OPMINUS:
  1530. offset = p->l - off;
  1531. break;
  1532. case FILE_OPMULTIPLY:
  1533. offset = p->l * off;
  1534. break;
  1535. case FILE_OPDIVIDE:
  1536. offset = p->l / off;
  1537. break;
  1538. case FILE_OPMODULO:
  1539. offset = p->l % off;
  1540. break;
  1541. }
  1542. } else
  1543. offset = p->l;
  1544. if (m->in_op & FILE_OPINVERSE)
  1545. offset = ~offset;
  1546. break;
  1547. default:
  1548. break;
  1549. }
  1550. switch (in_type) {
  1551. case FILE_LEID3:
  1552. case FILE_BEID3:
  1553. offset = ((((offset >> 0) & 0x7f) << 0) |
  1554. (((offset >> 8) & 0x7f) << 7) |
  1555. (((offset >> 16) & 0x7f) << 14) |
  1556. (((offset >> 24) & 0x7f) << 21)) + 10;
  1557. break;
  1558. default:
  1559. break;
  1560. }
  1561. if (m->flag & INDIROFFADD) {
  1562. offset += ms->c.li[cont_level-1].off;
  1563. if (offset == 0) {
  1564. if ((ms->flags & MAGIC_DEBUG) != 0)
  1565. fprintf(stderr,
  1566. "indirect *zero* offset\n");
  1567. return 0;
  1568. }
  1569. if ((ms->flags & MAGIC_DEBUG) != 0)
  1570. fprintf(stderr, "indirect +offs=%u\n", offset);
  1571. }
  1572. if (mcopy(ms, p, m->type, 0, s, offset, nbytes, count) == -1)
  1573. return -1;
  1574. ms->offset = offset;
  1575. if ((ms->flags & MAGIC_DEBUG) != 0) {
  1576. mdebug(offset, (char *)(void *)p,
  1577. sizeof(union VALUETYPE));
  1578. #ifndef COMPILE_ONLY
  1579. file_mdump(m);
  1580. #endif
  1581. }
  1582. }
  1583. /* Verify we have enough data to match magic type */
  1584. switch (m->type) {
  1585. case FILE_BYTE:
  1586. if (OFFSET_OOB(nbytes, offset, 1))
  1587. return 0;
  1588. break;
  1589. case FILE_SHORT:
  1590. case FILE_BESHORT:
  1591. case FILE_LESHORT:
  1592. if (OFFSET_OOB(nbytes, offset, 2))
  1593. return 0;
  1594. break;
  1595. case FILE_LONG:
  1596. case FILE_BELONG:
  1597. case FILE_LELONG:
  1598. case FILE_MELONG:
  1599. case FILE_DATE:
  1600. case FILE_BEDATE:
  1601. case FILE_LEDATE:
  1602. case FILE_MEDATE:
  1603. case FILE_LDATE:
  1604. case FILE_BELDATE:
  1605. case FILE_LELDATE:
  1606. case FILE_MELDATE:
  1607. case FILE_FLOAT:
  1608. case FILE_BEFLOAT:
  1609. case FILE_LEFLOAT:
  1610. if (OFFSET_OOB(nbytes, offset, 4))
  1611. return 0;
  1612. break;
  1613. case FILE_DOUBLE:
  1614. case FILE_BEDOUBLE:
  1615. case FILE_LEDOUBLE:
  1616. if (OFFSET_OOB(nbytes, offset, 8))
  1617. return 0;
  1618. break;
  1619. case FILE_STRING:
  1620. case FILE_PSTRING:
  1621. case FILE_SEARCH:
  1622. if (OFFSET_OOB(nbytes, offset, m->vallen))
  1623. return 0;
  1624. break;
  1625. case FILE_REGEX:
  1626. if (OFFSET_OOB(nbytes, offset, 0))
  1627. return 0;
  1628. break;
  1629. case FILE_INDIRECT:
  1630. if (offset == 0)
  1631. return 0;
  1632. if (OFFSET_OOB(nbytes, offset, 0))
  1633. return 0;
  1634. sbuf = ms->o.buf;
  1635. soffset = ms->offset;
  1636. ms->o.buf = NULL;
  1637. ms->offset = 0;
  1638. rv = file_softmagic(ms, s + offset, nbytes - offset,
  1639. recursion_level, BINTEST, text);
  1640. if ((ms->flags & MAGIC_DEBUG) != 0)
  1641. fprintf(stderr, "indirect @offs=%u[%d]\n", offset, rv);
  1642. rbuf = ms->o.buf;
  1643. ms->o.buf = sbuf;
  1644. ms->offset = soffset;
  1645. if (rv == 1) {
  1646. if ((ms->flags & (MAGIC_MIME|MAGIC_APPLE)) == 0 &&
  1647. file_printf(ms, F(m->desc, "%u"), offset) == -1)
  1648. return -1;
  1649. if (file_printf(ms, "%s", rbuf) == -1)
  1650. return -1;
  1651. free(rbuf);
  1652. }
  1653. return rv;
  1654. case FILE_USE:
  1655. if (OFFSET_OOB(nbytes, offset, 0))
  1656. return 0;
  1657. sbuf = m->value.s;
  1658. if (*sbuf == '^') {
  1659. sbuf++;
  1660. flip = !flip;
  1661. }
  1662. if (file_magicfind(ms, sbuf, &ml) == -1) {
  1663. file_error(ms, 0, "cannot find entry `%s'", sbuf);
  1664. return -1;
  1665. }
  1666. oneed_separator = *need_separator;
  1667. if (m->flag & NOSPACE)
  1668. *need_separator = 0;
  1669. rv = match(ms, ml.magic, ml.nmagic, s, nbytes, offset + o,
  1670. mode, text, flip, recursion_level, printed_something,
  1671. need_separator, returnval);
  1672. if (rv != 1)
  1673. *need_separator = oneed_separator;
  1674. return rv;
  1675. case FILE_NAME:
  1676. if (file_printf(ms, "%s", m->desc) == -1)
  1677. return -1;
  1678. return 1;
  1679. case FILE_DEFAULT: /* nothing to check */
  1680. case FILE_CLEAR:
  1681. default:
  1682. break;
  1683. }
  1684. if (!mconvert(ms, m, flip))
  1685. return 0;
  1686. return 1;
  1687. }
  1688. private uint64_t
  1689. file_strncmp(const char *s1, const char *s2, size_t len, uint32_t flags)
  1690. {
  1691. /*
  1692. * Convert the source args to unsigned here so that (1) the
  1693. * compare will be unsigned as it is in strncmp() and (2) so
  1694. * the ctype functions will work correctly without extra
  1695. * casting.
  1696. */
  1697. const unsigned char *a = (const unsigned char *)s1;
  1698. const unsigned char *b = (const unsigned char *)s2;
  1699. uint64_t v;
  1700. /*
  1701. * What we want here is v = strncmp(s1, s2, len),
  1702. * but ignoring any nulls.
  1703. */
  1704. v = 0;
  1705. if (0L == flags) { /* normal string: do it fast */
  1706. while (len-- > 0)
  1707. if ((v = *b++ - *a++) != '\0')
  1708. break;
  1709. }
  1710. else { /* combine the others */
  1711. while (len-- > 0) {
  1712. if ((flags & STRING_IGNORE_LOWERCASE) &&
  1713. islower(*a)) {
  1714. if ((v = tolower(*b++) - *a++) != '\0')
  1715. break;
  1716. }
  1717. else if ((flags & STRING_IGNORE_UPPERCASE) &&
  1718. isupper(*a)) {
  1719. if ((v = toupper(*b++) - *a++) != '\0')
  1720. break;
  1721. }
  1722. else if ((flags & STRING_COMPACT_WHITESPACE) &&
  1723. isspace(*a)) {
  1724. a++;
  1725. if (isspace(*b++)) {
  1726. if (!isspace(*a))
  1727. while (isspace(*b))
  1728. b++;
  1729. }
  1730. else {
  1731. v = 1;
  1732. break;
  1733. }
  1734. }
  1735. else if ((flags & STRING_COMPACT_OPTIONAL_WHITESPACE) &&
  1736. isspace(*a)) {
  1737. a++;
  1738. while (isspace(*b))
  1739. b++;
  1740. }
  1741. else {
  1742. if ((v = *b++ - *a++) != '\0')
  1743. break;
  1744. }
  1745. }
  1746. }
  1747. return v;
  1748. }
  1749. private uint64_t
  1750. file_strncmp16(const char *a, const char *b, size_t len, uint32_t flags)
  1751. {
  1752. /*
  1753. * XXX - The 16-bit string compare probably needs to be done
  1754. * differently, especially if the flags are to be supported.
  1755. * At the moment, I am unsure.
  1756. */
  1757. flags = 0;
  1758. return file_strncmp(a, b, len, flags);
  1759. }
  1760. private int
  1761. magiccheck(struct magic_set *ms, struct magic *m)
  1762. {
  1763. uint64_t l = m->value.q;
  1764. uint64_t v;
  1765. float fl, fv;
  1766. double dl, dv;
  1767. int matched;
  1768. union VALUETYPE *p = &ms->ms_value;
  1769. switch (m->type) {
  1770. case FILE_BYTE:
  1771. v = p->b;
  1772. break;
  1773. case FILE_SHORT:
  1774. case FILE_BESHORT:
  1775. case FILE_LESHORT:
  1776. v = p->h;
  1777. break;
  1778. case FILE_LONG:
  1779. case FILE_BELONG:
  1780. case FILE_LELONG:
  1781. case FILE_MELONG:
  1782. case FILE_DATE:
  1783. case FILE_BEDATE:
  1784. case FILE_LEDATE:
  1785. case FILE_MEDATE:
  1786. case FILE_LDATE:
  1787. case FILE_BELDATE:
  1788. case FILE_LELDATE:
  1789. case FILE_MELDATE:
  1790. v = p->l;
  1791. break;
  1792. case FILE_QUAD:
  1793. case FILE_LEQUAD:
  1794. case FILE_BEQUAD:
  1795. case FILE_QDATE:
  1796. case FILE_BEQDATE:
  1797. case FILE_LEQDATE:
  1798. case FILE_QLDATE:
  1799. case FILE_BEQLDATE:
  1800. case FILE_LEQLDATE:
  1801. case FILE_QWDATE:
  1802. case FILE_BEQWDATE:
  1803. case FILE_LEQWDATE:
  1804. v = p->q;
  1805. break;
  1806. case FILE_FLOAT:
  1807. case FILE_BEFLOAT:
  1808. case FILE_LEFLOAT:
  1809. fl = m->value.f;
  1810. fv = p->f;
  1811. switch (m->reln) {
  1812. case 'x':
  1813. matched = 1;
  1814. break;
  1815. case '!':
  1816. matched = fv != fl;
  1817. break;
  1818. case '=':
  1819. matched = fv == fl;
  1820. break;
  1821. case '>':
  1822. matched = fv > fl;
  1823. break;
  1824. case '<':
  1825. matched = fv < fl;
  1826. break;
  1827. default:
  1828. matched = 0;
  1829. file_magerror(ms, "cannot happen with float: invalid relation `%c'",
  1830. m->reln);
  1831. return -1;
  1832. }
  1833. return matched;
  1834. case FILE_DOUBLE:
  1835. case FILE_BEDOUBLE:
  1836. case FILE_LEDOUBLE:
  1837. dl = m->value.d;
  1838. dv = p->d;
  1839. switch (m->reln) {
  1840. case 'x':
  1841. matched = 1;
  1842. break;
  1843. case '!':
  1844. matched = dv != dl;
  1845. break;
  1846. case '=':
  1847. matched = dv == dl;
  1848. break;
  1849. case '>':
  1850. matched = dv > dl;
  1851. break;
  1852. case '<':
  1853. matched = dv < dl;
  1854. break;
  1855. default:
  1856. matched = 0;
  1857. file_magerror(ms, "cannot happen with double: invalid relation `%c'", m->reln);
  1858. return -1;
  1859. }
  1860. return matched;
  1861. case FILE_DEFAULT:
  1862. case FILE_CLEAR:
  1863. l = 0;
  1864. v = 0;
  1865. break;
  1866. case FILE_STRING:
  1867. case FILE_PSTRING:
  1868. l = 0;
  1869. v = file_strncmp(m->value.s, p->s, (size_t)m->vallen, m->str_flags);
  1870. break;
  1871. case FILE_BESTRING16:
  1872. case FILE_LESTRING16:
  1873. l = 0;
  1874. v = file_strncmp16(m->value.s, p->s, (size_t)m->vallen, m->str_flags);
  1875. break;
  1876. case FILE_SEARCH: { /* search ms->search.s for the string m->value.s */
  1877. size_t slen;
  1878. size_t idx;
  1879. if (ms->search.s == NULL)
  1880. return 0;
  1881. slen = MIN(m->vallen, sizeof(m->value.s));
  1882. l = 0;
  1883. v = 0;
  1884. for (idx = 0; m->str_range == 0 || idx < m->str_range; idx++) {
  1885. if (slen + idx > ms->search.s_len)
  1886. break;
  1887. v = file_strncmp(m->value.s, ms->search.s + idx, slen, m->str_flags);
  1888. if (v == 0) { /* found match */
  1889. ms->search.offset += idx;
  1890. break;
  1891. }
  1892. }
  1893. break;
  1894. }
  1895. case FILE_REGEX: {
  1896. int rc;
  1897. regex_t rx;
  1898. char errmsg[512];
  1899. if (ms->search.s == NULL)
  1900. return 0;
  1901. l = 0;
  1902. rc = regcomp(&rx, m->value.s,
  1903. REG_EXTENDED|REG_NEWLINE|
  1904. ((m->str_flags & STRING_IGNORE_CASE) ? REG_ICASE : 0));
  1905. if (rc) {
  1906. (void)regerror(rc, &rx, errmsg, sizeof(errmsg));
  1907. file_magerror(ms, "regex error %d, (%s)",
  1908. rc, errmsg);
  1909. v = (uint64_t)-1;
  1910. }
  1911. else {
  1912. regmatch_t pmatch[1];
  1913. #ifndef REG_STARTEND
  1914. #define REG_STARTEND 0
  1915. size_t l = ms->search.s_len - 1;
  1916. char c = ms->search.s[l];
  1917. ((char *)(intptr_t)ms->search.s)[l] = '\0';
  1918. #else
  1919. pmatch[0].rm_so = 0;
  1920. pmatch[0].rm_eo = ms->search.s_len;
  1921. #endif
  1922. rc = regexec(&rx, (const char *)ms->search.s,
  1923. 1, pmatch, REG_STARTEND);
  1924. #if REG_STARTEND == 0
  1925. ((char *)(intptr_t)ms->search.s)[l] = c;
  1926. #endif
  1927. switch (rc) {
  1928. case 0:
  1929. ms->search.s += (int)pmatch[0].rm_so;
  1930. ms->search.offset += (size_t)pmatch[0].rm_so;
  1931. ms->search.rm_len =
  1932. (size_t)(pmatch[0].rm_eo - pmatch[0].rm_so);
  1933. v = 0;
  1934. break;
  1935. case REG_NOMATCH:
  1936. v = 1;
  1937. break;
  1938. default:
  1939. (void)regerror(rc, &rx, errmsg, sizeof(errmsg));
  1940. file_magerror(ms, "regexec error %d, (%s)",
  1941. rc, errmsg);
  1942. v = (uint64_t)-1;
  1943. break;
  1944. }
  1945. regfree(&rx);
  1946. }
  1947. if (v == (uint64_t)-1)
  1948. return -1;
  1949. break;
  1950. }
  1951. case FILE_INDIRECT:
  1952. case FILE_USE:
  1953. case FILE_NAME:
  1954. return 1;
  1955. default:
  1956. file_magerror(ms, "invalid type %d in magiccheck()", m->type);
  1957. return -1;
  1958. }
  1959. v = file_signextend(ms, m, v);
  1960. switch (m->reln) {
  1961. case 'x':
  1962. if ((ms->flags & MAGIC_DEBUG) != 0)
  1963. (void) fprintf(stderr, "%" INT64_T_FORMAT
  1964. "u == *any* = 1\n", (unsigned long long)v);
  1965. matched = 1;
  1966. break;
  1967. case '!':
  1968. matched = v != l;
  1969. if ((ms->flags & MAGIC_DEBUG) != 0)
  1970. (void) fprintf(stderr, "%" INT64_T_FORMAT "u != %"
  1971. INT64_T_FORMAT "u = %d\n", (unsigned long long)v,
  1972. (unsigned long long)l, matched);
  1973. break;
  1974. case '=':
  1975. matched = v == l;
  1976. if ((ms->flags & MAGIC_DEBUG) != 0)
  1977. (void) fprintf(stderr, "%" INT64_T_FORMAT "u == %"
  1978. INT64_T_FORMAT "u = %d\n", (unsigned long long)v,
  1979. (unsigned long long)l, matched);
  1980. break;
  1981. case '>':
  1982. if (m->flag & UNSIGNED) {
  1983. matched = v > l;
  1984. if ((ms->flags & MAGIC_DEBUG) != 0)
  1985. (void) fprintf(stderr, "%" INT64_T_FORMAT
  1986. "u > %" INT64_T_FORMAT "u = %d\n",
  1987. (unsigned long long)v,
  1988. (unsigned long long)l, matched);
  1989. }
  1990. else {
  1991. matched = (int64_t) v > (int64_t) l;
  1992. if ((ms->flags & MAGIC_DEBUG) != 0)
  1993. (void) fprintf(stderr, "%" INT64_T_FORMAT
  1994. "d > %" INT64_T_FORMAT "d = %d\n",
  1995. (long long)v, (long long)l, matched);
  1996. }
  1997. break;
  1998. case '<':
  1999. if (m->flag & UNSIGNED) {
  2000. matched = v < l;
  2001. if ((ms->flags & MAGIC_DEBUG) != 0)
  2002. (void) fprintf(stderr, "%" INT64_T_FORMAT
  2003. "u < %" INT64_T_FORMAT "u = %d\n",
  2004. (unsigned long long)v,
  2005. (unsigned long long)l, matched);
  2006. }
  2007. else {
  2008. matched = (int64_t) v < (int64_t) l;
  2009. if ((ms->flags & MAGIC_DEBUG) != 0)
  2010. (void) fprintf(stderr, "%" INT64_T_FORMAT
  2011. "d < %" INT64_T_FORMAT "d = %d\n",
  2012. (long long)v, (long long)l, matched);
  2013. }
  2014. break;
  2015. case '&':
  2016. matched = (v & l) == l;
  2017. if ((ms->flags & MAGIC_DEBUG) != 0)
  2018. (void) fprintf(stderr, "((%" INT64_T_FORMAT "x & %"
  2019. INT64_T_FORMAT "x) == %" INT64_T_FORMAT
  2020. "x) = %d\n", (unsigned long long)v,
  2021. (unsigned long long)l, (unsigned long long)l,
  2022. matched);
  2023. break;
  2024. case '^':
  2025. matched = (v & l) != l;
  2026. if ((ms->flags & MAGIC_DEBUG) != 0)
  2027. (void) fprintf(stderr, "((%" INT64_T_FORMAT "x & %"
  2028. INT64_T_FORMAT "x) != %" INT64_T_FORMAT
  2029. "x) = %d\n", (unsigned long long)v,
  2030. (unsigned long long)l, (unsigned long long)l,
  2031. matched);
  2032. break;
  2033. default:
  2034. matched = 0;
  2035. file_magerror(ms, "cannot happen: invalid relation `%c'",
  2036. m->reln);
  2037. return -1;
  2038. }
  2039. return matched;
  2040. }
  2041. private int
  2042. handle_annotation(struct magic_set *ms, struct magic *m)
  2043. {
  2044. if (ms->flags & MAGIC_APPLE) {
  2045. if (file_printf(ms, "%.8s", m->apple) == -1)
  2046. return -1;
  2047. return 1;
  2048. }
  2049. if ((ms->flags & MAGIC_MIME_TYPE) && m->mimetype[0]) {
  2050. if (file_printf(ms, "%s", m->mimetype) == -1)
  2051. return -1;
  2052. return 1;
  2053. }
  2054. return 0;
  2055. }
  2056. private int
  2057. print_sep(struct magic_set *ms, int firstline)
  2058. {
  2059. if (ms->flags & MAGIC_MIME)
  2060. return 0;
  2061. if (firstline)
  2062. return 0;
  2063. /*
  2064. * we found another match
  2065. * put a newline and '-' to do some simple formatting
  2066. */
  2067. return file_printf(ms, "\n- ");
  2068. }