@@ -327,16 +327,31 @@ type XCTAttachment struct {
327327 userInfo map [string ]interface {}
328328}
329329
330+ // resolveRef follows a keyed archive reference, returning nil when the key is
331+ // absent, is not a reference, or points outside the object table. Callers
332+ // comma-ok assert the result, so an omitted field yields a zero value.
333+ func resolveRef (object map [string ]interface {}, key string , objects []interface {}) interface {} {
334+ uid , isRef := object [key ].(plist.UID )
335+ if ! isRef || int (uid ) >= len (objects ) {
336+ return nil
337+ }
338+ return objects [uid ]
339+ }
340+
330341func NewXCTAttachment (object map [string ]interface {}, objects []interface {}) interface {} {
331- lifetime := object ["lifetime" ].(uint64 )
332- uniformTypeIdentifier := objects [object ["uniformTypeIdentifier" ].(plist.UID )].(string )
333- fileNameOverride := objects [object ["fileNameOverride" ].(plist.UID )].(string )
334- timestamp := objects [object ["timestamp" ].(plist.UID )].(float64 )
335- name := objects [object ["name" ].(plist.UID )].(string )
336- userInfo , _ := extractDictionary (objects [object ["userInfo" ].(plist.UID )].(map [string ]interface {}), objects , 0 )
342+ lifetime , _ := object ["lifetime" ].(uint64 )
343+ uniformTypeIdentifier , _ := resolveRef (object , "uniformTypeIdentifier" , objects ).(string )
344+ fileNameOverride , _ := resolveRef (object , "fileNameOverride" , objects ).(string )
345+ timestamp , _ := resolveRef (object , "timestamp" , objects ).(float64 )
346+ name , _ := resolveRef (object , "name" , objects ).(string )
347+
348+ // An absent userInfo arrives as the string "$null", not a dictionary.
349+ var userInfo map [string ]interface {}
350+ if raw , isDict := resolveRef (object , "userInfo" , objects ).(map [string ]interface {}); isDict {
351+ userInfo , _ = extractDictionary (raw , objects , 0 )
352+ }
337353
338- payloadRaw := objects [object ["payload" ].(plist.UID )]
339- payload := extractAttachmentPayload (payloadRaw , objects )
354+ payload := extractAttachmentPayload (resolveRef (object , "payload" , objects ), objects )
340355
341356 return XCTAttachment {
342357 lifetime : lifetime ,
@@ -354,7 +369,7 @@ func extractAttachmentPayload(payloadRaw interface{}, objects []interface{}) []u
354369 if ! byteSliceOk {
355370 mapPayload , mapOk := payloadRaw .(map [string ]interface {})
356371 if mapOk {
357- payloadClassMap , classOk := objects [ mapPayload [ "$class" ].(plist. UID )] .(map [string ]interface {})
372+ payloadClassMap , classOk := resolveRef ( mapPayload , "$class" , objects ) .(map [string ]interface {})
358373 if classOk {
359374 payloadClass := payloadClassMap ["$classname" ]
360375 if payloadClass == "NSMutableData" || payloadClass == "NSData" {
@@ -772,14 +787,14 @@ type XCTIssue struct {
772787}
773788
774789func NewXCTIssue (object map [string ]interface {}, objects []interface {}) interface {} {
775- runtimeIssueSeverity := object ["runtimeIssueSeverity" ].(uint64 )
776- detailedDescriptionRef := object ["detailed-description" ].(plist.UID )
777- sourceCodeContextRef := object ["source-code-context" ].(plist.UID )
778- compactDescriptionRef := object ["compact-description" ].(plist.UID )
790+ runtimeIssueSeverity , _ := object ["runtimeIssueSeverity" ].(uint64 )
791+ detailedDescription , _ := resolveRef (object , "detailed-description" , objects ).(string )
792+ compactDescription , _ := resolveRef (object , "compact-description" , objects ).(string )
779793
780- detailedDescription := objects [detailedDescriptionRef ].(string )
781- compactDescription := objects [compactDescriptionRef ].(string )
782- sourceCodeContext := NewXCTSourceCodeContext (objects [sourceCodeContextRef ].(map [string ]interface {}), objects ).(XCTSourceCodeContext )
794+ var sourceCodeContext XCTSourceCodeContext
795+ if raw , isDict := resolveRef (object , "source-code-context" , objects ).(map [string ]interface {}); isDict {
796+ sourceCodeContext , _ = NewXCTSourceCodeContext (raw , objects ).(XCTSourceCodeContext )
797+ }
783798
784799 return XCTIssue {RuntimeIssueSeverity : runtimeIssueSeverity , DetailedDescription : detailedDescription , CompactDescription : compactDescription , SourceCodeContext : sourceCodeContext }
785800}
@@ -798,8 +813,10 @@ type XCTSourceCodeContext struct {
798813}
799814
800815func NewXCTSourceCodeContext (object map [string ]interface {}, objects []interface {}) interface {} {
801- locationRef := object ["location" ].(plist.UID )
802- location := NewXCTSourceCodeLocation (objects [locationRef ].(map [string ]interface {}), objects ).(XCTSourceCodeLocation )
816+ var location XCTSourceCodeLocation
817+ if raw , isDict := resolveRef (object , "location" , objects ).(map [string ]interface {}); isDict {
818+ location , _ = NewXCTSourceCodeLocation (raw , objects ).(XCTSourceCodeLocation )
819+ }
803820
804821 return XCTSourceCodeContext {Location : location }
805822}
@@ -810,13 +827,13 @@ type XCTSourceCodeLocation struct {
810827}
811828
812829func NewXCTSourceCodeLocation (object map [string ]interface {}, objects []interface {}) interface {} {
813- fileUrlRef := object [ "file-url" ].(plist. UID )
814- relativeRef := objects [ fileUrlRef ] .(map [string ]interface {})[ "NS.relative" ].(plist. UID )
815- relativePath := objects [ int ( relativeRef )] .(string )
816- fileUrl := NewNSURL ( relativePath )
817- lineNumber := object ["line-number" ].(uint64 )
830+ var relativePath string
831+ if fileURL , isDict := resolveRef ( object , "file-url" , objects ) .(map [string ]interface {}); isDict {
832+ relativePath , _ = resolveRef ( fileURL , "NS.relative" , objects ) .(string )
833+ }
834+ lineNumber , _ := object ["line-number" ].(uint64 )
818835
819- return XCTSourceCodeLocation {FileUrl : fileUrl , LineNumber : lineNumber }
836+ return XCTSourceCodeLocation {FileUrl : NewNSURL ( relativePath ) , LineNumber : lineNumber }
820837}
821838
822839func toInterfaceSliceOfTests (testSlice []XCTTestIdentifier ) []interface {} {
0 commit comments