WBXML: add a basic sanity check for offset overflow

This is a naive approach allowing to detact that something went wrong,
without the need to replace all proto_tree_add_text() calls as what was
done in master-2.0 branch.

Bug: 12408
Change-Id: Ia14905005e17ae322c2fc639ad5e491fa08b0108
Reviewed-on: https://code.wireshark.org/review/15310
Reviewed-by: Michael Mann <mmann78@netscape.net>
Reviewed-by: Pascal Quantin <pascal.quantin@gmail.com>
wv_datetime_from_opaque(tvbuff_t *tvb, guint32 offset, guint32 data_len)
{
	char *str;
	guint16 year;
	guint8 month, day, hour, minute, second, time_zone;
	guint8 peek;

	if (data_len == 6) { /* Valid */

		/* Octet 1: 00YY YYYY */
		year = tvb_get_guint8(tvb, offset) & 0x3F; /* ..11 1111 */
		year <<=6;
		/* Octet 2: YYYY YYMM */
		peek = tvb_get_guint8(tvb, offset + 1);
		year += (peek >> 2); /* 1111 11.. */
		month = (peek & 0x03) << 2; /* .... ..11 */
		/* Octet 3: MMDD DDDh */
		peek = tvb_get_guint8(tvb, offset + 2);
		month += (peek >> 6); /* 11.. .... */
		day = (peek & 0x3E) >> 1; /* ..11 111. */
		hour = (peek & 0x01) << 4; /* .... ...1 */
		/* Octet 4: hhhh mmmm */
		peek = tvb_get_guint8(tvb, offset + 3);
		hour += (peek >> 4);
		minute = (peek & 0x0F) << 2; /* .... 1111 */
		/* Octet 5: mmss ssss */
		peek = tvb_get_guint8(tvb, offset + 4);
		minute += (peek >> 6); /* 11.. .... */
		second = peek & 0x3F; /* ..11 1111 */
		/* octet 6: ZZZZZZZZ */
		time_zone = tvb_get_guint8(tvb, offset + 5);
		/* Now construct the string */
		str = wmem_strdup_printf(wmem_packet_scope(), "WV-CSP DateTime: "
				      "%04d-%02d-%02dT%02d:%02d:%02d%c",
				      year, month, day, hour, minute, second, time_zone);
	} else { /* Invalid length for a WV-CSP DateTime tag value */
		str = wmem_strdup_printf(wmem_packet_scope(), "<Error: invalid binary WV-CSP DateTime value "
				      "(%d bytes of opaque data)>", data_len);
	}
	return str;
}

wv_datetime_from_opaque(tvbuff_t *tvb, guint32 offset, guint32 data_len)
{
	char *str;
	guint16 year;
	guint8 month, day, hour, minute, second, time_zone;
	guint8 peek;

	if (data_len == 6) { /* Valid */

		/* Octet 1: 00YY YYYY */
		year = tvb_get_guint8(tvb, offset) & 0x3F; /* ..11 1111 */
		year <<=6;
		/* Octet 2: YYYY YYMM */
		peek = tvb_get_guint8(tvb, offset + 1);
		year += (peek >> 2); /* 1111 11.. */
		month = (peek & 0x03) << 2; /* .... ..11 */
		/* Octet 3: MMDD DDDh */
		peek = tvb_get_guint8(tvb, offset + 2);
		month += (peek >> 6); /* 11.. .... */
		day = (peek & 0x3E) >> 1; /* ..11 111. */
		hour = (peek & 0x01) << 4; /* .... ...1 */
		/* Octet 4: hhhh mmmm */
		peek = tvb_get_guint8(tvb, offset + 3);
		hour += (peek >> 4);
		minute = (peek & 0x0F) << 2; /* .... 1111 */
		/* Octet 5: mmss ssss */
		peek = tvb_get_guint8(tvb, offset + 4);
		minute += (peek >> 6); /* 11.. .... */
		second = peek & 0x3F; /* ..11 1111 */
		/* octet 6: ZZZZZZZZ */
		time_zone = tvb_get_guint8(tvb, offset + 5);
		/* Now construct the string */
		str = wmem_strdup_printf(wmem_packet_scope(), "WV-CSP DateTime: "
				      "%04d-%02d-%02dT%02d:%02d:%02d%c",
				      year, month, day, hour, minute, second, time_zone);
	} else { /* Invalid length for a WV-CSP DateTime tag value */
		str = wmem_strdup_printf(wmem_packet_scope(), "<Error: invalid binary WV-CSP DateTime value "
				      "(%d bytes of opaque data)>", data_len);
	}
	return str;
}
