added stack checking into ber_skip_length also

diff --git a/skeletons/ber_decoder.c b/skeletons/ber_decoder.c
index 95d7101..f932b3b 100644
--- a/skeletons/ber_decoder.c
+++ b/skeletons/ber_decoder.c
@@ -71,10 +71,12 @@
 	int step = opt_ctx ? opt_ctx->step : 0;	/* Where we left previously */
 	int tagno;
 
+	/*
+	 * Make sure we didn't exceed the maximum stack size.
+	 */
 	if(opt_codec_ctx && opt_codec_ctx->max_stack_size) {
 		ptrdiff_t usedstack = ((char *)opt_codec_ctx - (char *)&size);
-		/* do not change the semantics:
-		 * double negative is required to avoid int wrap-around */
+		/* double negative is required to avoid int wrap-around */
 		if(usedstack > 0) usedstack = -usedstack;
 		ASN_DEBUG("Current stack size %ld", -(long)usedstack);
 		if(usedstack < -(ptrdiff_t)opt_codec_ctx->max_stack_size) {
diff --git a/skeletons/ber_tlv_length.c b/skeletons/ber_tlv_length.c
index a0ec1e5..10a9e1c 100644
--- a/skeletons/ber_tlv_length.c
+++ b/skeletons/ber_tlv_length.c
@@ -74,13 +74,29 @@
 }
 
 ssize_t
-ber_skip_length(int _is_constructed, void *ptr, size_t size) {
+ber_skip_length(asn_codec_ctx_t *opt_codec_ctx,
+		int _is_constructed, void *ptr, size_t size) {
 	ber_tlv_len_t vlen;	/* Length of V in TLV */
 	ssize_t tl;		/* Length of L in TLV */
 	ssize_t ll;		/* Length of L in TLV */
 	size_t skip;
 
 	/*
+	 * Make sure we didn't exceed the maximum stack size.
+	 */
+	if(opt_codec_ctx && opt_codec_ctx->max_stack_size) {
+		ptrdiff_t usedstack = ((char *)opt_codec_ctx - (char *)&size);
+		/* double negative is required to avoid int wrap-around */
+		if(usedstack > 0) usedstack = -usedstack;
+		ASN_DEBUG("Current stack size %ld", -(long)usedstack);
+		if(usedstack < -(ptrdiff_t)opt_codec_ctx->max_stack_size) {
+			ASN_DEBUG("Stack limit %ld reached",
+				(long)opt_codec_ctx->max_stack_size);
+			return -1;
+		}
+	}
+
+	/*
 	 * Determine the size of L in TLV.
 	 */
 	ll = ber_fetch_length(_is_constructed, ptr, size, &vlen);
@@ -107,7 +123,8 @@
 		tl = ber_fetch_tag(ptr, size, &tag);
 		if(tl <= 0) return tl;
 
-		ll = ber_skip_length(BER_TLV_CONSTRUCTED(ptr),
+		ll = ber_skip_length(opt_codec_ctx,
+			BER_TLV_CONSTRUCTED(ptr),
 			((char *)ptr) + tl, size - tl);
 		if(ll <= 0) return ll;
 
diff --git a/skeletons/ber_tlv_length.h b/skeletons/ber_tlv_length.h
index 5222bbf..9d99e66 100644
--- a/skeletons/ber_tlv_length.h
+++ b/skeletons/ber_tlv_length.h
@@ -27,7 +27,10 @@
  * RETURN VALUES:
  * 	Standard {-1,0,>0} convention.
  */
-ssize_t ber_skip_length(int _is_constructed, void *bufptr, size_t size);
+struct asn_codec_ctx_s;	/* Forward declaration */
+ssize_t ber_skip_length(
+	struct asn_codec_ctx_s *opt_codec_ctx,	/* optional context */
+	int _is_constructed, void *bufptr, size_t size);
 
 /*
  * This function serializes the length (L from TLV) in DER format.
diff --git a/skeletons/constr_CHOICE.c b/skeletons/constr_CHOICE.c
index ab15846..4db6d7b 100644
--- a/skeletons/constr_CHOICE.c
+++ b/skeletons/constr_CHOICE.c
@@ -209,7 +209,7 @@
 				ASN_DEBUG("Skipping unknown tag %s",
 					ber_tlv_tag_string(tlv_tag));
 
-				skip = ber_skip_length(
+				skip = ber_skip_length(opt_codec_ctx,
 					BER_TLV_CONSTRUCTED(ptr),
 					(char *)ptr + tag_len, LEFT - tag_len);
 
diff --git a/skeletons/constr_SEQUENCE.c b/skeletons/constr_SEQUENCE.c
index 740ce57..07c7772 100644
--- a/skeletons/constr_SEQUENCE.c
+++ b/skeletons/constr_SEQUENCE.c
@@ -352,7 +352,7 @@
 				/* Skip this tag */
 				ssize_t skip;
 
-				skip = ber_skip_length(
+				skip = ber_skip_length(opt_codec_ctx,
 					BER_TLV_CONSTRUCTED(ptr),
 					(char *)ptr + tag_len, LEFT - tag_len);
 				ASN_DEBUG("Skip length %d in %s",
@@ -474,7 +474,7 @@
 				RETURN(RC_FAIL);
 			}
 
-			ll = ber_skip_length(
+			ll = ber_skip_length(opt_codec_ctx,
 				BER_TLV_CONSTRUCTED(ptr),
 				(char *)ptr + tl, LEFT - tl);
 			switch(ll) {
diff --git a/skeletons/constr_SET.c b/skeletons/constr_SET.c
index 647bb83..d9f93c3 100644
--- a/skeletons/constr_SET.c
+++ b/skeletons/constr_SET.c
@@ -259,7 +259,7 @@
 				ASN_DEBUG("Skipping unknown tag %s",
 					ber_tlv_tag_string(tlv_tag));
 
-				skip = ber_skip_length(
+				skip = ber_skip_length(opt_codec_ctx,
 					BER_TLV_CONSTRUCTED(ptr),
 					(char *)ptr + tag_len, LEFT - tag_len);
 
@@ -381,7 +381,7 @@
 				RETURN(RC_FAIL);
 			}
 
-			ll = ber_skip_length(
+			ll = ber_skip_length(opt_codec_ctx,
 				BER_TLV_CONSTRUCTED(ptr),
 				(char *)ptr + tl, LEFT - tl);
 			switch(ll) {