From a8514a3caaaf33018dd9867c8ac7fe13afa569b5 Mon Sep 17 00:00:00 2001 From: Matthias Andreas Benkard Date: Thu, 30 Dec 2021 21:01:48 +0100 Subject: jgvariant-ostree: Handle non-canonical endianness in static deltas. Change-Id: I333fce6d6f4df995d6d965261bb66e50c116f02d --- .../eu/mulk/jgvariant/ostree/DeltaFallback.java | 10 ++++- .../eu/mulk/jgvariant/ostree/DeltaMetaEntry.java | 13 +++++-- .../eu/mulk/jgvariant/ostree/DeltaSuperblock.java | 44 +++++++++++++++++----- 3 files changed, 53 insertions(+), 14 deletions(-) (limited to 'jgvariant-ostree/src/main/java/eu') diff --git a/jgvariant-ostree/src/main/java/eu/mulk/jgvariant/ostree/DeltaFallback.java b/jgvariant-ostree/src/main/java/eu/mulk/jgvariant/ostree/DeltaFallback.java index 46470d4..0967043 100644 --- a/jgvariant-ostree/src/main/java/eu/mulk/jgvariant/ostree/DeltaFallback.java +++ b/jgvariant-ostree/src/main/java/eu/mulk/jgvariant/ostree/DeltaFallback.java @@ -23,15 +23,21 @@ public record DeltaFallback( DeltaFallback.class, Decoder.ofByte().map(ObjectType::valueOf), Checksum.decoder(), - Decoder.ofLong().withByteOrder(ByteOrder.LITTLE_ENDIAN), // FIXME: non-canonical - Decoder.ofLong().withByteOrder(ByteOrder.LITTLE_ENDIAN)); // FIXME: non-canonical + Decoder.ofLong(), + Decoder.ofLong()); /** * Acquires a {@link Decoder} for the enclosing type. * + *

Note: This decoder has an unspecified {@link ByteOrder}. + * * @return a possibly shared {@link Decoder}. */ public static Decoder decoder() { return DECODER; } + + DeltaFallback byteSwapped() { + return new DeltaFallback(objectType, checksum, compressedSize, uncompressedSize); + } } diff --git a/jgvariant-ostree/src/main/java/eu/mulk/jgvariant/ostree/DeltaMetaEntry.java b/jgvariant-ostree/src/main/java/eu/mulk/jgvariant/ostree/DeltaMetaEntry.java index 0eaea73..7269a80 100644 --- a/jgvariant-ostree/src/main/java/eu/mulk/jgvariant/ostree/DeltaMetaEntry.java +++ b/jgvariant-ostree/src/main/java/eu/mulk/jgvariant/ostree/DeltaMetaEntry.java @@ -49,10 +49,10 @@ public record DeltaMetaEntry( private static final Decoder DECODER = Decoder.ofStructure( DeltaMetaEntry.class, - Decoder.ofInt().withByteOrder(ByteOrder.LITTLE_ENDIAN), // FIXME: non-canonical + Decoder.ofInt(), Checksum.decoder(), - Decoder.ofLong().withByteOrder(ByteOrder.LITTLE_ENDIAN), // FIXME: non-canonical - Decoder.ofLong().withByteOrder(ByteOrder.LITTLE_ENDIAN), // FIXME: non-canonical + Decoder.ofLong(), + Decoder.ofLong(), Decoder.ofByteArray().map(DeltaMetaEntry::parseObjectList)); private static List parseObjectList(byte[] bytes) { @@ -71,9 +71,16 @@ public record DeltaMetaEntry( /** * Acquires a {@link Decoder} for the enclosing type. * + *

Note: This decoder has an unspecified {@link ByteOrder}. + * * @return a possibly shared {@link Decoder}. */ public static Decoder decoder() { return DECODER; } + + DeltaMetaEntry byteSwapped() { + // FIXME + return new DeltaMetaEntry(version, checksum, compressedSize, uncompressedSize, objects); + } } diff --git a/jgvariant-ostree/src/main/java/eu/mulk/jgvariant/ostree/DeltaSuperblock.java b/jgvariant-ostree/src/main/java/eu/mulk/jgvariant/ostree/DeltaSuperblock.java index edcf2bf..10b1661 100644 --- a/jgvariant-ostree/src/main/java/eu/mulk/jgvariant/ostree/DeltaSuperblock.java +++ b/jgvariant-ostree/src/main/java/eu/mulk/jgvariant/ostree/DeltaSuperblock.java @@ -57,15 +57,41 @@ public record DeltaSuperblock( private static final Decoder DECODER = Decoder.ofStructure( - DeltaSuperblock.class, - Metadata.decoder(), - Decoder.ofLong().withByteOrder(ByteOrder.BIG_ENDIAN), - Checksum.decoder(), - Checksum.decoder(), - Commit.decoder(), - Decoder.ofByteArray().map(DeltaSuperblock::parseDeltaNameList), - Decoder.ofArray(DeltaMetaEntry.decoder()), - Decoder.ofArray(DeltaFallback.decoder())); + DeltaSuperblock.class, + Metadata.decoder(), + Decoder.ofLong().withByteOrder(ByteOrder.BIG_ENDIAN), + Checksum.decoder(), + Checksum.decoder(), + Commit.decoder(), + Decoder.ofByteArray().map(DeltaSuperblock::parseDeltaNameList), + Decoder.ofArray(DeltaMetaEntry.decoder()).withByteOrder(ByteOrder.LITTLE_ENDIAN), + Decoder.ofArray(DeltaFallback.decoder()).withByteOrder(ByteOrder.LITTLE_ENDIAN)) + .map( + deltaSuperblock -> { + // Fix up the endianness of the 'entries' and 'fallbacks' fields, which have + // unspecified byte order. + var endiannessMetadatum = + deltaSuperblock.metadata().fields().get("ostree.endianness"); + if (endiannessMetadatum != null + && endiannessMetadatum.value() instanceof Byte endiannessByte + && endiannessByte == (byte) 'B') { + return deltaSuperblock.byteSwapped(); + } else { + return deltaSuperblock; + } + }); + + private DeltaSuperblock byteSwapped() { + return new DeltaSuperblock( + metadata, + timestamp, + fromChecksum, + toChecksum, + commit, + dependencies, + entries.stream().map(DeltaMetaEntry::byteSwapped).toList(), + fallbacks.stream().map(DeltaFallback::byteSwapped).toList()); + } private static List parseDeltaNameList(byte[] bytes) { var byteBuffer = ByteBuffer.wrap(bytes); -- cgit v1.2.3