static void stream_unget(stream_t *stream, int c) { if(c == STREAM_STATE_EOF || c == STREAM_STATE_ERROR) return; stream->position--; if(c == '\n') { stream->line--; stream->column = stream->last_column; } else if(json_utf8_check_first(c)) stream->column--; assert(stream->buffer_pos > 0); stream->buffer_pos--; assert(stream->buffer[stream->buffer_pos] == c); }
int ast_json_utf8_check_len(const char *str, size_t len) { size_t pos; size_t count; int res = 1; if (!str) { return 0; } /* * Since the json library does not make the check function * public we recreate/copy the function in our interface * module. * * Loop ported from libjansson utf.c:utf8_check_string() */ for (pos = 0; pos < len; pos += count) { count = json_utf8_check_first(str[pos]); if (count == 0) { res = 0; break; } else if (count > 1) { if (count > len - pos) { /* UTF-8 needs more than we have left in the string. */ res = 0; break; } if (!json_utf8_check_full(&str[pos], count)) { res = 0; break; } } } if (!res) { ast_debug(1, "String '%.*s' is not UTF-8 for json conversion\n", (int) len, str); } return res; }
static int stream_get(stream_t *stream, json_error_t *error) { int c; if(stream->state != STREAM_STATE_OK) return stream->state; if(!stream->buffer[stream->buffer_pos]) { c = stream->get(stream->data); if(c == EOF) { stream->state = STREAM_STATE_EOF; return STREAM_STATE_EOF; } stream->buffer[0] = c; stream->buffer_pos = 0; if(0x80 <= c && c <= 0xFF) { /* multi-byte UTF-8 sequence */ int i, count; count = json_utf8_check_first(c); if(!count) goto out; assert(count >= 2); for(i = 1; i < count; i++) stream->buffer[i] = stream->get(stream->data); if(!json_utf8_check_full(stream->buffer, count, NULL)) goto out; stream->buffer[count] = '\0'; } else stream->buffer[1] = '\0'; } c = stream->buffer[stream->buffer_pos++]; stream->position++; if(c == '\n') { stream->line++; stream->last_column = stream->column; stream->column = 0; } else if(json_utf8_check_first(c)) { /* track the Unicode character column, so increment only if this is the first character of a UTF-8 sequence */ stream->column++; } return c; out: stream->state = STREAM_STATE_ERROR; error_set(error, stream_to_lex(stream), "unable to decode byte 0x%x", c); return STREAM_STATE_ERROR; }