softmagic.c 48 KB

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