fix(workspace): snapshot OS drop entries before traversal (#7142)
Co-authored-by: nightcityblade <nightcityblade@gmail.com> Co-authored-by: nesquena-hermes <nesquena+hermes@gmail.com>
This commit is contained in:
2 files changed
+45
-3
No files matched your search
+9
-3
@@ -1425,16 +1425,22 @@ async function _collectFilesFromEntry(entry, relPrefix) {
|
|||||||
async function _collectOsDropUploads(dataTransfer) {
|
async function _collectOsDropUploads(dataTransfer) {
|
||||||
const out = [];
|
const out = [];
|
||||||
const items = dataTransfer.items ? [...dataTransfer.items] : [];
|
const items = dataTransfer.items ? [...dataTransfer.items] : [];
|
||||||
if (items.length && typeof items[0].webkitGetAsEntry === 'function') {
|
const files = dataTransfer.files ? [...dataTransfer.files] : [];
|
||||||
|
if (items.length) {
|
||||||
|
const entries = [];
|
||||||
for (const item of items) {
|
for (const item of items) {
|
||||||
if (item.kind !== 'file') continue;
|
if (item.kind !== 'file') continue;
|
||||||
const entry = item.webkitGetAsEntry();
|
const getAsEntry = item.getAsEntry || item.webkitGetAsEntry;
|
||||||
|
const entry = typeof getAsEntry === 'function' ? getAsEntry.call(item) : null;
|
||||||
if (!entry) continue;
|
if (!entry) continue;
|
||||||
|
entries.push(entry);
|
||||||
|
}
|
||||||
|
for (const entry of entries) {
|
||||||
out.push(...await _collectFilesFromEntry(entry, ''));
|
out.push(...await _collectFilesFromEntry(entry, ''));
|
||||||
}
|
}
|
||||||
if (out.length) return out;
|
if (out.length) return out;
|
||||||
}
|
}
|
||||||
for (const file of dataTransfer.files) {
|
for (const file of files) {
|
||||||
out.push({ file, relDir: '' });
|
out.push({ file, relDir: '' });
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
|
|||||||
@@ -81,3 +81,39 @@ console.log(JSON.stringify(cases.map(([a,b]) => b)));
|
|||||||
".", "docs", "docs/reports", "src/lib/utils",
|
".", "docs", "docs/reports", "src/lib/utils",
|
||||||
"projects", "projects/bundle", "bundle/sub",
|
"projects", "projects/bundle", "bundle/sub",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def test_os_drop_snapshots_entries_before_async_traversal():
|
||||||
|
node = shutil.which("node")
|
||||||
|
if not node:
|
||||||
|
return
|
||||||
|
js = r"""
|
||||||
|
const fs=require('fs'),vm=require('vm');
|
||||||
|
const src=fs.readFileSync('static/workspace.js','utf8');
|
||||||
|
const block=src.slice(
|
||||||
|
src.indexOf('async function _readAllDirectoryEntries'),
|
||||||
|
src.indexOf('function _clearWorkspaceOsUploadDragOver'));
|
||||||
|
const uploaded=[],acquired=[],atTraversal=[];
|
||||||
|
const ctx={
|
||||||
|
S:{session:true,currentDir:'.'},_workspacePathIsReadOnly:()=>false,
|
||||||
|
showToast(){},t:x=>x,_targetDirForRelDir:(d,r)=>r||d,
|
||||||
|
uploadToWorkspace:async f=>uploaded.push(f.name),loadDir:async()=>{}};
|
||||||
|
vm.createContext(ctx);vm.runInContext(block+';this.collect=_collectOsDropUploads;this.upload=uploadOsDropToWorkspace',ctx);
|
||||||
|
let locked=false;
|
||||||
|
const fileEntry=name=>({isFile:true,file:resolve=>queueMicrotask(()=>{atTraversal.push(acquired.length);locked=true;resolve({name})})});
|
||||||
|
const names=['alpha.txt','beta.txt','gamma.txt'];
|
||||||
|
const items=names.map(name=>({kind:'file',webkitGetAsEntry(){acquired.push(name);return locked?null:fileEntry(name)}}));
|
||||||
|
(async()=>{
|
||||||
|
await ctx.upload({items,files:[]},'.');
|
||||||
|
let reads=0;const nested={name:'nested',isDirectory:true,createReader:()=>({readEntries:resolve=>queueMicrotask(()=>resolve(reads++?[]:[fileEntry('inside.txt')]))})};
|
||||||
|
const nestedFiles=await ctx.collect({items:[{kind:'file',getAsEntry:()=>nested}],files:[]});
|
||||||
|
const fallback=await ctx.collect({items:[{kind:'file',getAsEntry:()=>null}],files:[{name:'fallback.txt'}]});
|
||||||
|
console.log(JSON.stringify([acquired,atTraversal.slice(0,3),uploaded,nestedFiles.map(x=>[x.file.name,x.relDir]),fallback.map(x=>x.file.name)]));
|
||||||
|
})().catch(error=>{console.error(error);process.exit(1)});
|
||||||
|
"""
|
||||||
|
out = subprocess.check_output([node, "-e", js], text=True).strip()
|
||||||
|
assert json.loads(out) == [
|
||||||
|
["alpha.txt", "beta.txt", "gamma.txt"], [3, 3, 3],
|
||||||
|
["alpha.txt", "beta.txt", "gamma.txt"],
|
||||||
|
[["inside.txt", "nested/"]], ["fallback.txt"],
|
||||||
|
]
|
||||||
Reference in new issue
Block a user