Repository: SerenityOS/serenity
File: Userland/Libraries/LibGfx/ImageFormats/TIFFLoader.cpp (C++)

Code before:
    ErrorOr<void> read_tag()
    {
        auto const tag = TRY(read_value<u16>());
        auto const raw_type = TRY(read_value<u16>());
        auto const type = TRY(tiff_type_from_u16(raw_type));
        auto const count = TRY(read_value<u32>());

        Checked<u32> checked_size = size_of_type(type);
        checked_size *= count;

        if (checked_size.has_overflow())
            return Error::from_string_literal("TIFFImageDecoderPlugin: Invalid tag with too large data");

        auto tiff_value = TRY(([=, this]() -> ErrorOr<Vector<Value>> {
            if (checked_size.value() <= 4) {
                auto value = TRY(read_tiff_value(type, count, TRY(m_stream->tell())));
                TRY(m_stream->discard(4));
                return value;
            }
            auto const offset = TRY(read_value<u32>());
            return read_tiff_value(type, count, offset);
        }()));

        auto subifd_handler = [&](u32 ifd_offset) -> ErrorOr<void> {
            if (auto result = set_next_ifd(ifd_offset); result.is_error()) {
                dbgln_if(TIFF_DEBUG, "{}", result.error());
                return {};
            }
            TRY(read_next_image_file_directory());
            return {};
        };

        TRY(handle_tag(move(subifd_handler), m_metadata, tag, type, count, move(tiff_value)));

        return {};
    }

    NonnullOwnPtr<FixedMemoryStream> m_stream;
    State m_state {};
    RefPtr<Bitmap> m_bitmap {};
    RefPtr<CMYKBitmap> m_cmyk_bitmap {};

    ByteOrder m_byte_order {};
    Optional<u32> m_next_ifd {};

    ExifMetadata m_metadata {};

    // These are caches for m_metadata values
    PhotometricInterpretation m_photometric_interpretation {};
    Vector<u32, 4> m_bits_per_sample {};
    u32 m_image_width {};

Review comment (bug):
Should this be a `dbgln()` instead of a `dbgln_if()`? Seems pretty broken if this happens.

Code after:
    ErrorOr<void> read_tag()
    {
        auto const tag = TRY(read_value<u16>());
        auto const raw_type = TRY(read_value<u16>());
        auto const type = TRY(tiff_type_from_u16(raw_type));
        auto const count = TRY(read_value<u32>());

        Checked<u32> checked_size = size_of_type(type);
        checked_size *= count;

        if (checked_size.has_overflow())
            return Error::from_string_literal("TIFFImageDecoderPlugin: Invalid tag with too large data");

        auto tiff_value = TRY(([=, this]() -> ErrorOr<Vector<Value>> {
            if (checked_size.value() <= 4) {
                auto value = TRY(read_tiff_value(type, count, TRY(m_stream->tell())));
                TRY(m_stream->discard(4));
                return value;
            }
            auto const offset = TRY(read_value<u32>());
            return read_tiff_value(type, count, offset);
        }()));

        auto subifd_handler = [&](u32 ifd_offset) -> ErrorOr<void> {
            if (auto result = set_next_ifd(ifd_offset); result.is_error()) {
                dbgln("{}", result.error());
                return {};
            }
            TRY(read_next_image_file_directory());
            return {};
        };

        TRY(handle_tag(move(subifd_handler), m_metadata, tag, type, count, move(tiff_value)));

        return {};
    }

    NonnullOwnPtr<FixedMemoryStream> m_stream;
    State m_state {};
    RefPtr<Bitmap> m_bitmap {};
    RefPtr<CMYKBitmap> m_cmyk_bitmap {};

    ByteOrder m_byte_order {};
    Optional<u32> m_next_ifd {};

    ExifMetadata m_metadata {};

    // These are caches for m_metadata values
    PhotometricInterpretation m_photometric_interpretation {};
    Vector<u32, 4> m_bits_per_sample {};
    u32 m_image_width {};