Skip to content

Commit 72288c3

Browse files
authored
fix: ZIP files always use forward slashes / regardless of the operating system (#616)
1 parent da9b7ae commit 72288c3

2 files changed

Lines changed: 125 additions & 3 deletions

File tree

pkg/bundle_packager/memory_zip.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import (
44
"archive/zip"
55
"bytes"
66
"io"
7-
"path/filepath"
87
"strings"
98

109
"github.com/langgenius/dify-plugin-daemon/pkg/entities/bundle_entities"
@@ -64,7 +63,9 @@ func NewMemoryZipBundlePackager(zipFile []byte) (*MemoryZipBundlePackager, error
6463
// walk through the zip file and load the assets
6564
for _, file := range zipReader.File {
6665
// if file starts with "_assets/"
67-
if strings.HasPrefix(file.Name, "_assets"+string(filepath.Separator)) {
66+
// FIXES: https://github.com/langgenius/dify/issues/32650
67+
// zip file is os-independent, `/` is the separator
68+
if strings.HasPrefix(file.Name, "_assets/") {
6869
// load the asset
6970
asset, err := file.Open()
7071
if err != nil {
@@ -78,7 +79,7 @@ func NewMemoryZipBundlePackager(zipFile []byte) (*MemoryZipBundlePackager, error
7879
}
7980

8081
// trim the prefix "_assets/"
81-
assetName := strings.TrimPrefix(file.Name, "_assets"+string(filepath.Separator))
82+
assetName := strings.TrimPrefix(file.Name, "_assets/")
8283

8384
packager.assets[assetName] = bytes.NewBuffer(assetBytes)
8485
}
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
package bundle_packager
2+
3+
import (
4+
"archive/zip"
5+
"bytes"
6+
"testing"
7+
8+
"github.com/stretchr/testify/assert"
9+
)
10+
11+
func TestNewMemoryZipBundlePackager_AssetsExtraction(t *testing.T) {
12+
// Create a test ZIP file with assets
13+
zipBuffer := bytes.NewBuffer([]byte{})
14+
zipWriter := zip.NewWriter(zipBuffer)
15+
16+
// Add manifest.yaml
17+
manifest, err := zipWriter.Create("manifest.yaml")
18+
assert.NoError(t, err)
19+
_, err = manifest.Write([]byte("version: 0.0.1\nname: test-bundle\n"))
20+
assert.NoError(t, err)
21+
22+
// Add assets in _assets directory using forward slashes (ZIP standard)
23+
asset1, err := zipWriter.Create("_assets/icon.png")
24+
assert.NoError(t, err)
25+
_, err = asset1.Write([]byte("fake-png-data"))
26+
assert.NoError(t, err)
27+
28+
asset2, err := zipWriter.Create("_assets/logo.svg")
29+
assert.NoError(t, err)
30+
_, err = asset2.Write([]byte("fake-svg-data"))
31+
assert.NoError(t, err)
32+
33+
// Add nested asset
34+
asset3, err := zipWriter.Create("_assets/subdir/image.jpg")
35+
assert.NoError(t, err)
36+
_, err = asset3.Write([]byte("fake-jpg-data"))
37+
assert.NoError(t, err)
38+
39+
err = zipWriter.Close()
40+
assert.NoError(t, err)
41+
42+
// Test MemoryZipBundlePackager
43+
packager, err := NewMemoryZipBundlePackager(zipBuffer.Bytes())
44+
assert.NoError(t, err)
45+
assert.NotNil(t, packager)
46+
47+
// Verify assets are correctly extracted
48+
assets, err := packager.Assets()
49+
assert.NoError(t, err)
50+
assert.Len(t, assets, 3)
51+
52+
// Check each asset exists with correct content (without _assets prefix)
53+
assert.Contains(t, assets, "icon.png")
54+
assert.Equal(t, []byte("fake-png-data"), assets["icon.png"])
55+
56+
assert.Contains(t, assets, "logo.svg")
57+
assert.Equal(t, []byte("fake-svg-data"), assets["logo.svg"])
58+
59+
assert.Contains(t, assets, "subdir/image.jpg")
60+
assert.Equal(t, []byte("fake-jpg-data"), assets["subdir/image.jpg"])
61+
}
62+
63+
func TestNewMemoryZipBundlePackager_NoAssets(t *testing.T) {
64+
// Create a test ZIP file without assets
65+
zipBuffer := bytes.NewBuffer([]byte{})
66+
zipWriter := zip.NewWriter(zipBuffer)
67+
68+
// Add manifest.yaml only
69+
manifest, err := zipWriter.Create("manifest.yaml")
70+
assert.NoError(t, err)
71+
_, err = manifest.Write([]byte("version: 0.0.1\nname: test-bundle\n"))
72+
assert.NoError(t, err)
73+
74+
err = zipWriter.Close()
75+
assert.NoError(t, err)
76+
77+
// Test MemoryZipBundlePackager
78+
packager, err := NewMemoryZipBundlePackager(zipBuffer.Bytes())
79+
assert.NoError(t, err)
80+
assert.NotNil(t, packager)
81+
82+
// Verify no assets are extracted
83+
assets, err := packager.Assets()
84+
assert.NoError(t, err)
85+
assert.Len(t, assets, 0)
86+
}
87+
88+
func TestNewMemoryZipBundlePackager_ReadFile(t *testing.T) {
89+
// Create a test ZIP file
90+
zipBuffer := bytes.NewBuffer([]byte{})
91+
zipWriter := zip.NewWriter(zipBuffer)
92+
93+
// Add manifest.yaml
94+
manifest, err := zipWriter.Create("manifest.yaml")
95+
assert.NoError(t, err)
96+
_, err = manifest.Write([]byte("version: 0.0.1\nname: test-bundle\n"))
97+
assert.NoError(t, err)
98+
99+
// Add a non-asset file
100+
readme, err := zipWriter.Create("README.md")
101+
assert.NoError(t, err)
102+
_, err = readme.Write([]byte("# Test Bundle"))
103+
assert.NoError(t, err)
104+
105+
err = zipWriter.Close()
106+
assert.NoError(t, err)
107+
108+
// Test MemoryZipBundlePackager
109+
packager, err := NewMemoryZipBundlePackager(zipBuffer.Bytes())
110+
assert.NoError(t, err)
111+
assert.NotNil(t, packager)
112+
113+
// Test reading file
114+
content, err := packager.ReadFile("README.md")
115+
assert.NoError(t, err)
116+
assert.Equal(t, []byte("# Test Bundle"), content)
117+
118+
// Test reading non-existent file
119+
_, err = packager.ReadFile("nonexistent.md")
120+
assert.Error(t, err)
121+
}

0 commit comments

Comments
 (0)