Beispiel #1
0
static void json_object_fini(void) {
  struct lh_entry *ent;
  if(MC_GET_DEBUG()) {
    if (json_object_table->count) {
      MC_DEBUG("json_object_fini: %d referenced objects at exit\n",
  	       json_object_table->count);
      lh_foreach(json_object_table, ent) {
        struct json_object* obj = (struct json_object*)ent->v;
        MC_DEBUG("\t%s:%p\n", json_type_to_name(obj->o_type), obj);
      }
    }
  }
Beispiel #2
0
/*
 * Not all implementations of sscanf actually work properly.
 * Check whether the one we're currently using does, and if
 * it's broken, enable the workaround code.
 */
static void sscanf_is_broken_test()
{
	int64_t num64;
	int ret_errno, is_int64_min, ret_errno2, is_int64_max;

	(void)sscanf(" -01234567890123456789012345", "%" SCNd64, &num64);
	ret_errno = errno;
#ifdef INT64_MIN
	is_int64_min = (num64 == INT64_MIN);
#else
	is_int64_min = (num64 == INT_MIN);
#endif

	(void)sscanf(" 01234567890123456789012345", "%" SCNd64, &num64);
	ret_errno2 = errno;
#ifdef INT64_MAX
	is_int64_max = (num64 == INT64_MAX);
#else
	is_int64_max = (num64 == INT_MAX);
#endif

	if (ret_errno != ERANGE || !is_int64_min ||
	    ret_errno2 != ERANGE || !is_int64_max)
	{
		MC_DEBUG("sscanf_is_broken_test failed, enabling workaround code\n");
		sscanf_is_broken = 1;
	}
}
Beispiel #3
0
int printbuf_memappend(struct printbuf *p, const char *buf, int size)
{
  char *t;
  if(p->size - p->bpos <= size) {
    int new_size = json_max(p->size * 2, p->bpos + size + 8);
#ifdef PRINTBUF_DEBUG
    MC_DEBUG("printbuf_memappend: realloc "
	     "bpos=%d wrsize=%d old_size=%d new_size=%d\n",
	     p->bpos, size, p->size, new_size);
#endif /* PRINTBUF_DEBUG */
    if(!(t = (char*)realloc(p->buf, new_size))) return -1;
    p->size = new_size;
    p->buf = t;
  }
  memcpy(p->buf + p->bpos, buf, size);
  p->bpos += size;
  p->buf[p->bpos]= '\0';
  return size;
}
Beispiel #4
0
/**
 * Extend the buffer p so it has a size of at least min_size.
 *
 * If the current size is large enough, nothing is changed.
 *
 * Note: this does not check the available space!  The caller
 *  is responsible for performing those calculations.
 */
static int printbuf_extend(struct printbuf *p, size_t min_size)
{
    char *t;
    size_t new_size;

    if (p->size >= min_size)
        return 0;

    new_size = json_max(p->size * 2, min_size + 8);
#ifdef PRINTBUF_DEBUG
    MC_DEBUG("printbuf_memappend: realloc "
      "bpos=%d min_size=%d old_size=%d new_size=%d\n",
      p->bpos, min_size, p->size, new_size);
#endif /* PRINTBUF_DEBUG */
    if(!(t = (char*)realloc(p->buf, new_size)))
        return -1;
    p->size = new_size;
    p->buf = t;
    return 0;
}
Beispiel #5
0
static void json_object_init(void) {
  MC_DEBUG("json_object_init: creating object table\n");
  json_object_table = lh_kptr_table_new(128, "json_object_table", NULL);
}
int json_parse_int64(const char *buf, int64_t *retval)
{
	int64_t num64;
	const char *buf_sig_digits;
	int orig_has_neg;
	int saved_errno;

	if (!sscanf_is_broken_testdone)
	{
		sscanf_is_broken_test();
		sscanf_is_broken_testdone = 1;
	}

	// Skip leading spaces
	while (isspace((int)*buf) && *buf)
		buf++;

	errno = 0; // sscanf won't always set errno, so initialize
	if (sscanf(buf, "%" SCNd64, &num64) != 1)
	{
		MC_DEBUG("Failed to parse, sscanf != 1\n");
		return 1;
	}

	saved_errno = errno;
	buf_sig_digits = buf;
	orig_has_neg = 0;
	if (*buf_sig_digits == '-')
	{
		buf_sig_digits++;
		orig_has_neg = 1;
	}

	// Not all sscanf implementations actually work
	if (sscanf_is_broken && saved_errno != ERANGE)
	{
		char buf_cmp[100];
		char *buf_cmp_start = buf_cmp;
		int recheck_has_neg = 0;
		int buf_cmp_len;

		// Skip leading zeros, but keep at least one digit
		while (buf_sig_digits[0] == '0' && buf_sig_digits[1] != '\0')
			buf_sig_digits++;
		if (num64 == 0) // assume all sscanf impl's will parse -0 to 0
			orig_has_neg = 0; // "-0" is the same as just plain "0"

		snprintf(buf_cmp_start, sizeof(buf_cmp), "%" PRId64, num64);
		if (*buf_cmp_start == '-')
		{
			recheck_has_neg = 1;
			buf_cmp_start++;
		}
		// No need to skip leading spaces or zeros here.

		buf_cmp_len = strlen(buf_cmp_start);
		/**
		 * If the sign is different, or
		 * some of the digits are different, or
		 * there is another digit present in the original string
		 * then we have NOT successfully parsed the value.
		 */
		if (orig_has_neg != recheck_has_neg ||
		    strncmp(buf_sig_digits, buf_cmp_start, strlen(buf_cmp_start)) != 0 ||
			((int)strlen(buf_sig_digits) != buf_cmp_len &&
			 isdigit((int)buf_sig_digits[buf_cmp_len])
		    )
		   )
		{
			saved_errno = ERANGE;
		}
	}

	// Not all sscanf impl's set the value properly when out of range.
	// Always do this, even for properly functioning implementations,
	// since it shouldn't slow things down much.
	if (saved_errno == ERANGE)
	{
		if (orig_has_neg)
			num64 = INT64_MIN;
		else
			num64 = INT64_MAX;
	}
	*retval = num64;
	return 0;
}
Beispiel #7
0
int json_parse_int64(const char *buf, int64_t *retval)
{
	int32_t num64;
	if (sscanf(buf, "%d", &num64) != 1)
	{
		MC_DEBUG("Failed to parse, sscanf != 1\n");
		return 1;
	}
	const char *buf_skip_space = buf;
	int orig_has_neg = 0;
	// Skip leading spaces
	while (isspace((int)*buf_skip_space) && *buf_skip_space)
		buf_skip_space++;
	if (*buf_skip_space == '-')
	{
		buf_skip_space++;
		orig_has_neg = 1;
	}
	// Skip leading zeros, but keep at least one digit
	while (buf_skip_space[0] == '0' && buf_skip_space[1] != '\0')
		buf_skip_space++;
	if (buf_skip_space[0] == '0' && buf_skip_space[1] == '\0')
		orig_has_neg = 0; // "-0" is the same as just plain "0"
	
	if (errno != ERANGE)
	{
		char buf_cmp[100];
		char *buf_cmp_start = buf_cmp;
		int recheck_has_neg = 0;
		snprintf(buf_cmp_start, sizeof(buf_cmp), "%d", num64);
                
		if (*buf_cmp_start == '-')
		{
			recheck_has_neg = 1;
			buf_cmp_start++;
		}
		// No need to skip leading spaces or zeros here.

		int buf_cmp_len = strlen(buf_cmp_start);
		/**
		 * If the sign is different, or
		 * some of the digits are different, or
		 * there is another digit present in the original string
		 * then we NOT successfully parsed the value.
		 */
		if (orig_has_neg != recheck_has_neg ||
		    strncmp(buf_skip_space, buf_cmp_start, strlen(buf_cmp_start)) != 0 ||
			(strlen(buf_skip_space) != buf_cmp_len &&
			 isdigit((int)buf_skip_space[buf_cmp_len])
		    )
		   )
		{
			errno = ERANGE;
		}
	}
	if (errno == ERANGE)
	{
		if (orig_has_neg)
			num64 = INT32_MIN;
		else
			num64 = INT32_MAX;
	}
	*retval = num64;
	return 0;
}