diff options
| author | Felix Geyer <fgeyer@debian.org> | 2013-07-14 17:47:01 +0200 |
|---|---|---|
| committer | Felix Geyer <fgeyer@debian.org> | 2013-07-14 17:47:01 +0200 |
| commit | 915d69eb315216560c765c50574aa84bd89b197b (patch) | |
| tree | 3644889a2b98e31eede40b234c9e2f1da80a01f1 /src/VBox/Main/xml | |
| parent | 74acfd23bd86ff7a3a6e8d10ab83ea79d5110538 (diff) | |
| download | virtualbox-915d69eb315216560c765c50574aa84bd89b197b.tar.gz | |
Imported Upstream version 4.2.16-dfsgupstream/4.2.16-dfsg
Diffstat (limited to 'src/VBox/Main/xml')
| -rw-r--r-- | src/VBox/Main/xml/Settings.cpp | 34 |
1 files changed, 25 insertions, 9 deletions
diff --git a/src/VBox/Main/xml/Settings.cpp b/src/VBox/Main/xml/Settings.cpp index 339bd8ea7..36eb3278d 100644 --- a/src/VBox/Main/xml/Settings.cpp +++ b/src/VBox/Main/xml/Settings.cpp @@ -3303,12 +3303,17 @@ void MachineConfigFile::readGroups(const xml::ElementNode *pElmGroups, StringsLi * contain a list of child snapshots; such lists are maintained in the * Snapshot structure. * + * @param depth * @param elmSnapshot * @param snap */ -void MachineConfigFile::readSnapshot(const xml::ElementNode &elmSnapshot, +void MachineConfigFile::readSnapshot(uint32_t depth, + const xml::ElementNode &elmSnapshot, Snapshot &snap) { + if (depth > SETTINGS_SNAPSHOT_DEPTH_MAX) + throw ConfigFileError(this, &elmSnapshot, N_("Maximum snapshot tree depth of %u exceeded"), depth); + Utf8Str strTemp; if (!elmSnapshot.getAttributeValue("uuid", strTemp)) @@ -3355,9 +3360,14 @@ void MachineConfigFile::readSnapshot(const xml::ElementNode &elmSnapshot, { if (pelmChildSnapshot->nameEquals("Snapshot")) { - Snapshot child; - readSnapshot(*pelmChildSnapshot, child); - snap.llChildSnapshots.push_back(child); + // Use the heap to reduce the stack footprint. Each + // recursion needs over 1K, and there can be VMs with + // deeply nested snapshots. The stack can be quite + // small, especially with XPCOM. + Snapshot *child = new Snapshot(); + readSnapshot(depth + 1, *pelmChildSnapshot, *child); + snap.llChildSnapshots.push_back(*child); + delete child; } } } @@ -3493,7 +3503,7 @@ void MachineConfigFile::readMachine(const xml::ElementNode &elmMachine) { Snapshot snap; // this will recurse into child snapshots, if necessary - readSnapshot(*pelmMachineChild, snap); + readSnapshot(1, *pelmMachineChild, snap); llFirstSnapshot.push_back(snap); } else if (pelmMachineChild->nameEquals("Description")) @@ -4361,7 +4371,7 @@ void MachineConfigFile::buildStorageControllersXML(xml::ElementNode &elmParent, if ( (m->sv < SettingsVersion_v1_9) && (sc.controllerType == StorageControllerType_I82078) ) - // floppy controller already got written into <Hardware>/<FloppyController> in writeHardware() + // floppy controller already got written into <Hardware>/<FloppyController> in buildHardwareXML() // for pre-1.9 settings continue; @@ -4560,12 +4570,18 @@ void MachineConfigFile::buildGroupsXML(xml::ElementNode *pElmParent, const Strin * Writes a single snapshot into the DOM tree. Initially this gets called from MachineConfigFile::write() * for the root snapshot of a machine, if present; elmParent then points to the <Snapshots> node under the * <Machine> node to which <Snapshot> must be added. This may then recurse for child snapshots. + * + * @param depth * @param elmParent * @param snap */ -void MachineConfigFile::buildSnapshotXML(xml::ElementNode &elmParent, +void MachineConfigFile::buildSnapshotXML(uint32_t depth, + xml::ElementNode &elmParent, const Snapshot &snap) { + if (depth > SETTINGS_SNAPSHOT_DEPTH_MAX) + throw ConfigFileError(this, NULL, N_("Maximum snapshot tree depth of %u exceeded"), SETTINGS_SNAPSHOT_DEPTH_MAX); + xml::ElementNode *pelmSnapshot = elmParent.createChild("Snapshot"); pelmSnapshot->setAttribute("uuid", snap.uuid.toStringCurly()); @@ -4597,7 +4613,7 @@ void MachineConfigFile::buildSnapshotXML(xml::ElementNode &elmParent, ++it) { const Snapshot &child = *it; - buildSnapshotXML(*pelmChildren, child); + buildSnapshotXML(depth + 1, *pelmChildren, child); } } } @@ -4730,7 +4746,7 @@ void MachineConfigFile::buildMachineXML(xml::ElementNode &elmMachine, if ( (fl & BuildMachineXML_IncludeSnapshots) && llFirstSnapshot.size()) - buildSnapshotXML(elmMachine, llFirstSnapshot.front()); + buildSnapshotXML(1, elmMachine, llFirstSnapshot.front()); buildHardwareXML(elmMachine, hardwareMachine, storageMachine); buildStorageControllersXML(elmMachine, |
