* BREAKING API CHANGE: allow client to specify memory allocation routines

* bump yajl version to 1.0.0
 * update TODO list, removing completed tasks
 * update yajl_test to override allocation routines and count allocations/frees, providing an automated standalone way to validate we're not leaky
 * update all copyright dates
 * update all .gold files with new test output
 * update ChangeLog in preparation for 1.0.0 release
This commit is contained in:
Lloyd Hilaiel 2009-04-01 18:05:07 +03:00
parent af305526e7
commit b78dd79082
67 changed files with 404 additions and 72 deletions

View File

@ -1,4 +1,4 @@
# Copyright 2007, Lloyd Hilaiel.
# Copyright 2007-2009, Lloyd Hilaiel.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
@ -32,9 +32,9 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
PROJECT(YetAnotherJSONParser)
SET (YAJL_MAJOR 0)
SET (YAJL_MINOR 4)
SET (YAJL_MICRO 1)
SET (YAJL_MAJOR 1)
SET (YAJL_MINOR 0)
SET (YAJL_MICRO 0)
SET (YAJL_DIST_NAME "yajl-${YAJL_MAJOR}.${YAJL_MINOR}.${YAJL_MICRO}")

View File

@ -1,4 +1,4 @@
Copyright 2007, Lloyd Hilaiel.
Copyright 2007-2009, Lloyd Hilaiel.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are

View File

@ -1,6 +1,17 @@
1.0.0
* lth add 'make install' rules, thaks to Andrei Soroker for the
contribution.
* lth client may override allocation routines at generator or parser
allocation time
* tjw add yajl_parse_complete routine to allow client to explicitly
specify end-of-input, solving the "lonely number" case, where
json text consists only of an element with no explicit syntactic
end.
* tjw many new test cases
* tjw cleanup of code for symmetry and ease of reading
* lth integration of patches from Robert Varga which cleanup
compilation warnings on 64 bit linux
0.4.0
* lth buffer overflow bug in yajl_gen_double s/%lf/%g/ - thanks to
Eric Bergstrome

4
TODO
View File

@ -1,13 +1,9 @@
* add a test for 0x1F bug
* numeric overflow in integers and double
* line and char offsets in the lexer and in error messages
* numbers at eof bug. client must have a way of indicating 'end of input'
(other than passing in a ' ' whitespace byte),
problem illustrated with lonely number test case.
* testing:
a. the permuter
b. some performance comparison against json_checker.
* investigate pull instead of push parsing
* Handle memory allocation failures gracefully
* allow client to override malloc/calloc/free impl.
* cygwin/msys support on win32

2
configure vendored
View File

@ -1,5 +1,5 @@
#!/usr/bin/env ruby
# Copyright 2007, Lloyd Hilaiel.
# Copyright 2007-2009, Lloyd Hilaiel.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are

View File

@ -1,4 +1,4 @@
# Copyright 2007, Lloyd Hilaiel.
# Copyright 2007-2009, Lloyd Hilaiel.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are

View File

