Deleted Added
full compact
funcs.c (169942) funcs.c (169962)
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
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
39
40#ifndef lint
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 $")
42#endif /* lint */
43
44#ifndef HAVE_VSNPRINTF
45int vsnprintf(char *, size_t, const char *, va_list);
46#endif
47
48/*
49 * Like printf, only we print to a buffer and advance it.
50 */
51protected int
52file_printf(struct magic_set *ms, const char *fmt, ...)
53{
54 va_list ap;
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;
56 char *buf;
57
58 va_start(ap, fmt);
59
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
61 va_end(ap);
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);
64 return -1;
65 }
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;
67 ms->o.buf = buf;
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;
70
71 va_start(ap, fmt);
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);
73 }
87 }
74 ms->o.ptr += len;
75 ms->o.len -= len;
76 va_end(ap);
88 va_end(ap);
89 ms->o.ptr += len;
90 ms->o.left -= len;
77 return 0;
78}
79
80/*
81 * error - print best error message possible
82 */
83/*VARARGS*/
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)
86{
101{
87 va_list va;
102 size_t len;
88 /* Only the first error is ok */
89 if (ms->haderr)
90 return;
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);
94 if (error > 0) {
112 if (error > 0) {
95 size_t len = strlen(ms->o.buf);
113 len = strlen(ms->o.buf);
96 (void)snprintf(ms->o.buf + len, ms->o.size - len, " (%s)",
97 strerror(error));
98 }
99 ms->haderr++;
100 ms->error = error;
101}
102
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}
103
130
131/*
132 * Print an error with magic line number.
133 */
134/*VARARGS*/
104protected void
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
105file_oomem(struct magic_set *ms, size_t len)
106{
107 file_error(ms, errno, "cannot allocate %zu bytes", len);
108}
109
110protected void
111file_badseek(struct magic_set *ms)
112{
113 file_error(ms, errno, "error seeking");
114}
115
116protected void
117file_badread(struct magic_set *ms)
118{
119 file_error(ms, errno, "error reading");
120}
121
122#ifndef COMPILE_ONLY
123protected int
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)
125{
126 int m;
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
127 /* try compression stuff */
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) {
129 /* Check if we have a tar file */
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) {
131 /* try tests in /etc/magic (or surrogate magic file) */
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) {
133 /* try known keywords, check whether it is ASCII */
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) {
135 /* abandon hope, all ye who remain here */
136 if (file_printf(ms, ms->flags & MAGIC_MIME ?
137 (nb ? "application/octet-stream" :
138 "application/empty") :
139 (nb ? "data" :
140 "empty")) == -1)
141 return -1;
142 m = 1;
143 }
144 }
145 }
146 }
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
147 return m;
148}
149#endif
150
151protected int
152file_reset(struct magic_set *ms)
153{
154 if (ms->mlist == NULL) {
155 file_error(ms, 0, "no magic files loaded");
156 return -1;
157 }
158 ms->o.ptr = ms->o.buf;
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;
159 ms->haderr = 0;
160 ms->error = -1;
161 return 0;
162}
163
164#define OCTALIFY(n, o) \
165 /*LINTED*/ \
166 (void)(*(n)++ = '\\', \
167 *(n)++ = (((uint32_t)*(o) >> 6) & 3) + '0', \
168 *(n)++ = (((uint32_t)*(o) >> 3) & 7) + '0', \
169 *(n)++ = (((uint32_t)*(o) >> 0) & 7) + '0', \
170 (o)++)
171
172protected const char *
173file_getbuffer(struct magic_set *ms)
174{
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;
177
178 if (ms->haderr)
179 return NULL;
180
181 if (ms->flags & MAGIC_RAW)
182 return ms->o.buf;
183
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);
188 return NULL;
189 }
267 return NULL;
268 }
190 ms->o.psize = nsize;
191 ms->o.pbuf = nbuf;
269 ms->o.psize = psize;
270 ms->o.pbuf = pbuf;
192 }
193
194#if defined(HAVE_WCHAR_H) && defined(HAVE_MBRTOWC) && defined(HAVE_WCWIDTH)
195 {
196 mbstate_t state;
197 wchar_t nextchar;
198 int mb_conv = 1;
199 size_t bytesconsumed;

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

236 } else {
237 OCTALIFY(np, op);
238 }
239 }
240 *np = '\0';
241 return ms->o.pbuf;
242}
243
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}
244/*
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?
247 */
248#ifndef HAVE_VSNPRINTF
249int
250vsnprintf(char *buf, size_t len, const char *fmt, va_list ap)
251{
252 return vsprintf(buf, fmt, ap);
253}
254#endif

--- 14 unchanged lines hidden ---
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 ---