Beispiel #1
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;
}
Beispiel #2
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;
}
Beispiel #3
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;
}
Beispiel #4
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;
}