Example #1
0
const char *
_munpack_item(const char *p, size_t len, SV **res, HV *ext, int utf)
{
	if (!len || !p)
		croak("Internal error: out of pointer");

	const char *pe = p + len;

	switch(mp_typeof(*p)) {
		case MP_UINT:
			*res = newSViv( mp_decode_uint(&p) );
			break;
		case MP_INT:
			*res = newSViv( mp_decode_int(&p) );
			break;
		case MP_FLOAT:
			*res = newSVnv( mp_decode_float(&p) );
			break;
		case MP_DOUBLE:
			*res = newSVnv( mp_decode_double(&p) );
			break;
		case MP_STR: {
			const char *s;
			uint32_t len;
			s = mp_decode_str(&p, &len);
			*res = newSVpvn_flags(s, len, utf ? SVf_UTF8 : 0);
			break;
		}
		case MP_NIL: {
			mp_decode_nil(&p);
			*res = newSV(0);
			break;
		}
		case MP_BOOL:
			if (mp_decode_bool(&p)) {
				*res = newSViv(1);
			} else {
				*res = newSViv(0);
			}
			break;
		case MP_MAP: {
			uint32_t l, i;
			l = mp_decode_map(&p);
			HV * h = newHV();
			sv_2mortal((SV *)h);
			for (i = 0; i < l; i++) {
				SV *k = 0;
				SV *v = 0;
				if (p >= pe)
					croak("Unexpected EOF msgunpack str");
				p = _munpack_item(p, pe - p, &k, ext, utf);
				sv_2mortal(k);
				if (p >= pe)
					croak("Unexpected EOF msgunpack str");
				p = _munpack_item(p, pe - p, &v, ext, utf);
				hv_store_ent(h, k, v, 0);
			}
			*res = newRV((SV *)h);
			break;
		}
		case MP_ARRAY: {
			uint32_t l, i;
			l = mp_decode_array(&p);
			AV *a = newAV();
			sv_2mortal((SV *)a);
			for (i = 0; i < l; i++) {
				SV *item = 0;
				if (p >= pe)
					croak("Unexpected EOF msgunpack str");
				p = _munpack_item(p, pe - p, &item, ext, utf);
				av_push(a, item);

			}
			*res = newRV((SV *)a);
			break;
		}
		case MP_EXT: {
			croak("Isn't defined yet");
		}
		default:
			croak("Unexpected symbol 0x%02x", 0xFF & (int)(*p));

	}
	return p;
}
Example #2
0
static int
test_format(void)
{
	plan(282);
	header();

	const size_t buf_size = 1024;
	char buf[buf_size];
	size_t sz;
	const char *fmt;
	const char *p, *c, *e;
	uint32_t len = 0;

	fmt = "%d %u %i  %ld %lu %li  %lld %llu %lli"
	      "%hd %hu %hi  %hhd %hhu %hhi";
	sz = mp_format(buf, buf_size, fmt, 1, 2, 3,
		       (long)4, (long)5, (long)6,
		       (long long)7, (long long)8, (long long)9,
		       (short)10, (short)11, (short)12,
		       (char)13, (char)14, (char)15);
	p = buf;
	for (unsigned i = 0; i < 15; i++) {
		ok(mp_typeof(*p) == MP_UINT, "Test type on step %d", i);
		ok(mp_decode_uint(&p) == i + 1, "Test value on step %d", i);
	}
	sz = mp_format(buf, buf_size, fmt, -1, -2, -3,
		       (long)-4, (long)-5, (long)-6,
		       (long long)-7, (long long)-8, (long long)-9,
		       (short)-10, (unsigned short)-11, (short)-12,
		       (signed char)-13, (unsigned char)-14, (signed char)-15);
	p = buf;
	for (int i = 0; i < 15; i++) {
		uint64_t expects[5] = { UINT_MAX - 1,
					ULONG_MAX - 4,
					ULLONG_MAX - 7,
					USHRT_MAX - 10,
					UCHAR_MAX - 13 };
		if (i % 3 == 1) {
			ok(mp_typeof(*p) == MP_UINT, "Test type on step %d", i);
			ok(mp_decode_uint(&p) == expects[i / 3],
			   "Test value on step %d", i);
		} else {
			ok(mp_typeof(*p) == MP_INT, "Test type on step %d", i);
			ok(mp_decode_int(&p) == - i - 1,
			   "Test value on step %d", i);
		}
	}

	char data1[32];
	char *data1_end = data1;
	data1_end = mp_encode_array(data1_end, 2);
	data1_end = mp_encode_str(data1_end, "ABC", 3);
	data1_end = mp_encode_uint(data1_end, 11);
	size_t data1_len = data1_end - data1;
	assert(data1_len <= sizeof(data1));

	char data2[32];
	char *data2_end = data2;
	data2_end = mp_encode_int(data2_end, -1234567890);
	data2_end = mp_encode_str(data2_end, "DEFGHIJKLMN", 11);
	data2_end = mp_encode_uint(data2_end, 321);
	size_t data2_len = data2_end - data2;
	assert(data2_len <= sizeof(data2));

	fmt = "%d NIL [%d %b %b] this is test"
		"[%d %%%% [[ %d {%s %f %%  %.*s %lf %.*s NIL}"
		"%p %d %.*p ]] %d%d%d]";
#define TEST_PARAMS 0, 1, true, false, -1, 2, \
	"flt", 0.1, 6, "double#ignored", 0.2, 0, "ignore", \
	data1, 3, data2_len, data2, 4, 5, 6
	sz = mp_format(buf, buf_size, fmt, TEST_PARAMS);
	p = buf;
	e = buf + sz;

	c = p;
	ok(mp_check(&c, e) == 0, "check");
	ok(mp_typeof(*p) == MP_UINT, "type");
	ok(mp_decode_uint(&p) == 0, "decode");

	c = p;
	ok(mp_check(&c, e) == 0, "check");
	ok(mp_typeof(*p) == MP_NIL, "type");
	mp_decode_nil(&p);

	c = p;
	ok(mp_check(&c, e) == 0, "check");
	ok(mp_typeof(*p) == MP_ARRAY, "type");
	ok(mp_decode_array(&p) == 3, "decode");

	c = p;
	ok(mp_check(&c, e) == 0, "check");
	ok(mp_typeof(*p) == MP_UINT, "type");
	ok(mp_decode_uint(&p) == 1, "decode");

	c = p;
	ok(mp_check(&c, e) == 0, "check");
	ok(mp_typeof(*p) == MP_BOOL, "type");
	ok(mp_decode_bool(&p) == true, "decode");

	c = p;
	ok(mp_check(&c, e) == 0, "check");
	ok(mp_typeof(*p) == MP_BOOL, "type");
	ok(mp_decode_bool(&p) == false, "decode");

	c = p;
	ok(mp_check(&c, e) == 0, "check");
	ok(mp_typeof(*p) == MP_ARRAY, "type");
	ok(mp_decode_array(&p) == 5, "decode");

	c = p;
	ok(mp_check(&c, e) == 0, "check");
	ok(mp_typeof(*p) == MP_INT, "type");
	ok(mp_decode_int(&p) == -1, "decode");

	c = p;
	ok(mp_check(&c, e) == 0, "check");
	ok(mp_typeof(*p) == MP_ARRAY, "type");
	ok(mp_decode_array(&p) == 1, "decode");

	c = p;
	ok(mp_check(&c, e) == 0, "check");
	ok(mp_typeof(*p) == MP_ARRAY, "type");
	ok(mp_decode_array(&p) == 5, "decode");

	c = p;
	ok(mp_check(&c, e) == 0, "check");
	ok(mp_typeof(*p) == MP_UINT, "type");
	ok(mp_decode_uint(&p) == 2, "decode");

	c = p;
	ok(mp_check(&c, e) == 0, "check");
	ok(mp_typeof(*p) == MP_MAP, "type");
	ok(mp_decode_map(&p) == 3, "decode");

	c = p;
	ok(mp_check(&c, e) == 0, "check");
	ok(mp_typeof(*p) == MP_STR, "type");
	c = mp_decode_str(&p, &len);
	ok(len == 3, "decode");
	ok(memcmp(c, "flt", 3) == 0, "compare");

	c = p;
	ok(mp_check(&c, e) == 0, "check");
	ok(mp_typeof(*p) == MP_FLOAT, "type");
	ok(fequal(mp_decode_float(&p), 0.1), "decode");

	c = p;
	ok(mp_check(&c, e) == 0, "check");
	ok(mp_typeof(*p) == MP_STR, "type");
	c = mp_decode_str(&p, &len);
	ok(len == 6, "decode");
	ok(memcmp(c, "double", 6) == 0, "compare");

	c = p;
	ok(mp_check(&c, e) == 0, "check");
	ok(mp_typeof(*p) == MP_DOUBLE, "type");
	ok(dequal(mp_decode_double(&p), 0.2), "decode");

	c = p;
	ok(mp_check(&c, e) == 0, "check");
	ok(mp_typeof(*p) == MP_STR, "type");
	c = mp_decode_str(&p, &len);
	ok(len == 0, "decode");

	c = p;
	ok(mp_check(&c, e) == 0, "check");
	ok(mp_typeof(*p) == MP_NIL, "type");
	mp_decode_nil(&p);

	c = p;
	ok(mp_check(&c, e) == 0, "check");
	ok(((size_t)(c - p) == data1_len) &&
	   memcmp(p, data1, data1_len) == 0, "compare");
	p = c;

	c = p;
	ok(mp_check(&c, e) == 0, "check");
	ok(mp_typeof(*p) == MP_UINT, "type");
	ok(mp_decode_uint(&p) == 3, "decode");

	c = p;
	ok(mp_check(&c, e) == 0, "check");
	ok(mp_typeof(*p) == MP_INT, "type");
	ok(mp_decode_int(&p) == -1234567890, "decode");

	c = p;
	ok(mp_check(&c, e) == 0, "check");
	ok(mp_typeof(*p) == MP_STR, "type");
	c = mp_decode_str(&p, &len);
	ok(len == 11, "decode");
	ok(memcmp(c, "DEFGHIJKLMN", 11) == 0, "compare");

	c = p;
	ok(mp_check(&c, e) == 0, "check");
	ok(mp_typeof(*p) == MP_UINT, "type");
	ok(mp_decode_uint(&p) == 321, "decode");

	c = p;
	ok(mp_check(&c, e) == 0, "check");
	ok(mp_typeof(*p) == MP_UINT, "type");
	ok(mp_decode_uint(&p) == 4, "decode");

	c = p;
	ok(mp_check(&c, e) == 0, "check");
	ok(mp_typeof(*p) == MP_UINT, "type");
	ok(mp_decode_uint(&p) == 5, "decode");

	c = p;
	ok(mp_check(&c, e) == 0, "check");
	ok(mp_typeof(*p) == MP_UINT, "type");
	ok(mp_decode_uint(&p) == 6, "decode");

	ok(p == e, "nothing more");

	ok(sz < 70, "no magic detected");

	for (size_t lim = 0; lim <= 70; lim++) {
		memset(buf, 0, buf_size);
		size_t test_sz = mp_format(buf, lim, fmt, TEST_PARAMS);
		ok(test_sz == sz, "return value on step %d", (int)lim);
		bool all_zero = true;
		for(size_t z = lim; z < buf_size; z++)
			all_zero = all_zero && (buf[z] == 0);
		ok(all_zero, "buffer overflow on step %d", (int)lim);

	}

#undef TEST_PARAMS

	footer();
	return check_plan();
}
Example #3
0
static int
opt_set(void *opts, const struct opt_def *def, const char **val,
	struct region *region, uint32_t errcode, uint32_t field_no)
{
	int64_t ival;
	uint64_t uval;
	char *errmsg = tt_static_buf();
	double dval;
	uint32_t str_len;
	const char *str;
	char *ptr;
	char *opt = ((char *) opts) + def->offset;
	switch (def->type) {
	case OPT_BOOL:
		if (mp_typeof(**val) != MP_BOOL)
			goto type_mismatch_err;
		store_bool(opt, mp_decode_bool(val));
		break;
	case OPT_UINT32:
		if (mp_typeof(**val) != MP_UINT)
			goto type_mismatch_err;
		uval = mp_decode_uint(val);
		if (uval > UINT32_MAX)
			goto type_mismatch_err;
		store_u32(opt, uval);
		break;
	case OPT_INT64:
		if (mp_read_int64(val, &ival) != 0)
			goto type_mismatch_err;
		store_u64(opt, ival);
		break;
	case OPT_FLOAT:
		if (mp_read_double(val, &dval) != 0)
			goto type_mismatch_err;
		store_double(opt, dval);
		break;
	case OPT_STR:
		if (mp_typeof(**val) != MP_STR)
			goto type_mismatch_err;
		str = mp_decode_str(val, &str_len);
		str_len = MIN(str_len, def->len - 1);
		memcpy(opt, str, str_len);
		opt[str_len] = '\0';
		break;
	case OPT_STRPTR:
		if (mp_typeof(**val) != MP_STR)
			goto type_mismatch_err;
		str = mp_decode_str(val, &str_len);
		if (str_len > 0) {
			ptr = (char *) region_alloc(region, str_len + 1);
			if (ptr == NULL) {
				diag_set(OutOfMemory, str_len + 1, "region",
					 "opt string");
				return -1;
			}
			memcpy(ptr, str, str_len);
			ptr[str_len] = '\0';
			assert (strlen(ptr) == str_len);
		} else {
			ptr = NULL;
		}
		*(const char **)opt = ptr;
		break;
	case OPT_ENUM:
		if (mp_typeof(**val) != MP_STR)
			goto type_mismatch_err;
		str = mp_decode_str(val, &str_len);
		if (def->to_enum == NULL) {
			ival = strnindex(def->enum_strs, str, str_len,
					 def->enum_max);
		} else {
			ival = def->to_enum(str, str_len);
		}
		switch(def->enum_size) {
		case sizeof(uint8_t):
			store_u8(opt, (uint8_t)ival);
			break;
		case sizeof(uint16_t):
			store_u16(opt, (uint16_t)ival);
			break;
		case sizeof(uint32_t):
			store_u32(opt, (uint32_t)ival);
			break;
		case sizeof(uint64_t):
			store_u64(opt, (uint64_t)ival);
			break;
		default:
			unreachable();
		};
		break;
	case OPT_ARRAY:
		if (mp_typeof(**val) != MP_ARRAY)
			goto type_mismatch_err;
		ival = mp_decode_array(val);
		assert(def->to_array != NULL);
		if (def->to_array(val, ival, opt, errcode, field_no) != 0)
			return -1;
		break;
	case OPT_LEGACY:
		mp_next(val);
		break;
	default:
		unreachable();
	}
	return 0;

type_mismatch_err:
	snprintf(errmsg, TT_STATIC_BUF_LEN, "'%s' must be %s", def->name,
		 opt_type_strs[def->type]);
	diag_set(ClientError, errcode, field_no, errmsg);
	return -1;
}