Exemple #1
0
// this function compares labels in label format:
//   [length] [value ...] [length] [value ...] [0]
static int matchlabel(const unsigned char *a, int asize, const unsigned char *b, int bsize, const unsigned char *ref, int refsize, int ahopsleft, int bhopsleft)
{
	int n, alen, blen, offset;

	// same pointer?
	if(a == b)
		return 1;

	if(asize < 1 || bsize < 1)
		return 0;

	// always ensure we get called without a pointer
	if(*a & 0xc0)
	{
		if(asize < 2)
			return 0;
		offset = getoffset(a, refsize, &ahopsleft);
		if(offset == -1)
			return 0;
		return matchlabel(ref + offset, refsize - offset, b, bsize, ref, refsize, ahopsleft, bhopsleft);
	}
	if(*b & 0xc0)
	{
		if(bsize < 2)
			return 0;
		offset = getoffset(b, refsize, &bhopsleft);
		if(offset == -1)
			return 0;
		return matchlabel(a, asize, ref + offset, refsize - offset, ref, refsize, ahopsleft, bhopsleft);
	}

	alen = *a & 0x3f;
	blen = *b & 0x3f;

	// must be same length
	if(alen != blen)
		return 0;

	// done?
	if(alen == 0)
		return 1;

	// length byte + length + first byte of next label
	if(asize < alen + 2)
		return 0;
	if(bsize < blen + 2)
		return 0;

	// compare the value
	for(n = 1; n < alen + 1; ++n)
	{
		if(a[n] != b[n])
			return 0;
	}

	// try next labels
	n = alen + 1;
	return matchlabel(a + n, asize - n, b + n, bsize - n, ref, refsize, ahopsleft, bhopsleft);
}
Exemple #2
0
static js_Ast *continuetarget(JF, js_Ast *node, const char *label)
{
	while (node) {
		if (isfun(node->type))
			break;
		if (isloop(node->type)) {
			if (!label)
				return node;
			else if (matchlabel(node->parent, label))
				return node;
		}
		node = node->parent;
	}
	return NULL;
}
Exemple #3
0
static js_Ast *breaktarget(JF, js_Ast *node, const char *label)
{
	while (node) {
		if (isfun(node->type))
			break;
		if (!label) {
			if (isloop(node->type) || node->type == STM_SWITCH)
				return node;
		} else {
			if (matchlabel(node->parent, label))
				return node;
		}
		node = node->parent;
	}
	return NULL;
}
Exemple #4
0
// lookup list is made of jdns_packet_labels
static int writelabel(const jdns_string_t *name, int at, int left, unsigned char **bufp, jdns_list_t *lookup)
{
	unsigned char label[MAX_LABEL_LENGTH];
	int n, i, len;
	unsigned char *l;
	unsigned char *ref;
	int refsize;

	len = name_to_label(name, label);
	if(len == -1)
		return 0;

	ref = *bufp - at;
	refsize = at + left;
	for(n = 0; label[n]; n += label[n] + 1)
	{
		for(i = 0; i < lookup->count; ++i)
		{
			jdns_packet_label_t *pl = (jdns_packet_label_t *)lookup->item[i];

			if(matchlabel(label + n, len - n, pl->value->data, pl->value->size, ref, refsize, 8, 8))
			{
				// set up a pointer right here, overwriting
				//   the length byte and the first content
				//   byte of this section within 'label'.
				//   this is safe, because the length value
				//   will always be greater than zero,
				//   ensuring we have two bytes available to
				//   use.
				l = label + n;
				short2net((unsigned short int)pl->offset, &l);
				label[n] |= 0xc0;
				len = n + 2; // cut things short
				break;
			}
		}
		if(label[n] & 0xc0) // double loop, so break again
			break;
	}

	if(left < len)
		return 0;

	// copy into buffer, point there now
	memcpy(*bufp, label, len);
	l = *bufp;
	*bufp += len;

	// for each new label, store its location for future compression
	for(n = 0; l[n]; n += l[n] + 1)
	{
		jdns_string_t *str;
		jdns_packet_label_t *pl;
		if(l[n] & 0xc0)
			break;

		pl = jdns_packet_label_new();
		str = jdns_string_new();
		jdns_string_set(str, l + n, len - n);
		pl->offset = l + n - ref;
		pl->value = str;
		jdns_list_insert(lookup, pl, -1);
	}

	return 1;
}