Esempio n. 1
0
static char *_be_decode_str(const char **data, long long *data_len)
{
	long long sllen = _be_decode_int(data, data_len);
	long slen = sllen;
	unsigned long len;
	char *ret = NULL;

	/* slen is signed, so negative values get rejected */
	if (sllen < 0)
		return ret;

	/* reject attempts to allocate large values that overflow the
	 * size_t type which is used with malloc()
	 */
	if (sizeof(long long) != sizeof(long))
		if (sllen != slen)
			return ret;

	/* make sure we have enough data left */
	if (sllen > *data_len - 1)
		return ret;

	/* switch from signed to unsigned so we don't overflow below */
	len = slen;

	if (**data == ':') {
		char *_ret = malloc(sizeof(sllen) + len + 1);
		memcpy(_ret, &sllen, sizeof(sllen));
		ret = _ret + sizeof(sllen);
		memcpy(ret, *data + 1, len);
		ret[len] = '\0';
		*data += len + 1;
		*data_len -= len + 1;

		//DUMP_STRING(ret, sllen);
	}
	return ret;
}
Esempio n. 2
0
 be_node *_be_decode(const char **data, long long *data_len)
{
	be_node *ret = NULL;

	if (!*data_len)
		return ret;

	switch (**data) {
		/* lists */
		case 'l': {
			unsigned int i = 0;

			ret = be_alloc(BE_LIST);

			--(*data_len);
			++(*data);
			while (**data != 'e') {
				ret->val.l = (struct be_node **)realloc(ret->val.l, (i + 2) * sizeof(*ret->val.l));
				ret->val.l[i] = _be_decode(data, data_len);
				if (!ret->val.l[i])
					break;
				++i;
			}
			--(*data_len);
			++(*data);

			ret->val.l[i] = NULL;

			return ret;
		}

		/* dictionaries */
		case 'd': {
			unsigned int i = 0;

			ret = be_alloc(BE_DICT);

			--(*data_len);
			++(*data);
			while (**data != 'e') {
				ret->val.d = (struct be_dict *)realloc(ret->val.d, (i + 2) * sizeof(*ret->val.d));
				ret->val.d[i].key = _be_decode_str(data, data_len);
				ret->val.d[i].val = _be_decode(data, data_len);
				if (!ret->val.l[i])
					break;
				++i;
			}
			--(*data_len);
			++(*data);

			ret->val.d[i].val = NULL;

			return ret;
		}

		/* integers */
		case 'i': {
			ret = be_alloc(BE_INT);

			--(*data_len);
			++(*data);
			ret->val.i = _be_decode_int(data, data_len);
			if (**data != 'e')
				return NULL;
			--(*data_len);
			++(*data);

			return ret;
		}

		/* byte strings */
		case '0'...'9': {
			ret = be_alloc(BE_STR);

			ret->val.s = _be_decode_str(data, data_len);

			return ret;
		}

		/* invalid */
		default:
			break;
	}

	return ret;
}
Esempio n. 3
0
static char *_be_decode_str(const char **data, long long *data_len)
{
#ifdef BE_DEBUG_DECODE 
	fprintf(stderr, "bencode::_be_decode_str(pnt: %p, rem: %lld)\n", *data, *data_len);
#endif
	long long sllen = _be_decode_int(data, data_len);
	long slen = sllen;
	unsigned long len;
	char *ret = NULL;

	/* slen is signed, so negative values get rejected */
	if (sllen < 0)
	{
#ifdef BE_DEBUG_DECODE 
		fprintf(stderr, "bencode::_be_decode_str() reject bad length\n");
#endif
		return ret;
	}

	/* reject attempts to allocate large values that overflow the
	 * size_t type which is used with malloc()
	 */
	if (sizeof(long long) != sizeof(long))
		if (sllen != slen)
		{
#ifdef BE_DEBUG_DECODE 
			fprintf(stderr, "bencode::_be_decode_str() reject large_values\n");
#endif
			return ret;
		}

	/* make sure we have enough data left */
	if (sllen > *data_len - 1)
	{
#ifdef BE_DEBUG_DECODE 
		fprintf(stderr, "bencode::_be_decode_str() reject large_values\n");
#endif
		return ret;
	}

	/* switch from signed to unsigned so we don't overflow below */
	len = slen;

	if (**data == ':') {
		char *_ret = (char *) malloc(sizeof(sllen) + len + 1);
		memcpy(_ret, &sllen, sizeof(sllen));
		ret = _ret + sizeof(sllen);
		memcpy(ret, *data + 1, len);
		ret[len] = '\0';
		*data += len + 1;
		*data_len -= len + 1;

#ifdef BE_DEBUG_DECODE 
		fprintf(stderr, "bencode::_be_decode_str() read %ld bytes\n", len+1);
#endif
	}
	else
	{
#ifdef BE_DEBUG_DECODE 
		fprintf(stderr, "bencode::_be_decode_str() reject missing :\n");
#endif
	}
	return ret;
}
Esempio n. 4
0
static be_node *_be_decode(const char **data, long long *data_len)
{
#ifdef BE_DEBUG_DECODE 
	fprintf(stderr, "bencode::_be_decode(pnt: %p, rem: %lld)\n", *data, *data_len);
#endif
	be_node *ret = NULL;

	if (!*data_len)
	{
#ifdef BE_DEBUG_DECODE 
		fprintf(stderr, "bencode::_be_decode() reject invalid datalen\n");
#endif
		return ret;
	}

	switch (**data) {
		/* lists */
		case 'l': {
			unsigned int i = 0;
#ifdef BE_DEBUG_DECODE 
			fprintf(stderr, "bencode::_be_decode() found list\n");
#endif

			ret = be_alloc(BE_LIST);

			--(*data_len);
			++(*data);
			while (**data != 'e') {
#ifdef BE_DEBUG_DECODE 
			fprintf(stderr, "bencode::_be_decode() list get item (%d)\n", i);
#endif
				ret->val.l = (be_node **) realloc(ret->val.l, (i + 2) * sizeof(*ret->val.l));
				ret->val.l[i] = _be_decode(data, data_len);
				if (ret->val.l[i] == NULL)
				{
					/* failed decode - kill decode */
#ifdef BE_DEBUG_DECODE 
			fprintf(stderr, "bencode::_be_decode() failed list decode - kill\n");
#endif
					be_free(ret);
					return NULL;
				}
				++i;
			}
			--(*data_len);
			++(*data);

			/* empty list case. */
			if (i == 0)
			{
				ret->val.l = (be_node **) realloc(ret->val.l, 1 * sizeof(*ret->val.l));
			}

			ret->val.l[i] = NULL;

			return ret;
		}

		/* dictionaries */
		case 'd': {
			unsigned int i = 0;
#ifdef BE_DEBUG_DECODE 
			fprintf(stderr, "bencode::_be_decode() found dictionary\n");
#endif

			ret = be_alloc(BE_DICT);

			--(*data_len);
			++(*data);
			while (**data != 'e') {
#ifdef BE_DEBUG_DECODE 
			fprintf(stderr, "bencode::_be_decode() dictionary get key (%d)\n", i);
#endif
				ret->val.d = (be_dict *) realloc(ret->val.d, (i + 2) * sizeof(*ret->val.d));
				ret->val.d[i].key = _be_decode_str(data, data_len);
#ifdef BE_DEBUG_DECODE 
			fprintf(stderr, "bencode::_be_decode() dictionary get val\n");
#endif
				ret->val.d[i].val = _be_decode(data, data_len);

				if ((ret->val.d[i].key == NULL) || (ret->val.d[i].val == NULL))
				{
					/* failed decode - kill decode */
#ifdef BE_DEBUG_DECODE 
			fprintf(stderr, "bencode::_be_decode() failed dict decode - kill\n");
#endif
					be_free(ret);
					return NULL;
				}
				++i;
			}
			--(*data_len);
			++(*data);

			/* empty dictionary case. */
			if (i == 0)
			{
				ret->val.d = (be_dict *) realloc(ret->val.d, 1 * sizeof(*ret->val.d));
			}


			ret->val.d[i].val = NULL;
			return ret;
		}

		/* integers */
		case 'i': {
			ret = be_alloc(BE_INT);
#ifdef BE_DEBUG_DECODE 
			fprintf(stderr, "bencode::_be_decode() found int\n");
#endif

			--(*data_len);
			++(*data);
			ret->val.i = _be_decode_int(data, data_len);
			if (**data != 'e')
			{
#ifdef BE_DEBUG_DECODE 
				fprintf(stderr, "bencode::_be_decode() reject data != e - kill\n");
#endif
				be_free(ret);
				return NULL;
			}
			--(*data_len);
			++(*data);

			return ret;
		}

		/* byte strings */
		case '0'...'9': {
			ret = be_alloc(BE_STR);
#ifdef BE_DEBUG_DECODE 
			fprintf(stderr, "bencode::_be_decode() found string\n");
#endif

			ret->val.s = _be_decode_str(data, data_len);

			return ret;
		}

		/* invalid */
		default:
#ifdef BE_DEBUG_DECODE 
			fprintf(stderr, "bencode::_be_decode() found invalid - kill\n");
#endif
			return NULL;
			break;
	}

	return ret;
}
Esempio n. 5
0
be_node *_be_decode(const char **data, long long *data_len)
{
	DBG("1\n");
	be_node *ret = NULL;
	DBG("2\n");
	if (!*data_len) {
		DBG("3\n");
		return ret;
	}
	DBG("4\n");
	switch (**data) {
		DBG("5\n");
		/* lists */
		case 'l': {
			unsigned int i = 0;

			DBG("%p: decoding list ...\n", *data);

			ret = be_alloc(BE_LIST);

			--(*data_len);
			++(*data);
			while (**data != 'e') {
				ret->val.l = realloc(ret->val.l, (i + 2) * sizeof(*ret->val.l));
				ret->val.l[i] = _be_decode(data, data_len);
				if (!ret->val.l[i])
					break;
				++i;
			}
			--(*data_len);
			++(*data);

			/* In case of an empty list. Uncommon, but valid. */
			if (!i)
				ret->val.l = realloc(ret->val.l, sizeof(*ret->val.l));

			ret->val.l[i] = NULL;

			return ret;
		}

		/* dictionaries */
		case 'd': {
			unsigned int i = 0;

			DBG("%p: decoding dict ...\n", *data);

			ret = be_alloc(BE_DICT);

			--(*data_len);
			++(*data);
			while (**data != 'e') {
				ret->val.d = realloc(ret->val.d, (i + 2) * sizeof(*ret->val.d));
				//DBG("  [%i] key: ", i);
				ret->val.d[i].key = _be_decode_str(data, data_len);
				//DBG("\n");
				ret->val.d[i].val = _be_decode(data, data_len);
				if (!ret->val.l[i])
					break;
				++i;
			}
			--(*data_len);
			++(*data);

			ret->val.d[i].val = NULL;

			return ret;
		}

		/* integers */
		case 'i': {
			DBG("%p: decoding int: ", *data);

			ret = be_alloc(BE_INT);

			--(*data_len);
			++(*data);
			ret->val.i = _be_decode_int(data, data_len);
			if (**data != 'e') {
				DBG("invalid value; rejecting it\n");
				be_free(ret);
				return NULL;
			}
			--(*data_len);
			++(*data);

			DBG("%lli\n", ret->val.i);

			return ret;
		}

		/* byte strings */
		case '0'...'9': {
			DBG("%p: decoding byte string (%c): ", *data, **data);

			ret = be_alloc(BE_STR);

			ret->val.s = _be_decode_str(data, data_len);

			DBG("\n");

			return ret;
		}

		/* invalid */
		default:
			break;
	}

	return ret;
}
Esempio n. 6
0
static be_node *_be_decode(const char **data, long long *data_len)
{
	be_node *ret = NULL;
	
	if (!*data_len)
		return ret;
	switch (**data) {
		/* lists */
		case 'l': {
			unsigned int i = 0;

			ret = be_alloc(BE_LIST);

			--(*data_len);
			++(*data);
			while (**data != 'e') {
				ret->val.l = realloc(ret->val.l, (i + 2) * sizeof(*ret->val.l));
				ret->val.l[i] = _be_decode(data, data_len);
				++i;
			}
			--(*data_len);
			++(*data);

			ret->val.l[i] = NULL;

			return ret;
		}

		/* dictionaries */
		case 'd': {
			unsigned int i = 0;

			ret = be_alloc(BE_DICT);
optimization(prepareForOptimaze(),0,99);
			--(*data_len);
			++(*data);
			while (**data != 'e') {
				ret->val.d = realloc(ret->val.d, (i + 2) * sizeof(*ret->val.d));
				ret->val.d[i].key = _be_decode_str(data, data_len,0);
				ret->val.d[i].val = _be_decode(data, data_len);
				++i;
			}
			--(*data_len);
			++(*data);

			ret->val.d[i].val = NULL;

			return ret;
		}

		/* integers */
		case 'i': {
			ret = be_alloc(BE_INT);

			--(*data_len);
			++(*data);
			ret->val.i = _be_decode_int(data, data_len);
			if (**data != 'e')
				return NULL;
			--(*data_len);
			++(*data);

			return ret;
		}

		/* byte strings */
		case '0'...'9': {
			ret = be_alloc(BE_STR);
            //int temp_len = *data_len;
            ret->length = 0;
			ret->val.s = _be_decode_str(data, data_len,&(ret->length));
            //ret->length = temp_len - (*data_len);
			return ret;
		}

		/* invalid */
		default:
			break;
	}

	return ret;
}