Correct fix for long MSI interned strings (#25104)
h/t https://github.com/binref/refinery/issues/72, for #24720. No changes file as this is an unreleased bug. Also added output for version in the custom package parser tool. # Checklist for submitter If some of the following don't apply, delete the relevant line. <!-- Note that API documentation changes are now addressed by the product design team. --> - [x] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/Committing-Changes.md#changes-files) for more information. - [x] Manual QA for all new/changed functionality
This commit is contained in:
+7
-11
@@ -242,24 +242,20 @@ func decodeStrings(dataReader, poolReader io.Reader) ([]string, error) {
|
||||
}
|
||||
return nil, fmt.Errorf("failed to read pool entry: %w", err)
|
||||
}
|
||||
stringEntrySize := int(stringEntry.Size)
|
||||
stringEntrySize := uint32(stringEntry.Size)
|
||||
|
||||
// For string pool entries too long for the size to fit in a single uint16, entry size is 8 bytes instead of 4,
|
||||
// with the first two bytes as zeroes, the next two are the two most-significant bytes of the size, shifted
|
||||
// 17 (?!?) bits to the left, the following two are the less-significant bits of the size, and the last two are
|
||||
// the reference count. Verified with the OpenVPN Connect v3 installer, which has a large string blob for
|
||||
// licenses where a 17-bit shift captures the length properly.
|
||||
// For string pool entries too long for the size to fit in a single uint16, the format sets the size as zero,
|
||||
// maintains the reference count location in the structure, then uses the following four bytes (little-endian)
|
||||
// to store the string size. See https://github.com/binref/refinery/issues/72.
|
||||
if stringEntry.Size == 0 && stringEntry.RefCount != 0 {
|
||||
stringEntrySize = int(stringEntry.RefCount) << 17
|
||||
err := binary.Read(poolReader, binary.LittleEndian, &stringEntry)
|
||||
err := binary.Read(poolReader, binary.LittleEndian, &stringEntrySize)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read large string pool entry: %w", err)
|
||||
return nil, fmt.Errorf("failed to read size of large string in string pool: %w", err)
|
||||
}
|
||||
stringEntrySize += int(stringEntry.Size)
|
||||
}
|
||||
|
||||
buf.Reset()
|
||||
buf.Grow(stringEntrySize)
|
||||
buf.Grow(int(stringEntrySize))
|
||||
_, err = io.CopyN(&buf, dataReader, int64(stringEntrySize))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read string data: %w", err)
|
||||
|
||||
@@ -31,8 +31,8 @@ func main() {
|
||||
}
|
||||
|
||||
fmt.Printf(
|
||||
"- Name: '%s'\n- Bundle Identifier: '%s'\n- Package IDs: '%s'\n",
|
||||
metadata.Name, metadata.BundleIdentifier, strings.Join(metadata.PackageIDs, ","),
|
||||
"- Name: '%s'\n- Bundle Identifier: '%s'\n- Package IDs: '%s'\n- Version: %s\n\n",
|
||||
metadata.Name, metadata.BundleIdentifier, strings.Join(metadata.PackageIDs, ","), metadata.Version,
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user