istream-jsonstr.c revision bcd286622779a93f809b11993db0550f8c7cc9b5
/* Copyright (c) 2013-2017 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "buffer.h"
#include "hex-dec.h"
#include "unichar.h"
#include "istream-private.h"
#include "istream-jsonstr.h"
#define MAX_UTF8_LEN 6
struct jsonstr_istream {
struct istream_private istream;
/* The end '"' was found */
bool str_end:1;
};
static int
unsigned int min_bytes)
{
"EOF before trailing <\"> was seen");
}
return ret;
}
}
return -2;
return 1;
}
static int
unsigned int *src_size_r, unsigned int *dest_size_r)
{
switch (*src) {
case '"':
case '\\':
case '/':
break;
case 'b':
*dest = '\b';
break;
case 'f':
*dest = '\f';
break;
case 'n':
*dest = '\n';
break;
case 'r':
*dest = '\r';
break;
case 't':
*dest = '\t';
break;
case 'u': {
*src_size_r = 5;
return 0;
}
default:
return -1;
}
*src_size_r = 1;
*dest_size_r = 1;
return 0;
}
{
const unsigned char *data;
return -1;
}
if (ret <= 0)
return ret;
/* @UNSAFE */
extra = 0;
if (data[i] == '"') {
return -1;
}
break;
} else if (data[i] == '\\') {
if (i+1 == size) {
/* not enough input for \x */
extra = 1;
break;
}
/* not enough input for \u0000 */
extra = 5;
break;
}
/* UTF8 output is max. 6 chars */
return -2;
break;
}
i++;
if (i_stream_json_unescape(data + i,
/* invalid string */
"Invalid JSON string");
return -1;
}
i += srcskip;
} else {
i++;
}
}
if (ret == 0) {
/* not enough input */
i_assert(i == 0);
if (ret <= 0)
return ret;
return i_stream_jsonstr_read(stream);
}
return ret;
}
{
struct jsonstr_istream *dstream;
i_stream_get_fd(input), 0);
}