kingkont 0.7.89 → 0.7.90
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/renderer/state.js +31 -0
package/package.json
CHANGED
package/renderer/state.js
CHANGED
|
@@ -86,7 +86,38 @@ async function fileExists(handle, name) {
|
|
|
86
86
|
try { await handle.getFileHandle(name); return true; } catch { return false; }
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
+
// Имена из внешних источников (drag-drop из Telegram/чатов, paste, импорт)
|
|
90
|
+
// часто содержат символы, недопустимые для File-System-Access-API: двоеточия
|
|
91
|
+
// (timestamp'ы вроде «IMAGE 16:48:03.jpg»), слэши, *, ? и control-символы.
|
|
92
|
+
// FS-Access-API строго следует правилам Windows-FS, поэтому даже на macOS
|
|
93
|
+
// getFileHandle('foo:bar.jpg') бросает 'Name is not allowed'.
|
|
94
|
+
function sanitizeFilename(name) {
|
|
95
|
+
if (!name) return 'file';
|
|
96
|
+
let safe = String(name)
|
|
97
|
+
.replace(/[\\/:*?"<>|\x00-\x1F]/g, '-') // зарезервированные + control-chars
|
|
98
|
+
.replace(/^\.+/, '') // имя не должно начинаться с точки
|
|
99
|
+
.replace(/[. ]+$/, '') // и не должно кончаться на точку/пробел (Windows)
|
|
100
|
+
.trim();
|
|
101
|
+
if (!safe) safe = 'file';
|
|
102
|
+
// Зарезервированные базовые имена Windows.
|
|
103
|
+
const reserved = /^(CON|PRN|AUX|NUL|COM[1-9]|LPT[1-9])(\..*)?$/i;
|
|
104
|
+
if (reserved.test(safe)) safe = '_' + safe;
|
|
105
|
+
// Лимит длины (NTFS = 255, оставляем запас под суффикс _N).
|
|
106
|
+
if (safe.length > 200) {
|
|
107
|
+
const dot = safe.lastIndexOf('.');
|
|
108
|
+
if (dot > 0 && safe.length - dot < 20) {
|
|
109
|
+
safe = safe.slice(0, 200 - (safe.length - dot)) + safe.slice(dot);
|
|
110
|
+
} else {
|
|
111
|
+
safe = safe.slice(0, 200);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return safe;
|
|
115
|
+
}
|
|
116
|
+
|
|
89
117
|
async function uniqueName(handle, name) {
|
|
118
|
+
// Always sanitize — uniqueName это «бутылочное горлышко» для всех импортов
|
|
119
|
+
// и записей с внешними именами. Если уже sanitized — операция идемпотентна.
|
|
120
|
+
name = sanitizeFilename(name);
|
|
90
121
|
if (!(await fileExists(handle, name))) return name;
|
|
91
122
|
const dot = name.lastIndexOf('.');
|
|
92
123
|
const base = dot > 0 ? name.slice(0, dot) : name;
|