Ruby  2.0.0p451(2014-02-24revision45167)
marshal.c
Go to the documentation of this file.
1 /**********************************************************************
2 
3  marshal.c -
4 
5  $Author: nagachika $
6  created at: Thu Apr 27 16:30:01 JST 1995
7 
8  Copyright (C) 1993-2007 Yukihiro Matsumoto
9 
10 **********************************************************************/
11 
12 #include "ruby/ruby.h"
13 #include "ruby/io.h"
14 #include "ruby/st.h"
15 #include "ruby/util.h"
16 #include "ruby/encoding.h"
17 #include "internal.h"
18 
19 #include <math.h>
20 #ifdef HAVE_FLOAT_H
21 #include <float.h>
22 #endif
23 #ifdef HAVE_IEEEFP_H
24 #include <ieeefp.h>
25 #endif
26 
27 #define BITSPERSHORT (2*CHAR_BIT)
28 #define SHORTMASK ((1<<BITSPERSHORT)-1)
29 #define SHORTDN(x) RSHIFT((x),BITSPERSHORT)
30 
31 #if SIZEOF_SHORT == SIZEOF_BDIGITS
32 #define SHORTLEN(x) (x)
33 #else
34 static long
35 shortlen(long len, BDIGIT *ds)
36 {
37  BDIGIT num;
38  int offset = 0;
39 
40  num = ds[len-1];
41  while (num) {
42  num = SHORTDN(num);
43  offset++;
44  }
45  return (len - 1)*sizeof(BDIGIT)/2 + offset;
46 }
47 #define SHORTLEN(x) shortlen((x),d)
48 #endif
49 
50 #define MARSHAL_MAJOR 4
51 #define MARSHAL_MINOR 8
52 
53 #define TYPE_NIL '0'
54 #define TYPE_TRUE 'T'
55 #define TYPE_FALSE 'F'
56 #define TYPE_FIXNUM 'i'
57 
58 #define TYPE_EXTENDED 'e'
59 #define TYPE_UCLASS 'C'
60 #define TYPE_OBJECT 'o'
61 #define TYPE_DATA 'd'
62 #define TYPE_USERDEF 'u'
63 #define TYPE_USRMARSHAL 'U'
64 #define TYPE_FLOAT 'f'
65 #define TYPE_BIGNUM 'l'
66 #define TYPE_STRING '"'
67 #define TYPE_REGEXP '/'
68 #define TYPE_ARRAY '['
69 #define TYPE_HASH '{'
70 #define TYPE_HASH_DEF '}'
71 #define TYPE_STRUCT 'S'
72 #define TYPE_MODULE_OLD 'M'
73 #define TYPE_CLASS 'c'
74 #define TYPE_MODULE 'm'
75 
76 #define TYPE_SYMBOL ':'
77 #define TYPE_SYMLINK ';'
78 
79 #define TYPE_IVAR 'I'
80 #define TYPE_LINK '@'
81 
85 
86 typedef struct {
89  VALUE (*dumper)(VALUE);
90  VALUE (*loader)(VALUE, VALUE);
92 
95 
96 static int
98 {
100  rb_gc_mark(p->newclass);
101  rb_gc_mark(p->oldclass);
102  return ST_CONTINUE;
103 }
104 
105 static void
107 {
108  if (!tbl) return;
110 }
111 
112 void
113 rb_marshal_define_compat(VALUE newclass, VALUE oldclass, VALUE (*dumper)(VALUE), VALUE (*loader)(VALUE, VALUE))
114 {
115  marshal_compat_t *compat;
116  rb_alloc_func_t allocator = rb_get_alloc_func(newclass);
117 
118  if (!allocator) {
119  rb_raise(rb_eTypeError, "no allocator");
120  }
121 
122  compat = ALLOC(marshal_compat_t);
123  compat->newclass = Qnil;
124  compat->oldclass = Qnil;
125  compat->newclass = newclass;
126  compat->oldclass = oldclass;
127  compat->dumper = dumper;
128  compat->loader = loader;
129 
130  st_insert(compat_allocator_tbl, (st_data_t)allocator, (st_data_t)compat);
131 }
132 
133 #define MARSHAL_INFECTION (FL_TAINT|FL_UNTRUSTED)
134 typedef char ruby_check_marshal_viral_flags[MARSHAL_INFECTION == (int)MARSHAL_INFECTION ? 1 : -1];
135 
136 struct dump_arg {
143 };
144 
147  struct dump_arg *arg;
148  int limit;
149 };
150 
151 static void
153 {
154  if (!arg->symbols) {
155  rb_raise(rb_eRuntimeError, "Marshal.dump reentered at %s",
156  rb_id2name(sym));
157  }
158 }
159 
160 static void clear_dump_arg(struct dump_arg *arg);
161 
162 static void
163 mark_dump_arg(void *ptr)
164 {
165  struct dump_arg *p = ptr;
166  if (!p->symbols)
167  return;
168  rb_mark_set(p->data);
170  rb_gc_mark(p->str);
171 }
172 
173 static void
174 free_dump_arg(void *ptr)
175 {
176  clear_dump_arg(ptr);
177  xfree(ptr);
178 }
179 
180 static size_t
181 memsize_dump_arg(const void *ptr)
182 {
183  return ptr ? sizeof(struct dump_arg) : 0;
184 }
185 
187  "dump_arg",
189 };
190 
191 static const char *
192 must_not_be_anonymous(const char *type, VALUE path)
193 {
194  char *n = RSTRING_PTR(path);
195 
196  if (!rb_enc_asciicompat(rb_enc_get(path))) {
197  /* cannot occur? */
198  rb_raise(rb_eTypeError, "can't dump non-ascii %s name", type);
199  }
200  if (n[0] == '#') {
201  rb_raise(rb_eTypeError, "can't dump anonymous %s %.*s", type,
202  (int)RSTRING_LEN(path), n);
203  }
204  return n;
205 }
206 
207 static VALUE
209 {
210  VALUE path = rb_class_path(klass);
211  const char *n;
212 
213  n = must_not_be_anonymous((RB_TYPE_P(klass, T_CLASS) ? "class" : "module"), path);
214  if (rb_path_to_class(path) != rb_class_real(klass)) {
215  rb_raise(rb_eTypeError, "%s can't be referred to", n);
216  }
217  return path;
218 }
219 
220 static void w_long(long, struct dump_arg*);
221 static void w_encoding(VALUE obj, long num, struct dump_call_arg *arg);
222 
223 static void
224 w_nbyte(const char *s, long n, struct dump_arg *arg)
225 {
226  VALUE buf = arg->str;
227  rb_str_buf_cat(buf, s, n);
228  RBASIC(buf)->flags |= arg->infection;
229  if (arg->dest && RSTRING_LEN(buf) >= BUFSIZ) {
230  rb_io_write(arg->dest, buf);
231  rb_str_resize(buf, 0);
232  }
233 }
234 
235 static void
236 w_byte(char c, struct dump_arg *arg)
237 {
238  w_nbyte(&c, 1, arg);
239 }
240 
241 static void
242 w_bytes(const char *s, long n, struct dump_arg *arg)
243 {
244  w_long(n, arg);
245  w_nbyte(s, n, arg);
246 }
247 
248 #define w_cstr(s, arg) w_bytes((s), strlen(s), (arg))
249 
250 static void
251 w_short(int x, struct dump_arg *arg)
252 {
253  w_byte((char)((x >> 0) & 0xff), arg);
254  w_byte((char)((x >> 8) & 0xff), arg);
255 }
256 
257 static void
258 w_long(long x, struct dump_arg *arg)
259 {
260  char buf[sizeof(long)+1];
261  int i, len = 0;
262 
263 #if SIZEOF_LONG > 4
264  if (!(RSHIFT(x, 31) == 0 || RSHIFT(x, 31) == -1)) {
265  /* big long does not fit in 4 bytes */
266  rb_raise(rb_eTypeError, "long too big to dump");
267  }
268 #endif
269 
270  if (x == 0) {
271  w_byte(0, arg);
272  return;
273  }
274  if (0 < x && x < 123) {
275  w_byte((char)(x + 5), arg);
276  return;
277  }
278  if (-124 < x && x < 0) {
279  w_byte((char)((x - 5)&0xff), arg);
280  return;
281  }
282  for (i=1;i<(int)sizeof(long)+1;i++) {
283  buf[i] = (char)(x & 0xff);
284  x = RSHIFT(x,8);
285  if (x == 0) {
286  buf[0] = i;
287  break;
288  }
289  if (x == -1) {
290  buf[0] = -i;
291  break;
292  }
293  }
294  len = i;
295  for (i=0;i<=len;i++) {
296  w_byte(buf[i], arg);
297  }
298 }
299 
300 #ifdef DBL_MANT_DIG
301 #define DECIMAL_MANT (53-16) /* from IEEE754 double precision */
302 
303 #if DBL_MANT_DIG > 32
304 #define MANT_BITS 32
305 #elif DBL_MANT_DIG > 24
306 #define MANT_BITS 24
307 #elif DBL_MANT_DIG > 16
308 #define MANT_BITS 16
309 #else
310 #define MANT_BITS 8
311 #endif
312 
313 static double
314 load_mantissa(double d, const char *buf, long len)
315 {
316  if (!len) return d;
317  if (--len > 0 && !*buf++) { /* binary mantissa mark */
318  int e, s = d < 0, dig = 0;
319  unsigned long m;
320 
321  modf(ldexp(frexp(fabs(d), &e), DECIMAL_MANT), &d);
322  do {
323  m = 0;
324  switch (len) {
325  default: m = *buf++ & 0xff;
326 #if MANT_BITS > 24
327  case 3: m = (m << 8) | (*buf++ & 0xff);
328 #endif
329 #if MANT_BITS > 16
330  case 2: m = (m << 8) | (*buf++ & 0xff);
331 #endif
332 #if MANT_BITS > 8
333  case 1: m = (m << 8) | (*buf++ & 0xff);
334 #endif
335  }
336  dig -= len < MANT_BITS / 8 ? 8 * (unsigned)len : MANT_BITS;
337  d += ldexp((double)m, dig);
338  } while ((len -= MANT_BITS / 8) > 0);
339  d = ldexp(d, e - DECIMAL_MANT);
340  if (s) d = -d;
341  }
342  return d;
343 }
344 #else
345 #define load_mantissa(d, buf, len) (d)
346 #endif
347 
348 #ifdef DBL_DIG
349 #define FLOAT_DIG (DBL_DIG+2)
350 #else
351 #define FLOAT_DIG 17
352 #endif
353 
354 static void
355 w_float(double d, struct dump_arg *arg)
356 {
357  char *ruby_dtoa(double d_, int mode, int ndigits, int *decpt, int *sign, char **rve);
358  char buf[FLOAT_DIG + (DECIMAL_MANT + 7) / 8 + 10];
359 
360  if (isinf(d)) {
361  if (d < 0) w_cstr("-inf", arg);
362  else w_cstr("inf", arg);
363  }
364  else if (isnan(d)) {
365  w_cstr("nan", arg);
366  }
367  else if (d == 0.0) {
368  if (1.0/d < 0) w_cstr("-0", arg);
369  else w_cstr("0", arg);
370  }
371  else {
372  int decpt, sign, digs, len = 0;
373  char *e, *p = ruby_dtoa(d, 0, 0, &decpt, &sign, &e);
374  if (sign) buf[len++] = '-';
375  digs = (int)(e - p);
376  if (decpt < -3 || decpt > digs) {
377  buf[len++] = p[0];
378  if (--digs > 0) buf[len++] = '.';
379  memcpy(buf + len, p + 1, digs);
380  len += digs;
381  len += snprintf(buf + len, sizeof(buf) - len, "e%d", decpt - 1);
382  }
383  else if (decpt > 0) {
384  memcpy(buf + len, p, decpt);
385  len += decpt;
386  if ((digs -= decpt) > 0) {
387  buf[len++] = '.';
388  memcpy(buf + len, p + decpt, digs);
389  len += digs;
390  }
391  }
392  else {
393  buf[len++] = '0';
394  buf[len++] = '.';
395  if (decpt) {
396  memset(buf + len, '0', -decpt);
397  len -= decpt;
398  }
399  memcpy(buf + len, p, digs);
400  len += digs;
401  }
402  xfree(p);
403  w_bytes(buf, len, arg);
404  }
405 }
406 
407 static void
408 w_symbol(ID id, struct dump_arg *arg)
409 {
410  VALUE sym;
411  st_data_t num;
412  int encidx = -1;
413 
414  if (st_lookup(arg->symbols, id, &num)) {
415  w_byte(TYPE_SYMLINK, arg);
416  w_long((long)num, arg);
417  }
418  else {
419  sym = rb_id2str(id);
420  if (!sym) {
421  rb_raise(rb_eTypeError, "can't dump anonymous ID %"PRIdVALUE, id);
422  }
423  encidx = rb_enc_get_index(sym);
424  if (encidx == rb_usascii_encindex() ||
426  encidx = -1;
427  }
428  else {
429  w_byte(TYPE_IVAR, arg);
430  }
431  w_byte(TYPE_SYMBOL, arg);
432  w_bytes(RSTRING_PTR(sym), RSTRING_LEN(sym), arg);
433  st_add_direct(arg->symbols, id, arg->symbols->num_entries);
434  if (encidx != -1) {
435  struct dump_call_arg c_arg;
436  c_arg.limit = 1;
437  c_arg.arg = arg;
438  w_encoding(sym, 0, &c_arg);
439  }
440  }
441 }
442 
443 static void
445 {
446  must_not_be_anonymous("class", s);
447  w_symbol(rb_intern_str(s), arg);
448 }
449 
450 static void w_object(VALUE,struct dump_arg*,int);
451 
452 static int
454 {
455  w_object(key, arg->arg, arg->limit);
456  w_object(value, arg->arg, arg->limit);
457  return ST_CONTINUE;
458 }
459 
460 #define SINGLETON_DUMP_UNABLE_P(klass) \
461  (RCLASS_M_TBL(klass)->num_entries || \
462  (RCLASS_IV_TBL(klass) && RCLASS_IV_TBL(klass)->num_entries > 1))
463 
464 static void
465 w_extended(VALUE klass, struct dump_arg *arg, int check)
466 {
467  if (check && FL_TEST(klass, FL_SINGLETON)) {
468  VALUE origin = RCLASS_ORIGIN(klass);
469  if (SINGLETON_DUMP_UNABLE_P(klass) ||
470  (origin != klass && SINGLETON_DUMP_UNABLE_P(origin))) {
471  rb_raise(rb_eTypeError, "singleton can't be dumped");
472  }
473  klass = RCLASS_SUPER(klass);
474  }
475  while (BUILTIN_TYPE(klass) == T_ICLASS) {
476  VALUE path = rb_class_name(RBASIC(klass)->klass);
477  w_byte(TYPE_EXTENDED, arg);
478  w_unique(path, arg);
479  klass = RCLASS_SUPER(klass);
480  }
481 }
482 
483 static void
484 w_class(char type, VALUE obj, struct dump_arg *arg, int check)
485 {
486  VALUE path;
487  st_data_t real_obj;
488  VALUE klass;
489 
490  if (st_lookup(arg->compat_tbl, (st_data_t)obj, &real_obj)) {
491  obj = (VALUE)real_obj;
492  }
493  klass = CLASS_OF(obj);
494  w_extended(klass, arg, check);
495  w_byte(type, arg);
496  path = class2path(rb_class_real(klass));
497  w_unique(path, arg);
498 }
499 
500 static void
501 w_uclass(VALUE obj, VALUE super, struct dump_arg *arg)
502 {
503  VALUE klass = CLASS_OF(obj);
504 
505  w_extended(klass, arg, TRUE);
506  klass = rb_class_real(klass);
507  if (klass != super) {
508  w_byte(TYPE_UCLASS, arg);
509  w_unique(class2path(klass), arg);
510  }
511 }
512 
513 static int
515 {
516  ID id = (ID)key;
517  VALUE value = (VALUE)val;
518  struct dump_call_arg *arg = (struct dump_call_arg *)a;
519 
520  if (id == rb_id_encoding()) return ST_CONTINUE;
521  if (id == rb_intern("E")) return ST_CONTINUE;
522  w_symbol(id, arg->arg);
523  w_object(value, arg->arg, arg->limit);
524  return ST_CONTINUE;
525 }
526 
527 static void
528 w_encoding(VALUE obj, long num, struct dump_call_arg *arg)
529 {
530  int encidx = rb_enc_get_index(obj);
531  rb_encoding *enc = 0;
532  st_data_t name;
533 
534  if (encidx <= 0 || !(enc = rb_enc_from_index(encidx))) {
535  w_long(num, arg->arg);
536  return;
537  }
538  w_long(num + 1, arg->arg);
539 
540  /* special treatment for US-ASCII and UTF-8 */
541  if (encidx == rb_usascii_encindex()) {
542  w_symbol(rb_intern("E"), arg->arg);
543  w_object(Qfalse, arg->arg, arg->limit + 1);
544  return;
545  }
546  else if (encidx == rb_utf8_encindex()) {
547  w_symbol(rb_intern("E"), arg->arg);
548  w_object(Qtrue, arg->arg, arg->limit + 1);
549  return;
550  }
551 
552  w_symbol(rb_id_encoding(), arg->arg);
553  do {
554  if (!arg->arg->encodings)
556  else if (st_lookup(arg->arg->encodings, (st_data_t)rb_enc_name(enc), &name))
557  break;
558  name = (st_data_t)rb_str_new2(rb_enc_name(enc));
559  st_insert(arg->arg->encodings, (st_data_t)rb_enc_name(enc), name);
560  } while (0);
561  w_object(name, arg->arg, arg->limit + 1);
562 }
563 
564 static void
566 {
567  long num = tbl ? tbl->num_entries : 0;
568 
569  w_encoding(obj, num, arg);
570  if (tbl) {
572  }
573 }
574 
575 static void
577 {
578  VALUE *ptr;
579  long i, len, num;
580 
581  len = ROBJECT_NUMIV(obj);
582  ptr = ROBJECT_IVPTR(obj);
583  num = 0;
584  for (i = 0; i < len; i++)
585  if (ptr[i] != Qundef)
586  num += 1;
587 
588  w_encoding(obj, num, arg);
589  if (num != 0) {
591  }
592 }
593 
594 static void
596 {
597  struct dump_call_arg c_arg;
598  st_table *ivtbl = 0;
599  st_data_t num;
600  int hasiv = 0;
601 #define has_ivars(obj, ivtbl) (((ivtbl) = rb_generic_ivar_table(obj)) != 0 || \
602  (!SPECIAL_CONST_P(obj) && !ENCODING_IS_ASCII8BIT(obj)))
603 
604  if (limit == 0) {
605  rb_raise(rb_eArgError, "exceed depth limit");
606  }
607 
608  limit--;
609  c_arg.limit = limit;
610  c_arg.arg = arg;
611 
612  if (st_lookup(arg->data, obj, &num)) {
613  w_byte(TYPE_LINK, arg);
614  w_long((long)num, arg);
615  return;
616  }
617 
618  if (obj == Qnil) {
619  w_byte(TYPE_NIL, arg);
620  }
621  else if (obj == Qtrue) {
622  w_byte(TYPE_TRUE, arg);
623  }
624  else if (obj == Qfalse) {
625  w_byte(TYPE_FALSE, arg);
626  }
627  else if (FIXNUM_P(obj)) {
628 #if SIZEOF_LONG <= 4
629  w_byte(TYPE_FIXNUM, arg);
630  w_long(FIX2INT(obj), arg);
631 #else
632  if (RSHIFT((long)obj, 31) == 0 || RSHIFT((long)obj, 31) == -1) {
633  w_byte(TYPE_FIXNUM, arg);
634  w_long(FIX2LONG(obj), arg);
635  }
636  else {
637  w_object(rb_int2big(FIX2LONG(obj)), arg, limit);
638  }
639 #endif
640  }
641  else if (SYMBOL_P(obj)) {
642  w_symbol(SYM2ID(obj), arg);
643  }
644  else if (FLONUM_P(obj)) {
645  st_add_direct(arg->data, obj, arg->data->num_entries);
646  w_byte(TYPE_FLOAT, arg);
647  w_float(RFLOAT_VALUE(obj), arg);
648  }
649  else {
650  VALUE v;
651 
652  arg->infection |= (int)FL_TEST(obj, MARSHAL_INFECTION);
653 
654  if (rb_obj_respond_to(obj, s_mdump, TRUE)) {
655  st_add_direct(arg->data, obj, arg->data->num_entries);
656 
657  v = rb_funcall2(obj, s_mdump, 0, 0);
658  check_dump_arg(arg, s_mdump);
659  hasiv = has_ivars(v, ivtbl);
660  if (hasiv) w_byte(TYPE_IVAR, arg);
661  w_class(TYPE_USRMARSHAL, obj, arg, FALSE);
662  w_object(v, arg, limit);
663  if (hasiv) w_ivar(v, ivtbl, &c_arg);
664  return;
665  }
666  if (rb_obj_respond_to(obj, s_dump, TRUE)) {
667  st_table *ivtbl2 = 0;
668  int hasiv2;
669 
670  v = INT2NUM(limit);
671  v = rb_funcall2(obj, s_dump, 1, &v);
672  check_dump_arg(arg, s_dump);
673  if (!RB_TYPE_P(v, T_STRING)) {
674  rb_raise(rb_eTypeError, "_dump() must return string");
675  }
676  hasiv = has_ivars(obj, ivtbl);
677  if (hasiv) w_byte(TYPE_IVAR, arg);
678  if ((hasiv2 = has_ivars(v, ivtbl2)) != 0 && !hasiv) {
679  w_byte(TYPE_IVAR, arg);
680  }
681  w_class(TYPE_USERDEF, obj, arg, FALSE);
682  w_bytes(RSTRING_PTR(v), RSTRING_LEN(v), arg);
683  if (hasiv2) {
684  w_ivar(v, ivtbl2, &c_arg);
685  }
686  else if (hasiv) {
687  w_ivar(obj, ivtbl, &c_arg);
688  }
689  st_add_direct(arg->data, obj, arg->data->num_entries);
690  return;
691  }
692 
693  st_add_direct(arg->data, obj, arg->data->num_entries);
694 
695  hasiv = has_ivars(obj, ivtbl);
696  {
697  st_data_t compat_data;
698  rb_alloc_func_t allocator = rb_get_alloc_func(RBASIC(obj)->klass);
699  if (st_lookup(compat_allocator_tbl,
700  (st_data_t)allocator,
701  &compat_data)) {
702  marshal_compat_t *compat = (marshal_compat_t*)compat_data;
703  VALUE real_obj = obj;
704  obj = compat->dumper(real_obj);
705  st_insert(arg->compat_tbl, (st_data_t)obj, (st_data_t)real_obj);
706  if (obj != real_obj && !ivtbl) hasiv = 0;
707  }
708  }
709  if (hasiv) w_byte(TYPE_IVAR, arg);
710 
711  switch (BUILTIN_TYPE(obj)) {
712  case T_CLASS:
713  if (FL_TEST(obj, FL_SINGLETON)) {
714  rb_raise(rb_eTypeError, "singleton class can't be dumped");
715  }
716  w_byte(TYPE_CLASS, arg);
717  {
718  VALUE path = class2path(obj);
719  w_bytes(RSTRING_PTR(path), RSTRING_LEN(path), arg);
720  RB_GC_GUARD(path);
721  }
722  break;
723 
724  case T_MODULE:
725  w_byte(TYPE_MODULE, arg);
726  {
727  VALUE path = class2path(obj);
728  w_bytes(RSTRING_PTR(path), RSTRING_LEN(path), arg);
729  RB_GC_GUARD(path);
730  }
731  break;
732 
733  case T_FLOAT:
734  w_byte(TYPE_FLOAT, arg);
735  w_float(RFLOAT_VALUE(obj), arg);
736  break;
737 
738  case T_BIGNUM:
739  w_byte(TYPE_BIGNUM, arg);
740  {
741  char sign = RBIGNUM_SIGN(obj) ? '+' : '-';
742  long len = RBIGNUM_LEN(obj);
743  BDIGIT *d = RBIGNUM_DIGITS(obj);
744 
745  w_byte(sign, arg);
746  w_long(SHORTLEN(len), arg); /* w_short? */
747  while (len--) {
748 #if SIZEOF_BDIGITS > SIZEOF_SHORT
749  BDIGIT num = *d;
750  int i;
751 
752  for (i=0; i<SIZEOF_BDIGITS; i+=SIZEOF_SHORT) {
753  w_short(num & SHORTMASK, arg);
754  num = SHORTDN(num);
755  if (len == 0 && num == 0) break;
756  }
757 #else
758  w_short(*d, arg);
759 #endif
760  d++;
761  }
762  }
763  break;
764 
765  case T_STRING:
766  w_uclass(obj, rb_cString, arg);
767  w_byte(TYPE_STRING, arg);
768  w_bytes(RSTRING_PTR(obj), RSTRING_LEN(obj), arg);
769  break;
770 
771  case T_REGEXP:
772  w_uclass(obj, rb_cRegexp, arg);
773  w_byte(TYPE_REGEXP, arg);
774  {
775  int opts = rb_reg_options(obj);
776  w_bytes(RREGEXP_SRC_PTR(obj), RREGEXP_SRC_LEN(obj), arg);
777  w_byte((char)opts, arg);
778  }
779  break;
780 
781  case T_ARRAY:
782  w_uclass(obj, rb_cArray, arg);
783  w_byte(TYPE_ARRAY, arg);
784  {
785  long i, len = RARRAY_LEN(obj);
786 
787  w_long(len, arg);
788  for (i=0; i<RARRAY_LEN(obj); i++) {
789  w_object(RARRAY_PTR(obj)[i], arg, limit);
790  if (len != RARRAY_LEN(obj)) {
791  rb_raise(rb_eRuntimeError, "array modified during dump");
792  }
793  }
794  }
795  break;
796 
797  case T_HASH:
798  w_uclass(obj, rb_cHash, arg);
799  if (NIL_P(RHASH_IFNONE(obj))) {
800  w_byte(TYPE_HASH, arg);
801  }
802  else if (FL_TEST(obj, FL_USER2)) {
803  /* FL_USER2 means HASH_PROC_DEFAULT (see hash.c) */
804  rb_raise(rb_eTypeError, "can't dump hash with default proc");
805  }
806  else {
807  w_byte(TYPE_HASH_DEF, arg);
808  }
809  w_long(RHASH_SIZE(obj), arg);
810  rb_hash_foreach(obj, hash_each, (st_data_t)&c_arg);
811  if (!NIL_P(RHASH_IFNONE(obj))) {
812  w_object(RHASH_IFNONE(obj), arg, limit);
813  }
814  break;
815 
816  case T_STRUCT:
817  w_class(TYPE_STRUCT, obj, arg, TRUE);
818  {
819  long len = RSTRUCT_LEN(obj);
820  VALUE mem;
821  long i;
822 
823  w_long(len, arg);
824  mem = rb_struct_members(obj);
825  for (i=0; i<len; i++) {
826  w_symbol(SYM2ID(RARRAY_PTR(mem)[i]), arg);
827  w_object(RSTRUCT_PTR(obj)[i], arg, limit);
828  }
829  }
830  break;
831 
832  case T_OBJECT:
833  w_class(TYPE_OBJECT, obj, arg, TRUE);
834  w_objivar(obj, &c_arg);
835  break;
836 
837  case T_DATA:
838  {
839  VALUE v;
840 
841  if (!rb_obj_respond_to(obj, s_dump_data, TRUE)) {
843  "no _dump_data is defined for class %s",
844  rb_obj_classname(obj));
845  }
846  v = rb_funcall2(obj, s_dump_data, 0, 0);
848  w_class(TYPE_DATA, obj, arg, TRUE);
849  w_object(v, arg, limit);
850  }
851  break;
852 
853  default:
854  rb_raise(rb_eTypeError, "can't dump %s",
855  rb_obj_classname(obj));
856  break;
857  }
858  RB_GC_GUARD(obj);
859  }
860  if (hasiv) {
861  w_ivar(obj, ivtbl, &c_arg);
862  }
863 }
864 
865 static void
867 {
868  if (!arg->symbols) return;
869  st_free_table(arg->symbols);
870  arg->symbols = 0;
871  st_free_table(arg->data);
872  arg->data = 0;
874  arg->compat_tbl = 0;
875  if (arg->encodings) {
876  st_free_table(arg->encodings);
877  arg->encodings = 0;
878  }
879 }
880 
881 NORETURN(static inline void io_needed(void));
882 static inline void
884 {
885  rb_raise(rb_eTypeError, "instance of IO needed");
886 }
887 
888 /*
889  * call-seq:
890  * dump( obj [, anIO] , limit=-1 ) -> anIO
891  *
892  * Serializes obj and all descendant objects. If anIO is
893  * specified, the serialized data will be written to it, otherwise the
894  * data will be returned as a String. If limit is specified, the
895  * traversal of subobjects will be limited to that depth. If limit is
896  * negative, no checking of depth will be performed.
897  *
898  * class Klass
899  * def initialize(str)
900  * @str = str
901  * end
902  * def say_hello
903  * @str
904  * end
905  * end
906  *
907  * (produces no output)
908  *
909  * o = Klass.new("hello\n")
910  * data = Marshal.dump(o)
911  * obj = Marshal.load(data)
912  * obj.say_hello #=> "hello\n"
913  *
914  * Marshal can't dump following objects:
915  * * anonymous Class/Module.
916  * * objects which related to its system (ex: Dir, File::Stat, IO, File, Socket
917  * and so on)
918  * * an instance of MatchData, Data, Method, UnboundMethod, Proc, Thread,
919  * ThreadGroup, Continuation
920  * * objects which defines singleton methods
921  */
922 static VALUE
924 {
925  VALUE obj, port, a1, a2;
926  int limit = -1;
927  struct dump_arg *arg;
928  volatile VALUE wrapper;
929 
930  port = Qnil;
931  rb_scan_args(argc, argv, "12", &obj, &a1, &a2);
932  if (argc == 3) {
933  if (!NIL_P(a2)) limit = NUM2INT(a2);
934  if (NIL_P(a1)) io_needed();
935  port = a1;
936  }
937  else if (argc == 2) {
938  if (FIXNUM_P(a1)) limit = FIX2INT(a1);
939  else if (NIL_P(a1)) io_needed();
940  else port = a1;
941  }
943  arg->dest = 0;
944  arg->symbols = st_init_numtable();
945  arg->data = st_init_numtable();
946  arg->infection = 0;
947  arg->compat_tbl = st_init_numtable();
948  arg->encodings = 0;
949  arg->str = rb_str_buf_new(0);
950  if (!NIL_P(port)) {
951  if (!rb_respond_to(port, s_write)) {
952  io_needed();
953  }
954  arg->dest = port;
955  if (rb_check_funcall(port, s_binmode, 0, 0) != Qundef) {
957  }
958  }
959  else {
960  port = arg->str;
961  }
962 
963  w_byte(MARSHAL_MAJOR, arg);
964  w_byte(MARSHAL_MINOR, arg);
965 
966  w_object(obj, arg, limit);
967  if (arg->dest) {
968  rb_io_write(arg->dest, arg->str);
969  rb_str_resize(arg->str, 0);
970  }
971  clear_dump_arg(arg);
972  RB_GC_GUARD(wrapper);
973 
974  return port;
975 }
976 
977 struct load_arg {
979  char *buf;
980  long buflen;
981  long readable;
982  long offset;
988 };
989 
990 static void
992 {
993  if (!arg->symbols) {
994  rb_raise(rb_eRuntimeError, "Marshal.load reentered at %s",
995  rb_id2name(sym));
996  }
997 }
998 
999 static void clear_load_arg(struct load_arg *arg);
1000 
1001 static void
1002 mark_load_arg(void *ptr)
1003 {
1004  struct load_arg *p = ptr;
1005  if (!p->symbols)
1006  return;
1007  rb_mark_tbl(p->data);
1009 }
1010 
1011 static void
1012 free_load_arg(void *ptr)
1013 {
1014  clear_load_arg(ptr);
1015  xfree(ptr);
1016 }
1017 
1018 static size_t
1019 memsize_load_arg(const void *ptr)
1020 {
1021  return ptr ? sizeof(struct load_arg) : 0;
1022 }
1023 
1025  "load_arg",
1027 };
1028 
1029 #define r_entry(v, arg) r_entry0((v), (arg)->data->num_entries, (arg))
1030 static VALUE r_entry0(VALUE v, st_index_t num, struct load_arg *arg);
1031 static VALUE r_object(struct load_arg *arg);
1032 static ID r_symbol(struct load_arg *arg);
1033 static VALUE path2class(VALUE path);
1034 
1035 NORETURN(static void too_short(void));
1036 static void
1038 {
1039  rb_raise(rb_eArgError, "marshal data too short");
1040 }
1041 
1042 static st_index_t
1044 {
1045  st_index_t idx = arg->data->num_entries;
1046 
1047  st_insert(arg->data, (st_data_t)idx, (st_data_t)Qundef);
1048  return idx;
1049 }
1050 
1051 static unsigned char
1053 {
1054  if (arg->buflen == 0) {
1055  long readable = arg->readable < BUFSIZ ? arg->readable : BUFSIZ;
1056  VALUE str, n = LONG2NUM(readable);
1057 
1058  str = rb_funcall2(arg->src, s_read, 1, &n);
1059 
1060  check_load_arg(arg, s_read);
1061  if (NIL_P(str)) too_short();
1062  StringValue(str);
1063  arg->infection |= (int)FL_TEST(str, MARSHAL_INFECTION);
1064  memcpy(arg->buf, RSTRING_PTR(str), RSTRING_LEN(str));
1065  arg->offset = 0;
1066  arg->buflen = RSTRING_LEN(str);
1067  }
1068  arg->buflen--;
1069  return arg->buf[arg->offset++];
1070 }
1071 
1072 static int
1074 {
1075  int c;
1076 
1077  if (RB_TYPE_P(arg->src, T_STRING)) {
1078  if (RSTRING_LEN(arg->src) > arg->offset) {
1079  c = (unsigned char)RSTRING_PTR(arg->src)[arg->offset++];
1080  }
1081  else {
1082  too_short();
1083  }
1084  }
1085  else {
1086  if (arg->readable >0 || arg->buflen > 0) {
1087  c = r_byte1_buffered(arg);
1088  }
1089  else {
1090  VALUE v = rb_funcall2(arg->src, s_getbyte, 0, 0);
1091  check_load_arg(arg, s_getbyte);
1092  if (NIL_P(v)) rb_eof_error();
1093  c = (unsigned char)NUM2CHR(v);
1094  }
1095  }
1096  return c;
1097 }
1098 
1099 static void
1101 {
1102  rb_raise(rb_eTypeError, "long too big for this architecture (size "
1103  STRINGIZE(SIZEOF_LONG)", given %d)", size);
1104 }
1105 
1106 #undef SIGN_EXTEND_CHAR
1107 #if __STDC__
1108 # define SIGN_EXTEND_CHAR(c) ((signed char)(c))
1109 #else /* not __STDC__ */
1110 /* As in Harbison and Steele. */
1111 # define SIGN_EXTEND_CHAR(c) ((((unsigned char)(c)) ^ 128) - 128)
1112 #endif
1113 
1114 static long
1116 {
1117  register long x;
1118  int c = SIGN_EXTEND_CHAR(r_byte(arg));
1119  long i;
1120 
1121  if (c == 0) return 0;
1122  if (c > 0) {
1123  if (4 < c && c < 128) {
1124  return c - 5;
1125  }
1126  if (c > (int)sizeof(long)) long_toobig(c);
1127  x = 0;
1128  for (i=0;i<c;i++) {
1129  x |= (long)r_byte(arg) << (8*i);
1130  }
1131  }
1132  else {
1133  if (-129 < c && c < -4) {
1134  return c + 5;
1135  }
1136  c = -c;
1137  if (c > (int)sizeof(long)) long_toobig(c);
1138  x = -1;
1139  for (i=0;i<c;i++) {
1140  x &= ~((long)0xff << (8*i));
1141  x |= (long)r_byte(arg) << (8*i);
1142  }
1143  }
1144  return x;
1145 }
1146 
1147 static VALUE
1148 r_bytes1(long len, struct load_arg *arg)
1149 {
1150  VALUE str, n = LONG2NUM(len);
1151 
1152  str = rb_funcall2(arg->src, s_read, 1, &n);
1153  check_load_arg(arg, s_read);
1154  if (NIL_P(str)) too_short();
1155  StringValue(str);
1156  if (RSTRING_LEN(str) != len) too_short();
1157  arg->infection |= (int)FL_TEST(str, MARSHAL_INFECTION);
1158 
1159  return str;
1160 }
1161 
1162 static VALUE
1163 r_bytes1_buffered(long len, struct load_arg *arg)
1164 {
1165  VALUE str;
1166 
1167  if (len <= arg->buflen) {
1168  str = rb_str_new(arg->buf+arg->offset, len);
1169  arg->offset += len;
1170  arg->buflen -= len;
1171  }
1172  else {
1173  long buflen = arg->buflen;
1174  long readable = arg->readable + 1;
1175  long tmp_len, read_len, need_len = len - buflen;
1176  VALUE tmp, n;
1177 
1178  readable = readable < BUFSIZ ? readable : BUFSIZ;
1179  read_len = need_len > readable ? need_len : readable;
1180  n = LONG2NUM(read_len);
1181  tmp = rb_funcall2(arg->src, s_read, 1, &n);
1182 
1183  check_load_arg(arg, s_read);
1184  if (NIL_P(tmp)) too_short();
1185  StringValue(tmp);
1186 
1187  tmp_len = RSTRING_LEN(tmp);
1188 
1189  if (tmp_len < need_len) too_short();
1190  arg->infection |= (int)FL_TEST(tmp, MARSHAL_INFECTION);
1191 
1192  str = rb_str_new(arg->buf+arg->offset, buflen);
1193  rb_str_cat(str, RSTRING_PTR(tmp), need_len);
1194 
1195  if (tmp_len > need_len) {
1196  buflen = tmp_len - need_len;
1197  memcpy(arg->buf, RSTRING_PTR(tmp)+need_len, buflen);
1198  arg->buflen = buflen;
1199  }
1200  else {
1201  arg->buflen = 0;
1202  }
1203  arg->offset = 0;
1204  }
1205 
1206  return str;
1207 }
1208 
1209 #define r_bytes(arg) r_bytes0(r_long(arg), (arg))
1210 
1211 static VALUE
1212 r_bytes0(long len, struct load_arg *arg)
1213 {
1214  VALUE str;
1215 
1216  if (len == 0) return rb_str_new(0, 0);
1217  if (RB_TYPE_P(arg->src, T_STRING)) {
1218  if (RSTRING_LEN(arg->src) - arg->offset >= len) {
1219  str = rb_str_new(RSTRING_PTR(arg->src)+arg->offset, len);
1220  arg->offset += len;
1221  }
1222  else {
1223  too_short();
1224  }
1225  }
1226  else {
1227  if (arg->readable > 0 || arg->buflen > 0) {
1228  str = r_bytes1_buffered(len, arg);
1229  }
1230  else {
1231  str = r_bytes1(len, arg);
1232  }
1233  }
1234  return str;
1235 }
1236 
1237 static int
1239 {
1240  if (id == rb_id_encoding()) {
1241  int idx = rb_enc_find_index(StringValueCStr(val));
1242  return idx;
1243  }
1244  else if (id == rb_intern("E")) {
1245  if (val == Qfalse) return rb_usascii_encindex();
1246  else if (val == Qtrue) return rb_utf8_encindex();
1247  /* bogus ignore */
1248  }
1249  return -1;
1250 }
1251 
1252 static ID
1254 {
1255  st_data_t id;
1256  long num = r_long(arg);
1257 
1258  if (!st_lookup(arg->symbols, num, &id)) {
1259  rb_raise(rb_eArgError, "bad symbol");
1260  }
1261  return (ID)id;
1262 }
1263 
1264 static ID
1265 r_symreal(struct load_arg *arg, int ivar)
1266 {
1267  VALUE s = r_bytes(arg);
1268  ID id;
1269  int idx = -1;
1270  st_index_t n = arg->symbols->num_entries;
1271 
1272  st_insert(arg->symbols, (st_data_t)n, (st_data_t)0);
1273  if (ivar) {
1274  long num = r_long(arg);
1275  while (num-- > 0) {
1276  id = r_symbol(arg);
1277  idx = id2encidx(id, r_object(arg));
1278  }
1279  }
1280  if (idx > 0) rb_enc_associate_index(s, idx);
1281  id = rb_intern_str(s);
1282  st_insert(arg->symbols, (st_data_t)n, (st_data_t)id);
1283 
1284  return id;
1285 }
1286 
1287 static ID
1289 {
1290  int type, ivar = 0;
1291 
1292  again:
1293  switch ((type = r_byte(arg))) {
1294  default:
1295  rb_raise(rb_eArgError, "dump format error for symbol(0x%x)", type);
1296  case TYPE_IVAR:
1297  ivar = 1;
1298  goto again;
1299  case TYPE_SYMBOL:
1300  return r_symreal(arg, ivar);
1301  case TYPE_SYMLINK:
1302  if (ivar) {
1303  rb_raise(rb_eArgError, "dump format error (symlink with encoding)");
1304  }
1305  return r_symlink(arg);
1306  }
1307 }
1308 
1309 static VALUE
1311 {
1312  return rb_id2str(r_symbol(arg));
1313 }
1314 
1315 static VALUE
1317 {
1318  return r_bytes(arg);
1319 }
1320 
1321 static VALUE
1323 {
1324  st_data_t real_obj = (VALUE)Qundef;
1325  if (st_lookup(arg->compat_tbl, v, &real_obj)) {
1326  st_insert(arg->data, num, (st_data_t)real_obj);
1327  }
1328  else {
1329  st_insert(arg->data, num, (st_data_t)v);
1330  }
1331  if (arg->infection &&
1332  !RB_TYPE_P(v, T_CLASS) && !RB_TYPE_P(v, T_MODULE)) {
1333  FL_SET(v, arg->infection);
1334  if ((VALUE)real_obj != Qundef)
1335  FL_SET((VALUE)real_obj, arg->infection);
1336  }
1337  return v;
1338 }
1339 
1340 static VALUE
1342 {
1343  st_data_t data;
1344  if (st_lookup(arg->compat_tbl, v, &data)) {
1345  VALUE real_obj = (VALUE)data;
1346  rb_alloc_func_t allocator = rb_get_alloc_func(CLASS_OF(real_obj));
1347  st_data_t key = v;
1348  if (st_lookup(compat_allocator_tbl, (st_data_t)allocator, &data)) {
1349  marshal_compat_t *compat = (marshal_compat_t*)data;
1350  compat->loader(real_obj, v);
1351  }
1352  st_delete(arg->compat_tbl, &key, 0);
1353  v = real_obj;
1354  }
1355  if (arg->proc) {
1356  v = rb_funcall(arg->proc, s_call, 1, v);
1357  check_load_arg(arg, s_call);
1358  }
1359  return v;
1360 }
1361 
1362 static void
1363 r_ivar(VALUE obj, int *has_encoding, struct load_arg *arg)
1364 {
1365  long len;
1366 
1367  len = r_long(arg);
1368  if (len > 0) {
1369  do {
1370  ID id = r_symbol(arg);
1371  VALUE val = r_object(arg);
1372  int idx = id2encidx(id, val);
1373  if (idx >= 0) {
1374  rb_enc_associate_index(obj, idx);
1375  if (has_encoding) *has_encoding = TRUE;
1376  }
1377  else {
1378  rb_ivar_set(obj, id, val);
1379  }
1380  } while (--len > 0);
1381  }
1382 }
1383 
1384 static VALUE
1386 {
1387  VALUE v = rb_path_to_class(path);
1388 
1389  if (!RB_TYPE_P(v, T_CLASS)) {
1390  rb_raise(rb_eArgError, "%"PRIsVALUE" does not refer to class", path);
1391  }
1392  return v;
1393 }
1394 
1395 static VALUE
1397 {
1398  VALUE v = rb_path_to_class(path);
1399 
1400  if (!RB_TYPE_P(v, T_MODULE)) {
1401  rb_raise(rb_eArgError, "%"PRIsVALUE" does not refer to module", path);
1402  }
1403  return v;
1404 }
1405 
1406 static VALUE
1407 obj_alloc_by_klass(VALUE klass, struct load_arg *arg, VALUE *oldclass)
1408 {
1409  st_data_t data;
1410  rb_alloc_func_t allocator;
1411 
1412  allocator = rb_get_alloc_func(klass);
1413  if (st_lookup(compat_allocator_tbl, (st_data_t)allocator, &data)) {
1414  marshal_compat_t *compat = (marshal_compat_t*)data;
1415  VALUE real_obj = rb_obj_alloc(klass);
1416  VALUE obj = rb_obj_alloc(compat->oldclass);
1417  if (oldclass) *oldclass = compat->oldclass;
1418  st_insert(arg->compat_tbl, (st_data_t)obj, (st_data_t)real_obj);
1419  return obj;
1420  }
1421 
1422  return rb_obj_alloc(klass);
1423 }
1424 
1425 static VALUE
1427 {
1428  return obj_alloc_by_klass(path2class(path), arg, 0);
1429 }
1430 
1431 static VALUE
1433 {
1434  long i = RARRAY_LEN(extmod);
1435  while (i > 0) {
1436  VALUE m = RARRAY_PTR(extmod)[--i];
1437  rb_extend_object(obj, m);
1438  }
1439  return obj;
1440 }
1441 
1442 #define prohibit_ivar(type, str) do { \
1443  if (!ivp || !*ivp) break; \
1444  rb_raise(rb_eTypeError, \
1445  "can't override instance variable of "type" `%"PRIsVALUE"'", \
1446  (str)); \
1447  } while (0)
1448 
1449 static VALUE
1450 r_object0(struct load_arg *arg, int *ivp, VALUE extmod)
1451 {
1452  VALUE v = Qnil;
1453  int type = r_byte(arg);
1454  long id;
1455  st_data_t link;
1456 
1457  switch (type) {
1458  case TYPE_LINK:
1459  id = r_long(arg);
1460  if (!st_lookup(arg->data, (st_data_t)id, &link)) {
1461  rb_raise(rb_eArgError, "dump format error (unlinked)");
1462  }
1463  v = (VALUE)link;
1464  if (arg->proc) {
1465  v = rb_funcall(arg->proc, s_call, 1, v);
1466  check_load_arg(arg, s_call);
1467  }
1468  break;
1469 
1470  case TYPE_IVAR:
1471  {
1472  int ivar = TRUE;
1473 
1474  v = r_object0(arg, &ivar, extmod);
1475  if (ivar) r_ivar(v, NULL, arg);
1476  }
1477  break;
1478 
1479  case TYPE_EXTENDED:
1480  {
1481  VALUE m = path2module(r_unique(arg));
1482 
1483  if (NIL_P(extmod)) extmod = rb_ary_tmp_new(0);
1484  rb_ary_push(extmod, m);
1485 
1486  v = r_object0(arg, 0, extmod);
1487  while (RARRAY_LEN(extmod) > 0) {
1488  m = rb_ary_pop(extmod);
1489  rb_extend_object(v, m);
1490  }
1491  }
1492  break;
1493 
1494  case TYPE_UCLASS:
1495  {
1496  VALUE c = path2class(r_unique(arg));
1497 
1498  if (FL_TEST(c, FL_SINGLETON)) {
1499  rb_raise(rb_eTypeError, "singleton can't be loaded");
1500  }
1501  v = r_object0(arg, 0, extmod);
1502  if (rb_special_const_p(v) || RB_TYPE_P(v, T_OBJECT) || RB_TYPE_P(v, T_CLASS)) {
1503  format_error:
1504  rb_raise(rb_eArgError, "dump format error (user class)");
1505  }
1506  if (RB_TYPE_P(v, T_MODULE) || !RTEST(rb_class_inherited_p(c, RBASIC(v)->klass))) {
1507  VALUE tmp = rb_obj_alloc(c);
1508 
1509  if (TYPE(v) != TYPE(tmp)) goto format_error;
1510  }
1511  RBASIC(v)->klass = c;
1512  }
1513  break;
1514 
1515  case TYPE_NIL:
1516  v = Qnil;
1517  v = r_leave(v, arg);
1518  break;
1519 
1520  case TYPE_TRUE:
1521  v = Qtrue;
1522  v = r_leave(v, arg);
1523  break;
1524 
1525  case TYPE_FALSE:
1526  v = Qfalse;
1527  v = r_leave(v, arg);
1528  break;
1529 
1530  case TYPE_FIXNUM:
1531  {
1532  long i = r_long(arg);
1533  v = LONG2FIX(i);
1534  }
1535  v = r_leave(v, arg);
1536  break;
1537 
1538  case TYPE_FLOAT:
1539  {
1540  double d;
1541  VALUE str = r_bytes(arg);
1542  const char *ptr = RSTRING_PTR(str);
1543 
1544  if (strcmp(ptr, "nan") == 0) {
1545  d = NAN;
1546  }
1547  else if (strcmp(ptr, "inf") == 0) {
1548  d = INFINITY;
1549  }
1550  else if (strcmp(ptr, "-inf") == 0) {
1551  d = -INFINITY;
1552  }
1553  else {
1554  char *e;
1555  d = strtod(ptr, &e);
1556  d = load_mantissa(d, e, RSTRING_LEN(str) - (e - ptr));
1557  }
1558  v = DBL2NUM(d);
1559  v = r_entry(v, arg);
1560  v = r_leave(v, arg);
1561  }
1562  break;
1563 
1564  case TYPE_BIGNUM:
1565  {
1566  long len;
1567  BDIGIT *digits;
1568  VALUE data;
1569 
1570  NEWOBJ_OF(big, struct RBignum, rb_cBignum, T_BIGNUM);
1571  RBIGNUM_SET_SIGN(big, (r_byte(arg) == '+'));
1572  len = r_long(arg);
1573  data = r_bytes0(len * 2, arg);
1574 #if SIZEOF_BDIGITS == SIZEOF_SHORT
1575  rb_big_resize((VALUE)big, len);
1576 #else
1577  rb_big_resize((VALUE)big, (len + 1) * 2 / sizeof(BDIGIT));
1578 #endif
1579  digits = RBIGNUM_DIGITS(big);
1580  MEMCPY(digits, RSTRING_PTR(data), char, len * 2);
1581  rb_str_resize(data, 0L);
1582 #if SIZEOF_BDIGITS > SIZEOF_SHORT
1583  MEMZERO((char *)digits + len * 2, char,
1584  RBIGNUM_LEN(big) * sizeof(BDIGIT) - len * 2);
1585 #endif
1586  len = RBIGNUM_LEN(big);
1587  while (len > 0) {
1588  unsigned char *p = (unsigned char *)digits;
1589  BDIGIT num = 0;
1590 #if SIZEOF_BDIGITS > SIZEOF_SHORT
1591  int shift = 0;
1592  int i;
1593 
1594  for (i=0; i<SIZEOF_BDIGITS; i++) {
1595  num |= (int)p[i] << shift;
1596  shift += 8;
1597  }
1598 #else
1599  num = p[0] | (p[1] << 8);
1600 #endif
1601  *digits++ = num;
1602  len--;
1603  }
1604  v = rb_big_norm((VALUE)big);
1605  v = r_entry(v, arg);
1606  v = r_leave(v, arg);
1607  }
1608  break;
1609 
1610  case TYPE_STRING:
1611  v = r_entry(r_string(arg), arg);
1612  v = r_leave(v, arg);
1613  break;
1614 
1615  case TYPE_REGEXP:
1616  {
1617  VALUE str = r_bytes(arg);
1618  int options = r_byte(arg);
1619  int has_encoding = FALSE;
1620  st_index_t idx = r_prepare(arg);
1621 
1622  if (ivp) {
1623  r_ivar(str, &has_encoding, arg);
1624  *ivp = FALSE;
1625  }
1626  if (!has_encoding) {
1627  /* 1.8 compatibility; remove escapes undefined in 1.8 */
1628  char *ptr = RSTRING_PTR(str), *dst = ptr, *src = ptr;
1629  long len = RSTRING_LEN(str);
1630  long bs = 0;
1631  for (; len-- > 0; *dst++ = *src++) {
1632  switch (*src) {
1633  case '\\': bs++; break;
1634  case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
1635  case 'm': case 'o': case 'p': case 'q': case 'u': case 'y':
1636  case 'E': case 'F': case 'H': case 'I': case 'J': case 'K':
1637  case 'L': case 'N': case 'O': case 'P': case 'Q': case 'R':
1638  case 'S': case 'T': case 'U': case 'V': case 'X': case 'Y':
1639  if (bs & 1) --dst;
1640  default: bs = 0; break;
1641  }
1642  }
1643  rb_str_set_len(str, dst - ptr);
1644  }
1645  v = r_entry0(rb_reg_new_str(str, options), idx, arg);
1646  v = r_leave(v, arg);
1647  }
1648  break;
1649 
1650  case TYPE_ARRAY:
1651  {
1652  volatile long len = r_long(arg); /* gcc 2.7.2.3 -O2 bug?? */
1653 
1654  v = rb_ary_new2(len);
1655  v = r_entry(v, arg);
1656  arg->readable += len - 1;
1657  while (len--) {
1658  rb_ary_push(v, r_object(arg));
1659  arg->readable--;
1660  }
1661  v = r_leave(v, arg);
1662  arg->readable++;
1663  }
1664  break;
1665 
1666  case TYPE_HASH:
1667  case TYPE_HASH_DEF:
1668  {
1669  long len = r_long(arg);
1670 
1671  v = rb_hash_new();
1672  v = r_entry(v, arg);
1673  arg->readable += (len - 1) * 2;
1674  while (len--) {
1675  VALUE key = r_object(arg);
1676  VALUE value = r_object(arg);
1677  rb_hash_aset(v, key, value);
1678  arg->readable -= 2;
1679  }
1680  arg->readable += 2;
1681  if (type == TYPE_HASH_DEF) {
1682  RHASH_IFNONE(v) = r_object(arg);
1683  }
1684  v = r_leave(v, arg);
1685  }
1686  break;
1687 
1688  case TYPE_STRUCT:
1689  {
1690  VALUE mem, values;
1691  volatile long i; /* gcc 2.7.2.3 -O2 bug?? */
1692  ID slot;
1693  st_index_t idx = r_prepare(arg);
1694  VALUE klass = path2class(r_unique(arg));
1695  long len = r_long(arg);
1696 
1697  v = rb_obj_alloc(klass);
1698  if (!RB_TYPE_P(v, T_STRUCT)) {
1699  rb_raise(rb_eTypeError, "class %s not a struct", rb_class2name(klass));
1700  }
1701  mem = rb_struct_s_members(klass);
1702  if (RARRAY_LEN(mem) != len) {
1703  rb_raise(rb_eTypeError, "struct %s not compatible (struct size differs)",
1704  rb_class2name(klass));
1705  }
1706 
1707  arg->readable += (len - 1) * 2;
1708  v = r_entry0(v, idx, arg);
1709  values = rb_ary_new2(len);
1710  for (i=0; i<len; i++) {
1711  slot = r_symbol(arg);
1712 
1713  if (RARRAY_PTR(mem)[i] != ID2SYM(slot)) {
1714  rb_raise(rb_eTypeError, "struct %s not compatible (:%s for :%s)",
1715  rb_class2name(klass),
1716  rb_id2name(slot),
1717  rb_id2name(SYM2ID(RARRAY_PTR(mem)[i])));
1718  }
1719  rb_ary_push(values, r_object(arg));
1720  arg->readable -= 2;
1721  }
1722  rb_struct_initialize(v, values);
1723  v = r_leave(v, arg);
1724  arg->readable += 2;
1725  }
1726  break;
1727 
1728  case TYPE_USERDEF:
1729  {
1730  VALUE klass = path2class(r_unique(arg));
1731  VALUE data;
1732 
1733  if (!rb_obj_respond_to(klass, s_load, TRUE)) {
1734  rb_raise(rb_eTypeError, "class %s needs to have method `_load'",
1735  rb_class2name(klass));
1736  }
1737  data = r_string(arg);
1738  if (ivp) {
1739  r_ivar(data, NULL, arg);
1740  *ivp = FALSE;
1741  }
1742  v = rb_funcall2(klass, s_load, 1, &data);
1743  check_load_arg(arg, s_load);
1744  v = r_entry(v, arg);
1745  v = r_leave(v, arg);
1746  }
1747  break;
1748 
1749  case TYPE_USRMARSHAL:
1750  {
1751  VALUE klass = path2class(r_unique(arg));
1752  VALUE oldclass = 0;
1753  VALUE data;
1754 
1755  v = obj_alloc_by_klass(klass, arg, &oldclass);
1756  if (!NIL_P(extmod)) {
1757  /* for the case marshal_load is overridden */
1758  append_extmod(v, extmod);
1759  }
1760  if (!rb_obj_respond_to(v, s_mload, TRUE)) {
1761  rb_raise(rb_eTypeError, "instance of %s needs to have method `marshal_load'",
1762  rb_class2name(klass));
1763  }
1764  v = r_entry(v, arg);
1765  data = r_object(arg);
1766  rb_funcall2(v, s_mload, 1, &data);
1767  check_load_arg(arg, s_mload);
1768  v = r_leave(v, arg);
1769  if (!NIL_P(extmod)) {
1770  if (oldclass) append_extmod(v, extmod);
1771  rb_ary_clear(extmod);
1772  }
1773  }
1774  break;
1775 
1776  case TYPE_OBJECT:
1777  {
1778  st_index_t idx = r_prepare(arg);
1779  v = obj_alloc_by_path(r_unique(arg), arg);
1780  if (!RB_TYPE_P(v, T_OBJECT)) {
1781  rb_raise(rb_eArgError, "dump format error");
1782  }
1783  v = r_entry0(v, idx, arg);
1784  r_ivar(v, NULL, arg);
1785  v = r_leave(v, arg);
1786  }
1787  break;
1788 
1789  case TYPE_DATA:
1790  {
1791  VALUE klass = path2class(r_unique(arg));
1792  VALUE oldclass = 0;
1793  VALUE r;
1794 
1795  v = obj_alloc_by_klass(klass, arg, &oldclass);
1796  if (!RB_TYPE_P(v, T_DATA)) {
1797  rb_raise(rb_eArgError, "dump format error");
1798  }
1799  v = r_entry(v, arg);
1800  if (!rb_obj_respond_to(v, s_load_data, TRUE)) {
1802  "class %s needs to have instance method `_load_data'",
1803  rb_class2name(klass));
1804  }
1805  r = r_object0(arg, 0, extmod);
1806  rb_funcall2(v, s_load_data, 1, &r);
1808  v = r_leave(v, arg);
1809  }
1810  break;
1811 
1812  case TYPE_MODULE_OLD:
1813  {
1814  VALUE str = r_bytes(arg);
1815 
1816  v = rb_path_to_class(str);
1817  prohibit_ivar("class/module", str);
1818  v = r_entry(v, arg);
1819  v = r_leave(v, arg);
1820  }
1821  break;
1822 
1823  case TYPE_CLASS:
1824  {
1825  VALUE str = r_bytes(arg);
1826 
1827  v = path2class(str);
1828  prohibit_ivar("class", str);
1829  v = r_entry(v, arg);
1830  v = r_leave(v, arg);
1831  }
1832  break;
1833 
1834  case TYPE_MODULE:
1835  {
1836  VALUE str = r_bytes(arg);
1837 
1838  v = path2module(str);
1839  prohibit_ivar("module", str);
1840  v = r_entry(v, arg);
1841  v = r_leave(v, arg);
1842  }
1843  break;
1844 
1845  case TYPE_SYMBOL:
1846  if (ivp) {
1847  v = ID2SYM(r_symreal(arg, *ivp));
1848  *ivp = FALSE;
1849  }
1850  else {
1851  v = ID2SYM(r_symreal(arg, 0));
1852  }
1853  v = r_leave(v, arg);
1854  break;
1855 
1856  case TYPE_SYMLINK:
1857  v = ID2SYM(r_symlink(arg));
1858  break;
1859 
1860  default:
1861  rb_raise(rb_eArgError, "dump format error(0x%x)", type);
1862  break;
1863  }
1864  return v;
1865 }
1866 
1867 static VALUE
1869 {
1870  return r_object0(arg, 0, Qnil);
1871 }
1872 
1873 static void
1875 {
1876  if (arg->buf) {
1877  xfree(arg->buf);
1878  arg->buf = 0;
1879  }
1880  arg->buflen = 0;
1881  arg->offset = 0;
1882  arg->readable = 0;
1883  if (!arg->symbols) return;
1884  st_free_table(arg->symbols);
1885  arg->symbols = 0;
1886  st_free_table(arg->data);
1887  arg->data = 0;
1888  st_free_table(arg->compat_tbl);
1889  arg->compat_tbl = 0;
1890 }
1891 
1892 /*
1893  * call-seq:
1894  * load( source [, proc] ) -> obj
1895  * restore( source [, proc] ) -> obj
1896  *
1897  * Returns the result of converting the serialized data in source into a
1898  * Ruby object (possibly with associated subordinate objects). source
1899  * may be either an instance of IO or an object that responds to
1900  * to_str. If proc is specified, it will be passed each object as it
1901  * is deserialized.
1902  *
1903  * Never pass untrusted data (including user supplied input) to this method.
1904  * Please see the overview for further details.
1905  */
1906 static VALUE
1908 {
1909  VALUE port, proc;
1910  int major, minor, infection = 0;
1911  VALUE v;
1912  volatile VALUE wrapper;
1913  struct load_arg *arg;
1914 
1915  rb_scan_args(argc, argv, "11", &port, &proc);
1916  v = rb_check_string_type(port);
1917  if (!NIL_P(v)) {
1918  infection = (int)FL_TEST(port, MARSHAL_INFECTION); /* original taintedness */
1919  port = v;
1920  }
1921  else if (rb_respond_to(port, s_getbyte) && rb_respond_to(port, s_read)) {
1922  rb_check_funcall(port, s_binmode, 0, 0);
1923  infection = (int)(FL_TAINT | FL_TEST(port, FL_UNTRUSTED));
1924  }
1925  else {
1926  io_needed();
1927  }
1929  arg->infection = infection;
1930  arg->src = port;
1931  arg->offset = 0;
1932  arg->symbols = st_init_numtable();
1933  arg->data = st_init_numtable();
1934  arg->compat_tbl = st_init_numtable();
1935  arg->proc = 0;
1936  arg->readable = 0;
1937 
1938  if (NIL_P(v))
1939  arg->buf = xmalloc(BUFSIZ);
1940  else
1941  arg->buf = 0;
1942 
1943  major = r_byte(arg);
1944  minor = r_byte(arg);
1945  if (major != MARSHAL_MAJOR || minor > MARSHAL_MINOR) {
1946  clear_load_arg(arg);
1947  rb_raise(rb_eTypeError, "incompatible marshal file format (can't be read)\n\
1948 \tformat version %d.%d required; %d.%d given",
1949  MARSHAL_MAJOR, MARSHAL_MINOR, major, minor);
1950  }
1951  if (RTEST(ruby_verbose) && minor != MARSHAL_MINOR) {
1952  rb_warn("incompatible marshal file format (can be read)\n\
1953 \tformat version %d.%d required; %d.%d given",
1954  MARSHAL_MAJOR, MARSHAL_MINOR, major, minor);
1955  }
1956 
1957  if (!NIL_P(proc)) arg->proc = proc;
1958  v = r_object(arg);
1959  clear_load_arg(arg);
1960  RB_GC_GUARD(wrapper);
1961 
1962  return v;
1963 }
1964 
1965 /*
1966  * The marshaling library converts collections of Ruby objects into a
1967  * byte stream, allowing them to be stored outside the currently
1968  * active script. This data may subsequently be read and the original
1969  * objects reconstituted.
1970  *
1971  * Marshaled data has major and minor version numbers stored along
1972  * with the object information. In normal use, marshaling can only
1973  * load data written with the same major version number and an equal
1974  * or lower minor version number. If Ruby's ``verbose'' flag is set
1975  * (normally using -d, -v, -w, or --verbose) the major and minor
1976  * numbers must match exactly. Marshal versioning is independent of
1977  * Ruby's version numbers. You can extract the version by reading the
1978  * first two bytes of marshaled data.
1979  *
1980  * str = Marshal.dump("thing")
1981  * RUBY_VERSION #=> "1.9.0"
1982  * str[0].ord #=> 4
1983  * str[1].ord #=> 8
1984  *
1985  * Some objects cannot be dumped: if the objects to be dumped include
1986  * bindings, procedure or method objects, instances of class IO, or
1987  * singleton objects, a TypeError will be raised.
1988  *
1989  * If your class has special serialization needs (for example, if you
1990  * want to serialize in some specific format), or if it contains
1991  * objects that would otherwise not be serializable, you can implement
1992  * your own serialization strategy.
1993  *
1994  * There are two methods of doing this, your object can define either
1995  * marshal_dump and marshal_load or _dump and _load. marshal_dump will take
1996  * precedence over _dump if both are defined. marshal_dump may result in
1997  * smaller Marshal strings.
1998  *
1999  * == Security considerations
2000  *
2001  * By design, Marshal.load can deserialize almost any class loaded into the
2002  * Ruby process. In many cases this can lead to remote code execution if the
2003  * Marshal data is loaded from an untrusted source.
2004  *
2005  * As a result, Marshal.load is not suitable as a general purpose serialization
2006  * format and you should never unmarshal user supplied input or other untrusted
2007  * data.
2008  *
2009  * If you need to deserialize untrusted data, use JSON or another serialization
2010  * format that is only able to load simple, 'primitive' types such as String,
2011  * Array, Hash, etc. Never allow user input to specify arbitrary types to
2012  * deserialize into.
2013  *
2014  * == marshal_dump and marshal_load
2015  *
2016  * When dumping an object the method marshal_dump will be called.
2017  * marshal_dump must return a result containing the information necessary for
2018  * marshal_load to reconstitute the object. The result can be any object.
2019  *
2020  * When loading an object dumped using marshal_dump the object is first
2021  * allocated then marshal_load is called with the result from marshal_dump.
2022  * marshal_load must recreate the object from the information in the result.
2023  *
2024  * Example:
2025  *
2026  * class MyObj
2027  * def initialize name, version, data
2028  * @name = name
2029  * @version = version
2030  * @data = data
2031  * end
2032  *
2033  * def marshal_dump
2034  * [@name, @version]
2035  * end
2036  *
2037  * def marshal_load array
2038  * @name, @version = array
2039  * end
2040  * end
2041  *
2042  * == _dump and _load
2043  *
2044  * Use _dump and _load when you need to allocate the object you're restoring
2045  * yourself.
2046  *
2047  * When dumping an object the instance method _dump is called with an Integer
2048  * which indicates the maximum depth of objects to dump (a value of -1 implies
2049  * that you should disable depth checking). _dump must return a String
2050  * containing the information necessary to reconstitute the object.
2051  *
2052  * The class method _load should take a String and use it to return an object
2053  * of the same class.
2054  *
2055  * Example:
2056  *
2057  * class MyObj
2058  * def initialize name, version, data
2059  * @name = name
2060  * @version = version
2061  * @data = data
2062  * end
2063  *
2064  * def _dump level
2065  * [@name, @version].join ':'
2066  * end
2067  *
2068  * def self._load args
2069  * new(*args.split(':'))
2070  * end
2071  * end
2072  *
2073  * Since Marhsal.dump outputs a string you can have _dump return a Marshal
2074  * string which is Marshal.loaded in _load for complex objects.
2075  */
2076 void
2078 {
2079 #undef rb_intern
2080 #define rb_intern(str) rb_intern_const(str)
2081 
2082  VALUE rb_mMarshal = rb_define_module("Marshal");
2083 
2084  s_dump = rb_intern("_dump");
2085  s_load = rb_intern("_load");
2086  s_mdump = rb_intern("marshal_dump");
2087  s_mload = rb_intern("marshal_load");
2088  s_dump_data = rb_intern("_dump_data");
2089  s_load_data = rb_intern("_load_data");
2090  s_alloc = rb_intern("_alloc");
2091  s_call = rb_intern("call");
2092  s_getbyte = rb_intern("getbyte");
2093  s_read = rb_intern("read");
2094  s_write = rb_intern("write");
2095  s_binmode = rb_intern("binmode");
2096 
2097  rb_define_module_function(rb_mMarshal, "dump", marshal_dump, -1);
2098  rb_define_module_function(rb_mMarshal, "load", marshal_load, -1);
2099  rb_define_module_function(rb_mMarshal, "restore", marshal_load, -1);
2100 
2101  rb_define_const(rb_mMarshal, "MAJOR_VERSION", INT2FIX(MARSHAL_MAJOR));
2102  rb_define_const(rb_mMarshal, "MINOR_VERSION", INT2FIX(MARSHAL_MINOR));
2103 
2104  compat_allocator_tbl = st_init_numtable();
2106  Data_Wrap_Struct(rb_cData, mark_marshal_compat_t, 0, compat_allocator_tbl);
2108 }
2109 
2110 VALUE
2112 {
2113  int argc = 1;
2114  VALUE argv[2];
2115 
2116  argv[0] = obj;
2117  argv[1] = port;
2118  if (!NIL_P(port)) argc = 2;
2119  return marshal_dump(argc, argv);
2120 }
2121 
2122 VALUE
2124 {
2125  return marshal_load(1, &port);
2126 }
#define RB_TYPE_P(obj, type)
static VALUE marshal_load(int argc, VALUE *argv)
Definition: marshal.c:1907
#define ALLOC(type)
static const rb_data_type_t dump_arg_data
Definition: marshal.c:186
static void long_toobig(int size)
Definition: marshal.c:1100
int rb_enc_get_index(VALUE obj)
Definition: encoding.c:690
#define TYPE_OBJECT
Definition: marshal.c:60
static long r_long(struct load_arg *arg)
Definition: marshal.c:1115
VALUE proc
Definition: marshal.c:985
#define FLONUM_P(x)
char * buf
Definition: marshal.c:979
VALUE rb_ary_pop(VALUE ary)
Definition: array.c:879
int infection
Definition: marshal.c:142
#define RSTRUCT_LEN(st)
static int rb_special_const_p(VALUE obj)
Definition: ripper.y:1560
static VALUE class2path(VALUE klass)
Definition: marshal.c:208
#define FALSE
Definition: nkf.h:174
#define load_mantissa(d, buf, len)
Definition: marshal.c:345
#define T_STRUCT
void rb_mark_tbl(struct st_table *)
Definition: gc.c:2543
VALUE(* rb_alloc_func_t)(VALUE)
Definition: ripper.y:352
VALUE rb_struct_members(VALUE)
Definition: struct.c:53
int i
Definition: win32ole.c:784
unsigned long VALUE
Definition: ripper.y:104
const char * rb_obj_classname(VALUE)
Definition: variable.c:396
static unsigned char r_byte1_buffered(struct load_arg *arg)
Definition: marshal.c:1052
VALUE rb_id2str(ID id)
Definition: ripper.c:16992
int minor
Definition: tcltklib.c:110
#define FL_TEST(x, f)
static size_t memsize_dump_arg(const void *ptr)
Definition: marshal.c:181
int st_lookup(st_table *, st_data_t, st_data_t *)
void st_add_direct(st_table *, st_data_t, st_data_t)
Definition: st.c:624
struct dump_arg * arg
Definition: marshal.c:147
static int w_obj_each(st_data_t key, st_data_t val, st_data_t a)
Definition: marshal.c:514
#define SIZEOF_BDIGITS
Definition: ripper.y:185
static void w_objivar(VALUE obj, struct dump_call_arg *arg)
Definition: marshal.c:576
#define FL_SET(x, f)
st_table * st_init_numtable(void)
Definition: st.c:272
#define T_ICLASS
VALUE rb_marshal_dump(VALUE obj, VALUE port)
Definition: marshal.c:2111
static const char * must_not_be_anonymous(const char *type, VALUE path)
Definition: marshal.c:192
#define SHORTMASK
Definition: marshal.c:28
static void w_long(long, struct dump_arg *)
Definition: marshal.c:258
#define rb_enc_name(enc)
static void w_object(VALUE, struct dump_arg *, int)
Definition: marshal.c:595
const int id
Definition: nkf.c:209
static VALUE marshal_dump(int argc, VALUE *argv)
Definition: marshal.c:923
#define r_bytes(arg)
Definition: marshal.c:1209
#define RFLOAT_VALUE(v)
#define TYPE_LINK
Definition: marshal.c:80
#define NAN
Definition: missing.h:146
#define RCLASS_ORIGIN(c)
#define RBIGNUM_SIGN(b)
VALUE rb_eTypeError
Definition: error.c:511
#define FLOAT_DIG
Definition: marshal.c:351
#define SHORTLEN(x)
Definition: marshal.c:32
VALUE rb_ary_push(VALUE ary, VALUE item)
Definition: array.c:822
#define TYPE_SYMLINK
Definition: marshal.c:77
st_table * st_init_strcasetable(void)
Definition: st.c:296
int rb_usascii_encindex(void)
Definition: encoding.c:1192
#define TYPE(x)
static ID s_load_data
Definition: marshal.c:83
VALUE rb_ary_tmp_new(long capa)
Definition: array.c:465
static int r_byte(struct load_arg *arg)
Definition: marshal.c:1073
#define RSTRING_PTR(str)
#define CLASS_OF(v)
#define ROBJECT_IVPTR(o)
#define T_ARRAY
int rb_reg_options(VALUE)
Definition: re.c:3083
VALUE dest
Definition: marshal.c:137
#define xfree
VALUE rb_funcall(VALUE, ID, int,...)
Calls a method.
Definition: vm_eval.c:773
#define Qnil
static void w_short(int x, struct dump_arg *arg)
Definition: marshal.c:251
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:1780
#define T_HASH
VALUE rb_ary_clear(VALUE ary)
Definition: array.c:3220
static ID s_getbyte
Definition: marshal.c:84
VALUE rb_class_name(VALUE)
Definition: variable.c:383
void rb_mark_set(struct st_table *)
Definition: gc.c:2389
char ruby_check_marshal_viral_flags[MARSHAL_INFECTION==(int) MARSHAL_INFECTION?1:-1]
Definition: marshal.c:134
static void w_uclass(VALUE obj, VALUE super, struct dump_arg *arg)
Definition: marshal.c:501
#define TYPE_UCLASS
Definition: marshal.c:59
#define SHORTDN(x)
Definition: marshal.c:29
#define FL_UNTRUSTED
#define rb_str_new2
static void w_ivar(VALUE obj, st_table *tbl, struct dump_call_arg *arg)
Definition: marshal.c:565
ID rb_id_encoding(void)
Definition: encoding.c:683
#define TYPE_USERDEF
Definition: marshal.c:62
void rb_big_resize(VALUE big, long len)
Definition: bignum.c:160
VALUE rb_path_to_class(VALUE)
Definition: variable.c:331
#define ID2SYM(x)
static VALUE path2class(VALUE path)
Definition: marshal.c:1385
#define T_FLOAT
VALUE rb_class_path(VALUE)
Definition: variable.c:261
#define T_OBJECT
static VALUE r_bytes1_buffered(long len, struct load_arg *arg)
Definition: marshal.c:1163
#define RHASH_SIZE(h)
static void w_class(char type, VALUE obj, struct dump_arg *arg, int check)
Definition: marshal.c:484
#define LONG2NUM(x)
static int hash_each(VALUE key, VALUE value, struct dump_call_arg *arg)
Definition: marshal.c:453
static VALUE obj_alloc_by_path(VALUE path, struct load_arg *arg)
Definition: marshal.c:1426
void rb_hash_foreach(VALUE, int(*)(ANYARGS), VALUE)
Definition: hash.c:200
RUBY_EXTERN VALUE rb_cRegexp
Definition: ripper.y:1454
static void w_nbyte(const char *s, long n, struct dump_arg *arg)
Definition: marshal.c:224
#define TYPE_IVAR
Definition: marshal.c:79
st_table * symbols
Definition: marshal.c:983
#define sym(x)
Definition: date_core.c:3715
#define TYPE_FALSE
Definition: marshal.c:55
#define TYPE_HASH_DEF
Definition: marshal.c:70
#define RBIGNUM_LEN(b)
Win32OLEIDispatch * p
Definition: win32ole.c:786
st_table * compat_tbl
Definition: marshal.c:986
#define MEMZERO(p, type, n)
static VALUE r_string(struct load_arg *arg)
Definition: marshal.c:1316
void st_foreach_safe(struct st_table *, int(*)(ANYARGS), st_data_t)
Definition: hash.c:133
VALUE rb_reg_new_str(VALUE, int)
Definition: re.c:2487
unsigned long st_data_t
Definition: ripper.y:35
#define strtod(s, e)
Definition: util.h:76
int st_delete(st_table *, st_data_t *, st_data_t *)
#define RSTRUCT_PTR(st)
#define prohibit_ivar(type, str)
Definition: marshal.c:1442
#define TYPE_FLOAT
Definition: marshal.c:64
static ID s_read
Definition: marshal.c:84
static void check_dump_arg(struct dump_arg *arg, ID sym)
Definition: marshal.c:152
#define TYPE_CLASS
Definition: marshal.c:73
st_table * data
Definition: marshal.c:984
static void check_load_arg(struct load_arg *arg, ID sym)
Definition: marshal.c:991
#define FIXNUM_P(f)
#define rb_intern_str(string)
Definition: generator.h:17
#define TYPE_STRING
Definition: marshal.c:66
#define RARRAY_LEN(a)
long buflen
Definition: marshal.c:980
#define ROBJECT_NUMIV(o)
#define val
static VALUE path2module(VALUE path)
Definition: marshal.c:1396
VALUE rb_eRuntimeError
Definition: error.c:510
#define Qtrue
#define TYPE_REGEXP
Definition: marshal.c:67
return c
Definition: ripper.y:7591
#define SINGLETON_DUMP_UNABLE_P(klass)
Definition: marshal.c:460
RUBY_EXTERN VALUE rb_cHash
Definition: ripper.y:1440
#define TYPE_BIGNUM
Definition: marshal.c:65
#define StringValueCStr(v)
unsigned long ID
Definition: ripper.y:105
#define TYPE_MODULE_OLD
Definition: marshal.c:72
static ID s_call
Definition: marshal.c:83
void rb_gc_mark(VALUE)
Definition: gc.c:2600
#define RCLASS_SUPER(c)
VALUE oldclass
Definition: marshal.c:88
void rb_define_const(VALUE, const char *, VALUE)
Definition: variable.c:2202
#define RSTRING_LEN(str)
#define FIX2INT(x)
#define INT2FIX(i)
#define Qfalse
static ID r_symlink(struct load_arg *arg)
Definition: marshal.c:1253
#define FL_USER2
#define FIX2LONG(x)
#define T_STRING
#define xmalloc
static VALUE r_entry0(VALUE v, st_index_t num, struct load_arg *arg)
Definition: marshal.c:1322
static VALUE r_object0(struct load_arg *arg, int *ivp, VALUE extmod)
Definition: marshal.c:1450
int argc
Definition: ruby.c:130
#define NIL_P(v)
#define TYPE_SYMBOL
Definition: marshal.c:76
static st_index_t r_prepare(struct load_arg *arg)
Definition: marshal.c:1043
VALUE rb_enc_associate_index(VALUE obj, int idx)
Definition: encoding.c:748
VALUE str
Definition: marshal.c:137
arg
Definition: ripper.y:1316
#define TYPE_NIL
Definition: marshal.c:53
#define DBL2NUM(dbl)
VALUE rb_check_funcall(VALUE, ID, int, VALUE *)
Definition: vm_eval.c:408
int link(const char *, const char *)
Definition: win32.c:4235
static size_t memsize_load_arg(const void *ptr)
Definition: marshal.c:1019
#define RBIGNUM_DIGITS(b)
static void mark_dump_arg(void *ptr)
Definition: marshal.c:163
VALUE rb_str_buf_cat(VALUE, const char *, long)
Definition: string.c:1948
#define ruby_verbose
VALUE rb_struct_s_members(VALUE)
Definition: struct.c:39
static void too_short(void)
Definition: marshal.c:1037
static void w_unique(VALUE s, struct dump_arg *arg)
Definition: marshal.c:444
VALUE rb_hash_aset(VALUE, VALUE, VALUE)
#define TYPE_USRMARSHAL
Definition: marshal.c:63
VALUE rb_str_resize(VALUE, long)
Definition: string.c:1854
#define RTEST(v)
void rb_define_module_function(VALUE module, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a module function for module.
Definition: class.c:1512
int st_foreach(st_table *, int(*)(ANYARGS), st_data_t)
Definition: st.c:1000
#define RREGEXP_SRC_PTR(r)
#define RBIGNUM_SET_SIGN(b, sign)
#define TYPE_FIXNUM
Definition: marshal.c:56
#define TRUE
Definition: nkf.h:175
#define StringValue(v)
#define TYPE_STRUCT
Definition: marshal.c:71
#define MARSHAL_MAJOR
Definition: marshal.c:50
#define T_REGEXP
#define const
Definition: strftime.c:102
static VALUE r_bytes1(long len, struct load_arg *arg)
Definition: marshal.c:1148
void rb_gc_register_mark_object(VALUE)
Definition: gc.c:2982
VALUE rb_class_inherited_p(VALUE, VALUE)
Definition: object.c:1480
#define TYPE_TRUE
Definition: marshal.c:54
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Definition: class.c:1570
st_table * compat_tbl
Definition: marshal.c:140
#define TYPE_DATA
Definition: marshal.c:61
static st_table * compat_allocator_tbl
Definition: marshal.c:93
VALUE(* loader)(VALUE, VALUE)
Definition: marshal.c:90
unsigned char buf[MIME_BUF_SIZE]
Definition: nkf.c:4308
#define RARRAY_PTR(a)
static ID r_symbol(struct load_arg *arg)
Definition: marshal.c:1288
static void r_ivar(VALUE obj, int *has_encoding, struct load_arg *arg)
Definition: marshal.c:1363
#define rb_intern(str)
#define RB_GC_GUARD(v)
int type
Definition: tcltklib.c:111
static int options(unsigned char *cp)
Definition: nkf.c:6355
#define FL_TAINT
#define TYPE_ARRAY
Definition: marshal.c:68
#define RHASH_IFNONE(h)
VALUE rb_str_buf_new(long)
Definition: string.c:777
static ID s_dump
Definition: marshal.c:82
static void clear_dump_arg(struct dump_arg *arg)
Definition: marshal.c:866
void rb_extend_object(VALUE obj, VALUE module)
Definition: eval.c:1234
int rb_utf8_encindex(void)
Definition: encoding.c:1177
#define has_ivars(obj, ivtbl)
static void free_load_arg(void *ptr)
Definition: marshal.c:1012
#define SIGN_EXTEND_CHAR(c)
Definition: marshal.c:1111
#define TYPE_MODULE
Definition: marshal.c:74
#define INFINITY
Definition: missing.h:138
#define BDIGIT
Definition: ripper.y:184
static ID s_alloc
Definition: marshal.c:83
static int mark_marshal_compat_i(st_data_t key, st_data_t value)
Definition: marshal.c:97
RUBY_EXTERN int isinf(double)
Definition: isinf.c:56
#define isnan(x)
Definition: win32.h:327
static void mark_load_arg(void *ptr)
Definition: marshal.c:1002
static void shift(struct cparse_params *v, long act, VALUE tok, VALUE val)
Definition: cparse.c:662
RUBY_EXTERN VALUE rb_cString
Definition: ripper.y:1456
st_table * symbols
Definition: marshal.c:138
static int id2encidx(ID id, VALUE val)
Definition: marshal.c:1238
#define w_cstr(s, arg)
Definition: marshal.c:248
static VALUE r_bytes0(long len, struct load_arg *arg)
Definition: marshal.c:1212
#define T_BIGNUM
#define MARSHAL_INFECTION
Definition: marshal.c:133
#define MEMCPY(p1, p2, type, n)
st_table * encodings
Definition: marshal.c:141
static ID s_mload
Definition: marshal.c:82
static ID s_load
Definition: marshal.c:82
static ID s_binmode
Definition: marshal.c:84
NORETURN(static inline void io_needed(void))
const char * rb_class2name(VALUE)
Definition: variable.c:389
VALUE rb_ivar_set(VALUE, ID, VALUE)
Definition: variable.c:1128
static void w_bytes(const char *s, long n, struct dump_arg *arg)
Definition: marshal.c:242
VALUE(* dumper)(VALUE)
Definition: marshal.c:89
#define NEWOBJ_OF(obj, type, klass, flags)
VALUE rb_str_cat(VALUE, const char *, long)
Definition: string.c:1964
#define ENC_CODERANGE_7BIT
rb_encoding * rb_enc_get(VALUE obj)
Definition: encoding.c:772
#define MARSHAL_MINOR
Definition: marshal.c:51
static ID s_write
Definition: marshal.c:84
int size
Definition: encoding.c:52
static void clear_load_arg(struct load_arg *arg)
Definition: marshal.c:1874
VALUE rb_cBignum
Definition: bignum.c:28
#define SYMBOL_P(x)
#define FL_SINGLETON
#define Qundef
#define T_CLASS
#define TYPE_HASH
Definition: marshal.c:69
#define STRINGIZE(expr)
Definition: ripper.y:169
void Init_marshal(void)
Definition: marshal.c:2077
int rb_obj_respond_to(VALUE, ID, int)
Definition: vm_method.c:1544
VALUE rb_struct_initialize(VALUE, VALUE)
Definition: struct.c:407
#define TypedData_Make_Struct(klass, type, data_type, sval)
st_data_t st_index_t
Definition: ripper.y:63
int infection
Definition: marshal.c:987
static void w_symbol(ID id, struct dump_arg *arg)
Definition: marshal.c:408
#define LONG2FIX(i)
uint8_t key[16]
Definition: random.c:1370
VALUE rb_big_norm(VALUE x)
Definition: bignum.c:282
#define RBASIC(obj)
static VALUE compat_allocator_tbl_wrapper
Definition: marshal.c:94
#define INT2NUM(x)
VALUE src
Definition: marshal.c:978
v
Definition: win32ole.c:798
rb_alloc_func_t rb_get_alloc_func(VALUE)
Definition: vm_method.c:498
long offset
Definition: marshal.c:982
static VALUE append_extmod(VALUE obj, VALUE extmod)
Definition: marshal.c:1432
int rb_respond_to(VALUE, ID)
Definition: vm_method.c:1583
static VALUE r_unique(struct load_arg *arg)
Definition: marshal.c:1310
static ID r_symreal(struct load_arg *arg, int ivar)
Definition: marshal.c:1265
int st_insert(st_table *, st_data_t, st_data_t)
static void free_dump_arg(void *ptr)
Definition: marshal.c:174
VALUE rb_cArray
Definition: array.c:29
VALUE rb_int2big(SIGNED_VALUE n)
Definition: bignum.c:309
VALUE rb_ary_new2(long capa)
Definition: array.c:417
static VALUE r_object(struct load_arg *arg)
Definition: marshal.c:1868
VALUE rb_str_new(const char *, long)
Definition: string.c:425
static void mark_marshal_compat_t(void *tbl)
Definition: marshal.c:106
#define T_MODULE
long readable
Definition: marshal.c:981
void rb_marshal_define_compat(VALUE newclass, VALUE oldclass, VALUE(*dumper)(VALUE), VALUE(*loader)(VALUE, VALUE))
Definition: marshal.c:113
st_table * data
Definition: marshal.c:139
static struct StringIO * readable(VALUE strio)
Definition: stringio.c:122
const char * name
Definition: nkf.c:208
#define PRIdVALUE
#define rb_enc_asciicompat(enc)
static VALUE obj_alloc_by_klass(VALUE klass, struct load_arg *arg, VALUE *oldclass)
Definition: marshal.c:1407
#define NUM2INT(x)
static void io_needed(void)
Definition: marshal.c:883
VALUE rb_hash_new(void)
Definition: hash.c:234
VALUE rb_obj_alloc(VALUE)
Definition: object.c:1721
const char * rb_id2name(ID id)
Definition: ripper.c:17058
#define BUILTIN_TYPE(x)
VALUE rb_class_real(VALUE)
Definition: object.c:171
#define PRIsVALUE
void rb_mark_hash(struct st_table *)
Definition: gc.c:2413
static const rb_data_type_t load_arg_data
Definition: marshal.c:1024
VALUE rb_funcall2(VALUE, ID, int, const VALUE *)
Calls a method.
Definition: vm_eval.c:804
#define NUM2CHR(x)
int rb_enc_find_index(const char *name)
Definition: encoding.c:635
int major
Definition: tcltklib.c:109
#define Data_Wrap_Struct(klass, mark, free, sval)
#define RREGEXP_SRC_LEN(r)
#define snprintf
VALUE rb_define_module(const char *name)
Definition: class.c:617
void rb_ivar_foreach(VALUE, int(*)(ANYARGS), st_data_t)
Definition: variable.c:1271
RUBY_EXTERN VALUE rb_cData
Definition: ripper.y:1433
VALUE obj
Definition: marshal.c:146
static void w_extended(VALUE klass, struct dump_arg *arg, int check)
Definition: marshal.c:465
#define NULL
Definition: _sdbm.c:103
#define T_DATA
static void w_byte(char c, struct dump_arg *arg)
Definition: marshal.c:236
static void w_float(double d, struct dump_arg *arg)
Definition: marshal.c:355
VALUE rb_marshal_load(VALUE port)
Definition: marshal.c:2123
VALUE rb_check_string_type(VALUE)
Definition: string.c:1509
#define r_entry(v, arg)
Definition: marshal.c:1029
static ID s_dump_data
Definition: marshal.c:83
static ID s_mdump
Definition: marshal.c:82
int rb_enc_str_coderange(VALUE)
Definition: string.c:327
st_index_t num_entries
Definition: ripper.y:93
void rb_warn(const char *fmt,...)
Definition: error.c:216
#define SYM2ID(x)
VALUE rb_eArgError
Definition: error.c:512
VALUE newclass
Definition: marshal.c:87
void st_free_table(st_table *)
Definition: st.c:334
char ** argv
Definition: ruby.c:131
static VALUE r_leave(VALUE v, struct load_arg *arg)
Definition: marshal.c:1341
VALUE rb_io_write(VALUE, VALUE)
Definition: io.c:1415
#define TYPE_EXTENDED
Definition: marshal.c:58
char * ruby_dtoa(double d_, int mode, int ndigits, int *decpt, int *sign, char **rve)
Definition: util.c:3093
rb_encoding * rb_enc_from_index(int index)
Definition: encoding.c:548
static void w_encoding(VALUE obj, long num, struct dump_call_arg *arg)
Definition: marshal.c:528
void rb_eof_error(void)
Definition: io.c:581
void rb_str_set_len(VALUE, long)
Definition: string.c:1838