Skip to content

Commit 30dfd73

Browse files
committed
Fix fragmented write_octetstring and add return value to write_length_determinant
1 parent c925df6 commit 30dfd73

File tree

2 files changed

+35
-27
lines changed

2 files changed

+35
-27
lines changed

src/io/per/mod.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,13 +98,15 @@ pub trait PackedWrite {
9898
) -> Result<(), Error>;
9999

100100
/// According to ITU-T X.691 | ISO/IEC 8825-2:2015, chapter 3.7.17, the length determinant is
101-
/// a number used to count bits, octets (bytes), characters or components
101+
/// a number used to count bits, octets (bytes), characters or components.
102+
/// Returns `Some`-value, if the transmitted value differs from the given length (for example
103+
/// when the length exceeds the non-fragmented size)
102104
fn write_length_determinant(
103105
&mut self,
104106
lower_bound: Option<u64>,
105107
upper_bound: Option<u64>,
106108
length: u64,
107-
) -> Result<(), Error>;
109+
) -> Result<Option<u64>, Error>;
108110

109111
/// According to ITU-T X.691 | ISO/IEC 8825-2:2015, chapter 3.7.19, a number without constrains
110112
/// and is likely to be small. It is used where small lengths are more likely than large values.

src/io/per/unaligned/mod.rs

Lines changed: 31 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ pub const BYTE_LEN: usize = 8;
99
const FRAGMENT_SIZE: u64 = 16 * 1024;
1010
const MAX_FRAGMENTS: u8 = 4 /* 11.9.3.8, NOTE */ ;
1111
const MIN_FRAGMENT_SIZE: u64 = FRAGMENT_SIZE;
12-
const MAX_FRAGMENT_SIZE: u64 = FRAGMENT_SIZE * MAX_FRAGMENTS as u64;
12+
const MAX_FRAGMENTS_SIZE: u64 = FRAGMENT_SIZE * MAX_FRAGMENTS as u64;
1313

