SPOOLSS: Try to avoid an infinite loop.

Use tvb_reported_length_remaining in dissect_spoolss_uint16uni. Make
sure our offset always increments in dissect_spoolss_keybuffer.

Change-Id: I7017c9685bb2fa27161d80a03b8fca4ef630e793
Reviewed-on: https://code.wireshark.org/review/14687
Reviewed-by: Gerald Combs <gerald@wireshark.org>
Petri-Dish: Gerald Combs <gerald@wireshark.org>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Michael Mann <mmann78@netscape.net>
cb_notify_str_postprocess(packet_info *pinfo _U_,
				      proto_tree *tree _U_,
				      proto_item *item, dcerpc_info *di _U_, tvbuff_t *tvb,
				      int start_offset, int end_offset,
				      void *callback_args)
{
	gint levels, hf_index = GPOINTER_TO_INT(callback_args);
	guint32 len;
	char *s;
	proto_item *hidden_item;

	/* Align start_offset on 4-byte boundary. */

	if (start_offset % 4)
		start_offset += 4 - (start_offset % 4);

	/* Get string length */

	len = tvb_get_letohl(tvb, start_offset);

	s = tvb_get_string_enc(NULL,
		tvb, start_offset + 4, (end_offset - start_offset - 4), ENC_UTF_16|ENC_LITTLE_ENDIAN);

	/* Append string to upper-level proto_items */

	levels = 2;

	if (levels > 0 && item && s && s[0]) {
		proto_item_append_text(item, ": %s", s);
		item = item->parent;
		levels--;
		if (levels > 0) {
			proto_item_append_text(item, ": %s", s);
			item = item->parent;
			levels--;
			while (levels > 0) {
				proto_item_append_text(item, " %s", s);
				item = item->parent;
				levels--;
			}
		}
	}

	/* Add hidden field so filter brings up any notify data */

	if (hf_index != -1) {
		hidden_item = proto_tree_add_string(
			tree, hf_index, tvb, start_offset, len, s);
		PROTO_ITEM_SET_HIDDEN(hidden_item);
	}

	g_free(s);
}

cb_notify_str_postprocess(packet_info *pinfo _U_,
				      proto_tree *tree _U_,
				      proto_item *item, dcerpc_info *di _U_, tvbuff_t *tvb,
				      int start_offset, int end_offset,
				      void *callback_args)
{
	gint levels, hf_index = GPOINTER_TO_INT(callback_args);
	guint32 len;
	char *s;
	proto_item *hidden_item;

	/* Align start_offset on 4-byte boundary. */

	if (start_offset % 4)
		start_offset += 4 - (start_offset % 4);

	/* Get string length */

	len = tvb_get_letohl(tvb, start_offset);

	s = tvb_get_string_enc(NULL,
		tvb, start_offset + 4, (end_offset - start_offset - 4), ENC_UTF_16|ENC_LITTLE_ENDIAN);

	/* Append string to upper-level proto_items */

	levels = 2;

	if (levels > 0 && item && s && s[0]) {
		proto_item_append_text(item, ": %s", s);
		item = item->parent;
		levels--;
		if (levels > 0) {
			proto_item_append_text(item, ": %s", s);
			item = item->parent;
			levels--;
			while (levels > 0) {
				proto_item_append_text(item, " %s", s);
				item = item->parent;
				levels--;
			}
		}
	}

	/* Add hidden field so filter brings up any notify data */

	if (hf_index != -1) {
		hidden_item = proto_tree_add_string(
			tree, hf_index, tvb, start_offset, len, s);
		PROTO_ITEM_SET_HIDDEN(hidden_item);
	}

	g_free(s);
}
