documented
diff --git a/skeletons/per_support.c b/skeletons/per_support.c
index 4e38c1a..9153e58 100644
--- a/skeletons/per_support.c
+++ b/skeletons/per_support.c
@@ -161,30 +161,36 @@
}
/*
- * Get the length "n" from the stream.
+ * X.691-201508 #10.9 General rules for encoding a length determinant.
+ * Get the optionally constrained length "n" from the stream.
*/
ssize_t
uper_get_length(asn_per_data_t *pd, int ebits, int *repeat) {
- ssize_t value;
+ ssize_t value;
- *repeat = 0;
+ *repeat = 0;
- if(ebits >= 0) return per_get_few_bits(pd, ebits);
+ /* #11.9.4.1 Encoding if constrained (according to effective bits) */
+ if(ebits >= 0 && ebits <= 16) {
+ return per_get_few_bits(pd, ebits);
+ }
value = per_get_few_bits(pd, 8);
- if(value < 0) return -1;
- if((value & 128) == 0) /* #10.9.3.6 */
- return (value & 0x7F);
- if((value & 64) == 0) { /* #10.9.3.7 */
- value = ((value & 63) << 8) | per_get_few_bits(pd, 8);
- if(value < 0) return -1;
- return value;
- }
- value &= 63; /* this is "m" from X.691, #10.9.3.8 */
- if(value < 1 || value > 4)
- return -1;
- *repeat = 1;
- return (16384 * value);
+ if((value & 0x80) == 0) { /* #11.9.3.6 */
+ return (value & 0x7F);
+ } else if((value & 0x40) == 0) { /* #11.9.3.7 */
+ /* bit 8 ... set to 1 and bit 7 ... set to zero */
+ value = ((value & 0x3f) << 8) | per_get_few_bits(pd, 8);
+ return value; /* potential -1 from per_get_few_bits passes through. */
+ } else if(value < 0) {
+ return -1;
+ }
+ value &= 0x3f; /* this is "m" from X.691, #11.9.3.8 */
+ if(value < 1 || value > 4) {
+ return -1; /* Prohibited by #11.9.3.8 */
+ }
+ *repeat = 1;
+ return (16384 * value);
}
/*