[qt/qt/qtinterfaceframework-taglib]: Summary of bulk changes made

KDE Git Services - Bulk Change <[email protected]>
Newsgroups gmane.comp.kde.cvs
Message-ID <[email protected]>
Git repository change summary for qt/qt/qtinterfaceframework-taglib
Pushed by mirror-service into branch 'upstream/master'.
Changed from c3d4eef597cc4914ec6177cae83d792158bf8be3 to ee0ab489e041144be7583f9ef2f348a111815180
Acknowledgement was received that this change introduces only existing code that has been pushed to another public open source repository.

This change contains the following new commits:

Git commit be424957dae963d9735933ae557e5cffee508fd5 by Urs Fleisch (on behalf of manuaudio) on 16/08/2026 at 06:16..
MPEG: do not convert out of range properties to int

The Xing header supplies both the frame count and the byte count as raw
32 bit values, and TagLib multiplies the frame count by the per-frame
duration without checking the result. At MPEG 2.5 Layer III / 8 kHz a
frame is 72 ms, so 2^32-1 declared frames puts the length at ~3.1e11 ms
and the conversion to int is undefined:

  taglib/mpeg/mpegproperties.cpp:166:35: runtime error: 3.09238e+11 is
  outside the range of representable values of type 'int'

The bitrate on the next line is reachable the other way round. One
declared frame of MPEG 1 Layer I at 48 kHz is 8 ms, and the declared
size is not the real file size, so a 1 KB file can claim 2^32-1 bytes:

  taglib/mpeg/mpegproperties.cpp:167:35: runtime error: 4.29497e+09 is
  outside the range of representable values of type 'int'

The length computed on the non-Xing path has the same shape but is
bounded by the real stream length rather than a declared count, so it
needs a file of a couple of gigabytes rather than a crafted header. I
have not built one; that guard is there for consistency, not on
demonstrated evidence.

Leave the field at its default rather than converting.

Two reports before the change, none after. The 23 MPEG files in
tests/data report identical channels, sample rate, bitrate and length
before and after, and the suite runs 576 tests either way.

Assisted-By: Claude Code (Claude Opus 5)
https://invent.kde.org/qt/qt/qtinterfaceframework-taglib/-/commit/be424957dae963d9735933ae557e5cffee508fd5

Git commit d841424d4854cb083237b61c5569b77369151411 by Urs Fleisch (on behalf of manuaudio) on 16/08/2026 at 06:19..
MP4: do not convert an out of range length to int

The mdhd duration is a signed 64 bit field in version 1 and the
timescale sitting beside it is a 32 bit field that may be 1, so a
4 KB file can declare 2^62 units of a one-hertz clock. The millisecond
length is then ~4.6e21 and the conversion to int is undefined:

  taglib/mp4/mp4properties.cpp:207:34: runtime error: 4.61169e+21 is
  outside the range of representable values of type 'int'

The version 0 path reaches the same line with a 32 bit duration:

  taglib/mp4/mp4properties.cpp:207:34: runtime error: 4.29497e+12 is
  outside the range of representable values of type 'int'

The mvhd fallback a few lines above feeds the same expression, so it is
covered by the same guard.

Leave the field at its default rather than converting.

For the record, the other conversions in this file were checked and are
not affected. The esds and alac nominal bitrates divide a 32 bit value
by 1000.0, which cannot leave int's range, and the three
calculateMdatLength() estimates are integer arithmetic on a long long
rather than a double conversion.

One report per file before the change, none after. The 18 MP4 files in
tests/data report identical channels, sample rate, bitrate and length
before and after, and the suite runs 576 tests either way.

Assisted-By: Claude Code (Claude Opus 5)
https://invent.kde.org/qt/qt/qtinterfaceframework-taglib/-/commit/d841424d4854cb083237b61c5569b77369151411

