// DecodeJSON tries to decompress the given data. The call to decompress, fails // if the content was not compressed in the first place, which is identified by // a canary byte before the compressed data. If the data is not compressed, it // is JSON decoded directly. Otherwise the decompressed data will be JSON // decoded. func DecodeJSON(data []byte, out interface{}) error { if data == nil || len(data) == 0 { return fmt.Errorf("'data' being decoded is nil") } if out == nil { return fmt.Errorf("output parameter 'out' is nil") } // Decompress the data if it was compressed in the first place decompressedBytes, uncompressed, err := compressutil.Decompress(data) if err != nil { return fmt.Errorf("failed to decompress JSON: err: %v", err) } if !uncompressed && (decompressedBytes == nil || len(decompressedBytes) == 0) { return fmt.Errorf("decompressed data being decoded is invalid") } // If the input supplied failed to contain the compression canary, it // will be notified by the compression utility. Decode the decompressed // input. if !uncompressed { data = decompressedBytes } return DecodeJSONFromReader(bytes.NewReader(data), out) }
func testCore_MountTable_UpgradeToTyped_Common( t *testing.T, c *Core, testType string) { var path string var mt *MountTable switch testType { case "mounts": path = coreMountConfigPath mt = c.mounts case "audits": path = coreAuditConfigPath mt = c.audit case "credentials": path = coreAuthConfigPath mt = c.auth } // Save the expected table goodJson, err := json.Marshal(mt) if err != nil { t.Fatal(err) } // Create a pre-typed version mt.Type = "" for _, entry := range mt.Entries { entry.Table = "" } raw, err := json.Marshal(mt) if err != nil { t.Fatal(err) } if reflect.DeepEqual(raw, goodJson) { t.Fatalf("bad: values here should be different") } entry := &Entry{ Key: path, Value: raw, } if err := c.barrier.Put(entry); err != nil { t.Fatal(err) } var persistFunc func(*MountTable) error // It should load successfully and be upgraded and persisted switch testType { case "mounts": err = c.loadMounts() persistFunc = c.persistMounts mt = c.mounts case "credentials": err = c.loadCredentials() persistFunc = c.persistAuth mt = c.auth case "audits": err = c.loadAudits() persistFunc = c.persistAudit mt = c.audit } if err != nil { t.Fatal(err) } entry, err = c.barrier.Get(path) if err != nil { t.Fatal(err) } decompressedBytes, uncompressed, err := compressutil.Decompress(entry.Value) if err != nil { t.Fatal(err) } actual := decompressedBytes if uncompressed { actual = entry.Value } if strings.TrimSpace(string(actual)) != strings.TrimSpace(string(goodJson)) { t.Fatalf("bad: expected\n%s\nactual\n%s\n", string(goodJson), string(actual)) } // Now try saving invalid versions origTableType := mt.Type mt.Type = "foo" if err := persistFunc(mt); err == nil { t.Fatal("expected error") } if len(mt.Entries) > 0 { mt.Type = origTableType mt.Entries[0].Table = "bar" if err := persistFunc(mt); err == nil { t.Fatal("expected error") } mt.Entries[0].Table = mt.Type if err := persistFunc(mt); err != nil { t.Fatal(err) } } }