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*****>