diff --git a/Library/DiscUtils.Registry/RegistryValue.cs b/Library/DiscUtils.Registry/RegistryValue.cs index 7acc93841..e6a9bd08f 100644 --- a/Library/DiscUtils.Registry/RegistryValue.cs +++ b/Library/DiscUtils.Registry/RegistryValue.cs @@ -44,18 +44,12 @@ internal RegistryValue(RegistryHive hive, ValueCell cell) /// /// Gets the type of the value. /// - public RegistryValueType DataType - { - get { return _cell.DataType; } - } + public RegistryValueType DataType => _cell.DataType; /// /// Gets the name of the value, or empty string if unnamed. /// - public string Name - { - get { return _cell.Name ?? string.Empty; } - } + public string Name => _cell.Name ?? string.Empty; /// /// Gets the value data mapped to a .net object. @@ -100,7 +94,7 @@ public object Value { get { - var buffer = ArrayPool.Shared.Rent(_cell.DataLength & int.MaxValue); + var buffer = ArrayPool.Shared.Rent(RawLength); try { return ConvertToObject(GetRawData(buffer), DataType); @@ -112,6 +106,12 @@ public object Value } } + /// + /// Gets size in bytes of raw value data + /// + /// Size in bytes of raw value data + public int RawLength => _cell.DataLength & int.MaxValue; + /// /// Gets raw binary value without interpretation as any particular data type. /// @@ -119,7 +119,7 @@ public byte[] RawValue { get { - var buffer = ArrayPool.Shared.Rent(_cell.DataLength & int.MaxValue); + var buffer = ArrayPool.Shared.Rent(RawLength); try { return GetRawData(buffer).ToArray(); @@ -219,20 +219,45 @@ private static object ConvertToObject(ReadOnlySpan data, RegistryValueType case RegistryValueType.String: case RegistryValueType.ExpandString: case RegistryValueType.Link: + if (data.Length == 0) + { + return null; + } + return EndianUtilities.LittleEndianUnicodeBytesToString(data).Trim('\0'); case RegistryValueType.Dword: + if (data.Length == 0) + { + return null; + } + return EndianUtilities.ToInt32LittleEndian(data); case RegistryValueType.DwordBigEndian: + if (data.Length == 0) + { + return null; + } + return EndianUtilities.ToInt32BigEndian(data); case RegistryValueType.MultiString: + if (data.Length == 0) + { + return null; + } + var multiString = EndianUtilities.LittleEndianUnicodeBytesToString(data).TrimEnd('\0'); return multiString.Split('\0'); case RegistryValueType.Qword: - return string.Empty + EndianUtilities.ToUInt64LittleEndian(data); + if (data.Length == 0) + { + return null; + } + + return EndianUtilities.ToUInt64LittleEndian(data); default: return data.ToArray(); @@ -297,7 +322,7 @@ private static ReadOnlyMemory ConvertToData(object value, RegistryValueTyp private string DataAsString() { - var buffer = ArrayPool.Shared.Rent(_cell.DataLength & int.MaxValue); + var buffer = ArrayPool.Shared.Rent(RawLength); try { var data = GetRawData(buffer);