diff options
author | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2001-05-30 09:12:34 +0000 |
---|---|---|
committer | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2001-05-30 09:12:34 +0000 |
commit | abfaac7a6cbdbfad9e7c05bc5ebcb4df57906fcb (patch) | |
tree | 4d406191345ff9f25e3a3c9ce5f85a3a13e6f7d1 /string.c | |
parent | 4cd1cd7201757185e63a5a33181932a6670887ad (diff) |
* ruby.c (proc_options): unexpected SecurityError happens when -T4.
* regex.c (re_compile_pattern): * \1 .. \9 should be
backreferences always.
* regex.c (re_match): backreferences corresponding to
unclosed/unmatched parentheses should fail always.
* string.c (rb_str_cat): use rb_str_buf_cat() if possible. [new]
* string.c (rb_str_append): ditto.
* string.c (rb_str_buf_cat): remove unnecessary check (type,
taint, modify) to gain performance.
* string.c (rb_str_buf_append): ditto.
* string.c (rb_str_buf_new): buffering string function. [new]
* string.c (rb_str_buf_append): ditto.
* string.c (rb_str_buf_cat): ditto.
* time.c (make_time_t): local time adjustment revised.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@1476 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'string.c')
-rw-r--r-- | string.c | 186 |
1 files changed, 157 insertions, 29 deletions
@@ -28,6 +28,7 @@ VALUE rb_cString; #define STR_NO_ORIG FL_USER2 +#define STR_ASSOC FL_USER3 VALUE rb_fs; @@ -132,6 +133,40 @@ rb_str_new4(orig) } } +#define STR_BUF_MIN_SIZE 128 + +VALUE +rb_str_buf_new(capa) + long capa; +{ + NEWOBJ(str, struct RString); + OBJSETUP(str, rb_cString, T_STRING); + + FL_SET(str, STR_NO_ORIG); + if (capa < STR_BUF_MIN_SIZE) + capa = STR_BUF_MIN_SIZE; + str->ptr = 0; + str->len = 0; + str->orig = LONG2FIX(capa); + str->ptr = ALLOC_N(char, capa+1); + str->ptr[0] = '\0'; + + return (VALUE)str; +} + +VALUE +rb_str_buf_new2(ptr) + const char *ptr; +{ + VALUE str; + long len = strlen(ptr); + + str = rb_str_buf_new(len + STR_BUF_MIN_SIZE); + rb_str_cat(str, ptr, len); + + return str; +} + VALUE rb_str_to_str(str) VALUE str; @@ -176,7 +211,7 @@ rb_str_associate(str, add) rb_str_modify(str); } RSTRING(str)->orig = rb_ary_new(); - FL_SET(str, STR_NO_ORIG); + FL_SET(str, STR_NO_ORIG|STR_ASSOC); } rb_ary_push(RSTRING(str)->orig, add); } @@ -185,7 +220,7 @@ VALUE rb_str_associated(str) VALUE str; { - if (!FL_TEST(str, STR_NO_ORIG)) { + if (!FL_TEST(str, STR_NO_ORIG|STR_ASSOC)) { return Qfalse; } return RSTRING(str)->orig; @@ -443,27 +478,69 @@ rb_str_resize(str, len) } VALUE +rb_str_buf_cat(str, ptr, len) + VALUE str; + const char *ptr; + long len; +{ + long i, capa, total; + + if (RSTRING(str)->orig == 0) { + capa = RSTRING(str)->len; + FL_SET(str, STR_NO_ORIG); + } + else { + capa = FIX2LONG(RSTRING(str)->orig); + } + + total = RSTRING(str)->len+len; + if (capa <= total) { + while (total > capa) { + capa = (capa + 1) * 2; + } + REALLOC_N(RSTRING(str)->ptr, char, capa+1); + RSTRING(str)->orig = LONG2FIX(capa); + } + memcpy(RSTRING(str)->ptr + RSTRING(str)->len, ptr, len); + RSTRING(str)->len = total; + RSTRING(str)->ptr[total] = '\0'; /* sentinel */ + + return str; +} + +VALUE +rb_str_buf_cat2(str, ptr) + VALUE str; + const char *ptr; +{ + return rb_str_buf_cat(str, ptr, strlen(ptr)); +} + +VALUE rb_str_cat(str, ptr, len) VALUE str; const char *ptr; long len; { - if (len > 0) { - int poffset = -1; + long i, capa; - rb_str_modify(str); - if (RSTRING(str)->ptr <= ptr && - ptr < RSTRING(str)->ptr + RSTRING(str)->len) { - poffset = ptr - RSTRING(str)->ptr; + rb_str_modify(str); + if (len > 0) { + if (RSTRING(str)->orig == 0 || + (FL_TEST(str, STR_NO_ORIG) && !FL_TEST(str, STR_ASSOC))) { + return rb_str_buf_cat(str, ptr, len); } - REALLOC_N(RSTRING(str)->ptr, char, RSTRING(str)->len + len + 1); + REALLOC_N(RSTRING(str)->ptr, char, RSTRING(str)->len+1); if (ptr) { - if (poffset >= 0) ptr = RSTRING(str)->ptr + poffset; memcpy(RSTRING(str)->ptr + RSTRING(str)->len, ptr, len); } + else { + MEMZERO(RSTRING(str)->ptr + RSTRING(str)->len, char, len); + } RSTRING(str)->len += len; RSTRING(str)->ptr[RSTRING(str)->len] = '\0'; /* sentinel */ } + return str; } @@ -476,14 +553,61 @@ rb_str_cat2(str, ptr) } VALUE -rb_str_append(str1, str2) - VALUE str1, str2; +rb_str_buf_append(str, str2) + VALUE str, str2; { + long i, capa, len; + + if (RSTRING(str)->orig == 0) { + capa = RSTRING(str)->len; + FL_SET(str, STR_NO_ORIG); + } + else { + capa = FIX2LONG(RSTRING(str)->orig); + } + + len = RSTRING(str)->len+RSTRING(str2)->len; + if (capa <= len) { + while (len > capa) { + capa = (capa + 1) * 2; + } + REALLOC_N(RSTRING(str)->ptr, char, capa+1); + RSTRING(str)->orig = LONG2FIX(capa); + } + memcpy(RSTRING(str)->ptr + RSTRING(str)->len, + RSTRING(str2)->ptr, RSTRING(str2)->len); + RSTRING(str)->len += RSTRING(str2)->len; + RSTRING(str)->ptr[RSTRING(str)->len] = '\0'; /* sentinel */ + + return str; +} + +VALUE +rb_str_append(str, str2) + VALUE str, str2; +{ + long i, capa, len; + StringValue(str2); - str1 = rb_str_cat(str1, RSTRING(str2)->ptr, RSTRING(str2)->len); - OBJ_INFECT(str1, str2); + rb_str_modify(str); + len = RSTRING(str)->len+RSTRING(str2)->len; + if (len > 0) { + if (RSTRING(str)->orig == 0 || + (FL_TEST(str, STR_NO_ORIG) && !FL_TEST(str, STR_ASSOC))) { + rb_str_buf_append(str, str2); + OBJ_INFECT(str, str2); + + return str; + } + REALLOC_N(RSTRING(str)->ptr, char, len+1); + memcpy(RSTRING(str)->ptr + RSTRING(str)->len, + RSTRING(str2)->ptr, RSTRING(str2)->len); + RSTRING(str)->len += RSTRING(str2)->len; + RSTRING(str)->ptr[RSTRING(str)->len] = '\0'; /* sentinel */ + } + OBJ_INFECT(str, str2); - return str1; + return str; } VALUE @@ -998,6 +1122,7 @@ rb_str_update(str, beg, len, val) } RSTRING(str)->len += RSTRING(val)->len - len; RSTRING(str)->ptr[RSTRING(str)->len] = '\0'; + OBJ_INFECT(str, val); } static VALUE rb_str_sub_bang _((int, VALUE*, VALUE)); @@ -1518,7 +1643,7 @@ rb_str_inspect(str) VALUE str; { char *p, *pend; - VALUE result = rb_str_new2("\""); + VALUE result = rb_str_buf_new2("\""); char s[5]; p = RSTRING(str)->ptr; pend = p + RSTRING(str)->len; @@ -1526,51 +1651,51 @@ rb_str_inspect(str) char c = *p++; if (ismbchar(c) && p < pend) { int len = mbclen(c); - rb_str_cat(result, p - 1, len); + rb_str_buf_cat(result, p - 1, len); p += len - 1; } else if (c == '"'|| c == '\\') { s[0] = '\\'; s[1] = c; - rb_str_cat(result, s, 2); + rb_str_buf_cat(result, s, 2); } else if (ISPRINT(c)) { s[0] = c; - rb_str_cat(result, s, 1); + rb_str_buf_cat(result, s, 1); } else if (c == '\n') { s[0] = '\\'; s[1] = 'n'; - rb_str_cat(result, s, 2); + rb_str_buf_cat(result, s, 2); } else if (c == '\r') { s[0] = '\\'; s[1] = 'r'; - rb_str_cat(result, s, 2); + rb_str_buf_cat(result, s, 2); } else if (c == '\t') { s[0] = '\\'; s[1] = 't'; - rb_str_cat(result, s, 2); + rb_str_buf_cat(result, s, 2); } else if (c == '\f') { s[0] = '\\'; s[1] = 'f'; - rb_str_cat(result, s, 2); + rb_str_buf_cat(result, s, 2); } else if (c == '\013') { s[0] = '\\'; s[1] = 'v'; - rb_str_cat(result, s, 2); + rb_str_buf_cat(result, s, 2); } else if (c == '\007') { s[0] = '\\'; s[1] = 'a'; - rb_str_cat(result, s, 2); + rb_str_buf_cat(result, s, 2); } else if (c == 033) { s[0] = '\\'; s[1] = 'e'; - rb_str_cat(result, s, 2); + rb_str_buf_cat(result, s, 2); } else { sprintf(s, "\\%03o", c & 0377); - rb_str_cat2(result, s); + rb_str_buf_cat2(result, s); } } - rb_str_cat2(result, "\""); + rb_str_buf_cat2(result, "\""); OBJ_INFECT(result, str); return result; @@ -2661,7 +2786,7 @@ rb_str_crypt(str, salt) StringValue(salt); if (RSTRING(salt)->len < 2) rb_raise(rb_eArgError, "salt too short(need >=2 bytes)"); - return rb_str_new2(crypt(RSTRING(str)->ptr, RSTRING(salt)->ptr)); + return rb_tainted_str_new2(crypt(RSTRING(str)->ptr, RSTRING(salt)->ptr)); } static VALUE @@ -2738,6 +2863,7 @@ rb_str_ljust(str, w) while (p < pend) { *p++ = ' '; } + OBJ_INFECT(res, str); return res; } @@ -2757,6 +2883,7 @@ rb_str_rjust(str, w) *p++ = ' '; } memcpy(pend, RSTRING(str)->ptr, RSTRING(str)->len); + OBJ_INFECT(res, str); return res; } @@ -2782,6 +2909,7 @@ rb_str_center(str, w) while (p < pend) { *p++ = ' '; } + OBJ_INFECT(res, str); return res; } |