Fix crash

This commit is contained in:
Ali 2022-08-15 02:25:51 +03:00
parent 88b1dab7ff
commit fb0824ed8b
3 changed files with 114 additions and 84 deletions

View File

@ -716,76 +716,82 @@ public final class PostboxDecoder {
self.buffer = buffer
}
private class func skipValue(_ bytes: UnsafePointer<Int8>, offset: inout Int, length: Int, valueType: ValueType) {
private class func skipValue(_ bytes: UnsafePointer<Int8>, offset: inout Int, length: Int, valueType: ValueType) -> Bool {
switch valueType {
case .Int32:
offset += 4
case .Int64:
offset += 8
case .Bool:
offset += 1
case .Double:
offset += 8
case .String:
var length: Int32 = 0
memcpy(&length, bytes + offset, 4)
offset += 4 + Int(length)
case .Object:
var length: Int32 = 0
memcpy(&length, bytes + (offset + 4), 4)
offset += 8 + Int(length)
case .Int32Array:
var length: Int32 = 0
memcpy(&length, bytes + offset, 4)
offset += 4 + Int(length) * 4
case .Int64Array:
var length: Int32 = 0
memcpy(&length, bytes + offset, 4)
offset += 4 + Int(length) * 8
case .ObjectArray:
var length: Int32 = 0
memcpy(&length, bytes + offset, 4)
offset += 4
var i: Int32 = 0
while i < length {
var objectLength: Int32 = 0
memcpy(&objectLength, bytes + (offset + 4), 4)
offset += 8 + Int(objectLength)
i += 1
case .Int32:
offset += 4
case .Int64:
offset += 8
case .Bool:
offset += 1
case .Double:
offset += 8
case .String:
var length: Int32 = 0
memcpy(&length, bytes + offset, 4)
offset += 4 + Int(length)
case .Object:
var length: Int32 = 0
memcpy(&length, bytes + (offset + 4), 4)
offset += 8 + Int(length)
case .Int32Array:
var length: Int32 = 0
memcpy(&length, bytes + offset, 4)
offset += 4 + Int(length) * 4
case .Int64Array:
var length: Int32 = 0
memcpy(&length, bytes + offset, 4)
offset += 4 + Int(length) * 8
case .ObjectArray:
var subLength: Int32 = 0
memcpy(&subLength, bytes + offset, 4)
offset += 4
var i: Int32 = 0
while i < subLength {
var objectLength: Int32 = 0
memcpy(&objectLength, bytes + (offset + 4), 4)
offset += 8 + Int(objectLength)
if offset < 0 || offset > length {
offset = 0
return false
}
case .ObjectDictionary:
var length: Int32 = 0
memcpy(&length, bytes + offset, 4)
offset += 4
var i: Int32 = 0
while i < length {
var keyLength: Int32 = 0
memcpy(&keyLength, bytes + (offset + 4), 4)
offset += 8 + Int(keyLength)
i += 1
}
return true
case .ObjectDictionary:
var length: Int32 = 0
memcpy(&length, bytes + offset, 4)
offset += 4
var i: Int32 = 0
while i < length {
var keyLength: Int32 = 0
memcpy(&keyLength, bytes + (offset + 4), 4)
offset += 8 + Int(keyLength)
var valueLength: Int32 = 0
memcpy(&valueLength, bytes + (offset + 4), 4)
offset += 8 + Int(valueLength)
i += 1
}
case .Bytes:
var length: Int32 = 0
memcpy(&length, bytes + offset, 4)
offset += 4 + Int(length)
case .Nil:
break
case .StringArray, .BytesArray:
var length: Int32 = 0
memcpy(&length, bytes + offset, 4)
offset += 4
var i: Int32 = 0
while i < length {
var stringLength: Int32 = 0
memcpy(&stringLength, bytes + offset, 4)
offset += 4 + Int(stringLength)
i += 1
}
var valueLength: Int32 = 0
memcpy(&valueLength, bytes + (offset + 4), 4)
offset += 8 + Int(valueLength)
i += 1
}
case .Bytes:
var length: Int32 = 0
memcpy(&length, bytes + offset, 4)
offset += 4 + Int(length)
case .Nil:
break
case .StringArray, .BytesArray:
var length: Int32 = 0
memcpy(&length, bytes + offset, 4)
offset += 4
var i: Int32 = 0
while i < length {
var stringLength: Int32 = 0
memcpy(&stringLength, bytes + offset, 4)
offset += 4 + Int(stringLength)
i += 1
}
}
return true
}
private class func positionOnKey(_ rawBytes: UnsafeRawPointer, offset: inout Int, maxOffset: Int, length: Int, key: String, valueType: ValueType) -> Bool {
@ -815,7 +821,9 @@ public final class PostboxDecoder {
if keyLength != Int(readKeyLength) {
/*let keyString = String(data: Data(bytes: bytes + (offset - Int(readKeyLength) - 1), count: Int(readKeyLength)), encoding: .utf8)
print("\(String(describing: keyString))")*/
skipValue(bytes, offset: &offset, length: length, valueType: ValueType(rawValue: readValueType)!)
if !skipValue(bytes, offset: &offset, length: length, valueType: ValueType(rawValue: readValueType)!) {
return false
}
continue
}
@ -829,7 +837,9 @@ public final class PostboxDecoder {
} else if readValueType == ValueType.Nil.rawValue {
return false
} else {
skipValue(bytes, offset: &offset, length: length, valueType: ValueType(rawValue: readValueType)!)
if !skipValue(bytes, offset: &offset, length: length, valueType: ValueType(rawValue: readValueType)!) {
return false
}
}
} else {
if !consumeKey {
@ -839,7 +849,9 @@ public final class PostboxDecoder {
return true
}
} else {
skipValue(bytes, offset: &offset, length: length, valueType: ValueType(rawValue: readValueType)!)
if !skipValue(bytes, offset: &offset, length: length, valueType: ValueType(rawValue: readValueType)!) {
return false
}
}
}
@ -877,10 +889,14 @@ public final class PostboxDecoder {
} else if readValueType == ValueType.Nil.rawValue {
return false
} else {
skipValue(bytes, offset: &offset, length: length, valueType: ValueType(rawValue: readValueType)!)
if !skipValue(bytes, offset: &offset, length: length, valueType: ValueType(rawValue: readValueType)!) {
return false
}
}
} else {
skipValue(bytes, offset: &offset, length: length, valueType: ValueType(rawValue: readValueType)!)
if !skipValue(bytes, offset: &offset, length: length, valueType: ValueType(rawValue: readValueType)!) {
return false
}
}
}
@ -909,7 +925,9 @@ public final class PostboxDecoder {
offset += 1
if readValueType != valueType.rawValue || keyLength != Int(readKeyLength) || memcmp(bytes + (offset - Int(readKeyLength) - 1), &keyValue, keyLength) != 0 {
skipValue(bytes, offset: &offset, length: length, valueType: ValueType(rawValue: readValueType)!)
if !skipValue(bytes, offset: &offset, length: length, valueType: ValueType(rawValue: readValueType)!) {
return false
}
} else {
return true
}
@ -1105,7 +1123,9 @@ public final class PostboxDecoder {
return (innerData, .Object(hash: hash))
} else {
let initialOffset = self.offset
PostboxDecoder.skipValue(self.buffer.memory.assumingMemoryBound(to: Int8.self), offset: &self.offset, length: self.buffer.length, valueType: actualValueType)
if !PostboxDecoder.skipValue(self.buffer.memory.assumingMemoryBound(to: Int8.self), offset: &self.offset, length: self.buffer.length, valueType: actualValueType) {
return nil
}
let data = ReadBuffer(memory: UnsafeMutableRawPointer(mutating: self.buffer.memory.advanced(by: initialOffset)), length: self.offset - initialOffset, freeWhenDone: false).makeData()

View File

@ -562,9 +562,7 @@ public final class CachedChannelData: CachedPeerData {
self.sendAsPeerId = decoder.decodeOptionalInt64ForKey("sendAsPeerId").flatMap(PeerId.init)
if let allowedReactions = decoder.decodeArray([MessageReaction.Reaction].self, forKey: "allowedReactionList") {
self.allowedReactions = allowedReactions
} else if let allowedReactions = decoder.decodeOptionalStringArrayForKey("allowedReactions") {
if let allowedReactions = decoder.decodeOptionalStringArrayForKey("allowedReactions") {
self.allowedReactions = allowedReactions.map(MessageReaction.Reaction.builtin)
} else {
self.allowedReactions = nil
@ -715,9 +713,16 @@ public final class CachedChannelData: CachedPeerData {
}
if let allowedReactions = self.allowedReactions {
encoder.encodeArray(allowedReactions, forKey: "allowedReactionList")
encoder.encodeStringArray(allowedReactions.compactMap { item -> String? in
switch item {
case let .builtin(value):
return value
case .custom:
return nil
}
}, forKey: "allowedReactions")
} else {
encoder.encodeNil(forKey: "allowedReactionList")
encoder.encodeNil(forKey: "allowedReactions")
}
}

View File

@ -180,9 +180,7 @@ public final class CachedGroupData: CachedPeerData {
self.inviteRequestsPending = decoder.decodeOptionalInt32ForKey("irp")
if let allowedReactions = decoder.decodeArray([MessageReaction.Reaction].self, forKey: "allowedReactionList") {
self.allowedReactions = allowedReactions
} else if let allowedReactions = decoder.decodeOptionalStringArrayForKey("allowedReactions") {
if let allowedReactions = decoder.decodeOptionalStringArrayForKey("allowedReactions") {
self.allowedReactions = allowedReactions.map(MessageReaction.Reaction.builtin)
} else {
self.allowedReactions = nil
@ -279,9 +277,16 @@ public final class CachedGroupData: CachedPeerData {
}
if let allowedReactions = self.allowedReactions {
encoder.encodeArray(allowedReactions, forKey: "allowedReactionList")
encoder.encodeStringArray(allowedReactions.compactMap { item -> String? in
switch item {
case let .builtin(value):
return value
case .custom:
return nil
}
}, forKey: "allowedReactions")
} else {
encoder.encodeNil(forKey: "allowedReactionList")
encoder.encodeNil(forKey: "allowedReactions")
}
}