Browse code

First working version

git-svn-id: file:///var/lib/svn/clamav-devel/trunk/clamav-devel@2416 77e5149b-7576-45b1-b177-96237e5ba77b

Nigel Horne authored on 2006/10/20 02:29:47
Showing 19 changed files
... ...
@@ -19,7 +19,7 @@
19 19
  * Save the JavaScript embedded in an HTML file, then run the script, saving
20 20
  * the output in a file that is to be scanned, then remove the script file
21 21
  */
22
-static	char	const	rcsid[] = "$Id: js.c,v 1.9 2006/10/09 15:51:33 njh Exp $";
22
+static	char	const	rcsid[] = "$Id: js.c,v 1.10 2006/10/19 17:29:47 njh Exp $";
23 23
 
24 24
 #if HAVE_CONFIG_H
25 25
 #include "clamav-config.h"
... ...
@@ -60,6 +60,7 @@ static	char	const	rcsid[] = "$Id: js.c,v 1.9 2006/10/09 15:51:33 njh Exp $";
60 60
 # endif
61 61
 #endif
62 62
 
63
+static	void	run_js(const char *filename, const char *dir);
63 64
 static	const	char	*cli_pmemstr(const char *haystack, size_t hs, const char *needle, size_t ns);
64 65
 
65 66
 int
... ...
@@ -70,9 +71,10 @@ cli_scanjs(const char *dir, int desc)
70 70
 	char *buf;	/* start of memory mapped area */
71 71
 	const char *p;
72 72
 	long bytesleft;
73
-	int done_header, rc;
73
+	int created_output, done_header, rc;
74 74
 	FILE *fout;
75 75
 	char script_filename[NAME_MAX + 1];
76
+	extern short cli_leavetemps_flag;
76 77
 
77 78
 	cli_dbgmsg("in cli_scanjs(%s)\n", dir);
78 79
 
... ...
@@ -95,7 +97,7 @@ cli_scanjs(const char *dir, int desc)
95 95
 
96 96
 	p = buf;
97 97
 	bytesleft = size;
98
-	done_header = 0;
98
+	created_output = done_header = 0;
99 99
 	fout = NULL;
100 100
 
101 101
 	while(p < &buf[size]) {
... ...
@@ -133,7 +135,7 @@ cli_scanjs(const char *dir, int desc)
133 133
 				p++;
134 134
 				if(--bytesleft == 0)
135 135
 					break;
136
-				if(*p == '!') {
136
+				if((*p == '!') && !done_header) {
137 137
 					while(bytesleft && (*p != '\n')) {
138 138
 						p++;
139 139
 						bytesleft--;
... ...
@@ -147,11 +149,21 @@ cli_scanjs(const char *dir, int desc)
147 147
 						p++;
148 148
 						bytesleft--;
149 149
 					}
150
+					if(fout) {
151
+						fclose(fout);
152
+						fout = NULL;
153
+						run_js(script_filename, dir);
154
+
155
+						if(!cli_leavetemps_flag)
156
+							unlink(script_filename);
157
+					}
158
+					done_header = 0;
150 159
 					break;
151 160
 				}
152 161
 				c = '<';
153 162
 			} else {
154
-				c = tolower(*p);
163
+				/*c = tolower(*p);*/
164
+				c = *p;
155 165
 				p++;
156 166
 				bytesleft--;
157 167
 			}
... ...
@@ -194,15 +206,22 @@ cli_scanjs(const char *dir, int desc)
194 194
 				/*
195 195
 				 * Create a document object, on web pages it's
196 196
 				 *	used to send output to the browser
197
+				 * FIXME: will create a file even if the script
198
+				 *	is empty, e.g. src is somewhere else
197 199
 				 */
198 200
 				fputs("function createDoc() {\n", fout);
199 201
 				fputs("\tfunction write(text) {\n", fout);
200
-				fputs("\t\tprint(text);\n", fout);
202
+				/*
203
+				 * Use System.print rather than print so that
204
+				 *	a new line is not appended
205
+				 */
206
+				fputs("\t\tSystem.print(text);\n", fout);
201 207
 				fputs("\t}\n", fout);
202 208
 				fputs("}\n", fout);
203 209
 				fputs("document = new createDoc();\n", fout);
204 210
 
205 211
 				done_header = 1;
212
+				created_output = 1;
206 213
 			}
207 214
 			putc(c, fout);
208 215
 		}
... ...
@@ -212,35 +231,63 @@ cli_scanjs(const char *dir, int desc)
212 212
 
213 213
 	rc = CL_SUCCESS;
214 214
 
215
-	if(!done_header)
215
+	if(!created_output)
216 216
 		cli_dbgmsg("No javascript was detected\n");
217
-	else if(fout == NULL)
218
-		cli_errmsg("cli_scanjs: fout == NULL\n");
219
-	else {
220
-		extern short cli_leavetemps_flag;
221
-		JSInterpPtr interp;
222
-
217
+	else if(fout) {
223 218
 		fclose(fout);
219
+		run_js(script_filename, dir);
224 220
 
225
-#if	0
226
-		/*
227
-		 * Run NGS on the file
228
-		 */
229
-		interp = create_interp();
221
+		if(!cli_leavetemps_flag)
222
+			unlink(script_filename);
223
+	}
224
+	return rc;
225
+}
230 226
 
