Skip to content

Commit 9a63ad1

Browse files
authored
Merge branch 'master' into ref-get-set-legal-hold
2 parents dc1a330 + 4f53378 commit 9a63ad1

File tree

3 files changed

+78
-4
lines changed

3 files changed

+78
-4
lines changed

src/internal/helper.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,10 @@ export function sanitizeObjectKey(objectName: string): string {
462462
return decodeURIComponent(asStrName)
463463
}
464464

465+
export function sanitizeSize(size?: string): number | undefined {
466+
return size ? Number.parseInt(size) : undefined
467+
}
468+
465469
export const PART_CONSTRAINTS = {
466470
// absMinPartSize - absolute minimum part size (5 MiB)
467471
ABS_MIN_PART_SIZE: 1024 * 1024 * 5,

src/xml-parsers.js

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,27 @@
1515
*/
1616

1717
import crc32 from 'buffer-crc32'
18+
import { XMLParser } from 'fast-xml-parser'
1819

1920
import * as errors from './errors.ts'
2021
import { SelectResults } from './helpers.ts'
21-
import { isObject, parseXml, readableStream, sanitizeETag, sanitizeObjectKey, toArray } from './internal/helper.ts'
22+
import {
23+
isObject,
24+
parseXml,
25+
readableStream,
26+
sanitizeETag,
27+
sanitizeObjectKey,
28+
sanitizeSize,
29+
toArray,
30+
} from './internal/helper.ts'
2231
import { RETENTION_VALIDITY_UNITS } from './internal/type.ts'
2332

33+
const fxpWithoutNumParser = new XMLParser({
34+
numberParseOptions: {
35+
skipLike: /./,
36+
},
37+
})
38+
2439
// parse XML response for copy object
2540
export function parseCopyObject(xml) {
2641
var result = {
@@ -201,12 +216,13 @@ const formatObjInfo = (content, opts = {}) => {
201216
const name = sanitizeObjectKey(toArray(Key)[0])
202217
const lastModified = new Date(toArray(LastModified)[0])
203218
const etag = sanitizeETag(toArray(ETag)[0])
219+
const size = sanitizeSize(Size)
204220

205221
return {
206222
name,
207223
lastModified,
208224
etag,
209-
size: Size,
225+
size,
210226
versionId: VersionId,
211227
isLatest: IsLatest,
212228
isDeleteMarker: opts.IsDeleteMarker ? opts.IsDeleteMarker : false,
@@ -221,7 +237,7 @@ export function parseListObjects(xml) {
221237
}
222238
let isTruncated = false
223239
let nextMarker, nextVersionKeyMarker
224-
const xmlobj = parseXml(xml)
240+
const xmlobj = fxpWithoutNumParser.parse(xml)
225241

226242
const parseCommonPrefixesEntity = (responseEntity) => {
227243
if (responseEntity) {
@@ -243,7 +259,7 @@ export function parseListObjects(xml) {
243259
const name = sanitizeObjectKey(toArray(content.Key)[0])
244260
const lastModified = new Date(toArray(content.LastModified)[0])
245261
const etag = sanitizeETag(toArray(content.ETag)[0])
246-
const size = content.Size
262+
const size = sanitizeSize(content.Size)
247263
result.objects.push({ name, lastModified, etag, size })
248264
})
249265
}

tests/unit/test.js

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import {
2929
partsRequired,
3030
} from '../../src/internal/helper.ts'
3131
import * as Minio from '../../src/minio.js'
32+
import { parseListObjects } from '../../src/xml-parsers.js'
3233

3334
const Package = { version: 'development' }
3435

@@ -2170,3 +2171,56 @@ describe('IP Address Validations', () => {
21702171
})
21712172
})
21722173
})
2174+
2175+
describe('xml-parser', () => {
2176+
describe('#listObjects()', () => {
2177+
describe('value type casting', () => {
2178+
const xml = `
2179+
<?xml version="1.0" encoding="UTF-8"?>
2180+
<ListVersionsResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
2181+
<Name>some-bucket</Name>
2182+
<Prefix>42</Prefix>
2183+
<Delimiter>/</Delimiter>
2184+
<IsTruncated>false</IsTruncated>
2185+
<EncodingType>url</EncodingType>
2186+
<KeyMarker/>
2187+
<VersionIdMarker/>
2188+
<Version>
2189+
<IsLatest>true</IsLatest>
2190+
<VersionId>1234</VersionId>
2191+
<ETag>"767dedcb515a0e2d995ed95191b75484-29"</ETag>
2192+
<Key>1337</Key>
2193+
<LastModified>2023-07-12T14:41:46.000Z</LastModified>
2194+
<Size>151306240</Size>
2195+
</Version>
2196+
<DeleteMarker>
2197+
<IsLatest>false</IsLatest>
2198+
<Key>1337</Key>
2199+
<LastModified>2023-07-12T14:39:22.000Z</LastModified>
2200+
<VersionId>5678</VersionId>
2201+
</DeleteMarker>
2202+
<CommonPrefixes>
2203+
<Prefix>42</Prefix>
2204+
</CommonPrefixes>
2205+
</ListVersionsResult>
2206+
`
2207+
2208+
it('should parse VersionId as string even if number is provided', () => {
2209+
const { objects } = parseListObjects(xml)
2210+
2211+
assert.equal(objects[0].versionId, '1234')
2212+
assert.equal(objects[1].versionId, '5678')
2213+
assert.equal(objects[0].name, '1337')
2214+
assert.equal(objects[1].name, '1337')
2215+
assert.deepEqual(objects[2], { prefix: '42', size: 0 })
2216+
})
2217+
2218+
it('should parse Size as number', () => {
2219+
const { objects } = parseListObjects(xml)
2220+
2221+
assert.equal(objects[0].size, 151306240)
2222+
assert.equal(objects[1].size, undefined)
2223+
})
2224+
})
2225+
})
2226+
})

0 commit comments

Comments
 (0)