@ -1,5 +1,5 @@
/*
* Copyright 2007, Lloyd Hilaiel.
* Copyright 2007-2009, Lloyd Hilaiel.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@ -156,10 +156,10 @@ main(int argc, char ** argv)
usage(argv[0]);
}
g = yajl_gen_alloc(&conf);
g = yajl_gen_alloc(&conf, NULL);
/* ok. open file. let's read and parse */
hand = yajl_alloc(&callbacks, &cfg, (void *) g);
hand = yajl_alloc(&callbacks, &cfg, (void *) g, NULL);
while (!done) {
rd = fread((void *) fileData, 1, sizeof(fileData) - 1, stdin);
@ -185,7 +185,7 @@ main(int argc, char ** argv)
{
unsigned char * str = yajl_get_error(hand, 1, fileData, rd);
fprintf(stderr, (const char *) str);
yajl_free_error(str);
yajl_free_error(hand, str);
} else {
const unsigned char * buf;
unsigned int len;

View File

@ -1,4 +1,4 @@
# Copyright 2007, Lloyd Hilaiel.
# Copyright 2007-2009, Lloyd Hilaiel.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
@ -28,8 +28,9 @@
# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
SET (SRCS yajl.c yajl_lex.c yajl_parser.c yajl_buf.c yajl_encode.c yajl_gen.c)
SET (HDRS yajl_parser.h yajl_lex.h yajl_buf.h yajl_encode.h)
SET (SRCS yajl.c yajl_lex.c yajl_parser.c yajl_buf.c
yajl_encode.c yajl_gen.c yajl_alloc.c)
SET (HDRS yajl_parser.h yajl_lex.h yajl_buf.h yajl_encode.h yajl_alloc.h)
SET (PUB_HDRS api/yajl_parse.h api/yajl_gen.h api/yajl_common.h)
# useful when fixing lexer bugs.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2007, Lloyd Hilaiel.
* Copyright 2007-2009, Lloyd Hilaiel.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@ -33,6 +33,10 @@
#ifndef __YAJL_COMMON_H__
#define __YAJL_COMMON_H__
#ifdef __cplusplus
extern "C" {
#endif
#define YAJL_MAX_DEPTH 128
/* msft dll export gunk. To build a DLL on windows, you
@ -48,4 +52,34 @@
# define YAJL_API
#endif
/** pointer to a malloc function, supporting client overriding memory
* allocation routines */
typedef void * (*yajl_malloc_func)(void *ctx, unsigned int sz);
/** pointer to a free function, supporting client overriding memory
* allocation routines */
typedef void (*yajl_free_func)(void *ctx, void * ptr);
/** pointer to a realloc function which can resize an allocation. */
typedef void * (*yajl_realloc_func)(void *ctx, void * ptr, unsigned int sz);
/** A structure which can be passed to yajl_*_alloc routines to allow the
* client to specify memory allocation functions to be used. */
typedef struct
{
/** pointer to a function that can allocate uninitialized memory */
yajl_malloc_func malloc;
/** pointer to a function that can resize memory allocations */
yajl_realloc_func realloc;
/** pointer to a function that can free memory allocated using
* reallocFunction or mallocFunction */
yajl_free_func free;
/** a context pointer that will be passed to above allocation routines */
void * ctx;
} yajl_alloc_funcs;
#ifdef __cplusplus
};
#endif
#endif

View File

@ -1,5 +1,5 @@
/*
* Copyright 2007, Lloyd Hilaiel.
* Copyright 2007-2009, Lloyd Hilaiel.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@ -73,8 +73,18 @@ extern "C" {
const char * indentString;
} yajl_gen_config;
/** allocate a generator handle */
yajl_gen YAJL_API yajl_gen_alloc(const yajl_gen_config * config);
/** allocate a generator handle
* \param config a pointer to a structure containing parameters which
* configure the behavior of the json generator
* \param allocFuncs an optional pointer to a structure which allows
* the client to overide the memory allocation
* used by yajl. May be NULL, in which case
* malloc/free/realloc will be used.
*
* \returns an allocated handle on success, NULL on failure (bad params)
*/
yajl_gen YAJL_API yajl_gen_alloc(const yajl_gen_config * config,
const yajl_alloc_funcs * allocFuncs);
/** free a generator handle */
void YAJL_API yajl_gen_free(yajl_gen handle);

View File

@ -1,5 +1,5 @@
/*
* Copyright 2007, Lloyd Hilaiel.
* Copyright 2007-2009, Lloyd Hilaiel.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@ -129,6 +129,7 @@ extern "C" {
*/
yajl_handle YAJL_API yajl_alloc(const yajl_callbacks * callbacks,
const yajl_parser_config * config,
const yajl_alloc_funcs * allocFuncs,
void * ctx);
/** free a parser handle */
@ -169,7 +170,7 @@ extern "C" {
unsigned int jsonTextLength);
/** free an error returned from yajl_get_error */
void YAJL_API yajl_free_error(unsigned char * str);
void YAJL_API yajl_free_error(yajl_handle hand, unsigned char * str);
#ifdef __cplusplus
};

View File

@ -1,7 +1,7 @@
/*!
\mainpage Yet Another JSON Library (YAJL)
\author Lloyd Hilaiel
\date 2007-2008
\date 2007-2009
Yet Another JSON Library (YAJL) is a small event-driven (SAX-style)
JSON parser written in ANSI C, and a small validating JSON

View File

@ -1,5 +1,5 @@
/*
* Copyright 2007, Lloyd Hilaiel.
* Copyright 2007-2009, Lloyd Hilaiel.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@ -33,6 +33,7 @@
#include "api/yajl_parse.h"
#include "yajl_lex.h"
#include "yajl_parser.h"
#include "yajl_alloc.h"
#include <stdlib.h>
#include <string.h>
@ -62,11 +63,29 @@ yajl_status_to_string(yajl_status stat)
yajl_handle
yajl_alloc(const yajl_callbacks * callbacks,
const yajl_parser_config * config,
const yajl_alloc_funcs * afs,
void * ctx)
{
unsigned int allowComments = 0;
unsigned int validateUTF8 = 0;
yajl_handle hand = (yajl_handle) malloc(sizeof(struct yajl_handle_t));
yajl_handle hand = NULL;
yajl_alloc_funcs afsBuffer;
/* first order of business is to set up memory allocation routines */
if (afs != NULL) {
if (afs->malloc == NULL || afs->realloc == NULL || afs->free == NULL)
{
return NULL;
}
} else {
yajl_set_default_alloc_funcs(&afsBuffer);
afs = &afsBuffer;
}
hand = (yajl_handle) YA_MALLOC(afs, sizeof(struct yajl_handle_t));
/* copy in pointers to allocation routines */
memcpy((void *) &(hand->alloc), (void *) afs, sizeof(yajl_alloc_funcs));
if (config != NULL) {
allowComments = config->allowComments;
@ -75,10 +94,10 @@ yajl_alloc(const yajl_callbacks * callbacks,
hand->callbacks = callbacks;
hand->ctx = ctx;
hand->lexer = yajl_lex_alloc(allowComments, validateUTF8);
hand->lexer = yajl_lex_alloc(&(hand->alloc), allowComments, validateUTF8);
hand->errorOffset = 0;
hand->decodeBuf = yajl_buf_alloc();
hand->stateBuf = yajl_buf_alloc();
hand->decodeBuf = yajl_buf_alloc(&(hand->alloc));
hand->stateBuf = yajl_buf_alloc(&(hand->alloc));
yajl_state_push(hand, yajl_state_start);
@ -91,7 +110,7 @@ yajl_free(yajl_handle handle)
yajl_buf_free(handle->stateBuf);
yajl_buf_free(handle->decodeBuf);
yajl_lex_free(handle->lexer);
free(handle);
YA_FREE(&(handle->alloc), handle);
}
yajl_status
@ -124,10 +143,10 @@ yajl_get_error(yajl_handle hand, int verbose,
}
void
yajl_free_error(unsigned char * str)
yajl_free_error(yajl_handle hand, unsigned char * str)
{
/* XXX: use memory allocation functions if set */
free(str);
/* use memory allocation functions if set */
YA_FREE(&(hand->alloc), str);
}
/* XXX: add utility routines to parse from file */

65
src/yajl_alloc.c Normal file
View File

@ -0,0 +1,65 @@
/*
* Copyright 2007-2009, Lloyd Hilaiel.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. Neither the name of Lloyd Hilaiel nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \file yajl_alloc.h
* default memory allocation routines for yajl which use malloc/realloc and
* free
*/
#include "yajl_alloc.h"
#include <stdlib.h>
static void * yajl_internal_malloc(void *ctx, unsigned int sz)
{
return malloc(sz);
}
static void * yajl_internal_realloc(void *ctx, void * previous,
unsigned int sz)
{
return realloc(previous, sz);
}
static void yajl_internal_free(void *ctx, void * ptr)
{
free(ptr);
}
void yajl_set_default_alloc_funcs(yajl_alloc_funcs * yaf)
{
yaf->malloc = yajl_internal_malloc;
yaf->free = yajl_internal_free;
yaf->realloc = yajl_internal_realloc;
yaf->ctx = NULL;
}

50
src/yajl_alloc.h Normal file
View File

@ -0,0 +1,50 @@
/*
* Copyright 2007-2009, Lloyd Hilaiel.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. Neither the name of Lloyd Hilaiel nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \file yajl_alloc.h
* default memory allocation routines for yajl which use malloc/realloc and
* free
*/
#ifndef __YAJL_ALLOC_H__
#define __YAJL_ALLOC_H__
#include "api/yajl_common.h"
#define YA_MALLOC(afs, sz) (afs)->malloc((afs)->ctx, (sz))
#define YA_FREE(afs, ptr) (afs)->free((afs)->ctx, (ptr))
#define YA_REALLOC(afs, ptr, sz) (afs)->realloc((afs)->ctx, (ptr), (sz))
void yajl_set_default_alloc_funcs(yajl_alloc_funcs * yaf);
#endif

View File

@ -1,5 +1,5 @@
/*
* Copyright 2007, Lloyd Hilaiel.
* Copyright 2007-2009, Lloyd Hilaiel.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@ -42,6 +42,7 @@ struct yajl_buf_t {
unsigned int len;
unsigned int used;
unsigned char * data;
yajl_alloc_funcs * alloc;
};
static
@ -54,7 +55,7 @@ void yajl_buf_ensure_available(yajl_buf buf, unsigned int want)
/* first call */
if (buf->data == NULL) {
buf->len = YAJL_BUF_INIT_SIZE;
buf->data = (unsigned char *) malloc(buf->len);
buf->data = (unsigned char *) YA_MALLOC(buf->alloc, buf->len);
buf->data[0] = 0;
}
@ -63,21 +64,24 @@ void yajl_buf_ensure_available(yajl_buf buf, unsigned int want)
while (want >= (need - buf->used)) need <<= 1;
if (need != buf->len) {
buf->data = (unsigned char *) realloc(buf->data, need);
buf->data = (unsigned char *) YA_REALLOC(buf->alloc, buf->data, need);
buf->len = need;
}
}
yajl_buf yajl_buf_alloc(void)
yajl_buf yajl_buf_alloc(yajl_alloc_funcs * alloc)
{
return (yajl_buf) calloc(1, sizeof(struct yajl_buf_t));
yajl_buf b = YA_MALLOC(alloc, sizeof(struct yajl_buf_t));
memset((void *) b, 0, sizeof(struct yajl_buf_t));
b->alloc = alloc;
return b;
}
void yajl_buf_free(yajl_buf buf)
{
assert(buf != NULL);
if (buf->data) free(buf->data);
free(buf);
if (buf->data) YA_FREE(buf->alloc, buf->data);
YA_FREE(buf->alloc, buf);
}
void yajl_buf_append(yajl_buf buf, const void * data, unsigned int len)

View File

@ -1,5 +1,5 @@
/*
* Copyright 2007, Lloyd Hilaiel.
* Copyright 2007-2009, Lloyd Hilaiel.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@ -33,6 +33,9 @@
#ifndef __YAJL_BUF_H__
#define __YAJL_BUF_H__
#include "api/yajl_common.h"
#include "yajl_alloc.h"
/**
* yajl_buf is a buffer with exponential growth. the buffer ensures that
* you are always null padded.
@ -40,7 +43,7 @@
typedef struct yajl_buf_t * yajl_buf;
/* allocate a new buffer */
yajl_buf yajl_buf_alloc(void);
yajl_buf yajl_buf_alloc(yajl_alloc_funcs * alloc);
/* free the buffer */
void yajl_buf_free(yajl_buf buf);

View File

@ -1,5 +1,5 @@
/*
* Copyright 2007, Lloyd Hilaiel.
* Copyright 2007-2009, Lloyd Hilaiel.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are

View File

@ -1,5 +1,5 @@
/*
* Copyright 2007, Lloyd Hilaiel.
* Copyright 2007-2009, Lloyd Hilaiel.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are

View File

@ -1,5 +1,5 @@
/*
* Copyright 2007, Lloyd Hilaiel.
* Copyright 2007-2009, Lloyd Hilaiel.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@ -56,18 +56,39 @@ struct yajl_gen_t
const char * indentString;
yajl_gen_state state[YAJL_MAX_DEPTH];
yajl_buf buf;
/* memory allocation routines */
yajl_alloc_funcs alloc;
};
yajl_gen
yajl_gen_alloc(const yajl_gen_config * config)
yajl_gen_alloc(const yajl_gen_config * config,
const yajl_alloc_funcs * afs)
{
yajl_gen g = (yajl_gen) malloc(sizeof(struct yajl_gen_t));
yajl_gen g = NULL;
yajl_alloc_funcs afsBuffer;
/* first order of business is to set up memory allocation routines */
if (afs != NULL) {
if (afs->malloc == NULL || afs->realloc == NULL || afs->free == NULL)
{
return NULL;
}
} else {
yajl_set_default_alloc_funcs(&afsBuffer);
afs = &afsBuffer;
}
g = (yajl_gen) YA_MALLOC(afs, sizeof(struct yajl_gen_t));
memset((void *) g, 0, sizeof(struct yajl_gen_t));
/* copy in pointers to allocation routines */
memcpy((void *) &(g->alloc), (void *) afs, sizeof(yajl_alloc_funcs));
if (config) {
g->pretty = config->beautify;
g->indentString = config->indentString ? config->indentString : " ";
}
g->buf = yajl_buf_alloc();
g->buf = yajl_buf_alloc(&(g->alloc));
return g;
}
@ -75,7 +96,7 @@ void
yajl_gen_free(yajl_gen g)
{
yajl_buf_free(g->buf);
free(g);
YA_FREE(&(g->alloc), g);
}
#define INSERT_SEP \

