Skip to content

Commit 96444fb

Browse files
committed
fix: add try-catch protection to JSON.parse in config API routes
Prevent crashes from malformed snapshot JSON by wrapping all JSON.parse calls in try-catch blocks across config API endpoints.
1 parent baf4508 commit 96444fb

File tree

3 files changed

+58
-12
lines changed

3 files changed

+58
-12
lines changed

src/routes/api/configs/+server.ts

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,21 @@ export const GET: RequestHandler = async ({ platform, cookies, request }) => {
2121
.bind(user.id)
2222
.all();
2323

24-
const configs = results.map((config: any) => ({
25-
...config,
26-
snapshot: config.snapshot ? JSON.parse(config.snapshot) : null
27-
}));
24+
const configs = results.map((config: any) => {
25+
let snapshot = null;
26+
if (config.snapshot) {
27+
try {
28+
snapshot = JSON.parse(config.snapshot);
29+
} catch {
30+
// Invalid JSON in database - return null instead of crashing
31+
snapshot = null;
32+
}
33+
}
34+
return {
35+
...config,
36+
snapshot
37+
};
38+
});
2839

2940
return json({ configs, username: user.username });
3041
};

src/routes/api/configs/[slug]/+server.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,20 @@ export const GET: RequestHandler = async ({ platform, cookies, params, request }
4646
return p;
4747
});
4848

49+
let parsedSnapshot = null;
50+
if (config.snapshot) {
51+
try {
52+
parsedSnapshot = JSON.parse(config.snapshot as string);
53+
} catch {
54+
parsedSnapshot = null;
55+
}
56+
}
57+
4958
return json({
5059
config: {
5160
...config,
5261
packages,
53-
snapshot: config.snapshot ? JSON.parse(config.snapshot as string) : null
62+
snapshot: parsedSnapshot
5463
},
5564
install_url: installUrl
5665
});

src/routes/api/configs/from-snapshot/+server.ts

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -61,11 +61,24 @@ export const POST: RequestHandler = async ({ platform, cookies, request }) => {
6161
'SELECT id, slug, name, description, base_preset, packages, snapshot, snapshot_at, visibility FROM configs WHERE user_id = ? AND slug = ?'
6262
).bind(user.id, config_slug).first();
6363

64-
return json({
65-
...updated,
66-
snapshot: JSON.parse((updated as any).snapshot),
67-
packages: JSON.parse((updated as any).packages)
68-
});
64+
let parsedSnapshot = null;
65+
let parsedPackages = [];
66+
try {
67+
parsedSnapshot = JSON.parse((updated as any).snapshot);
68+
} catch {
69+
parsedSnapshot = null;
70+
}
71+
try {
72+
parsedPackages = JSON.parse((updated as any).packages);
73+
} catch {
74+
parsedPackages = [];
75+
}
76+
77+
return json({
78+
...updated,
79+
snapshot: parsedSnapshot,
80+
packages: parsedPackages
81+
});
6982
}
7083

7184
const configCount = await env.DB.prepare(
@@ -119,9 +132,22 @@ export const POST: RequestHandler = async ({ platform, cookies, request }) => {
119132
'SELECT id, slug, name, description, base_preset, packages, snapshot, snapshot_at, visibility FROM configs WHERE id = ?'
120133
).bind(id).first();
121134

135+
let createdSnapshot = null;
136+
let createdPackages = [];
137+
try {
138+
createdSnapshot = JSON.parse((created as any).snapshot);
139+
} catch {
140+
createdSnapshot = null;
141+
}
142+
try {
143+
createdPackages = JSON.parse((created as any).packages);
144+
} catch {
145+
createdPackages = [];
146+
}
147+
122148
return json({
123149
...created,
124-
snapshot: JSON.parse((created as any).snapshot),
125-
packages: JSON.parse((created as any).packages)
150+
snapshot: createdSnapshot,
151+
packages: createdPackages
126152
}, { status: 201 });
127153
};

0 commit comments

Comments
 (0)