diff --git a/src/builtin_functions.c b/src/builtin_functions.c index 00b66922a68374f49c025c559cf987f233275e83..b7d893ee28d488ef853f42b1dd538902581d4886 100644 --- a/src/builtin_functions.c +++ b/src/builtin_functions.c @@ -706,6 +706,7 @@ PMOD_EXPORT void f_lower_case(INT32 args) ret = end_shared_string(ret); ret->flags |= STRING_IS_LOWERCASE; + ret->flags |= orig->flags & STRING_CLEAR_ON_EXIT; pop_n_elems(args); push_string(ret); } @@ -813,6 +814,7 @@ PMOD_EXPORT void f_upper_case(INT32 args) pop_n_elems(args); ret = end_shared_string(ret); ret->flags |= STRING_IS_UPPERCASE; + ret->flags |= orig->flags & STRING_CLEAR_ON_EXIT; push_string(ret); } @@ -1779,6 +1781,7 @@ PMOD_EXPORT void f_string_to_unicode(INT32 args) #endif } pop_n_elems(args); + out->flags |= in->flags & STRING_CLEAR_ON_EXIT; push_string(out); } @@ -1938,6 +1941,7 @@ PMOD_EXPORT void f_unicode_to_string(INT32 args) } out = end_shared_string(out); pop_n_elems(args); + out->flags |= in->flags & STRING_CLEAR_ON_EXIT; push_string(out); } @@ -2082,6 +2086,7 @@ PMOD_EXPORT void f_string_to_utf8(INT32 args) #endif /* PIKE_DEBUG */ out = end_shared_string(out); pop_n_elems(args); + out->flags |= in->flags & STRING_CLEAR_ON_EXIT; push_string(out); } @@ -2435,6 +2440,7 @@ PMOD_EXPORT void f_utf8_to_string(INT32 args) check_string (out); #endif pop_n_elems(args); + out->flags |= in->flags & STRING_CLEAR_ON_EXIT; push_string(out); } diff --git a/src/operators.c b/src/operators.c index 2dcbc8019b64562d422ce15c0d25569fae3911ba..43808e9858078c2c03134ce8b3d929d2cfa85c85 100644 --- a/src/operators.c +++ b/src/operators.c @@ -2741,28 +2741,31 @@ PMOD_EXPORT void o_and(void) #define STRING_BITOP(OP,STROP) \ case T_STRING: \ { \ - struct pike_string *s; \ + struct pike_string *s, *a, *b; \ ptrdiff_t len, i; \ - \ - len = sp[-2].u.string->len; \ - if (len != sp[-1].u.string->len) \ + a = sp[-2].u.string; \ + b = sp[-1].u.string; \ + len = a->len; \ + if (len != b->len) \ PIKE_ERROR("`" #OP, "Bitwise "STROP \ " on strings of different lengths.\n", sp, 2); \ - if(!sp[-2].u.string->size_shift && !sp[-1].u.string->size_shift) \ + if(!a->size_shift && !b->size_shift) \ { \ s = begin_shared_string(len); \ for (i=0; i<len; i++) \ - s->str[i] = sp[-2].u.string->str[i] OP sp[-1].u.string->str[i]; \ + s->str[i] = a->str[i] OP b->str[i]; \ }else{ \ s = begin_wide_shared_string(len, \ - MAXIMUM(sp[-2].u.string->size_shift, \ - sp[-1].u.string->size_shift)); \ + MAXIMUM(a->size_shift, \ + b->size_shift)); \ for (i=0; i<len; i++) \ - low_set_index(s,i,index_shared_string(sp[-2].u.string,i) OP \ - index_shared_string(sp[-1].u.string,i)); \ + low_set_index(s,i,index_shared_string(a,i) OP \ + index_shared_string(b,i)); \ } \ + s = end_shared_string(s); \ + s->flags |= (a->flags | b->flags) & STRING_CLEAR_ON_EXIT; \ pop_n_elems(2); \ - push_string(end_shared_string(s)); \ + push_string(s); \ return; \ } diff --git a/src/stralloc.c b/src/stralloc.c index 5d97026659c5195b8499a0a212428080c1768cc0..91da8781859427c8bb0e81a103787fff7ad0a14e 100644 --- a/src/stralloc.c +++ b/src/stralloc.c @@ -1778,7 +1778,8 @@ struct pike_string *realloc_unlinked_string(struct pike_string *a, if(!r) { r=begin_wide_shared_string(size, a->size_shift); - r->flags |= a->flags & ~15; + /* we keep both content information and the clear flags */ + r->flags |= a->flags & (STRING_CONTENT_MASK|STRING_CLEAR_ON_EXIT); r->min = a->min; r->max = a->max; if (a->len <= size) { @@ -1806,7 +1807,8 @@ static struct pike_string *realloc_shared_string(struct pike_string *a, }else{ r=begin_wide_shared_string(size,a->size_shift); MEMCPY(r->str, a->str, a->len<<a->size_shift); - r->flags |= a->flags & ~15; + /* we keep both content information and the clear flags */ + r->flags |= a->flags & (STRING_CONTENT_MASK|STRING_CLEAR_ON_EXIT); r->min = a->min; r->max = a->max; free_string(a); @@ -1821,7 +1823,7 @@ struct pike_string *new_realloc_shared_string(struct pike_string *a, INT32 size, r=begin_wide_shared_string(size,shift); pike_string_cpy(MKPCHARP_STR(r),a); - r->flags |= (a->flags & ~15); + r->flags |= (a->flags & (STRING_CONTENT_MASK|STRING_CLEAR_ON_EXIT)); r->min = a->min; r->max = a->max; free_string(a); @@ -1994,7 +1996,7 @@ PMOD_EXPORT void set_flags_for_add( struct pike_string *ret, struct pike_string *b) { if( !b->len ) { - ret->flags |= aflags & ~15; + ret->flags |= aflags & (STRING_CONTENT_MASK|STRING_CLEAR_ON_EXIT); ret->min = amin; ret->max = amax; return; @@ -2010,6 +2012,7 @@ PMOD_EXPORT void set_flags_for_add( struct pike_string *ret, ret->flags &= ~(STRING_IS_LOWERCASE | STRING_IS_UPPERCASE); ret->flags |= (aflags & b->flags & (STRING_IS_LOWERCASE | STRING_IS_UPPERCASE)); + ret->flags |= (aflags | b->flags) & STRING_CLEAR_ON_EXIT; } PMOD_EXPORT void update_flags_for_add( struct pike_string *a, struct pike_string *b) @@ -2027,6 +2030,7 @@ PMOD_EXPORT void update_flags_for_add( struct pike_string *a, struct pike_string } a->flags &= ~(STRING_IS_LOWERCASE | STRING_IS_UPPERCASE) | b->flags; + a->flags |= b->flags & STRING_CLEAR_ON_EXIT; } /*** Add strings ***/ diff --git a/src/stralloc.h b/src/stralloc.h index 951d3f6c6dd61418f80dd30dc0308812e65cede1..2f90e6629fe1605a2804a06fe70d3bf0a1a596e4 100644 --- a/src/stralloc.h +++ b/src/stralloc.h @@ -62,6 +62,8 @@ struct string_builder #define STRING_IS_LOWERCASE 32 #define STRING_IS_UPPERCASE 64 +#define STRING_CONTENT_MASK (STRING_CONTENT_CHECKED|STRING_IS_LOWERCASE|STRING_IS_UPPERCASE) + #define CLEAR_STRING_CHECKED(X) do{(X)->flags &= 15;}while(0) /* Flags used by string_builder_append_integer() */