Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions ios/nskeyedarchiver/archiver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
"reflect"

"testing"
Expand All @@ -16,6 +17,18 @@ import (
"github.com/stretchr/testify/assert"
)

func TestSavedState(t *testing.T) {
bytes, _ := os.ReadFile("fixtures/savedstate.plist")
res, err := nskeyedarchiver.Unarchive(bytes)
if assert.NoError(t, err) {
nskm := res[0].(map[string]interface{})
assert.Equal(t, uint64(25919), nskm["CoreGraphics Window ID"])
assert.Equal(t, true, nskm["MenuBar Main"])
assert.Equal(t, []interface{}{"MenuBar Main", "MenuBar AvailableSpace", "CoreGraphics Window ID"}, nskm["_NSDictionaryKeys"])
assert.Equal(t, float64(1053), nskm["MenuBar AvailableSpace"])
}
}

func TestArchiveSlice(t *testing.T) {
var option = make(map[string]interface{})
option["name"] = "james"
Expand Down
22 changes: 21 additions & 1 deletion ios/nskeyedarchiver/archiverutils.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,30 @@ import (
"bytes"
"encoding/json"
"fmt"

plist "howett.net/plist"
"regexp"
)

func areNumeric(keys []string) bool {
for _, key := range keys {
match, _ := regexp.MatchString("\\$[0-9]+", key)
if !match {
return false
}
}
return true
}

func getKeysOfMap(themap map[string]interface{}) []string {
result := make([]string, len(themap))
i := 0
for key, _ := range themap {
result[i] = key
i++
}
return result
}

func toInterfaceSlice(stringSlice []string) []interface{} {
result := make([]interface{}, len(stringSlice))
for i, e := range stringSlice {
Expand Down
Binary file added ios/nskeyedarchiver/fixtures/savedstate.plist
Binary file not shown.
31 changes: 25 additions & 6 deletions ios/nskeyedarchiver/unarchiver.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,32 @@ func extractObjectsFromTop(top map[string]interface{}, objects []interface{}) ([
if root, ok := top["root"]; ok {
return extractObjects([]plist.UID{root.(plist.UID)}, objects)
}

objectRefs := make([]plist.UID, objectCount)
//convert the Dictionary with the objectReferences into a flat list of UIDs, so we can reuse the extractObjects function later
for i := 0; i < objectCount; i++ {
objectIndex := top[fmt.Sprintf("$%d", i)].(plist.UID)
keys := getKeysOfMap(top)
//if all keys are like $0, $1 etc. the code returns an array
if areNumeric(keys) {
for i := 0; i < objectCount; i++ {
objectIndex := top[fmt.Sprintf("$%d", i)].(plist.UID)
objectRefs[i] = objectIndex
}
return extractObjects(objectRefs, objects)
}
// otherwise return a map as the only object in []interface{}
for i, key := range keys {
objectIndex := top[key].(plist.UID)
objectRefs[i] = objectIndex
}
return extractObjects(objectRefs, objects)
extractedObjects, err := extractObjects(objectRefs, objects)
if err != nil {
return extractedObjects, err
}

result := map[string]interface{}{}
for i, key := range keys {
result[key] = extractedObjects[i]
}
return []interface{}{result}, nil
}

func extractObjects(objectRefs []plist.UID, objects []interface{}) ([]interface{}, error) {
Expand All @@ -52,8 +71,8 @@ func extractObjects(objectRefs []plist.UID, objects []interface{}) ([]interface{
continue
}
//if this crashes, I forgot a primitive type
nonPrimitiveObjectRef,ok := objectRef.(map[string]interface{})
if !ok{
nonPrimitiveObjectRef, ok := objectRef.(map[string]interface{})
if !ok {
return []interface{}{}, fmt.Errorf("object not a dictionary: %+v", objectRef)
}
if object, ok := isArrayObject(nonPrimitiveObjectRef, objects); ok {
Expand Down