make one-pass parsing for object identifier
diff --git a/skeletons/INTEGER.c b/skeletons/INTEGER.c
index 8203ffd..56d02b4 100644
--- a/skeletons/INTEGER.c
+++ b/skeletons/INTEGER.c
@@ -499,14 +499,17 @@
 		break;
 	case ST_DIGITS:
 		dec_value_end = lstop;
+		/* FALL THROUGH */
 	case ST_DIGITS_TRAILSPACE:
 		/* The last symbol encountered was a digit. */
-		switch(asn_strtol(dec_value_start, dec_value_end, &dec_value)) {
+		switch(asn_strtol_lim(dec_value_start, &dec_value_end, &dec_value)) {
 		case ASN_STRTOL_OK:
 			break;
 		case ASN_STRTOL_ERROR_RANGE:
 			return XPBD_DECODER_LIMIT;
 		case ASN_STRTOL_ERROR_INVAL:
+		case ASN_STRTOL_EXPECT_MORE:
+		case ASN_STRTOL_EXTRA_DATA:
 			return XPBD_BROKEN_ENCODING;
 		}
 		break;
@@ -950,15 +953,44 @@
 	return 0;
 }
 
+/*
+ * This function is going to be DEPRECATED soon.
+ */
 enum asn_strtol_result_e
 asn_strtol(const char *str, const char *end, long *lp) {
+    const char *endp = end;
+
+    switch(asn_strtol_lim(str, &endp, lp)) {
+    case ASN_STRTOL_ERROR_RANGE:
+        return ASN_STRTOL_ERROR_RANGE;
+    case ASN_STRTOL_ERROR_INVAL:
+        return ASN_STRTOL_ERROR_INVAL;
+    case ASN_STRTOL_EXPECT_MORE:
+        return ASN_STRTOL_ERROR_INVAL;  /* Retain old behavior */
+    case ASN_STRTOL_OK:
+        return ASN_STRTOL_OK;
+    case ASN_STRTOL_EXTRA_DATA:
+        return ASN_STRTOL_ERROR_INVAL;  /* Retain old behavior */
+    }
+
+    return ASN_STRTOL_ERROR_INVAL;  /* Retain old behavior */
+}
+
+/*
+ * Parse the number in the given string until the given *end position,
+ * returning the position after the last parsed character back using the
+ * same (*end) pointer.
+ * WARNING: This behavior is different from the standard strtol(3).
+ */
+enum asn_strtol_result_e
+asn_strtol_lim(const char *str, const char **end, long *lp) {
 	int sign = 1;
 	long l;
 
 	const long upper_boundary = LONG_MAX / 10;
 	long last_digit_max = LONG_MAX % 10;
 
-	if(str >= end) return ASN_STRTOL_ERROR_INVAL;
+	if(str >= *end) return ASN_STRTOL_ERROR_INVAL;
 
 	switch(*str) {
 	case '-':
@@ -966,11 +998,13 @@
 		sign = -1;
 	case '+':
 		str++;
+		if(str >= *end) {
+			*end = str;
+			return ASN_STRTOL_EXPECT_MORE;
+		}
 	}
 
-	if(str >= end) return ASN_STRTOL_ERROR_INVAL;
-
-	for(l = 0; str < end; str++) {
+	for(l = 0; str < (*end); str++) {
 		switch(*str) {
 		case 0x30: case 0x31: case 0x32: case 0x33: case 0x34:
 		case 0x35: case 0x36: case 0x37: case 0x38: case 0x39: {
@@ -986,18 +1020,23 @@
 						l = -l * 10 - d;
 					}
 				} else {
+					*end = str;
 					return ASN_STRTOL_ERROR_RANGE;
 				}
 			} else {
+				*end = str;
 				return ASN_STRTOL_ERROR_RANGE;
 			}
 		    }
 		    continue;
 		default:
-			return ASN_STRTOL_ERROR_INVAL;
+		    *end = str;
+		    *lp = sign * l;
+		    return ASN_STRTOL_EXTRA_DATA;
 		}
 	}
 
+	*end = str;
 	*lp = sign * l;
 	return ASN_STRTOL_OK;
 }