Repository navigation
[Code scan] Avoid data loss when loading repeated list and dict inputs #559
Description
This issue was found during a Codex global code scan of the repository.
Baseline commit: e3c5b38
Problem
The repeated list and dict loaders mutate repeat_jdata and then immediately read $refs before Vue has rendered the new repeated children. The repeated dict path also treats a dictionary as if it had obj.length.
Code references:
dpgui/src/components/dargs/DargsItem.vue
Lines 448 to 470 in e3c5b38
| if (this.jdata.type.includes("list") && Array.isArray(obj)) { | |
| if (this.jdata.repeat) { | |
| this.repeat_jdata = []; | |
| [...Array(obj.length).keys()].forEach((ii) => { | |
| this.repeat_jdata.push(this.jdata); | |
| }); | |
| [...Array(obj.length).keys()].forEach((ii) => { | |
| var subobj = obj[ii]; | |
| if (this.$refs[`subitem_${ii}`]) | |
| this.$refs[`subitem_${ii}`].forEach((vv) => { | |
| // check if it exists, name and alias | |
| if (vv.jdata.name in subobj) { | |
| // exists | |
| vv.load(subobj[vv.jdata.name]); | |
| } | |
| vv.jdata.alias.forEach((aa) => { | |
| if (aa in subobj) vv.load(subobj[aa]); | |
| }); | |
| if (vv.jdata.optional) { | |
| vv.check = vv.jdata.name in subobj; | |
| } | |
| }); | |
| }); |
dpgui/src/components/dargs/DargsItem.vue
Lines 500 to 522 in e3c5b38
| } else if (this.jdata.type.includes("dict") && this.jdata.repeat) { | |
| this.repeat_jdata = []; | |
| this.keys = Object.keys(obj); | |
| [...Array(obj.length).keys()].forEach((ii) => { | |
| this.repeat_jdata.push(this.jdata); | |
| }); | |
| [...Array(obj.length).keys()].forEach((ii) => { | |
| var subobj = obj[this.keys[ii]]; | |
| if (this.$refs[`subitem_${ii}`]) | |
| this.$refs[`subitem_${ii}`].forEach((vv) => { | |
| // check if it exists, name and alias | |
| if (vv.jdata.name in subobj) { | |
| // exists | |
| vv.load(subobj[vv.jdata.name]); | |
| } | |
| vv.jdata.alias.forEach((aa) => { | |
| if (aa in subobj) vv.load(subobj[aa]); | |
| }); | |
| if (vv.jdata.optional) { | |
| vv.check = vv.jdata.name in subobj; | |
| } | |
| }); | |
| }); |
Relevant snippet:
this.keys = Object.keys(obj);
[...Array(obj.length).keys()].forEach((ii) => {
this.repeat_jdata.push(this.jdata);
});Impact
Loading an existing JSON file with repeated entries can skip rows or fail to populate nested fields. Saving after that can drop data from the imported configuration.
Suggested fix
For repeated dicts, iterate over Object.keys(obj) instead of obj.length. After resizing repeat_jdata, wait for Vue to render the new children, for example with nextTick, before walking $refs and loading nested values.
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsTodo
Activity