1
14
Fork
You've already forked s3mini
1

Fix XML parsing #4

Merged
Jolly_Good merged 2 commits from pavulon/s3mini:xml-fix into dev 2026年06月29日 14:52:32 +02:00
Contributor
Copy link

I've found that the simple XML parser util doesn't handle self-closing tags properly, so for a response like this:

Example
<?xml version='1.0' encoding='UTF-8'?>
<ListVersionsResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
 <Name>bucket</Name>
 <Prefix/>
 <KeyMarker/>
 <VersionIdMarker/>
 <MaxKeys>1000</MaxKeys>
 <IsTruncated>false</IsTruncated>
 <Version>
 <Key>file1.jpg</Key>
 <VersionId>1781648073.939709</VersionId>
 <IsLatest>true</IsLatest>
 <LastModified>2026年06月16日T22:14:34.000Z</LastModified>
 <Size>26702</Size>
 <Owner>
 <ID>user</ID>
 <DisplayName>user</DisplayName>
 </Owner>
 <StorageClass>STANDARD</StorageClass>
 </Version>
 <Version>
 <Key>file2.mp4</Key>
 <VersionId>1781648486.233691</VersionId>
 <IsLatest>true</IsLatest>
 <LastModified>2026年06月16日T22:21:26.000Z</LastModified>
 <Size>3217865</Size>
 <Owner>
 <ID>user</ID>
 <DisplayName>user</DisplayName>
 </Owner>
 <StorageClass>STANDARD</StorageClass>
 </Version>
</ListVersionsResult>

it would produce completely borked json

Before After
{
 "ListVersionsResult": {
 "Name": "bucket",
 "Key": {
 "MaxKeys": "1000",
 "IsTruncated": "false"
 },
 "VersionId": "1781648073.939709",
 "IsLatest": "true",
 "LastModified": "2026年06月16日T22:14:34.000Z",
 "Size": "26702",
 "Owner": {
 "ID": "user",
 "DisplayName": "user"
 },
 "StorageClass": "STANDARD",
 "Version": {
 "Key": "file2.mp4",
 "VersionId": "1781648486.233691",
 "IsLatest": "true",
 "LastModified": "2026年06月16日T22:21:26.000Z",
 "Size": "3217865",
 "Owner": {
 "ID": "user",
 "DisplayName": "user"
 },
 "StorageClass": "STANDARD"
 }
 }
}
{
 "ListVersionsResult": {
 "Name": "bucket",
 "Prefix": "",
 "KeyMarker": "",
 "VersionIdMarker": "",
 "MaxKeys": "1000",
 "IsTruncated": "false",
 "Version": [
 {
 "Key": "file1.jpg",
 "VersionId": "1781648073.939709",
 "IsLatest": "true",
 "LastModified": "2026年06月16日T22:14:34.000Z",
 "Size": "26702",
 "Owner": {
 "ID": "user",
 "DisplayName": "user"
 },
 "StorageClass": "STANDARD"
 },
 {
 "Key": "file2.mp4",
 "VersionId": "1781648486.233691",
 "IsLatest": "true",
 "LastModified": "2026年06月16日T22:21:26.000Z",
 "Size": "3217865",
 "Owner": {
 "ID": "user",
 "DisplayName": "user"
 },
 "StorageClass": "STANDARD"
 }
 ]
 }
}

I've also added some tests.

test:unit was using the default jest.config.js, so I've created a separate config so that

  • you don't need to set provider env variables to run it (seems like jest.config.js is meant mostly for test:providers?)
  • you can import source files in tests directly
