Deleted Added
full compact
1/*
2 * Copyright (c) Christos Zoulas 2003.
3 * All Rights Reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 22 unchanged lines hidden (view full) ---

31#include <string.h>
32#include <ctype.h>
33#if defined(HAVE_WCHAR_H)
34#include <wchar.h>
35#endif
36#if defined(HAVE_WCTYPE_H)
37#include <wctype.h>
38#endif
39#if defined(HAVE_LIMITS_H)
40#include <limits.h>
41#endif
42#ifndef SIZE_T_MAX
43#ifdef __LP64__
44#define SIZE_T_MAX (size_t)0xfffffffffffffffffU
45#else
46#define SIZE_T_MAX (size_t)0xffffffffU
47#endif
48#endif
49
50#ifndef lint
41FILE_RCSID("@(#)$Id: funcs.c,v 1.23 2006/12/11 21:48:49 christos Exp $")
51FILE_RCSID("@(#)$File: funcs.c,v 1.32 2007/05/24 17:22:27 christos Exp $")
52#endif /* lint */
53
54#ifndef HAVE_VSNPRINTF
55int vsnprintf(char *, size_t, const char *, va_list);
56#endif
57
58/*
59 * Like printf, only we print to a buffer and advance it.
60 */
61protected int
62file_printf(struct magic_set *ms, const char *fmt, ...)
63{
64 va_list ap;
55 size_t len;
65 size_t len, size;
66 char *buf;
67
68 va_start(ap, fmt);
69
60 if ((len = vsnprintf(ms->o.ptr, ms->o.len, fmt, ap)) >= ms->o.len) {
70 if ((len = vsnprintf(ms->o.ptr, ms->o.left, fmt, ap)) >= ms->o.left) {
71 long diff; /* XXX: really ptrdiff_t */
72
73 va_end(ap);
62 if ((buf = realloc(ms->o.buf, len + 1024)) == NULL) {
63 file_oomem(ms, len + 1024);
74 size = (ms->o.size - ms->o.left) + len + 1024;
75 if ((buf = realloc(ms->o.buf, size)) == NULL) {
76 file_oomem(ms, size);
77 return -1;
78 }
66 ms->o.ptr = buf + (ms->o.ptr - ms->o.buf);
79 diff = ms->o.ptr - ms->o.buf;
80 ms->o.ptr = buf + diff;
81 ms->o.buf = buf;
68 ms->o.len = ms->o.size - (ms->o.ptr - ms->o.buf);
69 ms->o.size = len + 1024;
82 ms->o.left = size - diff;
83 ms->o.size = size;
84
85 va_start(ap, fmt);
72 len = vsnprintf(ms->o.ptr, ms->o.len, fmt, ap);
86 len = vsnprintf(ms->o.ptr, ms->o.left, fmt, ap);
87 }
74 ms->o.ptr += len;
75 ms->o.len -= len;
88 va_end(ap);
89 ms->o.ptr += len;
90 ms->o.left -= len;
91 return 0;
92}
93
94/*
95 * error - print best error message possible
96 */
97/*VARARGS*/
84protected void
85file_error(struct magic_set *ms, int error, const char *f, ...)
98private void
99file_error_core(struct magic_set *ms, int error, const char *f, va_list va,
100 uint32_t lineno)
101{
87 va_list va;
102 size_t len;
103 /* Only the first error is ok */
104 if (ms->haderr)
105 return;
91 va_start(va, f);
92 (void)vsnprintf(ms->o.buf, ms->o.size, f, va);
93 va_end(va);
106 len = 0;
107 if (lineno != 0) {
108 (void)snprintf(ms->o.buf, ms->o.size, "line %u: ", lineno);
109 len = strlen(ms->o.buf);
110 }
111 (void)vsnprintf(ms->o.buf + len, ms->o.size - len, f, va);
112 if (error > 0) {
95 size_t len = strlen(ms->o.buf);
113 len = strlen(ms->o.buf);
114 (void)snprintf(ms->o.buf + len, ms->o.size - len, " (%s)",
115 strerror(error));
116 }
117 ms->haderr++;
118 ms->error = error;
119}
120
121/*VARARGS*/
122protected void
123file_error(struct magic_set *ms, int error, const char *f, ...)
124{
125 va_list va;
126 va_start(va, f);
127 file_error_core(ms, error, f, va, 0);
128 va_end(va);
129}
130
131/*
132 * Print an error with magic line number.
133 */
134/*VARARGS*/
135protected void
136file_magerror(struct magic_set *ms, const char *f, ...)
137{
138 va_list va;
139 va_start(va, f);
140 file_error_core(ms, 0, f, va, ms->line);
141 va_end(va);
142}
143
144protected void
145file_oomem(struct magic_set *ms, size_t len)
146{
147 file_error(ms, errno, "cannot allocate %zu bytes", len);
148}
149
150protected void
151file_badseek(struct magic_set *ms)
152{
153 file_error(ms, errno, "error seeking");
154}
155
156protected void
157file_badread(struct magic_set *ms)
158{
159 file_error(ms, errno, "error reading");
160}
161
162#ifndef COMPILE_ONLY
163protected int
124file_buffer(struct magic_set *ms, int fd, const void *buf, size_t nb)
164file_buffer(struct magic_set *ms, int fd, const char *inname, const void *buf,
165 size_t nb)
166{
167 int m;
168
169#ifdef __EMX__
170 if ((ms->flags & MAGIC_NO_CHECK_APPTYPE) == 0 && inname) {
171 switch (file_os2_apptype(ms, inname, buf, nb)) {
172 case -1:
173 return -1;
174 case 0:
175 break;
176 default:
177 return 1;
178 }
179 }
180#endif
181
182 /* try compression stuff */
128 if ((m = file_zmagic(ms, fd, buf, nb)) == 0) {
183 if ((ms->flags & MAGIC_NO_CHECK_COMPRESS) != 0 ||
184 (m = file_zmagic(ms, fd, inname, buf, nb)) == 0) {
185 /* Check if we have a tar file */
130 if ((m = file_is_tar(ms, buf, nb)) == 0) {
186 if ((ms->flags & MAGIC_NO_CHECK_TAR) != 0 ||
187 (m = file_is_tar(ms, buf, nb)) == 0) {
188 /* try tests in /etc/magic (or surrogate magic file) */
132 if ((m = file_softmagic(ms, buf, nb)) == 0) {
189 if ((ms->flags & MAGIC_NO_CHECK_SOFT) != 0 ||
190 (m = file_softmagic(ms, buf, nb)) == 0) {
191 /* try known keywords, check whether it is ASCII */
134 if ((m = file_ascmagic(ms, buf, nb)) == 0) {
192 if ((ms->flags & MAGIC_NO_CHECK_ASCII) != 0 ||
193 (m = file_ascmagic(ms, buf, nb)) == 0) {
194 /* abandon hope, all ye who remain here */
195 if (file_printf(ms, ms->flags & MAGIC_MIME ?
196 (nb ? "application/octet-stream" :
197 "application/empty") :
198 (nb ? "data" :
199 "empty")) == -1)
200 return -1;
201 m = 1;
202 }
203 }
204 }
205 }
206#ifdef BUILTIN_ELF
207 if ((ms->flags & MAGIC_NO_CHECK_ELF) == 0 && m == 1 && nb > 5 && fd != -1) {
208 /*
209 * We matched something in the file, so this *might*
210 * be an ELF file, and the file is at least 5 bytes
211 * long, so if it's an ELF file it has at least one
212 * byte past the ELF magic number - try extracting
213 * information from the ELF headers that cannot easily
214 * be extracted with rules in the magic file.
215 */
216 (void)file_tryelf(ms, fd, buf, nb);
217 }
218#endif
219 return m;
220}
221#endif
222
223protected int
224file_reset(struct magic_set *ms)
225{
226 if (ms->mlist == NULL) {
227 file_error(ms, 0, "no magic files loaded");
228 return -1;
229 }
230 ms->o.ptr = ms->o.buf;
231 ms->o.left = ms->o.size;
232 ms->haderr = 0;
233 ms->error = -1;
234 return 0;
235}
236
237#define OCTALIFY(n, o) \
238 /*LINTED*/ \
239 (void)(*(n)++ = '\\', \
240 *(n)++ = (((uint32_t)*(o) >> 6) & 3) + '0', \
241 *(n)++ = (((uint32_t)*(o) >> 3) & 7) + '0', \
242 *(n)++ = (((uint32_t)*(o) >> 0) & 7) + '0', \
243 (o)++)
244
245protected const char *
246file_getbuffer(struct magic_set *ms)
247{
175 char *nbuf, *op, *np;
176 size_t nsize;
248 char *pbuf, *op, *np;
249 size_t psize, len;
250
251 if (ms->haderr)
252 return NULL;
253
254 if (ms->flags & MAGIC_RAW)
255 return ms->o.buf;
256
184 nsize = ms->o.len * 4 + 1;
185 if (ms->o.psize < nsize) {
186 if ((nbuf = realloc(ms->o.pbuf, nsize)) == NULL) {
187 file_oomem(ms, nsize);
257 len = ms->o.size - ms->o.left;
258 /* * 4 is for octal representation, + 1 is for NUL */
259 if (len > (SIZE_T_MAX - 1) / 4) {
260 file_oomem(ms, len);
261 return NULL;
262 }
263 psize = len * 4 + 1;
264 if (ms->o.psize < psize) {
265 if ((pbuf = realloc(ms->o.pbuf, psize)) == NULL) {
266 file_oomem(ms, psize);
267 return NULL;
268 }
190 ms->o.psize = nsize;
191 ms->o.pbuf = nbuf;
269 ms->o.psize = psize;
270 ms->o.pbuf = pbuf;
271 }
272
273#if defined(HAVE_WCHAR_H) && defined(HAVE_MBRTOWC) && defined(HAVE_WCWIDTH)
274 {
275 mbstate_t state;
276 wchar_t nextchar;
277 int mb_conv = 1;
278 size_t bytesconsumed;

--- 36 unchanged lines hidden (view full) ---

315 } else {
316 OCTALIFY(np, op);
317 }
318 }
319 *np = '\0';
320 return ms->o.pbuf;
321}
322
323protected int
324file_check_mem(struct magic_set *ms, unsigned int level)
325{
326 size_t len;
327
328 if (level >= ms->c.len) {
329 len = (ms->c.len += 20) * sizeof(*ms->c.li);
330 ms->c.li = (ms->c.li == NULL) ? malloc(len) :
331 realloc(ms->c.li, len);
332 if (ms->c.li == NULL) {
333 file_oomem(ms, len);
334 return -1;
335 }
336 }
337 ms->c.li[level].got_match = 0;
338#ifdef ENABLE_CONDITIONALS
339 ms->c.li[level].last_match = 0;
340 ms->c.li[level].last_cond = COND_NONE;
341#endif /* ENABLE_CONDITIONALS */
342 return 0;
343}
344/*
245 * Yes these wrappers suffer from buffer overflows, but if your OS does not have
246 * the real functions, maybe you should consider replacing your OS?
345 * Yes these wrappers suffer from buffer overflows, but if your OS does not
346 * have the real functions, maybe you should consider replacing your OS?
347 */
348#ifndef HAVE_VSNPRINTF
349int
350vsnprintf(char *buf, size_t len, const char *fmt, va_list ap)
351{
352 return vsprintf(buf, fmt, ap);
353}
354#endif

--- 14 unchanged lines hidden ---