static int managesieve_parser_read_literal_data(struct managesieve_parser *parser, const unsigned char *data, size_t data_size) { if (parser->literal_skip_crlf) { /* skip \r\n or \n, anything else gives an error */ if (data_size == 0) return FALSE; if (*data == '\r') { parser->line_size++; data++; data_size--; i_stream_skip(parser->input, 1); if (data_size == 0) return FALSE; } if (*data != '\n') { parser->error = "Missing LF after literal size"; return FALSE; } parser->line_size++; data++; data_size--; i_stream_skip(parser->input, 1); parser->literal_skip_crlf = FALSE; i_assert(parser->cur_pos == 0); } if ((parser->flags & MANAGESIEVE_PARSE_FLAG_STRING_STREAM) == 0) { /* now we just wait until we've read enough data */ if (data_size < parser->literal_size) { return FALSE; } else { if ( !uni_utf8_data_is_valid (data, (size_t)parser->literal_size) ) { parser->error = "Invalid UTF-8 character in literal string."; return FALSE; } managesieve_parser_save_arg(parser, data, (size_t)parser->literal_size); parser->cur_pos = (size_t)parser->literal_size; return TRUE; } } else { /* we don't read the data; we just create a stream for the literal */ parser->eol = TRUE; parser->str_stream = i_stream_create_limit (parser->input, parser->literal_size); managesieve_parser_save_arg(parser, NULL, 0); return TRUE; } }
static int managesieve_parser_read_string(struct managesieve_parser *parser, const unsigned char *data, size_t data_size) { size_t i; /* QUOTED-CHAR = SAFE-UTF8-CHAR / "\" QUOTED-SPECIALS * quoted = <"> *QUOTED-CHAR <"> * ;; limited to 1024 octets between the <">s */ /* read until we've found non-escaped ", CR or LF */ for (i = parser->cur_pos; i < data_size; i++) { if (data[i] == '"') { if ( !uni_utf8_data_is_valid(data+1, i-1) ) { parser->error = "Invalid UTF-8 character in quoted-string."; return FALSE; } managesieve_parser_save_arg(parser, data, i); i++; /* skip the trailing '"' too */ break; } if (data[i] == '\\') { if (i+1 == data_size) { /* known data ends with '\' - leave it to next time as well if it happens to be \" */ break; } /* save the first escaped char */ if (parser->str_first_escape < 0) parser->str_first_escape = i; /* skip the escaped char */ i++; if ( !IS_QUOTED_SPECIAL(data[i]) ) { parser->error = "Escaped quoted-string character is not a QUOTED-SPECIAL."; return FALSE; } continue; } if ( (data[i] & 0x80) == 0 && !IS_SAFE_CHAR(data[i]) ) { parser->error = "String contains invalid character."; return FALSE; } } parser->cur_pos = i; return parser->cur_type == ARG_PARSE_NONE; }
void fts_parser_more(struct fts_parser *parser, struct message_block *block) { if (parser->v.more != NULL) parser->v.more(parser, block); if (!uni_utf8_data_is_valid(block->data, block->size) || data_has_nuls(block->data, block->size)) { /* output isn't valid UTF-8. make it. */ if (parser->utf8_output == NULL) { parser->utf8_output = buffer_create_dynamic(default_pool, 4096); } else { buffer_set_used_size(parser->utf8_output, 0); } (void)uni_utf8_get_valid_data(block->data, block->size, parser->utf8_output); replace_nul_bytes(parser->utf8_output); block->data = parser->utf8_output->data; block->size = parser->utf8_output->used; } }