Skip to content

Commit 0fa294b

Browse files
authored
fix: add acceptance test for s3 object path sanitization (#1239)
1 parent 789b8a6 commit 0fa294b

1 file changed

Lines changed: 58 additions & 0 deletions

File tree

acceptance/specs/s3.test.ts

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,64 @@ describeAcceptance(
339339
client.destroy()
340340
}
341341
})
342+
343+
it('correctly handles objects with special characters in key', async () => {
344+
const client = createAcceptanceS3Client()
345+
const bucketName = uniqueBucketName('s3chars')
346+
const keyFullyValid = uniqueObjectKey("test!$&'() *+,:;=@ing", 'bin')
347+
const keyInvalid = uniqueObjectKey('test[]^|ing', 'bin')
348+
349+
const payload = Buffer.from('acceptance-s3-char-key')
350+
351+
try {
352+
await client.send(new CreateBucketCommand({ Bucket: bucketName }))
353+
354+
// storage api rejects []^| but does not hit a signature rejection due to escaping
355+
await expect(
356+
client.send(
357+
new PutObjectCommand({
358+
Body: payload,
359+
Bucket: bucketName,
360+
ContentType: 'application/octet-stream',
361+
Key: keyInvalid,
362+
})
363+
)
364+
).rejects.toThrow('Invalid key: ' + keyInvalid)
365+
366+
await client.send(
367+
new PutObjectCommand({
368+
Body: payload,
369+
Bucket: bucketName,
370+
ContentType: 'application/octet-stream',
371+
Key: keyFullyValid,
372+
})
373+
)
374+
375+
const downloaded = await client.send(
376+
new GetObjectCommand({
377+
Bucket: bucketName,
378+
Key: keyFullyValid,
379+
})
380+
)
381+
expect(await downloaded.Body?.transformToString()).toBe(payload.toString())
382+
383+
const listed = await client.send(
384+
new ListObjectsV2Command({
385+
Bucket: bucketName,
386+
Prefix: keyFullyValid.split('/')[0],
387+
})
388+
)
389+
expect(listed.Contents?.map((object) => object.Key)).toContain(keyFullyValid)
390+
391+
const deleted = await client.send(
392+
new DeleteObjectCommand({ Bucket: bucketName, Key: keyFullyValid })
393+
)
394+
expect(deleted.$metadata.httpStatusCode).toBe(204)
395+
} finally {
396+
await cleanupS3Bucket(client, bucketName)
397+
client.destroy()
398+
}
399+
})
342400
}
343401
)
344402

0 commit comments

Comments
 (0)