softmagic.c 45 KB

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