1414
const LENGTH_127: u64 = 127;
1515
const LENGTH_16K: u64 = 16 * 1024;
@@ -519,7 +519,7 @@ impl<T: BitWrite> PackedWrite for T {
519519
lower_bound: Option<u64>,
520520
upper_bound: Option<u64>,
521521
value: u64,
522-
) -> Result<(), Error> {
522+
) -> Result<Option<u64>, Error> {
523523
let lower_bound_unwrapped = const_unwrap_or!(lower_bound, 0);
524524
let upper_bound_unwrapped = const_unwrap_or!(upper_bound, i64::MAX as u64);
525525

@@ -528,7 +528,7 @@ impl<T: BitWrite> PackedWrite for T {
528528
{
529529
// 11.9.4.2
530530
if lower_bound == upper_bound {
531-
Ok(())
531+
Ok(None)
532532
} else if value < lower_bound_unwrapped {
533533
Err(Error::ValueNotInRange(
534534
value as i64,
@@ -540,29 +540,33 @@ impl<T: BitWrite> PackedWrite for T {
540540
lower_bound,
541541
upper_bound,
542542
value - lower_bound_unwrapped,
543-
)
543+
)?;
544+
Ok(None)
544545
}
545546
} else if const_is_some!(upper_bound) && upper_bound_unwrapped <= LENGTH_64K {
546547
// 11.9.4.1 -> 11.9.3.4 -> 11.6.1
547-
self.write_non_negative_binary_integer(lower_bound, upper_bound, value)
548+
self.write_non_negative_binary_integer(lower_bound, upper_bound, value)?;
549+
Ok(None)
548550
} else {
549551
// 11.9.4.1 -> 11.9.3.5
550552
if value <= LENGTH_127 {
551553
// 11.9.3.6: less than or equal to 127
552554
self.write_bit(false)?;
553-
self.write_non_negative_binary_integer(None, Some(LENGTH_127), value)
555+
self.write_non_negative_binary_integer(None, Some(LENGTH_127), value)?;
556+
Ok(None)
554557
} else if value < LENGTH_16K {
555558
// 11.9.3.7: greater than 127 and less than or equal to 16K
556559
self.write_bit(true)?;
557560
self.write_bit(false)?;
558-
self.write_non_negative_binary_integer(None, Some(LENGTH_16K - 1), value)
561+
self.write_non_negative_binary_integer(None, Some(LENGTH_16K - 1), value)?;
562+
Ok(None)
559563
} else {
560564
// 11.9.3.8: chunks of 16k multiples
561565
self.write_bit(true)?;
562566
self.write_bit(true)?;
563-
let multiple = ((value / LENGTH_16K) as u8).max(MAX_FRAGMENTS);
567+
let multiple = ((value / LENGTH_16K) as u8).min(MAX_FRAGMENTS);
564568
self.write_bits_with_offset(&[multiple], 2)?;
565-
Ok(())
569+
Ok(Some(u64::from(multiple) * LENGTH_16K))
566570
}
567571
}
568572
}
@@ -583,7 +587,7 @@ impl<T: BitWrite> PackedWrite for T {
583587
let lower_bound = const_unwrap_or!(lower_bound_size, 0);
584588
let upper_bound = const_unwrap_or!(upper_bound_size, i64::MAX as u64);
585589
let length = len;
586-
let fragmented = length > MAX_FRAGMENT_SIZE;
590+
let fragmented = length > MAX_FRAGMENTS_SIZE;
587591
let out_of_range = length < lower_bound || length > upper_bound;
588592

589593
if extensible {
@@ -619,13 +623,13 @@ impl<T: BitWrite> PackedWrite for T {
619623
self.write_bits_with_offset_len(
620624
src,
621625
offset as usize,
622-
MAX_FRAGMENT_SIZE.min(length) as usize,
626+
MAX_FRAGMENTS_SIZE.min(length) as usize,
623627
)?;
624628

625629
if fragmented {
626-
let mut written_bits = MAX_FRAGMENT_SIZE;
630+
let mut written_bits = MAX_FRAGMENTS_SIZE;
627631
loop {
628-
let fragment_size = (length - written_bits).min(MAX_FRAGMENT_SIZE);
632+
let fragment_size = (length - written_bits).min(MAX_FRAGMENTS_SIZE);
629633
let fragment_size = fragment_size - (fragment_size % MIN_FRAGMENT_SIZE);
630634
self.write_length_determinant(None, None, fragment_size)?;
631635
self.write_bits_with_offset_len(
@@ -658,19 +662,18 @@ impl<T: BitWrite> PackedWrite for T {
658662
let lower_bound = const_unwrap_or!(lower_bound_size, 0);
659663
let upper_bound = const_unwrap_or!(upper_bound_size, i64::MAX as u64);
660664
let length = src.len() as u64;
661-
let fragmented = length > MAX_FRAGMENT_SIZE;
662665
let out_of_range = length < lower_bound || length > upper_bound;
663666

664667
if extensible {
665668
self.write_bit(out_of_range)?;
666669
}
667670

668-
if out_of_range {
671+
let fragment_size = if out_of_range {
669672
if extensible {
670673
// 17.3
671674
// self.read_semi_constrained_whole_number(0)
672675
// self.read_non_negative_binary_integer(0, MAX) + lb | lb=0=>MIN for unsigned
673-
self.write_length_determinant(None, None, length)?;
676+
self.write_length_determinant(None, None, length)?
674677
} else {
675678
return Err(Error::SizeNotInRange(length, lower_bound, upper_bound));
676679
}
@@ -689,27 +692,30 @@ impl<T: BitWrite> PackedWrite for T {
689692
&& upper_bound < LENGTH_64K
690693
{
691694
// 17.7
695+
None
692696
} else {
693697
// 17.8
694-
self.write_length_determinant(lower_bound_size, upper_bound_size, length)?;
695-
}
698+
self.write_length_determinant(lower_bound_size, upper_bound_size, length)?
699+
};
696700

697-
self.write_bits(&src[..MAX_FRAGMENT_SIZE.min(length) as usize])?;
701+
self.write_bits(&src[..fragment_size.unwrap_or(length) as usize])?;
698702

699-
if fragmented {
700-
let mut written_bytes = MAX_FRAGMENT_SIZE;
703+
if let Some(mut written_bytes) = fragment_size {
701704
loop {
702-
let fragment_size = (length - written_bytes).min(MAX_FRAGMENT_SIZE);
703-
let fragment_size = fragment_size - (fragment_size % MIN_FRAGMENT_SIZE);
704-
self.write_length_determinant(None, None, fragment_size)?;
705+
let remaining = length - written_bytes;
706+
let fragment_size = self
707+
.write_length_determinant(None, None, remaining)?
708+
.unwrap_or(remaining);
709+
705710
self.write_bits(
706711
&src[written_bytes as usize..(written_bytes + fragment_size) as usize],
707712
)?;
708-
written_bytes += fragment_size;
709713

710714
if fragment_size < MIN_FRAGMENT_SIZE {
711715
break;
712716
}
717+
718+
written_bytes += fragment_size;
713719
}
714720
}
715721

0 commit comments

Comments
 (0)