I've found that the simple XML parser util doesn't handle self-closing tags properly, so for a response like this: <details> <summary>Example</summary> ```xml <?xml version='1.0' encoding='UTF-8'?> <ListVersionsResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> <Name>bucket</Name> <Prefix/> <KeyMarker/> <VersionIdMarker/> <MaxKeys>1000</MaxKeys> <IsTruncated>false</IsTruncated> <Version> <Key>file1.jpg</Key> <VersionId>1781648073.939709</VersionId> <IsLatest>true</IsLatest> <LastModified>2026年06月16日T22:14:34.000Z</LastModified> <Size>26702</Size> <Owner> <ID>user</ID> <DisplayName>user</DisplayName> </Owner> <StorageClass>STANDARD</StorageClass> </Version> <Version> <Key>file2.mp4</Key> <VersionId>1781648486.233691</VersionId> <IsLatest>true</IsLatest> <LastModified>2026年06月16日T22:21:26.000Z</LastModified> <Size>3217865</Size> <Owner> <ID>user</ID> <DisplayName>user</DisplayName> </Owner> <StorageClass>STANDARD</StorageClass> </Version> </ListVersionsResult> ``` </details> it would produce completely borked json <table> <tr> <th>Before</th> <th>After</th> </tr> <tr> <td> ```json { "ListVersionsResult": { "Name": "bucket", "Key": { "MaxKeys": "1000", "IsTruncated": "false" }, "VersionId": "1781648073.939709", "IsLatest": "true", "LastModified": "2026年06月16日T22:14:34.000Z", "Size": "26702", "Owner": { "ID": "user", "DisplayName": "user" }, "StorageClass": "STANDARD", "Version": { "Key": "file2.mp4", "VersionId": "1781648486.233691", "IsLatest": "true", "LastModified": "2026年06月16日T22:21:26.000Z", "Size": "3217865", "Owner": { "ID": "user", "DisplayName": "user" }, "StorageClass": "STANDARD" } } } ``` </td> <td> ```json { "ListVersionsResult": { "Name": "bucket", "Prefix": "", "KeyMarker": "", "VersionIdMarker": "", "MaxKeys": "1000", "IsTruncated": "false", "Version": [ { "Key": "file1.jpg", "VersionId": "1781648073.939709", "IsLatest": "true", "LastModified": "2026年06月16日T22:14:34.000Z", "Size": "26702", "Owner": { "ID": "user", "DisplayName": "user" }, "StorageClass": "STANDARD" }, { "Key": "file2.mp4", "VersionId": "1781648486.233691", "IsLatest": "true", "LastModified": "2026年06月16日T22:21:26.000Z", "Size": "3217865", "Owner": { "ID": "user", "DisplayName": "user" }, "StorageClass": "STANDARD" } ] } } ``` </td> </tr> </table> I've also added some tests. `test:unit` was using the default `jest.config.js`, so I've created a separate config so that - you don't need to set provider env variables to run it (seems like `jest.config.js` is meant mostly for `test:providers`?) - you can import source files in tests directly
add test
Some checks failed
SonarCloud analysis / SonarQube (pull_request) Failing after 52s
Test:e2e(all) / test (pull_request) Failing after 2m22s
e8ffb872f4

@pavulon thanks a lot for catching this and your contribtion! ❤️

I made a tiny adjustment to that REGEX ... test seems to be passing and SonarQube is also happy. Could you please checkout the DEV and doublecheck if its all fine.

@pavulon thanks a lot for catching this and your contribtion! ❤️ I made a tiny adjustment to that REGEX ... test seems to be passing and SonarQube is also happy. Could you please checkout the DEV and doublecheck if its all fine.
Author
Contributor
Copy link

Looks good, although figuring out why it had non-linear backtracking goes way over my head 😅

By the way, for @babel/preset-typescript I used version 7.x because jest is still using it.
With 8.x on dev branch I get a bunch of warnings when I run npm install

Looks good, although figuring out why it had non-linear backtracking goes way over my head 😅 By the way, for `@babel/preset-typescript` I used version 7.x because `jest` is still using it. \ With 8.x on `dev` branch I get a bunch of warnings when I run `npm install`

I despise every extra dependency ... how about switching to ts-jest - do you have any experience with that?

I despise every extra dependency ... how about switching to `ts-jest` - do you have any experience with that?
Sign in to join this conversation.
No reviewers
Milestone
Clear milestone
No items
No milestone
Projects
Clear projects
No items
No project
Assignees
Clear assignees
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
thinking_tools/s3mini!4
Reference in a new issue
thinking_tools/s3mini
No description provided.
Delete branch "pavulon/s3mini:xml-fix"

Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?