This was the only function in rfc822-parser.h that wasn't NUL-safe.
This won't fix anything, but it makes the rfc822-parser.h API fully
consistent with the NUL handling.
Normally rfc2231_parse() should be called instead of calling
rfc822_parse_content_param() directly, so this shouldn't break any plugins.
ARRAY(struct rfc2231_parameter) rfc2231_params_arr;
struct rfc2231_parameter rfc2231_param;
const struct rfc2231_parameter *rfc2231_params;
- const char *key, *value, *p, *p2;
+ const char *key, *p, *p2;
string_t *str;
unsigned int i, j, count, next, next_idx;
bool ok, have_extended, broken = FALSE;
i_zero(&rfc2231_param);
t_array_init(&result, 8);
t_array_init(&rfc2231_params_arr, 8);
- while ((ret = rfc822_parse_content_param(ctx, &key, &value)) != 0) {
+ str = t_str_new(64);
+ while ((ret = rfc822_parse_content_param(ctx, &key, str)) != 0) {
if (ret < 0) {
/* try to continue anyway.. */
broken = TRUE;
p = NULL;
else {
rfc2231_param.key = t_strdup_until(key, p2);
- rfc2231_param.value = value;
+ rfc2231_param.value = t_strdup(str_c(str));
array_append(&rfc2231_params_arr,
&rfc2231_param, 1);
}
}
if (p == NULL) {
+ const char *value = t_strdup(str_c(str));
array_append(&result, &key, 1);
array_append(&result, &value, 1);
}
/* keys are now sorted primarily by their name and secondarily by
their index. If any indexes are missing, fallback to assuming
these aren't RFC 2231 encoded parameters. */
- str = t_str_new(64);
for (i = 0; i < count; i = next) {
ok = TRUE;
have_extended = FALSE;
key = rfc2231_params[i].key;
if (have_extended)
key = t_strconcat(key, "*", NULL);
- value = t_strdup(str_c(str));
+ const char *value = t_strdup(str_c(str));
array_append(&result, &key, 1);
array_append(&result, &value, 1);
}
}
int rfc822_parse_content_param(struct rfc822_parser_context *ctx,
- const char **key_r, const char **value_r)
+ const char **key_r, string_t *value)
{
- string_t *tmp;
- size_t value_pos;
+ string_t *key;
int ret;
/* .. := *(";" parameter)
value := token / quoted-string
*/
*key_r = NULL;
- *value_r = NULL;
+ str_truncate(value, 0);
if (ctx->data >= ctx->end)
return 0;
if (rfc822_skip_lwsp(ctx) <= 0)
return -1;
- tmp = t_str_new(64);
- if (rfc822_parse_mime_token(ctx, tmp) <= 0)
+ key = t_str_new(64);
+ if (rfc822_parse_mime_token(ctx, key) <= 0)
return -1;
- str_append_c(tmp, '\0');
- value_pos = str_len(tmp);
if (*ctx->data != '=')
return -1;
if ((ret = rfc822_skip_lwsp(ctx)) <= 0) {
/* broken / no value */
} else if (*ctx->data == '"') {
- ret = rfc822_parse_quoted_string(ctx, tmp);
+ ret = rfc822_parse_quoted_string(ctx, value);
} else if (ctx->data < ctx->end && *ctx->data == '=') {
/* workaround for broken input:
name==?utf-8?b?...?= */
while (ctx->data < ctx->end && *ctx->data != ';' &&
*ctx->data != ' ' && *ctx->data != '\t' &&
*ctx->data != '\r' && *ctx->data != '\n') {
- str_append_c(tmp, *ctx->data);
+ str_append_c(value, *ctx->data);
ctx->data++;
}
} else {
- ret = rfc822_parse_mime_token(ctx, tmp);
+ ret = rfc822_parse_mime_token(ctx, value);
}
- *key_r = str_c(tmp);
- *value_r = *key_r + value_pos;
+ *key_r = str_c(key);
return ret < 0 ? -1 : 1;
}
/* Parse Content-Type header's type/subtype. */
int rfc822_parse_content_type(struct rfc822_parser_context *ctx, string_t *str);
/* For Content-Type style parameter parsing. Expect ";" key "=" value.
- value is unescaped if needed. The returned strings are allocated from data
- stack. Returns 1 = key/value set, 0 = no more data, -1 = invalid input. */
+ value is unescaped if needed. The returned key is allocated from data
+ stack. The value string is truncated for each call. Returns 1 = key/value
+ set, 0 = no more data, -1 = invalid input. */
int rfc822_parse_content_param(struct rfc822_parser_context *ctx,
- const char **key_r, const char **value_r);
+ const char **key_r, string_t *value);
#endif
{ "key2", " \"(),/:;<=>?@[\\]" }
};
struct rfc822_parser_context parser;
- const char *key, *value;
+ const char *key;
+ string_t *value = t_str_new(64);
unsigned int i = 0;
int ret;
test_begin("rfc822 parse content param");
rfc822_parser_init(&parser, (const void *)input, strlen(input), NULL);
- while ((ret = rfc822_parse_content_param(&parser, &key, &value)) > 0 &&
+ while ((ret = rfc822_parse_content_param(&parser, &key, value)) > 0 &&
i < N_ELEMENTS(output)) {
test_assert_idx(strcmp(output[i].key, key) == 0, i);
- test_assert_idx(strcmp(output[i].value, value) == 0, i);
+ test_assert_idx(strcmp(output[i].value, str_c(value)) == 0, i);
i++;
}
rfc822_parser_deinit(&parser);