git-svn: trunk@2435
Nigel Horne authored on 2006/10/27 23:07:37... | ... |
@@ -1,3 +1,7 @@ |
1 |
+Fri Oct 27 15:06:53 BST 2006 (njh) |
|
2 |
+---------------------------------- |
|
3 |
+ * libclamav/js.[ch]: Renamed to jscript.[ch] at the request of TK |
|
4 |
+ |
|
1 | 5 |
Fri Oct 27 02:37:49 CEST 2006 (acab) |
2 | 6 |
------------------------------------ |
3 | 7 |
* libclamav/petite.c: sanity check the number of rebuilt sections |
4 | 8 |
deleted file mode 100644 |
... | ... |
@@ -1,354 +0,0 @@ |
1 |
-/* |
|
2 |
- * Copyright (C) 2006 Nigel Horne <njh@clamav.net> |
|
3 |
- * |
|
4 |
- * This program is free software; you can redistribute it and/or modify |
|
5 |
- * it under the terms of the GNU General Public License as published by |
|
6 |
- * the Free Software Foundation; either version 2 of the License, or |
|
7 |
- * (at your option) any later version. |
|
8 |
- * |
|
9 |
- * This program is distributed in the hope that it will be useful, |
|
10 |
- * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 |
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 |
- * GNU General Public License for more details. |
|
13 |
- * |
|
14 |
- * You should have received a copy of the GNU General Public License |
|
15 |
- * along with this program; if not, write to the Free Software |
|
16 |
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, |
|
17 |
- * MA 02110-1301, USA. |
|
18 |
- * |
|
19 |
- * Save the JavaScript embedded in an HTML file, then run the script, saving |
|
20 |
- * the output in a file that is to be scanned, then remove the script file |
|
21 |
- */ |
|
22 |
-static char const rcsid[] = "$Id: js.c,v 1.13 2006/10/22 09:35:05 njh Exp $"; |
|
23 |
- |
|
24 |
-#if HAVE_CONFIG_H |
|
25 |
-#include "clamav-config.h" |
|
26 |
-#endif |
|
27 |
- |
|
28 |
-#include "clamav.h" |
|
29 |
-#include "others.h" |
|
30 |
- |
|
31 |
-#ifdef CL_EXPERIMENTAL |
|
32 |
- |
|
33 |
-#if HAVE_MMAP |
|
34 |
- |
|
35 |
-#include <memory.h> |
|
36 |
-#include <string.h> |
|
37 |
-#include <limits.h> |
|
38 |
-#include <errno.h> |
|
39 |
-#include <ctype.h> |
|
40 |
- |
|
41 |
-#ifdef HAVE_UNISTD_H |
|
42 |
-#include <unistd.h> |
|
43 |
-#endif |
|
44 |
- |
|
45 |
-#include "js.h" |
|
46 |
- |
|
47 |
-#if HAVE_SYS_MMAN_H |
|
48 |
-#include <sys/mman.h> |
|
49 |
-#endif |
|
50 |
- |
|
51 |
-/* Maximum filenames under various systems - njh */ |
|
52 |
-#ifndef NAME_MAX /* e.g. Linux */ |
|
53 |
-# ifdef MAXNAMELEN /* e.g. Solaris */ |
|
54 |
-# define NAME_MAX MAXNAMELEN |
|
55 |
-# else |
|
56 |
-# ifdef FILENAME_MAX /* e.g. SCO */ |
|
57 |
-# define NAME_MAX FILENAME_MAX |
|
58 |
-# else |
|
59 |
-# define NAME_MAX 256 |
|
60 |
-# endif |
|
61 |
-# endif |
|
62 |
-#endif |
|
63 |
- |
|
64 |
-static void run_js(const char *filename, const char *dir); |
|
65 |
-static const char *cli_pmemstr(const char *haystack, size_t hs, const char *needle, size_t ns); |
|
66 |
- |
|
67 |
-int |
|
68 |
-cli_scanjs(const char *dir, int desc) |
|
69 |
-{ |
|
70 |
- struct stat statb; |
|
71 |
- off_t size; /* total number of bytes in the file */ |
|
72 |
- char *buf; /* start of memory mapped area */ |
|
73 |
- const char *p; |
|
74 |
- long bytesleft; |
|
75 |
- int created_output, done_header, rc; |
|
76 |
- FILE *fout; |
|
77 |
- char script_filename[NAME_MAX + 1]; |
|
78 |
- extern short cli_leavetemps_flag; |
|
79 |
- |
|
80 |
- cli_dbgmsg("in cli_scanjs(%s)\n", dir); |
|
81 |
- |
|
82 |
- if(fstat(desc, &statb) < 0) |
|
83 |
- return CL_EOPEN; |
|
84 |
- |
|
85 |
- size = (size_t)statb.st_size; |
|
86 |
- |
|
87 |
- if(size == 0) |
|
88 |
- return CL_CLEAN; |
|
89 |
- |
|
90 |
- if(size <= 17) /* doesn't even include <script></script> */ |
|
91 |
- return CL_EFORMAT; |
|
92 |
- |
|
93 |
- p = buf = mmap(NULL, size, PROT_READ, MAP_PRIVATE, desc, 0); |
|
94 |
- if(buf == MAP_FAILED) |
|
95 |
- return CL_EMEM; |
|
96 |
- |
|
97 |
- cli_dbgmsg("cli_scanjs: scanning %lu bytes\n", size); |
|
98 |
- |
|
99 |
- p = buf; |
|
100 |
- bytesleft = size; |
|
101 |
- created_output = done_header = 0; |
|
102 |
- fout = NULL; |
|
103 |
- |
|
104 |
- while(p < &buf[size]) { |
|
105 |
- const char *q = cli_pmemstr(p, bytesleft, "<script", 7); |
|
106 |
- |
|
107 |
- if(q == NULL) |
|
108 |
- /* TODO: full case independant search */ |
|
109 |
- q = cli_pmemstr(p, bytesleft, "<SCRIPT", 7); |
|
110 |
- |
|
111 |
- if(q == NULL) |
|
112 |
- break; |
|
113 |
- |
|
114 |
- /* |
|
115 |
- * TODO: check language is javascript |
|
116 |
- * TODO: follow src if mail-follow-urls is set |
|
117 |
- */ |
|
118 |
- |
|
119 |
- bytesleft -= (q - p); |
|
120 |
- p = q; |
|
121 |
- |
|
122 |
- q = cli_pmemstr(p, bytesleft, ">", 1); |
|
123 |
- if(q == NULL) |
|
124 |
- break; |
|
125 |
- |
|
126 |
- bytesleft -= (q - p); |
|
127 |
- p = q; |
|
128 |
- |
|
129 |
- p++; |
|
130 |
- bytesleft--; |
|
131 |
- |
|
132 |
- while(bytesleft) { |
|
133 |
- char c; |
|
134 |
- |
|
135 |
- if(*p == '<') { |
|
136 |
- p++; |
|
137 |
- if(--bytesleft == 0) |
|
138 |
- break; |
|
139 |
- if((*p == '!') && !done_header) { |
|
140 |
- while(bytesleft && (*p != '\n')) { |
|
141 |
- p++; |
|
142 |
- bytesleft--; |
|
143 |
- } |
|
144 |
- continue; |
|
145 |
- } |
|
146 |
- if((bytesleft >= 7) && (strncasecmp(p, "/script", 7) == 0)) { |
|
147 |
- bytesleft -= 7; |
|
148 |
- p = &p[7]; |
|
149 |
- while(bytesleft && (*p != '>')) { |
|
150 |
- p++; |
|
151 |
- bytesleft--; |
|
152 |
- } |
|
153 |
- if(fout) { |
|
154 |
- fclose(fout); |
|
155 |
- fout = NULL; |
|
156 |
- run_js(script_filename, dir); |
|
157 |
- |
|
158 |
- if(!cli_leavetemps_flag) |
|
159 |
- unlink(script_filename); |
|
160 |
- } |
|
161 |
- done_header = 0; |
|
162 |
- break; |
|
163 |
- } |
|
164 |
- c = '<'; |
|
165 |
- } else { |
|
166 |
- /*c = tolower(*p);*/ |
|
167 |
- c = *p; |
|
168 |
- p++; |
|
169 |
- bytesleft--; |
|
170 |
- } |
|
171 |
- |
|
172 |
- if(!done_header) { |
|
173 |
- int fd; |
|
174 |
- |
|
175 |
- snprintf(script_filename, sizeof(script_filename), "%s/jsXXXXXX", dir); |
|
176 |
-#if defined(C_LINUX) || defined(C_BSD) || defined(HAVE_MKSTEMP) || defined(C_SOLARIS) || defined(C_CYGWIN) |
|
177 |
- fd = mkstemp(script_filename); |
|
178 |
- fout = fdopen(fd, "wb"); |
|
179 |
- if(fout == NULL) |
|
180 |
- close(fd); |
|
181 |
-#elif defined(C_WINDOWS) |
|
182 |
- if(_mktemp(script_filename) == NULL) { |
|
183 |
- /* mktemp only allows 26 files */ |
|
184 |
- char *name = cli_gentemp(dir); |
|
185 |
- if(name == NULL) |
|
186 |
- fout = NULL; |
|
187 |
- else { |
|
188 |
- strcpy(script_filename, name); |
|
189 |
- free(name); |
|
190 |
- fout = fopen(script_filename, "wb"); |
|
191 |
- } |
|
192 |
- } else |
|
193 |
- fout = fopen(script_filename, "wb"); |
|
194 |
-#else |
|
195 |
- mktemp(script_filename); |
|
196 |
- fout = fopen(script_filename, "wb"); |
|
197 |
-#endif |
|
198 |
- |
|
199 |
- if(fout == NULL) { |
|
200 |
- cli_errmsg("cli_scanjs: can't create temporary file %s: %s\n", script_filename, strerror(errno)); |
|
201 |
- munmap(buf, size); |
|
202 |
- return CL_ETMPFILE; |
|
203 |
- } |
|
204 |
- cli_dbgmsg("Saving javascript to %s\n", |
|
205 |
- script_filename); |
|
206 |
- |
|
207 |
- /* |
|
208 |
- * Create a document object, on web pages it's |
|
209 |
- * used to send output to the browser |
|
210 |
- * FIXME: will create a file even if the script |
|
211 |
- * is empty, e.g. src is somewhere else |
|
212 |
- */ |
|
213 |
- fputs("function createDoc() {\n", fout); |
|
214 |
- fputs("\tfunction write(text) {\n", fout); |
|
215 |
- /* |
|
216 |
- * Use System.print rather than print so that |
|
217 |
- * a new line is not appended |
|
218 |
- */ |
|
219 |
- fputs("\t\tSystem.print(text);\n", fout); |
|
220 |
- fputs("\t}\n", fout); |
|
221 |
- fputs("}\n", fout); |
|
222 |
- fputs("document = new createDoc();\n", fout); |
|
223 |
- |
|
224 |
- done_header = 1; |
|
225 |
- created_output = 1; |
|
226 |
- } |
|
227 |
- putc(c, fout); |
|
228 |
- } |
|
229 |
- } |
|
230 |
- |
|
231 |
- munmap(buf, size); |
|
232 |
- |
|
233 |
- rc = CL_SUCCESS; |
|
234 |
- |
|
235 |
- if(!created_output) |
|
236 |
- cli_dbgmsg("No javascript was detected\n"); |
|
237 |
- else if(fout) { |
|
238 |
- fclose(fout); |
|
239 |
- run_js(script_filename, dir); |
|
240 |
- |
|
241 |
- if(!cli_leavetemps_flag) |
|
242 |
- unlink(script_filename); |
|
243 |
- } |
|
244 |
- return rc; |
|
245 |
-} |
|
246 |
- |
|
247 |
-static void |
|
248 |
-run_js(const char *filename, const char *dir) |
|
249 |
-{ |
|
250 |
- JSInterpPtr interp; |
|
251 |
- FILE *real_stdout, *temp_stdout; |
|
252 |
- char *outputfilename; |
|
253 |
- |
|
254 |
- cli_dbgmsg("run_js(%s)\n", filename); |
|
255 |
- |
|
256 |
- fflush(stdout); |
|
257 |
- real_stdout = stdout; |
|
258 |
- outputfilename = cli_gentemp(dir); |
|
259 |
- if(outputfilename) { |
|
260 |
- temp_stdout = fopen(outputfilename, "wb"); |
|
261 |
- if(temp_stdout) { |
|
262 |
- cli_dbgmsg("Redirecting JS VM stdout to %s\n", |
|
263 |
- outputfilename); |
|
264 |
- stdout = temp_stdout; |
|
265 |
- } |
|
266 |
- } else |
|
267 |
- temp_stdout = NULL; |
|
268 |
- |
|
269 |
- /* |
|
270 |
- * Run NGS on the file |
|
271 |
- */ |
|
272 |
- interp = create_interp(); |
|
273 |
- |
|
274 |
- if(!js_eval_file(interp, filename)) { |
|
275 |
- cli_warnmsg("JS failed: %s\n", js_error_message(interp)); |
|
276 |
- /*rc = CL_EIO;*/ |
|
277 |
- } |
|
278 |
- |
|
279 |
- js_destroy_interp(interp); |
|
280 |
- |
|
281 |
- if(temp_stdout) { |
|
282 |
- fclose(temp_stdout); |
|
283 |
- stdout = real_stdout; |
|
284 |
- } |
|
285 |
-} |
|
286 |
- |
|
287 |
-#include "js/compiler.c" |
|
288 |
-#include "js/iostream.c" |
|
289 |
-#include "js/js.c" |
|
290 |
-#include "js/main.c" |
|
291 |
-#include "js/debug.c" |
|
292 |
-#include "js/crc32.c" |
|
293 |
- |
|
294 |
-/* Copied from pdf.c :-( */ |
|
295 |
-/* |
|
296 |
- * like cli_memstr - but returns the location of the match |
|
297 |
- * FIXME: need a case insensitive version` |
|
298 |
- */ |
|
299 |
-static const char * |
|
300 |
-cli_pmemstr(const char *haystack, size_t hs, const char *needle, size_t ns) |
|
301 |
-{ |
|
302 |
- const char *pt, *hay; |
|
303 |
- size_t n; |
|
304 |
- |
|
305 |
- if(haystack == needle) |
|
306 |
- return haystack; |
|
307 |
- |
|
308 |
- if(hs < ns) |
|
309 |
- return NULL; |
|
310 |
- |
|
311 |
- if(memcmp(haystack, needle, ns) == 0) |
|
312 |
- return haystack; |
|
313 |
- |
|
314 |
- pt = hay = haystack; |
|
315 |
- n = hs; |
|
316 |
- |
|
317 |
- while((pt = memchr(hay, needle[0], n)) != NULL) { |
|
318 |
- n -= (int) pt - (int) hay; |
|
319 |
- if(n < ns) |
|
320 |
- break; |
|
321 |
- |
|
322 |
- if(memcmp(pt, needle, ns) == 0) |
|
323 |
- return pt; |
|
324 |
- |
|
325 |
- if(hay == pt) { |
|
326 |
- n--; |
|
327 |
- hay++; |
|
328 |
- } else |
|
329 |
- hay = pt; |
|
330 |
- } |
|
331 |
- |
|
332 |
- return NULL; |
|
333 |
-} |
|
334 |
- |
|
335 |
-#else |
|
336 |
- |
|
337 |
-int |
|
338 |
-cli_scanjs(const char *dir, int desc) |
|
339 |
-{ |
|
340 |
- cli_warnmsg("File not decoded - JS decoding needs mmap() (for now)\n"); |
|
341 |
- return CL_CLEAN; |
|
342 |
-} |
|
343 |
-#endif /*HAVE_MMAP*/ |
|
344 |
- |
|
345 |
-#else /*!CL_EXPERIMENTAL*/ |
|
346 |
- |
|
347 |
-int |
|
348 |
-cli_scanjs(const char *dir, int desc) |
|
349 |
-{ |
|
350 |
- cli_warnmsg("JS decoding files not yet supported\n"); |
|
351 |
- return CL_EFORMAT; |
|
352 |
-} |
|
353 |
- |
|
354 |
-#endif /*CL_EXPERIMENTAL*/ |
355 | 1 |
deleted file mode 100644 |
... | ... |
@@ -1,24 +0,0 @@ |
1 |
-/* |
|
2 |
- * Copyright (C) 2006 Nigel Horne <njh@clamav.net> |
|
3 |
- * |
|
4 |
- * This program is free software; you can redistribute it and/or modify |
|
5 |
- * it under the terms of the GNU General Public License as published by |
|
6 |
- * the Free Software Foundation; either version 2 of the License, or |
|
7 |
- * (at your option) any later version. |
|
8 |
- * |
|
9 |
- * This program is distributed in the hope that it will be useful, |
|
10 |
- * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 |
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 |
- * GNU General Public License for more details. |
|
13 |
- * |
|
14 |
- * You should have received a copy of the GNU General Public License |
|
15 |
- * along with this program; if not, write to the Free Software |
|
16 |
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, |
|
17 |
- * MA 02110-1301, USA. |
|
18 |
- */ |
|
19 |
- |
|
20 |
-#include "js/js.h" |
|
21 |
- |
|
22 |
-int cli_scanjs(const char *dir, int desc); |
|
23 |
- |
|
24 |
-JSInterpPtr create_interp(void); |
25 | 1 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,354 @@ |
0 |
+/* |
|
1 |
+ * Copyright (C) 2006 Nigel Horne <njh@clamav.net> |
|
2 |
+ * |
|
3 |
+ * This program is free software; you can redistribute it and/or modify |
|
4 |
+ * it under the terms of the GNU General Public License as published by |
|
5 |
+ * the Free Software Foundation; either version 2 of the License, or |
|
6 |
+ * (at your option) any later version. |
|
7 |
+ * |
|
8 |
+ * This program is distributed in the hope that it will be useful, |
|
9 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
10 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
11 |
+ * GNU General Public License for more details. |
|
12 |
+ * |
|
13 |
+ * You should have received a copy of the GNU General Public License |
|
14 |
+ * along with this program; if not, write to the Free Software |
|
15 |
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, |
|
16 |
+ * MA 02110-1301, USA. |
|
17 |
+ * |
|
18 |
+ * Save the JavaScript embedded in an HTML file, then run the script, saving |
|
19 |
+ * the output in a file that is to be scanned, then remove the script file |
|
20 |
+ */ |
|
21 |
+static char const rcsid[] = "$Id: jscript.c,v 1.1 2006/10/27 14:06:06 njh Exp $"; |
|
22 |
+ |
|
23 |
+#if HAVE_CONFIG_H |
|
24 |
+#include "clamav-config.h" |
|
25 |
+#endif |
|
26 |
+ |
|
27 |
+#include "clamav.h" |
|
28 |
+#include "others.h" |
|
29 |
+ |
|
30 |
+#ifdef CL_EXPERIMENTAL |
|
31 |
+ |
|
32 |
+#if HAVE_MMAP |
|
33 |
+ |
|
34 |
+#include <memory.h> |
|
35 |
+#include <string.h> |
|
36 |
+#include <limits.h> |
|
37 |
+#include <errno.h> |
|
38 |
+#include <ctype.h> |
|
39 |
+ |
|
40 |
+#ifdef HAVE_UNISTD_H |
|
41 |
+#include <unistd.h> |
|
42 |
+#endif |
|
43 |
+ |
|
44 |
+#include "js.h" |
|
45 |
+ |
|
46 |
+#if HAVE_SYS_MMAN_H |
|
47 |
+#include <sys/mman.h> |
|
48 |
+#endif |
|
49 |
+ |
|
50 |
+/* Maximum filenames under various systems - njh */ |
|
51 |
+#ifndef NAME_MAX /* e.g. Linux */ |
|
52 |
+# ifdef MAXNAMELEN /* e.g. Solaris */ |
|
53 |
+# define NAME_MAX MAXNAMELEN |
|
54 |
+# else |
|
55 |
+# ifdef FILENAME_MAX /* e.g. SCO */ |
|
56 |
+# define NAME_MAX FILENAME_MAX |
|
57 |
+# else |
|
58 |
+# define NAME_MAX 256 |
|
59 |
+# endif |
|
60 |
+# endif |
|
61 |
+#endif |
|
62 |
+ |
|
63 |
+static void run_js(const char *filename, const char *dir); |
|
64 |
+static const char *cli_pmemstr(const char *haystack, size_t hs, const char *needle, size_t ns); |
|
65 |
+ |
|
66 |
+int |
|
67 |
+cli_scanjs(const char *dir, int desc) |
|
68 |
+{ |
|
69 |
+ struct stat statb; |
|
70 |
+ off_t size; /* total number of bytes in the file */ |
|
71 |
+ char *buf; /* start of memory mapped area */ |
|
72 |
+ const char *p; |
|
73 |
+ long bytesleft; |
|
74 |
+ int created_output, done_header, rc; |
|
75 |
+ FILE *fout; |
|
76 |
+ char script_filename[NAME_MAX + 1]; |
|
77 |
+ extern short cli_leavetemps_flag; |
|
78 |
+ |
|
79 |
+ cli_dbgmsg("in cli_scanjs(%s)\n", dir); |
|
80 |
+ |
|
81 |
+ if(fstat(desc, &statb) < 0) |
|
82 |
+ return CL_EOPEN; |
|
83 |
+ |
|
84 |
+ size = (size_t)statb.st_size; |
|
85 |
+ |
|
86 |
+ if(size == 0) |
|
87 |
+ return CL_CLEAN; |
|
88 |
+ |
|
89 |
+ if(size <= 17) /* doesn't even include <script></script> */ |
|
90 |
+ return CL_EFORMAT; |
|
91 |
+ |
|
92 |
+ p = buf = mmap(NULL, size, PROT_READ, MAP_PRIVATE, desc, 0); |
|
93 |
+ if(buf == MAP_FAILED) |
|
94 |
+ return CL_EMEM; |
|
95 |
+ |
|
96 |
+ cli_dbgmsg("cli_scanjs: scanning %lu bytes\n", size); |
|
97 |
+ |
|
98 |
+ p = buf; |
|
99 |
+ bytesleft = size; |
|
100 |
+ created_output = done_header = 0; |
|
101 |
+ fout = NULL; |
|
102 |
+ |
|
103 |
+ while(p < &buf[size]) { |
|
104 |
+ const char *q = cli_pmemstr(p, bytesleft, "<script", 7); |
|
105 |
+ |
|
106 |
+ if(q == NULL) |
|
107 |
+ /* TODO: full case independant search */ |
|
108 |
+ q = cli_pmemstr(p, bytesleft, "<SCRIPT", 7); |
|
109 |
+ |
|
110 |
+ if(q == NULL) |
|
111 |
+ break; |
|
112 |
+ |
|
113 |
+ /* |
|
114 |
+ * TODO: check language is javascript |
|
115 |
+ * TODO: follow src if mail-follow-urls is set |
|
116 |
+ */ |
|
117 |
+ |
|
118 |
+ bytesleft -= (q - p); |
|
119 |
+ p = q; |
|
120 |
+ |
|
121 |
+ q = cli_pmemstr(p, bytesleft, ">", 1); |
|
122 |
+ if(q == NULL) |
|
123 |
+ break; |
|
124 |
+ |
|
125 |
+ bytesleft -= (q - p); |
|
126 |
+ p = q; |
|
127 |
+ |
|
128 |
+ p++; |
|
129 |
+ bytesleft--; |
|
130 |
+ |
|
131 |
+ while(bytesleft) { |
|
132 |
+ char c; |
|
133 |
+ |
|
134 |
+ if(*p == '<') { |
|
135 |
+ p++; |
|
136 |
+ if(--bytesleft == 0) |
|
137 |
+ break; |
|
138 |
+ if((*p == '!') && !done_header) { |
|
139 |
+ while(bytesleft && (*p != '\n')) { |
|
140 |
+ p++; |
|
141 |
+ bytesleft--; |
|
142 |
+ } |
|
143 |
+ continue; |
|
144 |
+ } |
|
145 |
+ if((bytesleft >= 7) && (strncasecmp(p, "/script", 7) == 0)) { |
|
146 |
+ bytesleft -= 7; |
|
147 |
+ p = &p[7]; |
|
148 |
+ while(bytesleft && (*p != '>')) { |
|
149 |
+ p++; |
|
150 |
+ bytesleft--; |
|
151 |
+ } |
|
152 |
+ if(fout) { |
|
153 |
+ fclose(fout); |
|
154 |
+ fout = NULL; |
|
155 |
+ run_js(script_filename, dir); |
|
156 |
+ |
|
157 |
+ if(!cli_leavetemps_flag) |
|
158 |
+ unlink(script_filename); |
|
159 |
+ } |
|
160 |
+ done_header = 0; |
|
161 |
+ break; |
|
162 |
+ } |
|
163 |
+ c = '<'; |
|
164 |
+ } else { |
|
165 |
+ /*c = tolower(*p);*/ |
|
166 |
+ c = *p; |
|
167 |
+ p++; |
|
168 |
+ bytesleft--; |
|
169 |
+ } |
|
170 |
+ |
|
171 |
+ if(!done_header) { |
|
172 |
+ int fd; |
|
173 |
+ |
|
174 |
+ snprintf(script_filename, sizeof(script_filename), "%s/jsXXXXXX", dir); |
|
175 |
+#if defined(C_LINUX) || defined(C_BSD) || defined(HAVE_MKSTEMP) || defined(C_SOLARIS) || defined(C_CYGWIN) |
|
176 |
+ fd = mkstemp(script_filename); |
|
177 |
+ fout = fdopen(fd, "wb"); |
|
178 |
+ if(fout == NULL) |
|
179 |
+ close(fd); |
|
180 |
+#elif defined(C_WINDOWS) |
|
181 |
+ if(_mktemp(script_filename) == NULL) { |
|
182 |
+ /* mktemp only allows 26 files */ |
|
183 |
+ char *name = cli_gentemp(dir); |
|
184 |
+ if(name == NULL) |
|
185 |
+ fout = NULL; |
|
186 |
+ else { |
|
187 |
+ strcpy(script_filename, name); |
|
188 |
+ free(name); |
|
189 |
+ fout = fopen(script_filename, "wb"); |
|
190 |
+ } |
|
191 |
+ } else |
|
192 |
+ fout = fopen(script_filename, "wb"); |
|
193 |
+#else |
|
194 |
+ mktemp(script_filename); |
|
195 |
+ fout = fopen(script_filename, "wb"); |
|
196 |
+#endif |
|
197 |
+ |
|
198 |
+ if(fout == NULL) { |
|
199 |
+ cli_errmsg("cli_scanjs: can't create temporary file %s: %s\n", script_filename, strerror(errno)); |
|
200 |
+ munmap(buf, size); |
|
201 |
+ return CL_ETMPFILE; |
|
202 |
+ } |
|
203 |
+ cli_dbgmsg("Saving javascript to %s\n", |
|
204 |
+ script_filename); |
|
205 |
+ |
|
206 |
+ /* |
|
207 |
+ * Create a document object, on web pages it's |
|
208 |
+ * used to send output to the browser |
|
209 |
+ * FIXME: will create a file even if the script |
|
210 |
+ * is empty, e.g. src is somewhere else |
|
211 |
+ */ |
|
212 |
+ fputs("function createDoc() {\n", fout); |
|
213 |
+ fputs("\tfunction write(text) {\n", fout); |
|
214 |
+ /* |
|
215 |
+ * Use System.print rather than print so that |
|
216 |
+ * a new line is not appended |
|
217 |
+ */ |
|
218 |
+ fputs("\t\tSystem.print(text);\n", fout); |
|
219 |
+ fputs("\t}\n", fout); |
|
220 |
+ fputs("}\n", fout); |
|
221 |
+ fputs("document = new createDoc();\n", fout); |
|
222 |
+ |
|
223 |
+ done_header = 1; |
|
224 |
+ created_output = 1; |
|
225 |
+ } |
|
226 |
+ putc(c, fout); |
|
227 |
+ } |
|
228 |
+ } |
|
229 |
+ |
|
230 |
+ munmap(buf, size); |
|
231 |
+ |
|
232 |
+ rc = CL_SUCCESS; |
|
233 |
+ |
|
234 |
+ if(!created_output) |
|
235 |
+ cli_dbgmsg("No javascript was detected\n"); |
|
236 |
+ else if(fout) { |
|
237 |
+ fclose(fout); |
|
238 |
+ run_js(script_filename, dir); |
|
239 |
+ |
|
240 |
+ if(!cli_leavetemps_flag) |
|
241 |
+ unlink(script_filename); |
|
242 |
+ } |
|
243 |
+ return rc; |
|
244 |
+} |
|
245 |
+ |
|
246 |
+static void |
|
247 |
+run_js(const char *filename, const char *dir) |
|
248 |
+{ |
|
249 |
+ JSInterpPtr interp; |
|
250 |
+ FILE *real_stdout, *temp_stdout; |
|
251 |
+ char *outputfilename; |
|
252 |
+ |
|
253 |
+ cli_dbgmsg("run_js(%s)\n", filename); |
|
254 |
+ |
|
255 |
+ fflush(stdout); |
|
256 |
+ real_stdout = stdout; |
|
257 |
+ outputfilename = cli_gentemp(dir); |
|
258 |
+ if(outputfilename) { |
|
259 |
+ temp_stdout = fopen(outputfilename, "wb"); |
|
260 |
+ if(temp_stdout) { |
|
261 |
+ cli_dbgmsg("Redirecting JS VM stdout to %s\n", |
|
262 |
+ outputfilename); |
|
263 |
+ stdout = temp_stdout; |
|
264 |
+ } |
|
265 |
+ } else |
|
266 |
+ temp_stdout = NULL; |
|
267 |
+ |
|
268 |
+ /* |
|
269 |
+ * Run NGS on the file |
|
270 |
+ */ |
|
271 |
+ interp = create_interp(); |
|
272 |
+ |
|
273 |
+ if(!js_eval_file(interp, filename)) { |
|
274 |
+ cli_warnmsg("JS failed: %s\n", js_error_message(interp)); |
|
275 |
+ /*rc = CL_EIO;*/ |
|
276 |
+ } |
|
277 |
+ |
|
278 |
+ js_destroy_interp(interp); |
|
279 |
+ |
|
280 |
+ if(temp_stdout) { |
|
281 |
+ fclose(temp_stdout); |
|
282 |
+ stdout = real_stdout; |
|
283 |
+ } |
|
284 |
+} |
|
285 |
+ |
|
286 |
+#include "js/compiler.c" |
|
287 |
+#include "js/iostream.c" |
|
288 |
+#include "js/js.c" |
|
289 |
+#include "js/main.c" |
|
290 |
+#include "js/debug.c" |
|
291 |
+#include "js/crc32.c" |
|
292 |
+ |
|
293 |
+/* Copied from pdf.c :-( */ |
|
294 |
+/* |
|
295 |
+ * like cli_memstr - but returns the location of the match |
|
296 |
+ * FIXME: need a case insensitive version` |
|
297 |
+ */ |
|
298 |
+static const char * |
|
299 |
+cli_pmemstr(const char *haystack, size_t hs, const char *needle, size_t ns) |
|
300 |
+{ |
|
301 |
+ const char *pt, *hay; |
|
302 |
+ size_t n; |
|
303 |
+ |
|
304 |
+ if(haystack == needle) |
|
305 |
+ return haystack; |
|
306 |
+ |
|
307 |
+ if(hs < ns) |
|
308 |
+ return NULL; |
|
309 |
+ |
|
310 |
+ if(memcmp(haystack, needle, ns) == 0) |
|
311 |
+ return haystack; |
|
312 |
+ |
|
313 |
+ pt = hay = haystack; |
|
314 |
+ n = hs; |
|
315 |
+ |
|
316 |
+ while((pt = memchr(hay, needle[0], n)) != NULL) { |
|
317 |
+ n -= (int) pt - (int) hay; |
|
318 |
+ if(n < ns) |
|
319 |
+ break; |
|
320 |
+ |
|
321 |
+ if(memcmp(pt, needle, ns) == 0) |
|
322 |
+ return pt; |
|
323 |
+ |
|
324 |
+ if(hay == pt) { |
|
325 |
+ n--; |
|
326 |
+ hay++; |
|
327 |
+ } else |
|
328 |
+ hay = pt; |
|
329 |
+ } |
|
330 |
+ |
|
331 |
+ return NULL; |
|
332 |
+} |
|
333 |
+ |
|
334 |
+#else |
|
335 |
+ |
|
336 |
+int |
|
337 |
+cli_scanjs(const char *dir, int desc) |
|
338 |
+{ |
|
339 |
+ cli_warnmsg("File not decoded - JS decoding needs mmap() (for now)\n"); |
|
340 |
+ return CL_CLEAN; |
|
341 |
+} |
|
342 |
+#endif /*HAVE_MMAP*/ |
|
343 |
+ |
|
344 |
+#else /*!CL_EXPERIMENTAL*/ |
|
345 |
+ |
|
346 |
+int |
|
347 |
+cli_scanjs(const char *dir, int desc) |
|
348 |
+{ |
|
349 |
+ cli_warnmsg("JS decoding files not yet supported\n"); |
|
350 |
+ return CL_EFORMAT; |
|
351 |
+} |
|
352 |
+ |
|
353 |
+#endif /*CL_EXPERIMENTAL*/ |
0 | 354 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,24 @@ |
0 |
+/* |
|
1 |
+ * Copyright (C) 2006 Nigel Horne <njh@clamav.net> |
|
2 |
+ * |
|
3 |
+ * This program is free software; you can redistribute it and/or modify |
|
4 |
+ * it under the terms of the GNU General Public License as published by |
|
5 |
+ * the Free Software Foundation; either version 2 of the License, or |
|
6 |
+ * (at your option) any later version. |
|
7 |
+ * |
|
8 |
+ * This program is distributed in the hope that it will be useful, |
|
9 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
10 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
11 |
+ * GNU General Public License for more details. |
|
12 |
+ * |
|
13 |
+ * You should have received a copy of the GNU General Public License |
|
14 |
+ * along with this program; if not, write to the Free Software |
|
15 |
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, |
|
16 |
+ * MA 02110-1301, USA. |
|
17 |
+ */ |
|
18 |
+ |
|
19 |
+#include "js/js.h" |
|
20 |
+ |
|
21 |
+int cli_scanjs(const char *dir, int desc); |
|
22 |
+ |
|
23 |
+JSInterpPtr create_interp(void); |