View File

@ -1,5 +1,5 @@
/*
* Copyright 2007, Lloyd Hilaiel.
* Copyright 2007-2009, Lloyd Hilaiel.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@ -105,6 +105,8 @@ struct yajl_lexer_t {
/* shall we validate utf8 inside strings? */
unsigned int validateUTF8;
yajl_alloc_funcs * alloc;
};
static unsigned char
@ -127,12 +129,15 @@ unreadChar(yajl_lexer lxr, unsigned int *off)
}
yajl_lexer
yajl_lex_alloc(unsigned int allowComments, unsigned int validateUTF8)
yajl_lex_alloc(yajl_alloc_funcs * alloc,
unsigned int allowComments, unsigned int validateUTF8)
{
yajl_lexer lxr = (yajl_lexer) calloc(1, sizeof(struct yajl_lexer_t));
lxr->buf = yajl_buf_alloc();
yajl_lexer lxr = (yajl_lexer) YA_MALLOC(alloc, sizeof(struct yajl_lexer_t));
memset((void *) lxr, 0, sizeof(struct yajl_lexer_t));
lxr->buf = yajl_buf_alloc(alloc);
lxr->allowComments = allowComments;
lxr->validateUTF8 = validateUTF8;
lxr->alloc = alloc;
return lxr;
}
@ -140,7 +145,7 @@ void
yajl_lex_free(yajl_lexer lxr)
{
yajl_buf_free(lxr->buf);
free(lxr);
YA_FREE(lxr->alloc, lxr);
return;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2007, Lloyd Hilaiel.
* Copyright 2007-2009, Lloyd Hilaiel.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@ -33,6 +33,8 @@
#ifndef __YAJL_LEX_H__
#define __YAJL_LEX_H__
#include "api/yajl_common.h"
typedef enum {
yajl_tok_bool,
yajl_tok_colon,
@ -61,7 +63,8 @@ typedef enum {
typedef struct yajl_lexer_t * yajl_lexer;
yajl_lexer yajl_lex_alloc(unsigned int allowComments,
yajl_lexer yajl_lex_alloc(yajl_alloc_funcs * alloc,
unsigned int allowComments,
unsigned int validateUTF8);
void yajl_lex_free(yajl_lexer lexer);

View File

@ -1,5 +1,5 @@
/*
* Copyright 2007, Lloyd Hilaiel.
* Copyright 2007-2009, Lloyd Hilaiel.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@ -71,7 +71,7 @@ yajl_render_error_string(yajl_handle hand, const unsigned char * jsonText,
memneeded += strlen(": ");
memneeded += strlen(errorText);
}
str = (unsigned char *) malloc(memneeded + 2);
str = (unsigned char *) YA_MALLOC(&(hand->alloc), memneeded + 2);
str[0] = 0;
strcat((char *) str, errorType);
strcat((char *) str, " error");
@ -108,14 +108,15 @@ yajl_render_error_string(yajl_handle hand, const unsigned char * jsonText,
text[i++] = '\n';
text[i] = 0;
{
char * newStr = (char *) malloc(strlen((char *) str) +
strlen((char *) text) +
strlen(arrow) + 1);
char * newStr = (char *)
YA_MALLOC(&(hand->alloc), (strlen((char *) str) +
strlen((char *) text) +
strlen(arrow) + 1));
newStr[0] = 0;
strcat((char *) newStr, (char *) str);
strcat((char *) newStr, text);
strcat((char *) newStr, arrow);
free(str);
YA_FREE(&(hand->alloc), str);
str = (unsigned char *) newStr;
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2007, Lloyd Hilaiel.
* Copyright 2007-2009, Lloyd Hilaiel.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@ -61,6 +61,8 @@ struct yajl_handle_t {
yajl_buf decodeBuf;
/* a stack of states. access with yajl_state_XXX routines */
yajl_buf stateBuf;
/* memory allocation routines */
yajl_alloc_funcs alloc;
};
yajl_status

View File

@ -1,4 +1,4 @@
# Copyright 2007, Lloyd Hilaiel.
# Copyright 2007-2009, Lloyd Hilaiel.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are

View File

@ -19,3 +19,4 @@ array close ']'
string: '
\'
array close ']'
memory leaks: 0

View File

@ -1 +1,2 @@
parse error: unallowed token at this point in JSON text
memory leaks: 0

View File

@ -1 +1,2 @@
array open '['
memory leaks: 0

View File

@ -7,3 +7,4 @@ string: 'be'
string: 'a happy bit of json'
string: 'but someone, misspelled "true"'
lexical error: invalid string in json text.
memory leaks: 0

View File

@ -1 +1,2 @@
string: 'Mа𐌂'
memory leaks: 0

View File

@ -2,3 +2,4 @@ map open '{'
key: 'this'
string: 'is'
lexical error: probable comment found in input text, comments are not enabled.
memory leaks: 0

View File

@ -2046,3 +2046,4 @@ array close ']'
array close ']'
array close ']'
array close ']'
memory leaks: 0

View File

@ -33,3 +33,4 @@ array close ']'
map close '}'
map close '}'
map close '}'
memory leaks: 0

View File

@ -33,3 +33,4 @@ array close ']'
map close '}'
map close '}'
map close '}'
memory leaks: 0

View File

@ -4,3 +4,4 @@ double: 10
double: 3.14157
double: 1000
array close ']'
memory leaks: 0

View File

@ -1,2 +1,3 @@
array open '['
array close ']'
memory leaks: 0

View File

@ -1 +1,2 @@
string: ''
memory leaks: 0

View File

@ -4,3 +4,4 @@ string: 'Му'
string: 'Еба'
string: 'Майката'
array close ']'
memory leaks: 0

View File

@ -1 +1,2 @@
string: 'foobar'
memory leaks: 0

View File

@ -1 +1,2 @@
bool: false
memory leaks: 0

View File

@ -1 +1,2 @@
bool: false
memory leaks: 0

View File

@ -11,3 +11,4 @@ integer: -123456789
integer: 2147483647
integer: -2147483647
parse error: integer overflow
memory leaks: 0

View File

@ -1,2 +1,3 @@
array open '['
lexical error: invalid bytes in UTF8 string.
memory leaks: 0

View File

@ -1 +1,2 @@
string: '?'
memory leaks: 0

View File

@ -2,3 +2,4 @@ map open '{'
key: 'bad thing'
integer: 0
parse error: after key and value, inside map, I expect ',' or '}'
memory leaks: 0

View File

@ -6,3 +6,4 @@ string: 'blue'
string: 'baby where are you?'
string: 'oh boo hoo!'
lexical error: malformed number, a digit is required after the minus sign.
memory leaks: 0

View File

@ -1 +1,2 @@
integer: 123456789
memory leaks: 0

View File

@ -1 +1,2 @@
parse error: unallowed token at this point in JSON text
memory leaks: 0

View File

@ -1 +1,2 @@
map open '{'
memory leaks: 0

View File

@ -1 +1,2 @@
lexical error: malformed number, a digit is required after the decimal point.
memory leaks: 0

View File

@ -1 +1,2 @@
lexical error: malformed number, a digit is required after the exponent.
memory leaks: 0

View File

@ -5,3 +5,4 @@ key: 'CoreletType'
string: 'standalone'
key: 'documentation'
lexical error: invalid bytes in UTF8 string.
memory leaks: 0

View File

@ -1 +1,2 @@
null
memory leaks: 0

View File

@ -1 +1,2 @@
null
memory leaks: 0

View File

@ -6,3 +6,4 @@ bool: false
key: 'null'
null
map close '}'
memory leaks: 0

View File

@ -6,3 +6,4 @@ string: 'simple'
key: 'json'
string: 'right?'
map close '}'
memory leaks: 0

View File

@ -6,3 +6,4 @@ string: 'simple'
key: 'json'
string: 'right?'
map close '}'
memory leaks: 0

View File

@ -1,2 +1,3 @@
array open '['
lexical error: inside a string, '\' occurs before a character which it may not.
memory leaks: 0

View File

@ -1 +1,2 @@
lexical error: invalid (non-hex) character occurs after '\u' inside string.
memory leaks: 0

View File

@ -4,3 +4,4 @@ string: '
string: '"and this string has an escape at the beginning'
string: 'and this string has no escapes'
array close ']'
memory leaks: 0

View File

@ -1 +1,2 @@
lexical error: invalid character inside string.
memory leaks: 0

View File

@ -1 +1,2 @@
bool: true
memory leaks: 0

View File

@ -1 +1,2 @@
bool: true
memory leaks: 0

View File

@ -1,3 +1,4 @@
array open '['
string: 'Да Му Еба Майката'
array close ']'
memory leaks: 0

View File

@ -1,5 +1,5 @@
/*
* Copyright 2007, Lloyd Hilaiel.
* Copyright 2007-2009, Lloyd Hilaiel.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@ -37,6 +37,48 @@
#include <stdlib.h>
#include <string.h>
#include <assert.h>
/* memory debugging routines */
typedef struct
{
unsigned int numFrees;
unsigned int numMallocs;
/* XXX: we really need a hash table here with per-allocation
* information */
} yajlTestMemoryContext;
/* cast void * into context */
#define TEST_CTX(vptr) ((yajlTestMemoryContext *) (vptr))
static void yajlTestFree(void * ctx, void * ptr)
{
assert(ptr != NULL);
TEST_CTX(ctx)->numFrees++;
free(ptr);
}
static void * yajlTestMalloc(void * ctx, unsigned int sz)
{
assert(sz != 0);
TEST_CTX(ctx)->numMallocs++;
return malloc(sz);
}
static void * yajlTestRealloc(void * ctx, void * ptr, unsigned int sz)
{
if (ptr == NULL) {
assert(sz != 0);
TEST_CTX(ctx)->numMallocs++;
} else if (sz == 0) {
TEST_CTX(ctx)->numFrees++;
}
return realloc(ctx, sz);
}
/* begin parsing callback routines */
#define BUF_SIZE 2048
static int test_yajl_null(void *ctx)
@ -144,6 +186,21 @@ main(int argc, char ** argv)
yajl_parser_config cfg = { 0, 1 };
int i, j, done;
/* memory allocation debugging: allocate a structure which collects
* statistics */
yajlTestMemoryContext memCtx = { 0,0 };
/* memory allocation debugging: allocate a structure which holds
* allocation routines */
yajl_alloc_funcs allocFuncs = {
yajlTestMalloc,
yajlTestRealloc,
yajlTestFree,
(void *) NULL
};
allocFuncs.ctx = (void *) &memCtx;
/* check arguments. We expect exactly one! */
for (i=1;i<argc;i++) {
if (!strcmp("-c", argv[i])) {
@ -183,7 +240,7 @@ main(int argc, char ** argv)
fileName = argv[argc-1];
/* ok. open file. let's read and parse */
hand = yajl_alloc(&callbacks, &cfg, NULL);
hand = yajl_alloc(&callbacks, &cfg, &allocFuncs, NULL);
done = 0;
while (!done) {
@ -210,7 +267,7 @@ main(int argc, char ** argv)
unsigned char * str = yajl_get_error(hand, 0, fileData, rd);
fflush(stdout);
fprintf(stderr, (char *) str);
yajl_free_error(str);
yajl_free_error(hand, str);
break;
}
}
@ -218,5 +275,15 @@ main(int argc, char ** argv)
yajl_free(hand);
free(fileData);
/* finally, print out some memory statistics */
/* (lth) only print leaks here, as allocations and frees may vary depending
* on read buffer size, causing false failures.
*
* printf("allocations:\t%u\n", memCtx.numMallocs);
* printf("frees:\t\t%u\n", memCtx.numFrees);
*/
printf("memory leaks:\t%u\n", memCtx.numMallocs - memCtx.numFrees);
return 0;
}

View File

@ -1,4 +1,4 @@
# Copyright 2007, Lloyd Hilaiel.
# Copyright 2007-2009, Lloyd Hilaiel.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are

View File

@ -1,5 +1,5 @@
/*
* Copyright 2007, Lloyd Hilaiel.
* Copyright 2007-2009, Lloyd Hilaiel.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@ -80,7 +80,7 @@ main(int argc, char ** argv)
}
/* allocate a parser */
hand = yajl_alloc(NULL, &cfg, NULL);
hand = yajl_alloc(NULL, &cfg, NULL, NULL);
while (!done) {
rd = fread((void *) fileData, 1, sizeof(fileData) - 1, stdin);
@ -112,7 +112,7 @@ main(int argc, char ** argv)
if (!quiet) {
unsigned char * str = yajl_get_error(hand, 1, fileData, rd);
fprintf(stderr, (const char *) str);
yajl_free_error(str);
yajl_free_error(hand, str);
}
retval = 1;
break;