zoukankan      html  css  js  c++  java
  • 织梦后台文件编辑器和删除文件异常

      在使用织梦后台管理网站的过程中,有一个网站文件管理器出现了异常,情况如下:

    1.删除文件的时候在确认文件删除的对话框上下出现了两行javascript代码,代码的内容就是blank.js文件的内容(该文件在管理员目录下面的js目录中),而且这两行代码被用红色背景加重(现在  想想应该是浏览器的警示,与代码本身无关)。

    2.部分文件删除的时候,系统提示警告,禁止删除

    3.编辑文件的时候工作目录和文件名称的两个input的内容是空的,正常情况下应该自动填充当前目录和当前要修改的文件名称才对。所以导致编辑完成后无法保存文件,即文件无法修改。

      根据编辑和删除文件的链接路径,我找到了文件管理器执行的第一个php文件---file_mange_view.php,这个文件在后台管理 员文件夹下(默认/admin),打开这个文件,可以看到这个文件控制了后台文件管理过程中显示的对话框页面,包括几种情况:重命名、新建目录、移动文 件、删除文件、编辑文件、可视化编辑、新建文件和上传文件,用if/else判断$fmdo变量的值来决定要进行的操作,$fmdo变量是通过url传递 进来的,也就是在$_GET变量中保存的。

      首先针对第一个问题,先看删除文件部分的情况,删除部分的代码截取如下:

    复制代码
    //file_mange_view.php
    //删除文件 else if($fmdo=="del") { $wintitle = "&nbsp;文件管理"; $wecome_info = "&nbsp;文件管理::删除文件 [<a href='file_manage_main.php?activepath=$activepath'>文件浏览器</a>]</a>"; $win = new OxWindow(); $win->Init("file_manage_control.php","js/blank.js","POST"); $win->AddHidden("fmdo",$fmdo); $win->AddHidden("activepath",$activepath); $win->AddHidden("filename",$filename); if(@is_dir($cfg_basedir.$activepath."/$filename")) { $wmsg = "你确信要删除目录:$filename 吗?"; } else { $wmsg = "你确信要删除文件:$filename 吗?"; } $win->AddTitle("删除文件确认"); $win->AddMsgItem($wmsg,"50"); $winform = $win->GetWindow("ok"); $win->Display(); }
    复制代码

      首先看这一行:$win = new OxWindow();,这里初始化了一个类OxWindow,随即调用了这个类的Init()方法,而这个类在本文件的开头用require_once引入进来:

    require_once(DEDEINC."/oxwindow.class.php");

    DEDEINC变量就是根目录下面的/include文件夹,于是也打开这个文件查看,首先发现它又引入了另一个文件:

    require_once(DEDEINC."/dedetag.class.php");

    先不管这个dedetag.class.php,用到它的时候再去找它,先看这个oxwindow是干什么的,根据 file_mange_view.php中代码执行的流程,首先实例化OxWindow,也就是调用它的构造方法,但是这玩意儿并没有构造方法,所以继续 看下去,调用了Init方法,下面截取这个方法的代码:

    复制代码
     /**
         *  初始化为含表单的页面
         *
         * @param     string  $formaction  表单操作action
         * @param     string  $checkScript  检测验证js
         * @param     string  $formmethod  表单类型
         * @param     string  $formname  表单名称
         * @return    void
         */
        function Init($formaction="", $checkScript="js/blank.js", $formmethod="POST", $formname="myform")
        {
            $this->myWin .= "<script language='javascript'>
    ";
            if($checkScript!="" && file_exists($checkScript))
            {
                $fp = fopen($checkScript,"r");
                $this->myWin .= fread($fp,filesize($checkScript));
                fclose($fp);
            }
            else
            {
                $this->myWin .= "<!-- function CheckSubmit()
    { return true; } -->";
            }
            $this->myWin .= "</script>
    ";
            $this->formName = $formname;
            $this->myWin .= "<form name='$formname' method='$formmethod' onSubmit='return CheckSubmit();' action='$formaction'>
    ";
        }
    复制代码
    这个方法是这样调用的$win->Init("file_manage_control.php","js/blank.js","POST");,所以传递的参数也显而易见,就是两个文件名和一个POST字符串,这个方法干了什么呢,正如它的注释中说的,就是将$this->myWin
    这个变量搞成一个非常长的字符串,字符串中就是一个html页面的一部分,开头是从js/blank.js中读出来的javascript代码,如果这个文件为空或者不存在,就写一个名叫CheckSubmit()的函数并且永远返回真,其实打开
    这个blank.js文件发现文件中的内容也是这个永远返回真的函数,所以这段代码其实很无聊。接下来就是一个表单的开始,就是form标签的前半部分,用传递的参数设置name,method,action等值。然后回到调用Init函数的
    地方接着往下看就大概明白了,原来调用这个OxWindow类就是为了在删除/编辑文件等操作的的时候初始化一个提示页面,这个页面被初始化成一个带表单的页面,也就是本文开头第一个问题中的那个问题页面,所以接下来的
    几行代码都是在借助OxWindow类向这个页面中添加要显示的内容,最后在调用Display()方法把这个页面显示出来。所以要解决问题一就要看一看这个页面是怎么显示出来的,下面是这个Display()方法:
    复制代码
     /**
         *  显示页面
         *
         * @access    public
         * @param     string  $modfile  模型模板
         * @return    string
         */
        function Display($modfile="")
        {
            global $cfg_templets_dir,$wecome_info,$cfg_basedir;
            if(empty($wecome_info))
            {
                $wecome_info = "DedeCMS OX 通用对话框:";
            }
            $ctp = new DedeTagParse();
            if($modfile=='')
            {
                $ctp->LoadTemplate($cfg_basedir.$cfg_templets_dir.'/plus/win_templet.htm');
            }
            else
            {
                $ctp->LoadTemplate($modfile);
            }
            $emnum = $ctp->Count;
            for($i=0;$i<=$emnum;$i++)
            {
                if(isset($GLOBALS[$ctp->CTags[$i]->GetTagName()]))
                {
                    $ctp->Assign($i,$GLOBALS[$ctp->CTags[$i]->GetTagName()]);
                }
            }
            $ctp->Display();
            $ctp->Clear();
        }
    } //End Class
    复制代码

     

     一眼就看到这个方法又实例化了另外一个类叫DedeTagParse,然后调用它的LoadTemplate()方法,可以猜测出来,这个类是调用了模板显示前面已经初始化好的页面内容。LoadTemplate()方法就是调用模板,最后的
    Display()方法就是显示,所以问题1的异常就可能有两种成因:第一个是调用的模板出了问题,另一个是处理模板的过程有问题,然而处理模板的过程都是通过实例化类来完成的,类文件出问题的概率是比较小的,所以
    首先检查这个模板,传递的这个参数就是这个模板的路径和文件名,也就是在根目录下面的模板目录/templets/plus/win_templet.htm文件,打开仔细检查就发现问题所在了,在模板中引用织梦后台变量的时候居然单引号
    和双引号用的很混乱,有一处单引号中还有单引号,所以在解析模板后显示的时候很多地方都出错,于是将引号修正再进入后台就显示正常了。
      问题1一解决,同理就先从模板入手来解决问题3,但是没有发现任何异常,无奈就在出现问题的页面使用firebug查看源码,发现其中在head标签中meta标记里面居然写着charset=<?php echo $cfg_charset_lang;?>
    为什么php代码被浏览器原样输出,而没有解析呢,于是找到另一个网站后台的同一个模板页面将其替换掉,然后就一切正常了。这样问题1和问题3都被解决。
      问题2实在郁闷,进入ftp发现文件的权限被设置为644,除了root外,其他用户没有写权限,所以在后台删除不了。
    清风明月本无价,近水远山皆有情。
  • 相关阅读:
    设计模式之迭代器与组合模式(三)
    设计模式之迭代器与组合模式(二)
    设计模式之迭代器与组合模式(一)
    设计模式之模板方法模式(一)
    设计模式之模板方法模式(三)
    设计模式之模板方法模式(二)
    Spring Cloud微服务初探
    设计模式之适配器模式与外观模式(二)
    设计模式之适配器模式与外观模式(一)
    设计模式之命令模式(三)
  • 原文地址:https://www.cnblogs.com/onlylove2015/p/4392078.html
Copyright © 2011-2022 走看看