istream-jsonstr.c revision 1c6f6f5bef70f16546b3bc8f4cd5f93f373e82a2
5a580c3a38ced62d4bcc95b8ac7c4f2935b5d294Timo Sirainen/* Copyright (c) 2013 Dovecot authors, see the included COPYING file */
7877db7b5daad125b6cb3e015574f33871c9a51bTimo Sirainen /* The end '"' was found */
7877db7b5daad125b6cb3e015574f33871c9a51bTimo Siraineni_stream_jsonstr_read_parent(struct jsonstr_istream *jstream,
7877db7b5daad125b6cb3e015574f33871c9a51bTimo Sirainen struct istream_private *stream = &jstream->istream;
7877db7b5daad125b6cb3e015574f33871c9a51bTimo Sirainen size = i_stream_get_data_size(stream->parent);
7877db7b5daad125b6cb3e015574f33871c9a51bTimo Sirainen if (ret <= 0 && (ret != -2 || stream->skip == 0)) {
7877db7b5daad125b6cb3e015574f33871c9a51bTimo Sirainen size = i_stream_get_data_size(stream->parent);
7877db7b5daad125b6cb3e015574f33871c9a51bTimo Sirainen if (!i_stream_try_alloc(stream, size, &avail))
7877db7b5daad125b6cb3e015574f33871c9a51bTimo Siraineni_stream_json_unescape(const unsigned char *src, unsigned char *dest,
7877db7b5daad125b6cb3e015574f33871c9a51bTimo Sirainen unsigned int *src_size_r, unsigned int *dest_size_r)
7877db7b5daad125b6cb3e015574f33871c9a51bTimo Sirainen buffer_create_from_data(&buf, dest, MAX_UTF8_LEN);
7877db7b5daad125b6cb3e015574f33871c9a51bTimo Sirainenstatic ssize_t i_stream_jsonstr_read(struct istream_private *stream)
7877db7b5daad125b6cb3e015574f33871c9a51bTimo Sirainen struct jsonstr_istream *jstream = (struct jsonstr_istream *)stream;
7877db7b5daad125b6cb3e015574f33871c9a51bTimo Sirainen const unsigned char *data;
7877db7b5daad125b6cb3e015574f33871c9a51bTimo Sirainen ret = i_stream_jsonstr_read_parent(jstream, 1);
7877db7b5daad125b6cb3e015574f33871c9a51bTimo Sirainen /* @UNSAFE */
7877db7b5daad125b6cb3e015574f33871c9a51bTimo Sirainen data = i_stream_get_data(stream->parent, &size);
7877db7b5daad125b6cb3e015574f33871c9a51bTimo Sirainen for (i = 0; i < size && dest < stream->buffer_size; ) {
7877db7b5daad125b6cb3e015574f33871c9a51bTimo Sirainen /* not enough input for \x */
7877db7b5daad125b6cb3e015574f33871c9a51bTimo Sirainen /* not enough input for \u0000 */
7877db7b5daad125b6cb3e015574f33871c9a51bTimo Sirainen if (data[i+1] == 'u' && stream->buffer_size - dest < MAX_UTF8_LEN) {
7877db7b5daad125b6cb3e015574f33871c9a51bTimo Sirainen /* UTF8 output is max. 6 chars */
7877db7b5daad125b6cb3e015574f33871c9a51bTimo Sirainen /* invalid string */
1c6f6f5bef70f16546b3bc8f4cd5f93f373e82a2Timo Sirainen "Invalid JSON string");
7877db7b5daad125b6cb3e015574f33871c9a51bTimo Sirainen /* not enough input */
7877db7b5daad125b6cb3e015574f33871c9a51bTimo Sirainen ret = i_stream_jsonstr_read_parent(jstream, i+extra+1);
7877db7b5daad125b6cb3e015574f33871c9a51bTimo Sirainenstruct istream *i_stream_create_jsonstr(struct istream *input)
7877db7b5daad125b6cb3e015574f33871c9a51bTimo Sirainen dstream->istream.max_buffer_size = input->real_stream->max_buffer_size;
7877db7b5daad125b6cb3e015574f33871c9a51bTimo Sirainen dstream->istream.read = i_stream_jsonstr_read;
7877db7b5daad125b6cb3e015574f33871c9a51bTimo Sirainen dstream->istream.istream.blocking = input->blocking;