Issue Information
-
#000017
Issue Confirmations
-
Yes (0)No (0)
Circular references in the document tree can be created by changing the parent of a document to be one of its children document. When loading such document, the script will run until PHP's max_execution_time is over or memory_limit is exhausted, without properly displaying the page content and loading the web/sql server. A circular reference cannot be fixed easily by the user because the orphaned document branch is not displayed in the manager document tree.
Website visitors will still find the problem document even if the page does not appears in any site navigation because they can try to load it from a bookmark or from a search engine result, effectively overloading the server.
Simple user's mistakes should not bring the web/sql server to its knees.
Add a check when changing the Parent Document (when editing the document or when saving it). Disallow the operation if it would create a circular reference.
or
Add a check when changing the Parent Document (when editing the document or when saving it) to search and fix automatically any circular reference in the document tree.
or
Add a check to break the cycle in a circular reference (when rendering the page) and allow orphaned branches to be displayed in the document tree (so the user can fix it itself).
Thanks in advance.
Website visitors will still find the problem document even if the page does not appears in any site navigation because they can try to load it from a bookmark or from a search engine result, effectively overloading the server.
Simple user's mistakes should not bring the web/sql server to its knees.
Add a check when changing the Parent Document (when editing the document or when saving it). Disallow the operation if it would create a circular reference.
or
Add a check when changing the Parent Document (when editing the document or when saving it) to search and fix automatically any circular reference in the document tree.
or
Add a check to break the cycle in a circular reference (when rendering the page) and allow orphaned branches to be displayed in the document tree (so the user can fix it itself).
Thanks in advance.
Partial solution, a patch for save_content_processor.php:
After block (around 365 or so):
Add this:
This code will check if the new parent is a descendant of the current document. If it is, it will silently reset the new parent to the old parent. This can be changed to just report the problem and not saving the document (like the other checks done in this script).
Also, to be complete, replace line (around 360 or so):
with:
so it does not try to convert the new parent to a folder.
Regards,
MV
After block (around 365 or so):
if($parent == $id)
{
echo "Document can not be it's own parent!";
//$parent = $oldparent;
exit;
}
Add this:
// Check if new parent is not a child...
$check_parent = $parent;
while ($check_parent != 0)
{
$sql = "SELECT parent FROM $dbase.".$table_prefix."site_content WHERE id=$check_parent;";
$rs = mysql_query($sql);
if(!$rs){
echo "An error occured while attempting to find the document's parent.";
}
$row = mysql_fetch_assoc($rs);
$check_parent = $row['parent'];
if ($check_parent == $id) {
$parent = $oldparent;
//echo "Document can not have a child as parent!";
//exit;
}
}
This code will check if the new parent is a descendant of the current document. If it is, it will silently reset the new parent to the old parent. This can be changed to just report the problem and not saving the document (like the other checks done in this script).
Also, to be complete, replace line (around 360 or so):
$sql = "UPDATE $dbase.".$table_prefix."site_content SET isfolder=1 WHERE id=".$_REQUEST['parent'].";";
with:
$sql = "UPDATE $dbase.".$table_prefix."site_content SET isfolder=1 WHERE id=$parent;";
so it does not try to convert the new parent to a folder.
Regards,
MV
A quick snippet to search and reattach orphaned subtrees:
// Snippet name: mv_findorphans
// Snippet description: Finds orphaned pages
// Revision: 1.0
// Date: 2010-04-03
// by Mario A. Valdez-Ramirez
// Add this snippet to any page (to a test page not listed in the site),
// with [!mv_findorphans!], then load the page, click the search button,
// select what orphan pages to reattach to the test page, and then click
// the attach button. You should reattach only the pages that look like
// the main document for each orphaned subtree. For example, if the
// documents are: 5->20, 6->20, 7->20, 20->21, 21->22->5, then it looks
// like the root of the orphaned tree was 22, so that is the only
// node you should reattach (the other pages in the subtree are already
// attached to the document 22). When finished, remove the snippet,
// as its security has not been tested.
$mv_findorphans = "";
function mv_loadchild ($parent, $depth) {
global $etomite;
$children = $etomite->getIntTableRows ("id", "site_content", "parent=" . $parent);
foreach ($children as $child) {
$GLOBALS["mv_doclist2"][$child["id"]] = 1;
mv_loadchild ($child["id"], $depth + 1);
}
}
if ($_POST["mv_post_checkorphans"]) {
$mv_doclist = array();
$GLOBALS["mv_doclist2"] = array();
$mv_doclist = $etomite->getIntTableRows ("id", "site_content", "");
foreach ($mv_doclist as $mv_curitem => $mv_curlist) {
$GLOBALS["mv_doclist2"][$mv_doclist[$mv_curitem]["id"]] = 0;
}
mv_loadchild (0, 0);
$mv_findorphans .= "<p>Orphaned documents:</p>";
$mv_findorphans .= "<form method=\"post\">";
$mv_findorphans .= "<table><tr><td>ID</td><td>Parent</td><td>Title</td><td>Reattach</td></tr>\n";
foreach ($GLOBALS["mv_doclist2"] as $mv_curitem => $mv_curdoc) {
if ($mv_curdoc < 1) {
$mv_orphan = $etomite->getIntTableRows ("id,parent,pagetitle", "site_content", "id=" . $mv_curitem, "id");
$mv_findorphans .= "<tr><td>{$mv_orphan[0]["id"]}</td><td>{$mv_orphan[0]["parent"]}</td><td>{$mv_orphan[0]["pagetitle"]}</td>";
$mv_findorphans .= "<td><input type=\"checkbox\" value=\"{$mv_orphan[0]["id"]}\" name=\"mv_post_id[{$mv_orphan[0]["id"]}]\"></td></tr>\n";
}
}
$mv_findorphans .= "</table>";
$mv_findorphans .= "<input type=\"submit\" name=\"mv_post_reattachorphans\" value=\"Link selected pages to this page\"><br>";
$mv_findorphans .= "</form>";
}
elseif ($_POST["mv_post_reattachorphans"] && isset($_POST["mv_post_id"])) {
$mv_update_id = $_POST["mv_post_id"];
if (is_array ($mv_update_id) && (count ($mv_update_id) > 0)) {
$mv_tmproot["isfolder"] = 1;
if ($etomite->updIntTableRows ($mv_tmproot, "site_content", "id=". $etomite->documentIdentifier)) {
$mv_findorphans .= "Folder created...<br>";
foreach ($mv_update_id as $mv_curitem) {
$mv_tmpdoc["parent"] = $etomite->documentIdentifier;
if ($etomite->updIntTableRows ($mv_tmpdoc, "site_content", "id=". $mv_curitem)) {
$mv_findorphans .= "Document $mv_curitem reattached...<br>";
}
}
$etomite->clearCache ();
}
}
}
$mv_findorphans .= "<form method=\"post\">";
$mv_findorphans .= "<input type=\"submit\" name=\"mv_post_checkorphans\" value=\"Search orphan pages\">";
$mv_findorphans .= "</form>";
return $mv_findorphans;
Updating status to: In Progress
Updating severity to: 3 - Medium
This problem was supposed to have been fixed in a previous release... It's possible that is was overwritten with an unfixed version in svn repository...
Updating severity to: 3 - Medium
This problem was supposed to have been fixed in a previous release... It's possible that is was overwritten with an unfixed version in svn repository...
0 user(s) are reading this issue
0 members, 0 guests, 0 anonymous users










