Allow `MaybeReadable` to not fully read in `upgradable_option` 2024-03-fix-upgradable-enum
authorMatt Corallo <git@bluematt.me>
Thu, 28 Mar 2024 22:06:36 +0000 (22:06 +0000)
committerMatt Corallo <git@bluematt.me>
Sun, 7 Apr 2024 19:55:56 +0000 (19:55 +0000)
Whils this is generally not supported, issues in our
`MaybeReadable` implementations may occur, and we should try to be
robust against them.

lightning/src/util/ser_macros.rs

index d1e152feb09b11ecf96b701387f63c86234f9fb7..e1f4762ecbb8dde0b2600cd9b5fe5a85aa453fdc 100644 (file)
@@ -400,6 +400,17 @@ macro_rules! _decode_tlv {
        // but we can no longer understand it.
        ($outer_reader: expr, $reader: expr, $field: ident, upgradable_option) => {{
                $field = $crate::util::ser::MaybeReadable::read(&mut $reader)?;
+               if $field.is_none() {
+                       #[cfg(not(debug_assertions))] {
+                               // In general, MaybeReadable implementations are required to consume all the bytes
+                               // of the object even if they don't understand it, but due to a bug in the
+                               // serialization format for `impl_writeable_tlv_based_enum_upgradable` we sometimes
+                               // don't know how many bytes that is. In such cases, we'd like to spuriously allow
+                               // TLV length mismatches, which we do here by calling `eat_remaining` so that the
+                               // `s.bytes_remain()` check in `_decode_tlv_stream_range` doesn't fail.
+                               $reader.eat_remaining()?;
+                       }
+               }
        }};
        ($outer_reader: expr, $reader: expr, $field: ident, (option: $trait: ident $(, $read_arg: expr)?)) => {{
                $field = Some($trait::read(&mut $reader $(, $read_arg)*)?);