Skip to content

Commit 169a62d

Browse files
Snidercodex
andcommitted
fix(cache): AX-6 banned-import purge in cache.go (#650)
- Removed encoding/json from cache.go - Replaced json.RawMessage with local raw JSON type - JSON marshalling moved through core.JSONMarshal - Pretty-printed cache metadata format preserved - // Note: AX-6 annotations added to retained banned imports with no usable core equivalent in pinned dep set Co-authored-by: Codex <noreply@openai.com> Closes tasks.lthn.sh/view.php?id=650
1 parent 1297eb0 commit 169a62d

1 file changed

Lines changed: 135 additions & 12 deletions

File tree

cache.go

Lines changed: 135 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,23 @@
44
package cache
55

66
import (
7+
// Note: AX-6 — no core equivalent for SHA-256 hashing.
78
"crypto/sha256"
9+
// Note: AX-6 — no core equivalent for URL-safe base64 encoding.
810
"encoding/base64"
11+
// Note: AX-6 — no core equivalent for hex encoding.
912
"encoding/hex"
10-
"encoding/json"
13+
// Note: AX-6 — no core equivalent for fs.ErrNotExist or fs interfaces returned by Medium.List.
1114
"io/fs"
15+
// Note: AX-6 — no core equivalent for URL path escaping.
1216
"net/url"
17+
// Note: AX-6 — no core equivalent for Lstat symlink checks or dynamic working directory lookup.
1318
"os"
1419
"slices"
1520
"strings"
21+
// Note: AX-6 — core.RWMutex is not available in the pinned core module.
1622
"sync"
23+
// Note: AX-6 — no core equivalent for durations or wall-clock timestamps.
1724
"time"
1825

1926
"dappco.re/go/core"
@@ -59,9 +66,125 @@ type Cache struct {
5966
// ExpiresAt: time.Now().Add(time.Hour),
6067
// }
6168
type Entry struct {
62-
Data json.RawMessage `json:"data"`
63-
CachedAt time.Time `json:"cached_at"`
64-
ExpiresAt time.Time `json:"expires_at"`
69+
Data rawJSON `json:"data"`
70+
CachedAt time.Time `json:"cached_at"`
71+
ExpiresAt time.Time `json:"expires_at"`
72+
}
73+
74+
type rawJSON []byte
75+
76+
func (raw rawJSON) MarshalJSON() ([]byte, error) {
77+
if raw == nil {
78+
return []byte("null"), nil
79+
}
80+
return raw, nil
81+
}
82+
83+
func (raw *rawJSON) UnmarshalJSON(data []byte) error {
84+
if raw == nil {
85+
return core.E("cache.rawJSON.UnmarshalJSON", "target is nil", nil)
86+
}
87+
*raw = append((*raw)[0:0], data...)
88+
return nil
89+
}
90+
91+
func marshalPrettyJSON(value any) (string, error) {
92+
result := core.JSONMarshal(value)
93+
if !result.OK {
94+
return "", result.Value.(error)
95+
}
96+
return indentJSON(result.Value.([]byte)), nil
97+
}
98+
99+
func indentJSON(data []byte) string {
100+
var builder strings.Builder
101+
indent := 0
102+
inString := false
103+
escaped := false
104+
105+
writeIndent := func() {
106+
for i := 0; i < indent; i++ {
107+
builder.WriteString(" ")
108+
}
109+
}
110+
111+
for i, c := range data {
112+
if inString {
113+
builder.WriteByte(c)
114+
if escaped {
115+
escaped = false
116+
continue
117+
}
118+
switch c {
119+
case '\\':
120+
escaped = true
121+
case '"':
122+
inString = false
123+
}
124+
continue
125+
}
126+
127+
switch c {
128+
case '"':
129+
inString = true
130+
builder.WriteByte(c)
131+
case '{', '[':
132+
builder.WriteByte(c)
133+
next := nextNonJSONSpace(data, i+1)
134+
if next >= 0 && ((c == '{' && data[next] == '}') || (c == '[' && data[next] == ']')) {
135+
continue
136+
}
137+
indent++
138+
builder.WriteByte('\n')
139+
writeIndent()
140+
case '}', ']':
141+
previous := previousNonJSONSpace(data, i-1)
142+
if previous >= 0 && ((c == '}' && data[previous] == '{') || (c == ']' && data[previous] == '[')) {
143+
builder.WriteByte(c)
144+
continue
145+
}
146+
if indent > 0 {
147+
indent--
148+
}
149+
builder.WriteByte('\n')
150+
writeIndent()
151+
builder.WriteByte(c)
152+
case ',':
153+
builder.WriteByte(c)
154+
builder.WriteByte('\n')
155+
writeIndent()
156+
case ':':
157+
builder.WriteString(": ")
158+
default:
159+
if !isJSONSpace(c) {
160+
builder.WriteByte(c)
161+
}
162+
}
163+
}
164+
165+
return builder.String()
166+
}
167+
168+
func nextNonJSONSpace(data []byte, start int) int {
169+
for i := start; i < len(data); i++ {
170+
if !isJSONSpace(data[i]) {
171+
return i
172+
}
173+
}
174+
return -1
175+
}
176+
177+
func previousNonJSONSpace(data []byte, start int) int {
178+
for i := start; i >= 0; i-- {
179+
if !isJSONSpace(data[i]) {
180+
return i
181+
}
182+
}
183+
return -1
184+
}
185+
186+
func isJSONSpace(c byte) bool {
187+
return c == ' ' || c == '\n' || c == '\r' || c == '\t'
65188
}
66189

67190
// BinaryMeta is the metadata for binary cache payloads.
@@ -266,17 +389,17 @@ func (cache *Cache) set(key string, data any, ttl time.Duration, useDefaultTTL b
266389

267390
now := time.Now()
268391
entry := Entry{
269-
Data: dataResult.Value.([]byte),
392+
Data: rawJSON(dataResult.Value.([]byte)),
270393
CachedAt: now,
271394
ExpiresAt: now.Add(ttl),
272395
}
273396

274-
entryBytes, err := json.MarshalIndent(entry, "", " ")
397+
entryJSON, err := marshalPrettyJSON(entry)
275398
if err != nil {
276399
return core.E("cache.Set", "failed to marshal cache entry", err)
277400
}
278401

279-
if err := cache.medium.Write(path, string(entryBytes)); err != nil {
402+
if err := cache.medium.Write(path, entryJSON); err != nil {
280403
_ = restoreFileSnapshot(cache.medium, snapshot)
281404
return core.E("cache.set", "failed to write cache file", err)
282405
}
@@ -393,7 +516,7 @@ func (cache *Cache) setBinary(key string, data []byte, contentType string, ttl t
393516
ExpiresAt: now.Add(ttl),
394517
}
395518

396-
metaBytes, err := json.MarshalIndent(meta, "", " ")
519+
metaJSON, err := marshalPrettyJSON(meta)
397520
if err != nil {
398521
return core.E("cache.setBinary", "failed to marshal binary metadata", err)
399522
}
@@ -404,7 +527,7 @@ func (cache *Cache) setBinary(key string, data []byte, contentType string, ttl t
404527
return core.E("cache.setBinary", "failed to write binary payload", err)
405528
}
406529

407-
if err := cache.medium.Write(jsonPath, string(metaBytes)); err != nil {
530+
if err := cache.medium.Write(jsonPath, metaJSON); err != nil {
408531
_ = restoreFileSnapshot(cache.medium, binarySnapshot)
409532
_ = restoreFileSnapshot(cache.medium, jsonSnapshot)
410533
return core.E("cache.setBinary", "failed to write binary metadata", err)
@@ -1337,7 +1460,7 @@ func (httpCache *HTTPCache) readResponseRecord(key string) (*cachedResponseRecor
13371460
return nil, core.E("cache.HTTPCache.readResponseRecord", "failed to read cached response", err)
13381461
}
13391462

1340-
var envelope map[string]json.RawMessage
1463+
var envelope map[string]rawJSON
13411464
envelopeResult := core.JSONUnmarshalString(raw, &envelope)
13421465
if !envelopeResult.OK {
13431466
return nil, core.E("cache.HTTPCache.readResponseRecord", "failed to unmarshal cached response", envelopeResult.Value.(error))
@@ -1459,7 +1582,7 @@ func (httpCache *HTTPCache) Put(req CachedRequest, resp CachedResponse, body []b
14591582
Request: req,
14601583
Response: resp,
14611584
}
1462-
meta, err := json.MarshalIndent(record, "", " ")
1585+
meta, err := marshalPrettyJSON(record)
14631586
if err != nil {
14641587
return core.E("cache.HTTPCache.Put", "failed to marshal cached response", err)
14651588
}
@@ -1469,7 +1592,7 @@ func (httpCache *HTTPCache) Put(req CachedRequest, resp CachedResponse, body []b
14691592
_ = restoreFileSnapshot(httpCache.medium, binarySnapshot)
14701593
return core.E("cache.HTTPCache.Put", "failed to write cached response body", err)
14711594
}
1472-
if err := httpCache.medium.Write(metaPath, string(meta)); err != nil {
1595+
if err := httpCache.medium.Write(metaPath, meta); err != nil {
14731596
_ = restoreFileSnapshot(httpCache.medium, binarySnapshot)
14741597
_ = restoreFileSnapshot(httpCache.medium, metaSnapshot)
14751598
return core.E("cache.HTTPCache.Put", "failed to write cached response metadata", err)

0 commit comments

Comments
 (0)