diff --git a/src/encode.c b/src/encode.c index 938e5d58fb0cc750193dfb663713616585e3ff20..9a492bc5026c44d73d9e9c0732cf8d135d2ff016 100644 --- a/src/encode.c +++ b/src/encode.c @@ -25,7 +25,7 @@ #include "version.h" #include "bignum.h" -RCSID("$Id: encode.c,v 1.106 2001/07/03 08:04:59 hubbe Exp $"); +RCSID("$Id: encode.c,v 1.107 2001/07/03 15:04:51 grubba Exp $"); /* #define ENCODE_DEBUG */ @@ -769,7 +769,7 @@ static void encode_value2(struct svalue *val, struct encode_data *data) return; } } - Pike_error("Failed to encode function.\n"); + Pike_error("Encoding of efuns is not supported yet.\n"); } code_entry(type_to_tag(val->type), 0,data); @@ -850,7 +850,7 @@ static void encode_value2(struct svalue *val, struct encode_data *data) pop_stack(); #define FOO(X,Y,Z) \ - code_number( p->num_##Z, data); + code_number( p->PIKE_CONCAT(num_,Z), data); #include "program_areas.h" adddata2(p->program, p->num_program); @@ -894,6 +894,7 @@ static void encode_value2(struct svalue *val, struct encode_data *data) }else if(p->inherits[d].prog){ ref_push_program(p->inherits[d].prog); }else{ + Pike_error("Failed to encode inherit #%d\n", d); push_int(0); } encode_value2(Pike_sp-1,data); @@ -914,7 +915,13 @@ static void encode_value2(struct svalue *val, struct encode_data *data) code_number(p->identifiers[d].identifier_flags,data); code_number(p->identifiers[d].run_time_type,data); code_number(p->identifiers[d].opt_flags,data); - code_number(p->identifiers[d].func.offset,data); + if (!(p->identifiers[d].identifier_flags & IDENTIFIER_C_FUNCTION)) { + code_number(p->identifiers[d].func.offset,data); + } else { + Pike_error("Cannot encode functions implemented in C " + "(identifier='%s').\n", + p->identifiers[d].name->str); + } } for(d=0;d<p->num_constants;d++) @@ -1068,6 +1075,8 @@ struct decode_data struct svalue counter; struct object *codec; int pickyness; + struct pike_string *raw; + struct decode_data *next; }; static void decode_value2(struct decode_data *data); @@ -1829,7 +1838,10 @@ static void decode_value2(struct decode_data *data) default: Pike_error("Program decode failed!\n"); } - if(p->parent) add_ref(p->parent); + if(p->parent) { + add_ref(p->parent); + p->parent_program_id = p->parent->id; + } pop_stack(); debug_malloc_touch(p); @@ -2004,7 +2016,14 @@ static void decode_value2(struct decode_data *data) decode_number(p->identifiers[d].identifier_flags,data); decode_number(p->identifiers[d].run_time_type,data); decode_number(p->identifiers[d].opt_flags,data); - decode_number(p->identifiers[d].func.offset,data); + if (!(p->identifiers[d].identifier_flags & IDENTIFIER_C_FUNCTION)) + { + decode_number(p->identifiers[d].func.offset,data); + } else { + Pike_error("Cannot decode functions implemented in C " + "(identifier='%s').\n", + p->identifiers[d].name->str); + } } @@ -2151,6 +2170,8 @@ static void decode_value2(struct decode_data *data) } +static struct decode_data *current_decode = NULL; + static void free_decode_data(struct decode_data *data) { free_mapping(data->decoded); @@ -2160,6 +2181,22 @@ static void free_decode_data(struct decode_data *data) data->unfinished_programs=tmp->next; free((char *)tmp); } + if (current_decode == data) { + current_decode = data->next; + } else { + struct decode_data *d; + for (d = current_decode; d; d=d->next) { + if (d->next == data) { + d->next = d->next->next; + break; + } + } +#ifdef PIKE_DEBUG + if (!d) { + fatal("Decode data fell off the stack!\n"); + } +#endif /* PIKE_DEBUG */ + } } static INT32 my_decode(struct pike_string *tmp, @@ -2167,6 +2204,27 @@ static INT32 my_decode(struct pike_string *tmp, { ONERROR err; struct decode_data d, *data; + + /* Attempt to avoid infinite recursion on circular structures. */ + for (data = current_decode; data; data=data->next) { + if (data->raw == tmp) { + struct svalue *res; + struct svalue val = { + T_INT, NUMBER_NUMBER, +#ifdef HAVE_UNION_INIT + {0}, /* Only to avoid warnings. */ +#endif /* HAVE_UNION_INIT */ + }; + val.u.integer = 0; + if ((res = low_mapping_lookup(data->decoded, &val))) { + push_svalue(res); + return 1; + } + /* Possible recursion detected. */ + /* return 0; */ + } + } + data=&d; data->counter.type=T_INT; data->counter.u.integer=COUNTER_START; @@ -2176,6 +2234,8 @@ static INT32 my_decode(struct pike_string *tmp, data->codec=codec; data->pickyness=0; data->unfinished_programs=0; + data->raw = tmp; + data->next = current_decode; if (tmp->size_shift) return 0; if(data->len < 5) return 0; @@ -2187,14 +2247,16 @@ static INT32 my_decode(struct pike_string *tmp, data->decoded=allocate_mapping(128); + current_decode = data; + SET_ONERROR(err, free_decode_data, data); decode_value2(data); - UNSET_ONERROR(err); + #ifdef PIKE_DEBUG if(data->unfinished_programs) fatal("We have unfinished programs left in decode()! We may need a double loop!\n"); #endif - free_mapping(data->decoded); + CALL_AND_UNSET_ONERROR(err); return 1; }