softmagic.c 49 KB

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