Git commit ee0ab489e041144be7583f9ef2f348a111815180 by GitHub (on behalf of manuaudio) on 16/08/2026 at 10:30..
Validate enumerations decoded from file bytes before casting to them (#1420)

* ID3v2: validate the text encoding byte before casting it

The first byte of most ID3v2 frames selects the text encoding and is
cast straight to String::Type. It comes from the file, so it can be any
value, and String::Type enumerates 0..4 — loading an enumeration object
whose value is outside the enumeration's range is undefined:

  runtime error: load of value 127, which is not a valid value for type
  'String::Type'
  runtime error: load of value 4294967295, which is not a valid value
  for type 'String::Type'

The second value is 0xFF read through a plain signed char.

It matters beyond the sanitizer: String::data() switches on the type
with no default case, so an unrecognised encoding silently falls
through and returns an empty ByteVector on the render path.

Add Utils::textEncodingFromByte(), which maps the byte to its
String::Type or falls back to Latin1 — the encoding these frames
already declare as their default — and use it at the eleven sites that
read the byte from a file.

Note that a byte of 5, 6 or 7 is *not* undefined, because the range of
an enumeration is the bit width spanned by its enumerators rather than
the enumerators themselves. It is still not a valid encoding, and the
same helper rejects it.

Assisted-By: Claude Code (Claude Opus 5)

* Validate the picture type byte before casting it

The picture type enumeration is declared by DECLARE_PICTURE_TYPE_ENUM
and shared by three classes, and all three cast a file-supplied value
to it without checking. The enumerators run 0x00..0x14, so the range of
the enumeration is 0..31 and a load outside that is undefined:

  taglib/mpeg/id3v2/frames/attachedpictureframe.cpp:96:13: runtime
  error: load of value 4294967295, which is not a valid value for type
  'AttachedPictureFrame::Type'
  taglib/flac/flacpicture.cpp:129:13: runtime error: load of value
  65536, which is not a valid value for type 'Type'

FLAC is the widest of the three: it casts a whole 32 bit field, so no
truncation to a byte limits it. ASF and ID3v2 read a plain signed char,
which reaches the same place through sign extension.

This is visible to callers, not only to a sanitizer. Before the change
AttachedPictureFrame::type() and FLAC::Picture::type() return -1 and
65536 for the files above; after it they return Other.

Since the enumeration comes from a macro, add one typeFromByte() to the
macro backed by Utils::pictureTypeFromByte(), rather than three copies
of the same check.

Six reports before the change, none after.

Assisted-By: Claude Code (Claude Opus 5)

* ID3v2: validate the RVA2 channel byte before casting it

Each channel record in a relative volume frame starts with a channel
type byte that is cast straight to ChannelType. The enumerators run
0x00..0x08, so the range of the enumeration is 0..15 and the byte from
the file can leave it:

  runtime error: load of value 127, which is not a valid value for type
  'RelativeVolumeFrame::ChannelType'
  runtime error: load of value 4294967295, which is not a valid value
  for type 'RelativeVolumeFrame::ChannelType'

The value is also used as a map key, so the frame ends up holding a
channel that channels() then reports back.

Map an unrecognised byte to Other instead.

Two reports before the change, none after. The 123 files in tests/data
produce identical channel output either way.

Assisted-By: Claude Code (Claude Opus 5)

* ID3v2: validate the SYLT and ETCO enum bytes before casting them

Synchronised lyrics carry a timestamp format byte and a content type
byte, and event timing codes carry a timestamp format byte. All three
are cast without checking. TimestampFormat enumerates 0..2, so its
range is only 0..3:

  runtime error: load of value 127, which is not a valid value for type
  'SynchronizedLyricsFrame::TimestampFormat'
  runtime error: load of value 127, which is not a valid value for type
  'SynchronizedLyricsFrame::Type'
  runtime error: load of value 127, which is not a valid value for type
  'EventTimingCodesFrame::TimestampFormat'

with 4294967295 in place of 127 when the byte is 0xFF. Before the
change timestampFormat() and type() return -1 for such a file.

Map an unrecognised byte to Unknown and Other respectively.

Worth noting what is *not* changed: the event type byte on the line
below the ETCO cast is already written
static_cast<EventType>(static_cast<unsigned char>(...)), and EventType
enumerates up to 0xFE, so an unsigned char cannot leave its range. It
reads like the same defect and is not one.

Three reports before the change, none after. The 123 files in
tests/data produce identical output either way.

Assisted-By: Claude Code (Claude Opus 5)

* MP4: validate the atom data type before casting it

The type field of an iTunes metadata atom is a 32 bit value read from
the file and cast straight to AtomDataType, whose enumerators run
0..255. Values above 255 are outside the range of the enumeration:

  taglib/mp4/mp4atom.h:85:36: runtime error: load of value 65536, which
  is not a valid value for type 'AtomDataType'
  taglib/mp4/mp4atom.h:85:36: runtime error: load of value 4294967295,
  which is not a valid value for type 'AtomDataType'

Both cast sites are reachable: parseFreeForm calls parseData2 with
expectedFlags = -1, so the flags == expectedFlags test never
constrains the value, and the mean/name branch casts unconditionally. A
'----' atom with an arbitrary flags field reaches both.

Map anything outside the range to TypeUndefined, which the enumeration
already provides for exactly this.

Four reports before the change, none after. The 123 files in tests/data
produce identical item output either way.

Assisted-By: Claude Code (Claude Opus 5)
https://invent.kde.org/qt/qt/qtinterfaceframework-taglib/-/commit/ee0ab489e041144be7583f9ef2f348a111815180
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.