231
-		if(!js_eval_file(interp, script_filename)) {
232
-			cli_warnmsg("JS failed: %s\n", js_error_message(interp));
233
-			rc = CL_EIO;
227
+static void
228
+run_js(const char *filename, const char *dir)
229
+{
230
+	JSInterpPtr interp;
231
+	FILE *real_stdout, *temp_stdout;
232
+	char *outputfilename;
233
+
234
+	cli_dbgmsg("run_js(%s)\n", filename);
235
+
236
+	fflush(stdout);
237
+	real_stdout = stdout;
238
+	outputfilename = cli_gentemp(dir);
239
+	if(outputfilename) {
240
+		temp_stdout = fopen(outputfilename, "wb");
241
+		if(temp_stdout) {
242
+			cli_dbgmsg("Redirecting JS VM stdout to %s\n",
243
+				outputfilename);
244
+			stdout = temp_stdout;
234 245
 		}
235
-		js_destroy_interp(interp);
236
-#endif
246
+	} else
247
+		temp_stdout = NULL;
237 248
 
238
-		if(!cli_leavetemps_flag)
239
-			unlink(script_filename);
249
+	/*
250
+	 * Run NGS on the file
251
+	 */
252
+	interp = create_interp();
253
+
254
+	if(!js_eval_file(interp, filename)) {
255
+		cli_warnmsg("JS failed: %s\n", js_error_message(interp));
256
+		/*rc = CL_EIO;*/
257
+	}
258
+
259
+	js_destroy_interp(interp);
260
+
261
+	if(temp_stdout) {
262
+		fclose(temp_stdout);
263
+		stdout = real_stdout;
240 264
 	}
241
-	return CL_CLEAN;
242 265
 }
243 266
 
267
+#include "js/compiler.c"
268
+#include "js/iostream.c"
269
+#include "js/js.c"
270
+#include "js/main.c"
271
+
244 272
 /* Copied from pdf.c :-( */
245 273
 /*
246 274
  * like cli_memstr - but returns the location of the match
... ...
@@ -281,7 +328,7 @@ cli_pmemstr(const char *haystack, size_t hs, const char *needle, size_t ns)
281 281
 
282 282
 	return NULL;
283 283
 }
284
- 
284
+
285 285
 #else
286 286
 
287 287
 int
... ...
@@ -292,4 +339,13 @@ cli_scanjs(const char *dir, int desc)
292 292
 }
293 293
 #endif	/*HAVE_MMAP*/
294 294
 
295
+#else	/*!CL_EXPERIMENTAL*/
296
+
297
+int
298
+cli_scanjs(const char *dir, int desc)
299
+{
300
+	cli_warnmsg("JS decoding files not yet supported\n");
301
+	return CL_EFORMAT;
302
+}
303
+
295 304
 #endif	/*CL_EXPERIMENTAL*/
296 305
new file mode 100644
... ...
@@ -0,0 +1,650 @@
0
+/*
1
+ * The builtin Array object.
2
+ * Copyright (c) 1998 New Generation Software (NGS) Oy
3
+ *
4
+ * Author: Markku Rossi <mtr@ngs.fi>
5
+ */
6
+
7
+/*
8
+ * This library is free software; you can redistribute it and/or
9
+ * modify it under the terms of the GNU Library General Public
10
+ * License as published by the Free Software Foundation; either
11
+ * version 2 of the License, or (at your option) any later version.
12
+ *
13
+ * This library is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
+ * Library General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU Library General Public
19
+ * License along with this library; if not, write to the Free
20
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
21
+ * MA 02111-1307, USA
22
+ */
23
+
24
+/*
25
+ * $Source: /tmp/cvsroot-15-2-2007/clamav-devel/libclamav/js/b_array.c,v $
26
+ * $Id: b_array.c,v 1.1 2006/10/19 17:28:58 njh Exp $
27
+ */
28
+
29
+/*
30
+ * Mehtods:
31
+ *
32
+ *   concat (array) => array
33
+ *   join ([glue]) => string
34
+ *   pop () => last_element
35
+ *   push (any...) => last_element_added
36
+ *   reverse ()
37
+ *   shift () => first_element
38
+ *   slice (start, end) => array
39
+ *   splice (index, how_many[, any...]) => array
40
+ *   sort ([sort_function])
41
+ *   toString () => string
42
+ *   unshift (any...) => length_of_the_array
43
+ *
44
+ * Properties:
45
+ *
46
+ *   length
47
+ */
48
+
49
+#include "jsint.h"
50
+#include "mrgsort.h"
51
+
52
+/*
53
+ * Types and definitions.
54
+ */
55
+
56
+/* Class context. */
57
+struct array_ctx_st
58
+{
59
+  JSSymbol s_concat;
60
+  JSSymbol s_join;
61
+  JSSymbol s_pop;
62
+  JSSymbol s_push;
63
+  JSSymbol s_reverse;
64
+  JSSymbol s_shift;
65
+  JSSymbol s_slice;
66
+  JSSymbol s_splice;
67
+  JSSymbol s_sort;
68
+  JSSymbol s_unshift;
69
+
70
+  JSSymbol s_length;
71
+};
72
+
73
+typedef struct array_ctx_st ArrayCtx;
74
+
75
+/* Context for array sorts with JavaScript functions. */
76
+struct array_sort_ctx_st
77
+{
78
+  JSVirtualMachine *vm;
79
+  JSNode *func;
80
+  JSNode argv[3];
81
+};
82
+
83
+typedef struct array_sort_ctx_st ArraySortCtx;
84
+
85
+/*
86
+ * Prototypes for static functions.
87
+ */
88
+
89
+static void new_proc (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info,
90
+		      JSNode *args, JSNode *result_return);
91
+
92
+
93
+/*
94
+ * Static functions.
95
+ */
96
+
97
+static int
98
+sort_default_cmp_func (const void *aptr, const void *bptr, void *context)
99
+{
100
+  JSVirtualMachine *vm = context;
101
+  const JSNode *a = aptr;
102
+  const JSNode *b = bptr;
103
+  JSNode astr, bstr;
104
+
105
+  if (a->type == JS_UNDEFINED)
106
+    return 1;
107
+  if (b->type == JS_UNDEFINED)
108
+    return -1;
109
+
110
+  js_vm_to_string (vm, a, &astr);
111
+  js_vm_to_string (vm, b, &bstr);
112
+
113
+  return js_compare_strings (&astr, &bstr);
114
+}
115
+
116
+
117
+static int
118
+sort_js_cmp_func (const void *aptr, const void *bptr, void *context)
119
+{
120
+  ArraySortCtx *ctx = context;
121
+  const JSNode *a = aptr;
122
+  const JSNode *b = bptr;
123
+
124
+  /*
125
+   * Finalize the argument array.  The argumnet count has already been set.
126
+   * when the context were initialized.
127
+   */
128
+  JS_COPY (&ctx->argv[1], a);
129
+  JS_COPY (&ctx->argv[2], b);
130
+
131
+  /* Call the function. */
132
+  if (!js_vm_apply (ctx->vm, NULL, ctx->func, 3, ctx->argv))
133
+    /* Raise an error. */
134
+    js_vm_error (ctx->vm);
135
+
136
+  /* Fetch the return value. */
137
+  if (ctx->vm->exec_result.type != JS_INTEGER)
138
+    {
139
+      sprintf (ctx->vm->error,
140
+	       "Array.sort(): comparison function didn't return integer");
141
+      js_vm_error (ctx->vm);
142
+    }
143
+
144
+  return ctx->vm->exec_result.u.vinteger;
145
+}
146
+
147
+
148
+/* Global method proc. */
149
+static void
150
+global_method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info,
151
+	       void *instance_context, JSNode *result_return,
152
+	       JSNode *args)
153
+{
154
+  /* This does exactly the same as the new_proc. */
155
+  new_proc (vm, builtin_info, args, result_return);
156
+}
157
+
158
+
159
+/* Method proc. */
160
+static int
161
+method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info,
162
+	void *instance_context, JSSymbol method, JSNode *result_return,
163
+	JSNode *args)
164
+{
165
+  ArrayCtx *ctx = builtin_info->obj_context;
166
+  JSNode *n = instance_context;
167
+  int i;
168
+
169
+  /* XXX 15.7.4.3 toSource(). */
170
+
171
+  /* Handle static methods here. */
172
+  if (instance_context == NULL)
173
+    {
174
+      if (method == vm->syms.s_toString)
175
+	js_vm_make_static_string (vm, result_return, "Array", 5);
176
+      /* ************************************************************ */
177
+      else
178
+	return JS_PROPERTY_UNKNOWN;
179
+
180
+      return JS_PROPERTY_FOUND;
181
+    }
182
+
183
+  /* Handle the instance methods. */
184
+
185
+  /* Set the default result type. */
186
+  result_return->type = JS_UNDEFINED;
187
+
188
+  if (method == ctx->s_concat)
189
+    {
190
+      int nlen;
191
+      int pos;
192
+
193
+      /* Count the new len; */
194
+
195
+      nlen = n->u.varray->length;
196
+      for (i = 0; i < args->u.vinteger; i++)
197
+	{
198
+	  if (args[i + 1].type != JS_ARRAY)
199
+	    goto argument_error;
200
+
201
+	  nlen += args[i + 1].u.varray->length;
202
+	}
203
+
204
+      js_vm_make_array (vm, result_return, nlen);
205
+
206
+      /* Insert the items. */
207
+      memcpy (result_return->u.varray->data, n->u.varray->data,
208
+	      n->u.varray->length * sizeof (JSNode));
209
+      pos = n->u.varray->length;
210
+
211
+      for (i = 0; i < args->u.vinteger; i++)
212
+	{
213
+	  memcpy (&result_return->u.varray->data[pos],
214
+		  args[i + 1].u.varray->data,
215
+		  args[i + 1].u.varray->length * sizeof (JSNode));
216
+	  pos += args[i + 1].u.varray->length;
217
+	}
218
+    }
219
+  /* ********************************************************************** */
220
+  else if (method == ctx->s_join || method == vm->syms.s_toString)
221
+    {
222
+      char *glue = NULL;
223
+
224
+      if (method == vm->syms.s_toString)
225
+	{
226
+	  if (args->u.vinteger != 0)
227
+	    goto argument_error;
228
+	}
229
+      else
230
+	{
231
+	  if (args->u.vinteger == 0)
232
+	    ;
233
+	  else if (args->u.vinteger == 1)
234
+	    {
235
+	      JSNode glue_result;
236
+
237
+	      js_vm_to_string (vm, &args[1], &glue_result);
238
+	      glue = js_string_to_c_string (vm, &glue_result);
239
+	    }
240
+	  else
241
+	    goto argument_error;
242
+	}
243
+
244
+      /* Ok, ready to run. */
245
+      if (n->u.varray->length == 0)
246
+	js_vm_make_static_string (vm, result_return, "", 0);
247
+      else
248
+	{
249
+	  int len;
250
+	  int glue_len = glue ? strlen (glue) : 1;
251
+
252
+	  /* Estimate the result length. */
253
+	  len = (n->u.varray->length * 5
254
+		 + (n->u.varray->length - 1) * glue_len);
255
+
256
+	  js_vm_make_string (vm, result_return, NULL, len);
257
+	  result_return->u.vstring->len = 0;
258
+
259
+	  /* Do the join. */
260
+	  for (i = 0; i < n->u.varray->length; i++)
261
+	    {
262
+	      JSNode sitem;
263
+	      int delta;
264
+
265
+	      js_vm_to_string (vm, &n->u.varray->data[i], &sitem);
266
+	      delta = sitem.u.vstring->len;
267
+
268
+	      if (i + 1 < n->u.varray->length)
269
+		delta += glue_len;
270
+
271
+	      result_return->u.vstring->data
272
+		= js_vm_realloc (vm, result_return->u.vstring->data,
273
+				 result_return->u.vstring->len + delta);
274
+
275
+	      memcpy (result_return->u.vstring->data
276
+		      + result_return->u.vstring->len,
277
+		      sitem.u.vstring->data,
278
+		      sitem.u.vstring->len);
279
+	      result_return->u.vstring->len += sitem.u.vstring->len;
280
+
281
+	      if (i + 1 < n->u.varray->length)
282
+		{
283
+		  if (glue)
284
+		    {
285
+		      memcpy (result_return->u.vstring->data
286
+			      + result_return->u.vstring->len,
287
+			      glue, glue_len);
288
+		      result_return->u.vstring->len += glue_len;
289
+		    }
290
+		  else
291
+		    result_return->u.vstring->data
292
+		      [result_return->u.vstring->len++] = ',';
293
+		}
294
+	    }
295
+	}
296
+
297
+      if (glue)
298
+	js_free (glue);
299
+    }
300
+  /* ********************************************************************** */
301
+  else if (method == ctx->s_pop)
302
+    {
303
+      if (args->u.vinteger != 0)
304
+	goto argument_error;
305
+
306
+      if (n->u.varray->length == 0)
307
+	result_return->type = JS_UNDEFINED;
308
+      else
309
+	{
310
+	  JS_COPY (result_return, &n->u.varray->data[n->u.varray->length - 1]);
311
+	  n->u.varray->length--;
312
+	}
313
+    }
314
+  /* ********************************************************************** */
315
+  else if (method == ctx->s_push)
316
+    {
317
+      int old_len;
318
+
319
+      if (args->u.vinteger == 0)
320
+	goto argument_error;
321
+
322
+      old_len = n->u.varray->length;
323
+      js_vm_expand_array (vm, n, n->u.varray->length + args->u.vinteger);
324
+
325
+      for (i = 0; i < args->u.vinteger; i++)
326
+	JS_COPY (&n->u.varray->data[old_len + i], &args[i + 1]);
327
+
328
+      JS_COPY (result_return, &args[i]);
329
+    }
330
+  /* ********************************************************************** */
331
+  else if (method == ctx->s_reverse)
332
+    {
333
+      if (args->u.vinteger != 0)
334
+	goto argument_error;
335
+
336
+      for (i = 0; i < n->u.varray->length / 2; i++)
337
+	{
338
+	  JSNode tmp;
339
+
340
+	  JS_COPY (&tmp, &n->u.varray->data[i]);
341
+	  JS_COPY (&n->u.varray->data[i],
342
+		   &n->u.varray->data[n->u.varray->length - i - 1]);
343
+	  JS_COPY (&n->u.varray->data[n->u.varray->length - i - 1], &tmp);
344
+	}
345
+    }
346
+  /* ********************************************************************** */
347
+  else if (method == ctx->s_shift)
348
+    {
349
+      if (args->u.vinteger != 0)
350
+	goto argument_error;
351
+
352
+      if (n->u.varray->length == 0)
353
+	result_return->type = JS_UNDEFINED;
354
+      else
355
+	{
356
+	  JS_COPY (result_return, &n->u.varray->data[0]);
357
+	  memmove (&n->u.varray->data[0], &n->u.varray->data[1],
358
+		   (n->u.varray->length - 1) * sizeof (JSNode));
359
+	  n->u.varray->length--;
360
+	}
361
+    }
362
+  /* ********************************************************************** */
363
+  else if (method == ctx->s_slice)
364
+    {
365
+      int start, end;
366
+
367
+      if (args->u.vinteger < 1 || args->u.vinteger > 2)
368
+	goto argument_error;
369
+
370
+      if (args[1].type != JS_INTEGER)
371
+	goto argument_type_error;
372
+
373
+      start = args[1].u.vinteger;
374
+
375
+      if (args->u.vinteger == 2)
376
+	{
377
+	  if (args[2].type != JS_INTEGER)
378
+	    goto argument_type_error;
379
+
380
+	  end = args[2].u.vinteger;
381
+	}
382
+      else
383
+	end = n->u.varray->length;
384
+
385
+      if (end < 0)
386
+	end += n->u.varray->length;
387
+      if (end < 0)
388
+	end = start;
389
+
390
+      js_vm_make_array (vm, result_return, end - start);
391
+
392
+      /* Copy items. */
393
+      for (i = 0; i < end - start; i++)
394
+	JS_COPY (&result_return->u.varray->data[i],
395
+		 &n->u.varray->data[start + i]);
396
+    }
397
+  /* ********************************************************************** */
398
+  else if (method == ctx->s_splice)
399
+    {
400
+      unsigned int new_length;
401
+      unsigned int old_length;
402
+      int delta;
403
+
404
+      if (args->u.vinteger < 2)
405
+	goto argument_error;
406
+      if (args[1].type != JS_INTEGER || args[2].type != JS_INTEGER)
407
+	goto argument_type_error;
408
+
409
+      if (args[2].u.vinteger == 0 && args->u.vinteger == 2)
410
+	/* No deletions: must specify at least one item to insert. */
411
+	goto argument_error;
412
+
413
+      old_length = new_length = n->u.varray->length;
414
+      if (args[1].u.vinteger < new_length)
415
+	{
416
+	  if (args[2].u.vinteger > new_length - args[1].u.vinteger)
417
+	    {
418
+	      args[2].u.vinteger = new_length - args[1].u.vinteger;
419
+	      new_length = args[1].u.vinteger;
420
+	    }
421
+	  else
422
+	    new_length -= args[2].u.vinteger;
423
+	}
424
+      else
425
+	{
426
+	  new_length = args[1].u.vinteger;
427
+	  args[2].u.vinteger = 0;
428
+	}
429
+
430
+      new_length += args->u.vinteger - 2;
431
+
432
+      if (new_length > n->u.varray->length)
433
+	js_vm_expand_array (vm, n, new_length);
434
+      else
435
+	/* Cut the array. */
436
+	n->u.varray->length = new_length;
437
+
438
+      /* Do the stuffs we must do. */
439
+
440
+      /* Create the result array. */
441
+      if (args[2].u.vinteger == 0)
442
+	result_return->type = JS_UNDEFINED;
443
+      else
444
+	{
445
+	  js_vm_make_array (vm, result_return, args[2].u.vinteger);
446
+	  for (i = 0; i < args[2].u.vinteger; i++)
447
+	    JS_COPY (&result_return->u.varray->data[i],
448
+		     &n->u.varray->data[args[1].u.vinteger + i]);
449
+	}
450
+
451
+      /* Delete and move. */
452
+      delta = args->u.vinteger - 2 - args[2].u.vinteger;
453
+      memmove (&n->u.varray->data[args[1].u.vinteger + args[2].u.vinteger
454
+				 + delta],
455
+	       &n->u.varray->data[args[1].u.vinteger + args[2].u.vinteger],
456
+	       (old_length - (args[1].u.vinteger + args[2].u.vinteger))
457
+	       * sizeof (JSNode));
458
+
459
+      /* Insert. */
460
+      for (i = 0; i < args->u.vinteger - 2; i++)
461
+	JS_COPY (&n->u.varray->data[args[1].u.vinteger + i], &args[i + 3]);
462
+    }
463
+  /* ********************************************************************** */
464
+  else if (method == ctx->s_sort)
465
+    {
466
+      MergesortCompFunc func;
467
+      ArraySortCtx array_sort_ctx;
468
+      void *func_ctx = NULL;	/* Initialized to keep compiler quiet. */
469
+
470
+      if (args->u.vinteger == 0)
471
+	{
472
+	  func = sort_default_cmp_func;
473
+	  func_ctx = vm;
474
+	}
475
+      else if (args->u.vinteger == 1)
476
+	{
477
+	  if (args[1].type != JS_FUNC && args[1].type != JS_BUILTIN)
478
+	    goto argument_type_error;
479
+
480
+	  func = sort_js_cmp_func;
481
+
482
+	  /* Init context. */
483
+	  array_sort_ctx.vm = vm;
484
+	  array_sort_ctx.func = &args[1];
485
+
486
+	  /* Init the argc part of the argument vector here. */
487
+	  array_sort_ctx.argv[0].type = JS_INTEGER;
488
+	  array_sort_ctx.argv[0].u.vinteger = 3;
489
+
490
+	  func_ctx = &array_sort_ctx;
491
+	}
492
+      else
493
+	goto argument_error;
494
+
495
+      mergesort_r (n->u.varray->data, n->u.varray->length, sizeof (JSNode),
496
+		   func, func_ctx);
497
+    }
498
+  /* ********************************************************************** */
499
+  else if (method == ctx->s_unshift)
500
+    {
501
+      int old_len;
502
+
503
+      if (args->u.vinteger == 0)
504
+	goto argument_error;
505
+
506
+      old_len = n->u.varray->length;
507
+      js_vm_expand_array (vm, n, n->u.varray->length + args->u.vinteger);
508
+
509
+      memmove (&n->u.varray->data[args->u.vinteger], n->u.varray->data,
510
+	       old_len * sizeof (JSNode));
511
+
512
+      for (i = 0; i < args->u.vinteger; i++)
513
+	JS_COPY (&n->u.varray->data[i], &args[args->u.vinteger - i]);
514
+
515
+      result_return->type = JS_INTEGER;
516
+      result_return->u.vinteger = n->u.varray->length;
517
+    }
518
+  /* ********************************************************************** */
519
+  else
520
+    return JS_PROPERTY_UNKNOWN;
521
+
522
+  return JS_PROPERTY_FOUND;
523
+
524
+
525
+  /*
526
+   * Error handling.
527
+   */
528
+
529
+ argument_error:
530
+  sprintf (vm->error, "Array.%s(): illegal amount of arguments",
531
+	   js_vm_symname (vm, method));
532
+  js_vm_error (vm);
533
+
534
+ argument_type_error:
535
+  sprintf (vm->error, "Array.%s(): illegal argument",
536
+	   js_vm_symname (vm, method));
537
+  js_vm_error (vm);
538
+
539
+  /* NOTREACHED */
540
+  return 0;
541
+}
542
+
543
+/* Property proc. */
544
+static int
545
+property (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info,
546
+	  void *instance_context, JSSymbol property, int set, JSNode *node)
547
+{
548
+  ArrayCtx *ctx = builtin_info->obj_context;
549
+  JSNode *n = instance_context;
550
+
551
+  if (property == ctx->s_length)
552
+    {
553
+      if (set)
554
+	goto immutable;
555
+
556
+      node->type = JS_INTEGER;
557
+      node->u.vinteger = n->u.varray->length;
558
+    }
559
+  else
560
+    {
561
+      if (!set)
562
+	node->type = JS_UNDEFINED;
563
+
564
+      return JS_PROPERTY_UNKNOWN;
565
+    }
566
+
567
+  return JS_PROPERTY_FOUND;
568
+
569
+
570
+  /*
571
+   * Error handling.
572
+   */
573
+
574
+ immutable:
575
+  sprintf (vm->error, "Array.%s: immutable property",
576
+	   js_vm_symname (vm, property));
577
+  js_vm_error (vm);
578
+
579
+  /* NOTREACHED */
580
+  return 0;
581
+}
582
+
583
+/* New proc. */
584
+static void
585
+new_proc (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, JSNode *args,
586
+	  JSNode *result_return)
587
+{
588
+  int i;
589
+
590
+  if (args->u.vinteger == 1 && args[1].type == JS_INTEGER)
591
+    {
592
+      /* Create a fixed length array. */
593
+      js_vm_make_array (vm, result_return, args[1].u.vinteger);
594
+    }
595
+  else
596
+    {
597
+      if (args->u.vinteger < 0)
598
+	/* We are called from the array initializer. */
599
+	args->u.vinteger = -args->u.vinteger;
600
+
601
+      js_vm_make_array (vm, result_return, args->u.vinteger);
602
+      for (i = 0; i < args->u.vinteger; i++)
603
+	JS_COPY (&result_return->u.varray->data[i], &args[i + 1]);
604
+    }
605
+  /* Set the [[Prototype]] and [[Class]] properties. */
606
+  /* XXX 15.7.2.1 */
607
+}
608
+
609
+
610
+/*
611
+ * Global functions.
612
+ */
613
+
614
+void
615
+js_builtin_Array (JSVirtualMachine *vm)
616
+{
617
+  ArrayCtx *ctx;
618
+  JSNode *n;
619
+  JSBuiltinInfo *info;
620
+
621
+  ctx = js_calloc (vm, 1, sizeof (*ctx));
622
+
623
+  ctx->s_concat		= js_vm_intern (vm, "concat");
624
+  ctx->s_join		= js_vm_intern (vm, "join");
625
+  ctx->s_pop		= js_vm_intern (vm, "pop");
626
+  ctx->s_push		= js_vm_intern (vm, "push");
627
+  ctx->s_reverse	= js_vm_intern (vm, "reverse");
628
+  ctx->s_shift		= js_vm_intern (vm, "shift");
629
+  ctx->s_slice		= js_vm_intern (vm, "slice");
630
+  ctx->s_splice		= js_vm_intern (vm, "splice");
631
+  ctx->s_sort		= js_vm_intern (vm, "sort");
632
+  ctx->s_unshift	= js_vm_intern (vm, "unshift");
633
+
634
+  ctx->s_length		= js_vm_intern (vm, "length");
635
+
636
+  info = js_vm_builtin_info_create (vm);
637
+  vm->prim[JS_ARRAY] = info;
638
+
639
+  info->global_method_proc	= global_method;
640
+  info->method_proc		= method;
641
+  info->property_proc		= property;
642
+  info->new_proc		= new_proc;
643
+  info->obj_context		= ctx;
644
+  info->obj_context_delete	= js_free;
645
+
646
+  /* Define it. */
647
+  n = &vm->globals[js_vm_intern (vm, "Array")];
648
+  js_vm_builtin_create (vm, n, info, NULL);
649
+}
0 650
new file mode 100644
... ...
@@ -0,0 +1,153 @@
0
+/*
1
+ * The builtin Boolean object.
2
+ * Copyright (c) 1998 New Generation Software (NGS) Oy
3
+ *
4
+ * Author: Markku Rossi <mtr@ngs.fi>
5
+ */
6
+
7
+/*
8
+ * This library is free software; you can redistribute it and/or
9
+ * modify it under the terms of the GNU Library General Public
10
+ * License as published by the Free Software Foundation; either
11
+ * version 2 of the License, or (at your option) any later version.
12
+ *
13
+ * This library is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
+ * Library General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU Library General Public
19
+ * License along with this library; if not, write to the Free
20
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
21
+ * MA 02111-1307, USA
22
+ */
23
+
24
+/*
25
+ * $Source: /tmp/cvsroot-15-2-2007/clamav-devel/libclamav/js/b_bool.c,v $
26
+ * $Id: b_bool.c,v 1.1 2006/10/19 17:28:58 njh Exp $
27
+ */
28
+
29
+#include "jsint.h"
30
+
31
+/*
32
+ * Static functions.
33
+ */
34
+
35
+/* Global method proc. */
36
+static void
37
+global_method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info,
38
+	       void *instance_context, JSNode *result_return,
39
+	       JSNode *args)
40
+{
41
+  result_return->type = JS_BOOLEAN;
42
+
43
+  if (args->u.vinteger == 0)
44
+    result_return->u.vboolean = 0;
45
+  else if (args->u.vinteger == 1)
46
+    result_return->u.vboolean = js_vm_to_boolean (vm, &args[1]);
47
+  else
48
+    {
49
+      sprintf (vm->error, "Boolean(): illegal amount of arguments");
50
+      js_vm_error (vm);
51
+    }
52
+}
53
+
54
+/* Method proc. */
55
+static int
56
+method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info,
57
+	void *instance_context, JSSymbol method, JSNode *result_return,
58
+	JSNode *args)
59
+{
60
+  JSNode *n = instance_context;
61
+  char *cp;
62
+
63
+  if (method == vm->syms.s_toString)
64
+    {
65
+      if (args->u.vinteger != 0)
66
+	{
67
+	  sprintf (vm->error, "Boolean.%s(): illegal amount of arguments",
68
+		   js_vm_symname (vm, method));
69
+	  js_vm_error (vm);
70
+	}
71
+
72
+      if (n)
73
+	{
74
+	  cp = n->u.vboolean ? "true" : "false";
75
+	  js_vm_make_static_string (vm, result_return, cp, strlen (cp));
76
+	}
77
+      else
78
+	js_vm_make_static_string (vm, result_return, "Boolean", 7);
79
+    }
80
+  /* ********************************************************************** */
81
+  else if (method == vm->syms.s_valueOf)
82
+    {
83
+      if (n)
84
+	JS_COPY (result_return, n);
85
+      else
86
+	{
87
+	  n = &vm->globals[js_vm_intern (vm, "Boolean")];
88
+	  JS_COPY (result_return, n);
89
+	}
90
+    }
91
+  /* ********************************************************************** */
92
+  else
93
+    return JS_PROPERTY_UNKNOWN;
94
+
95
+  return JS_PROPERTY_FOUND;
96
+}
97
+
98
+/* Property proc. */
99
+static int
100
+property (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info,
101
+	  void *instance_context, JSSymbol property, int set, JSNode *node)
102
+{
103
+  if (!set)
104
+    node->type = JS_UNDEFINED;
105
+
106
+  return JS_PROPERTY_UNKNOWN;
107
+}
108
+
109
+/* New proc. */
110
+static void
111
+new_proc (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, JSNode *args,
112
+	  JSNode *result_return)
113
+{
114
+  result_return->type = JS_BOOLEAN;
115
+
116
+  if (args->u.vinteger == 0)
117
+    result_return->u.vboolean = 0;
118
+  else if (args->u.vinteger == 1)
119
+    result_return->u.vboolean = js_vm_to_boolean (vm, &args[1]);
120
+  else
121
+    {
122
+      sprintf (vm->error, "new Boolean(): illegal amount of arguments");
123
+      js_vm_error (vm);
124
+    }
125
+
126
+  /* Set the [[Prototype]] and [[Class]] properties. */
127
+  /* XXX 15.10.2.1 */
128
+}
129
+
130
+
131
+/*
132
+ * Global functions.
133
+ */
134
+
135
+void
136
+js_builtin_Boolean (JSVirtualMachine *vm)
137
+{
138
+  JSNode *n;
139
+  JSBuiltinInfo *info;
140
+
141
+  info = js_vm_builtin_info_create (vm);
142
+  vm->prim[JS_BOOLEAN] = info;
143
+
144
+  info->global_method_proc	= global_method;
145
+  info->method_proc		= method;
146
+  info->property_proc		= property;
147
+  info->new_proc		= new_proc;
148
+
149
+  /* Define it. */
150
+  n = &vm->globals[js_vm_intern (vm, "Boolean")];
151
+  js_vm_builtin_create (vm, n, info, NULL);
152
+}
0 153
new file mode 100644
... ...
@@ -0,0 +1,792 @@
0
+/*
1
+ * The builtin Date object.
2
+ * Copyright (c) 1998 New Generation Software (NGS) Oy
3
+ *
4
+ * Author: Markku Rossi <mtr@ngs.fi>
5
+ */
6
+
7
+/*
8
+ * This library is free software; you can redistribute it and/or
9
+ * modify it under the terms of the GNU Library General Public
10
+ * License as published by the Free Software Foundation; either
11
+ * version 2 of the License, or (at your option) any later version.
12
+ *
13
+ * This library is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
+ * Library General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU Library General Public
19
+ * License along with this library; if not, write to the Free
20
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
21
+ * MA 02111-1307, USA
22
+ */
23
+
24
+/*
25
+ * $Source: /tmp/cvsroot-15-2-2007/clamav-devel/libclamav/js/b_date.c,v $
26
+ * $Id: b_date.c,v 1.1 2006/10/19 17:28:58 njh Exp $
27
+ */
28
+
29
+#include "jsint.h"
30
+#include "rentrant.h"
31
+
32
+/* XXX TODO 15.13.3 -> */
33
+
34
+/*
35
+ * Types and definitions.
36
+ */
37
+
38
+#define GMT_DATE_FORMAT	"%a, %d %b %Y %H:%M:%S GMT"
39
+
40
+#define MS_PER_SECOND	1000
41
+#define MS_PER_MINUTE	(60 * MS_PER_SECOND)
42
+#define MS_PER_HOUR	(60 * MS_PER_MINUTE)
43
+#define MS_PER_DAY	(24 * MS_PER_HOUR)
44
+
45
+/* Class context. */
46
+struct date_ctx_st
47
+{
48
+  /* Static methods. */
49
+  JSSymbol s_parse;
50
+
51
+  /* Methods. */
52
+  JSSymbol s_format;
53
+  JSSymbol s_formatGMT;
54
+  JSSymbol s_getDate;
55
+  JSSymbol s_getDay;
56
+  JSSymbol s_getHours;
57
+  JSSymbol s_getMinutes;
58
+  JSSymbol s_getMonth;
59
+  JSSymbol s_getSeconds;
60
+  JSSymbol s_getTime;
61
+  JSSymbol s_getTimezoneOffset;
62
+  JSSymbol s_getYear;
63
+  JSSymbol s_setDate;
64
+  JSSymbol s_setHours;
65
+  JSSymbol s_setMinutes;
66
+  JSSymbol s_setMonth;
67
+  JSSymbol s_setSeconds;
68
+  JSSymbol s_setTime;
69
+  JSSymbol s_setYear;
70
+  JSSymbol s_toGMTString;
71
+  JSSymbol s_toLocaleString;
72
+  JSSymbol s_UTC;
73
+};
74
+
75
+typedef struct date_ctx_st DateCtx;
76
+
77
+/* Date instance context. */
78
+struct date_instance_ctx_st
79
+{
80
+  time_t secs;
81
+  struct tm localtime;
82
+};
83
+
84
+typedef struct date_instance_ctx_st DateInstanceCtx;
85
+
86
+/*
87
+ * Static functions.
88
+ */
89
+
90
+/* Global methods. */
91
+void
92
+MakeTime_global_method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info,
93
+			void *instance_context, JSNode *result_return,
94
+			JSNode *args)
95
+{
96
+  if (args->u.vinteger != 4)
97
+    {
98
+      sprintf (vm->error, "MakeTime: illegal amount of argument");
99
+      js_vm_error (vm);
100
+    }
101
+  if (!JS_IS_NUMBER (&args[1]) || !JS_IS_NUMBER (&args[2])
102
+      || !JS_IS_NUMBER (&args[3]) || !JS_IS_NUMBER (&args[4]))
103
+    {
104
+      sprintf (vm->error, "MakeTime: illegal argument");
105
+      js_vm_error (vm);
106
+    }
107
+  if (!JS_IS_FINITE (&args[1]) || !JS_IS_FINITE (&args[2])
108
+      || !JS_IS_FINITE (&args[3]) || !JS_IS_FINITE (&args[4]))
109
+    {
110
+      result_return->type = JS_NAN;
111
+    }
112
+  else
113
+    {
114
+      JSInt32 hour, min, sec, ms;
115
+
116
+      hour = js_vm_to_int32 (vm, &args[1]);
117
+      min  = js_vm_to_int32 (vm, &args[2]);
118
+      sec  = js_vm_to_int32 (vm, &args[3]);
119
+      ms   = js_vm_to_int32 (vm, &args[4]);
120
+
121
+      result_return->type = JS_FLOAT;
122
+      result_return->u.vfloat = (hour * MS_PER_HOUR
123
+				 + min * MS_PER_MINUTE
124
+				 + sec * MS_PER_SECOND
125
+				 + ms);
126
+    }
127
+}
128
+
129
+
130
+void
131
+MakeDay_global_method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info,
132
+		       void *instance_context, JSNode *result_return,
133
+		       JSNode *args)
134
+{
135
+  if (args->u.vinteger != 3)
136
+    {
137
+      sprintf (vm->error, "MakeDay: illegal amount of argument");
138
+      js_vm_error (vm);
139
+    }
140
+  if (!JS_IS_NUMBER (&args[1]) || !JS_IS_NUMBER (&args[2])
141
+      || !JS_IS_NUMBER (&args[3]))
142
+    {
143
+      sprintf (vm->error, "MakeDay: illegal argument");
144
+      js_vm_error (vm);
145
+    }
146
+  if (!JS_IS_FINITE (&args[1]) || !JS_IS_FINITE (&args[2])
147
+      || !JS_IS_FINITE (&args[3]))
148
+    {
149
+      result_return->type = JS_NAN;
150
+    }
151
+  else
152
+    {
153
+      JSInt32 year, month, day;
154
+
155
+      year  = js_vm_to_int32 (vm, &args[1]);
156
+      month = js_vm_to_int32 (vm, &args[2]);
157
+      day   = js_vm_to_int32 (vm, &args[3]);
158
+
159
+      sprintf (vm->error, "MakeDay: not implemented yet");
160
+      js_vm_error (vm);
161
+    }
162
+}
163
+
164
+
165
+void
166
+MakeDate_global_method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info,
167
+			void *instance_context, JSNode *result_return,
168
+			JSNode *args)
169
+{
170
+  if (args->u.vinteger != 2)
171
+    {
172
+      sprintf (vm->error, "MakeDate: illegal amount of argument");
173
+      js_vm_error (vm);
174
+    }
175
+  if (!JS_IS_NUMBER (&args[1]) || !JS_IS_NUMBER (&args[2]))
176
+    {
177
+      sprintf (vm->error, "MakeDate: illegal argument");
178
+      js_vm_error (vm);
179
+    }
180
+  if (!JS_IS_FINITE (&args[1]) || !JS_IS_FINITE (&args[2]))
181
+    {
182
+      result_return->type = JS_NAN;
183
+    }
184
+  else
185
+    {
186
+      JSInt32 day;
187
+      JSInt32 time;
188
+
189
+      day  = js_vm_to_int32 (vm, &args[1]);
190
+      time = js_vm_to_int32 (vm, &args[2]);
191
+
192
+      result_return->type = JS_FLOAT;
193
+      result_return->u.vfloat = (day * MS_PER_DAY + time);
194
+    }
195
+}
196
+
197
+
198
+void
199
+TimeClip_global_method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info,
200
+			void *instance_context, JSNode *result_return,
201
+			JSNode *args)
202
+{
203
+  if (args->u.vinteger != 1)
204
+    {
205
+      sprintf (vm->error, "TimeClip: illegal amount of argument");
206
+      js_vm_error (vm);
207
+    }
208
+  if (!JS_IS_NUMBER (&args[1]))
209
+    {
210
+      sprintf (vm->error, "TimeClip: illegal argument");
211
+      js_vm_error (vm);
212
+    }
213
+  if (!JS_IS_FINITE (&args[1]))
214
+    {
215
+      result_return->type = JS_NAN;
216
+    }
217
+  else
218
+    {
219
+      result_return->type = JS_FLOAT;
220
+
221
+      if (args[1].type == JS_INTEGER)
222
+	result_return->u.vfloat = (double) args[1].u.vinteger;
223
+      else
224
+	result_return->u.vfloat = args[1].u.vfloat;
225
+
226
+      if (result_return->u.vfloat > 8.64e15
227
+	  || result_return->u.vfloat < -8.64e15)
228
+	result_return->type = JS_NAN;
229
+    }
230
+}
231
+
232
+/* Method proc. */
233
+static int
234
+method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info,
235
+	void *instance_context, JSSymbol method, JSNode *result_return,
236
+	JSNode *args)
237
+{
238
+  DateCtx *ctx = builtin_info->obj_context;
239
+  DateInstanceCtx *ictx = instance_context;
240
+
241
+  /* The default return type is integer. */
242
+  result_return->type = JS_INTEGER;
243
+
244
+  /* Static methods. */
245
+  if (method == ctx->s_parse)
246
+    {
247
+      goto not_implemented_yet;
248
+    }
249
+  /* ********************************************************************** */
250
+  else if (method == vm->syms.s_toString)
251
+    {
252
+      if (args->u.vinteger != 0)
253
+	goto argument_error;
254
+
255
+      if (ictx)
256
+	goto date_to_string;
257
+      else
258
+	js_vm_make_static_string (vm, result_return, "Date", 4);
259
+    }
260
+  /* ********************************************************************** */
261
+  else if (ictx)
262
+    {
263
+      /* Methods. */
264
+
265
+      if (method == ctx->s_format || method == ctx->s_formatGMT)
266
+	{
267
+	  struct tm tm_st;
268
+	  struct tm *tm = &ictx->localtime;
269
+	  char *fmt;
270
+	  char *buf;
271
+	  unsigned int buflen;
272
+
273
+	  if (args->u.vinteger != 1)
274
+	    goto argument_error;
275
+	  if (args[1].type != JS_STRING)
276
+	    goto argument_type_error;
277
+
278
+	  fmt = js_string_to_c_string (vm, &args[1]);
279
+
280
+	  buflen = args[1].u.vstring->len * 2 + 1;
281
+	  buf = js_malloc (vm, buflen);
282
+
283
+	  if (method == ctx->s_formatGMT)
284
+	    {
285
+	      js_gmtime (&ictx->secs, &tm_st);
286
+	      tm = &tm_st;
287
+	    }
288
+
289
+	  if (args[1].u.vstring->len == 0)
290
+	    buf[0] = '\0';
291
+	  else
292
+	    {
293
+	      while (strftime (buf, buflen, fmt, tm) == 0)
294
+		{
295
+		  /* Expand the buffer. */
296
+		  buflen *= 2;
297
+		  buf = js_realloc (vm, buf, buflen);
298
+		}
299
+	    }
300
+
301
+	  js_vm_make_string (vm, result_return, buf, strlen (buf));
302
+
303
+	  js_free (fmt);
304
+	  js_free (buf);
305
+	}
306
+      /* ***************************************************************** */
307
+      else if (method == ctx->s_getDate)
308
+	{
309
+	  if (args->u.vinteger != 0)
310
+	    goto argument_error;
311
+
312
+	  result_return->u.vinteger = ictx->localtime.tm_mday;
313
+	}
314
+      /* ***************************************************************** */
315
+      else if (method == ctx->s_getDay)
316
+	{
317
+	  if (args->u.vinteger != 0)
318
+	    goto argument_error;
319
+
320
+	  result_return->u.vinteger = ictx->localtime.tm_wday;
321
+	}
322
+      /* ***************************************************************** */
323
+      else if (method == ctx->s_getHours)
324
+	{
325
+	  if (args->u.vinteger != 0)
326
+	    goto argument_error;
327
+
328
+	  result_return->u.vinteger = ictx->localtime.tm_hour;
329
+	}
330
+      /* ***************************************************************** */
331
+      else if (method == ctx->s_getMinutes)
332
+	{
333
+	  if (args->u.vinteger != 0)
334
+	    goto argument_error;
335
+
336
+	  result_return->u.vinteger = ictx->localtime.tm_min;
337
+	}
338
+      /* ***************************************************************** */
339
+      else if (method == ctx->s_getMonth)
340
+	{
341
+	  if (args->u.vinteger != 0)
342
+	    goto argument_error;
343
+
344
+	  result_return->u.vinteger = ictx->localtime.tm_mon;
345
+	}
346
+      /* ***************************************************************** */
347
+      else if (method == ctx->s_getSeconds)
348
+	{
349
+	  if (args->u.vinteger != 0)
350
+	    goto argument_error;
351
+
352
+	  result_return->u.vinteger = ictx->localtime.tm_sec;
353
+	}
354
+      /* ***************************************************************** */
355
+      else if (method == ctx->s_getTime)
356
+	{
357
+	  if (args->u.vinteger != 0)
358
+	    goto argument_error;
359
+
360
+	  result_return->type = JS_FLOAT;
361
+	  result_return->u.vfloat = (double) ictx->secs * 1000;
362
+	}
363
+      /* ***************************************************************** */
364
+      else if (method == ctx->s_getTimezoneOffset)
365
+	goto not_implemented_yet;
366
+      /* ***************************************************************** */
367
+      else if (method == ctx->s_getYear)
368
+	{
369
+	  if (args->u.vinteger != 0)
370
+	    goto argument_error;
371
+
372
+	  result_return->u.vinteger = ictx->localtime.tm_year;
373
+	  if (ictx->localtime.tm_year >= 100
374
+	      || ictx->localtime.tm_year < 0)
375
+	    result_return->u.vinteger += 1900;
376
+	}
377
+      /* ***************************************************************** */
378
+      else if (method == ctx->s_setDate)
379
+	{
380
+	  if (args->u.vinteger != 1)
381
+	    goto argument_error;
382
+	  if (args[1].type != JS_INTEGER)
383
+	    goto argument_type_error;
384
+
385
+	  if (1 <= args[1].u.vinteger && args[1].u.vinteger <= 31)
386
+	    {
387
+	      ictx->localtime.tm_mday = args[1].u.vinteger;
388
+	      ictx->secs = mktime (&ictx->localtime);
389
+	    }
390
+	  else
391
+	    goto argument_range_error;
392
+	}
393
+      /* ***************************************************************** */
394
+      else if (method == ctx->s_setHours)
395
+	{
396
+	  if (args->u.vinteger != 1)
397
+	    goto argument_error;
398
+	  if (args[1].type != JS_INTEGER)
399
+	    goto argument_type_error;
400
+
401
+	  if (0 <= args[1].u.vinteger && args[1].u.vinteger <= 23)
402
+	    {
403
+	      ictx->localtime.tm_hour = args[1].u.vinteger;
404
+	      ictx->secs = mktime (&ictx->localtime);
405
+	    }
406
+	  else
407
+	    goto argument_range_error;
408
+	}
409
+      /* ***************************************************************** */
410
+      else if (method == ctx->s_setMinutes)
411
+	{
412
+	  if (args->u.vinteger != 1)
413
+	    goto argument_error;
414
+	  if (args[1].type != JS_INTEGER)
415
+	    goto argument_type_error;
416
+
417
+	  if (0 <= args[1].u.vinteger && args[1].u.vinteger <= 59)
418
+	    {
419
+	      ictx->localtime.tm_min = args[1].u.vinteger;
420
+	      ictx->secs = mktime (&ictx->localtime);
421
+	    }
422
+	  else
423
+	    goto argument_range_error;
424
+	}
425
+      /* ***************************************************************** */
426
+      else if (method == ctx->s_setMonth)
427
+	{
428
+	  if (args->u.vinteger != 1)
429
+	    goto argument_error;
430
+	  if (args[1].type != JS_INTEGER)
431
+	    goto argument_type_error;
432
+
433
+	  if (0 <= args[1].u.vinteger && args[1].u.vinteger <= 11)
434
+	    {
435
+	      ictx->localtime.tm_mon = args[1].u.vinteger;
436
+	      ictx->secs = mktime (&ictx->localtime);
437
+	    }
438
+	  else
439
+	    goto argument_range_error;
440
+	}
441
+      /* ***************************************************************** */
442
+      else if (method == ctx->s_setSeconds)
443
+	{
444
+	  if (args->u.vinteger != 1)
445
+	    goto argument_error;
446
+	  if (args[1].type != JS_INTEGER)
447
+	    goto argument_type_error;
448
+
449
+	  if (0 <= args[1].u.vinteger && args[1].u.vinteger <= 59)
450
+	    {
451
+	      ictx->localtime.tm_sec = args[1].u.vinteger;
452
+	      ictx->secs = mktime (&ictx->localtime);
453
+	    }
454
+	  else
455
+	    goto argument_range_error;
456
+	}
457
+      /* ***************************************************************** */
458
+      else if (method == ctx->s_setTime)
459
+	{
460
+	  if (args->u.vinteger != 1)
461
+	    goto argument_error;
462
+
463
+	  if (args[1].type == JS_INTEGER)
464
+	    ictx->secs = args[1].u.vinteger / 1000;
465
+	  else if (args[1].type == JS_FLOAT)
466
+	    ictx->secs = (long) (args[1].u.vfloat / 1000);
467
+	  else
468
+	    goto argument_type_error;
469
+
470
+	  js_localtime (&ictx->secs, &ictx->localtime);
471
+	}
472
+      /* ***************************************************************** */
473
+      else if (method == ctx->s_setYear)
474
+	{
475
+	  if (args->u.vinteger != 1)
476
+	    goto argument_error;
477
+	  if (args[1].type != JS_INTEGER)
478
+	    goto argument_type_error;
479
+
480
+	  ictx->localtime.tm_year = args[1].u.vinteger;
481
+	  if (args[1].u.vinteger < 0 || args[1].u.vinteger >= 100)
482
+	    ictx->localtime.tm_year -= 1900;
483
+
484
+	  ictx->secs = mktime (&ictx->localtime);
485
+	}
486
+      /* ***************************************************************** */
487
+      else if (method == ctx->s_toGMTString)
488
+	{
489
+	  struct tm tm_st;
490
+	  char buf[1024];	/* This is enought. */
491
+
492
+	  if (args->u.vinteger != 0)
493
+	    goto argument_error;
494
+
495
+	  js_gmtime (&ictx->secs, &tm_st);
496
+	  strftime (buf, sizeof (buf), GMT_DATE_FORMAT, &tm_st);
497
+
498
+	  js_vm_make_string (vm, result_return, buf, strlen (buf));
499
+	}
500
+      /* ***************************************************************** */
501
+      else if (method == ctx->s_toLocaleString)
502
+	{
503
+	  char *cp;
504
+	  char buf[1024];	/* This is enought */
505
+
506
+	  if (args->u.vinteger != 0)
507
+	    goto argument_error;
508
+
509
+	date_to_string:
510
+
511
+	  js_asctime (&ictx->localtime, buf, sizeof (buf));
512
+	  cp = strchr (buf, '\n');
513
+	  if (cp)
514
+	    *cp = '\0';
515
+
516
+	  js_vm_make_string (vm, result_return, buf, strlen (buf));
517
+	}
518
+      /* ***************************************************************** */
519
+      else if (method == ctx->s_UTC)
520
+	goto not_implemented_yet;
521
+      /* ***************************************************************** */
522
+      else
523
+	return JS_PROPERTY_UNKNOWN;
524
+    }
525
+  /* ********************************************************************** */
526
+  else
527
+    return JS_PROPERTY_UNKNOWN;
528
+
529
+  return JS_PROPERTY_FOUND;
530
+
531
+
532
+  /*
533
+   * Error handling.
534
+   */
535
+
536
+ not_implemented_yet:
537
+  sprintf (vm->error, "Date.%s(): not implemented yet",
538
+	   js_vm_symname (vm, method));
539
+  js_vm_error (vm);
540
+
541
+ argument_error:
542
+  sprintf (vm->error, "Date.%s(): illegal amount of arguments",
543
+	   js_vm_symname (vm, method));
544
+  js_vm_error (vm);
545
+
546
+ argument_type_error:
547
+  sprintf (vm->error, "Date.%s(): illegal argument",
548
+	   js_vm_symname (vm, method));
549
+  js_vm_error (vm);
550
+
551
+ argument_range_error:
552
+  sprintf (vm->error, "Date.%s(): argument out of range",
553
+	   js_vm_symname (vm, method));
554
+  js_vm_error (vm);
555
+
556
+  /* NOTREACHED. */
557
+  return 0;
558
+}
559
+
560
+
561
+/* Global method proc. */
562
+static void
563
+global_method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info,
564
+	       void *instance_context, JSNode *result_return,
565
+	       JSNode *args)
566
+{
567
+  time_t secs;
568
+  struct tm localtime;
569
+  char buf[512];
570
+  char *cp;
571
+
572
+  if (args->u.vinteger > 7)
573
+    {
574
+      sprintf (vm->error, "Date(): illegal amount of arguments");
575
+      js_vm_error (vm);
576
+    }
577
+
578
+  /*
579
+   * We ignore our arguments and return the result of:
580
+   * `new Date ().toString ()'.
581
+   */
582
+
583
+  secs = time (NULL);
584
+  js_localtime (&secs, &localtime);
585
+  js_asctime (&localtime, buf, sizeof (buf));
586
+
587
+  cp = strchr (buf, '\n');
588
+  if (cp)
589
+    *cp = '\0';
590
+
591
+  js_vm_make_string (vm, result_return, buf, strlen (buf));
592
+}
593
+
594
+
595
+/* Property proc. */
596
+static int
597
+property (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info,
598
+	  void *instance_context, JSSymbol property, int set, JSNode *node)
599
+{
600
+  if (!set)
601
+    node->type = JS_UNDEFINED;
602
+
603
+  return JS_PROPERTY_UNKNOWN;
604
+}
605
+
606
+/* New proc. */
607
+static void
608
+new_proc (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, JSNode *args,
609
+	  JSNode *result_return)
610
+{
611
+  DateInstanceCtx *instance;
612
+  time_t seconds = 0;		/* Initialized to keep compiler quiet. */
613
+
614
+  instance = js_calloc (vm, 1, sizeof (*instance));
615
+
616
+  if (args->u.vinteger == 0)
617
+    {
618
+      instance->secs = time (NULL);
619
+      js_localtime (&instance->secs, &instance->localtime);
620
+    }
621
+  else if (args->u.vinteger == 1)
622
+    goto not_implemented_yet;
623
+  else if (args->u.vinteger == 3 || args->u.vinteger == 6)
624
+    {
625
+      int i;
626
+
627
+      for (i = 0; i < args->u.vinteger; i++)
628
+	if (args[i + 1].type != JS_INTEGER)
629
+	  goto argument_type_error;
630
+
631
+      /* Year. */
632
+      instance->localtime.tm_year = args[1].u.vinteger;
633
+      if (args[1].u.vinteger < 0 || args[1].u.vinteger >= 100)
634
+	instance->localtime.tm_year -= 1900;
635
+
636
+      /* Month. */
637
+      if (0 <= args[2].u.vinteger && args[2].u.vinteger <= 11)
638
+	instance->localtime.tm_mon = args[2].u.vinteger;
639
+      else
640
+	goto argument_range_error;
641
+
642
+      /* Day. */
643
+      if (1 <= args[3].u.vinteger && args[3].u.vinteger <= 31)
644
+	instance->localtime.tm_mday = args[3].u.vinteger;
645
+      else
646
+	goto argument_range_error;
647
+
648
+      if (args->u.vinteger == 6)
649
+	{
650
+	  /* Sync the localtime according to year, month and day. */
651
+	  mktime (&instance->localtime);
652
+
653
+	  /* Hours. */
654
+	  if (0 <= args[4].u.vinteger && args[4].u.vinteger <= 23)
655
+	    instance->localtime.tm_hour = args[4].u.vinteger;
656
+	  else
657
+	    goto argument_range_error;
658
+
659
+	  /* Minutes. */
660
+	  if (0 <= args[5].u.vinteger && args[5].u.vinteger <= 59)
661
+	    instance->localtime.tm_min = args[5].u.vinteger;
662
+	  else
663
+	    goto argument_range_error;
664
+
665
+	  /* Seconds. */
666
+	  if (0 <= args[6].u.vinteger && args[6].u.vinteger <= 59)
667
+	    instance->localtime.tm_sec = args[6].u.vinteger;
668
+	  else
669
+	    goto argument_range_error;
670
+	}
671
+
672
+      instance->secs = mktime (&instance->localtime);
673
+    }
674
+  else
675
+    {
676
+      js_free (instance);
677
+
678
+      sprintf (vm->error, "new Date(): illegal amount of arguments");
679
+      js_vm_error (vm);
680
+    }
681
+
682
+  js_vm_builtin_create (vm, result_return, builtin_info, instance);
683
+
684
+  return;
685
+
686
+  /*
687
+   * Error handling.
688
+   */
689
+
690
+ not_implemented_yet:
691
+  sprintf (vm->error, "new Date(%ld args): not implemented yet",
692
+	   args->u.vinteger);
693
+  js_vm_error (vm);
694
+
695
+ argument_type_error:
696
+  sprintf (vm->error, "new Date(): illegal argument");
697
+  js_vm_error (vm);
698
+
699
+ argument_range_error:
700
+  sprintf (vm->error, "new Date(): argument out of range");
701
+  js_vm_error (vm);
702
+}
703
+
704
+/* Delete proc. */
705
+static void
706
+delete_proc (JSBuiltinInfo *builtin_info, void *instance_context)
707
+{
708
+  DateInstanceCtx *ictx = instance_context;
709
+
710
+  if (ictx)
711
+    js_free (ictx);
712
+}
713
+
714
+
715
+/*
716
+ * Global functions.
717
+ */
718
+
719
+static struct
720
+{
721
+  char *name;
722
+  JSBuiltinGlobalMethod method;
723
+} global_methods[] =
724
+{
725
+  {"MakeTime",	MakeTime_global_method},
726
+  {"MakeDay",	MakeDay_global_method},
727
+  {"MakeDate",	MakeDate_global_method},
728
+  {"TimeClip",	TimeClip_global_method},
729
+
730
+  {NULL, NULL},
731
+};
732
+
733
+void
734
+js_builtin_Date (JSVirtualMachine *vm)
735
+{
736
+  JSBuiltinInfo *info;
737
+  DateCtx *ctx;
738
+  JSNode *n;
739
+  int i;
740
+
741
+  ctx = js_calloc (vm, 1, sizeof (*ctx));
742
+
743
+  ctx->s_format			= js_vm_intern (vm, "format");
744
+  ctx->s_formatGMT		= js_vm_intern (vm, "formatGMT");
745
+  ctx->s_getDate		= js_vm_intern (vm, "getDate");
746
+  ctx->s_getDay			= js_vm_intern (vm, "getDay");
747
+  ctx->s_getHours		= js_vm_intern (vm, "getHours");
748
+  ctx->s_getMinutes		= js_vm_intern (vm, "getMinutes");
749
+  ctx->s_getMonth		= js_vm_intern (vm, "getMonth");
750
+  ctx->s_getSeconds		= js_vm_intern (vm, "getSeconds");
751
+  ctx->s_getTime		= js_vm_intern (vm, "getTime");
752
+  ctx->s_getTimezoneOffset	= js_vm_intern (vm, "getTimezoneOffset");
753
+  ctx->s_getYear		= js_vm_intern (vm, "getYear");
754
+  ctx->s_parse			= js_vm_intern (vm, "parse");
755
+  ctx->s_setDate		= js_vm_intern (vm, "setDate");
756
+  ctx->s_setHours		= js_vm_intern (vm, "setHours");
757
+  ctx->s_setMinutes		= js_vm_intern (vm, "setMinutes");
758
+  ctx->s_setMonth		= js_vm_intern (vm, "setMonth");
759
+  ctx->s_setSeconds		= js_vm_intern (vm, "setSeconds");
760
+  ctx->s_setTime		= js_vm_intern (vm, "setTime");
761
+  ctx->s_setYear		= js_vm_intern (vm, "setYear");
762
+  ctx->s_toGMTString		= js_vm_intern (vm, "toGMTString");
763
+  ctx->s_toLocaleString		= js_vm_intern (vm, "toLocaleString");
764
+  ctx->s_UTC			= js_vm_intern (vm, "UTC");
765
+
766
+  /* Object information. */
767
+
768
+  info = js_vm_builtin_info_create (vm);
769
+
770
+  info->method_proc		= method;
771
+  info->global_method_proc	= global_method;
772
+  info->property_proc		= property;
773
+  info->new_proc		= new_proc;
774
+  info->delete_proc		= delete_proc;
775
+  info->obj_context		= ctx;
776
+  info->obj_context_delete	= js_free;
777
+
778
+  /* Define it. */
779
+  n = &vm->globals[js_vm_intern (vm, "Date")];
780
+  js_vm_builtin_create (vm, n, info, NULL);
781
+
782
+  /* Global methods. */
783
+
784
+  for (i = 0; global_methods[i].name; i++)
785
+    {
786
+      info = js_vm_builtin_info_create (vm);
787
+      info->global_method_proc = global_methods[i].method;
788
+      n = &vm->globals[js_vm_intern (vm, global_methods[i].name)];
789
+      js_vm_builtin_create (vm, n, info, NULL);
790
+    }
791
+}
0 792
new file mode 100644
... ...
@@ -0,0 +1,319 @@
0
+/*
1
+ * The builtin Directory object.
2
+ * Copyright (c) 1998-1999 New Generation Software (NGS) Oy
3
+ *
4
+ * Author: Markku Rossi <mtr@ngs.fi>
5
+ */
6
+
7
+/*
8
+ * This library is free software; you can redistribute it and/or
9
+ * modify it under the terms of the GNU Library General Public
10
+ * License as published by the Free Software Foundation; either
11
+ * version 2 of the License, or (at your option) any later version.
12
+ *
13
+ * This library is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
+ * Library General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU Library General Public
19
+ * License along with this library; if not, write to the Free
20
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
21
+ * MA 02111-1307, USA
22
+ */
23
+
24
+/*
25
+ * $Source: /tmp/cvsroot-15-2-2007/clamav-devel/libclamav/js/b_dir.c,v $
26
+ * $Id: b_dir.c,v 1.1 2006/10/19 17:28:58 njh Exp $
27
+ */
28
+
29
+#include "jsint.h"
30
+
31
+/*
32
+ * Types and definitions.
33
+ */
34
+
35
+/* Class context. */
36
+struct dir_ctx_st
37
+{
38
+  /* Methods. */
39
+  JSSymbol s_close;
40
+  JSSymbol s_open;
41
+  JSSymbol s_read;
42
+  JSSymbol s_rewind;
43
+  JSSymbol s_seek;
44
+  JSSymbol s_tell;
45
+};
46
+
47
+typedef struct dir_ctx_st DirCtx;
48
+
49
+/* Instance context. */
50
+struct dir_instance_ctx_st
51
+{
52
+  DIR *dir;
53
+  char *path;
54
+
55
+  /* The virtual machine handle is needed for the delete_proc. */
56
+  JSVirtualMachine *vm;
57
+};
58
+
59
+typedef struct dir_instance_ctx_st DirInstanceCtx;
60
+
61
+
62
+/*
63
+ * Static functions.
64
+ */
65
+
66
+/* Method proc. */
67
+static int
68
+method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info,
69
+	void *instance_context, JSSymbol method, JSNode *result_return,
70
+	JSNode *args)
71
+{
72
+  DirCtx *ctx = builtin_info->obj_context;
73
+  DirInstanceCtx *ictx = instance_context;
74
+
75
+  /* Static methods. */
76
+  if (method == vm->syms.s_toString)
77
+    {
78
+      if (args->u.vinteger != 0)
79
+	goto argument_error;
80
+
81
+      if (ictx)
82
+	js_vm_make_string (vm, result_return, ictx->path, strlen (ictx->path));
83
+      else
84
+	js_vm_make_static_string (vm, result_return, "Directory", 9);
85
+    }
86
+  /* ********************************************************************** */
87
+  else if (ictx)
88
+    {
89
+      /*
90
+       * Instance methods.
91
+       */
92
+      if (method == ctx->s_close)
93
+	{
94
+	  if (args->u.vinteger != 0)
95
+	    goto argument_error;
96
+
97
+	  if (ictx->dir)
98
+	    if (closedir (ictx->dir) >= 0)
99
+	      {
100
+		ictx->dir = NULL;
101
+		JS_VM_FREE_FD (vm);
102
+	      }
103
+
104
+	  result_return->type = JS_BOOLEAN;
105
+	  result_return->u.vboolean = ictx->dir == NULL;
106
+	}
107
+      /* ***************************************************************** */
108
+      else if (method == ctx->s_open)
109
+	{
110
+	  if (args->u.vinteger != 0)
111
+	    goto argument_error;
112
+
113
+	  if (ictx->dir == NULL)
114
+	    {
115
+	      JS_VM_ALLOCATE_FD (vm, "Directory.open()");
116
+	      ictx->dir = opendir (ictx->path);
117
+
118
+	      if (ictx->dir == NULL)
119
+		/* Directory opening failed. */
120
+		JS_VM_FREE_FD (vm);
121
+	    }
122
+
123
+	  result_return->type = JS_BOOLEAN;
124
+	  result_return->u.vboolean = ictx->dir != NULL;
125
+	}
126
+      /* ***************************************************************** */
127
+      else if (method == ctx->s_read)
128
+	{
129
+	  struct dirent *de;
130
+
131
+	  if (args->u.vinteger != 0)
132
+	    goto argument_error;
133
+	  if (ictx->dir == NULL)
134
+	    goto not_open;
135
+
136
+	  de = readdir (ictx->dir);
137
+	  if (de)
138
+	    js_vm_make_string (vm, result_return, de->d_name,
139
+			       strlen (de->d_name));
140
+	  else
141
+	    {
142
+	      result_return->type = JS_BOOLEAN;
143
+	      result_return->u.vboolean = 0;
144
+	    }
145
+	}
146
+      /* ***************************************************************** */
147
+      else if (method == ctx->s_rewind)
148
+	{
149
+	  if (args->u.vinteger != 0)
150
+	    goto argument_error;
151
+	  if (ictx->dir == NULL)
152
+	    goto not_open;
153
+
154
+	  rewinddir (ictx->dir);
155
+	  result_return->type = JS_UNDEFINED;
156
+	}
157
+      /* ***************************************************************** */
158
+      else if (method == ctx->s_seek)
159
+	{
160
+	  if (args->u.vinteger != 1)
161
+	    goto argument_error;
162
+	  if (args[1].type != JS_INTEGER)
163
+	    goto argument_type_error;
164
+	  if (ictx->dir == NULL)
165
+	    goto not_open;
166
+
167
+	  seekdir (ictx->dir, args[1].u.vinteger);
168
+	  result_return->type = JS_UNDEFINED;
169
+	}
170
+      /* ***************************************************************** */
171
+      else if (method == ctx->s_tell)
172
+	{
173
+	  if (args->u.vinteger != 0)
174
+	    goto argument_error;
175
+	  if (ictx->dir == NULL)
176
+	    goto not_open;
177
+
178
+	  result_return->u.vinteger = telldir (ictx->dir);
179
+	  if (result_return->u.vinteger < 0)
180
+	    {
181
+	      result_return->type = JS_BOOLEAN;
182
+	      result_return->u.vboolean = 0;
183
+	    }
184
+	  else
185
+	    result_return->type = JS_INTEGER;
186
+	}
187
+      /* ***************************************************************** */
188
+      else
189
+	return JS_PROPERTY_UNKNOWN;
190
+    }
191
+  /* ********************************************************************** */
192
+  else
193
+    return JS_PROPERTY_UNKNOWN;
194
+
195
+  return JS_PROPERTY_FOUND;
196
+
197
+
198
+  /*
199
+   * Error handling.
200
+   */
201
+
202
+ argument_error:
203
+  sprintf (vm->error, "Directory.%s(): illegal amount of arguments",
204
+	   js_vm_symname (vm, method));
205
+  js_vm_error (vm);
206
+
207
+ argument_type_error:
208
+  sprintf (vm->error, "Directory.%s(): illegal argument",
209
+	   js_vm_symname (vm, method));
210
+  js_vm_error (vm);
211
+
212
+ not_open:
213
+  sprintf (vm->error, "Directory.%s(): directory is no opened",
214
+	   js_vm_symname (vm, method));
215
+  js_vm_error (vm);
216
+
217
+ insecure_feature:
218
+  sprintf (vm->error, "Directory.%s(): not allowed in secure mode",
219
+	   js_vm_symname (vm, method));
220
+  js_vm_error (vm);
221
+
222
+  /* NOTREACHED */
223
+  return 0;
224
+}
225
+
226
+
227
+/* Property proc. */
228
+static int
229
+property (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info,
230
+	  void *instance_context, JSSymbol property, int set, JSNode *node)
231
+{
232
+  /* We have no properties. */
233
+
234
+  if (!set)
235
+    node->type = JS_UNDEFINED;
236
+
237
+  return JS_PROPERTY_UNKNOWN;
238
+}
239
+
240
+/* New proc. */
241
+static void
242
+new_proc (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, JSNode *args,
243
+	  JSNode *result_return)
244
+{
245
+  DirInstanceCtx *instance;
246
+  if (args->u.vinteger != 1)
247
+    {
248
+      sprintf (vm->error, "new Directory(): illegal amount of arguments");
249
+      js_vm_error (vm);
250
+    }
251
+  if (args[1].type != JS_STRING)
252
+    {
253
+      sprintf (vm->error, "new Directory(): illegal argument");
254
+      js_vm_error (vm);
255
+    }
256
+
257
+  instance = js_calloc (vm, 1, sizeof (*instance));
258
+  instance->path = js_string_to_c_string (vm, &args[1]);
259
+  instance->vm = vm;
260
+
261
+  js_vm_builtin_create (vm, result_return, builtin_info, instance);
262
+}
263
+
264
+/* Delete proc. */
265
+static void
266
+delete_proc (JSBuiltinInfo *builtin_info, void *instance_context)
267
+{
268
+  DirInstanceCtx *ictx = instance_context;
269
+
270
+  if (ictx)
271
+    {
272
+      if (ictx->dir)
273
+	{
274
+	  closedir (ictx->dir);
275
+	  JS_VM_FREE_FD (ictx->vm);
276
+	}
277
+
278
+      js_free (ictx->path);
279
+      js_free (ictx);
280
+    }
281
+}
282
+
283
+
284
+/*
285
+ * Global functions.
286
+ */
287
+
288
+void
289
+js_builtin_Directory (JSVirtualMachine *vm)
290
+{
291
+  JSNode *n;
292
+  JSBuiltinInfo *info;
293
+  DirCtx *ctx;
294
+
295
+  ctx = js_calloc (vm, 1, sizeof (*ctx));
296
+
297
+  ctx->s_close		= js_vm_intern (vm, "close");
298
+  ctx->s_open		= js_vm_intern (vm, "open");
299
+  ctx->s_read		= js_vm_intern (vm, "read");
300
+  ctx->s_rewind		= js_vm_intern (vm, "rewind");
301
+  ctx->s_seek		= js_vm_intern (vm, "seek");
302
+  ctx->s_tell		= js_vm_intern (vm, "tell");
303
+
304
+  /* Object information. */
305
+
306
+  info = js_vm_builtin_info_create (vm);
307
+
308
+  info->method_proc 		= method;
309
+  info->property_proc 		= property;
310
+  info->new_proc 		= new_proc;
311
+  info->delete_proc 		= delete_proc;
312
+  info->obj_context 		= ctx;
313
+  info->obj_context_delete	= js_free;
314
+
315
+  /* Define it. */
316
+  n = &vm->globals[js_vm_intern (vm, "Directory")];
317
+  js_vm_builtin_create (vm, n, info, NULL);
318
+}
0 319
new file mode 100644
... ...
@@ -0,0 +1,1012 @@
0
+/*
1
+ * The builtin File object.
2
+ * Copyright (c) 1998-1999 New Generation Software (NGS) Oy
3
+ *
4
+ * Author: Markku Rossi <mtr@ngs.fi>
5
+ */
6
+
7
+/*
8
+ * This library is free software; you can redistribute it and/or
9
+ * modify it under the terms of the GNU Library General Public
10
+ * License as published by the Free Software Foundation; either
11
+ * version 2 of the License, or (at your option) any later version.
12
+ *
13
+ * This library is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
+ * Library General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU Library General Public
19
+ * License along with this library; if not, write to the Free
20
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
21
+ * MA 02111-1307, USA
22
+ */
23
+
24
+/*
25
+ * $Source: /tmp/cvsroot-15-2-2007/clamav-devel/libclamav/js/b_file.c,v $
26
+ * $Id: b_file.c,v 1.1 2006/10/19 17:28:58 njh Exp $
27
+ */
28
+
29
+/*
30
+ * Static methods.
31
+ *
32
+ *   byteToString (BYTE) => string
33
+ * + chmod (string, int) => boolean
34
+ * + lstat (PATH) => array / boolean
35
+ * + remove (PATH) => boolean
36
+ * + rename (FROM, TO) => boolean
37
+ * + stat (PATH) => array / boolean
38
+ *   stringToByte (STRING) => number
39
+ *
40
+ * Methods:
41
+ *
42
+ *   open (MODE) => boolean
43
+ *   close () => boolean
44
+ *   setPosition (POSITION [, WHENCE]) => boolean
45
+ *   getPosition () => integer
46
+ *   eof () => boolean
47
+ *   read (SIZE) => string
48
+ *   readln () => string
49
+ *   readByte () => integer
50
+ *   write (STRING) => boolean
51
+ *   writeln (STRING) => boolean
52
+ *   writeByte (INTEGER) => boolean
53
+ * + ungetByte (BYTE) => boolean
54
+ *   flush () => boolean
55
+ *   getLength () => integer
56
+ *   exists () => boolean
57
+ *   error () => integer
58
+ *   clearError () => true
59
+ *
60
+ * Properties:
61
+ *
62
+ *   autoFlush	boolean		mutable
63
+ *   bufferSize	integer		mutable
64
+ */
65
+
66
+#include "jsint.h"
67
+
68
+#include <sys/stat.h>
69
+
70
+/*
71
+ * Types and definitions.
72
+ */
73
+
74
+#define INSECURE()		\
75
+  do {				\
76
+    if (secure_mode)		\
77
+      goto insecure_feature;	\
78
+  } while (0)
79
+
80
+/* Class context. */
81
+struct file_ctx_st
82
+{
83
+  /* Static methods. */
84
+  JSSymbol s_byteToString;
85
+  JSSymbol s_chmod;
86
+  JSSymbol s_lstat;
87
+  JSSymbol s_remove;
88
+  JSSymbol s_rename;
89
+  JSSymbol s_stat;
90
+  JSSymbol s_stringToByte;
91
+
92
+  /* Methods */
93
+  JSSymbol s_open;
94
+  JSSymbol s_close;
95
+  JSSymbol s_setPosition;
96
+  JSSymbol s_getPosition;
97
+  JSSymbol s_eof;
98
+  JSSymbol s_read;
99
+  JSSymbol s_readln;
100
+  JSSymbol s_readByte;
101
+  JSSymbol s_write;
102
+  JSSymbol s_writeln;
103
+  JSSymbol s_writeByte;
104
+  JSSymbol s_ungetByte;
105
+  JSSymbol s_flush;
106
+  JSSymbol s_getLength;
107
+  JSSymbol s_exists;
108
+  JSSymbol s_error;
109
+  JSSymbol s_clearError;
110
+
111
+  /* Properties. */
112
+  JSSymbol s_autoFlush;
113
+  JSSymbol s_bufferSize;
114
+};
115
+
116
+typedef struct file_ctx_st FileCtx;
117
+
118
+/* Instance context. */
119
+struct file_instance_ctx_st
120
+{
121
+  /* Flags. */
122
+  unsigned int dont_close : 1;
123
+
124
+  char *path;
125
+  JSIOStream *stream;
126
+
127
+  /* Needed for the delete_proc. */
128
+  JSVirtualMachine *vm;
129
+};
130
+
131
+typedef struct file_instance_ctx_st FileInstanceCtx;
132
+
133
+
134
+/*
135
+ * Static functions.
136
+ */
137
+
138
+/* Method proc. */
139
+static int
140
+method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info,
141
+	void *instance_context, JSSymbol method, JSNode *result_return,
142
+	JSNode *args)
143
+{
144
+  FileCtx *ctx = builtin_info->obj_context;
145
+  FileInstanceCtx *ictx = instance_context;
146
+  char buf[256];
147
+  long int li = 0;
148
+  int i = 0;
149
+  char *cp;
150
+  int secure_mode = vm->security & JS_VM_SECURE_FILE;
151
+
152
+  /* The default result is false. */
153
+  result_return->type = JS_BOOLEAN;
154
+  result_return->u.vboolean = 0;
155
+
156
+  /*
157
+   * Static methods.
158
+   */
159
+  if (method == ctx->s_byteToString)
160
+    {
161
+      if (args->u.vinteger != 1)
162
+	goto argument_error;
163
+
164
+      i = -1;
165
+      if (args[1].type == JS_INTEGER)
166
+	{
167
+	  i = args[1].u.vinteger;
168
+	  if (i < 0 || i > 255)
169
+	    i = -1;
170
+	}
171
+
172
+      js_vm_make_string (vm, result_return, NULL, 1);
173
+
174
+      if (i < 0)
175
+	result_return->u.vstring->len = 0;
176
+      else
177
+	result_return->u.vstring->data[0] = i;
178
+    }
179
+  /* ********************************************************************** */
180
+  else if (method == ctx->s_chmod)
181
+    {
182
+      INSECURE ();
183
+
184
+      if (args->u.vinteger != 2)
185
+	goto argument_error;
186
+      if (args[1].type != JS_STRING)
187
+	goto argument_type_error;
188
+      if (args[2].type != JS_INTEGER)
189
+	goto argument_type_error;
190
+
191
+      result_return->type= JS_BOOLEAN;
192
+
193
+      cp = js_string_to_c_string (vm, &args[1]);
194
+      result_return->u.vboolean = (chmod (cp, args[2].u.vinteger) == 0);
195
+      js_free (cp);
196
+    }
197
+  /* ********************************************************************** */
198
+  else if (method == ctx->s_lstat || method == ctx->s_stat)
199
+    {
200
+      char *path;
201
+      struct stat stat_st;
202
+      int result;
203
+
204
+      INSECURE ();
205
+
206
+      if (args->u.vinteger != 1)
207
+	goto argument_error;
208
+
209
+      path = js_string_to_c_string (vm, &args[1]);
210
+
211
+#if HAVE_LSTAT
212
+      if (method == ctx->s_lstat)
213
+	result = lstat (path, &stat_st);
214
+      else
215
+#endif /* HAVE_LSTAT */
216
+	result = stat (path, &stat_st);
217
+
218
+      js_free (path);
219
+
220
+      if (result >= 0)
221
+	{
222
+	  JSNode *node;
223
+
224
+	  /* Success. */
225
+	  js_vm_make_array (vm, result_return, 13);
226
+	  node = result_return->u.varray->data;
227
+
228
+	  /* dev */
229
+	  node->type = JS_INTEGER;
230
+	  node->u.vinteger = stat_st.st_dev;
231
+	  node++;
232
+
233
+	  /* ino */
234
+	  node->type = JS_INTEGER;
235
+	  node->u.vinteger = stat_st.st_ino;
236
+	  node++;
237
+
238
+	  /* mode */
239
+	  node->type = JS_INTEGER;
240
+	  node->u.vinteger = stat_st.st_mode;
241
+	  node++;
242
+
243
+	  /* nlink */
244
+	  node->type = JS_INTEGER;
245
+	  node->u.vinteger = stat_st.st_nlink;
246
+	  node++;
247
+
248
+	  /* uid */
249
+	  node->type = JS_INTEGER;
250
+	  node->u.vinteger = stat_st.st_uid;
251
+	  node++;
252
+
253
+	  /* gid */
254
+	  node->type = JS_INTEGER;
255
+	  node->u.vinteger = stat_st.st_gid;
256
+	  node++;
257
+
258
+	  /* rdev */
259
+	  node->type = JS_INTEGER;
260
+	  node->u.vinteger = stat_st.st_rdev;
261
+	  node++;
262
+
263
+	  /* size */
264
+	  node->type = JS_INTEGER;
265
+	  node->u.vinteger = stat_st.st_size;
266
+	  node++;
267
+
268
+	  /* atime */
269
+	  node->type = JS_INTEGER;
270
+	  node->u.vinteger = stat_st.st_atime;
271
+	  node++;
272
+
273
+	  /* mtime */
274
+	  node->type = JS_INTEGER;
275
+	  node->u.vinteger = stat_st.st_mtime;
276
+	  node++;
277
+
278
+	  /* ctime */
279
+	  node->type = JS_INTEGER;
280
+	  node->u.vinteger = stat_st.st_ctime;
281
+	  node++;
282
+
283
+	  /* blksize */
284
+	  node->type = JS_INTEGER;
285
+#if HAVE_STAT_ST_ST_BLKSIZE
286
+	  node->u.vinteger = stat_st.st_blksize;
287
+#else /* not HAVE_STAT_ST_ST_BLKSIZE */
288
+	  node->u.vinteger = 0;
289
+#endif /* not HAVE_STAT_ST_ST_BLKSIZE */
290
+	  node++;
291
+
292
+	  /* blocks */
293
+	  node->type = JS_INTEGER;
294
+#if HAVE_STAT_ST_ST_BLOCKS
295
+	  node->u.vinteger = stat_st.st_blocks;
296
+#else /* not HAVE_STAT_ST_ST_BLOCKS */
297
+	  node->u.vinteger = 0;
298
+#endif /* not HAVE_STAT_ST_ST_BLOCKS */
299
+	}
300
+    }
301
+  /* ********************************************************************** */
302
+  else if (method == ctx->s_remove)
303
+    {
304
+      char *path;
305
+
306
+      INSECURE ();
307
+
308
+      if (args->u.vinteger != 1)
309
+	goto argument_error;
310
+
311
+      if (args[1].type != JS_STRING)
312
+	goto argument_type_error;
313
+
314
+      path = js_string_to_c_string (vm, &args[1]);
315
+      i = remove (path);
316
+      js_free (path);
317
+
318
+      result_return->u.vboolean = (i == 0);
319
+    }
320
+  /* ********************************************************************** */
321
+  else if (method == ctx->s_rename)
322
+    {
323
+      char *path1;
324
+      char *path2;
325
+
326
+      INSECURE ();
327
+
328
+      if (args->u.vinteger != 2)
329
+	goto argument_error;
330
+
331
+      if (args[1].type != JS_STRING || args[2].type != JS_STRING)
332
+	goto argument_type_error;
333
+
334
+      path1 = js_string_to_c_string (vm, &args[1]);
335
+      path2 = js_string_to_c_string (vm, &args[2]);
336
+
337
+      i = rename (path1, path2);
338
+
339
+      js_free (path1);
340
+      js_free (path2);
341
+
342
+      result_return->u.vboolean = (i == 0);
343
+    }
344
+  /* ********************************************************************** */
345
+  else if (method == ctx->s_stringToByte)
346
+    {
347
+      if (args->u.vinteger != 1)
348
+	goto argument_error;
349
+
350
+      result_return->type = JS_INTEGER;
351
+
352
+      if (args[1].type == JS_STRING && args[1].u.vstring->len > 0)
353
+	result_return->u.vinteger = args[i].u.vstring->data[0];
354
+      else
355
+	result_return->u.vinteger = 0;
356
+    }
357
+  /* ********************************************************************** */
358
+  else if (method == vm->syms.s_toString)
359
+    {
360
+      if (args->u.vinteger != 0)
361
+	goto argument_error;
362
+
363
+      if (ictx)
364
+	js_vm_make_string (vm, result_return, ictx->path, strlen (ictx->path));
365
+      else
366
+	js_vm_make_static_string (vm, result_return, "File", 4);
367
+    }
368
+  /* ********************************************************************** */
369
+  else if (ictx)
370
+    {
371
+      /*
372
+       * Instance methods.
373
+       */
374
+
375
+      if (method == ctx->s_open)
376
+	{
377
+	  int readp = 0;
378
+	  int writep = 0;
379
+
380
+	  INSECURE ();
381
+
382
+	  if (args->u.vinteger != 1)
383
+	    goto argument_error;
384
+	  if (args[1].type != JS_STRING
385
+	      || args[1].u.vstring->len == 0
386
+	      || args[1].u.vstring->len > 3)
387
+	    goto argument_type_error;
388
+
389
+	  i = args[1].u.vstring->len;
390
+	  memcpy (buf, args[1].u.vstring->data, i);
391
+
392
+	  if (buf[i - 1] != 'b')
393
+	    buf[i++] = 'b';
394
+	  buf[i] = '\0';
395
+
396
+	  /* Check that the mode is valid. */
397
+	  if (strcmp (buf, "rb") == 0)
398
+	    readp = 1;
399
+	  else if (strcmp (buf, "wb") == 0)
400
+	    writep = 1;
401
+	  else if (strcmp (buf, "ab") == 0)
402
+	    writep = 1;
403
+	  else if (strcmp (buf, "r+b") == 0)
404
+	    readp = writep = 1;
405
+	  else if (strcmp (buf, "w+b") == 0)
406
+	    readp = writep = 1;
407
+	  else if (strcmp (buf, "a+b") == 0)
408
+	    readp = writep = 1;
409
+	  else
410
+	    {
411
+	      sprintf (vm->error, "File.%s(): illegal open mode \"%s\"",
412
+		       js_vm_symname (vm, method), buf);
413
+	      js_vm_error (vm);
414
+	    }
415
+
416
+	  if (ictx->stream == NULL)
417
+	    {
418
+	      /* Do open. */
419
+	      JS_VM_ALLOCATE_FD (vm, "File.open()");
420
+	      ictx->stream = js_iostream_file (fopen (ictx->path, buf), readp,
421
+					       writep, 1);
422
+	      if (ictx->stream == NULL)
423
+		JS_VM_FREE_FD (vm);
424
+	      else
425
+		result_return->u.vboolean = 1;
426
+	    }
427
+	}
428
+      /* ***************************************************************** */
429
+      else if (method == ctx->s_close)
430
+	{
431
+	  if (ictx->stream != NULL)
432
+	    {
433
+	      int result = 0;
434
+
435
+	      if (!ictx->dont_close)
436
+		{
437
+		  result = js_iostream_close (ictx->stream);
438
+		  JS_VM_FREE_FD (vm);
439
+		}
440
+
441
+	      ictx->stream = NULL;
442
+	      result_return->u.vboolean = result >= 0;
443
+	    }
444
+	}
445
+      /* ***************************************************************** */
446
+      else if (method == ctx->s_setPosition)
447
+	{
448
+	  if (args->u.vinteger == 1)
449
+	    {
450
+	      if (args[1].type != JS_INTEGER)
451
+		goto argument_type_error;
452
+	      li = args[1].u.vinteger;
453
+	      i = SEEK_SET;
454
+	    }
455
+	  else if (args->u.vinteger == 2)
456
+	    {
457
+	      if (args[2].type == JS_INTEGER)
458
+		{
459
+		  switch (args[2].u.vinteger)
460
+		    {
461
+		    case 1:
462
+		      i = SEEK_CUR;
463
+		      break;
464
+
465
+		    case 2:
466
+		      i = SEEK_END;
467
+		      break;
468
+
469
+		    default:
470
+		      i = SEEK_SET;
471
+		      break;
472
+		    }
473
+		}
474
+	      else
475
+		i = SEEK_SET;
476
+	    }
477
+	  else
478
+	    goto argument_error;
479
+
480
+	  if (ictx->stream && js_iostream_seek (ictx->stream, li, i) >= 0)
481
+	    result_return->u.vboolean = 1;
482
+	}
483
+      /* ***************************************************************** */
484
+      else if (method == ctx->s_getPosition)
485
+	{
486
+	  if (args->u.vinteger != 0)
487
+	    goto argument_error;
488
+
489
+	  result_return->type = JS_INTEGER;
490
+	  if (ictx->stream == NULL)
491
+	    result_return->u.vinteger = -1;
492
+	  else
493
+	    result_return->u.vinteger
494
+	      = js_iostream_get_position (ictx->stream);
495
+	}
496
+      /* ***************************************************************** */
497
+      else if (method == ctx->s_eof)
498
+	{
499
+	  if (args->u.vinteger != 0)
500
+	    goto argument_error;
501
+
502
+	  if (ictx->stream != NULL)
503
+	    result_return->u.vboolean = ictx->stream->at_eof;
504
+	}
505
+      /* ***************************************************************** */
506
+      else if (method == ctx->s_read)
507
+	{
508
+	  size_t got;
509
+	  char *buffer;
510
+
511
+	  if (args->u.vinteger != 1)
512
+	    goto argument_error;
513
+	  if (args[1].type != JS_INTEGER || args[1].u.vinteger < 0)
514
+	    goto argument_type_error;
515
+
516
+	  if (ictx->stream != NULL)
517
+	    {
518
+	      buffer = js_vm_alloc (vm, args[1].u.vinteger + 1);
519
+
520
+	      got = js_iostream_read (ictx->stream, buffer,
521
+				      args[1].u.vinteger);
522
+	      if (got < 0)
523
+		got = 0;
524
+
525
+	      js_vm_make_static_string (vm, result_return, buffer, got);
526
+	      result_return->u.vstring->staticp = 0;
527
+	    }
528
+	}
529
+      /* ***************************************************************** */
530
+      else if (method == ctx->s_readln)
531
+	{
532
+	  int ch;
533
+	  unsigned int bufpos = 0;
534
+	  unsigned int buflen = 0;
535
+	  char *buffer = NULL;
536
+
537
+	  if (args->u.vinteger != 0)
538
+	    goto argument_error;
539
+
540
+	  if (ictx->stream != NULL)
541
+	    {
542
+	      /* Flush all buffered output data. */
543
+	      js_iostream_flush (ictx->stream);
544
+
545
+	      while (1)
546
+		{
547
+		  /* Process all the data we have in the buffer. */
548
+		  for (; ictx->stream->bufpos < ictx->stream->data_in_buf
549
+			 && (ictx->stream->buffer[ictx->stream->bufpos]
550
+			     != '\n');
551
+		       ictx->stream->bufpos++)
552
+		    {
553
+		      if (bufpos >= buflen)
554
+			{
555
+			  buflen += 1024;
556
+			  buffer = js_vm_realloc (vm, buffer, buflen);
557
+			}
558
+		      buffer[bufpos++]
559
+			= ictx->stream->buffer[ictx->stream->bufpos];
560
+		    }
561
+
562
+		  if (ictx->stream->bufpos >= ictx->stream->data_in_buf)
563
+		    {
564
+		      int result;
565
+
566
+		      /* Read past the buffer. */
567
+		      if (ictx->stream->at_eof)
568
+			/* EOF seen. */
569
+			break;
570
+
571
+		      /* Read more data. */
572
+		      js_iostream_fill_buffer (ictx->stream);
573
+		    }
574
+		  else
575
+		    {
576
+		      /* Got it.  Skip the newline character. */
577
+		      ictx->stream->bufpos++;
578
+		      break;
579
+		    }
580
+		}
581
+
582
+	      /* Remove '\r' characters. */
583
+	      while (bufpos > 0)
584
+		if (buffer[bufpos - 1] == '\r')
585
+		  bufpos--;
586
+		else
587
+		  break;
588
+
589
+	      if (buffer == NULL)
590
+		/* An empty string.  Allocate one byte. */
591
+		buffer = js_vm_alloc (vm, 1);
592
+
593
+	      /*
594
+	       * Use the data we already had.  In maximum, it has only
595
+	       * 1023 bytes overhead.
596
+	       */
597
+	      js_vm_make_static_string (vm, result_return, buffer, bufpos);
598
+	      result_return->u.vstring->staticp = 0;
599
+	    }
600
+	}
601
+      /* ***************************************************************** */
602
+      else if (method == ctx->s_readByte)
603
+	{
604
+	  result_return->type = JS_INTEGER;
605
+	  if (ictx->stream == NULL)
606
+	    result_return->u.vinteger = -1;
607
+	  else
608
+	    {
609
+	    retry:
610
+	      if (ictx->stream->bufpos < ictx->stream->data_in_buf)
611
+		result_return->u.vinteger
612
+		  = ictx->stream->buffer[ictx->stream->bufpos++];
613
+	      else
614
+		{
615
+		  if (ictx->stream->at_eof)
616
+		    result_return->u.vinteger = -1;
617
+		  else
618
+		    {
619
+		      js_iostream_fill_buffer (ictx->stream);
620
+		      goto retry;
621
+		    }
622
+		}
623
+	    }
624
+	}
625
+      /* ***************************************************************** */
626
+      else if (method == ctx->s_write || method == ctx->s_writeln)
627
+	{
628
+	  size_t wrote;
629
+	  int autoflush;
630
+
631
+	  if (args->u.vinteger != 1)
632
+	    goto argument_error;
633
+	  if (args[1].type != JS_STRING)
634
+	    goto argument_type_error;
635
+
636
+	  if (ictx->stream != NULL)
637
+	    {
638
+	      autoflush = ictx->stream->autoflush;
639
+	      ictx->stream->autoflush = 0;
640
+
641
+	      wrote = js_iostream_write (ictx->stream,
642
+					 args[1].u.vstring->data,
643
+					 args[1].u.vstring->len);
644
+	      if (wrote == args[1].u.vstring->len)
645
+		{
646
+		  /* Success. */
647
+		  result_return->u.vboolean = 1;
648
+
649
+		  if (method == ctx->s_writeln)
650
+		    if (js_iostream_write (ictx->stream,
651
+					   JS_HOST_LINE_BREAK,
652
+					   JS_HOST_LINE_BREAK_LEN) < 0)
653
+		      /* No, it was not a success. */
654
+		      result_return->u.vboolean = 0;
655
+		}
656
+
657
+	      ictx->stream->autoflush = autoflush;
658
+	      if (autoflush)
659
+		js_iostream_flush (ictx->stream);
660
+	    }
661
+	}
662
+      /* ***************************************************************** */
663
+      else if (method == ctx->s_writeByte)
664
+	{
665
+	  unsigned char buf[1];
666
+
667
+	  if (args->u.vinteger != 1)
668
+	    goto argument_error;
669
+	  if (args[1].type != JS_INTEGER)
670
+	    goto argument_type_error;
671
+
672
+	  buf[0] = args[1].u.vinteger;
673
+
674
+	  if (ictx->stream != NULL)
675
+	    result_return->u.vboolean
676
+	      = js_iostream_write (ictx->stream, buf, 1) >= 0;
677
+	}
678
+      /* ***************************************************************** */
679
+      else if (method == ctx->s_ungetByte)
680
+	{
681
+	  if (args->u.vinteger != 1)
682
+	    goto argument_error;
683
+	  if (args[1].type != JS_INTEGER)
684
+	    goto argument_type_error;
685
+
686
+	  if (ictx->stream != NULL)
687
+	    result_return->u.vboolean
688
+	      = js_iostream_unget (ictx->stream, args[1].u.vinteger);
689
+	}
690
+      /* ***************************************************************** */
691
+      else if (method == ctx->s_flush)
692
+	{
693
+	  if (args->u.vinteger != 0)
694
+	    goto argument_error;
695
+
696
+	  if (ictx->stream != NULL && js_iostream_flush (ictx->stream) >= 0)
697
+	    result_return->u.vboolean = 1;
698
+	}
699
+      /* ***************************************************************** */
700
+      else if (method == ctx->s_getLength)
701
+	{
702
+	  if (args->u.vinteger != 0)
703
+	    goto argument_error;
704
+
705
+	  /* The default error code is an integer -1. */
706
+	  result_return->type = JS_INTEGER;
707
+	  result_return->u.vinteger = -1;
708
+
709
+	  if (ictx->stream != NULL)
710
+	    result_return->u.vinteger
711
+	      = js_iostream_get_length (ictx->stream);
712
+	}
713
+      /* ***************************************************************** */
714
+      else if (method == ctx->s_exists)
715
+	{
716
+	  if (args->u.vinteger != 0)
717
+	    goto argument_error;
718
+
719
+	  if (ictx->stream)
720
+	    {
721
+	      /* Since we have opened the file, it must exist. */
722
+	      result_return->u.vboolean = 1;
723
+	    }
724
+	  else
725
+	    {
726
+	      struct stat stat_st;
727
+
728
+	      if (stat (ictx->path, &stat_st) >= 0)
729
+		result_return->u.vboolean = 1;
730
+	    }
731
+	}
732
+      /* ***************************************************************** */
733
+      else if (method == ctx->s_error)
734
+	{
735
+	  if (args->u.vinteger != 0)
736
+	    goto argument_error;
737
+
738
+	  result_return->type = JS_INTEGER;
739
+	  if (ictx->stream == NULL)
740
+	    result_return->u.vinteger = -1;
741
+	  else
742
+	    result_return->u.vinteger = ictx->stream->error;
743
+	}
744
+      /* ***************************************************************** */
745
+      else if (method == ctx->s_clearError)
746
+	{
747
+	  if (args->u.vinteger != 0)
748
+	    goto argument_error;
749
+
750
+	  if (ictx->stream != NULL)
751
+	    {
752
+	      ictx->stream->error = 0;
753
+	      result_return->u.vboolean = 1;
754
+	    }
755
+	}
756
+      /* ***************************************************************** */
757
+      else
758
+	return JS_PROPERTY_UNKNOWN;
759
+    }
760
+  else
761
+    return JS_PROPERTY_UNKNOWN;
762
+
763
+  return JS_PROPERTY_FOUND;
764
+
765
+
766
+  /*
767
+   * Error handling.
768
+   */
769
+
770
+ argument_error:
771
+  sprintf (vm->error, "File.%s(): illegal amount of arguments",
772
+	   js_vm_symname (vm, method));
773
+  js_vm_error (vm);
774
+
775
+ argument_type_error:
776
+  sprintf (vm->error, "File.%s(): illegal argument",
777
+	   js_vm_symname (vm, method));
778
+  js_vm_error (vm);
779
+
780
+ insecure_feature:
781
+  sprintf (vm->error, "File.%s(): not allowed in secure mode",
782
+	   js_vm_symname (vm, method));
783
+  js_vm_error (vm);
784
+
785
+  /* NOTREACHED */
786
+  return 0;
787
+}
788
+
789
+/* Property proc. */
790
+static int
791
+property (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info,
792
+	  void *instance_context, JSSymbol property, int set, JSNode *node)
793
+{
794
+  FileCtx *ctx = builtin_info->obj_context;
795
+  FileInstanceCtx *ictx = instance_context;
796
+
797
+  if (ictx)
798
+    {
799
+      /* Instance properties. */
800
+      if (property == ctx->s_autoFlush)
801
+	{
802
+	  if (ictx->stream == NULL)
803
+	    goto not_open;
804
+
805
+	  if (set)
806
+	    {
807
+	      if (node->type != JS_BOOLEAN)
808
+		goto argument_type_error;
809
+
810
+	      ictx->stream->autoflush = node->u.vboolean;
811
+	    }
812
+	  else
813
+	    {
814
+	      node->type = JS_BOOLEAN;
815
+	      node->u.vboolean = ictx->stream->autoflush;
816
+	    }
817
+	}
818
+      /* ***************************************************************** */
819
+      else if (property == ctx->s_bufferSize)
820
+	{
821
+	  if (ictx->stream == NULL)
822
+	    goto not_open;
823
+
824
+	  if (set)
825
+	    {
826
+	      unsigned char *buf;
827
+	      unsigned int len;
828
+
829
+	      if (node->type != JS_INTEGER)
830
+		goto argument_type_error;
831
+
832
+	      js_iostream_flush (ictx->stream);
833
+
834
+	      len = node->u.vinteger;
835
+	      buf = js_realloc (vm, ictx->stream->buffer, len);
836
+
837
+	      ictx->stream->buflen = len;
838
+	      ictx->stream->buffer = buf;
839
+	    }
840
+	  else
841
+	    {
842
+	      node->type = JS_INTEGER;
843
+	      node->u.vinteger = ictx->stream->buflen;
844
+	    }
845
+	}
846
+      /* ***************************************************************** */
847
+      else
848
+	{
849
+	  if (!set)
850
+	    node->type = JS_UNDEFINED;
851
+
852
+	  return JS_PROPERTY_UNKNOWN;
853
+	}
854
+    }
855
+  else
856
+    {
857
+      if (!set)
858
+	node->type = JS_UNDEFINED;
859
+
860
+      return JS_PROPERTY_UNKNOWN;
861
+    }
862
+
863
+  return JS_PROPERTY_FOUND;
864
+
865
+
866
+  /* Error handling. */
867
+
868
+ argument_type_error:
869
+  sprintf (vm->error, "File.%s: illegal value",
870
+	   js_vm_symname (vm, property));
871
+  js_vm_error (vm);
872
+
873
+ not_open:
874
+  sprintf (vm->error, "File.%s: the stream is not opened",
875
+	   js_vm_symname (vm, property));
876
+  js_vm_error (vm);
877
+
878
+  /* NOTREACHED */
879
+  return 0;
880
+}
881
+
882
+
883
+/* New proc. */
884
+static void
885
+new_proc (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, JSNode *args,
886
+	  JSNode *result_return)
887
+{
888
+  FileInstanceCtx *instance;
889
+
890
+  if (args->u.vinteger != 1)
891
+    {
892
+      sprintf (vm->error, "new File(): illegal amount of arguments");
893
+      js_vm_error (vm);
894
+    }
895
+  if (args[1].type != JS_STRING)
896
+    {
897
+      sprintf (vm->error, "new File(): illegal argument");
898
+      js_vm_error (vm);
899
+    }
900
+
901
+  instance = js_calloc (vm, 1, sizeof (*instance));
902
+  instance->path = js_string_to_c_string (vm, &args[1]);
903
+  instance->vm = vm;
904
+
905
+  js_vm_builtin_create (vm, result_return, builtin_info, instance);
906
+}
907
+
908
+/* Delete proc. */
909
+static void
910
+delete_proc (JSBuiltinInfo *builtin_info, void *instance_context)
911
+{
912
+  FileInstanceCtx *ictx = instance_context;
913
+
914
+  if (ictx)
915
+    {
916
+      if (ictx->stream)
917
+	{
918
+	  if (!ictx->dont_close)
919
+	    {
920
+	      js_iostream_close (ictx->stream);
921
+	      JS_VM_FREE_FD (ictx->vm);
922
+	    }
923
+
924
+	  ictx->stream = NULL;
925
+	}
926
+
927
+      js_free (ictx->path);
928
+      js_free (ictx);
929
+    }
930
+}
931
+
932
+/*
933
+ * Global functions.
934
+ */
935
+
936
+void
937
+js_builtin_File (JSVirtualMachine *vm)
938
+{
939
+  JSNode *n;
940
+  JSBuiltinInfo *info;
941
+  FileCtx *ctx;
942
+
943
+  ctx = js_calloc (vm, 1, sizeof (*ctx));
944
+
945
+  ctx->s_byteToString	= js_vm_intern (vm, "byteToString");
946
+  ctx->s_chmod		= js_vm_intern (vm, "chmod");
947
+  ctx->s_lstat		= js_vm_intern (vm, "lstat");
948
+  ctx->s_remove		= js_vm_intern (vm, "remove");
949
+  ctx->s_rename		= js_vm_intern (vm, "rename");
950
+  ctx->s_stat		= js_vm_intern (vm, "stat");
951
+  ctx->s_stringToByte	= js_vm_intern (vm, "stringToByte");
952
+
953
+  ctx->s_open		= js_vm_intern (vm, "open");
954
+  ctx->s_close		= js_vm_intern (vm, "close");
955
+  ctx->s_setPosition	= js_vm_intern (vm, "setPosition");
956
+  ctx->s_getPosition	= js_vm_intern (vm, "getPosition");
957
+  ctx->s_eof		= js_vm_intern (vm, "eof");
958
+  ctx->s_read		= js_vm_intern (vm, "read");
959
+  ctx->s_readln		= js_vm_intern (vm, "readln");
960
+  ctx->s_readByte	= js_vm_intern (vm, "readByte");
961
+  ctx->s_write		= js_vm_intern (vm, "write");
962
+  ctx->s_writeln	= js_vm_intern (vm, "writeln");
963
+  ctx->s_writeByte	= js_vm_intern (vm, "writeByte");
964
+  ctx->s_ungetByte	= js_vm_intern (vm, "ungetByte");
965
+  ctx->s_flush		= js_vm_intern (vm, "flush");
966
+  ctx->s_getLength	= js_vm_intern (vm, "getLength");
967
+  ctx->s_exists		= js_vm_intern (vm, "exists");
968
+  ctx->s_error		= js_vm_intern (vm, "error");
969
+  ctx->s_clearError	= js_vm_intern (vm, "clearError");
970
+
971
+  ctx->s_autoFlush	= js_vm_intern (vm, "autoFlush");
972
+  ctx->s_bufferSize	= js_vm_intern (vm, "bufferSize");
973
+
974
+
975
+  /* Object information. */
976
+
977
+  info = js_vm_builtin_info_create (vm);
978
+
979
+  info->method_proc 		= method;
980
+  info->property_proc 		= property;
981
+  info->new_proc 		= new_proc;
982
+  info->delete_proc 		= delete_proc;
983
+  info->obj_context 		= ctx;
984
+  info->obj_context_delete	= js_free;
985
+
986
+  /* Define it. */
987
+  n = &vm->globals[js_vm_intern (vm, "File")];
988
+  js_vm_builtin_create (vm, n, info, NULL);
989
+}
990
+
991
+
992
+void
993
+js_builtin_File_new (JSVirtualMachine *vm, JSNode *result_return,
994
+		     char *path, JSIOStream *stream, int dont_close)
995
+{
996
+  JSNode *n;
997
+  FileInstanceCtx *ictx;
998
+
999
+  /* Lookup our context. */
1000
+  n = &vm->globals[js_vm_intern (vm, "File")];
1001
+
1002
+  /* Create a file instance. */
1003
+  ictx = js_calloc (vm, 1, sizeof (*ictx));
1004
+  ictx->path = js_strdup (vm, path);
1005
+  ictx->stream = stream;
1006
+  ictx->dont_close = dont_close;
1007
+  ictx->vm = vm;
1008
+
1009
+  /* Create the builtin. */
1010
+  js_vm_builtin_create (vm, result_return, n->u.vbuiltin->info, ictx);
1011
+}
0 1012
new file mode 100644
... ...
@@ -0,0 +1,78 @@
0
+/*
1
+ * The builtin Function object.
2
+ * Copyright (c) 1998 New Generation Software (NGS) Oy
3
+ *
4
+ * Author: Markku Rossi <mtr@ngs.fi>
5
+ */
6
+
7
+/*
8
+ * This library is free software; you can redistribute it and/or
9
+ * modify it under the terms of the GNU Library General Public
10
+ * License as published by the Free Software Foundation; either
11
+ * version 2 of the License, or (at your option) any later version.
12
+ *
13
+ * This library is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
+ * Library General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU Library General Public
19
+ * License along with this library; if not, write to the Free
20
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
21
+ * MA 02111-1307, USA
22
+ */
23
+
24
+/*
25
+ * $Source: /tmp/cvsroot-15-2-2007/clamav-devel/libclamav/js/b_func.c,v $
26
+ * $Id: b_func.c,v 1.1 2006/10/19 17:28:58 njh Exp $
27
+ */
28
+
29
+#include "jsint.h"
30
+
31
+/*
32
+ * Static functions.
33
+ */
34
+
35
+/* Method proc. */
36
+static int
37
+method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info,
38
+	void *instance_context, JSSymbol method, JSNode *result_return,
39
+	JSNode *args)
40
+{
41
+  return JS_PROPERTY_UNKNOWN;
42
+}
43
+
44
+/* Property proc. */
45
+static int
46
+property (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info,
47
+	  void *instance_context, JSSymbol property, int set, JSNode *node)
48
+{
49
+  JSNode *n = instance_context;
50
+
51
+  if (!set)
52
+    node->type = JS_UNDEFINED;
53
+
54
+  return JS_PROPERTY_UNKNOWN;
55
+}
56
+
57
+
58
+/*
59
+ * Global functions.
60
+ */
61
+
62
+void
63
+js_builtin_Function (JSVirtualMachine *vm)
64
+{
65
+  JSNode *n;
66
+  JSBuiltinInfo *info;
67
+
68
+  info = js_vm_builtin_info_create (vm);
69
+  vm->prim[JS_FUNC] = info;
70
+
71
+  info->method_proc	= method;
72
+  info->property_proc	= property;
73
+
74
+  /* Define it. */
75
+  n = &vm->globals[js_vm_intern (vm, "Function")];
76
+  js_vm_builtin_create (vm, n, info, NULL);
77
+}
0 78
new file mode 100644
... ...
@@ -0,0 +1,511 @@
0
+/*
1
+ * The builtin Math object.
2
+ * Copyright (c) 1998 New Generation Software (NGS) Oy
3
+ *
4
+ * Author: Markku Rossi <mtr@ngs.fi>
5
+ */
6
+
7
+/*
8
+ * This library is free software; you can redistribute it and/or
9
+ * modify it under the terms of the GNU Library General Public
10
+ * License as published by the Free Software Foundation; either
11
+ * version 2 of the License, or (at your option) any later version.
12
+ *
13
+ * This library is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
+ * Library General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU Library General Public
19
+ * License along with this library; if not, write to the Free
20
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
21
+ * MA 02111-1307, USA
22
+ */
23
+
24
+/*
25
+ * $Source: /tmp/cvsroot-15-2-2007/clamav-devel/libclamav/js/b_math.c,v $
26
+ * $Id: b_math.c,v 1.1 2006/10/19 17:28:58 njh Exp $
27
+ */
28
+
29
+#include "jsint.h"
30
+#include "rentrant.h"
31
+
32
+/*
33
+ * Types and definitions.
34
+ */
35
+
36
+#ifndef M_E
37
+#define M_E		2.71828182845904523536028747135266250
38
+#endif
39
+
40
+#ifndef M_LN10
41
+#define M_LN10		2.302585092994046
42
+#endif
43
+
44
+#ifndef M_LN2
45
+#define M_LN2		0.693147180559945309417232121458176568
46
+#endif
47
+
48
+#ifndef M_LOG10E
49
+#define M_LOG10E	0.434294481903251827651128918916605082
50
+#endif
51
+
52
+#ifndef M_LOG2E
53
+#define M_LOG2E		1.44269504088896340735992468100189214
54
+#endif
55
+
56
+#ifndef M_PI
57
+#define M_PI		3.14159265358979323846264338327950288
58
+#endif
59
+
60
+#ifndef M_SQRT1_2
61
+#define M_SQRT1_2	0.707106781186547524400844362104849039
62
+#endif
63
+
64
+#ifndef M_SQRT2
65
+#define M_SQRT2		1.41421356237309504880168872420969808
66
+#endif
67
+
68
+
69
+#define ONE_ARG()				\
70
+  do {						\
71
+    JSNode cvt;					\
72
+						\
73
+    if (args->u.vinteger != 1)			\
74
+      goto argument_error;			\
75
+						\
76
+    js_vm_to_number (vm, &args[1], &cvt);	\
77
+    if (cvt.type == JS_INTEGER)			\
78
+      d = (double) cvt.u.vinteger;		\
79
+    else if (cvt.type == JS_FLOAT)		\
80
+      d = cvt.u.vfloat;				\
81
+    else					\
82
+      {						\
83
+	/* Must be NaN. */			\
84
+	result_return->type = JS_NAN;		\
85
+	goto done;				\
86
+      }						\
87
+  } while (0)
88
+
89
+#define TWO_ARGS()				\
90
+  do {						\
91
+    JSNode cvt;					\
92
+						\
93
+    if (args->u.vinteger != 2)			\
94
+      goto argument_error;			\
95
+						\
96
+    js_vm_to_number (vm, &args[1], &cvt);	\
97
+    if (cvt.type == JS_INTEGER)			\
98
+      d = (double) cvt.u.vinteger;		\
99
+    else if (cvt.type == JS_FLOAT)		\
100
+      d = cvt.u.vfloat;				\
101
+    else					\
102
+      {						\
103
+	/* Must be NaN. */			\
104
+	result_return->type = JS_NAN;		\
105
+	goto done;				\
106
+      }						\
107
+						\
108
+    js_vm_to_number (vm, &args[2], &cvt);	\
109
+    if (cvt.type == JS_INTEGER)			\
110
+      d2 = (double) args[1].u.vinteger;		\
111
+    else if (cvt.type == JS_FLOAT)		\
112
+      d2 = cvt.u.vfloat;			\
113
+    else					\
114
+      {						\
115
+	/* Must be NaN. */			\
116
+	result_return->type = JS_NAN;		\
117
+	goto done;				\
118
+      }						\
119
+						\
120
+  } while (0)
121
+
122
+/* Class context. */
123
+struct math_ctx_st
124
+{
125
+  JSSymbol s_abs;
126
+  JSSymbol s_acos;
127
+  JSSymbol s_asin;
128
+  JSSymbol s_atan;
129
+  JSSymbol s_atan2;
130
+  JSSymbol s_ceil;
131
+  JSSymbol s_cos;
132
+  JSSymbol s_exp;
133
+  JSSymbol s_floor;
134
+  JSSymbol s_log;
135
+  JSSymbol s_max;
136
+  JSSymbol s_min;
137
+  JSSymbol s_pow;
138
+  JSSymbol s_random;
139
+  JSSymbol s_round;
140
+  JSSymbol s_seed;
141
+  JSSymbol s_sin;
142
+  JSSymbol s_sqrt;
143
+  JSSymbol s_tan;
144
+
145
+  JSSymbol s_E;
146
+  JSSymbol s_LN10;
147
+  JSSymbol s_LN2;
148
+  JSSymbol s_LOG10E;
149
+  JSSymbol s_LOG2E;
150
+  JSSymbol s_PI;
151
+  JSSymbol s_SQRT1_2;
152
+  JSSymbol s_SQRT2;
153
+
154
+  void *drand48_context;
155
+};
156
+
157
+typedef struct math_ctx_st MathCtx;
158
+
159
+/*
160
+ * Static functions.
161
+ */
162
+
163
+/* Method proc. */
164
+static int
165
+method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info,
166
+	void *instance_context, JSSymbol method, JSNode *result_return,
167
+	JSNode *args)
168
+{
169
+  MathCtx *ctx = builtin_info->obj_context;
170
+  double d, d2;
171
+  int i;
172
+
173
+  /* The default return value. */
174
+  result_return->type = JS_FLOAT;
175
+
176
+  if (method == ctx->s_abs)
177
+    {
178
+      ONE_ARG ();
179
+      result_return->u.vfloat = fabs (d);
180
+    }
181
+  /* ********************************************************************** */
182
+  else if (method == ctx->s_acos)
183
+    {
184
+      ONE_ARG ();
185
+      result_return->u.vfloat = acos (d);
186
+    }
187
+  /* ********************************************************************** */
188
+  else if (method == ctx->s_asin)
189
+    {
190
+      ONE_ARG ();
191
+      result_return->u.vfloat = asin (d);
192
+    }
193
+  /* ********************************************************************** */
194
+  else if (method == ctx->s_atan)
195
+    {
196
+      ONE_ARG ();
197
+      result_return->u.vfloat = atan (d);
198
+    }
199
+  /* ********************************************************************** */
200
+  else if (method == ctx->s_atan2)
201
+    {
202
+      TWO_ARGS ();
203
+      result_return->u.vfloat = atan2 (d, d2);
204
+    }
205
+  /* ********************************************************************** */
206
+  else if (method == ctx->s_ceil)
207
+    {
208
+      ONE_ARG ();
209
+      result_return->u.vfloat = ceil (d);
210
+    }
211
+  /* ********************************************************************** */
212
+  else if (method == ctx->s_cos)
213
+    {
214
+      ONE_ARG ();
215
+      result_return->u.vfloat = cos (d);
216
+    }
217
+  /* ********************************************************************** */
218
+  else if (method == ctx->s_exp)
219
+    {
220
+      ONE_ARG ();
221
+      result_return->u.vfloat = exp (d);
222
+    }
223
+  /* ********************************************************************** */
224
+  else if (method == ctx->s_floor)
225
+    {
226
+      ONE_ARG ();
227
+      result_return->u.vfloat = floor (d);
228
+    }
229
+  /* ********************************************************************** */
230
+  else if (method == ctx->s_log)
231
+    {
232
+      ONE_ARG ();
233
+      result_return->u.vfloat = log (d);
234
+    }
235
+  /* ********************************************************************** */
236
+  else if (method == ctx->s_max || method == ctx->s_min)
237
+    {
238
+      JSNode cvt;
239
+
240
+      if (args->u.vinteger < 1)
241
+	goto argument_error;
242
+
243
+      /* Take the initial argument. */
244
+      js_vm_to_number (vm, &args[1], &cvt);
245
+      if (cvt.type == JS_NAN)
246
+	{
247
+	  result_return->type = JS_NAN;
248
+	  goto done;
249
+	}
250
+      if (cvt.type == JS_INTEGER)
251
+	d = (double) cvt.u.vinteger;
252
+      else
253
+	d = cvt.u.vfloat;
254
+
255
+      /* Handle the rest. */
256
+      for (i = 1; i < args->u.vinteger; i++)
257
+	{
258
+	  js_vm_to_number (vm, &args[1], &cvt);
259
+	  if (cvt.type == JS_NAN)
260
+	    {
261
+	      result_return->type = JS_NAN;
262
+	      goto done;
263
+	    }
264
+	  if (cvt.type == JS_INTEGER)
265
+	    d2 = (double) cvt.u.vinteger;
266
+	  else
267
+	    d2 = cvt.u.vfloat;
268
+
269
+	  if (method == ctx->s_max)
270
+	    {
271
+	      if (d2 > d)
272
+		d = d2;
273
+	    }
274
+	  else
275
+	    {
276
+	      if (d2 < d)
277
+		d = d2;
278
+	    }
279
+	}
280
+
281
+      result_return->type = JS_FLOAT;
282
+      result_return->u.vfloat = d;
283
+    }
284
+  /* ********************************************************************** */
285
+  else if (method == ctx->s_pow)
286
+    {
287
+      TWO_ARGS ();
288
+      result_return->u.vfloat = pow (d, d2);
289
+    }
290
+  /* ********************************************************************** */
291
+  else if (method == ctx->s_random)
292
+    {
293
+      if (args->u.vinteger != 0)
294
+	goto argument_error;
295
+
296
+      /* js_srand48 (ctx->drand48_context, time (NULL)); */
297
+      js_drand48 (ctx->drand48_context, &result_return->u.vfloat);
298
+    }
299
+  /* ********************************************************************** */
300
+  else if (method == ctx->s_round)
301
+    {
302
+      ONE_ARG ();
303
+      result_return->type = JS_INTEGER;
304
+      result_return->u.vinteger = (long) (d + 0.5);
305
+    }
306
+  /* ********************************************************************** */
307
+  else if (method == ctx->s_seed)
308
+    {
309
+      ONE_ARG ();
310
+      js_srand48 (ctx->drand48_context, (long) d);
311
+      result_return->type = JS_UNDEFINED;
312
+    }
313
+  /* ********************************************************************** */
314
+  else if (method == ctx->s_sin)
315
+    {
316
+      ONE_ARG ();
317
+      result_return->u.vfloat = sin (d);
318
+    }
319
+  /* ********************************************************************** */
320
+  else if (method == ctx->s_sqrt)
321
+    {
322
+      ONE_ARG ();
323
+      result_return->u.vfloat = sqrt (d);
324
+    }
325
+  /* ********************************************************************** */
326
+  else if (method == ctx->s_tan)
327
+    {
328
+      ONE_ARG ();
329
+      result_return->u.vfloat = tan (d);
330
+    }
331
+  /* ********************************************************************** */
332
+  else if (method == vm->syms.s_toString)
333
+    {
334
+      js_vm_make_static_string (vm, result_return, "Math", 4);
335
+    }
336
+  /* ********************************************************************** */
337
+  else
338
+    return JS_PROPERTY_UNKNOWN;
339
+
340
+ done:
341
+
342
+  return JS_PROPERTY_FOUND;
343
+
344
+
345
+  /*
346
+   * Error handling.
347
+   */
348
+
349
+ argument_error:
350
+  sprintf (vm->error, "Math.%s(): illegal amount of arguments",
351
+	   js_vm_symname (vm, method));
352
+  js_vm_error (vm);
353
+
354
+ argument_type_error:
355
+  sprintf (vm->error, "Math.%s(): illegal argument",
356
+	   js_vm_symname (vm, method));
357
+  js_vm_error (vm);
358
+
359
+  /* NOTREACHED. */
360
+  return 0;
361
+}
362
+
363
+/* Property proc. */
364
+static int
365
+property (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info,
366
+	  void *instance_context, JSSymbol property, int set, JSNode *node)
367
+{
368
+  MathCtx *ctx = builtin_info->obj_context;
369
+
370
+  /* The default result is float. */
371
+  node->type = JS_FLOAT;
372
+
373
+  if (property == ctx->s_E)
374
+    {
375
+      if (set)
376
+	goto immutable;
377
+
378
+      node->u.vfloat = M_E;
379
+    }
380
+  else if (property == ctx->s_LN10)
381
+    {
382
+      if (set)
383
+	goto immutable;
384
+
385
+      node->u.vfloat = M_LN10;
386
+    }
387
+  else if (property == ctx->s_LN2)
388
+    {
389
+      if (set)
390
+	goto immutable;
391
+
392
+      node->u.vfloat = M_LN2;
393
+    }
394
+  else if (property == ctx->s_LOG10E)
395
+    {
396
+      if (set)
397
+	goto immutable;
398
+
399
+      node->u.vfloat = M_LOG10E;
400
+    }
401
+  else if (property == ctx->s_LOG2E)
402
+    {
403
+      if (set)
404
+	goto immutable;
405
+
406
+      node->u.vfloat = M_LOG2E;
407
+    }
408
+  else if (property == ctx->s_PI)
409
+    {
410
+      if (set)
411
+	goto immutable;
412
+
413
+      node->u.vfloat = M_PI;
414
+    }
415
+  else if (property == ctx->s_SQRT1_2)
416
+    {
417
+      if (set)
418
+	goto immutable;
419
+
420
+      node->u.vfloat = M_SQRT1_2;
421
+    }
422
+  else if (property == ctx->s_SQRT2)
423
+    {
424
+      if (set)
425
+	goto immutable;
426
+
427
+      node->u.vfloat = M_SQRT2;
428
+    }
429
+  else
430
+    {
431
+      if (!set)
432
+	node->type = JS_UNDEFINED;
433
+
434
+      return JS_PROPERTY_UNKNOWN;
435
+    }
436
+
437
+  return JS_PROPERTY_FOUND;
438
+
439
+
440
+  /*
441
+   * Error handling.
442
+   */
443
+
444
+ immutable:
445
+  sprintf (vm->error, "Math.%s: immutable property",
446
+	   js_vm_symname (vm, property));
447
+  js_vm_error (vm);
448
+
449
+  /* NOTREACHED. */
450
+  return 0;
451
+}
452
+
453
+
454
+/*
455
+ * Global functions.
456
+ */
457
+
458
+void
459
+js_builtin_Math (JSVirtualMachine *vm)
460
+{
461
+  JSBuiltinInfo *info;
462
+  MathCtx *ctx;
463
+  JSNode *n;
464
+
465
+  ctx = js_calloc (vm, 1, sizeof (*ctx));
466
+
467
+  ctx->s_abs		= js_vm_intern (vm, "abs");
468
+  ctx->s_acos		= js_vm_intern (vm, "acos");
469
+  ctx->s_asin		= js_vm_intern (vm, "asin");
470
+  ctx->s_atan		= js_vm_intern (vm, "atan");
471
+  ctx->s_atan2		= js_vm_intern (vm, "atan2");
472
+  ctx->s_ceil		= js_vm_intern (vm, "ceil");
473
+  ctx->s_cos		= js_vm_intern (vm, "cos");
474
+  ctx->s_exp		= js_vm_intern (vm, "exp");
475
+  ctx->s_floor		= js_vm_intern (vm, "floor");
476
+  ctx->s_log		= js_vm_intern (vm, "log");
477
+  ctx->s_max		= js_vm_intern (vm, "max");
478
+  ctx->s_min		= js_vm_intern (vm, "min");
479
+  ctx->s_pow		= js_vm_intern (vm, "pow");
480
+  ctx->s_random		= js_vm_intern (vm, "random");
481
+  ctx->s_round		= js_vm_intern (vm, "round");
482
+  ctx->s_seed		= js_vm_intern (vm, "seed");
483
+  ctx->s_sin		= js_vm_intern (vm, "sin");
484
+  ctx->s_sqrt		= js_vm_intern (vm, "sqrt");
485
+  ctx->s_tan		= js_vm_intern (vm, "tan");
486
+
487
+  ctx->s_E		= js_vm_intern (vm, "E");
488
+  ctx->s_LN10		= js_vm_intern (vm, "LN10");
489
+  ctx->s_LN2		= js_vm_intern (vm, "LN2");
490
+  ctx->s_LOG10E		= js_vm_intern (vm, "LOG10E");
491
+  ctx->s_LOG2E		= js_vm_intern (vm, "LOG2E");
492
+  ctx->s_PI		= js_vm_intern (vm, "PI");
493
+  ctx->s_SQRT1_2	= js_vm_intern (vm, "SQRT1_2");
494
+  ctx->s_SQRT2		= js_vm_intern (vm, "SQRT2");
495
+
496
+  ctx->drand48_context = js_drand48_create (vm);
497
+
498
+  /* Object information. */
499
+
500
+  info = js_vm_builtin_info_create (vm);
501
+
502
+  info->method_proc		= method;
503
+  info->property_proc		= property;
504
+  info->obj_context		= ctx;
505
+  info->obj_context_delete	= js_free;
506
+
507
+  /* Define it. */
508
+  n = &vm->globals[js_vm_intern (vm, "Math")];
509
+  js_vm_builtin_create (vm, n, info, NULL);
510
+}
0 511
new file mode 100644
... ...
@@ -0,0 +1,320 @@
0
+/*
1
+ * The builtin Number object.
2
+ * Copyright (c) 1998 New Generation Software (NGS) Oy
3
+ *
4
+ * Author: Markku Rossi <mtr@ngs.fi>
5
+ */
6
+
7
+/*
8
+ * This library is free software; you can redistribute it and/or
9
+ * modify it under the terms of the GNU Library General Public
10
+ * License as published by the Free Software Foundation; either
11
+ * version 2 of the License, or (at your option) any later version.
12
+ *
13
+ * This library is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
+ * Library General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU Library General Public
19
+ * License along with this library; if not, write to the Free
20
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
21
+ * MA 02111-1307, USA
22
+ */
23
+
24
+/*
25
+ * $Source: /tmp/cvsroot-15-2-2007/clamav-devel/libclamav/js/b_number.c,v $
26
+ * $Id: b_number.c,v 1.1 2006/10/19 17:28:58 njh Exp $
27
+ */
28
+
29
+/*
30
+ * Standard: ECMAScript-2.0.draft-22-Apr-98
31
+ */
32
+
33
+#include "jsint.h"
34
+
35
+/*
36
+ * Types and definitions.
37
+ */
38
+
39
+/* Class context. */
40
+struct number_ctx_st
41
+{
42
+  JSSymbol s_MAX_VALUE;
43
+  JSSymbol s_MIN_VALUE;
44
+  JSSymbol s_NaN;
45
+  JSSymbol s_NEGATIVE_INFINITY;
46
+  JSSymbol s_POSITIVE_INFINITY;
47
+};
48
+
49
+typedef struct number_ctx_st NumberCtx;
50
+
51
+
52
+/*
53
+ * Static functions.
54
+ */
55
+
56
+/* Global method proc. */
57
+static void
58
+global_method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info,
59
+	       void *instance_context, JSNode *result_return,
60
+	       JSNode *args)
61
+{
62
+  if (args->u.vinteger == 0)
63
+    {
64
+      result_return->type = JS_INTEGER;
65
+      result_return->u.vinteger = 0;
66
+    }
67
+  else if (args->u.vinteger == 1)
68
+    {
69
+      js_vm_to_number (vm, &args[1], result_return);
70
+    }
71
+  else
72
+    {
73
+      sprintf (vm->error, "Number(): illegal amount of arguments");
74
+      js_vm_error (vm);
75
+    }
76
+}
77
+
78
+/* Method proc. */
79
+static int
80
+method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info,
81
+	void *instance_context, JSSymbol method, JSNode *result_return,
82
+	JSNode *args)
83
+{
84
+  JSNode *n = instance_context;
85
+  char buf[256];
86
+
87
+  if (method == vm->syms.s_toString)
88
+    {
89
+      if (n)
90
+	{
91
+	  int radix = 10;
92
+
93
+	  if (args->u.vinteger == 0)
94
+	    ;
95
+	  else if (args->u.vinteger == 1)
96
+	    {
97
+	      if (args[1].type != JS_INTEGER)
98
+		goto argument_type_error;
99
+
100
+	      radix = args[1].u.vinteger;
101
+	    }
102
+	  else
103
+	    goto argument_error;
104
+
105
+	  if (n->type == JS_INTEGER)
106
+	    {
107
+	      switch (radix)
108
+		{
109
+		case 2:
110
+		  {
111
+		    char buf2[256];
112
+		    int i;
113
+		    unsigned int bit = 1;
114
+		    unsigned long ul = (unsigned long) n->u.vinteger;
115
+
116
+		    for (i = 0; bit > 0; bit <<= 1, i++)
117
+		      buf2[i] = (ul & bit) ? '1' : '0';
118
+
119
+		    for (i--; i > 0 && buf2[i] == '0'; i--)
120
+		      ;
121
+
122
+		    bit = i;
123
+		    for (; i >= 0; i--)
124
+		      buf[bit - i] = buf2[i];
125
+		    buf[bit + 1] = '\0';
126
+		  }
127
+		  break;
128
+
129
+		case 8:
130
+		  sprintf (buf, "%lo", (unsigned long) n->u.vinteger);
131
+		  break;
132
+
133
+		case 10:
134
+		  sprintf (buf, "%ld", n->u.vinteger);
135
+		  break;
136
+
137
+		case 16:
138
+		  sprintf (buf, "%lx", (unsigned long) n->u.vinteger);
139
+		  break;
140
+
141
+		default:
142
+		  sprintf (vm->error, "Number.%s(): illegal radix %d",
143
+			   js_vm_symname (vm, method), radix);
144
+		  js_vm_error (vm);
145
+		  break;
146
+		}
147
+	    }
148
+	  else if (n->type == JS_FLOAT)
149
+	    sprintf (buf, "%g", n->u.vfloat);
150
+	  else
151
+	    sprintf (buf, "NaN");
152
+
153
+	  js_vm_make_string (vm, result_return, buf, strlen (buf));
154
+	}
155
+      else
156
+	{
157
+	  if (args->u.vinteger != 0)
158
+	    goto argument_error;
159
+	  js_vm_make_static_string (vm, result_return, "Number", 6);
160
+	}
161
+    }
162
+  /* ********************************************************************** */
163
+  else if (method == vm->syms.s_valueOf)
164
+    {
165
+      if (n == NULL)
166
+	n = &vm->globals[js_vm_intern (vm, "Number")];
167
+
168
+      JS_COPY (result_return, n);
169
+    }
170
+  /* ********************************************************************** */
171
+  else
172
+    return JS_PROPERTY_UNKNOWN;
173
+
174
+  return JS_PROPERTY_FOUND;
175
+
176
+
177
+  /*
178
+   * Error handling.
179
+   */
180
+
181
+ argument_error:
182
+  sprintf (vm->error, "Number.%s(): illegal amount of arguments",
183
+	   js_vm_symname (vm, method));
184
+  js_vm_error (vm);
185
+
186
+ argument_type_error:
187
+  sprintf (vm->error, "Number.%s(): illegal argument",
188
+	   js_vm_symname (vm, method));
189
+  js_vm_error (vm);
190
+
191
+  /* NOTREACHED */
192
+  return 0;
193
+}
194
+
195
+/* Property proc. */
196
+static int
197
+property (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info,
198
+	  void *instance_context, JSSymbol property, int set, JSNode *node)
199
+{
200
+  NumberCtx *ctx = builtin_info->obj_context;
201
+
202
+  /* The default result type. */
203
+  node->type = JS_FLOAT;
204
+
205
+  if (property == ctx->s_MAX_VALUE)
206
+    {
207
+      if (set)
208
+	goto immutable;
209
+
210
+      node->u.vfloat = DBL_MAX;
211
+    }
212
+  else if (property == ctx->s_MIN_VALUE)
213
+    {
214
+      if (set)
215
+	goto immutable;
216
+
217
+      node->u.vfloat = DBL_MIN;
218
+    }
219
+  else if (property == ctx->s_NaN)
220
+    {
221
+      if (set)
222
+	goto immutable;
223
+
224
+      node->type = JS_NAN;
225
+    }
226
+  else if (property == ctx->s_NEGATIVE_INFINITY)
227
+    {
228
+      if (set)
229
+	goto immutable;
230
+
231
+      JS_MAKE_NEGATIVE_INFINITY (node);
232
+    }
233
+  else if (property == ctx->s_POSITIVE_INFINITY)
234
+    {
235
+      if (set)
236
+	goto immutable;
237
+
238
+      JS_MAKE_POSITIVE_INFINITY (node);
239
+    }
240
+  else
241
+    {
242
+      if (!set)
243
+	node->type = JS_UNDEFINED;
244
+
245
+      return JS_PROPERTY_UNKNOWN;
246
+    }
247
+
248
+  return JS_PROPERTY_FOUND;
249
+
250
+
251
+  /*
252
+   * Error handling.
253
+   */
254
+
255
+ immutable:
256
+  sprintf (vm->error, "Number.%s: immutable property",
257
+	   js_vm_symname (vm, property));
258
+  js_vm_error (vm);
259
+
260
+  /* NOTREACHED */
261
+  return 0;
262
+}
263
+
264
+/* New proc. */
265
+static void
266
+new_proc (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, JSNode *args,
267
+	  JSNode *result_return)
268
+{
269
+  if (args->u.vinteger == 0)
270
+    {
271
+      result_return->type = JS_INTEGER;
272
+      result_return->u.vinteger = 0;
273
+    }
274
+  else if (args->u.vinteger == 1)
275
+    {
276
+      js_vm_to_number (vm, &args[1], result_return);
277
+    }
278
+  else
279
+    {
280
+      sprintf (vm->error, "new Number(): illegal amount of arguments");
281
+      js_vm_error (vm);
282
+    }
283
+}
284
+
285
+/*
286
+ * Global functions.
287
+ */
288
+
289
+void
290
+js_builtin_Number (JSVirtualMachine *vm)
291
+{
292
+  NumberCtx *ctx;
293
+  JSNode *n;
294
+  JSBuiltinInfo *info;
295
+
296
+  ctx = js_calloc (vm, 1, sizeof (*ctx));
297
+
298
+  ctx->s_MAX_VALUE		= js_vm_intern (vm, "MAX_VALUE");
299
+  ctx->s_MIN_VALUE		= js_vm_intern (vm, "MIN_VALUE");
300
+  ctx->s_NaN			= js_vm_intern (vm, "NaN");
301
+  ctx->s_NEGATIVE_INFINITY	= js_vm_intern (vm, "NEGATIVE_INFINITY");
302
+  ctx->s_POSITIVE_INFINITY	= js_vm_intern (vm, "POSITIVE_INFINITY");
303
+
304
+  info = js_vm_builtin_info_create (vm);
305
+  vm->prim[JS_INTEGER]	= info;
306
+  vm->prim[JS_FLOAT]	= info;
307
+  vm->prim[JS_NAN]	= info;
308
+
309
+  info->global_method_proc	= global_method;
310
+  info->method_proc 		= method;
311
+  info->property_proc		= property;
312
+  info->new_proc		= new_proc;
313
+  info->obj_context		= ctx;
314
+  info->obj_context_delete	= js_free;
315
+
316
+  /* Define it. */
317
+  n = &vm->globals[js_vm_intern (vm, "Number")];
318
+  js_vm_builtin_create (vm, n, info, NULL);
319
+}
0 320
new file mode 100644
... ...
@@ -0,0 +1,195 @@
0
+/*
1
+ * The builtin Object object.
2
+ * Copyright (c) 1998 New Generation Software (NGS) Oy
3
+ *
4
+ * Author: Markku Rossi <mtr@ngs.fi>
5
+ */
6
+
7
+/*
8
+ * This library is free software; you can redistribute it and/or
9
+ * modify it under the terms of the GNU Library General Public
10
+ * License as published by the Free Software Foundation; either
11
+ * version 2 of the License, or (at your option) any later version.
12
+ *
13
+ * This library is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
+ * Library General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU Library General Public
19
+ * License along with this library; if not, write to the Free
20
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
21
+ * MA 02111-1307, USA
22
+ */
23
+
24
+/*
25
+ * $Source: /tmp/cvsroot-15-2-2007/clamav-devel/libclamav/js/b_object.c,v $
26
+ * $Id: b_object.c,v 1.1 2006/10/19 17:28:58 njh Exp $
27
+ */
28
+
29
+#include "jsint.h"
30
+
31
+/*
32
+ * Static functions.
33
+ */
34
+
35
+/* Global method proc. */
36
+static void
37
+global_method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info,
38
+	       void *instance_context, JSNode *result_return,
39
+	       JSNode *args)
40
+{
41
+  if (args->u.vinteger > 1)
42
+    {
43
+      sprintf (vm->error, "Object(): illegal amount of arguments");
44
+      js_vm_error (vm);
45
+    }
46
+  if (args->u.vinteger == 0
47
+      || (args->u.vinteger == 1
48
+	  && (args[1].type == JS_NULL
49
+	      || args[1].type == JS_UNDEFINED)))
50
+    {
51
+      /* Create a fresh new object. */
52
+      result_return->type = JS_OBJECT;
53
+      result_return->u.vobject = js_vm_object_new (vm);
54
+    }
55
+  else
56
+    {
57
+      /* We have one argument.  Call ToObject() for it. */
58
+      js_vm_to_object (vm, &args[1], result_return);
59
+    }
60
+}
61
+
62
+/* Method proc. */
63
+static int
64
+method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info,
65
+	void *instance_context, JSSymbol method, JSNode *result_return,
66
+	JSNode *args)
67
+{
68
+  JSNode *n = instance_context;
69
+
70
+  if (method == vm->syms.s_toSource)
71
+    {
72
+      char *source;
73
+
74
+      if (instance_context)
75
+	{
76
+	  result_return->type = JS_UNDEFINED;
77
+	  /* XXX 15.2.4.3 */
78
+	}
79
+      else
80
+	{
81
+	  source = "new Object()";
82
+	  js_vm_make_static_string (vm, result_return, source,
83
+				    strlen (source));
84
+	}
85
+    }
86
+  /* ********************************************************************** */
87
+  else if (method == vm->syms.s_toString)
88
+    {
89
+      if (instance_context)
90
+	js_vm_make_static_string (vm, result_return, "[object Object]", 15);
91
+      else
92
+	js_vm_make_static_string (vm, result_return, "Object", 6);
93
+    }
94
+  /* ********************************************************************** */
95
+  else if (method == vm->syms.s_valueOf)
96
+    {
97
+      if (instance_context)
98
+	JS_COPY (result_return, n);
99
+      else
100
+	{
101
+	  n = &vm->globals[js_vm_intern (vm, "Object")];
102
+	  JS_COPY (result_return, n);
103
+	}
104
+    }
105
+  /* ********************************************************************** */
106
+  else
107
+    return JS_PROPERTY_UNKNOWN;
108
+
109
+  return JS_PROPERTY_FOUND;
110
+}
111
+
112
+
113
+/* Property proc. */
114
+static int
115
+property (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info,
116
+	  void *instance_context, JSSymbol property, int set, JSNode *node)
117
+{
118
+  if (!set)
119
+    node->type = JS_UNDEFINED;
120
+
121
+  return JS_PROPERTY_UNKNOWN;
122
+}
123
+
124
+/* New proc. */
125
+static void
126
+new_proc (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, JSNode *args,
127
+	  JSNode *result_return)
128
+{
129
+  if (args->u.vinteger == 0)
130
+    {
131
+    return_native_object:
132
+      result_return->type = JS_OBJECT;
133
+      result_return->u.vobject = js_vm_object_new (vm);
134
+
135
+      /* Set the [[Prototype]] and [[Class]] properties. */
136
+      /* XXX 15.2.2.2 */
137
+    }
138
+  else if (args->u.vinteger == 1)
139
+    {
140
+      switch (args[1].type)
141
+	{
142
+	case JS_OBJECT:
143
+	  JS_COPY (result_return, &args[1]);
144
+	  break;
145
+
146
+	case JS_STRING:
147
+	case JS_BOOLEAN:
148
+	case JS_INTEGER:
149
+	case JS_FLOAT:
150
+	case JS_NAN:
151
+	  js_vm_to_object (vm, &args[1], result_return);
152
+	  break;
153
+
154
+	case JS_NULL:
155
+	case JS_UNDEFINED:
156
+	  goto return_native_object;
157
+	  break;
158
+
159
+	default:
160
+	  /* The rest are implementation dependent. */
161
+	  JS_COPY (result_return, &args[1]);
162
+	  break;
163
+	}
164
+    }
165
+  else
166
+    {
167
+      sprintf (vm->error, "new Object(): illegal amount of arguments");
168
+      js_vm_error (vm);
169
+    }
170
+}
171
+
172
+
173
+/*
174
+ * Global functions.
175
+ */
176
+
177
+void
178
+js_builtin_Object (JSVirtualMachine *vm)
179
+{
180
+  JSNode *n;
181
+  JSBuiltinInfo *info;
182
+
183
+  info = js_vm_builtin_info_create (vm);
184
+  vm->prim[JS_OBJECT] = info;
185
+
186
+  info->global_method_proc	= global_method;
187
+  info->method_proc		= method;
188
+  info->property_proc		= property;
189
+  info->new_proc		= new_proc;
190
+
191
+  /* Define it. */
192
+  n = &vm->globals[js_vm_intern (vm, "Object")];
193
+  js_vm_builtin_create (vm, n, info, NULL);
194
+}
0 195
new file mode 100644
... ...
@@ -0,0 +1,1136 @@
0
+/*
1
+ * The builtin RegExp object.
2
+ * Copyright (c) 1998 New Generation Software (NGS) Oy
3
+ *
4
+ * Author: Markku Rossi <mtr@ngs.fi>
5
+ */
6
+
7
+/*
8
+ * This library is free software; you can redistribute it and/or
9
+ * modify it under the terms of the GNU Library General Public
10
+ * License as published by the Free Software Foundation; either
11
+ * version 2 of the License, or (at your option) any later version.
12
+ *
13
+ * This library is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
+ * Library General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU Library General Public
19
+ * License along with this library; if not, write to the Free
20
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
21
+ * MA 02111-1307, USA
22
+ */
23
+
24
+/*
25
+ * $Source: /tmp/cvsroot-15-2-2007/clamav-devel/libclamav/js/b_regexp.c,v $
26
+ * $Id: b_regexp.c,v 1.1 2006/10/19 17:28:58 njh Exp $
27
+ */
28
+
29
+#include "jsint.h"
30
+#include "regex.h"
31
+
32
+/*
33
+ * Types and definitions.
34
+ */
35
+
36
+/* These must be in sync with the values, found from `../jsc/asm.js'. */
37
+#define JS_REGEXP_FLAG_G	0x01
38
+#define JS_REGEXP_FLAG_I	0x02
39
+
40
+/* Class context. */
41
+struct regexp_ctx_st
42
+{
43
+  /* Static properties. */
44
+  JSSymbol s_S1;
45
+  JSSymbol s_S2;
46
+  JSSymbol s_S3;
47
+  JSSymbol s_S4;
48
+  JSSymbol s_S5;
49
+  JSSymbol s_S6;
50
+  JSSymbol s_S7;
51
+  JSSymbol s_S8;
52
+  JSSymbol s_S9;
53
+  JSSymbol s_S_;
54
+  JSSymbol s_input;
55
+  JSSymbol s_lastMatch;
56
+  JSSymbol s_lastParen;
57
+  JSSymbol s_leftContext;
58
+  JSSymbol s_multiline;
59
+  JSSymbol s_rightContext;
60
+
61
+  /* Properties. */
62
+  JSSymbol s_global;
63
+  JSSymbol s_ignoreCase;
64
+  JSSymbol s_lastIndex;
65
+  JSSymbol s_source;
66
+
67
+  /* Methods. */
68
+  JSSymbol s_compile;
69
+  JSSymbol s_exec;
70
+  JSSymbol s_test;
71
+
72
+  /* Data that is needed for the static properties. */
73
+
74
+  JSNode input;
75
+  struct re_registers regs;
76
+};
77
+
78
+typedef struct regexp_ctx_st RegexpCtx;
79
+
80
+/* RegExp instance context. */
81
+struct regexp_instance_ctx_st
82
+{
83
+  /* The source for this regexp. */
84
+  char *source;
85
+  unsigned int source_len;
86
+
87
+  /* Flags. */
88
+  unsigned int global : 1;
89
+  unsigned int ignore_case : 1;
90
+  unsigned int immutable : 1;
91
+
92
+  /* Compiled pattern. */
93
+  struct re_pattern_buffer compiled;
94
+
95
+  /* The index from which the next match is started. */
96
+  unsigned int last_index;
97
+};
98
+
99
+typedef struct regexp_instance_ctx_st RegexpInstanceCtx;
100
+
101
+
102
+/*
103
+ * Prorototypes for some static functions.
104
+ */
105
+
106
+static void new_proc (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info,
107
+		      JSNode *args, JSNode *result_return);
108
+
109
+
110
+/*
111
+ * Static functions.
112
+ */
113
+
114
+/* A helper for RegExp.exec().  XXX Check the compliancy. */
115
+static void
116
+do_exec (JSVirtualMachine *vm, RegexpCtx *ctx, RegexpInstanceCtx *ictx,
117
+	 char *input, unsigned int input_len, JSNode *result_return)
118
+{
119
+  int result;
120
+  int i, j;
121
+
122
+  result = re_search (&ictx->compiled, input, input_len,
123
+		      ictx->global ? ictx->last_index : 0,
124
+		      input_len, &ctx->regs);
125
+
126
+  if (result < 0)
127
+    {
128
+      result_return->type = JS_NULL;
129
+      return;
130
+    }
131
+
132
+  /* Success.  Count how many matches we had. */
133
+  for (i = 0; i < ctx->regs.num_regs && ctx->regs.start[i] >= 0; i++)
134
+    ;
135
+
136
+  /* Create the result array and enter the sub-matches. */
137
+  js_vm_make_array (vm, result_return, i);
138
+
139
+  for (j = 0; j < i; j++)
140
+    js_vm_make_string (vm, &result_return->u.varray->data[j],
141
+		       input + ctx->regs.start[j],
142
+		       ctx->regs.end[j] - ctx->regs.start[j]);
143
+
144
+  ictx->last_index = ctx->regs.end[0];
145
+}
146
+
147
+/* Method proc. */
148
+static int
149
+method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info,
150
+	void *instance_context, JSSymbol method, JSNode *result_return,
151
+	JSNode *args)
152
+{
153
+  RegexpCtx *ctx = builtin_info->obj_context;
154
+  RegexpInstanceCtx *ictx = instance_context;
155
+  int result;
156
+  int i;
157
+
158
+  /* Set the default return value. */
159
+  result_return->type = JS_BOOLEAN;
160
+  result_return->u.vboolean = 1;
161
+
162
+  /* Static methods. */
163
+  if (method == vm->syms.s_toString)
164
+    {
165
+      if (ictx)
166
+	js_vm_make_string (vm, result_return, ictx->source, ictx->source_len);
167
+      else
168
+	js_vm_make_static_string (vm, result_return, "RegExp", 6);
169
+    }
170
+  /* ********************************************************************** */
171
+  else if (ictx)
172
+    {
173
+      /* Methods */
174
+
175
+      if (method == ctx->s_compile)
176
+	{
177
+	  int global = 0;
178
+	  int ignore_case = 0;
179
+	  const char *error;
180
+	  JSNode *pattern;
181
+	  JSNode pattern_cvt;
182
+
183
+	  if (ictx->immutable)
184
+	    goto immutable;
185
+
186
+	  if (args->u.vinteger != 1 && args->u.vinteger != 2)
187
+	    goto argument_error;
188
+
189
+	  if (args[1].type == JS_STRING)
190
+	    pattern = &args[1];
191
+	  else
192
+	    {
193
+	      js_vm_to_string (vm, &args[1], &pattern_cvt);
194
+	      pattern = &pattern_cvt;
195
+	    }
196
+
197
+	  if (args->u.vinteger == 2)
198
+	    {
199
+	      JSNode *flags;
200
+	      JSNode cvt;
201
+
202
+	      if (args[2].type == JS_STRING)
203
+		flags = &args[2];
204
+	      else
205
+		{
206
+		  js_vm_to_string (vm, &args[2], &cvt);
207
+		  flags = &cvt;
208
+		}
209
+
210
+	      for (i = 0; i < flags->u.vstring->len; i++)
211
+		switch (flags->u.vstring->data[i])
212
+		  {
213
+		  case 'g':
214
+		    global = 1;
215
+		    break;
216
+
217
+		  case 'i':
218
+		    ignore_case = 1;
219
+		    break;
220
+
221
+		  default:
222
+		    sprintf (vm->error, "new RegExp(): illegal flag `%c'",
223
+			     flags->u.vstring->data[i]);
224
+		    js_vm_error (vm);
225
+		    break;
226
+		  }
227
+	    }
228
+
229
+	  if (ictx->source)
230
+	    js_free (ictx->source);
231
+
232
+	  ictx->source_len = pattern->u.vstring->len;
233
+	  ictx->source = js_malloc (vm, ictx->source_len);
234
+	  memcpy (ictx->source, pattern->u.vstring->data, ictx->source_len);
235
+
236
+	  ictx->global = global;
237
+	  ictx->ignore_case = ignore_case;
238
+
239
+	  if (ictx->compiled.fastmap)
240
+	    js_free (ictx->compiled.fastmap);
241
+
242
+	  memset (&ictx->compiled, 0, sizeof (ictx->compiled));
243
+
244
+	  if (ictx->ignore_case)
245
+	    ictx->compiled.translate = js_latin1_tolower;
246
+
247
+	  error = re_compile_pattern (ictx->source, ictx->source_len,
248
+				      &ictx->compiled);
249
+	  if (error)
250
+	    {
251
+	      sprintf (vm->error,
252
+		       "RegExp.%s(): compilation of the expression failed: %s",
253
+		       js_vm_symname (vm, method), error);
254
+	      js_vm_error (vm);
255
+	    }
256
+	  ictx->compiled.fastmap = js_malloc (vm, 256);
257
+	  re_compile_fastmap (&ictx->compiled);
258
+	}
259
+      /* ***************************************************************** */
260
+      else if (method == ctx->s_exec)
261
+	{
262
+	  char *input;
263
+	  unsigned int input_len;
264
+	  JSNode *input_str;
265
+	  JSNode cvt;
266
+
267
+	  if (args->u.vinteger == 0)
268
+	    {
269
+	      if (ctx->input.type == JS_STRING)
270
+		input_str = &ctx->input;
271
+	      else
272
+		{
273
+		  js_vm_to_string (vm, &ctx->input, &cvt);
274
+		  input_str = &cvt;
275
+		}
276
+
277
+	      input = input_str->u.vstring->data;
278
+	      input_len = input_str->u.vstring->len;
279
+	    }
280
+	  else if (args->u.vinteger == 1)
281
+	    {
282
+	      if (args[1].type == JS_STRING)
283
+		input_str = &args[1];
284
+	      else
285
+		{
286
+		  js_vm_to_string (vm, &args[1], &cvt);
287
+		  input_str = &cvt;
288
+		}
289
+
290
+	      input = input_str->u.vstring->data;
291
+	      input_len = input_str->u.vstring->len;
292
+
293
+	      /* Set the input property to the class context. */
294
+	      JS_COPY (&ctx->input, input_str);
295
+	    }
296
+	  else
297
+	    goto argument_error;
298
+
299
+	  do_exec (vm, ctx, ictx, input, input_len, result_return);
300
+	}
301
+      /* ***************************************************************** */
302
+      else if (method == ctx->s_test)
303
+	{
304
+	  char *input;
305
+	  unsigned int input_len;
306
+	  JSNode *input_str;
307
+	  JSNode cvt;
308
+
309
+	  if (args->u.vinteger == 0)
310
+	    {
311
+	      if (ctx->input.type == JS_STRING)
312
+		input_str = &ctx->input;
313
+	      else
314
+		{
315
+		  js_vm_to_string (vm, &ctx->input, &cvt);
316
+		  input_str = &cvt;
317
+		}
318
+
319
+	      input = input_str->u.vstring->data;
320
+	      input_len = input_str->u.vstring->len;
321
+	    }
322
+	  else if (args->u.vinteger == 1)
323
+	    {
324
+	      if (args[1].type == JS_STRING)
325
+		input_str = &args[1];
326
+	      else
327
+		{
328
+		  js_vm_to_string (vm, &args[1], &cvt);
329
+		  input_str = &cvt;
330
+		}
331
+
332
+	      input = input_str->u.vstring->data;
333
+	      input_len = input_str->u.vstring->len;
334
+
335
+	      /* Set the input property to the class context. */
336
+	      JS_COPY (&ctx->input, input_str);
337
+	    }
338
+	  else
339
+	    goto argument_error;
340
+
341
+	  result = re_search (&ictx->compiled, input, input_len,
342
+			      ictx->global ? ictx->last_index : 0,
343
+			      input_len, &ctx->regs);
344
+
345
+	  result_return->type = JS_BOOLEAN;
346
+	  result_return->u.vboolean = result >= 0;
347
+
348
+	  if (result >= 0)
349
+	    /* ctx->regs.num_regs can be 0.  Or can it??? */
350
+	    ictx->last_index = ctx->regs.end[0];
351
+	}
352
+      /* ***************************************************************** */
353
+      else
354
+	return JS_PROPERTY_UNKNOWN;
355
+    }
356
+  /* ********************************************************************** */
357
+  else
358
+    return JS_PROPERTY_UNKNOWN;
359
+
360
+  return JS_PROPERTY_FOUND;
361
+
362
+
363
+  /*
364
+   * Error handling.
365
+   */
366
+
367
+ argument_error:
368
+  sprintf (vm->error, "RegExp.%s(): illegal amount of arguments",
369
+	   js_vm_symname (vm, method));
370
+  js_vm_error (vm);
371
+
372
+ argument_type_error:
373
+  sprintf (vm->error, "RegExp.%s(): illegal argument",
374
+	   js_vm_symname (vm, method));
375
+  js_vm_error (vm);
376
+
377
+ immutable:
378
+  sprintf (vm->error, "RegExp.%s(): immutable object",
379
+	   js_vm_symname (vm, method));
380
+  js_vm_error (vm);
381
+
382
+  /* NOTREACHED. */
383
+  return 0;
384
+}
385
+
386
+/* Global method proc. */
387
+static void
388
+global_method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info,
389
+	       void *instance_context, JSNode *result_return,
390
+	       JSNode *args)
391
+{
392
+  RegexpCtx *ctx = builtin_info->obj_context;
393
+  RegexpInstanceCtx *ictx = instance_context;
394
+  char *input = NULL;		/* Initialized to keep the compiler quiet. */
395
+  unsigned int input_len = 0;	/* Likewise. */
396
+
397
+  if (ictx)
398
+    {
399
+      /* A RegExp instance was called as a function. */
400
+
401
+      if (args->u.vinteger == 0)
402
+	{
403
+	  if (ctx->input.type != JS_STRING)
404
+	    {
405
+	      sprintf (vm->error, "RegExp(): RegExp.input is not a string");
406
+	      js_vm_error (vm);
407
+	    }
408
+	  input = ctx->input.u.vstring->data;
409
+	  input_len = ctx->input.u.vstring->len;
410
+	}
411
+      else if (args->u.vinteger == 1)
412
+	{
413
+	  if (args[1].type != JS_STRING)
414
+	    {
415
+	      sprintf (vm->error, "RegExp(): illegal argument");
416
+	      js_vm_error (vm);
417
+	    }
418
+
419
+	  input = args[1].u.vstring->data;
420
+	  input_len = args[1].u.vstring->len;
421
+
422
+	  /* Set the input property to the class context. */
423
+	  JS_COPY (&ctx->input, &args[1]);
424
+	}
425
+      else
426
+	{
427
+	  sprintf (vm->error, "RegExp(): illegal amount of arguments");
428
+	  js_vm_error (vm);
429
+	}
430
+
431
+      do_exec (vm, ctx, ictx, input, input_len, result_return);
432
+    }
433
+  else
434
+    {
435
+      /*
436
+       * The `RegExp' was called as a function.  We do exactly the
437
+       * same the `new RegExp()' would do with our arguments.
438
+       */
439
+      new_proc (vm, builtin_info, args, result_return);
440
+    }
441
+}
442
+
443
+/* Property proc. */
444
+static int
445
+property (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info,
446
+	  void *instance_context, JSSymbol property, int set, JSNode *node)
447
+{
448
+  RegexpCtx *ctx = builtin_info->obj_context;
449
+  RegexpInstanceCtx *ictx = instance_context;
450
+  int index;
451
+
452
+  /* Static properties. */
453
+  if (property == ctx->s_S1)
454
+    {
455
+      index = 1;
456
+
457
+    dollar_index:
458
+
459
+      if (set)
460
+	goto immutable;
461
+
462
+      if (ctx->input.type != JS_STRING
463
+	  || ctx->regs.end[0] > ctx->input.u.vstring->len
464
+	  || ctx->regs.start[index] < 0)
465
+	node->type = JS_UNDEFINED;
466
+      else
467
+	js_vm_make_string (vm, node,
468
+			   ctx->input.u.vstring->data
469
+			   + ctx->regs.start[index],
470
+			   ctx->regs.end[index] - ctx->regs.start[index]);
471
+    }
472
+  /* ********************************************************************** */
473
+  else if (property == ctx->s_S2)
474
+    {
475
+      index = 2;
476
+      goto dollar_index;
477
+    }
478
+  /* ********************************************************************** */
479
+  else if (property == ctx->s_S3)
480
+    {
481
+      index = 3;
482
+      goto dollar_index;
483
+    }
484
+  /* ********************************************************************** */
485
+  else if (property == ctx->s_S4)
486
+    {
487
+      index = 4;
488
+      goto dollar_index;
489
+    }
490
+  /* ********************************************************************** */
491
+  else if (property == ctx->s_S5)
492
+    {
493
+      index = 5;
494
+      goto dollar_index;
495
+    }
496
+  /* ********************************************************************** */
497
+  else if (property == ctx->s_S6)
498
+    {
499
+      index = 6;
500
+      goto dollar_index;
501
+    }
502
+  /* ********************************************************************** */
503
+  else if (property == ctx->s_S7)
504
+    {
505
+      index = 7;
506
+      goto dollar_index;
507
+    }
508
+  /* ********************************************************************** */
509
+  else if (property == ctx->s_S8)
510
+    {
511
+      index = 8;
512
+      goto dollar_index;
513
+    }
514
+  /* ********************************************************************** */
515
+  else if (property == ctx->s_S9)
516
+    {
517
+      index = 9;
518
+      goto dollar_index;
519
+    }
520
+  /* ********************************************************************** */
521
+  else if (property == ctx->s_S_ || property == ctx->s_input)
522
+    {
523
+      if (set)
524
+	{
525
+	  if (node->type != JS_STRING)
526
+	    goto argument_type_error;
527
+
528
+	  JS_COPY (&ctx->input, node);
529
+	}
530
+      else
531
+	JS_COPY (node, &ctx->input);
532
+    }
533
+  /* ********************************************************************** */
534
+  else if (property == ctx->s_lastMatch)
535
+    {
536
+      if (set)
537
+	goto immutable;
538
+
539
+      if (ctx->input.type != JS_STRING
540
+	  || ctx->regs.end[0] > ctx->input.u.vstring->len)
541
+	node->type = JS_UNDEFINED;
542
+      else
543
+	js_vm_make_string (vm, node,
544
+			   ctx->input.u.vstring->data + ctx->regs.start[0],
545
+			   ctx->regs.end[0] - ctx->regs.start[0]);
546
+    }
547
+  /* ********************************************************************** */
548
+  else if (property == ctx->s_lastParen)
549
+    {
550
+      if (set)
551
+	goto immutable;
552
+
553
+      if (ctx->input.type != JS_STRING
554
+	  || ctx->regs.end[0] > ctx->input.u.vstring->len)
555
+	node->type = JS_UNDEFINED;
556
+      else
557
+	{
558
+	  int i;
559
+
560
+	  for (i = 1; i < ctx->regs.num_regs && ctx->regs.start[i] >= 0; i++)
561
+	    ;
562
+	  i--;
563
+	  if (i == 0)
564
+	    node->type = JS_UNDEFINED;
565
+	  else
566
+	    js_vm_make_string (vm, node,
567
+			       ctx->input.u.vstring->data
568
+			       + ctx->regs.start[i],
569
+			       ctx->regs.end[i] - ctx->regs.start[i]);
570
+	}
571
+    }
572
+  /* ********************************************************************** */
573
+  else if (property == ctx->s_leftContext)
574
+    {
575
+      if (set)
576
+	goto immutable;
577
+
578
+      if (ctx->input.type != JS_STRING
579
+	  || ctx->regs.end[0] > ctx->input.u.vstring->len)
580
+	node->type = JS_UNDEFINED;
581
+      else
582
+	js_vm_make_string (vm, node, ctx->input.u.vstring->data,
583
+			   ctx->regs.start[0]);
584
+    }
585
+  /* ********************************************************************** */
586
+  else if (property == ctx->s_multiline)
587
+    {
588
+      goto not_implemented_yet;
589
+    }
590
+  /* ********************************************************************** */
591
+  else if (property == ctx->s_rightContext)
592
+    {
593
+      if (set)
594
+	goto immutable;
595
+      if (ctx->input.type != JS_STRING
596
+	  || ctx->regs.end[0] > ctx->input.u.vstring->len)
597
+	node->type = JS_UNDEFINED;
598
+      else
599
+	js_vm_make_string (vm, node,
600
+			   ctx->input.u.vstring->data + ctx->regs.end[0],
601
+			   ctx->input.u.vstring->len - ctx->regs.end[0]);
602
+    }
603
+  /* ********************************************************************** */
604
+  else if (ictx)
605
+    {
606
+      /* Properties. */
607
+      if (property == ctx->s_global)
608
+	{
609
+	  if (set)
610
+	    goto immutable;
611
+
612
+	  node->type = JS_BOOLEAN;
613
+	  node->u.vboolean = ictx->global;
614
+	}
615
+      /* ***************************************************************** */
616
+      else if (property == ctx->s_ignoreCase)
617
+	{
618
+	  if (set)
619
+	    goto immutable;
620
+
621
+	  node->type = JS_BOOLEAN;
622
+	  node->u.vboolean = ictx->ignore_case;
623
+	}
624
+      /* ***************************************************************** */
625
+      else if (property == ctx->s_lastIndex)
626
+	{
627
+	  if (set)
628
+	    {
629
+	      if (ictx->immutable)
630
+		goto immutable_object;
631
+
632
+	      if (node->type != JS_INTEGER)
633
+		goto argument_type_error;
634
+
635
+	      ictx->last_index = node->u.vinteger;
636
+	    }
637
+	  else
638
+	    {
639
+	      node->type = JS_INTEGER;
640
+	      node->u.vinteger = ictx->last_index;
641
+	    }
642
+	}
643
+      /* ***************************************************************** */
644
+      else if (property == ctx->s_source)
645
+	{
646
+	  if (set)
647
+	    goto immutable;
648
+
649
+	  js_vm_make_string (vm, node, ictx->source, ictx->source_len);
650
+	}
651
+      /* ***************************************************************** */
652
+      else
653
+	{
654
+	  if (!set)
655
+	    node->type = JS_UNDEFINED;
656
+
657
+	  return JS_PROPERTY_UNKNOWN;
658
+	}
659
+    }
660
+  /* ********************************************************************** */
661
+  else
662
+    {
663
+      if (!set)
664
+	node->type = JS_UNDEFINED;
665
+
666
+      return JS_PROPERTY_UNKNOWN;
667
+    }
668
+
669
+  return JS_PROPERTY_FOUND;
670
+
671
+
672
+  /* Error handling. */
673
+
674
+ argument_type_error:
675
+  sprintf (vm->error, "RegExp.%s: illegal value",
676
+	   js_vm_symname (vm, property));
677
+  js_vm_error (vm);
678
+
679
+ not_implemented_yet:
680
+  sprintf (vm->error, "RegExp.%s: not implemented yet",
681
+	   js_vm_symname (vm, property));
682
+  js_vm_error (vm);
683
+
684
+ immutable:
685
+  sprintf (vm->error, "RegExp.%s: immutable property",
686
+	   js_vm_symname (vm, property));
687
+  js_vm_error (vm);
688
+
689
+ immutable_object:
690
+  sprintf (vm->error, "RegExp.%s: immutable object",
691
+	   js_vm_symname (vm, property));
692
+  js_vm_error (vm);
693
+
694
+  /* NOTREACHED */
695
+  return 0;
696
+}
697
+
698
+/* New proc. */
699
+static void
700
+new_proc (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, JSNode *args,
701
+	  JSNode *result_return)
702
+{
703
+  unsigned int flags = 0;
704
+  char *source;
705
+  unsigned int source_len;
706
+  int i;
707
+
708
+  if (args->u.vinteger > 2)
709
+    {
710
+      sprintf (vm->error, "new RegExp(): illegal amount of arguments");
711
+      js_vm_error (vm);
712
+    }
713
+
714
+  if (args->u.vinteger == 0)
715
+    {
716
+      source = "";
717
+      source_len = 0;
718
+    }
719
+  else
720
+    {
721
+      if (args[1].type != JS_STRING)
722
+	{
723
+	argument_type_error:
724
+	  sprintf (vm->error, "new RegExp(): illegal argument");
725
+	  js_vm_error (vm);
726
+	}
727
+
728
+      source = args[1].u.vstring->data;
729
+      source_len = args[1].u.vstring->len;
730
+    }
731
+
732
+  if (args->u.vinteger == 2)
733
+    {
734
+      if (args[2].type != JS_STRING)
735
+	goto argument_type_error;
736
+
737
+      for (i = 0; i < args[2].u.vstring->len; i++)
738
+	switch (args[2].u.vstring->data[i])
739
+	  {
740
+	  case 'g':
741
+	    flags |= JS_REGEXP_FLAG_G;
742
+	    break;
743
+
744
+	  case 'i':
745
+	    flags |= JS_REGEXP_FLAG_I;
746
+	    break;
747
+
748
+	  default:
749
+	    sprintf (vm->error, "new RegExp(): illegal flag `%c'",
750
+		     args[2].u.vstring->data[i]);
751
+	    js_vm_error (vm);
752
+	    break;
753
+	  }
754
+    }
755
+
756
+  js_builtin_RegExp_new (vm, source, source_len, flags, 0, builtin_info,
757
+			 result_return);
758
+}
759
+
760
+/* Delete proc. */
761
+static void
762
+delete_proc (JSBuiltinInfo *builtin_info, void *instance_context)
763
+{
764
+  RegexpInstanceCtx *ictx = instance_context;
765
+
766
+  if (ictx)
767
+    {
768
+      js_free (ictx->source);
769
+
770
+      if (ictx->compiled.buffer)
771
+	free (ictx->compiled.buffer);
772
+      if (ictx->compiled.fastmap)
773
+	js_free (ictx->compiled.fastmap);
774
+
775
+      js_free (ictx);
776
+    }
777
+}
778
+
779
+/* Mark proc. */
780
+static void
781
+mark (JSBuiltinInfo *builtin_info, void *instance_context)
782
+{
783
+  RegexpCtx *ctx = builtin_info->obj_context;
784
+
785
+  js_vm_mark (&ctx->input);
786
+}
787
+
788
+/*
789
+ * Global functions.
790
+ */
791
+
792
+void
793
+js_builtin_RegExp (JSVirtualMachine *vm)
794
+{
795
+  JSBuiltinInfo *info;
796
+  RegexpCtx *ctx;
797
+  JSNode *n;
798
+
799
+  ctx = js_calloc (vm, 1, sizeof (*ctx));
800
+
801
+  ctx->s_S1		= js_vm_intern (vm, "$1");
802
+  ctx->s_S2		= js_vm_intern (vm, "$2");
803
+  ctx->s_S3		= js_vm_intern (vm, "$3");
804
+  ctx->s_S4		= js_vm_intern (vm, "$4");
805
+  ctx->s_S5		= js_vm_intern (vm, "$5");
806
+  ctx->s_S6		= js_vm_intern (vm, "$6");
807
+  ctx->s_S7		= js_vm_intern (vm, "$7");
808
+  ctx->s_S8		= js_vm_intern (vm, "$8");
809
+  ctx->s_S9		= js_vm_intern (vm, "$9");
810
+  ctx->s_S_		= js_vm_intern (vm, "$_");
811
+  ctx->s_input		= js_vm_intern (vm, "input");
812
+  ctx->s_lastMatch	= js_vm_intern (vm, "lastMatch");
813
+  ctx->s_lastParen	= js_vm_intern (vm, "lastParen");
814
+  ctx->s_leftContext	= js_vm_intern (vm, "leftContext");
815
+  ctx->s_multiline	= js_vm_intern (vm, "multiline");
816
+  ctx->s_rightContext	= js_vm_intern (vm, "rightContext");
817
+
818
+  ctx->s_global		= js_vm_intern (vm, "global");
819
+  ctx->s_ignoreCase	= js_vm_intern (vm, "ignoreCase");
820
+  ctx->s_lastIndex	= js_vm_intern (vm, "lastIndex");
821
+  ctx->s_source		= js_vm_intern (vm, "source");
822
+
823
+  ctx->s_compile	= js_vm_intern (vm, "compile");
824
+  ctx->s_exec		= js_vm_intern (vm, "exec");
825
+  ctx->s_test		= js_vm_intern (vm, "test");
826
+
827
+  /* Object information. */
828
+
829
+  info = js_vm_builtin_info_create (vm);
830
+
831
+  info->global_method_proc	= global_method;
832
+  info->method_proc		= method;
833
+  info->property_proc		= property;
834
+  info->new_proc		= new_proc;
835
+  info->delete_proc		= delete_proc;
836
+  info->mark_proc		= mark;
837
+  info->obj_context		= ctx;
838
+  info->obj_context_delete	= js_free;
839
+
840
+  /* Define it. */
841
+  n = &vm->globals[js_vm_intern (vm, "RegExp")];
842
+  js_vm_builtin_create (vm, n, info, NULL);
843
+}
844
+
845
+
846
+void
847
+js_builtin_RegExp_new (JSVirtualMachine *vm, char *source,
848
+		       unsigned int source_len, unsigned int flags,
849
+		       int immutable, JSBuiltinInfo *info,
850
+		       JSNode *result_return)
851
+{
852
+  RegexpInstanceCtx *instance;
853
+  const char *error;
854
+
855
+  instance = js_calloc (vm, 1, sizeof (*instance));
856
+
857
+  instance->source_len = source_len;
858
+
859
+  /* +1 to avoid zero allocation. */
860
+  instance->source = js_malloc (vm, instance->source_len + 1);
861
+  memcpy (instance->source, source, instance->source_len);
862
+
863
+  instance->global 	= (flags & JS_REGEXP_FLAG_G) != 0;
864
+  instance->ignore_case = (flags & JS_REGEXP_FLAG_I) != 0;
865
+  instance->immutable 	= immutable;
866
+
867
+  if (instance->ignore_case)
868
+    instance->compiled.translate = js_latin1_tolower;
869
+
870
+  error = re_compile_pattern (instance->source, instance->source_len,
871
+			      &instance->compiled);
872
+  if (error)
873
+    {
874
+      js_free (instance->source);
875
+      js_free (instance);
876
+      sprintf (vm->error,
877
+	       "new RegExp(): compilation of the expression failed: %s",
878
+	       error);
879
+      js_vm_error (vm);
880
+    }
881
+  instance->compiled.fastmap = js_malloc (vm, 256);
882
+  re_compile_fastmap (&instance->compiled);
883
+
884
+  if (info == NULL)
885
+    {
886
+      JSNode *n;
887
+
888
+      n = &vm->globals[js_vm_intern (vm, "RegExp")];
889
+      info = n->u.vbuiltin->info;
890
+    }
891
+
892
+  /* Create a new object. */
893
+  js_vm_builtin_create (vm, result_return, info, instance);
894
+}
895
+
896
+
897
+#define EMIT_TO_RESULT(md, mdl)					\
898
+  do {								\
899
+    result_return->u.vstring->data				\
900
+      = js_vm_realloc (vm, result_return->u.vstring->data,	\
901
+		       result_return->u.vstring->len + (mdl));	\
902
+    memcpy (result_return->u.vstring->data			\
903
+	    + result_return->u.vstring->len,			\
904
+	    (md), (mdl));					\
905
+    result_return->u.vstring->len += (mdl);			\
906
+  } while (0)
907
+
908
+void
909
+js_builtin_RegExp_replace (JSVirtualMachine *vm, char *data,
910
+			   unsigned int datalen, JSNode *regexp,
911
+			   char *repl, unsigned int repllen,
912
+			   JSNode *result_return)
913
+{
914
+  int i, j;
915
+  RegexpInstanceCtx *ictx = regexp->u.vbuiltin->instance_context;
916
+  struct re_registers regs = {0};
917
+  unsigned int substs = 0;
918
+  unsigned int pos = 0;
919
+
920
+  /*
921
+   * Allocate the result string, Let's guess that we need at least
922
+   * <datalen> bytes of data.
923
+   */
924
+  js_vm_make_string (vm, result_return, NULL, datalen);
925
+  result_return->u.vstring->len = 0;
926
+
927
+  /* Do searches. */
928
+  while (pos < datalen)
929
+    {
930
+      i = re_search (&ictx->compiled, data, datalen, pos, datalen - pos,
931
+		     &regs);
932
+
933
+      /* Check what we got. */
934
+      if (i >= 0)
935
+	{
936
+	  /* Emit all up to the first matched character. */
937
+	  EMIT_TO_RESULT (data + pos, regs.start[0] - pos);
938
+
939
+	  /* Check for empty matches. */
940
+	  if (regs.end[0] == regs.start[0])
941
+	    {
942
+	      pos = regs.end[0];
943
+
944
+	      /* Still something left to search? */
945
+	      if (pos < datalen)
946
+		{
947
+		  /* Go one character forward. */
948
+		  EMIT_TO_RESULT (data + pos, 1);
949
+		  pos++;
950
+		}
951
+	    }
952
+	  else
953
+	    {
954
+	      int start;
955
+
956
+	      /* Not an empty match. */
957
+	      substs++;
958
+
959
+	      /* Interpret replace string. */
960
+	      start = 0;
961
+	      for (i = 0; i < repllen; i++)
962
+		{
963
+		  if (repl[i] == '$')
964
+		    {
965
+		      if (i + 1 >= repllen)
966
+			/* The last character is '$'.  Just emit it. */
967
+			continue;
968
+
969
+		      /* First, emit all we have collected so far. */
970
+		      EMIT_TO_RESULT (repl + start, i - start);
971
+		      start = i++;
972
+
973
+		      /* Check tag. */
974
+		      switch (repl[i])
975
+			{
976
+			case '1':
977
+			case '2':
978
+			case '3':
979
+			case '4':
980
+			case '5':
981
+			case '6':
982
+			case '7':
983
+			case '8':
984
+			case '9':
985
+			  /* n:th subexpression. */
986
+			  j = repl[i] - '0';
987
+
988
+			  if (regs.start[j] >= 0)
989
+			    EMIT_TO_RESULT (data + regs.start[j],
990
+					    regs.end[j] - regs.start[j]);
991
+
992
+			  start = i + 1;
993
+			  break;
994
+
995
+			case '`':
996
+			  /* Left context. */
997
+			  EMIT_TO_RESULT (data, regs.start[0]);
998
+			  start = i + 1;
999
+			  break;
1000
+
1001
+			case '\'':
1002
+			  /* Right context. */
1003
+			  EMIT_TO_RESULT (data + regs.end[0],
1004
+					  datalen - regs.end[0]);
1005
+			  start = i + 1;
1006
+			  break;
1007
+
1008
+			case '&':
1009
+			  /* Last match. */
1010
+			  EMIT_TO_RESULT (data + regs.start[0],
1011
+					  regs.end[0] - regs.start[0]);
1012
+			  start = i + 1;
1013
+			  break;
1014
+
1015
+			case '$':
1016
+			  /* The dollar sign. */
1017
+			  EMIT_TO_RESULT ("$", 1);
1018
+			  start = i + 1;
1019
+			  break;
1020
+
1021
+			case '+':
1022
+			default:
1023
+			  /* Ignore. */
1024
+			  start = i - 1;
1025
+			  break;
1026
+			}
1027
+		    }
1028
+		}
1029
+
1030
+	      /* Emit all leftovers. */
1031
+	      EMIT_TO_RESULT (repl + start, i - start);
1032
+
1033
+	      /* Update search position. */
1034
+	      pos = regs.end[0];
1035
+	    }
1036
+	}
1037
+      else
1038
+	break;
1039
+
1040
+      if (!ictx->global && substs > 0)
1041
+	/* Substitute only the first match. */
1042
+	break;
1043
+    }
1044
+
1045
+  /* No more matches.  Emit the rest of the string to the result. */
1046
+  EMIT_TO_RESULT (data + pos, datalen - pos);
1047
+
1048
+  if (regs.start)
1049
+    free (regs.start);
1050
+  if (regs.end)
1051
+    free (regs.end);
1052
+}
1053
+
1054
+
1055
+void
1056
+js_builtin_RegExp_match (JSVirtualMachine *vm, char *data,
1057
+			 unsigned int datalen, JSNode *regexp,
1058
+			 JSNode *result_return)
1059
+{
1060
+  do_exec (vm, regexp->u.vbuiltin->info->obj_context,
1061
+	   regexp->u.vbuiltin->instance_context, data, datalen,
1062
+	   result_return);
1063
+}
1064
+
1065
+
1066
+void
1067
+js_builtin_RegExp_search (JSVirtualMachine *vm, char *data,
1068
+			  unsigned int datalen, JSNode *regexp,
1069
+			  JSNode *result_return)
1070
+{
1071
+  RegexpCtx *ctx = regexp->u.vbuiltin->info->obj_context;
1072
+  RegexpInstanceCtx *ictx = regexp->u.vbuiltin->instance_context;
1073
+
1074
+  result_return->type = JS_INTEGER;
1075
+  result_return->u.vinteger = re_search (&ictx->compiled, data, datalen,
1076
+					 ictx->global ? ictx->last_index : 0,
1077
+					 datalen, &ctx->regs);
1078
+
1079
+  if (result_return->u.vinteger >= 0)
1080
+    ictx->last_index = ctx->regs.end[0];
1081
+}
1082
+
1083
+
1084
+void
1085
+js_builtin_RegExp_split (JSVirtualMachine *vm, char *data,
1086
+			 unsigned int datalen, JSNode *regexp,
1087
+			 unsigned int limit, JSNode *result_return)
1088
+{
1089
+  unsigned int start = 0, pos;
1090
+  unsigned int alen = 0;
1091
+  RegexpInstanceCtx *ictx = regexp->u.vbuiltin->instance_context;
1092
+  struct re_registers regs = {0};
1093
+  int i;
1094
+
1095
+  js_vm_make_array (vm, result_return, alen);
1096
+
1097
+  for (pos = 0; alen < limit && pos <= datalen; )
1098
+    {
1099
+      i = re_search (&ictx->compiled, data, datalen, pos, datalen - pos,
1100
+		     &regs);
1101
+      if (i < 0)
1102
+	{
1103
+	  pos = datalen;
1104
+	  break;
1105
+	}
1106
+
1107
+      /* Found the separator. */
1108
+      js_vm_expand_array (vm, result_return, alen + 1);
1109
+      js_vm_make_string (vm, &result_return->u.varray->data[alen],
1110
+			 data + start, regs.start[0] - start);
1111
+      alen++;
1112
+
1113
+      if (regs.end[0] == pos)
1114
+	{
1115
+	  /* We didn't advance in the string. */
1116
+	  start = regs.end[0];
1117
+	  pos++;
1118
+	}
1119
+      else
1120
+	pos = start = regs.end[0];
1121
+    }
1122
+
1123
+  if (alen < limit)
1124
+    {
1125
+      /* Insert all leftovers. */
1126
+      js_vm_expand_array (vm, result_return, alen + 1);
1127
+      js_vm_make_string (vm, &result_return->u.varray->data[alen],
1128
+			 data + start, datalen - start);
1129
+    }
1130
+
1131
+  if (regs.start)
1132
+    free (regs.start);
1133
+  if (regs.end)
1134
+    free (regs.end);
1135
+}
0 1136
new file mode 100644
... ...
@@ -0,0 +1,937 @@
0
+/*
1
+ * The builtin String object.
2
+ * Copyright (c) 1998-1999 New Generation Software (NGS) Oy
3
+ *
4
+ * Author: Markku Rossi <mtr@ngs.fi>
5
+ */
6
+
7
+/*
8
+ * This library is free software; you can redistribute it and/or
9
+ * modify it under the terms of the GNU Library General Public
10
+ * License as published by the Free Software Foundation; either
11
+ * version 2 of the License, or (at your option) any later version.
12
+ *
13
+ * This library is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
+ * Library General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU Library General Public
19
+ * License along with this library; if not, write to the Free
20
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
21
+ * MA 02111-1307, USA
22
+ */
23
+
24
+/*
25
+ * $Source: /tmp/cvsroot-15-2-2007/clamav-devel/libclamav/js/b_string.c,v $
26
+ * $Id: b_string.c,v 1.1 2006/10/19 17:28:58 njh Exp $
27
+ */
28
+
29
+/* TODO: global method: String (obj) => string */
30
+
31
+#include "jsint.h"
32
+
33
+/*
34
+ * Types and definitions.
35
+ */
36
+
37
+#define UNPACK_NEED(n)							\
38
+  do {									\
39
+    if (bufpos + (n) > buflen)						\
40
+      {									\
41
+	sprintf (vm->error,						\
42
+		 "String.%s(): too short string for the format",	\
43
+		 js_vm_symname (vm, method));				\
44
+	js_vm_error (vm);						\
45
+      }									\
46
+  } while (0)
47
+
48
+#define UNPACK_EXPAND()						\
49
+  do {								\
50
+    js_vm_expand_array (vm, result_return, result_len + 1);	\
51
+    rnode = &result_return->u.varray->data[result_len];		\
52
+    result_len++;						\
53
+  } while (0)
54
+
55
+/* Class context. */
56
+struct string_ctx_st
57
+{
58
+  JSSymbol s_length;
59
+
60
+  JSSymbol s_append;
61
+  JSSymbol s_charAt;
62
+  JSSymbol s_charCodeAt;
63
+  JSSymbol s_concat;
64
+  JSSymbol s_crc32;
65
+  JSSymbol s_fromCharCode;
66
+  JSSymbol s_indexOf;
67
+  JSSymbol s_lastIndexOf;
68
+  JSSymbol s_match;
69
+  JSSymbol s_pack;
70
+  JSSymbol s_replace;
71
+  JSSymbol s_search;
72
+  JSSymbol s_slice;
73
+  JSSymbol s_split;
74
+  JSSymbol s_substr;
75
+  JSSymbol s_substring;
76
+  JSSymbol s_toLowerCase;
77
+  JSSymbol s_toUpperCase;
78
+  JSSymbol s_unpack;
79
+
80
+  /* Data we need to implement the RegExp related stuffs. */
81
+  JSBuiltinInfo *regexp_info;
82
+};
83
+
84
+typedef struct string_ctx_st StringCtx;
85
+
86
+
87
+/*
88
+ * Static functions.
89
+ */
90
+
91
+/* Global method proc. */
92
+static void
93
+global_method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info,
94
+	       void *instance_context, JSNode *result_return,
95
+	       JSNode *args)
96
+{
97
+  if (args->u.vinteger == 0)
98
+    js_vm_make_static_string (vm, result_return, "", 0);
99
+  else if (args->u.vinteger == 1)
100
+    js_vm_to_string (vm, &args[1], result_return);
101
+  else
102
+    {
103
+      sprintf (vm->error, "String(): illegal amount of arguments");
104
+      js_vm_error (vm);
105
+    }
106
+}
107
+
108
+/* Method proc. */
109
+static int
110
+method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info,
111
+	void *instance_context, JSSymbol method, JSNode *result_return,
112
+	JSNode *args)
113
+{
114
+  StringCtx *ctx = builtin_info->obj_context;
115
+  JSNode *n = instance_context;
116
+  unsigned int ui;
117
+  int i;
118
+
119
+  /*
120
+   * Static methods.
121
+   */
122
+
123
+  if (method == ctx->s_fromCharCode)
124
+    {
125
+      js_vm_make_string (vm, result_return, NULL, args->u.vinteger);
126
+
127
+      for (i = 0; i < args->u.vinteger; i++)
128
+	{
129
+	  if (args[1 + i].type != JS_INTEGER)
130
+	    goto argument_type_error;
131
+
132
+	  result_return->u.vstring->data[i]
133
+	    = (unsigned char) args[1 + i].u.vinteger;
134
+	}
135
+    }
136
+  /* ********************************************************************** */
137
+  else if (method == ctx->s_pack)
138
+    {
139
+      unsigned int op;
140
+      unsigned int arg = 2;
141
+      JSUInt32 ui;
142
+      double dval;
143
+      unsigned char *buffer = NULL;
144
+      unsigned int bufpos = 0;
145
+
146
+      if (args->u.vinteger < 1)
147
+	goto argument_error;
148
+      if (args[1].type != JS_STRING)
149
+	goto argument_type_error;
150
+
151
+      for (op = 0; op < args[1].u.vstring->len; op++)
152
+	{
153
+	  if (arg >= args->u.vinteger + 1)
154
+	    {
155
+	      sprintf (vm->error, "String.%s(): too few arguments for format",
156
+		       js_vm_symname (vm, method));
157
+	      js_vm_error (vm);
158
+	    }
159
+
160
+	  switch (args[1].u.vstring->data[op])
161
+	    {
162
+	    case 'C':
163
+	      if (args[arg].type != JS_INTEGER)
164
+		goto argument_type_error;
165
+
166
+	      buffer = js_vm_realloc (vm, buffer, bufpos + 1);
167
+	      buffer[bufpos++] = (unsigned char) args[arg++].u.vinteger;
168
+	      break;
169
+
170
+	    case 'n':
171
+	      if (args[arg].type != JS_INTEGER)
172
+		goto argument_type_error;
173
+
174
+	      ui = args[arg++].u.vinteger;
175
+
176
+	      buffer = js_vm_realloc (vm, buffer, bufpos + 2);
177
+	      buffer[bufpos++] = (unsigned char) ((ui & 0x0000ff00) >> 8);
178
+	      buffer[bufpos++] = (unsigned char) (ui & 0x000000ff);
179
+	      break;
180
+
181
+	    case 'N':
182
+	      if (args[arg].type != JS_INTEGER)
183
+		goto argument_type_error;
184
+
185
+	      ui = args[arg++].u.vinteger;
186
+
187
+	      buffer = js_vm_realloc (vm, buffer, bufpos + 4);
188
+	      buffer[bufpos++] = (unsigned char) ((ui & 0xff000000) >> 24);
189
+	      buffer[bufpos++] = (unsigned char) ((ui & 0x00ff0000) >> 16);
190
+	      buffer[bufpos++] = (unsigned char) ((ui & 0x0000ff00) >> 8);
191
+	      buffer[bufpos++] = (unsigned char) ((ui & 0x000000ff));
192
+	      break;
193
+
194
+	    case 'd':
195
+	      if (args[arg].type != JS_INTEGER && args[arg].type != JS_FLOAT)
196
+		goto argument_type_error;
197
+
198
+	      if (args[arg].type == JS_INTEGER)
199
+		dval = (double) args[arg].u.vinteger;
200
+	      else
201
+		dval = args[arg].u.vfloat;
202
+	      arg++;
203
+
204
+	      buffer = js_vm_realloc (vm, buffer, bufpos + sizeof (double));
205
+	      memcpy (buffer + bufpos, &dval, sizeof (double));
206
+	      bufpos += sizeof (double);
207
+	      break;
208
+
209
+	    default:
210
+	      /* Silently ignore it. */
211
+	      break;
212
+	    }
213
+	}
214
+
215
+      js_vm_make_static_string (vm, result_return, buffer, bufpos);
216
+      result_return->u.vstring->staticp = 0;
217
+    }
218
+  /* ********************************************************************** */
219
+  else if (method == vm->syms.s_toString)
220
+    {
221
+      if (n)
222
+	JS_COPY (result_return, n);
223
+      else
224
+	js_vm_make_static_string (vm, result_return, "String", 6);
225
+    }
226
+  /* ********************************************************************** */
227
+  else if (method == vm->syms.s_valueOf)
228
+    {
229
+      if (n)
230
+	JS_COPY (result_return, n);
231
+      else
232
+	{
233
+	  n = &vm->globals[js_vm_intern (vm, "String")];
234
+	  JS_COPY (result_return, n);
235
+	}
236
+    }
237
+  /* ********************************************************************** */
238
+  else if (n)
239
+    {
240
+      /*
241
+       * Instance methods.
242
+       */
243
+
244
+      if (method == ctx->s_append)
245
+	{
246
+	  if (args->u.vinteger != 1)
247
+	    goto argument_error;
248
+
249
+	  if (n->u.vstring->staticp)
250
+	    {
251
+	      sprintf (vm->error,
252
+		       "String.%s(): can't append to a static string",
253
+		       js_vm_symname (vm, method));
254
+	      js_vm_error (vm);
255
+	    }
256
+
257
+	  if (args[1].type == JS_STRING)
258
+	    {
259
+	      /* Append a string. */
260
+	      n->u.vstring->data = js_vm_realloc (vm, n->u.vstring->data,
261
+						  n->u.vstring->len
262
+						  + args[1].u.vstring->len);
263
+	      memcpy (n->u.vstring->data + n->u.vstring->len,
264
+		      args[1].u.vstring->data,
265
+		      args[1].u.vstring->len);
266
+	      n->u.vstring->len += args[1].u.vstring->len;
267
+	    }
268
+	  else if (args[1].type == JS_INTEGER)
269
+	    {
270
+	      /* Append a character. */
271
+	      n->u.vstring->data = js_vm_realloc (vm, n->u.vstring->data,
272
+						  n->u.vstring->len + 1);
273
+	      n->u.vstring->data[n->u.vstring->len++]
274
+		= (unsigned char) args[1].u.vinteger;
275
+	    }
276
+	  else
277
+	    goto argument_type_error;
278
+	}
279
+      /* ***************************************************************** */
280
+      else if (method == ctx->s_charAt)
281
+	{
282
+	  if (args->u.vinteger != 1)
283
+	    goto argument_error;
284
+	  if (args[1].type != JS_INTEGER)
285
+	    goto argument_type_error;
286
+
287
+	  js_vm_make_string (vm, result_return, NULL, 1);
288
+
289
+	  ui = args[1].u.vinteger;
290
+
291
+	  if (ui >= n->u.vstring->len)
292
+	    result_return->u.vstring->len = 0;
293
+	  else
294
+	    result_return->u.vstring->data[0] = n->u.vstring->data[ui];
295
+	}
296
+      /* ***************************************************************** */
297
+      else if (method == ctx->s_charCodeAt)
298
+	{
299
+	  if (args->u.vinteger == 0)
300
+	    ui = 0;
301
+	  else if (args->u.vinteger == 1)
302
+	    {
303
+	      if (args[1].type != JS_INTEGER)
304
+		goto argument_type_error;
305
+	      ui = args[1].u.vinteger;
306
+	    }
307
+	  else
308
+	    goto argument_error;
309
+
310
+	  if (ui >= n->u.vstring->len)
311
+	    {
312
+	      sprintf (vm->error, "String.%s(): index out of range",
313
+		       js_vm_symname (vm, method));
314
+	      js_vm_error (vm);
315
+	    }
316
+
317
+	  result_return->type = JS_INTEGER;
318
+	  result_return->u.vinteger = n->u.vstring->data[ui];
319
+	}
320
+      /* ***************************************************************** */
321
+      else if (method == ctx->s_concat)
322
+	{
323
+	  int nlen, pos;
324
+
325
+	  /* Count the new length. */
326
+
327
+	  nlen = n->u.vstring->len;
328
+
329
+	  for (i = 0; i < args->u.vinteger; i++)
330
+	    {
331
+	      if (args[i + 1].type != JS_STRING)
332
+		goto argument_type_error;
333
+	      nlen += args[i + 1].u.vstring->len;
334
+	    }
335
+
336
+	  js_vm_make_string (vm, result_return, NULL, nlen);
337
+
338
+	  memcpy (result_return->u.vstring->data, n->u.vstring->data,
339
+		  n->u.vstring->len);
340
+
341
+	  /* Append the argumens. */
342
+
343
+	  pos = n->u.vstring->len;
344
+
345
+	  for (i = 0; i < args->u.vinteger; i++)
346
+	    {
347
+	      memcpy (result_return->u.vstring->data + pos,
348
+		      args[i + 1].u.vstring->data, args[i + 1].u.vstring->len);
349
+	      pos += args[i + 1].u.vstring->len;
350
+	    }
351
+	}
352
+      /* ***************************************************************** */
353
+      else if (method == ctx->s_crc32)
354
+	{
355
+	  if (args->u.vinteger != 0)
356
+	    goto argument_error;
357
+
358
+	  result_return->type = JS_INTEGER;
359
+	  result_return->u.vinteger = js_crc32 (n->u.vstring->data,
360
+						n->u.vstring->len);
361
+	}
362
+      /* ***************************************************************** */
363
+      else if (method == ctx->s_indexOf)
364
+	{
365
+	  int start_index = 0;
366
+
367
+	  if (args->u.vinteger < 1 || args->u.vinteger > 2)
368
+	    goto argument_error;
369
+	  if (args[1].type != JS_STRING)
370
+	    goto argument_type_error;
371
+
372
+	  if (args->u.vinteger == 2)
373
+	    {
374
+	      if (args[2].type != JS_INTEGER)
375
+		goto argument_type_error;
376
+
377
+	      start_index = args[2].u.vinteger;
378
+	    }
379
+
380
+	  result_return->type = JS_INTEGER;
381
+	  result_return->u.vinteger = -1;
382
+
383
+	  if (start_index >= 0
384
+	      && start_index + args[1].u.vstring->len <= n->u.vstring->len)
385
+	    {
386
+	      /* Use the Brute Force Luke! */
387
+	      for (; start_index + args[1].u.vstring->len <= n->u.vstring->len;
388
+		   start_index++)
389
+		if (memcmp (n->u.vstring->data + start_index,
390
+			    args[1].u.vstring->data,
391
+			    args[1].u.vstring->len) == 0)
392
+		  {
393
+		    result_return->u.vinteger = start_index;
394
+		    break;
395
+		  }
396
+	    }
397
+	}
398
+      /* ***************************************************************** */
399
+      else if (method == ctx->s_lastIndexOf)
400
+	{
401
+	  int start_index;
402
+
403
+	  if (args->u.vinteger < 1 || args->u.vinteger > 2)
404
+	    goto argument_error;
405
+	  if (args[1].type != JS_STRING)
406
+	    goto argument_type_error;
407
+
408
+	  if (args->u.vinteger == 2)
409
+	    {
410
+	      if (args[2].type != JS_INTEGER)
411
+		goto argument_type_error;
412
+
413
+	      start_index = args[2].u.vinteger;
414
+	    }
415
+	  else
416
+	    start_index = n->u.vstring->len - args[1].u.vstring->len;
417
+
418
+	  result_return->type = JS_INTEGER;
419
+	  result_return->u.vinteger = -1;
420
+
421
+	  if (start_index >= 0
422
+	      && start_index + args[1].u.vstring->len <= n->u.vstring->len)
423
+	    {
424
+	      for (; start_index >= 0; start_index--)
425
+		if (memcmp (n->u.vstring->data + start_index,
426
+			    args[1].u.vstring->data,
427
+			    args[1].u.vstring->len) == 0)
428
+		  {
429
+		    result_return->u.vinteger = start_index;
430
+		    break;
431
+		  }
432
+	    }
433
+	}
434
+      /* ***************************************************************** */
435
+      else if (method == ctx->s_match)
436
+	{
437
+	  if (args->u.vinteger != 1)
438
+	    goto argument_error;
439
+
440
+	  if (args[1].type != JS_BUILTIN
441
+	      || args[1].u.vbuiltin->info != ctx->regexp_info)
442
+	    goto argument_type_error;
443
+
444
+	  js_builtin_RegExp_match (vm, n->u.vstring->data, n->u.vstring->len,
445
+				   &args[1], result_return);
446
+	}
447
+      /* ***************************************************************** */
448
+      else if (method == ctx->s_replace)
449
+	{
450
+	  if (args->u.vinteger != 2)
451
+	    goto argument_error;
452
+
453
+	  if (args[1].type != JS_BUILTIN
454
+	      || args[1].u.vbuiltin->info != ctx->regexp_info
455
+	      || args[2].type != JS_STRING)
456
+	    goto argument_type_error;
457
+
458
+	  js_builtin_RegExp_replace (vm, n->u.vstring->data, n->u.vstring->len,
459
+				     &args[1], args[2].u.vstring->data,
460
+				     args[2].u.vstring->len, result_return);
461
+	}
462
+      /* ***************************************************************** */
463
+      else if (method == ctx->s_search)
464
+	{
465
+	  if (args->u.vinteger != 1)
466
+	    goto argument_error;
467
+
468
+	  if (args[1].type != JS_BUILTIN
469
+	      || args[1].u.vbuiltin->info != ctx->regexp_info)
470
+	    goto argument_type_error;
471
+
472
+	  js_builtin_RegExp_search (vm, n->u.vstring->data, n->u.vstring->len,
473
+				    &args[1], result_return);
474
+	}
475
+      /* ***************************************************************** */
476
+      else if (method == ctx->s_slice)
477
+	{
478
+	  int start, end;
479
+
480
+	  if (args->u.vinteger != 1 && args->u.vinteger != 2)
481
+	    goto argument_error;
482
+
483
+	  if (args[1].type != JS_INTEGER)
484
+	    goto argument_type_error;
485
+
486
+	  start = args[1].u.vinteger;
487
+	  if (start < 0)
488
+	    start += n->u.vstring->len;
489
+	  if (start < 0)
490
+	    start = 0;
491
+	  if (start > n->u.vstring->len)
492
+	    start = n->u.vstring->len;
493
+
494
+	  if (args->u.vinteger == 2)
495
+	    {
496
+	      if (args[2].type != JS_INTEGER)
497
+		goto argument_type_error;
498
+
499
+	      end = args[2].u.vinteger;
500
+	      if (end < 0)
501
+		end += n->u.vstring->len;
502
+	      if (end < 0)
503
+		end = 0;
504
+	      if (end > n->u.vstring->len)
505
+		end = n->u.vstring->len;
506
+	    }
507
+	  else
508
+	    end = n->u.vstring->len;
509
+
510
+	  if (start > end)
511
+	    end = start;
512
+
513
+	  js_vm_make_string (vm, result_return, n->u.vstring->data + start,
514
+			     end - start);
515
+	}
516
+      /* ***************************************************************** */
517
+      else if (method == ctx->s_split)
518
+	{
519
+	  if (args->u.vinteger == 0)
520
+	    {
521
+	      js_vm_make_array (vm, result_return, 1);
522
+	      js_vm_make_string (vm, &result_return->u.varray->data[0],
523
+				 n->u.vstring->data, n->u.vstring->len);
524
+	    }
525
+	  else
526
+	    {
527
+	      unsigned int limit;
528
+
529
+	      if (args->u.vinteger == 1)
530
+		limit = -1;
531
+	      else if (args->u.vinteger == 2)
532
+		{
533
+		  if (args[2].type != JS_INTEGER)
534
+		    goto argument_type_error;
535
+
536
+		  limit = args[2].u.vinteger;
537
+		}
538
+	      else
539
+		goto argument_error;
540
+
541
+	      if (args[1].type == JS_STRING)
542
+		{
543
+		  unsigned int start = 0, pos;
544
+		  unsigned int alen = 0;
545
+
546
+		  js_vm_make_array (vm, result_return, alen);
547
+
548
+		  for (pos = 0;
549
+		       (alen < limit
550
+			&& pos + args[1].u.vstring->len <= n->u.vstring->len);
551
+		       )
552
+		    {
553
+		      if (memcmp (n->u.vstring->data + pos,
554
+				  args[1].u.vstring->data,
555
+				  args[1].u.vstring->len) == 0)
556
+			{
557
+			  /* Found the separator. */
558
+			  js_vm_expand_array (vm, result_return, alen + 1);
559
+			  js_vm_make_string (vm,
560
+					     &(result_return
561
+					       ->u.varray->data[alen]),
562
+					     n->u.vstring->data + start,
563
+					     pos - start);
564
+			  alen++;
565
+
566
+			  if (args[1].u.vstring->len == 0)
567
+			    {
568
+			      start = pos;
569
+			      pos++;
570
+			    }
571
+			  else
572
+			    {
573
+			      pos += args[1].u.vstring->len;
574
+			      start = pos;
575
+			    }
576
+			}
577
+		      else
578
+			pos++;
579
+		    }
580
+
581
+		  if (alen < limit)
582
+		    {
583
+		      /* And finally, insert all leftovers. */
584
+		      js_vm_expand_array (vm, result_return, alen + 1);
585
+		      js_vm_make_string (vm,
586
+					 &result_return->u.varray->data[alen],
587
+					 n->u.vstring->data + start,
588
+					 n->u.vstring->len - start);
589
+		    }
590
+		}
591
+	      else if (args[1].type == JS_BUILTIN
592
+		       && args[1].u.vbuiltin->info == ctx->regexp_info)
593
+		{
594
+		  js_builtin_RegExp_split (vm, n->u.vstring->data,
595
+					   n->u.vstring->len, &args[1],
596
+					   limit, result_return);
597
+		}
598
+	      else
599
+		goto argument_type_error;
600
+	    }
601
+	}
602
+      /* ***************************************************************** */
603
+      else if (method == ctx->s_substr)
604
+	{
605
+	  int start, length;
606
+
607
+	  if (args->u.vinteger != 1 && args->u.vinteger != 2)
608
+	    goto argument_error;
609
+
610
+	  if (args[1].type != JS_INTEGER)
611
+	    goto argument_type_error;
612
+
613
+	  start = args[1].u.vinteger;
614
+
615
+	  if (args->u.vinteger == 2)
616
+	    {
617
+	      if (args[2].type != JS_INTEGER)
618
+		goto argument_type_error;
619
+
620
+	      length = args[2].u.vinteger;
621
+	      if (length < 0)
622
+		length = 0;
623
+	    }
624
+	  else
625
+	    length = n->u.vstring->len;
626
+
627
+	  if (start < 0)
628
+	    start += n->u.vstring->len;
629
+	  if (start < 0)
630
+	    start = 0;
631
+	  if (start > n->u.vstring->len)
632
+	    start = n->u.vstring->len;
633
+
634
+	  if (start + length > n->u.vstring->len)
635
+	    length = n->u.vstring->len - start;
636
+
637
+	  js_vm_make_string (vm, result_return, n->u.vstring->data + start,
638
+			     length);
639
+	}
640
+      /* ***************************************************************** */
641
+      else if (method == ctx->s_substring)
642
+	{
643
+	  int start, end;
644
+
645
+	  if (args->u.vinteger != 1 && args->u.vinteger != 2)
646
+	    goto argument_error;
647
+
648
+	  if (args[1].type != JS_INTEGER)
649
+	    goto argument_type_error;
650
+
651
+	  start = args[1].u.vinteger;
652
+
653
+	  if (args->u.vinteger == 2)
654
+	    {
655
+	      if (args[2].type != JS_INTEGER)
656
+		goto argument_type_error;
657
+
658
+	      end = args[2].u.vinteger;
659
+	    }
660
+	  else
661
+	    end = n->u.vstring->len;
662
+
663
+	  if (start < 0)
664
+	    start = 0;
665
+
666
+	  if (end > n->u.vstring->len)
667
+	    end = n->u.vstring->len;
668
+
669
+	  if (start > end)
670
+	    {
671
+	      sprintf (vm->error,
672
+		       "String.%s(): start index is bigger than end",
673
+		       js_vm_symname (vm, method));
674
+	      js_vm_error (vm);
675
+	    }
676
+
677
+	  js_vm_make_string (vm, result_return, n->u.vstring->data + start,
678
+			     end - start);
679
+	}
680
+      /* ***************************************************************** */
681
+      else if (method == ctx->s_toLowerCase)
682
+	{
683
+	  if (args->u.vinteger != 0)
684
+	    goto argument_type_error;
685
+
686
+	  js_vm_make_string (vm, result_return, n->u.vstring->data,
687
+			     n->u.vstring->len);
688
+
689
+	  for (i = 0; i < result_return->u.vstring->len; i++)
690
+	    result_return->u.vstring->data[i]
691
+	      = js_latin1_tolower[result_return->u.vstring->data[i]];
692
+	}
693
+      /* ***************************************************************** */
694
+      else if (method == ctx->s_toUpperCase)
695
+	{
696
+	  if (args->u.vinteger != 0)
697
+	    goto argument_type_error;
698
+
699
+	  js_vm_make_string (vm, result_return, n->u.vstring->data,
700
+			     n->u.vstring->len);
701
+
702
+	  for (i = 0; i < result_return->u.vstring->len; i++)
703
+	    result_return->u.vstring->data[i]
704
+	      = js_latin1_toupper[result_return->u.vstring->data[i]];
705
+	}
706
+      /* ***************************************************************** */
707
+      else if (method == ctx->s_unpack)
708
+	{
709
+	  unsigned int op;
710
+	  unsigned char *buffer;
711
+	  unsigned int buflen;
712
+	  unsigned int bufpos = 0;
713
+	  JSUInt32 ui;
714
+	  unsigned int result_len = 0;
715
+	  JSNode *rnode;
716
+
717
+	  if (args->u.vinteger != 1)
718
+	    goto argument_error;
719
+	  if (args[1].type != JS_STRING)
720
+	    goto argument_type_error;
721
+
722
+	  buffer = n->u.vstring->data;
723
+	  buflen = n->u.vstring->len;
724
+
725
+	  js_vm_make_array (vm, result_return, 0);
726
+
727
+	  for (op = 0; op < args[1].u.vstring->len; op++)
728
+	    {
729
+	      switch (args[1].u.vstring->data[op])
730
+		{
731
+		case 'C':
732
+		  UNPACK_NEED (1);
733
+		  UNPACK_EXPAND ();
734
+		  rnode->type = JS_INTEGER;
735
+		  rnode->u.vinteger = buffer[bufpos++];
736
+		  break;
737
+
738
+		case 'n':
739
+		  UNPACK_NEED (2);
740
+		  UNPACK_EXPAND ();
741
+
742
+		  ui = buffer[bufpos++];
743
+		  ui <<= 8;
744
+		  ui |= buffer[bufpos++];
745
+
746
+		  rnode->type = JS_INTEGER;
747
+		  rnode->u.vinteger = ui;
748
+		  break;
749
+
750
+		case 'N':
751
+		  UNPACK_NEED (4);
752
+		  UNPACK_EXPAND ();
753
+
754
+		  ui = buffer[bufpos++];
755
+		  ui <<= 8;
756
+		  ui |= buffer[bufpos++];
757
+		  ui <<= 8;
758
+		  ui |= buffer[bufpos++];
759
+		  ui <<= 8;
760
+		  ui |= buffer[bufpos++];
761
+
762
+		  rnode->type = JS_INTEGER;
763
+		  rnode->u.vinteger = ui;
764
+		  break;
765
+
766
+		case 'd':
767
+		  UNPACK_NEED (8);
768
+		  UNPACK_EXPAND ();
769
+
770
+		  rnode->type = JS_FLOAT;
771
+		  memcpy (&rnode->u.vfloat, buffer + bufpos, 8);
772
+		  bufpos += 8;
773
+		  break;
774
+
775
+		default:
776
+		  /* Silently ignore it. */
777
+		  break;
778
+		}
779
+	    }
780
+	}
781
+      /* ***************************************************************** */
782
+      else
783
+	return JS_PROPERTY_UNKNOWN;
784
+    }
785
+  else
786
+    return JS_PROPERTY_UNKNOWN;
787
+
788
+  return JS_PROPERTY_FOUND;
789
+
790
+
791
+  /*
792
+   * Error handling.
793
+   */
794
+
795
+ argument_error:
796
+  sprintf (vm->error, "String.%s(): illegal amount of arguments",
797
+	   js_vm_symname (vm, method));
798
+  js_vm_error (vm);
799
+
800
+ argument_type_error:
801
+  sprintf (vm->error, "String %s(): illegal argument",
802
+	   js_vm_symname (vm, method));
803
+  js_vm_error (vm);
804
+
805
+  /* NOTREACHED */
806
+  return 0;
807
+}
808
+
809
+
810
+/* Property proc. */
811
+static int
812
+property (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info,
813
+	  void *instance_context, JSSymbol property, int set, JSNode *node)
814
+{
815
+  StringCtx *ctx = builtin_info->obj_context;
816
+  JSNode *n = instance_context;
817
+
818
+  if (n && property == ctx->s_length)
819
+    {
820
+      if (set)
821
+	goto immutable;
822
+
823
+      node->type = JS_INTEGER;
824
+      node->u.vinteger = n->u.vstring->len;
825
+    }
826
+  else
827
+    {
828
+      if (!set)
829
+	node->type = JS_UNDEFINED;
830
+
831
+      return JS_PROPERTY_UNKNOWN;
832
+    }
833
+
834
+  return JS_PROPERTY_FOUND;
835
+
836
+
837
+  /*
838
+   * Error handling.
839
+   */
840
+
841
+ immutable:
842
+  sprintf (vm->error, "String.%s: immutable property",
843
+	   js_vm_symname (vm, property));
844
+  js_vm_error (vm);
845
+
846
+  /* NOTREACHED. */
847
+  return 0;
848
+}
849
+
850
+
851
+/* New proc. */
852
+static void
853
+new_proc (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, JSNode *args,
854
+	  JSNode *result_return)
855
+{
856
+  JSNode source_n;
857
+  JSNode *source;
858
+
859
+  if (args->u.vinteger == 0)
860
+    js_vm_make_string (vm, result_return, NULL, 0);
861
+  else if (args->u.vinteger == 1)
862
+    {
863
+      if (args[1].type == JS_STRING)
864
+	source = &args[1];
865
+      else
866
+	{
867
+	  js_vm_to_string (vm, &args[1], &source_n);
868
+	  source = &source_n;
869
+	}
870
+
871
+      js_vm_make_string (vm, result_return, source->u.vstring->data,
872
+			 source->u.vstring->len);
873
+    }
874
+  else
875
+    {
876
+      sprintf (vm->error, "new String(): illegal amount of arguments");
877
+      js_vm_error (vm);
878
+    }
879
+
880
+  /* Set the [[Prototype]] and [[Class]] properties. */
881
+  /* XXX 15.8.2 */
882
+}
883
+
884
+/*
885
+ * Global functions.
886
+ */
887
+
888
+void
889
+js_builtin_String (JSVirtualMachine *vm)
890
+{
891
+  StringCtx *ctx;
892
+  JSNode *n;
893
+  JSBuiltinInfo *info;
894
+
895
+  ctx = js_calloc (vm, 1, sizeof (*ctx));
896
+
897
+  ctx->s_length		= js_vm_intern (vm, "length");
898
+
899
+  ctx->s_append		= js_vm_intern (vm, "append");
900
+  ctx->s_charAt		= js_vm_intern (vm, "charAt");
901
+  ctx->s_charCodeAt	= js_vm_intern (vm, "charCodeAt");
902
+  ctx->s_concat		= js_vm_intern (vm, "concat");
903
+  ctx->s_crc32		= js_vm_intern (vm, "crc32");
904
+  ctx->s_fromCharCode	= js_vm_intern (vm, "fromCharCode");
905
+  ctx->s_indexOf	= js_vm_intern (vm, "indexOf");
906
+  ctx->s_lastIndexOf	= js_vm_intern (vm, "lastIndexOf");
907
+  ctx->s_match		= js_vm_intern (vm, "match");
908
+  ctx->s_pack		= js_vm_intern (vm, "pack");
909
+  ctx->s_replace	= js_vm_intern (vm, "replace");
910
+  ctx->s_search		= js_vm_intern (vm, "search");
911
+  ctx->s_slice		= js_vm_intern (vm, "slice");
912
+  ctx->s_split		= js_vm_intern (vm, "split");
913
+  ctx->s_substr		= js_vm_intern (vm, "substr");
914
+  ctx->s_substring	= js_vm_intern (vm, "substring");
915
+  ctx->s_toLowerCase	= js_vm_intern (vm, "toLowerCase");
916
+  ctx->s_toUpperCase	= js_vm_intern (vm, "toUpperCase");
917
+  ctx->s_unpack		= js_vm_intern (vm, "unpack");
918
+
919
+  info = js_vm_builtin_info_create (vm);
920
+  vm->prim[JS_STRING] = info;
921
+
922
+  info->global_method_proc	= global_method;
923
+  info->method_proc 		= method;
924
+  info->property_proc		= property;
925
+  info->new_proc		= new_proc;
926
+  info->obj_context		= ctx;
927
+  info->obj_context_delete	= js_free;
928
+
929
+  /* Define it. */
930
+  n = &vm->globals[js_vm_intern (vm, "String")];
931
+  js_vm_builtin_create (vm, n, info, NULL);
932
+
933
+  /* Fetch the JSBuiltinInfo of the RegExp object. */
934
+  n = &vm->globals[js_vm_intern (vm, "RegExp")];
935
+  ctx->regexp_info = n->u.vbuiltin->info;
936
+}
0 937
new file mode 100644
... ...
@@ -0,0 +1,521 @@
0
+/*
1
+ * The builtin System object.
2
+ * Copyright (c) 1998-1999 New Generation Software (NGS) Oy
3
+ *
4
+ * Author: Markku Rossi <mtr@ngs.fi>
5
+ */
6
+
7
+/*
8
+ * This library is free software; you can redistribute it and/or
9
+ * modify it under the terms of the GNU Library General Public
10
+ * License as published by the Free Software Foundation; either
11
+ * version 2 of the License, or (at your option) any later version.
12
+ *
13
+ * This library is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
+ * Library General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU Library General Public
19
+ * License along with this library; if not, write to the Free
20
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
21
+ * MA 02111-1307, USA
22
+ */
23
+
24
+/*
25
+ * $Source: /tmp/cvsroot-15-2-2007/clamav-devel/libclamav/js/b_system.c,v $
26
+ * $Id: b_system.c,v 1.1 2006/10/19 17:28:58 njh Exp $
27
+ */
28
+
29
+/*
30
+ * Static methods:
31
+ *
32
+ *   chdir (string) => boolean
33
+ *   error ([ANY...]) => undefined
34
+ *   exit (value)
35
+ *   getcwd () => string
36
+ *   getenv (string) => string / undefined
37
+ *   popen (COMMAND, MODE) => file
38
+ *   print ([ANY...]) => undefined
39
+ *   sleep (int) => undefined
40
+ *   strerror (errno) => string
41
+ *   system (string) => integer
42
+ *   usleep (int) => undefined
43
+ *
44
+ * Properties:			type		mutable
45
+ *
46
+ *   bits			integer
47
+ *   canonicalHost		string
48
+ *   canonicalHostCPU		string
49
+ *   canonicalHostVendor	string
50
+ *   canonicalHostOS		string
51
+ *   errno			integer
52
+ *   lineBreakSequence		string
53
+ *   stderr			file
54
+ *   stdin			file
55
+ *   stdout			file
56
+ */
57
+
58
+#include "jsint.h"
59
+
60
+/*
61
+ * Types and definitions.
62
+ */
63
+
64
+#define INSECURE()		\
65
+  do {				\
66
+    if (secure_mode)		\
67
+      goto insecure_feature;	\
68
+  } while (0)
69
+
70
+struct system_ctx_st
71
+{
72
+  JSSymbol s_chdir;
73
+  JSSymbol s_error;
74
+  JSSymbol s_exit;
75
+  JSSymbol s_getcwd;
76
+  JSSymbol s_getenv;
77
+  JSSymbol s_popen;
78
+  JSSymbol s_print;
79
+  JSSymbol s_sleep;
80
+  JSSymbol s_strerror;
81
+  JSSymbol s_system;
82
+  JSSymbol s_usleep;
83
+
84
+  JSSymbol s_bits;
85
+  JSSymbol s_canonicalHost;
86
+  JSSymbol s_canonicalHostCPU;
87
+  JSSymbol s_canonicalHostVendor;
88
+  JSSymbol s_canonicalHostOS;
89
+  JSSymbol s_errno;
90
+  JSSymbol s_lineBreakSequence;
91
+  JSSymbol s_stderr;
92
+  JSSymbol s_stdin;
93
+  JSSymbol s_stdout;
94
+
95
+  /* System file handles. */
96
+  JSNode pstderr;
97
+  JSNode pstdin;
98
+  JSNode pstdout;
99
+};
100
+
101
+typedef struct system_ctx_st SystemCtx;
102
+
103
+
104
+/*
105
+ * Static functions.
106
+ */
107
+
108
+/* Method proc */
109
+static int
110
+method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info,
111
+	void *instance_context, JSSymbol method, JSNode *result_return,
112
+	JSNode *args)
113
+{
114
+  SystemCtx *ctx = builtin_info->obj_context;
115
+  int i;
116
+  char *cp;
117
+  int secure_mode = vm->security & JS_VM_SECURE_SYSTEM;
118
+
119
+  /* The default result. */
120
+  result_return->type = JS_UNDEFINED;
121
+
122
+  if (method == ctx->s_chdir)
123
+    {
124
+      INSECURE ();
125
+
126
+      if (args->u.vinteger != 1)
127
+	goto argument_error;
128
+      if (args[1].type != JS_STRING)
129
+	goto argument_type_error;
130
+
131
+      result_return->type= JS_BOOLEAN;
132
+
133
+      cp = js_string_to_c_string (vm, &args[1]);
134
+      result_return->u.vboolean = (chdir (cp) == 0);
135
+      js_free (cp);
136
+    }
137
+  /* ********************************************************************** */
138
+  else if (method == ctx->s_exit)
139
+    {
140
+      INSECURE ();
141
+
142
+      if (args->u.vinteger != 1)
143
+	goto argument_error;
144
+      if (args[1].type != JS_INTEGER)
145
+	goto argument_type_error;
146
+
147
+      /* Exit. */
148
+      exit (args[1].u.vinteger);
149
+    }
150
+  /* ********************************************************************** */
151
+  else if (method == ctx->s_getcwd)
152
+    {
153
+      int size = 10 * 1024;
154
+
155
+      INSECURE ();
156
+
157
+      if (args->u.vinteger != 0)
158
+	goto argument_error;
159
+
160
+      cp = js_malloc (vm, size);
161
+      if (!getcwd (cp, size))
162
+	{
163
+	  result_return->type = JS_BOOLEAN;
164
+	  result_return->u.vboolean = 0;
165
+	  js_free (cp);
166
+	}
167
+      else
168
+	{
169
+	  js_vm_make_string (vm, result_return, cp, strlen (cp));
170
+	  js_free (cp);
171
+	}
172
+    }
173
+  /* ********************************************************************** */
174
+  else if (method == ctx->s_getenv)
175
+    {
176
+      char *val;
177
+
178
+      if (args->u.vinteger != 1)
179
+	goto argument_error;
180
+      if (args[1].type != JS_STRING)
181
+	goto argument_type_error;
182
+
183
+      cp = js_string_to_c_string (vm, &args[1]);
184
+      val = getenv (cp);
185
+      js_free (cp);
186
+
187
+      if (val)
188
+	js_vm_make_string (vm, result_return, val, strlen (val));
189
+    }
190
+  /* ********************************************************************** */
191
+  else if (method == ctx->s_popen)
192
+    {
193
+      char *cmd, *mode;
194
+      FILE *fp;
195
+      int readp = 0;
196
+
197
+      INSECURE ();
198
+
199
+      if (args->u.vinteger != 2)
200
+	goto argument_error;
201
+      if (args[1].type != JS_STRING || args[2].type != JS_STRING
202
+	  || args[2].u.vstring->len > 10)
203
+	goto argument_type_error;
204
+
205
+      cmd = js_string_to_c_string (vm, &args[1]);
206
+      mode = js_string_to_c_string (vm, &args[2]);
207
+
208
+      for (i = 0; mode[i]; i++)
209
+	if (mode[i] == 'r')
210
+	  readp = 1;
211
+
212
+      JS_VM_ALLOCATE_FD (vm, "System.popen()");
213
+      fp = popen (cmd, mode);
214
+
215
+      if (fp == NULL)
216
+	JS_VM_FREE_FD (vm);
217
+      else
218
+	js_builtin_File_new (vm, result_return, cmd,
219
+			     js_iostream_pipe (fp, readp), 0);
220
+
221
+      js_free (cmd);
222
+      js_free (mode);
223
+    }
224
+  /* ********************************************************************** */
225
+  else if (method == ctx->s_print || method == ctx->s_error)
226
+    {
227
+      JSIOStream *stream;
228
+
229
+      if (method == ctx->s_print)
230
+	stream = vm->s_stdout;
231
+      else
232
+	stream = vm->s_stderr;
233
+
234
+      for (i = 1; i <= args->u.vinteger; i++)
235
+	{
236
+	  JSNode result;
237
+
238
+	  js_vm_to_string (vm, &args[i], &result);
239
+	  js_iostream_write (stream, result.u.vstring->data,
240
+			     result.u.vstring->len);
241
+	}
242
+    }
243
+  /* ********************************************************************** */
244
+  else if (method == ctx->s_sleep)
245
+    {
246
+      if (args->u.vinteger != 1)
247
+	goto argument_error;
248
+      if (args[1].type != JS_INTEGER)
249
+	goto argument_type_error;
250
+
251
+      sleep (args[1].u.vinteger);
252
+    }
253
+  /* ********************************************************************** */
254
+  else if (method == ctx->s_strerror)
255
+    {
256
+      if (args->u.vinteger != 1)
257
+	goto argument_error;
258
+      if (args[1].type != JS_INTEGER)
259
+	goto argument_type_error;
260
+
261
+      cp = strerror (args[1].u.vinteger);
262
+      js_vm_make_string (vm, result_return, cp, strlen (cp));
263
+    }
264
+  /* ********************************************************************** */
265
+  else if (method == ctx->s_system)
266
+    {
267
+      INSECURE ();
268
+
269
+      if (args->u.vinteger != 1)
270
+	goto argument_error;
271
+      if (args[1].type != JS_STRING)
272
+	goto argument_type_error;
273
+
274
+      result_return->type = JS_INTEGER;
275
+
276
+      cp = js_string_to_c_string (vm, &args[1]);
277
+      result_return->u.vinteger = system (cp);
278
+      js_free (cp);
279
+    }
280
+  /* ********************************************************************** */
281
+  else if (method == vm->syms.s_toString)
282
+    {
283
+      if (args->u.vinteger != 0)
284
+	goto argument_error;
285
+
286
+      js_vm_make_static_string (vm, result_return, "System", 6);
287
+    }
288
+  /* ********************************************************************** */
289
+  else if (method == ctx->s_usleep)
290
+    {
291
+      if (args->u.vinteger != 1)
292
+	goto argument_error;
293
+      if (args[1].type != JS_INTEGER)
294
+	goto argument_type_error;
295
+
296
+      usleep (args[1].u.vinteger);
297
+    }
298
+  /* ********************************************************************** */
299
+  else
300
+    return JS_PROPERTY_UNKNOWN;
301
+
302
+  return JS_PROPERTY_FOUND;
303
+
304
+
305
+  /*
306
+   * Error handling.
307
+   */
308
+
309
+ argument_error:
310
+  sprintf (vm->error, "System.%s(): illegal amout of arguments",
311
+	   js_vm_symname (vm, method));
312
+  js_vm_error (vm);
313
+
314
+ argument_type_error:
315
+  sprintf (vm->error, "System.%s(): illegal argument",
316
+	   js_vm_symname (vm, method));
317
+  js_vm_error (vm);
318
+
319
+ insecure_feature:
320
+  sprintf (vm->error, "System.%s(): not allowed in secure mode",
321
+	   js_vm_symname (vm, method));
322
+  js_vm_error (vm);
323
+
324
+  /* NOTREACHED */
325
+  return 0;
326
+}
327
+
328
+/* Property proc. */
329
+static int
330
+property (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info,
331
+	  void *instance_context, JSSymbol property, int set, JSNode *node)
332
+{
333
+  SystemCtx *ctx = builtin_info->obj_context;
334
+
335
+  if (property == ctx->s_bits)
336
+    {
337
+      if (set)
338
+	goto immutable;
339
+
340
+      node->type = JS_INTEGER;
341
+#if SIZEOF_INT == 2
342
+      node->u.vinteger = 16;
343
+#else /* not SIZEOF_INT == 2 */
344
+
345
+#if SIZEOF_LONG == 4
346
+      node->u.vinteger = 32;
347
+#else /* not SIZEOF_LONG == 4 */
348
+
349
+#if SIZEOF_LONG == 8
350
+      node->u.vinteger = 64;
351
+#else /* not SIZEOF_LONG == 8 */
352
+
353
+      /* Do not know. */
354
+      node->u.vinteger = 0;
355
+
356
+#endif /* not SIZEOF_LONG == 8 */
357
+#endif /* not SIZEOF_LONG == 4 */
358
+#endif /* not SIZEOF_INT == 2 */
359
+    }
360
+  else if (property == ctx->s_canonicalHost)
361
+    {
362
+      if (set)
363
+	goto immutable;
364
+
365
+      js_vm_make_static_string (vm, node, CANONICAL_HOST,
366
+				strlen (CANONICAL_HOST));
367
+    }
368
+  else if (property == ctx->s_canonicalHostCPU)
369
+    {
370
+      if (set)
371
+	goto immutable;
372
+
373
+      js_vm_make_static_string (vm, node, CANONICAL_HOST_CPU,
374
+				strlen (CANONICAL_HOST_CPU));
375
+    }
376
+  else if (property == ctx->s_canonicalHostVendor)
377
+    {
378
+      if (set)
379
+	goto immutable;
380
+
381
+      js_vm_make_static_string (vm, node, CANONICAL_HOST_VENDOR,
382
+				strlen (CANONICAL_HOST_VENDOR));
383
+    }
384
+  else if (property == ctx->s_canonicalHostOS)
385
+    {
386
+      if (set)
387
+	goto immutable;
388
+
389
+      js_vm_make_static_string (vm, node, CANONICAL_HOST_OS,
390
+				strlen (CANONICAL_HOST_OS));
391
+    }
392
+  else if (property == ctx->s_errno)
393
+    {
394
+      if (set)
395
+	goto immutable;
396
+
397
+      node->type = JS_INTEGER;
398
+      node->u.vinteger = errno;
399
+    }
400
+  else if (property == ctx->s_lineBreakSequence)
401
+    {
402
+      if (set)
403
+	goto immutable;
404
+
405
+      js_vm_make_static_string (vm, node, JS_HOST_LINE_BREAK,
406
+				JS_HOST_LINE_BREAK_LEN);
407
+    }
408
+  else if (property == ctx->s_stderr)
409
+    {
410
+      if (set)
411
+	goto immutable;
412
+
413
+      JS_COPY (node, &ctx->pstderr);
414
+    }
415
+  else if (property == ctx->s_stdin)
416
+    {
417
+      if (set)
418
+	goto immutable;
419
+
420
+      JS_COPY (node, &ctx->pstdin);
421
+    }
422
+  else if (property == ctx->s_stdout)
423
+    {
424
+      if (set)
425
+	goto immutable;
426
+
427
+      JS_COPY (node, &ctx->pstdout);
428
+    }
429
+
430
+  else
431
+    {
432
+      if (!set)
433
+	node->type = JS_UNDEFINED;
434
+
435
+      return JS_PROPERTY_UNKNOWN;
436
+    }
437
+
438
+  return JS_PROPERTY_FOUND;
439
+
440
+
441
+  /*
442
+   * Error handling.
443
+   */
444
+
445
+ immutable:
446
+  sprintf (vm->error, "System.%s: immutable property",
447
+	   js_vm_symname (vm, property));
448
+  js_vm_error (vm);
449
+
450
+  /* NOTREACHED. */
451
+  return 0;
452
+}
453
+
454
+/* Mark proc. */
455
+static void
456
+mark (JSBuiltinInfo *builtin_info, void *instance_context)
457
+{
458
+  SystemCtx *ctx = builtin_info->obj_context;
459
+
460
+  js_vm_mark (&ctx->pstderr);
461
+  js_vm_mark (&ctx->pstdin);
462
+  js_vm_mark (&ctx->pstdout);
463
+}
464
+
465
+
466
+/*
467
+ * Global functions.
468
+ */
469
+
470
+void
471
+js_builtin_System (JSVirtualMachine *vm)
472
+{
473
+  JSNode *n;
474
+  JSBuiltinInfo *info;
475
+  SystemCtx *ctx;
476
+
477
+  ctx = js_calloc (vm, 1, sizeof (*ctx));
478
+
479
+  ctx->s_chdir			= js_vm_intern (vm, "chdir");
480
+  ctx->s_error			= js_vm_intern (vm, "error");
481
+  ctx->s_exit			= js_vm_intern (vm, "exit");
482
+  ctx->s_getcwd			= js_vm_intern (vm, "getcwd");
483
+  ctx->s_getenv			= js_vm_intern (vm, "getenv");
484
+  ctx->s_popen			= js_vm_intern (vm, "popen");
485
+  ctx->s_print			= js_vm_intern (vm, "print");
486
+  ctx->s_sleep			= js_vm_intern (vm, "sleep");
487
+  ctx->s_strerror		= js_vm_intern (vm, "strerror");
488
+  ctx->s_system			= js_vm_intern (vm, "system");
489
+  ctx->s_usleep			= js_vm_intern (vm, "usleep");
490
+
491
+  ctx->s_bits			= js_vm_intern (vm, "bits");
492
+  ctx->s_canonicalHost		= js_vm_intern (vm, "canonicalHost");
493
+  ctx->s_canonicalHostCPU	= js_vm_intern (vm, "canonicalHostCPU");
494
+  ctx->s_canonicalHostVendor	= js_vm_intern (vm, "canonicalHostVendor");
495
+  ctx->s_canonicalHostOS	= js_vm_intern (vm, "canonicalHostOS");
496
+  ctx->s_errno			= js_vm_intern (vm, "errno");
497
+  ctx->s_lineBreakSequence	= js_vm_intern (vm, "lineBreakSequence");
498
+  ctx->s_stderr			= js_vm_intern (vm, "stderr");
499
+  ctx->s_stdin			= js_vm_intern (vm, "stdin");
500
+  ctx->s_stdout			= js_vm_intern (vm, "stdout");
501
+
502
+  /* Object information. */
503
+
504
+  info = js_vm_builtin_info_create (vm);
505
+
506
+  info->method_proc 		= method;
507
+  info->property_proc		= property;
508
+  info->mark_proc		= mark;
509
+  info->obj_context 		= ctx;
510
+  info->obj_context_delete	= js_free;
511
+
512
+  /* Define it. */
513
+  n = &vm->globals[js_vm_intern (vm, "System")];
514
+  js_vm_builtin_create (vm, n, info, NULL);
515
+
516
+  /* Enter system properties. */
517
+  js_builtin_File_new (vm, &ctx->pstderr, "stdout", vm->s_stderr, 1);
518
+  js_builtin_File_new (vm, &ctx->pstdin, "stdin", vm->s_stdin, 1);
519
+  js_builtin_File_new (vm, &ctx->pstdout, "stdout", vm->s_stdout, 1);
520
+}
0 521
new file mode 100644
... ...
@@ -0,0 +1,445 @@
0
+/*
1
+ * The builtin VM object.
2
+ * Copyright (c) 1998-1999 New Generation Software (NGS) Oy
3
+ *
4
+ * Author: Markku Rossi <mtr@ngs.fi>
5
+ */
6
+
7
+/*
8
+ * This library is free software; you can redistribute it and/or
9
+ * modify it under the terms of the GNU Library General Public
10
+ * License as published by the Free Software Foundation; either
11
+ * version 2 of the License, or (at your option) any later version.
12
+ *
13
+ * This library is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
+ * Library General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU Library General Public
19
+ * License along with this library; if not, write to the Free
20
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
21
+ * MA 02111-1307, USA
22
+ */
23
+
24
+/*
25
+ * $Source: /tmp/cvsroot-15-2-2007/clamav-devel/libclamav/js/b_vm.c,v $
26
+ * $Id: b_vm.c,v 1.1 2006/10/19 17:28:58 njh Exp $
27
+ */
28
+
29
+/*
30
+ * Class:
31
+ *
32
+ * - static methods:
33
+ *
34
+ *   VM.garbageCollect ()
35
+ *   VM.stackTrace ()
36
+ *
37
+ * - properties:		type		mutable
38
+ *
39
+ *   VM.dispatchMethod		string
40
+ *   VM.fdCount                 integer
41
+ *   VM.gcCount			integer
42
+ *   VM.gcTrigger		integer		yes
43
+ *   VM.heapAllocated		integer
44
+ *   VM.heapFree		integer
45
+ *   VM.heapSize		integer
46
+ *   VM.numConstants		integer
47
+ *   VM.numGlobals		integer
48
+ *   VM.stackSize		integer
49
+ *   VM.stacktraceOnError	boolean		yes
50
+ *   VM.verbose			integer 	yes
51
+ *   VM.verboseStacktrace	boolean		yes
52
+ *   VM.version			string
53
+ *   VM.versionMajor		integer
54
+ *   VM.versionMinor		integer
55
+ *   VM.versionPatch		integer
56
+ *   VM.warnUndef		boolean		yes
57
+ */
58
+
59
+#include "jsint.h"
60
+
61
+/*
62
+ * Types and definitions.
63
+ */
64
+
65
+struct vm_ctx_st
66
+{
67
+  JSSymbol s_garbageCollect;
68
+  JSSymbol s_stackTrace;
69
+
70
+  JSSymbol s_dispatchMethod;
71
+  JSSymbol s_fdCount;
72
+  JSSymbol s_gcCount;
73
+  JSSymbol s_gcTrigger;
74
+  JSSymbol s_heapAllocated;
75
+  JSSymbol s_heapFree;
76
+  JSSymbol s_heapSize;
77
+  JSSymbol s_numConstants;
78
+  JSSymbol s_numGlobals;
79
+  JSSymbol s_stackSize;
80
+  JSSymbol s_stacktraceOnError;
81
+  JSSymbol s_verbose;
82
+  JSSymbol s_verboseStacktrace;
83
+  JSSymbol s_version;
84
+  JSSymbol s_versionMajor;
85
+  JSSymbol s_versionMinor;
86
+  JSSymbol s_versionPatch;
87
+  JSSymbol s_warnUndef;
88
+};
89
+
90
+typedef struct vm_ctx_st VMCtx;
91
+
92
+
93
+/*
94
+ * Static functions.
95
+ */
96
+
97
+/* Method proc */
98
+static int
99
+method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info,
100
+	void *instance_context, JSSymbol method, JSNode *result_return,
101
+	JSNode *args)
102
+{
103
+  VMCtx *ctx = builtin_info->obj_context;
104
+
105
+  /* The default return value is undefined. */
106
+  result_return->type = JS_UNDEFINED;
107
+
108
+  if (method == ctx->s_garbageCollect)
109
+    {
110
+      if (args->u.vinteger != 0)
111
+	goto argument_error;
112
+
113
+      /* Ok, let's trigger a garbage collection. */
114
+      vm->gc.bytes_allocated = vm->gc.trigger + 1;
115
+    }
116
+  /* ********************************************************************** */
117
+  else if (method == ctx->s_stackTrace)
118
+    {
119
+      unsigned int limit;
120
+
121
+      if (args->u.vinteger == 0)
122
+	limit = -1;
123
+      else if (args->u.vinteger == 1)
124
+	{
125
+	  if (args[1].type != JS_INTEGER)
126
+	    goto argument_type_error;
127
+
128
+	  limit = args[1].u.vinteger;
129
+	}
130
+      else
131
+	goto argument_error;
132
+
133
+      js_vm_stacktrace (vm, limit);
134
+    }
135
+  /* ********************************************************************** */
136
+  else if (method == vm->syms.s_toString)
137
+    {
138
+      if (args->u.vinteger != 0)
139
+	goto argument_error;
140
+
141
+      js_vm_make_static_string (vm, result_return, "VM", 2);
142
+    }
143
+  /* ********************************************************************** */
144
+  else
145
+    return JS_PROPERTY_UNKNOWN;
146
+
147
+  return JS_PROPERTY_FOUND;
148
+
149
+
150
+  /*
151
+   * Error handling.
152
+   */
153
+
154
+ argument_error:
155
+  sprintf (vm->error, "VM.%s(): illegal amout of arguments",
156
+	   js_vm_symname (vm, method));
157
+  js_vm_error (vm);
158
+
159
+ argument_type_error:
160
+  sprintf (vm->error, "VM.%s(): illegal argument",
161
+	   js_vm_symname (vm, method));
162
+  js_vm_error (vm);
163
+
164
+  /* NOTREACHED */
165
+  return 0;
166
+}
167
+
168
+/* Property proc. */
169
+static int
170
+property (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info,
171
+	  void *instance_context, JSSymbol property, int set, JSNode *node)
172
+{
173
+  VMCtx *ctx = builtin_info->obj_context;
174
+
175
+  if (property == ctx->s_dispatchMethod)
176
+    {
177
+      if (set)
178
+	goto immutable;
179
+
180
+      js_vm_make_static_string (vm, node,
181
+				vm->dispatch_method_name,
182
+				strlen (vm->dispatch_method_name));
183
+    }
184
+  /* ***************************************************************** */
185
+  else if (property == ctx->s_fdCount)
186
+    {
187
+      if (set)
188
+	goto immutable;
189
+
190
+      node->type = JS_INTEGER;
191
+      node->u.vinteger = vm->fd_count;
192
+    }
193
+  /* ***************************************************************** */
194
+  else if (property == ctx->s_gcCount)
195
+    {
196
+      if (set)
197
+	goto immutable;
198
+
199
+      node->type = JS_INTEGER;
200
+      node->u.vinteger = vm->gc.count;
201
+    }
202
+  /* ***************************************************************** */
203
+  else if (property == ctx->s_gcTrigger)
204
+    {
205
+      if (set)
206
+	{
207
+	  if (node->type != JS_INTEGER)
208
+	    goto value_error;
209
+	  vm->gc.trigger = node->u.vinteger;
210
+	}
211
+      else
212
+	{
213
+	  node->type = JS_INTEGER;
214
+	  node->u.vinteger = vm->gc.trigger;
215
+	}
216
+    }
217
+  /* ***************************************************************** */
218
+  else if (property == ctx->s_heapAllocated)
219
+    {
220
+      if (set)
221
+	goto immutable;
222
+
223
+      node->type = JS_INTEGER;
224
+      node->u.vinteger = vm->gc.bytes_allocated;
225
+    }
226
+  /* ***************************************************************** */
227
+  else if (property == ctx->s_heapFree)
228
+    {
229
+      if (set)
230
+	goto immutable;
231
+
232
+      node->type = JS_INTEGER;
233
+      node->u.vinteger = vm->gc.bytes_free;
234
+    }
235
+  /* ***************************************************************** */
236
+  else if (property == ctx->s_heapSize)
237
+    {
238
+      if (set)
239
+	goto immutable;
240
+
241
+      node->type = JS_INTEGER;
242
+      node->u.vinteger = vm->heap_size;
243
+    }
244
+  /* ***************************************************************** */
245
+  else if (property == ctx->s_numConstants)
246
+    {
247
+      if (set)
248
+	goto immutable;
249
+
250
+      node->type = JS_INTEGER;
251
+      node->u.vinteger = vm->num_consts;
252
+    }
253
+  /* ***************************************************************** */
254
+  else if (property == ctx->s_numGlobals)
255
+    {
256
+      if (set)
257
+	goto immutable;
258
+
259
+      node->type = JS_INTEGER;
260
+      node->u.vinteger = vm->num_globals;
261
+    }
262
+  /* ***************************************************************** */
263
+  else if (property == ctx->s_stackSize)
264
+    {
265
+      if (set)
266
+	goto immutable;
267
+
268
+      node->type = JS_INTEGER;
269
+      node->u.vinteger = vm->stack_size;
270
+    }
271
+  /* ***************************************************************** */
272
+  else if (property == ctx->s_stacktraceOnError)
273
+    {
274
+      if (set)
275
+	{
276
+	  if (node->type != JS_BOOLEAN)
277
+	    goto value_error;
278
+	  vm->stacktrace_on_error = node->u.vboolean;
279
+	}
280
+      else
281
+	{
282
+	  node->type = JS_BOOLEAN;
283
+	  node->u.vboolean = vm->stacktrace_on_error;
284
+	}
285
+    }
286
+  /* ***************************************************************** */
287
+  else if (property == ctx->s_verbose)
288
+    {
289
+      if (set)
290
+	{
291
+	  if (node->type != JS_INTEGER)
292
+	    goto value_error;
293
+	  vm->verbose = node->u.vinteger;
294
+	}
295
+      else
296
+	{
297
+	  node->type = JS_INTEGER;
298
+	  node->u.vinteger = vm->verbose;
299
+	}
300
+    }
301
+  /* ***************************************************************** */
302
+  else if (property == ctx->s_verboseStacktrace)
303
+    {
304
+      if (set)
305
+	{
306
+	  if (node->type != JS_BOOLEAN)
307
+	    goto value_error;
308
+	  vm->verbose_stacktrace = node->u.vboolean;
309
+	}
310
+      else
311
+	{
312
+	  node->type = JS_BOOLEAN;
313
+	  node->u.vboolean = vm->verbose_stacktrace;
314
+	}
315
+    }
316
+  /* ***************************************************************** */
317
+  else if (property == ctx->s_version)
318
+    {
319
+      if (set)
320
+	goto immutable;
321
+
322
+      js_vm_make_static_string (vm, node, VERSION, strlen (VERSION));
323
+    }
324
+  /* ***************************************************************** */
325
+  else if (property == ctx->s_versionMajor)
326
+    {
327
+      if (set)
328
+	goto immutable;
329
+
330
+      node->type = JS_INTEGER;
331
+      node->u.vinteger = atoi (VERSION);
332
+    }
333
+  /* ***************************************************************** */
334
+  else if (property == ctx->s_versionMinor)
335
+    {
336
+      if (set)
337
+	goto immutable;
338
+
339
+      node->type = JS_INTEGER;
340
+      node->u.vinteger = atoi (VERSION + 2);
341
+    }
342
+  /* ***************************************************************** */
343
+  else if (property == ctx->s_versionPatch)
344
+    {
345
+      if (set)
346
+	goto immutable;
347
+
348
+      node->type = JS_INTEGER;
349
+      node->u.vinteger = atoi (VERSION + 4);
350
+    }
351
+  /* ***************************************************************** */
352
+  else if (property == ctx->s_warnUndef)
353
+    {
354
+      if (set)
355
+	{
356
+	  if (node->type != JS_INTEGER)
357
+	    goto value_error;
358
+	  vm->warn_undef = node->u.vinteger != 0;
359
+	}
360
+      else
361
+	{
362
+	  node->type = JS_INTEGER;
363
+	  node->u.vinteger = vm->warn_undef;
364
+	}
365
+    }
366
+  /* ***************************************************************** */
367
+  else
368
+    {
369
+      if (!set)
370
+	node->type = JS_UNDEFINED;
371
+
372
+      return JS_PROPERTY_UNKNOWN;
373
+    }
374
+
375
+  return JS_PROPERTY_FOUND;
376
+
377
+
378
+  /*
379
+   * Error handling.
380
+   */
381
+
382
+ value_error:
383
+  sprintf (vm->error, "VM.%s: illegal value",
384
+	   js_vm_symname (vm, property));
385
+  js_vm_error (vm);
386
+
387
+ immutable:
388
+  sprintf (vm->error, "VM.%s: immutable property",
389
+	   js_vm_symname (vm, property));
390
+  js_vm_error (vm);
391
+
392
+  /* NOTREACHED. */
393
+  return 0;
394
+}
395
+
396
+
397
+/*
398
+ * Global functions.
399
+ */
400
+
401
+void
402
+js_builtin_VM (JSVirtualMachine *vm)
403
+{
404
+  JSNode *n;
405
+  JSBuiltinInfo *info;
406
+  VMCtx *ctx;
407
+
408
+  ctx = js_calloc (vm, 1, sizeof (*ctx));
409
+
410
+  ctx->s_garbageCollect		= js_vm_intern (vm, "garbageCollect");
411
+  ctx->s_stackTrace		= js_vm_intern (vm, "stackTrace");
412
+
413
+  ctx->s_dispatchMethod		= js_vm_intern (vm, "dispatchMethod");
414
+  ctx->s_fdCount		= js_vm_intern (vm, "fdCount");
415
+  ctx->s_gcCount		= js_vm_intern (vm, "gcCount");
416
+  ctx->s_gcTrigger		= js_vm_intern (vm, "gcTrigger");
417
+  ctx->s_heapAllocated		= js_vm_intern (vm, "heapAllocated");
418
+  ctx->s_heapFree		= js_vm_intern (vm, "heapFree");
419
+  ctx->s_heapSize		= js_vm_intern (vm, "heapSize");
420
+  ctx->s_numConstants		= js_vm_intern (vm, "numConstants");
421
+  ctx->s_numGlobals		= js_vm_intern (vm, "numGlobals");
422
+  ctx->s_stackSize		= js_vm_intern (vm, "stackSize");
423
+  ctx->s_stacktraceOnError	= js_vm_intern (vm, "stacktraceOnError");
424
+  ctx->s_verbose		= js_vm_intern (vm, "verbose");
425
+  ctx->s_verboseStacktrace	= js_vm_intern (vm, "verboseStacktrace");
426
+  ctx->s_version		= js_vm_intern (vm, "version");
427
+  ctx->s_versionMajor		= js_vm_intern (vm, "versionMajor");
428
+  ctx->s_versionMinor		= js_vm_intern (vm, "versionMinor");
429
+  ctx->s_versionPatch		= js_vm_intern (vm, "versionPatch");
430
+  ctx->s_warnUndef		= js_vm_intern (vm, "warnUndef");
431
+
432
+  /* Object information. */
433
+
434
+  info = js_vm_builtin_info_create (vm);
435
+
436
+  info->method_proc 		= method;
437
+  info->property_proc 		= property;
438
+  info->obj_context 		= ctx;
439
+  info->obj_context_delete	= js_free;
440
+
441
+  /* Define it. */
442
+  n = &vm->globals[js_vm_intern (vm, "VM")];
443
+  js_vm_builtin_create (vm, n, info, NULL);
444
+}
0 445
new file mode 100644
... ...
@@ -0,0 +1,224 @@
0
+/*
1
+ * Byte code handling routines.
2
+ * Copyright (c) 1998 New Generation Software (NGS) Oy
3
+ *
4
+ * Author: Markku Rossi <mtr@ngs.fi>
5
+ */
6
+
7
+/*
8
+ * This library is free software; you can redistribute it and/or
9
+ * modify it under the terms of the GNU Library General Public
10
+ * License as published by the Free Software Foundation; either
11
+ * version 2 of the License, or (at your option) any later version.
12
+ *
13
+ * This library is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
+ * Library General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU Library General Public
19
+ * License along with this library; if not, write to the Free
20
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
21
+ * MA 02111-1307, USA
22
+ */
23
+
24
+/*
25
+ * $Source: /tmp/cvsroot-15-2-2007/clamav-devel/libclamav/js/bc.c,v $
26
+ * $Id: bc.c,v 1.1 2006/10/19 17:28:58 njh Exp $
27
+ */
28
+
29
+#include "jsint.h"
30
+
31
+/*
32
+ * Global functions.
33
+ */
34
+
35
+JSByteCode *
36
+js_bc_read_file (FILE *fp)
37
+{
38
+  unsigned char header[8];
39
+  JSUInt32 ui;
40
+  int i, got;
41
+  JSByteCode *bc = NULL;
42
+
43
+  if ((i = fgetc (fp)) == '#')
44
+    {
45
+      /* Skip the first line. */
46
+      while ((i = fgetc (fp)) != EOF && i != '\n')
47
+	;
48
+      if (i == EOF)
49
+	goto format_error;
50
+    }
51
+  else
52
+    ungetc (i, fp);
53
+
54
+  got = fread (header, 4, 2, fp);
55
+  if (got != 2)
56
+    goto format_error;
57
+
58
+  JS_BC_READ_INT32 (header, ui);
59
+  if (ui != JS_BC_FILE_MAGIC)
60
+    goto format_error;
61
+
62
+  bc = js_calloc (NULL, 1, sizeof (*bc));
63
+  if (bc == NULL)
64
+    return NULL;
65
+
66
+
67
+  JS_BC_READ_INT32 (header + 4, ui);
68
+  bc->num_sects = (unsigned int) ui;
69
+
70
+  bc->sects = js_calloc (NULL, bc->num_sects, sizeof (JSBCSect));
71
+  if (bc->sects == NULL)
72
+    {
73
+      js_free (bc);
74
+      return NULL;
75
+    }
76
+
77
+  /* Read sections. */
78
+  for (i = 0; i < bc->num_sects; i++)
79
+    {
80
+      got = fread (header, 4, 2, fp);
81
+      if (got != 2)
82
+	goto format_error;
83
+
84
+      /* Get type. */
85
+      JS_BC_READ_INT32 (header, ui);
86
+      bc->sects[i].type = (int) ui;
87
+
88
+      /* Get section length. */
89
+      JS_BC_READ_INT32 (header + 4, ui);
90
+      bc->sects[i].length = (unsigned int) ui;
91
+      bc->sects[i].data = js_malloc (NULL, bc->sects[i].length + 1
92
+				     /* +1 to avoid zero allocations */);
93
+      if (bc->sects[i].data == NULL)
94
+	{
95
+	  for (i--; i >= 0; i--)
96
+	    js_free (bc->sects[i].data);
97
+
98
+	  js_free (bc->sects);
99
+	  js_free (bc);
100
+	  return NULL;
101
+	}
102
+
103
+
104
+      /* Read section's data. */
105
+      got = fread (bc->sects[i].data, 1, bc->sects[i].length, fp);
106
+      if (got != bc->sects[i].length)
107
+	goto format_error;
108
+    }
109
+
110
+  return bc;
111
+
112
+ format_error:
113
+
114
+  if (bc)
115
+    js_bc_free (bc);
116
+
117
+  return NULL;
118
+}
119
+
120
+
121
+JSByteCode *
122
+js_bc_read_data (unsigned char *data, unsigned int datalen)
123
+{
124
+  JSUInt32 ui;
125
+  unsigned int pos = 0;
126
+  int i;
127
+  JSByteCode *bc = NULL;
128
+
129
+  if (data[pos] == '#')
130
+    {
131
+      /* Skip the first line. */
132
+      for (; pos < datalen && data[pos] != '\n'; pos++)
133
+	;
134
+      if (pos >= datalen)
135
+	goto format_error;
136
+    }
137
+
138
+  if (datalen - pos < 8)
139
+    goto format_error;
140
+
141
+  JS_BC_READ_INT32 (data + pos, ui);
142
+  if (ui != JS_BC_FILE_MAGIC)
143
+    goto format_error;
144
+  pos += 4;
145
+
146
+  bc = js_calloc (NULL, 1, sizeof (*bc));
147
+  if (bc == NULL)
148
+    return NULL;
149
+
150
+  JS_BC_READ_INT32 (data + pos, ui);
151
+  bc->num_sects = (unsigned int) ui;
152
+  pos += 4;
153
+
154
+  bc->sects = js_calloc (NULL, bc->num_sects, sizeof (JSBCSect));
155
+  if (bc->sects == NULL)
156
+    {
157
+      js_free (bc);
158
+      return NULL;
159
+    }
160
+
161
+  /* Read sections. */
162
+  for (i = 0; i < bc->num_sects; i++)
163
+    {
164
+      if (datalen - pos < 8)
165
+	goto format_error;
166
+
167
+      /* Get type. */
168
+      JS_BC_READ_INT32 (data + pos, ui);
169
+      bc->sects[i].type = (int) ui;
170
+      pos += 4;
171
+
172
+      /* Get section length. */
173
+      JS_BC_READ_INT32 (data + pos, ui);
174
+      bc->sects[i].length = (unsigned int) ui;
175
+      pos += 4;
176
+
177
+      bc->sects[i].data = js_malloc (NULL, bc->sects[i].length + 1
178
+				     /* +1 to avoid zero allocations */);
179
+      if (bc->sects[i].data == NULL)
180
+	{
181
+	  for (i--; i >= 0; i--)
182
+	    js_free (bc->sects[i].data);
183
+
184
+	  js_free (bc->sects);
185
+	  js_free (bc);
186
+	  return NULL;
187
+	}
188
+
189
+      /* Read section's data. */
190
+      if (datalen - pos < bc->sects[i].length)
191
+	goto format_error;
192
+
193
+      memcpy (bc->sects[i].data, data + pos, bc->sects[i].length);
194
+      pos += bc->sects[i].length;
195
+    }
196
+
197
+  if (pos != datalen)
198
+    goto format_error;
199
+
200
+  return bc;
201
+
202
+
203
+ format_error:
204
+
205
+  if (bc)
206
+    js_bc_free (bc);
207
+
208
+  return NULL;
209
+}
210
+
211
+
212
+void
213
+js_bc_free (JSByteCode *bc)
214
+{
215
+  int i;
216
+
217
+  for (i = 0; i < bc->num_sects; i++)
218
+    if (bc->sects[i].data)
219
+      js_free (bc->sects[i].data);
220
+
221
+  js_free (bc->sects);
222
+  js_free (bc);
223
+}
0 224
new file mode 100644
... ...
@@ -0,0 +1,586 @@
0
+/*
1
+ * Dynamic memory allocation.
2
+ * Copyright (c) 1998 New Generation Software (NGS) Oy
3
+ *
4
+ * Author: Markku Rossi <mtr@ngs.fi>
5
+ */
6
+
7
+/*
8
+ * This library is free software; you can redistribute it and/or
9
+ * modify it under the terms of the GNU Library General Public
10
+ * License as published by the Free Software Foundation; either
11
+ * version 2 of the License, or (at your option) any later version.
12
+ *
13
+ * This library is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
+ * Library General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU Library General Public
19
+ * License along with this library; if not, write to the Free
20
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
21
+ * MA 02111-1307, USA
22
+ */
23
+
24
+/*
25
+ * $Source: /tmp/cvsroot-15-2-2007/clamav-devel/libclamav/js/heap.c,v $
26
+ * $Id: heap.c,v 1.1 2006/10/19 17:28:58 njh Exp $
27
+ */
28
+
29
+#include "jsint.h"
30
+
31
+/*
32
+ * Types and definitions.
33
+ */
34
+
35
+#if SIZEOF_INT == 2
36
+#define BLOCK_SIZE 	(63 * 1024)
37
+#else
38
+#define BLOCK_SIZE 	(100 * 1024)
39
+#endif
40
+
41
+/*
42
+ * The size of the minimum block that can be allocated from the heap.
43
+ * The block must be big enought to hold one pointer that is used when
44
+ * then block is entered to the freelist.
45
+ */
46
+#define MIN_ALLOC 	(sizeof (void *))
47
+
48
+#if JS_MEM_DEBUG
49
+#define MAGIC 0xfe109abe
50
+#endif
51
+
52
+/*
53
+ * Prototypes for static functions.
54
+ */
55
+
56
+static inline unsigned int
57
+list (unsigned int size)
58
+{
59
+  unsigned int list = 0;
60
+  size >>= 3;
61
+
62
+  while (size > 0)
63
+    {
64
+      size >>= 1;
65
+      list++;
66
+    }
67
+  if (list >= JS_NUM_HEAP_FREELISTS)
68
+    list = JS_NUM_HEAP_FREELISTS - 1;
69
+
70
+  return list;
71
+}
72
+
73
+
74
+static inline void
75
+delete_destroyable (JSHeapMemoryBlock *b)
76
+{
77
+  JSHeapDestroyable *destroyable
78
+    = (JSHeapDestroyable *) ((unsigned char *) b
79
+			     + sizeof (JSHeapMemoryBlock));
80
+
81
+  if (destroyable->destroy)
82
+    (*destroyable->destroy) (destroyable);
83
+}
84
+
85
+
86
+static unsigned long
87
+sweep (JSVirtualMachine *vm)
88
+{
89
+  JSHeapBlock *hb;
90
+  unsigned long bytes_in_use = 0;
91
+  int i;
92
+  unsigned int freelist;
93
+
94
+  for (i = 0; i < JS_NUM_HEAP_FREELISTS; i++)
95
+    vm->heap_freelists[i] = NULL;
96
+
97
+  vm->gc.bytes_free = 0;
98
+  vm->gc.bytes_allocated = 0;
99
+
100
+  for (hb = vm->heap; hb; hb = hb->next)
101
+    {
102
+      JSHeapMemoryBlock *b, *e, *bnext;
103
+
104
+      b = (JSHeapMemoryBlock *) ((unsigned char *) hb + sizeof (JSHeapBlock));
105
+      e = (JSHeapMemoryBlock *) ((unsigned char *) hb + sizeof (JSHeapBlock)
106
+				 + hb->size);
107
+      for (; b < e; b = bnext)
108
+	{
109
+#if JS_MEM_DEBUG
110
+	  assert (b->magic == MAGIC);
111
+#endif
112
+	  bnext = (JSHeapMemoryBlock *) ((unsigned char *) b
113
+					 + sizeof (JSHeapMemoryBlock)
114
+					 + b->size);
115
+
116
+	  if (b->flag_mark)
117
+	    {
118
+	      bytes_in_use += b->size;
119
+	      b->flag_mark = 0;
120
+	      vm->gc.bytes_allocated = b->size;
121
+	    }
122
+	  else
123
+	    {
124
+	      if (b->flag_destroyable)
125
+		delete_destroyable (b);
126
+
127
+	      /* Pack consecutive free blocks to one big block. */
128
+	      while (bnext < e && bnext->flag_mark == 0)
129
+		{
130
+#if JS_MEM_DEBUG
131
+		  assert (bnext->magic == MAGIC);
132
+#endif
133
+		  if (bnext->flag_destroyable)
134
+		    delete_destroyable (bnext);
135
+
136
+		  b->size += bnext->size + sizeof (JSHeapMemoryBlock);
137
+		  bnext = (JSHeapMemoryBlock *) ((unsigned char *) bnext
138
+						 + sizeof (JSHeapMemoryBlock)
139
+						 + bnext->size);
140
+		}
141
+
142
+	      JS_HEAP_MEMORY_BLOCK_CLEAR_FLAGS (b);
143
+
144
+	      /* Link it to the freelist. */
145
+	      freelist = list (b->size);
146
+
147
+	      ((JSHeapFreelistBlock *) b)->next = vm->heap_freelists[freelist];
148
+	      vm->heap_freelists[freelist] = b;
149
+	      vm->gc.bytes_free += b->size;
150
+	    }
151
+	}
152
+    }
153
+
154
+  return bytes_in_use;
155
+}
156
+
157
+
158
+/*
159
+ * Global functions.
160
+ */
161
+
162
+void *
163
+js_vm_alloc (JSVirtualMachine *vm, unsigned int size)
164
+{
165
+  JSHeapMemoryBlock *b, *prev;
166
+  unsigned int alloc_size;
167
+  JSHeapBlock *hb;
168
+  unsigned int to_alloc;
169
+  unsigned int freelist;
170
+  char buf[512];
171
+
172
+  /* Round it up to the next pow of two. */
173
+  for (alloc_size = MIN_ALLOC; alloc_size < size; alloc_size *= 2)
174
+    ;
175
+
176
+ retry:
177
+
178
+  /* Take first block from the freelist that is big enough for us. */
179
+  for (freelist = list (alloc_size); freelist < JS_NUM_HEAP_FREELISTS;
180
+       freelist++)
181
+    for (prev = NULL, b = vm->heap_freelists[freelist]; b;
182
+	 prev = b, b = ((JSHeapFreelistBlock *) b)->next)
183
+      if (b->size >= alloc_size)
184
+	{
185
+	  /* Ok, take this one. */
186
+	  if (prev)
187
+	    ((JSHeapFreelistBlock *) prev)->next
188
+	      = ((JSHeapFreelistBlock *) b)->next;
189
+	  else
190
+	    vm->heap_freelists[freelist] = ((JSHeapFreelistBlock *) b)->next;
191
+
192
+	  if (b->size > alloc_size + sizeof (JSHeapMemoryBlock) + MIN_ALLOC)
193
+	    {
194
+	      JSHeapMemoryBlock *nb;
195
+
196
+	      /* We can split it. */
197
+	      nb = ((JSHeapMemoryBlock *)
198
+		    ((unsigned char *) b
199
+		     + sizeof (JSHeapMemoryBlock) + alloc_size));
200
+
201
+#if JS_MEM_DEBUG
202
+	      nb->magic = MAGIC;
203
+#endif
204
+	      JS_HEAP_MEMORY_BLOCK_CLEAR_FLAGS (nb);
205
+	      nb->size = b->size - sizeof (JSHeapMemoryBlock) - alloc_size;
206
+
207
+	      vm->gc.bytes_free -= sizeof (JSHeapMemoryBlock);
208
+
209
+	      freelist = list (nb->size);
210
+	      ((JSHeapFreelistBlock *) nb)->next
211
+		= vm->heap_freelists[freelist];
212
+	      vm->heap_freelists[freelist] = nb;
213
+
214
+	      b->size = alloc_size;
215
+	    }
216
+
217
+	  JS_HEAP_MEMORY_BLOCK_CLEAR_FLAGS (b);
218
+	  vm->gc.bytes_free -= b->size;
219
+	  vm->gc.bytes_allocated += b->size;
220
+
221
+	  return (unsigned char *) b + sizeof (JSHeapMemoryBlock);
222
+	}
223
+
224
+  /* Must allocate new blocks to the freelist. */
225
+
226
+  if (alloc_size > (BLOCK_SIZE
227
+		    - sizeof (JSHeapBlock)
228
+		    - sizeof (JSHeapMemoryBlock)))
229
+    to_alloc = alloc_size + sizeof (JSHeapBlock) + sizeof (JSHeapMemoryBlock);
230
+  else
231
+    to_alloc = BLOCK_SIZE;
232
+
233
+  if (vm->verbose > 2)
234
+    {
235
+      sprintf (buf,
236
+	       "VM: heap: malloc(%u): needed=%u, size=%lu, free=%lu, allocated=%lu%s",
237
+	       to_alloc, alloc_size, vm->heap_size, vm->gc.bytes_free,
238
+	       vm->gc.bytes_allocated,
239
+	       JS_HOST_LINE_BREAK);
240
+      js_iostream_write (vm->s_stderr, buf, strlen (buf));
241
+    }
242
+
243
+  hb = js_malloc (vm, to_alloc);
244
+
245
+  vm->heap_size += to_alloc;
246
+  hb->next = vm->heap;
247
+  vm->heap = hb;
248
+  hb->size = to_alloc - sizeof (JSHeapBlock);
249
+
250
+  /* Link it to the freelist. */
251
+  b = (JSHeapMemoryBlock *) ((unsigned char *) hb + sizeof (JSHeapBlock));
252
+
253
+#if JS_MEM_DEBUG
254
+  b->magic = MAGIC;
255
+#endif
256
+  JS_HEAP_MEMORY_BLOCK_CLEAR_FLAGS (b);
257
+  b->size = hb->size - sizeof (JSHeapMemoryBlock);
258
+
259
+  freelist = list (b->size);
260
+
261
+  ((JSHeapFreelistBlock *) b)->next = vm->heap_freelists[freelist];
262
+  vm->heap_freelists[freelist] = b;
263
+
264
+  vm->gc.bytes_free += b->size;
265
+
266
+  goto retry;
267
+
268
+  /* NOTRECHED */
269
+  return NULL;
270
+}
271
+
272
+
273
+void *
274
+js_vm_alloc_destroyable (JSVirtualMachine *vm, unsigned int size)
275
+{
276
+  unsigned char *bi;
277
+  JSHeapMemoryBlock *b;
278
+
279
+  bi = js_vm_alloc (vm, size);
280
+  memset (bi, 0, size);
281
+
282
+  b = (JSHeapMemoryBlock *) (bi - sizeof (JSHeapMemoryBlock));
283
+  b->flag_destroyable = 1;
284
+
285
+  return bi;
286
+}
287
+
288
+
289
+void *
290
+js_vm_realloc (JSVirtualMachine *vm, void *ptr, unsigned int new_size)
291
+{
292
+  JSHeapMemoryBlock *b;
293
+  void *nptr;
294
+
295
+  if (ptr == NULL)
296
+    return js_vm_alloc (vm, new_size);
297
+
298
+  /* Can be use the old block? */
299
+
300
+  b = (JSHeapMemoryBlock *) ((unsigned char *) ptr
301
+			     - sizeof (JSHeapMemoryBlock));
302
+
303
+#if JS_MEM_DEBUG
304
+  assert (b->magic == MAGIC);
305
+#endif
306
+
307
+  if (b->size >= new_size)
308
+    /* Yes we can. */
309
+    return ptr;
310
+
311
+  /* No we can't.  Must allocate a new one. */
312
+  nptr = js_vm_alloc (vm, new_size);
313
+  memcpy (nptr, ptr, b->size < new_size ? b->size : new_size);
314
+
315
+  js_vm_free (vm, ptr);
316
+
317
+  return nptr;
318
+}
319
+
320
+
321
+void
322
+js_vm_free (JSVirtualMachine *vm, void *ptr)
323
+{
324
+  JSHeapMemoryBlock *b;
325
+  unsigned int freelist;
326
+
327
+  b = (JSHeapMemoryBlock *) ((unsigned char *) ptr
328
+			     - sizeof (JSHeapMemoryBlock));
329
+
330
+#if JS_MEM_DEBUG
331
+  assert (b->magic == MAGIC);
332
+#endif
333
+
334
+  freelist = list (b->size);
335
+
336
+  ((JSHeapFreelistBlock *) b)->next = vm->heap_freelists[freelist];
337
+  vm->heap_freelists[freelist] = b;
338
+  vm->gc.bytes_free += b->size;
339
+
340
+  /*
341
+   * We could try to compact the heap, but we left it to the garbage
342
+   * collection.
343
+   */
344
+}
345
+
346
+
347
+int
348
+js_vm_mark_ptr (void *ptr)
349
+{
350
+  JSHeapMemoryBlock *b;
351
+
352
+  if (ptr == NULL)
353
+    return 0;
354
+
355
+  b = (JSHeapMemoryBlock *) ((unsigned char *) ptr
356
+			     - sizeof (JSHeapMemoryBlock));
357
+#if JS_MEM_DEBUG
358
+  assert (b->magic == MAGIC);
359
+#endif
360
+
361
+  if (b->flag_mark)
362
+    return 0;
363
+
364
+  b->flag_mark = 1;
365
+
366
+  return 1;
367
+}
368
+
369
+
370
+int
371
+js_vm_is_marked_ptr (void *ptr)
372
+{
373
+  JSHeapMemoryBlock *b;
374
+
375
+  if (ptr == NULL)
376
+    return 1;
377
+
378
+  b = (JSHeapMemoryBlock *) ((unsigned char *) ptr
379
+			     - sizeof (JSHeapMemoryBlock));
380
+#if JS_MEM_DEBUG
381
+  assert (b->magic == MAGIC);
382
+#endif
383
+
384
+  if (b->flag_mark)
385
+    return 1;
386
+
387
+  return 0;
388
+}
389
+
390
+
391
+void
392
+js_vm_mark (JSNode *n)
393
+{
394
+  unsigned int i;
395
+
396
+  switch (n->type)
397
+    {
398
+    case JS_UNDEFINED:
399
+    case JS_NULL:
400
+    case JS_BOOLEAN:
401
+    case JS_INTEGER:
402
+    case JS_FLOAT:
403
+    case JS_SYMBOL:
404
+    case JS_NAN:
405
+    case JS_IPTR:
406
+    case JS_ARGS_FIX:
407
+      /* Nothing here. */
408
+      break;
409
+
410
+    case JS_STRING:
411
+      js_vm_mark_ptr (n->u.vstring);
412
+      if (!n->u.vstring->staticp)
413
+	js_vm_mark_ptr (n->u.vstring->data);
414
+
415
+      js_vm_object_mark (n->u.vstring->prototype);
416
+      break;
417
+
418
+    case JS_OBJECT:
419
+      js_vm_object_mark (n->u.vobject);
420
+      break;
421
+
422
+    case JS_ARRAY:
423
+      if (js_vm_mark_ptr (n->u.varray))
424
+	{
425
+	  js_vm_mark_ptr (n->u.varray->data);
426
+
427
+	  for (i = 0; i < n->u.varray->length; i++)
428
+	    js_vm_mark (&n->u.varray->data[i]);
429
+
430
+	  js_vm_object_mark (n->u.varray->prototype);
431
+	}
432
+      break;
433
+
434
+    case JS_BUILTIN:
435
+      if (js_vm_mark_ptr (n->u.vbuiltin))
436
+	{
437
+	  js_vm_mark_ptr (n->u.vbuiltin->info);
438
+
439
+	  js_vm_object_mark (n->u.vbuiltin->info->prototype);
440
+	  js_vm_object_mark (n->u.vbuiltin->prototype);
441
+
442
+	  if (n->u.vbuiltin->info->mark_proc)
443
+	    (*n->u.vbuiltin->info->mark_proc) (
444
+					n->u.vbuiltin->info,
445
+					n->u.vbuiltin->instance_context);
446
+	}
447
+      break;
448
+
449
+    case JS_FUNC:
450
+      js_vm_mark_ptr (n->u.vfunction);
451
+      js_vm_mark_ptr (n->u.vfunction->implementation);
452
+      js_vm_object_mark (n->u.vfunction->prototype);
453
+      break;
454
+    }
455
+}
456
+
457
+#define GC_TIMES 0
458
+
459
+void
460
+js_vm_garbage_collect (JSVirtualMachine *vm, JSNode *fp, JSNode *sp)
461
+{
462
+  unsigned int i;
463
+  unsigned long bytes_in_use;
464
+  char buf[512];
465
+#if GC_TIMES
466
+  clock_t start_clock;
467
+  clock_t after_mark_clock;
468
+  clock_t after_sweep_clock;
469
+#endif
470
+
471
+  if (vm->verbose > 1)
472
+    {
473
+      sprintf (buf,
474
+	       "VM: heap: garbage collect: num_consts=%u, num_globals=%u%s",
475
+	       vm->num_consts, vm->num_globals,
476
+	       JS_HOST_LINE_BREAK);
477
+      js_iostream_write (vm->s_stderr, buf, strlen (buf));
478
+    }
479
+
480
+  vm->gc.count++;
481
+
482
+  /* Mark */
483
+
484
+#if GC_TIMES
485
+  start_clock = clock ();
486
+#endif
487
+
488
+  /* Mark all constants. */
489
+  for (i = 0; i < vm->num_consts; i++)
490
+    js_vm_mark (&vm->consts[i]);
491
+
492
+  /* Mark all globals. */
493
+  for (i = 0; i < vm->num_globals; i++)
494
+    js_vm_mark (&vm->globals[i]);
495
+
496
+  /* Mark the buitin-infos of the core objects. */
497
+  for (i = 0; i <= JS_IPTR; i++)
498
+    js_vm_mark_ptr (vm->prim[i]);
499
+
500
+  /* Mark stack. */
501
+
502
+  /* STACKFRAME */
503
+
504
+  /* Use brute force and mark the whole stack. */
505
+  for (sp++; sp < vm->stack + vm->stack_size; sp++)
506
+    {
507
+      if (sp->type == JS_IPTR)
508
+	{
509
+	  /* Handle the stack frames here. */
510
+
511
+	  /* Skip the return address. */
512
+	  sp++;
513
+
514
+	  /* Possible with-chain. */
515
+	  if (sp->u.iptr)
516
+	    {
517
+	      JSUIntAlign *uip = sp->u.iptr;
518
+	      JSUIntAlign ui = *uip;
519
+	      JSNode *wp;
520
+
521
+	      /* Mark the with-chain block. */
522
+	      js_vm_mark_ptr (uip);
523
+
524
+	      /* Mark the objects in the with-chain. */
525
+	      wp = (JSNode *) ((unsigned char *) uip + sizeof (JSUIntAlign));
526
+
527
+	      for (i = 0; i < ui; i++)
528
+		js_vm_mark (&wp[i]);
529
+
530
+	    }
531
+	  sp++;
532
+
533
+	  /* Skip the args_fix. */
534
+	  sp++;
535
+
536
+	  /*
537
+	   * And now we point to the old_fp.  We skip it too at the
538
+	   * for-loop.
539
+	   */
540
+	}
541
+      else
542
+	/* Mark this stack item. */
543
+	js_vm_mark (sp);
544
+    }
545
+
546
+  /* Sweep all blocks and collect free nodes to the freelist. */
547
+
548
+#if GC_TIMES
549
+  after_mark_clock = clock ();
550
+#endif
551
+
552
+  bytes_in_use = sweep (vm);
553
+
554
+#if GC_TIMES
555
+  after_sweep_clock = clock ();
556
+#endif
557
+
558
+  if (vm->verbose > 1)
559
+    {
560
+      sprintf (buf, "VM: heap: bytes_in_use=%lu, bytes_free=%lu%s",
561
+	       bytes_in_use, vm->gc.bytes_free,
562
+	       JS_HOST_LINE_BREAK);
563
+      js_iostream_write (vm->s_stderr, buf, strlen (buf));
564
+    }
565
+
566
+#if GC_TIMES
567
+  if (vm->verbose > 1)
568
+    {
569
+      sprintf (buf, "VM: heap: mark_time=%.4f, sweep_time=%.4f%s",
570
+	       (double) (after_mark_clock - start_clock) / CLOCKS_PER_SEC,
571
+	       (double) (after_sweep_clock - after_mark_clock)
572
+	       / CLOCKS_PER_SEC,
573
+	       JS_HOST_LINE_BREAK);
574
+      js_iostream_write (vm->s_stderr, buf, strlen (buf));
575
+    }
576
+#endif
577
+}
578
+
579
+
580
+void
581
+js_vm_clear_heap (JSVirtualMachine *vm)
582
+{
583
+  /* Just sweep without marking. */
584
+  sweep (vm);
585
+}
0 586
new file mode 100644
... ...
@@ -0,0 +1,535 @@
0
+/*
1
+ * User object handling.
2
+ * Copyright (c) 1998 New Generation Software (NGS) Oy
3
+ *
4
+ * Author: Markku Rossi <mtr@ngs.fi>
5
+ */
6
+
7
+/*
8
+ * This library is free software; you can redistribute it and/or
9
+ * modify it under the terms of the GNU Library General Public
10
+ * License as published by the Free Software Foundation; either
11
+ * version 2 of the License, or (at your option) any later version.
12
+ *
13
+ * This library is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
+ * Library General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU Library General Public
19
+ * License along with this library; if not, write to the Free
20
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
21
+ * MA 02111-1307, USA
22
+ */
23
+
24
+/*
25
+ * $Source: /tmp/cvsroot-15-2-2007/clamav-devel/libclamav/js/object.c,v $
26
+ * $Id: object.c,v 1.1 2006/10/19 17:28:58 njh Exp $
27
+ */
28
+
29
+#include "jsint.h"
30
+
31
+/*
32
+ * Types and definitions.
33
+ */
34
+
35
+#define HASH_SIZE 128
36
+
37
+/*
38
+ * Prototypes for static functions.
39
+ */
40
+
41
+static void hash_create (JSVirtualMachine *vm, JSObject *obj);
42
+
43
+static void hash_insert (JSVirtualMachine *vm, JSObject *obj, const char *name,
44
+			 unsigned int name_len, int pos);
45
+
46
+static void hash_delete (JSVirtualMachine *vm, JSObject *obj, const char *name,
47
+			 unsigned int name_len);
48
+
49
+static int hash_lookup (JSObject *obj, char *name, unsigned int name_len);
50
+
51
+
52
+/*
53
+ * Global functions.
54
+ */
55
+
56
+JSObject *
57
+js_vm_object_new (JSVirtualMachine *vm)
58
+{
59
+  JSObject *obj;
60
+
61
+  obj = js_vm_alloc (vm, sizeof (*obj));
62
+  obj->hash = NULL;
63
+  obj->num_props = 0;
64
+  obj->props = NULL;
65
+
66
+  return obj;
67
+}
68
+
69
+
70
+void
71
+js_vm_object_mark (JSObject *obj)
72
+{
73
+  int i;
74
+  unsigned int num_objects;
75
+
76
+  if (obj == NULL)
77
+    return;
78
+
79
+ tail_recursive:
80
+
81
+  if (!js_vm_mark_ptr (obj))
82
+    /* This object has already been marked.  Nothing to do here. */
83
+    return;
84
+
85
+  js_vm_mark_ptr (obj->props);
86
+
87
+  /* Mark property hash. */
88
+  if (obj->hash)
89
+    {
90
+      JSObjectPropHashBucket *b;
91
+      int i;
92
+
93
+      js_vm_mark_ptr (obj->hash);
94
+      js_vm_mark_ptr (obj->hash_lengths);
95
+
96
+      for (i = 0; i < HASH_SIZE; i++)
97
+	for (b = obj->hash[i]; b; b = b->next)
98
+	  {
99
+	    js_vm_mark_ptr (b);
100
+	    js_vm_mark_ptr (b->data);
101
+	  }
102
+    }
103
+
104
+  /* Mark all non-object properties. */
105
+  num_objects = 0;
106
+  for (i = 0; i < obj->num_props; i++)
107
+    {
108
+      if (obj->props[i].value.type == JS_OBJECT)
109
+	{
110
+	  if (!js_vm_is_marked_ptr (obj->props[i].value.u.vobject))
111
+	    num_objects++;
112
+	}
113
+      else
114
+	js_vm_mark (&obj->props[i].value);
115
+    }
116
+
117
+  /* And finally, mark all objects we have left. */
118
+  if (num_objects > 0)
119
+    {
120
+      /* Find the objects. */
121
+      for (i = 0; i < obj->num_props; i++)
122
+	if (obj->props[i].value.type == JS_OBJECT
123
+	    && !js_vm_is_marked_ptr (obj->props[i].value.u.vobject))
124
+	  {
125
+	    if (num_objects == 1)
126
+	      {
127
+		/*
128
+		 * Hahaa, this is the only non-marked object.  We can
129
+		 * do a tail-recursion optimization.
130
+		 */
131
+		obj = obj->props[i].value.u.vobject;
132
+		goto tail_recursive;
133
+	      }
134
+
135
+	    /* Just mark it. */
136
+	    js_vm_mark (&obj->props[i].value);
137
+	  }
138
+    }
139
+}
140
+
141
+
142
+int
143
+js_vm_object_load_property (JSVirtualMachine *vm, JSObject *obj,
144
+			    JSSymbol prop, JSNode *value_return)
145
+{
146
+  unsigned int ui;
147
+  JSSymbol link_sym = vm->syms.s___proto__;
148
+  JSObject *link_obj = NULL;
149
+
150
+follow_link:
151
+
152
+  /* Check if we know this property. */
153
+  for (ui = 0; ui < obj->num_props; ui++)
154
+    if (obj->props[ui].name == prop)
155
+      {
156
+	JS_COPY (value_return, &obj->props[ui].value);
157
+	return JS_PROPERTY_FOUND;
158
+      }
159
+    else if (obj->props[ui].name == link_sym
160
+	     && obj->props[ui].value.type == JS_OBJECT)
161
+      link_obj = obj->props[ui].value.u.vobject;
162
+
163
+  /* Undefined so far. */
164
+  if (link_obj)
165
+    {
166
+      /* Follow the link. */
167
+      obj = link_obj;
168
+
169
+      link_obj = NULL;
170
+      goto follow_link;
171
+    }
172
+
173
+  /* Undefined.  Make it undef. */
174
+  value_return->type = JS_UNDEFINED;
175
+  return JS_PROPERTY_UNKNOWN;
176
+}
177
+
178
+
179
+void
180
+js_vm_object_store_property (JSVirtualMachine *vm, JSObject *obj,
181
+			     JSSymbol prop, JSNode *val)
182
+{
183
+  unsigned int ui;
184
+  JSSymbol free_slot = JS_SYMBOL_NULL;
185
+
186
+  /* Check if we already know this property. */
187
+  for (ui = 0; ui < obj->num_props; ui++)
188
+    if (obj->props[ui].name == prop)
189
+      {
190
+	JS_COPY (&obj->props[ui].value, val);
191
+	return;
192
+      }
193
+    else if (obj->props[ui].name == JS_SYMBOL_NULL)
194
+      free_slot = ui;
195
+
196
+  /* Must create a new property. */
197
+
198
+  if (free_slot == JS_SYMBOL_NULL)
199
+    {
200
+      /* Expand our array of properties. */
201
+      obj->props = js_vm_realloc (vm, obj->props,
202
+				  (obj->num_props + 1) * sizeof (JSProperty));
203
+      free_slot = obj->num_props++;
204
+    }
205
+
206
+  obj->props[free_slot].name = prop;
207
+  obj->props[free_slot].attributes = 0;
208
+  JS_COPY (&obj->props[free_slot].value, val);
209
+
210
+  /* Insert it to the hash (if the hash has been created). */
211
+  if (obj->hash)
212
+    {
213
+      const char *name;
214
+
215
+      name = js_vm_symname (vm, prop);
216
+      hash_insert (vm, obj, name, strlen (name), free_slot);
217
+    }
218
+}
219
+
220
+
221
+void
222
+js_vm_object_delete_property (JSVirtualMachine *vm, JSObject *obj,
223
+			      JSSymbol prop)
224
+{
225
+  unsigned int ui;
226
+
227
+  /* Check if we already know this property. */
228
+  for (ui = 0; ui < obj->num_props; ui++)
229
+    if (obj->props[ui].name == prop)
230
+      {
231
+	/* Found, remove it from our list of properties. */
232
+	obj->props[ui].name = JS_SYMBOL_NULL;
233
+	obj->props[ui].value.type = JS_UNDEFINED;
234
+
235
+	/* Remove its name from the hash (if present). */
236
+	if (obj->hash)
237
+	  {
238
+	    const char *name = js_vm_symname (vm, prop);
239
+	    hash_delete (vm, obj, name, strlen (name));
240
+	  }
241
+
242
+	/* All done here. */
243
+	return;
244
+      }
245
+}
246
+
247
+
248
+void
249
+js_vm_object_load_array (JSVirtualMachine *vm, JSObject *obj, JSNode *sel,
250
+			 JSNode *value_return)
251
+{
252
+  if (sel->type == JS_INTEGER)
253
+    {
254
+      if (sel->u.vinteger < 0 || sel->u.vinteger >= obj->num_props)
255
+	value_return->type = JS_UNDEFINED;
256
+      else
257
+	JS_COPY (value_return, &obj->props[sel->u.vinteger].value);
258
+    }
259
+  else if (sel->type == JS_STRING)
260
+    {
261
+      int pos;
262
+
263
+      if (obj->hash == NULL)
264
+	hash_create (vm, obj);
265
+
266
+      pos = hash_lookup (obj, (char *) sel->u.vstring->data,
267
+			 sel->u.vstring->len);
268
+      if (pos < 0)
269
+	value_return->type = JS_UNDEFINED;
270
+      else
271
+	JS_COPY (value_return, &obj->props[pos].value);
272
+    }
273
+  else
274
+    {
275
+      sprintf (vm->error, "load_property: illegal array index");
276
+      js_vm_error (vm);
277
+    }
278
+}
279
+
280
+
281
+void
282
+js_vm_object_store_array (JSVirtualMachine *vm, JSObject *obj, JSNode *sel,
283
+			  JSNode *value)
284
+{
285
+  if (sel->type == JS_INTEGER)
286
+    {
287
+      if (sel->u.vinteger < 0)
288
+	{
289
+	  sprintf (vm->error, "store_array: array index can't be nagative");
290
+	  js_vm_error (vm);
291
+	}
292
+      if (sel->u.vinteger >= obj->num_props)
293
+	{
294
+	  /* Expand properties. */
295
+	  obj->props = js_vm_realloc (vm, obj->props,
296
+				      (sel->u.vinteger + 1)
297
+				      * sizeof (JSProperty));
298
+
299
+	  /* Init the possible gap. */
300
+	  for (; obj->num_props <= sel->u.vinteger; obj->num_props++)
301
+	    {
302
+	      obj->props[obj->num_props].name = 0;
303
+	      obj->props[obj->num_props].attributes = 0;
304
+	      obj->props[obj->num_props].value.type = JS_UNDEFINED;
305
+	    }
306
+	}
307
+
308
+      JS_COPY (&obj->props[sel->u.vinteger].value, value);
309
+    }
310
+  else if (sel->type == JS_STRING)
311
+    {
312
+      int pos;
313
+
314
+      if (obj->hash == NULL)
315
+	hash_create (vm, obj);
316
+
317
+      pos = hash_lookup (obj, (char *) sel->u.vstring->data,
318
+			 sel->u.vstring->len);
319
+      if (pos < 0)
320
+	{
321
+	  /* It is undefined, define it. */
322
+	  obj->props = js_vm_realloc (vm, obj->props,
323
+				      (obj->num_props + 1)
324
+				      * sizeof (JSProperty));
325
+
326
+	  /*
327
+	   * XXX if <sel> is a valid symbol, intern it and set symbol's
328
+	   * name below.
329
+	   */
330
+	  obj->props[obj->num_props].name = JS_SYMBOL_NULL;
331
+	  obj->props[obj->num_props].attributes = 0;
332
+	  JS_COPY (&obj->props[obj->num_props].value, value);
333
+
334
+	  hash_insert (vm, obj, (char *) sel->u.vstring->data,
335
+		       sel->u.vstring->len, obj->num_props);
336
+
337
+	  obj->num_props++;
338
+	}
339
+      else
340
+	JS_COPY (&obj->props[pos].value, value);
341
+    }
342
+}
343
+
344
+
345
+void
346
+js_vm_object_delete_array (JSVirtualMachine *vm, JSObject *obj, JSNode *sel)
347
+{
348
+  if (sel->type == JS_INTEGER)
349
+    {
350
+      if (0 <= sel->u.vinteger && sel->u.vinteger < obj->num_props)
351
+	{
352
+	  JSSymbol sym;
353
+
354
+	  sym = obj->props[sel->u.vinteger].name;
355
+	  obj->props[sel->u.vinteger].name = JS_SYMBOL_NULL;
356
+	  obj->props[sel->u.vinteger].value.type = JS_UNDEFINED;
357
+
358
+	  /* Remove its name from the hash (if present and it is not NULL). */
359
+	  if (sym != JS_SYMBOL_NULL && obj->hash)
360
+	    {
361
+	      const char *name = js_vm_symname (vm, sym);
362
+	      hash_delete (vm, obj, name, strlen (name));
363
+	    }
364
+	}
365
+    }
366
+  else if (sel->type == JS_STRING)
367
+    {
368
+      int pos;
369
+
370
+      if (obj->hash == NULL)
371
+	hash_create (vm, obj);
372
+
373
+      pos = hash_lookup (obj, (char *) sel->u.vstring->data,
374
+			 sel->u.vstring->len);
375
+      if (pos >= 0)
376
+	{
377
+	  /* Found it. */
378
+	  obj->props[pos].name = JS_SYMBOL_NULL;
379
+	  obj->props[pos].value.type = JS_UNDEFINED;
380
+
381
+	  /* And, delete its name from the hash. */
382
+	  hash_delete (vm, obj, (char *) sel->u.vstring->data,
383
+		       sel->u.vstring->len);
384
+	}
385
+    }
386
+  else
387
+    {
388
+      sprintf (vm->error, "delete_array: illegal array index");
389
+      js_vm_error (vm);
390
+    }
391
+}
392
+
393
+
394
+int
395
+js_vm_object_nth (JSVirtualMachine *vm, JSObject *obj, int nth,
396
+		  JSNode *value_return)
397
+{
398
+  int i;
399
+  JSObjectPropHashBucket *b;
400
+
401
+  value_return->type = JS_UNDEFINED;
402
+
403
+  if (nth < 0)
404
+    return 0;
405
+
406
+  if (obj->hash == NULL)
407
+    hash_create (vm, obj);
408
+
409
+  for (i = 0; i < HASH_SIZE && nth >= obj->hash_lengths[i]; i++)
410
+    nth -= obj->hash_lengths[i];
411
+
412
+  if (i >= HASH_SIZE)
413
+    return 0;
414
+
415
+  /* The chain <i> is the correct one. */
416
+  for (b = obj->hash[i]; b && nth > 0; b = b->next, nth--)
417
+    ;
418
+  if (b == NULL)
419
+    {
420
+      char buf[512];
421
+
422
+      sprintf (buf,
423
+	       "js_vm_object_nth(): chain didn't contain that many items%s",
424
+	       JS_HOST_LINE_BREAK);
425
+      js_iostream_write (vm->s_stderr, buf, strlen (buf));
426
+      js_iostream_flush (vm->s_stderr);
427
+
428
+      abort ();
429
+    }
430
+
431
+  js_vm_make_string (vm, value_return, b->data, b->len);
432
+
433
+  return 1;
434
+}
435
+
436
+
437
+/*
438
+ * Static functions.
439
+ */
440
+
441
+static void
442
+hash_create (JSVirtualMachine *vm, JSObject *obj)
443
+{
444
+  int i;
445
+
446
+  obj->hash = js_vm_alloc (vm, HASH_SIZE * sizeof (JSObjectPropHashBucket *));
447
+  memset (obj->hash, 0, HASH_SIZE * sizeof (JSObjectPropHashBucket *));
448
+
449
+  obj->hash_lengths = js_vm_alloc (vm, HASH_SIZE * sizeof (unsigned int));
450
+  memset (obj->hash_lengths, 0, HASH_SIZE * sizeof (unsigned int));
451
+
452
+  /* Insert all known properties to the hash. */
453
+  for (i = 0; i < obj->num_props; i++)
454
+    if (obj->props[i].name != JS_SYMBOL_NULL)
455
+      {
456
+	const char *name;
457
+
458
+	name = js_vm_symname (vm, obj->props[i].name);
459
+	hash_insert (vm, obj, name, strlen (name), i);
460
+      }
461
+}
462
+
463
+
464
+static void
465
+hash_insert (JSVirtualMachine *vm, JSObject *obj, const char *name,
466
+	     unsigned int name_len, int pos)
467
+{
468
+  unsigned int hash;
469
+  JSObjectPropHashBucket *b;
470
+
471
+  hash = js_count_hash (name, name_len) % HASH_SIZE;
472
+  for (b = obj->hash[hash]; b; b = b->next)
473
+    if (b->len == name_len
474
+	&& memcmp (b->data, name, name_len) == 0)
475
+      {
476
+	/* Ok, we already have a bucket */
477
+	b->value = pos;
478
+	return;
479
+      }
480
+
481
+  /* Create a new bucket. */
482
+  b = js_vm_alloc (vm, sizeof (*b));
483
+  b->len = name_len;
484
+  b->data = js_vm_alloc (vm, b->len);
485
+  memcpy (b->data, name, b->len);
486
+
487
+  b->value = pos;
488
+
489
+  b->next = obj->hash[hash];
490
+  obj->hash[hash] = b;
491
+
492
+  obj->hash_lengths[hash]++;
493
+}
494
+
495
+
496
+static void
497
+hash_delete (JSVirtualMachine *vm, JSObject *obj, const char *name,
498
+	     unsigned int name_len)
499
+{
500
+  unsigned int hash;
501
+  JSObjectPropHashBucket *b, *prev;
502
+
503
+  hash = js_count_hash (name, name_len) % HASH_SIZE;
504
+  for (prev = NULL, b = obj->hash[hash]; b; prev = b, b = b->next)
505
+    if (b->len == name_len
506
+	&& memcmp (b->data, name, name_len) == 0)
507
+      {
508
+	/* Ok, found it. */
509
+	if (prev)
510
+	  prev->next = b->next;
511
+	else
512
+	  obj->hash[hash] = b->next;
513
+
514
+	obj->hash_lengths[hash]--;
515
+
516
+	break;
517
+      }
518
+}
519
+
520
+
521
+static int
522
+hash_lookup (JSObject *obj, char *name, unsigned int name_len)
523
+{
524
+  unsigned int hash;
525
+  JSObjectPropHashBucket *b;
526
+
527
+  hash = js_count_hash (name, name_len) % HASH_SIZE;
528
+  for (b = obj->hash[hash]; b; b = b->next)
529
+    if (b->len == name_len
530
+	&& memcmp (b->data, name, name_len) == 0)
531
+      return b->value;
532
+
533
+  return -1;
534
+}
0 535
new file mode 100644
... ...
@@ -0,0 +1,129 @@
0
+/*
1
+ * Re-entrant functions from the Posix thread library.
2
+ * Copyright (c) 1998 New Generation Software (NGS) Oy
3
+ *
4
+ * Author: Markku Rossi <mtr@ngs.fi>
5
+ */
6
+
7
+/*
8
+ * This library is free software; you can redistribute it and/or
9
+ * modify it under the terms of the GNU Library General Public
10
+ * License as published by the Free Software Foundation; either
11
+ * version 2 of the License, or (at your option) any later version.
12
+ *
13
+ * This library is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
+ * Library General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU Library General Public
19
+ * License along with this library; if not, write to the Free
20
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
21
+ * MA 02111-1307, USA
22
+ */
23
+
24
+/*
25
+ * $Source: /tmp/cvsroot-15-2-2007/clamav-devel/libclamav/js/r_pthrs.c,v $
26
+ * $Id: r_pthrs.c,v 1.1 2006/10/19 17:28:58 njh Exp $
27
+ */
28
+
29
+#include "jsint.h"
30
+#include "rentrant.h"
31
+
32
+/*
33
+ * Types and definitions.
34
+ */
35
+
36
+/*
37
+ * Global functions.
38
+ */
39
+
40
+/* Time. */
41
+
42
+void
43
+js_localtime (const time_t *clock, struct tm *result)
44
+{
45
+  localtime_r (clock, result);
46
+}
47
+
48
+
49
+void
50
+js_gmtime (const time_t *clock, struct tm *result)
51
+{
52
+  gmtime_r (clock, result);
53
+}
54
+
55
+
56
+void
57
+js_asctime (const struct tm *tm, char *buffer, int buffer_length)
58
+{
59
+  asctime_r (tm, buffer
60
+#if ASCTIME_R_WITH_THREE_ARGS
61
+	     , buffer_length
62
+#endif /* ASCTIME_R_WITH_THREE_ARGS */
63
+	     );
64
+}
65
+
66
+
67
+/* Drand48. */
68
+
69
+#if DRAND48_R_WITH_DRAND48D
70
+
71
+void *
72
+js_drand48_create (JSVirtualMachine *vm)
73
+{
74
+  return js_malloc (vm, sizeof (DRAND48D));
75
+}
76
+
77
+
78
+void
79
+js_drand48_destroy (void *drand48_context)
80
+{
81
+  js_free (drand48_context);
82
+}
83
+
84
+
85
+void
86
+js_srand48 (void *drand48_context, long seed)
87
+{
88
+  DRAND48D *ctx = drand48_context;
89
+  srand48_r (seed, ctx);
90
+}
91
+
92
+void
93
+js_drand48 (void *drand48_context, double *random_return)
94
+{
95
+  DRAND48D *ctx = drand48_context;
96
+  drand48_r (ctx, random_return);
97
+}
98
+
99
+#else /* not DRAND48_R_WITH_DRAND48D */
100
+
101
+/* We trust the drand48() to be thread-safe. */
102
+
103
+void *
104
+js_drand48_create (JSVirtualMachine *vm)
105
+{
106
+  return NULL;
107
+}
108
+
109
+
110
+void
111
+js_drand48_destroy (void *drand48_context)
112
+{
113
+}
114
+
115
+
116
+void
117
+js_srand48 (void *drand48_context, long seed)
118
+{
119
+  srand48 (seed);
120
+}
121
+
122
+void
123
+js_drand48 (void *drand48_context, double *random_return)
124
+{
125
+  *random_return = drand48 ();
126
+}
127
+
128
+#endif /* not DRAND48_R_WITH_DRAND48D */
0 129
new file mode 100644
... ...
@@ -0,0 +1,439 @@
0
+/*
1
+ * General utilites.
2
+ * Copyright (c) 1998 New Generation Software (NGS) Oy
3
+ *
4
+ * Author: Markku Rossi <mtr@ngs.fi>
5
+ */
6
+
7
+/*
8
+ * This library is free software; you can redistribute it and/or
9
+ * modify it under the terms of the GNU Library General Public
10
+ * License as published by the Free Software Foundation; either
11
+ * version 2 of the License, or (at your option) any later version.
12
+ *
13
+ * This library is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
+ * Library General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU Library General Public
19
+ * License along with this library; if not, write to the Free
20
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
21
+ * MA 02111-1307, USA
22
+ */
23
+
24
+/*
25
+ * $Source: /tmp/cvsroot-15-2-2007/clamav-devel/libclamav/js/utils.c,v $
26
+ * $Id: utils.c,v 1.1 2006/10/19 17:28:58 njh Exp $
27
+ */
28
+
29
+#include "jsint.h"
30
+
31
+/*
32
+ * Global variables.
33
+ */
34
+
35
+unsigned char js_latin1_tolower[256] =
36
+{
37
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
38
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
39
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
40
+ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
41
+ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
42
+ 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
43
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
44
+ 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
45
+ 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
46
+ 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
47
+ 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
48
+ 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
49
+ 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
50
+ 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
51
+ 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
52
+ 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
53
+ 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
54
+ 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
55
+ 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
56
+ 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
57
+ 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
58
+ 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
59
+ 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
60
+ 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
61
+ 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0x61, 0xe7,
62
+ 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
63
+ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xd7,
64
+ 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xdf,
65
+ 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
66
+ 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
67
+ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
68
+ 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
69
+};
70
+
71
+unsigned char js_latin1_toupper[256] =
72
+{
73
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
74
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
75
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
76
+ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
77
+ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
78
+ 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
79
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
80
+ 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
81
+ 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
82
+ 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
83
+ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
84
+ 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
85
+ 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
86
+ 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
87
+ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
88
+ 0x58, 0x59, 0x5a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
89
+ 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
90
+ 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
91
+ 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
92
+ 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
93
+ 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
94
+ 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
95
+ 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
96
+ 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
97
+ 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
98
+ 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
99
+ 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
100
+ 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
101
+ 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xe6, 0xc7,
102
+ 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
103
+ 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xf7,
104
+ 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xff,
105
+};
106
+
107
+
108
+/*
109
+ * Global functions.
110
+ */
111
+
112
+void
113
+js_vm_to_primitive (JSVirtualMachine *vm, const JSNode *n,
114
+		    JSNode *result_return, JSNodeType preferred_type)
115
+{
116
+  JSNode args;
117
+
118
+  switch (n->type)
119
+    {
120
+    case JS_UNDEFINED:
121
+    case JS_NULL:
122
+    case JS_BOOLEAN:
123
+    case JS_INTEGER:
124
+    case JS_FLOAT:
125
+    case JS_NAN:
126
+    case JS_STRING:
127
+      JS_COPY (result_return, n);
128
+      break;
129
+
130
+    case JS_OBJECT:
131
+      if (preferred_type == JS_STRING)
132
+	{
133
+	  if (js_vm_call_method (vm, (JSNode *) n, "toString", 0, &args)
134
+	      && JS_IS_PRIMITIVE_VALUE (&vm->exec_result))
135
+	    JS_COPY (result_return, &vm->exec_result);
136
+	  else if (js_vm_call_method (vm, (JSNode *) n, "valueOf", 0, &args)
137
+		   && JS_IS_PRIMITIVE_VALUE (&vm->exec_result))
138
+	    JS_COPY (result_return, &vm->exec_result);
139
+	  else
140
+	    {
141
+	      sprintf (vm->error, "ToPrimitive(): couldn't convert");
142
+	      js_vm_error (vm);
143
+	    }
144
+	}
145
+      else
146
+	{
147
+	  /* It must be, or it defaults to NUMBER. */
148
+	  if (js_vm_call_method (vm, (JSNode *) n, "valueOf", 0, &args)
149
+	      && JS_IS_PRIMITIVE_VALUE (&vm->exec_result))
150
+	    JS_COPY (result_return, &vm->exec_result);
151
+	  else
152
+	    js_vm_to_string (vm, n, result_return);
153
+	}
154
+      break;
155
+
156
+    case JS_BUILTIN:
157
+      /* XXX ToPrimitive() for built-ins. */
158
+      sprintf (vm->error, "ToPrimitive(): not implemented yet for built-ins");
159
+      js_vm_error (vm);
160
+      break;
161
+
162
+    case JS_ARRAY:
163
+    case JS_SYMBOL:
164
+    case JS_FUNC:
165
+    case JS_IPTR:
166
+    default:
167
+      sprintf (vm->error, "ToPrimitive(): couldn't convert (%d)", n->type);
168
+      js_vm_error (vm);
169
+      break;
170
+    }
171
+}
172
+
173
+
174
+void
175
+js_vm_to_string (JSVirtualMachine *vm, const JSNode *n, JSNode *result_return)
176
+{
177
+  const char *tostring;
178
+  JSNode args;
179
+  JSNode *nnoconst = (JSNode *) n; /* toString methods behave `constantly'
180
+				      so no panic here. */
181
+
182
+  /* Create empty arguments. */
183
+  args.type = JS_INTEGER;
184
+  args.u.vinteger = 0;
185
+
186
+  switch (n->type)
187
+    {
188
+    case JS_UNDEFINED:
189
+      tostring = "undefined";
190
+      break;
191
+
192
+    case JS_NULL:
193
+      tostring = "null";
194
+      break;
195
+
196
+    case JS_BOOLEAN:
197
+    case JS_INTEGER:
198
+    case JS_FLOAT:
199
+    case JS_NAN:
200
+    case JS_STRING:
201
+    case JS_ARRAY:
202
+      (void) (*vm->prim[n->type]->method_proc) (vm, vm->prim[n->type],
203
+						nnoconst, vm->syms.s_toString,
204
+						result_return, &args);
205
+      return;
206
+      break;
207
+
208
+    case JS_OBJECT:
209
+      /* Try to call object's toString() method. */
210
+      if (js_vm_call_method (vm, (JSNode *) n, "toString", 0, &args)
211
+	  && vm->exec_result.type == JS_STRING)
212
+	{
213
+	  JS_COPY (result_return, &vm->exec_result);
214
+	  return;
215
+	}
216
+
217
+      /* No match. */
218
+      tostring = "object";
219
+      break;
220
+
221
+    case JS_SYMBOL:
222
+      tostring = js_vm_symname (vm, n->u.vsymbol);
223
+      break;
224
+
225
+    case JS_BUILTIN:
226
+      if (n->u.vbuiltin->info->method_proc)
227
+	if ((*n->u.vbuiltin->info->method_proc) (
228
+					vm,
229
+					n->u.vbuiltin->info,
230
+					n->u.vbuiltin->instance_context,
231
+					vm->syms.s_toString, result_return,
232
+					&args)
233
+	  == JS_PROPERTY_FOUND)
234
+	  return;
235
+
236
+      /* Builtin didn't answer toString().  Let's use our default. */
237
+      tostring = "builtin";
238
+      break;
239
+
240
+    case JS_FUNC:
241
+      tostring = "function";
242
+      break;
243
+
244
+    case JS_IPTR:
245
+      tostring = "pointer";
246
+      break;
247
+
248
+    default:
249
+      tostring = "??? unknown type in js_vm_to_string() ???";
250
+      break;
251
+    }
252
+
253
+  js_vm_make_static_string (vm, result_return, tostring, strlen (tostring));
254
+}
255
+
256
+
257
+void
258
+js_vm_to_number (JSVirtualMachine *vm, const JSNode *n, JSNode *result_return)
259
+{
260
+  char *cp, *end;
261
+
262
+  switch (n->type)
263
+    {
264
+    case JS_UNDEFINED:
265
+      result_return->type = JS_NAN;
266
+      break;
267
+
268
+    case JS_NULL:
269
+      result_return->type = JS_INTEGER;
270
+      result_return->u.vinteger = 0;
271
+      break;
272
+
273
+    case JS_BOOLEAN:
274
+      result_return->type = JS_INTEGER;
275
+      result_return->u.vinteger = n->u.vboolean ? 1 : 0;
276
+      break;
277
+
278
+    case JS_INTEGER:
279
+    case JS_FLOAT:
280
+    case JS_NAN:
281
+      JS_COPY (result_return, n);
282
+      break;
283
+
284
+    case JS_STRING:
285
+      cp = js_string_to_c_string (vm, n);
286
+      result_return->u.vinteger = strtol (cp, &end, 10);
287
+
288
+      if (cp == end)
289
+	{
290
+	  int i;
291
+
292
+	  /* It failed.  Check the `Infinity'. */
293
+
294
+	  for (i = 0; cp[i] && JS_IS_STR_WHITE_SPACE_CHAR (cp[i]); i++)
295
+	    ;
296
+
297
+	  if (cp[i] && memcmp (cp + i, "Infinity", 8) == 0)
298
+	    JS_MAKE_POSITIVE_INFINITY (result_return);
299
+	  else
300
+	    result_return->type = JS_NAN;
301
+	}
302
+      else
303
+	{
304
+	  if (*end == '.' || *end == 'e' || *end == 'E')
305
+	    {
306
+	      /* It is a float number. */
307
+	      result_return->u.vfloat = strtod (cp, &end);
308
+	      if (cp == end)
309
+		/*  Couldn't parse. */
310
+		result_return->type = JS_NAN;
311
+	      else
312
+		/* Success. */
313
+		result_return->type = JS_FLOAT;
314
+	    }
315
+	  else
316
+	    {
317
+	      /* It is an integer. */
318
+	      result_return->type = JS_INTEGER;
319
+	    }
320
+	}
321
+
322
+      js_free (cp);
323
+      break;
324
+
325
+    case JS_ARRAY:
326
+    case JS_OBJECT:
327
+    case JS_BUILTIN:
328
+      /* XXX Not implemented yet. */
329
+      result_return->type = JS_NAN;
330
+      break;
331
+
332
+    case JS_SYMBOL:
333
+    case JS_FUNC:
334
+    case JS_IPTR:
335
+    default:
336
+      result_return->type = JS_NAN;
337
+      break;
338
+    }
339
+}
340
+
341
+
342
+void
343
+js_vm_to_object (JSVirtualMachine *vm, const JSNode *n, JSNode *result_return)
344
+{
345
+  switch (n->type)
346
+    {
347
+    case JS_BOOLEAN:
348
+    case JS_INTEGER:
349
+    case JS_FLOAT:
350
+    case JS_NAN:
351
+    case JS_OBJECT:
352
+      JS_COPY (result_return, n);
353
+      break;
354
+
355
+    case JS_STRING:
356
+      js_vm_make_string (vm, result_return, n->u.vstring->data,
357
+			 n->u.vstring->len);
358
+      break;
359
+
360
+    case JS_UNDEFINED:
361
+    case JS_NULL:
362
+    default:
363
+      sprintf (vm->error, "ToObject(): illegal argument");
364
+      js_vm_error (vm);
365
+      break;
366
+    }
367
+}
368
+
369
+
370
+JSInt32
371
+js_vm_to_int32 (JSVirtualMachine *vm, JSNode *n)
372
+{
373
+  JSNode intermediate;
374
+  JSInt32 result;
375
+
376
+  js_vm_to_number (vm, n, &intermediate);
377
+
378
+  switch (intermediate.type)
379
+    {
380
+    case JS_INTEGER:
381
+      result = (JSInt32) intermediate.u.vinteger;
382
+      break;
383
+
384
+    case JS_FLOAT:
385
+      if (JS_IS_POSITIVE_INFINITY (&intermediate)
386
+	  || JS_IS_NEGATIVE_INFINITY (&intermediate))
387
+	result = 0;
388
+      else
389
+	result = (JSInt32) intermediate.u.vfloat;
390
+      break;
391
+
392
+    case JS_NAN:
393
+    default:
394
+      result = 0;
395
+      break;
396
+    }
397
+
398
+  return result;
399
+}
400
+
401
+
402
+int
403
+js_vm_to_boolean (JSVirtualMachine *vm, JSNode *n)
404
+{
405
+  int result;
406
+
407
+  switch (n->type)
408
+    {
409
+    case JS_BOOLEAN:
410
+      result = n->u.vboolean;
411
+      break;
412
+
413
+    case JS_INTEGER:
414
+      result = n->u.vinteger != 0;
415
+      break;
416
+
417
+    case JS_FLOAT:
418
+      result = n->u.vfloat != 0;
419
+      break;
420
+
421
+    case JS_STRING:
422
+      result = n->u.vstring->len > 0;
423
+      break;
424
+
425
+    case JS_OBJECT:
426
+      result = 1;
427
+      break;
428
+
429
+    case JS_UNDEFINED:
430
+    case JS_NULL:
431
+    case JS_NAN:
432
+    default:
433
+      result = 0;
434
+      break;
435
+    }
436
+
437
+  return result;
438
+}