Tasuku SUENAGA
a****@razil*****
2007年 2月 25日 (日) 13:23:40 JST
末永です。 立松 聖久 wrote: > 立松です. > > Senna-dev 426あたりから引きずっている問題なんですが,以下のクエリを投げ > るとMySQLがクラッシュします. > snippet関数がなければ正常に動作します. > (後略) 上記の問題、調査いたします。 昔のバージョン相当に挙動を戻すパッチを作成しました。 このパッチをお試しください。 --- udf_snippet.c 2007-02-25 13:12:58.000000000 +0900 +++ udf_snippet_new.c 2007-02-25 13:18:29.000000000 +0900 @@ -73,8 +73,10 @@ { char *result; char *buffer; + char *source; size_t result_len; size_t buffer_len; + size_t source_len; char *keytags; sen_snip *snip; } snip_struct; @@ -87,42 +89,31 @@ sen_encoding enc; sen_snip *snip; sen_snip_mapping *map; - unsigned int i; + int i, keytagslength; long long slength, snumber, htmlflag; - const enum Item_result arg_types[] = - {STRING_RESULT, INT_RESULT, INT_RESULT, STRING_RESULT, INT_RESULT, STRING_RESULT, STRING_RESULT}; + char *keytags, *p, *q, *r; initid->ptr = NULL; - if (args->arg_count < 10) { - strcpy(message, "snippet function requires at least 10 parameters."); - return 1; - } - if ((args->arg_count % 3) != 1) { - strcpy(message, "number of parameters for snippet function is wrong."); + if (args->arg_count < 10 + || (args->arg_count % 3) != 1 + || args->arg_type[1] != INT_RESULT + || args->args[1] == NULL + || args->arg_type[2] != INT_RESULT + || args->args[2] == NULL + || args->arg_type[3] != STRING_RESULT + || args->args[3] == NULL + || args->lengths[3] > INT_MAX + || args->arg_type[4] != INT_RESULT + || args->args[4] == NULL + || args->arg_type[5] != STRING_RESULT + || args->args[5] == NULL + || args->lengths[5] > INT_MAX + || args->arg_type[6] != STRING_RESULT + || args->args[6] == NULL || args->lengths[6] > INT_MAX) { + strcpy(message, "invalid parameters"); return 1; } - for (i = 1; i <= 6; i++) { - if (!args->args[i]) { - sprintf(message, "parameter number %d is NULL!", i + 1); - return 1; - } - if (args->arg_type[i] != arg_types[i]) { - sprintf(message, "type of parameter number %d is wrong.", i + 1); - return 1; - } - if (arg_types[i] == STRING_RESULT && args->lengths[i] > INT_MAX) { - sprintf(message, "parameter number %d is too long!", i + 1); - return 1; - } - } - - for (i = 7; i < args->arg_count; i++) { - if (args->arg_type[i] != STRING_RESULT) { - sprintf(message, "parameter number %d is invalid!", i + 1); - return 1; - } - } slength = *((long long *) args->args[1]); snumber = *((long long *) args->args[2]); @@ -160,6 +151,44 @@ map = (sen_snip_mapping *) -1; } + keytagslength = 0; + for (i = 7; i < args->arg_count; i++) { + if (args->arg_type[i] != STRING_RESULT) { + sprintf(message, "invalid parameters(%dth)", i); + return 1; + } + if (args->lengths[i] >= INT_MAX) { + sprintf(message, "too long parameters(%dth)", i); + return 1; + } + keytagslength += args->lengths[i] + 1; + } + + if (!(keytags = (char *) malloc(sizeof(char) * keytagslength))) { + strcpy(message, "memory allocation error !(tags)"); + return 1; + } + + p = keytags; + snip = sen_snip_open(enc, SEN_SNIP_NORMALIZE, slength, snumber, "", 0, "", 0, map); + for (i = 7; i < args->arg_count; i += 3) { + + memcpy(p, args->args[i], args->lengths[i]); /* keyword copy */ + p[args->lengths[i]] = '\0'; + q = p + args->lengths[i] + 1; + memcpy(q, args->args[i + 1], args->lengths[i + 1]); /* opentag copy */ + q[args->lengths[i + 1]] = '\0'; + r = q + args->lengths[i + 1] + 1; + memcpy(r, args->args[i + 2], args->lengths[i + 2]); /* closetag copy */ + r[args->lengths[i + 2]] = '\0'; + + if (sen_snip_add_cond(snip, p, strlen(p), q, strlen(q), r, strlen(r)) != sen_success) { + strcpy(message, "cannot add conditions"); + return 1; + } + p = r + args->lengths[i + 2] + 1; + } + if (!(ptr = (snip_struct *) malloc(sizeof(snip_struct)))) { strcpy(message, "memory allocation error !(snip_struct)"); return 1; @@ -170,8 +199,8 @@ initid->max_length = 65535; /* represents blob */ initid->maybe_null = FALSE; - ptr->snip = sen_snip_open - (enc, SEN_SNIP_NORMALIZE, slength, snumber, "", 0, "", 0, map); + ptr->snip = snip; + ptr->keytags = keytags; ptr->result_len = (size_t) ((long double) slength * snumber * 1.3); if (ptr->result_len < MINIMUM_RESULT_LENGTH) { ptr->result_len = MINIMUM_RESULT_LENGTH; @@ -184,6 +213,8 @@ return 1; } + ptr->source_len = 0; + if (!(ptr->result = (char *) malloc(sizeof(char) * ptr->result_len))) { snippet_deinit(initid); strcpy(message, "memory allocation error !(result)"); @@ -196,6 +227,13 @@ return 1; } + /* zero length allocation */ + if (!(ptr->source = (char *) malloc(sizeof(char) * ptr->source_len))) { + snippet_deinit(initid); + strcpy(message, "memory allocation error !(source)"); + return 1; + } + return 0; } @@ -215,6 +253,9 @@ if (ptr->buffer) { free(ptr->buffer); } + if (ptr->source) { + free(ptr->source); + } if (ptr->keytags) { free(ptr->keytags); } @@ -228,60 +269,41 @@ { snip_struct *ptr; sen_snip *snip; - unsigned int i, n_results, estimated_length, max_tagged_len; - char *p; + int i; + unsigned int n_results, estimated_length, max_tagged_len; + char *p, *q; ptr = (snip_struct *) initid->ptr; snip = ptr->snip; - if (!ptr->keytags){ - unsigned int keytagslength; - char *q, *r; - - keytagslength = 0; - for (i = 7; i < args->arg_count; i++) { - if (args->lengths[i] >= INT_MAX) { - sprintf(ptr->result, "parameter number %d is too long!", i + 1); - goto exit; - } - keytagslength += args->lengths[i]; - } - - if (!(ptr->keytags = (char *) malloc(sizeof(char) * keytagslength))) { - sprintf(ptr->result, "memory allocation error !(tags)"); - goto exit; - } - - p = ptr->keytags; - for (i = 7; i < args->arg_count; i += 3) { - - memcpy(p, args->args[i], args->lengths[i]); /* keyword copy */ - q = p + args->lengths[i]; - memcpy(q, args->args[i + 1], args->lengths[i + 1]); /* opentag copy */ - r = q + args->lengths[i + 1]; - memcpy(r, args->args[i + 2], args->lengths[i + 2]); /* closetag copy */ - - if (sen_snip_add_cond(snip, p, args->lengths[i], - q, args->lengths[i + 1], - r, args->lengths[i + 2]) != sen_success) { - strcpy(ptr->result, "cannot add conditions"); - goto exit; - } - p = r + args->lengths[i + 2]; - } - } - + p = ptr->result; if (args->arg_type[0] != STRING_RESULT) { strcpy(ptr->result, "cannot make snippet"); goto exit; - } - if (args->lengths[0] >= INT_MAX) { + } else if (args->lengths[0] >= INT_MAX) { strcpy(ptr->result, "string is too long"); goto exit; - } - if (args->args[0]) { - if (sen_snip_exec(snip, args->args[0], args->lengths[0], &n_results, &max_tagged_len) - != sen_success) { + } else if (args->args[0]) { + + if ((args->args[0])[args->lengths[0]] == '\0') { + q = args->args[0]; /* null terminated */ + } else { /* not null terminated */ + /* source realloc */ + if (ptr->source_len <= args->lengths[0]) { + ptr->source = + (char *) realloc(ptr->source, sizeof(char) * (args->lengths[0] + 1)); + if (!ptr->result) { + strcpy(ptr->result, "cannot reallocate memory for source"); + goto exit; + } + ptr->source_len = args->lengths[0] + 1; + } + q = ptr->source; + memcpy(q, args->args[0], args->lengths[0]); + q[args->lengths[0]] = '\0'; + } + + if (sen_snip_exec(snip, q, strlen(q), &n_results, &max_tagged_len) != sen_success) { strcpy(ptr->result, "cannot make snippet"); goto exit; } @@ -310,26 +332,23 @@ p = ptr->result; for (i = 0; i < n_results; i++) { - unsigned int r_len; - if (sen_snip_get_result(snip, i, ptr->buffer, &r_len) != sen_success) { + if (sen_snip_get_result(snip, i, ptr->buffer, NULL) != sen_success) { strcpy(ptr->result, "cannot get result"); goto exit; } memcpy(p, args->args[5], args->lengths[5]); p += args->lengths[5]; - memcpy(p, ptr->buffer, r_len); - p += r_len; + for (q = ptr->buffer; *q != '\0'; *p++ = *q++) { + } memcpy(p, args->args[6], args->lengths[6]); p += args->lengths[6]; } - *length = (size_t)(p - ptr->result); } - else { - *length = 0; - } - return ptr->result; + exit: + *p = '\0'; *length = strlen(ptr->result); + return ptr->result; } --- Tasuku SUENAGA <a****@razil*****>