From 5712d55d50418a36801fa62f3d2a54b74c7a4b28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20S=C3=B6derberg?= Date: Fri, 16 Jan 2015 14:05:05 +0100 Subject: [PATCH] Use proper free/malloc. Also export the correct symbols. --- src/error.c | 36 +++++++++++++++++-------- src/jansson.def | 2 ++ src/jansson.h | 1 + src/utf.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++ src/utf.h | 1 + 5 files changed, 99 insertions(+), 11 deletions(-) diff --git a/src/error.c b/src/error.c index f0fb0ca..7602a96 100644 --- a/src/error.c +++ b/src/error.c @@ -78,7 +78,7 @@ static size_t json_error_get_utf8_column(json_error_t *error, const char *src) return i; } -char *json_error_get_source_text(json_error_t *error, const char *src) +static char *json_error_get_source_text(json_error_t *error, const char *src) { const char *start; const char *end; @@ -95,7 +95,7 @@ char *json_error_get_source_text(json_error_t *error, const char *src) len = (end - start) + 2; - if (!(s = malloc(len))) { + if (!(s = jsonp_malloc(len))) { return NULL; } @@ -107,7 +107,7 @@ char *json_error_get_source_text(json_error_t *error, const char *src) return s; } -char *json_error_get_arrow(json_error_t *error, +static char *json_error_get_arrow(json_error_t *error, const char *src, size_t flags) { size_t msglen; @@ -120,7 +120,7 @@ char *json_error_get_arrow(json_error_t *error, const char padchars[] = "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"; if (strlen(src) < 2) { - return strdup(""); + return jsonp_strdup(""); } if (arrowlen < 0) { @@ -133,7 +133,7 @@ char *json_error_get_arrow(json_error_t *error, msglen = (error->column + strlen(error->text) + arrowlen + 1) * 2; - if (!(msg = malloc(msglen))) { + if (!(msg = jsonp_malloc(msglen))) { return NULL; } @@ -184,7 +184,7 @@ char *json_error_get_arrow(json_error_t *error, return msg; fail: - if (msg) free(msg); + if (msg) jsonp_free(msg); return NULL; } @@ -236,14 +236,28 @@ char *json_error_get_detailed(json_error_t *error, const char *src, size_t flags } } - free(problem_src); - free(arrow); + jsonp_free(problem_src); + jsonp_free(arrow); return s; fail: - if (problem_src) free(problem_src); - if (arrow) free(arrow); - if (s) free(s); + if (problem_src) jsonp_free(problem_src); + if (arrow) jsonp_free(arrow); + if (s) jsonp_free(s); return NULL; } +void json_error_print_detailed(FILE *fd, json_error_t *error, const char *src, size_t flags) +{ + char *d; + + if (!(d = json_error_get_detailed(error, src, flags))) { + // Since we're reporting an error, at least report something! + fprintf(fd, "%s\n", error->text); + return; + } + + fprintf(fd, "%s", d); + jsonp_free(d); +} + diff --git a/src/jansson.def b/src/jansson.def index da4cfd4..85c779a 100644 --- a/src/jansson.def +++ b/src/jansson.def @@ -66,4 +66,6 @@ EXPORTS json_unpack_ex json_vunpack_ex json_set_alloc_funcs + json_error_get_detailed + json_error_print_detailed diff --git a/src/jansson.h b/src/jansson.h index 77cd814..b0a1b8a 100644 --- a/src/jansson.h +++ b/src/jansson.h @@ -132,6 +132,7 @@ typedef struct { #define JSON_ERROR_FLIP 0x40 char *json_error_get_detailed(json_error_t *error, const char *src, size_t flags); +void json_error_print_detailed(FILE *fd, json_error_t *error, const char *src, size_t flags); /* getters, setters, manipulation */ diff --git a/src/utf.c b/src/utf.c index b56e125..d0ad389 100644 --- a/src/utf.c +++ b/src/utf.c @@ -185,3 +185,73 @@ int utf8_check_string(const char *string, size_t length) return 1; } + +// +// This code is from: +// http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ +// +// Copyright (c) 2008-2009 Bjoern Hoehrmann +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// +#define UTF8_ACCEPT 0 +#define UTF8_REJECT 1 + +static const uint8_t utf8d[] = { + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 00..1f + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 20..3f + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 40..5f + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 60..7f + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, // 80..9f + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, // a0..bf + 8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // c0..df + 0xa,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x4,0x3,0x3, // e0..ef + 0xb,0x6,0x6,0x6,0x5,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8, // f0..ff + 0x0,0x1,0x2,0x3,0x5,0x8,0x7,0x1,0x1,0x1,0x4,0x6,0x1,0x1,0x1,0x1, // s0..s0 + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,0,1,0,1,1,1,1,1,1, // s1..s2 + 1,2,1,1,1,1,1,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1, // s3..s4 + 1,2,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,3,1,1,1,1,1,1, // s5..s6 + 1,3,1,1,1,1,1,3,1,3,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // s7..s8 +}; + +static uint32_t decode(uint32_t* state, uint32_t* codep, uint32_t byte) +{ + uint32_t type = utf8d[byte]; + + *codep = (*state != UTF8_ACCEPT) ? + (byte & 0x3fu) | (*codep << 6) : + (0xff >> type) & (byte); + + *state = utf8d[256 + (*state) * 16 + type]; + return *state; +} + +int utf8_strlen(const char *s, size_t *count) +{ + uint32_t codepoint; + uint32_t state = UTF8_ACCEPT; + + for (*count = 0; *s; ++s) { + if (!decode(&state, &codepoint, (uint8_t)*s)) { + (*count)++; + } + } + + return state != UTF8_ACCEPT; +} diff --git a/src/utf.h b/src/utf.h index 2cebea0..9ffabae 100644 --- a/src/utf.h +++ b/src/utf.h @@ -23,5 +23,6 @@ size_t utf8_check_full(const char *buffer, size_t size, int32_t *codepoint); const char *utf8_iterate(const char *buffer, size_t size, int32_t *codepoint); int utf8_check_string(const char *string, size_t length); +int utf8_strlen(const char *str, size_t *count); #endif