@mandujs/core 0.54.26 → 0.54.28
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
CHANGED
|
@@ -195,7 +195,20 @@ export function ErrorOverlay({
|
|
|
195
195
|
const handleKeyDown = (e: KeyboardEvent) => {
|
|
196
196
|
if (e.key === 'Escape') {
|
|
197
197
|
onClose();
|
|
198
|
-
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
// Don't hijack single-letter shortcuts while the user is typing in an
|
|
201
|
+
// editable element, or when a modifier is held (e.g. real Ctrl/Cmd+C).
|
|
202
|
+
const target = e.target as HTMLElement | null;
|
|
203
|
+
const isEditable = !!target && (
|
|
204
|
+
target.tagName === 'INPUT' ||
|
|
205
|
+
target.tagName === 'TEXTAREA' ||
|
|
206
|
+
target.isContentEditable
|
|
207
|
+
);
|
|
208
|
+
if (isEditable || e.ctrlKey || e.metaKey || e.altKey) {
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
if (e.key === 'i' || e.key === 'I') {
|
|
199
212
|
onIgnore();
|
|
200
213
|
} else if (e.key === 'c' || e.key === 'C') {
|
|
201
214
|
onCopy();
|
|
@@ -142,6 +142,12 @@ export class PersistenceManager {
|
|
|
142
142
|
activeTab: 'unknown',
|
|
143
143
|
},
|
|
144
144
|
});
|
|
145
|
+
// A repeatedly-failing flush (e.g. a non-quota storage error) must not
|
|
146
|
+
// let pendingEvents grow unbounded. Keep only the most recent batch.
|
|
147
|
+
const cap = this.config.maxPersistEvents;
|
|
148
|
+
if (this.pendingEvents.length > cap) {
|
|
149
|
+
this.pendingEvents = this.pendingEvents.slice(-cap);
|
|
150
|
+
}
|
|
145
151
|
}
|
|
146
152
|
}
|
|
147
153
|
|
|
@@ -174,11 +174,22 @@ export class SourceContextProvider {
|
|
|
174
174
|
* 안전한 경로 확인 (Path Traversal 방지)
|
|
175
175
|
*/
|
|
176
176
|
private resolveSafePath(file: string): string | null {
|
|
177
|
+
// Reject absolute inputs outright: path.resolve(root, "/etc/passwd")
|
|
178
|
+
// returns "/etc/passwd", escaping the project root.
|
|
179
|
+
if (path.isAbsolute(file)) {
|
|
180
|
+
return null;
|
|
181
|
+
}
|
|
182
|
+
|
|
177
183
|
const absolutePath = path.resolve(this.options.projectRoot, file);
|
|
178
184
|
const normalizedRoot = path.normalize(this.options.projectRoot);
|
|
179
|
-
|
|
180
|
-
//
|
|
181
|
-
|
|
185
|
+
// Compare with a trailing separator so a sibling sharing the root's
|
|
186
|
+
// prefix (e.g. "/app/project-secrets" vs root "/app/project") is NOT
|
|
187
|
+
// treated as inside the root. Allow the root itself.
|
|
188
|
+
const rootWithSep = normalizedRoot.endsWith(path.sep)
|
|
189
|
+
? normalizedRoot
|
|
190
|
+
: normalizedRoot + path.sep;
|
|
191
|
+
|
|
192
|
+
if (absolutePath !== normalizedRoot && !absolutePath.startsWith(rootWithSep)) {
|
|
182
193
|
return null;
|
|
183
194
|
}
|
|
184
195
|
|
|
@@ -245,6 +245,8 @@ export class WorkerManager {
|
|
|
245
245
|
{ source: '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\\\.[a-zA-Z]{2,}', label: 'EMAIL' },
|
|
246
246
|
{ source: '\\\\+?[1-9]\\\\d{1,14}', label: 'PHONE' },
|
|
247
247
|
{ source: '\\\\b(?:\\\\d{1,3}\\\\.){3}\\\\d{1,3}\\\\b', label: 'IP' },
|
|
248
|
+
{ source: '\\\\b(?:\\\\d{4}[- ]?){3}\\\\d{4}\\\\b', label: 'CARD' },
|
|
249
|
+
{ source: '\\\\b\\\\d{3}-\\\\d{2}-\\\\d{4}\\\\b', label: 'SSN' },
|
|
248
250
|
];
|
|
249
251
|
|
|
250
252
|
function applyPattern(text, pattern) {
|