Skip to content

Commit

Permalink
Try akheron#2 at string lengths and string stealing
Browse files Browse the repository at this point in the history
  • Loading branch information
Chip Salzenberg committed Apr 4, 2012
1 parent e8fd3e3 commit 335764e
Show file tree
Hide file tree
Showing 8 changed files with 122 additions and 43 deletions.
17 changes: 10 additions & 7 deletions src/dump.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,24 +62,25 @@ static int dump_indent(size_t flags, int depth, int space, json_dump_callback_t
return 0;
}

static int dump_string(const char *str, int ascii, json_dump_callback_t dump, void *data)
static int dump_string(const char *str, size_t len, int ascii, json_dump_callback_t dump, void *data)
{
const char *pos, *end;
const char *pos, *end, *lim;
int32_t codepoint;

if(dump("\"", 1, data))
return -1;

end = pos = str;
lim = str + len;
while(1)
{
const char *text;
char seq[13];
int length;

while(*end)
while(end < lim)
{
end = utf8_iterate(pos, &codepoint);
end = utf8_iterate(pos, lim - pos, &codepoint);
if(!end)
return -1;

Expand Down Expand Up @@ -113,6 +114,7 @@ static int dump_string(const char *str, int ascii, json_dump_callback_t dump, vo
case '\n': text = "\\n"; break;
case '\r': text = "\\r"; break;
case '\t': text = "\\t"; break;
case '\0': text = "\\0"; break;
default:
{
/* codepoint is in BMP */
Expand Down Expand Up @@ -206,7 +208,7 @@ static int do_dump(const json_t *json, size_t flags, int depth,
}

case JSON_STRING:
return dump_string(json_string_value(json), ascii, dump, data);
return dump_string(json_string_value(json), json_string_len(json), ascii, dump, data);

case JSON_ARRAY:
{
Expand Down Expand Up @@ -327,7 +329,7 @@ static int do_dump(const json_t *json, size_t flags, int depth,
value = json_object_get(json, key);
assert(value);

dump_string(key, ascii, dump, data);
dump_string(key, strlen(key), ascii, dump, data);
if(dump(separator, separator_length, data) ||
do_dump(value, flags, depth + 1, dump, data))
{
Expand Down Expand Up @@ -364,7 +366,8 @@ static int do_dump(const json_t *json, size_t flags, int depth,
{
void *next = json_object_iter_next((json_t *)json, iter);

dump_string(json_object_iter_key(iter), ascii, dump, data);
const char *key = json_object_iter_key(iter);
dump_string(key, strlen(key), ascii, dump, data);
if(dump(separator, separator_length, data) ||
do_dump(json_object_iter_value(iter), flags, depth + 1,
dump, data))
Expand Down
6 changes: 6 additions & 0 deletions src/jansson.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,9 @@ typedef long json_int_t;
json_t *json_object(void);
json_t *json_array(void);
json_t *json_string(const char *value);
json_t *json_string_ex(const char *value, size_t len, size_t flags);
json_t *json_string_nocheck(const char *value);
json_t *json_string_nocheck_ex(const char *value, size_t len, size_t flags);
json_t *json_integer(json_int_t value);
json_t *json_real(double value);
json_t *json_true(void);
Expand Down Expand Up @@ -191,12 +193,15 @@ int json_array_insert(json_t *array, size_t index, json_t *value)
}

const char *json_string_value(const json_t *string);
size_t json_string_len(const json_t *string);
json_int_t json_integer_value(const json_t *integer);
double json_real_value(const json_t *real);
double json_number_value(const json_t *json);

int json_string_set(json_t *string, const char *value);
int json_string_set_ex(json_t *string, const char *value, size_t len, size_t flags);
int json_string_set_nocheck(json_t *string, const char *value);
int json_string_set_nocheck_ex(json_t *string, const char *value, size_t len, size_t flags);
int json_integer_set(json_t *integer, json_int_t value);
int json_real_set(json_t *real, double value);

Expand Down Expand Up @@ -249,6 +254,7 @@ json_t *json_load_callback(json_load_callback_t callback, void *data, size_t fla
#define JSON_SORT_KEYS 0x80
#define JSON_PRESERVE_ORDER 0x100
#define JSON_ENCODE_ANY 0x200
#define JSON_STEAL 0x400

typedef int (*json_dump_callback_t)(const char *buffer, size_t size, void *data);

Expand Down
2 changes: 2 additions & 0 deletions src/jansson_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ typedef struct {
typedef struct {
json_t json;
char *value;
size_t len;
} json_string_t;

typedef struct {
Expand Down Expand Up @@ -82,5 +83,6 @@ int jsonp_dtostr(char *buffer, size_t size, double value);
void* jsonp_malloc(size_t size);
void jsonp_free(void *ptr);
char *jsonp_strdup(const char *str);
char *jsonp_strndup(const char *str, size_t len);

#endif
2 changes: 1 addition & 1 deletion src/load.c
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,7 @@ static void lex_scan_string(lex_t *lex, json_error_t *error)
p++;
if(*p == 'u') {
char buffer[4];
int length;
size_t length;
int32_t value;

value = decode_unicode_escape(p);
Expand Down
14 changes: 12 additions & 2 deletions src/memory.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
#include <jansson.h>
#include "jansson_private.h"

/* C89 allows these to be macros */
#undef malloc
#undef free

/* memory function pointers */
static json_malloc_t do_malloc = malloc;
static json_free_t do_free = free;
Expand All @@ -33,14 +37,20 @@ void jsonp_free(void *ptr)
}

char *jsonp_strdup(const char *str)
{
return jsonp_strndup(str, strlen(str));
}

char *jsonp_strndup(const char *str, size_t len)
{
char *new_str;

new_str = jsonp_malloc(strlen(str) + 1);
new_str = jsonp_malloc(len + 1);
if(!new_str)
return NULL;

strcpy(new_str, str);
memcpy(new_str, str, len);
new_str[len] = '\0';
return new_str;
}

Expand Down
25 changes: 11 additions & 14 deletions src/utf.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
#include <string.h>
#include "utf.h"

int utf8_encode(int32_t codepoint, char *buffer, int *size)
int utf8_encode(int32_t codepoint, char *buffer, size_t *size)
{
if(codepoint < 0)
return -1;
Expand Down Expand Up @@ -44,7 +44,7 @@ int utf8_encode(int32_t codepoint, char *buffer, int *size)
return 0;
}

int utf8_check_first(char byte)
size_t utf8_check_first(char byte)
{
unsigned char u = (unsigned char)byte;

Expand Down Expand Up @@ -80,9 +80,9 @@ int utf8_check_first(char byte)
}
}

int utf8_check_full(const char *buffer, int size, int32_t *codepoint)
size_t utf8_check_full(const char *buffer, size_t size, int32_t *codepoint)
{
int i;
size_t i;
int32_t value = 0;
unsigned char u = (unsigned char)buffer[0];

Expand Down Expand Up @@ -136,12 +136,12 @@ int utf8_check_full(const char *buffer, int size, int32_t *codepoint)
return 1;
}

const char *utf8_iterate(const char *buffer, int32_t *codepoint)
const char *utf8_iterate(const char *buffer, size_t bufsize, int32_t *codepoint)
{
int count;
size_t count;
int32_t value;

if(!*buffer)
if(!bufsize)
return buffer;

count = utf8_check_first(buffer[0]);
Expand All @@ -152,7 +152,7 @@ const char *utf8_iterate(const char *buffer, int32_t *codepoint)
value = (unsigned char)buffer[0];
else
{
if(!utf8_check_full(buffer, count, &value))
if(count > bufsize || !utf8_check_full(buffer, count, &value))
return NULL;
}

Expand All @@ -162,16 +162,13 @@ const char *utf8_iterate(const char *buffer, int32_t *codepoint)
return buffer + count;
}

int utf8_check_string(const char *string, int length)
int utf8_check_string(const char *string, size_t length)
{
int i;

if(length == -1)
length = strlen(string);
size_t i;

for(i = 0; i < length; i++)
{
int count = utf8_check_first(string[i]);
size_t count = utf8_check_first(string[i]);
if(count == 0)
return 0;
else if(count > 1)
Expand Down
10 changes: 5 additions & 5 deletions src/utf.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,12 @@ typedef int int32_t;

#endif /* HAVE_CONFIG_H */

int utf8_encode(int codepoint, char *buffer, int *size);
int utf8_encode(int codepoint, char *buffer, size_t *size);

int utf8_check_first(char byte);
int utf8_check_full(const char *buffer, int size, int32_t *codepoint);
const char *utf8_iterate(const char *buffer, int32_t *codepoint);
size_t utf8_check_first(char byte);
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, int length);
int utf8_check_string(const char *string, size_t length);

#endif
Loading

0 comments on commit 335764e

Please sign in to comment.