diff --git a/app/pnpm-lock.yaml b/app/pnpm-lock.yaml
index 1191b5269..8eb0b583b 100644
--- a/app/pnpm-lock.yaml
+++ b/app/pnpm-lock.yaml
@@ -11,9 +11,6 @@ importers:
'@electron/remote':
specifier: ^2.1.3
version: 2.1.3(electron@39.2.7)
- pretty-bytes:
- specifier: ^7.1.0
- version: 7.1.0
devDependencies:
'@eslint/eslintrc':
specifier: ^3.3.1
@@ -60,6 +57,9 @@ importers:
file-loader:
specifier: ^6.2.0
version: 6.2.0(webpack@5.101.3)
+ filesize:
+ specifier: ^11.0.13
+ version: 11.0.13
globals:
specifier: ^15.12.0
version: 15.15.0
@@ -1395,6 +1395,10 @@ packages:
filelist@1.0.4:
resolution: {integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==}
+ filesize@11.0.13:
+ resolution: {integrity: sha512-mYJ/qXKvREuO0uH8LTQJ6v7GsUvVOguqxg2VTwQUkyTPXXRRWPdjuUPVqdBrJQhvci48OHlNGRnux+Slr2Rnvw==}
+ engines: {node: '>= 10.8.0'}
+
fill-range@7.1.1:
resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
engines: {node: '>=8'}
@@ -2228,10 +2232,6 @@ packages:
resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
engines: {node: '>= 0.8.0'}
- pretty-bytes@7.1.0:
- resolution: {integrity: sha512-nODzvTiYVRGRqAOvE84Vk5JDPyyxsVk0/fbA/bq7RqlnhksGpset09XTxbpvLTIjoaF7K8Z8DG8yHtKGTPSYRw==}
- engines: {node: '>=20'}
-
pretty-error@4.0.0:
resolution: {integrity: sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==}
@@ -4263,6 +4263,8 @@ snapshots:
dependencies:
minimatch: 5.1.6
+ filesize@11.0.13: {}
+
fill-range@7.1.1:
dependencies:
to-regex-range: 5.0.1
@@ -5108,8 +5110,6 @@ snapshots:
prelude-ls@1.2.1: {}
- pretty-bytes@7.1.0: {}
-
pretty-error@4.0.0:
dependencies:
lodash: 4.17.21
diff --git a/app/src/asset/anno.ts b/app/src/asset/anno.ts
index aec90b224..a91098ded 100644
--- a/app/src/asset/anno.ts
+++ b/app/src/asset/anno.ts
@@ -743,7 +743,7 @@ const copyAnno = (idPath: string, fileName: string, pdf: any) => {
const imageName = content + ".png";
let msg = "";
if (Constants.SIZE_UPLOAD_TIP_SIZE <= blob.size) {
- msg = window.siyuan.languages.uploadFileTooLarge.replace("${x}", imageName).replace("${y}", filesize(blob.size, {standard: "jedec"}));
+ msg = window.siyuan.languages.uploadFileTooLarge.replace("${x}", imageName).replace("${y}", filesize(blob.size, {standard: "iec"}));
}
confirmDialog(msg ? window.siyuan.languages.upload : "", msg, () => {
const formData = new FormData();
diff --git a/app/src/protyle/render/av/asset.ts b/app/src/protyle/render/av/asset.ts
index 7a2af2f19..3a8169f0b 100644
--- a/app/src/protyle/render/av/asset.ts
+++ b/app/src/protyle/render/av/asset.ts
@@ -427,7 +427,7 @@ export const dragUpload = (files: ILocalFiles[], protyle: IProtyle, cellElement:
const assetPaths: string[] = [];
files.forEach(item => {
if (item.size && Constants.SIZE_UPLOAD_TIP_SIZE <= item.size) {
- msg += window.siyuan.languages.uploadFileTooLarge.replace("${x}", item.path).replace("${y}", filesize(item.size, {standard: "jedec"})) + "
";
+ msg += window.siyuan.languages.uploadFileTooLarge.replace("${x}", item.path).replace("${y}", filesize(item.size, {standard: "iec"})) + "
";
}
assetPaths.push(item.path);
});
diff --git a/app/src/protyle/upload/index.ts b/app/src/protyle/upload/index.ts
index 0947dae47..3a736c1ed 100644
--- a/app/src/protyle/upload/index.ts
+++ b/app/src/protyle/upload/index.ts
@@ -220,7 +220,7 @@ export const uploadLocalFiles = (files: ILocalFiles[], protyle: IProtyle, isUplo
const assetPaths: string[] = [];
files.forEach(item => {
if (item.size && Constants.SIZE_UPLOAD_TIP_SIZE <= item.size) {
- msg += window.siyuan.languages.uploadFileTooLarge.replace("${x}", item.path).replace("${y}", filesize(item.size, {standard: "jedec"})) + "
";
+ msg += window.siyuan.languages.uploadFileTooLarge.replace("${x}", item.path).replace("${y}", filesize(item.size, {standard: "iec"})) + "
";
}
assetPaths.push(item.path);
});
@@ -311,7 +311,7 @@ export const uploadFiles = (protyle: IProtyle, files: FileList | DataTransferIte
for (let i = 0, iMax = validateResult.files.length; i < iMax; i++) {
formData.append(protyle.options.upload.fieldName, validateResult.files[i]);
if (Constants.SIZE_UPLOAD_TIP_SIZE <= validateResult.files[i].size) {
- msg += window.siyuan.languages.uploadFileTooLarge.replace("${x}", validateResult.files[i].name).replace("${y}", filesize(validateResult.files[i].size, {standard: "jedec"})) + "
";
+ msg += window.siyuan.languages.uploadFileTooLarge.replace("${x}", validateResult.files[i].name).replace("${y}", filesize(validateResult.files[i].size, {standard: "iec"})) + "
";
}
}
diff --git a/kernel/server/serve.go b/kernel/server/serve.go
index e55ee92d2..ed1f6c7e7 100644
--- a/kernel/server/serve.go
+++ b/kernel/server/serve.go
@@ -265,7 +265,39 @@ func rewritePortJSON(pid, port string) {
func serveExport(ginServer *gin.Engine) {
// Potential data export disclosure security vulnerability https://github.com/siyuan-note/siyuan/issues/12213
exportGroup := ginServer.Group("/export/", model.CheckAuth)
- exportGroup.Static("/", filepath.Join(util.TempDir, "export"))
+ exportBaseDir := filepath.Join(util.TempDir, "export")
+
+ // 应下载而不是查看导出的文件
+ exportGroup.GET("/*filepath", func(c *gin.Context) {
+ filePath := strings.TrimPrefix(c.Request.URL.Path, "/export/")
+
+ decodedPath, err := url.PathUnescape(filePath)
+ if err != nil {
+ decodedPath = filePath
+ }
+
+ fullPath := filepath.Join(exportBaseDir, decodedPath)
+
+ fileInfo, err := os.Stat(fullPath)
+ if os.IsNotExist(err) {
+ c.Status(http.StatusNotFound)
+ return
+ }
+ if err != nil {
+ c.Status(http.StatusInternalServerError)
+ return
+ }
+
+ if fileInfo.IsDir() {
+ c.Status(http.StatusNotFound)
+ return
+ }
+
+ fileName := filepath.Base(decodedPath)
+ c.Header("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s\"", fileName))
+
+ c.File(fullPath)
+ })
}
func serveWidgets(ginServer *gin.Engine) {