@@ -446,12 +446,6 @@ $actionSearch[10] = array( | |||||
'purview' =>'sys_data', | 'purview' =>'sys_data', | ||||
'linkurl' =>'sys_sql_query.php' | 'linkurl' =>'sys_sql_query.php' | ||||
), | ), | ||||
13 => array( | |||||
'title' =>'文件校验[S]', | |||||
'description' =>'文件校验将检查本站文件是否和dedecms原始文件是否完全一致', | |||||
'purview' =>'sys_verifies', | |||||
'linkurl' =>'sys_verifies.php' | |||||
), | |||||
14 => array( | 14 => array( | ||||
'title' =>'病毒扫描[S]', | 'title' =>'病毒扫描[S]', | ||||
'description' =>'以DedeCMS开发模式为标准对现有的文件进行扫描并进行判断', | 'description' =>'以DedeCMS开发模式为标准对现有的文件进行扫描并进行判断', | ||||
@@ -72,7 +72,6 @@ $adminMenu2 = "<m:top item='7_' name='模板管理' display='none' rank='temp_On | |||||
<m:item name='计划任务管理' link='sys_task.php' rank='sys_Task' target='main' /> | <m:item name='计划任务管理' link='sys_task.php' rank='sys_Task' target='main' /> | ||||
<m:item name='数据库备份/还原' link='sys_data.php' rank='sys_Data' target='main' /> | <m:item name='数据库备份/还原' link='sys_data.php' rank='sys_Data' target='main' /> | ||||
<m:item name='SQL命令行工具' link='sys_sql_query.php' rank='sys_Data' target='main' /> | <m:item name='SQL命令行工具' link='sys_sql_query.php' rank='sys_Data' target='main' /> | ||||
<m:item name='文件校验[S]' link='sys_verifies.php' rank='sys_verify' target='main' /> | |||||
<m:item name='病毒扫描[S]' link='sys_safetest.php' rank='sys_verify' target='main' /> | <m:item name='病毒扫描[S]' link='sys_safetest.php' rank='sys_verify' target='main' /> | ||||
<m:item name='系统错误修复[S]' link='sys_repair.php' rank='sys_verify' target='main' /> | <m:item name='系统错误修复[S]' link='sys_repair.php' rank='sys_verify' target='main' /> | ||||
</m:top> | </m:top> | ||||
@@ -123,7 +123,6 @@ $menusMain = " | |||||
<m:item name='计划任务管理' link='sys_task.php' rank='sys_Task' target='main' /> | <m:item name='计划任务管理' link='sys_task.php' rank='sys_Task' target='main' /> | ||||
<m:item name='数据库备份/还原' link='sys_data.php' rank='sys_Data' target='main' /> | <m:item name='数据库备份/还原' link='sys_data.php' rank='sys_Data' target='main' /> | ||||
<m:item name='SQL命令行工具' link='sys_sql_query.php' rank='sys_Data' target='main' /> | <m:item name='SQL命令行工具' link='sys_sql_query.php' rank='sys_Data' target='main' /> | ||||
<m:item name='文件校验[S]' link='sys_verifies.php' rank='sys_verify' target='main' /> | |||||
<m:item name='病毒扫描[S]' link='sys_safetest.php' rank='sys_verify' target='main' /> | <m:item name='病毒扫描[S]' link='sys_safetest.php' rank='sys_verify' target='main' /> | ||||
<m:item name='系统错误修复[S]' link='sys_repair.php' rank='sys_verify' target='main' /> | <m:item name='系统错误修复[S]' link='sys_repair.php' rank='sys_verify' target='main' /> | ||||
</m:top> | </m:top> | ||||
@@ -45,13 +45,12 @@ if($dopost=='savetag') | |||||
{ | { | ||||
$fulltag = addslashes($fulltag); | $fulltag = addslashes($fulltag); | ||||
$tagname = "auto"; | $tagname = "auto"; | ||||
$inQuery = " | |||||
INSERT INTO #@__mytag(typeid,tagname,timeset,starttime,endtime,normbody,expbody) | |||||
$inQuery = "INSERT INTO `#@__mytag`(typeid,tagname,timeset,starttime,endtime,normbody,expbody) | |||||
VALUES('0','$tagname','0','0','0','$fulltag',''); | VALUES('0','$tagname','0','0','0','$fulltag',''); | ||||
"; | "; | ||||
$dsql->ExecuteNoneQuery($inQuery); | $dsql->ExecuteNoneQuery($inQuery); | ||||
$id = $dsql->GetLastID(); | $id = $dsql->GetLastID(); | ||||
$dsql->ExecuteNoneQuery("UPDATE #@__mytag SET tagname='{$tagname}_{$id}' WHERE aid='$id'"); | |||||
$dsql->ExecuteNoneQuery("UPDATE `#@__mytag` SET tagname='{$tagname}_{$id}' WHERE aid='$id'"); | |||||
$fulltag = "{dede:mytag name='{$tagname}_{$id}' ismake='yes'/}"; | $fulltag = "{dede:mytag name='{$tagname}_{$id}' ismake='yes'/}"; | ||||
} | } | ||||
include DedeInclude('templets/mytag_tag_guide_ok.htm'); | include DedeInclude('templets/mytag_tag_guide_ok.htm'); |
@@ -13,13 +13,13 @@ CheckPurview('sys_plus'); | |||||
$aid = preg_replace("#[^0-9]#", "", $aid); | $aid = preg_replace("#[^0-9]#", "", $aid); | ||||
if($dopost=="show") | if($dopost=="show") | ||||
{ | { | ||||
$dsql->ExecuteNoneQuery("UPDATE #@__plus SET isshow=1 WHERE aid='$aid';"); | |||||
$dsql->ExecuteNoneQuery("UPDATE `#@__plus` SET isshow=1 WHERE aid='$aid';"); | |||||
ShowMsg("成功启用一个插件,请刷新导航菜单!","plus_main.php"); | ShowMsg("成功启用一个插件,请刷新导航菜单!","plus_main.php"); | ||||
exit(); | exit(); | ||||
} | } | ||||
else if($dopost=="hide") | else if($dopost=="hide") | ||||
{ | { | ||||
$dsql->ExecuteNoneQuery("UPDATE #@__plus SET isshow=0 WHERE aid='$aid';"); | |||||
$dsql->ExecuteNoneQuery("UPDATE `#@__plus` SET isshow=0 WHERE aid='$aid';"); | |||||
ShowMsg("成功禁用一个插件,请刷新导航菜单!","plus_main.php"); | ShowMsg("成功禁用一个插件,请刷新导航菜单!","plus_main.php"); | ||||
exit(); | exit(); | ||||
} | } | ||||
@@ -44,17 +44,17 @@ else if($dopost=="delete") | |||||
} | } | ||||
else if($job=="yes") //操作 | else if($job=="yes") //操作 | ||||
{ | { | ||||
$dsql->ExecuteNoneQuery("DELETE FROM #@__plus WHERE aid='$aid';"); | |||||
$dsql->ExecuteNoneQuery("DELETE FROM `#@__plus` WHERE aid='$aid';"); | |||||
ShowMsg("成功删除一个插件,请刷新导航菜单!","plus_main.php"); | ShowMsg("成功删除一个插件,请刷新导航菜单!","plus_main.php"); | ||||
exit(); | exit(); | ||||
} | } | ||||
} | } | ||||
else if($dopost=="saveedit") //保存更改 | else if($dopost=="saveedit") //保存更改 | ||||
{ | { | ||||
$inquery = "UPDATE #@__plus SET plusname='$plusname',menustring='$menustring',filelist='$filelist' WHERE aid='$aid';"; | |||||
$inquery = "UPDATE `#@__plus` SET plusname='$plusname',menustring='$menustring',filelist='$filelist' WHERE aid='$aid';"; | |||||
$dsql->ExecuteNoneQuery($inquery); | $dsql->ExecuteNoneQuery($inquery); | ||||
ShowMsg("成功更改插件的配置!","plus_main.php"); | ShowMsg("成功更改插件的配置!","plus_main.php"); | ||||
exit(); | exit(); | ||||
} | } | ||||
$row = $dsql->GetOne("SELECT * FROM #@__plus WHERE aid='$aid'"); | |||||
$row = $dsql->GetOne("SELECT * FROM `#@__plus` WHERE aid='$aid'"); | |||||
include DedeInclude('templets/plus_edit.htm'); | include DedeInclude('templets/plus_edit.htm'); |
@@ -13,7 +13,7 @@ CheckPurview('sys_plus'); | |||||
require_once(DEDEINC."/datalistcp.class.php"); | require_once(DEDEINC."/datalistcp.class.php"); | ||||
setcookie("ENV_GOBACK_URL",$dedeNowurl,time()+3600,"/"); | setcookie("ENV_GOBACK_URL",$dedeNowurl,time()+3600,"/"); | ||||
$sql = "SELECT aid,plusname,writer,isshow FROM #@__plus ORDER BY aid ASC"; | |||||
$sql = "SELECT aid,plusname,writer,isshow FROM `#@__plus` ORDER BY aid ASC"; | |||||
$dlist = new DataListCP(); | $dlist = new DataListCP(); | ||||
$dlist->SetTemplet(DEDEADMIN."/templets/plus_main.htm"); | $dlist->SetTemplet(DEDEADMIN."/templets/plus_main.htm"); | ||||
$dlist->SetSource($sql); | $dlist->SetSource($sql); | ||||
@@ -22,7 +22,7 @@ if($cid!=0) | |||||
$whereSql = " AND arc.typeid IN (".GetSonIds($cid).")"; | $whereSql = " AND arc.typeid IN (".GetSonIds($cid).")"; | ||||
} | } | ||||
$query = "SELECT arc.*,tp.typename FROM `#@__archives` AS arc | $query = "SELECT arc.*,tp.typename FROM `#@__archives` AS arc | ||||
LEFT JOIN #@__arctype AS tp ON arc.typeid = tp.id | |||||
LEFT JOIN `#@__arctype` AS tp ON arc.typeid = tp.id | |||||
WHERE arc.arcrank = '-2' $whereSql order by arc.id desc"; | WHERE arc.arcrank = '-2' $whereSql order by arc.id desc"; | ||||
$dlist = new DataListCP(); | $dlist = new DataListCP(); | ||||
$dlist->SetTemplet(DEDEADMIN."/templets/recycling.htm"); | $dlist->SetTemplet(DEDEADMIN."/templets/recycling.htm"); | ||||
@@ -84,7 +84,7 @@ function GetKeywordList($dsql,$pageno,$pagesize,$orderby='aid') | |||||
echo $printhead; | echo $printhead; | ||||
if($orderby=='result') $orderby = $orderby." ASC"; | if($orderby=='result') $orderby = $orderby." ASC"; | ||||
else $orderby = $orderby." DESC"; | else $orderby = $orderby." DESC"; | ||||
$dsql->SetQuery("SELECT * FROM #@__search_keywords ORDER BY $orderby LIMIT $start,$pagesize "); | |||||
$dsql->SetQuery("SELECT * FROM `#@__search_keywords` ORDER BY $orderby LIMIT $start,$pagesize "); | |||||
$dsql->Execute(); | $dsql->Execute(); | ||||
while($row = $dsql->GetArray()) | while($row = $dsql->GetArray()) | ||||
{ | { | ||||
@@ -26,7 +26,7 @@ if($do=='add') | |||||
$price = '0.00'; | $price = '0.00'; | ||||
} | } | ||||
$des = cn_substrR($des,255); | $des = cn_substrR($des,255); | ||||
$InQuery = "INSERT INTO #@__shops_delivery(`dname`,`price`,`des`) VALUES ('$dname','$price','$des');"; | |||||
$InQuery = "INSERT INTO `#@__shops_delivery`(`dname`,`price`,`des`) VALUES ('$dname','$price','$des');"; | |||||
$result = $dsql->ExecuteNoneQuery($InQuery); | $result = $dsql->ExecuteNoneQuery($InQuery); | ||||
if($result) | if($result) | ||||
{ | { | ||||
@@ -40,7 +40,7 @@ if($do=='add') | |||||
} else if ($do == 'del') | } else if ($do == 'del') | ||||
{ | { | ||||
$id = intval($id); | $id = intval($id); | ||||
$dsql->ExecuteNoneQuery("DELETE FROM #@__shops_delivery WHERE pid='$id'"); | |||||
$dsql->ExecuteNoneQuery("DELETE FROM `#@__shops_delivery` WHERE pid='$id'"); | |||||
ShowMsg("已删除当前配送方式!","shops_delivery.php"); | ShowMsg("已删除当前配送方式!","shops_delivery.php"); | ||||
exit(); | exit(); | ||||
} else if ($do == 'edit') | } else if ($do == 'edit') | ||||
@@ -48,7 +48,7 @@ if($do=='add') | |||||
foreach($pid as $id) | foreach($pid as $id) | ||||
{ | { | ||||
$id = intval($id); | $id = intval($id); | ||||
$row = $dsql->GetOne("SELECT pid,dname,price,des FROM #@__shops_delivery WHERE pid='$id' LIMIT 0,1"); | |||||
$row = $dsql->GetOne("SELECT pid,dname,price,des FROM `#@__shops_delivery` WHERE pid='$id' LIMIT 0,1"); | |||||
if(!is_array($row)) | if(!is_array($row)) | ||||
{ | { | ||||
continue; | continue; | ||||
@@ -73,22 +73,22 @@ if($do=='add') | |||||
{ | { | ||||
$des = cn_substrR($des,255); | $des = cn_substrR($des,255); | ||||
} | } | ||||
$dsql->ExecuteNoneQuery("UPDATE #@__shops_delivery SET dname='$dname',price='$price',des='$des' WHERE pid='$id'"); | |||||
$dsql->ExecuteNoneQuery("UPDATE `#@__shops_delivery` SET dname='$dname',price='$price',des='$des' WHERE pid='$id'"); | |||||
} | } | ||||
ShowMsg("成功修改配送方式!","shops_delivery.php"); | ShowMsg("成功修改配送方式!","shops_delivery.php"); | ||||
exit(); | exit(); | ||||
} | } | ||||
$deliveryarr = array(); | $deliveryarr = array(); | ||||
$dsql->SetQuery("SELECT pid,dname,price,des FROM #@__shops_delivery ORDER BY orders ASC"); | |||||
$dsql->SetQuery("SELECT pid,dname,price,des FROM `#@__shops_delivery` ORDER BY orders ASC"); | |||||
$dsql->Execute(); | $dsql->Execute(); | ||||
while($row = $dsql->GetArray()) | while($row = $dsql->GetArray()) | ||||
{ | { | ||||
$deliveryarr[] = $row; | $deliveryarr[] = $row; | ||||
} | } | ||||
$dlist = new DataListCP(); | $dlist = new DataListCP(); | ||||
$dlist->pageSize = 25; //设定每页显示记录数(默认25条) | |||||
$dlist->pageSize = 25; //设定每页显示记录数(默认25条) | |||||
//这两句的顺序不能更换 | //这两句的顺序不能更换 | ||||
$dlist->SetTemplate(DEDEADMIN."/templets/shops_delivery.htm"); //载入模板 | $dlist->SetTemplate(DEDEADMIN."/templets/shops_delivery.htm"); //载入模板 | ||||
$dlist->SetSource("SELECT `pid`,`dname`,`price`,`des` FROM #@__shops_delivery ORDER BY `orders` ASC"); //设定查询SQL | |||||
$dlist->Display(); //显示 | |||||
$dlist->SetSource("SELECT `pid`,`dname`,`price`,`des` FROM `#@__shops_delivery` ORDER BY `orders` ASC"); // 设定查询SQL | |||||
$dlist->Display(); //显示 |
@@ -24,7 +24,7 @@ if(isset($dopost)) | |||||
if($wh=='') $wh = " WHERE oid='$n' "; | if($wh=='') $wh = " WHERE oid='$n' "; | ||||
else $wh .= " OR oid='$n' "; | else $wh .= " OR oid='$n' "; | ||||
} | } | ||||
$sql="UPDATE #@__shops_orders SET `state`='1' $wh "; | |||||
$sql="UPDATE `#@__shops_orders` SET `state`='1' $wh "; | |||||
$dsql->ExecuteNoneQuery($sql); | $dsql->ExecuteNoneQuery($sql); | ||||
} | } | ||||
else if ($dopost == 'push') | else if ($dopost == 'push') | ||||
@@ -36,7 +36,7 @@ if(isset($dopost)) | |||||
if($wh=='') $wh = " WHERE oid='$n' "; | if($wh=='') $wh = " WHERE oid='$n' "; | ||||
else $wh .= " OR oid='$n' "; | else $wh .= " OR oid='$n' "; | ||||
} | } | ||||
$sql="UPDATE #@__shops_orders SET `state`='2' $wh "; | |||||
$sql="UPDATE `#@__shops_orders` SET `state`='2' $wh "; | |||||
$dsql->ExecuteNoneQuery($sql); | $dsql->ExecuteNoneQuery($sql); | ||||
} | } | ||||
else if ($dopost == 'ok') | else if ($dopost == 'ok') | ||||
@@ -48,7 +48,7 @@ if(isset($dopost)) | |||||
if($wh=='') $wh = " WHERE oid='$n' "; | if($wh=='') $wh = " WHERE oid='$n' "; | ||||
else $wh .= " OR oid='$n' "; | else $wh .= " OR oid='$n' "; | ||||
} | } | ||||
$sql="UPDATE #@__shops_orders SET `state`='4' $wh "; | |||||
$sql="UPDATE `#@__shops_orders` SET `state`='4' $wh "; | |||||
$dsql->ExecuteNoneQuery($sql); | $dsql->ExecuteNoneQuery($sql); | ||||
} | } | ||||
else if ($dopost == 'delete') | else if ($dopost == 'delete') | ||||
@@ -87,7 +87,7 @@ if(isset($sta)) | |||||
{ | { | ||||
$addsql = "WHERE s.`state`='$sta'"; | $addsql = "WHERE s.`state`='$sta'"; | ||||
} | } | ||||
$sql = "SELECT s.`oid`,s.`cartcount`,s.`price`,s.`state`,s.`stime`,s.priceCount,s.dprice,s.paytype,u.`consignee`,u.`tel`,s.`userid` FROM #@__shops_orders AS s LEFT JOIN #@__shops_userinfo AS u ON s.oid=u.oid $addsql ORDER BY `stime` DESC"; | |||||
$sql = "SELECT s.`oid`,s.`cartcount`,s.`price`,s.`state`,s.`stime`,s.priceCount,s.dprice,s.paytype,u.`consignee`,u.`tel`,s.`userid` FROM `#@__shops_orders` AS s LEFT JOIN `#@__shops_userinfo` AS u ON s.oid=u.oid $addsql ORDER BY `stime` DESC"; | |||||
$dlist = new DataListCP(); | $dlist = new DataListCP(); | ||||
$dlist->SetParameter("oid",$oid); | $dlist->SetParameter("oid",$oid); | ||||
@@ -127,7 +127,7 @@ function GetsType($pid) | |||||
{ | { | ||||
global $dsql; | global $dsql; | ||||
$pid = intval($pid); | $pid = intval($pid); | ||||
$row = $dsql->GetOne("SELECT name FROM #@__payment WHERE id='$pid'"); | |||||
$row = $dsql->GetOne("SELECT name FROM `#@__payment` WHERE id='$pid'"); | |||||
if(is_array($row)) | if(is_array($row)) | ||||
{ | { | ||||
return $row['name']; | return $row['name']; | ||||
@@ -142,7 +142,7 @@ function GetMemberID($mid) | |||||
{ | { | ||||
global $dsql; | global $dsql; | ||||
if($mid==0) return '0'; | if($mid==0) return '0'; | ||||
$row = $dsql->GetOne("SELECT userid FROM #@__member WHERE mid='$mid' "); | |||||
$row = $dsql->GetOne("SELECT userid FROM `#@__member` WHERE mid='$mid' "); | |||||
if(is_array($row)) | if(is_array($row)) | ||||
{ | { | ||||
return "<a href='member_view.php?id={$mid}'>".$row['userid']."</a>"; | return "<a href='member_view.php?id={$mid}'>".$row['userid']."</a>"; | ||||
@@ -16,8 +16,8 @@ if(!isset($oid)) exit("<a href='javascript:window.close()'>无效操作!</a>"); | |||||
$oid = preg_replace("#[^-0-9A-Z]#", "", $oid); | $oid = preg_replace("#[^-0-9A-Z]#", "", $oid); | ||||
if(empty($oid)) exit("<a href='javascript:window.close()'>无效订单号!</a>"); | if(empty($oid)) exit("<a href='javascript:window.close()'>无效订单号!</a>"); | ||||
$row = $dsql->GetOne("SELECT * FROM #@__shops_userinfo WHERE oid='$oid'"); | |||||
$sql="SELECT o.*,p.title,p.price as uprice,d.dname FROM #@__shops_orders as o left join #@__shops_products as p on o.oid=p.oid left join #@__shops_delivery as d on d.pid=o.pid WHERE o.oid='$oid'"; | |||||
$row = $dsql->GetOne("SELECT * FROM `#@__shops_userinfo` WHERE oid='$oid'"); | |||||
$sql="SELECT o.*,p.title,p.price as uprice,d.dname FROM `#@__shops_orders` as o left join `#@__shops_products` as p on o.oid=p.oid left join `#@__shops_delivery` as d on d.pid=o.pid WHERE o.oid='$oid'"; | |||||
$dlist = new DataListCP(); | $dlist = new DataListCP(); | ||||
$dlist->pageSize = 20; | $dlist->pageSize = 20; | ||||
@@ -30,8 +30,8 @@ $dlist->Close(); | |||||
function GetSta($sta,$oid) | function GetSta($sta,$oid) | ||||
{ | { | ||||
global $dsql; | global $dsql; | ||||
$row = $dsql->GetOne("SELECT paytype FROM #@__shops_orders WHERE oid='$oid'"); | |||||
$payname = $dsql->GetOne("SELECT name,fee FROM #@__payment WHERE id='{$row['paytype']}'"); | |||||
$row = $dsql->GetOne("SELECT paytype FROM `#@__shops_orders` WHERE oid='$oid'"); | |||||
$payname = $dsql->GetOne("SELECT name,fee FROM `#@__payment` WHERE id='{$row['paytype']}'"); | |||||
if($sta==0) | if($sta==0) | ||||
{ | { | ||||
return $payname['name']." 手续费:".$payname['fee']."元"; | return $payname['name']." 手续费:".$payname['fee']."元"; | ||||
@@ -14,16 +14,16 @@ if(!isset($oid)) exit("<a href='javascript:window.close()'>无效操作!</a>"); | |||||
$oid = preg_replace("#[^-0-9A-Z]#", "", $oid); | $oid = preg_replace("#[^-0-9A-Z]#", "", $oid); | ||||
if(empty($oid)) exit("<a href='javascript:window.close()'>无效订单号!</a>"); | if(empty($oid)) exit("<a href='javascript:window.close()'>无效订单号!</a>"); | ||||
$rows = $dsql->GetOne("SELECT * FROM #@__shops_userinfo WHERE oid='$oid' LIMIT 0,1"); | |||||
$rows = $dsql->GetOne("SELECT * FROM `#@__shops_userinfo` WHERE oid='$oid' LIMIT 0,1"); | |||||
if(!is_array($rows)){ | if(!is_array($rows)){ | ||||
$dsql->Close(); | $dsql->Close(); | ||||
exit("<a href='javascript:window.close()'>该订单下没相关用户信息!</a>"); | exit("<a href='javascript:window.close()'>该订单下没相关用户信息!</a>"); | ||||
} | } | ||||
$row = $dsql->GetOne("SELECT pid,dprice FROM #@__shops_orders WHERE oid='$oid'"); | |||||
$row = $dsql->GetOne("SELECT pid,dprice FROM `#@__shops_orders` WHERE oid='$oid'"); | |||||
if(is_array($row)) | if(is_array($row)) | ||||
{ | { | ||||
$rs = $dsql->GetOne("SELECT dname FROM #@__shops_delivery WHERE pid='$row[pid]'"); | |||||
$rs = $dsql->GetOne("SELECT dname FROM `#@__shops_delivery` WHERE pid='$row[pid]'"); | |||||
$rows['dname'] = $rs['dname']; | $rows['dname'] = $rs['dname']; | ||||
$rows['dprice'] = $row['dprice']; | $rows['dprice'] = $row['dprice']; | ||||
} | } | ||||
@@ -1,4 +1,5 @@ | |||||
<?php | <?php | ||||
/** | /** | ||||
* 安全检测 | * 安全检测 | ||||
* | * | ||||
@@ -8,130 +9,130 @@ | |||||
* @license https://www.dedebiz.com/license | * @license https://www.dedebiz.com/license | ||||
* @link https://www.dedebiz.com | * @link https://www.dedebiz.com | ||||
*/ | */ | ||||
require_once(dirname(__FILE__).'/config.php'); | |||||
require_once(dirname(__FILE__) . '/config.php'); | |||||
CheckPurview('sys_Edit'); | CheckPurview('sys_Edit'); | ||||
if(empty($action)) $action = ''; | |||||
if(empty($message)) $message = '尚未进行检测……'; | |||||
if(empty($filetype)) $filetype = 'php|inc'; | |||||
if(empty($info)) $info = 'eval|cmd|_GET|_POST'; | |||||
$safefile = "data/common.inc.php | |||||
index.php | |||||
dede/config.php | |||||
dede/index_body.php | |||||
dede/member_do.php | |||||
dede/sys_info_pay.php | |||||
dede/mychannel_main.php | |||||
group/postform.php | |||||
group/reply.php | |||||
include/common.inc.php | |||||
include/mail.class.php | |||||
include/Lurd.class.php | |||||
include/payment/alipay.php | |||||
include/payment/bank.php | |||||
include/payment/cod.php | |||||
include/payment/yeepay.php | |||||
include/helpers/debug.helper.php | |||||
include/request.class.php | |||||
include/dedecollection.class.php | |||||
include/dedetag.class.php | |||||
include/dialog/config.php | |||||
include/taglib/php.lib.php | |||||
include/FCKeditor/fckeditor.php | |||||
include/smtp.class.php | |||||
include/zip.class.php | |||||
install/common.inc.php | |||||
include/json.class.php | |||||
include/sphinxclient.class.php | |||||
plus/bshare.php | |||||
install/index.php"; | |||||
$adminDir = preg_replace("#(.*)[\/\\\\]#", "", dirname(__FILE__)); | |||||
$safefile = trim(str_replace('dede/',$adminDir.'/',$safefile)); | |||||
$safefiles = preg_split("#[\r\n]{1,}#", $safefile); | |||||
if (empty($action)) $action = ''; | |||||
if (empty($message)) $message = '尚未进行检测……'; | |||||
if (empty($filetype)) $filetype = 'php|inc'; | |||||
if (empty($info)) $info = 'eval|cmd|system|exec|_GET|_POST|_REQUEST|base64_decode'; | |||||
$fileHashURL = "https://cdn.dedebiz.com/release/{$cfg_version_detail}.json"; | |||||
$del = new DedeHttpDown(); | |||||
$del->OpenUrl($fileHashURL); | |||||
$filelist = $del->GetJSON(); | |||||
$offFiles = array(); | |||||
foreach ($filelist as $key => $ff) { | |||||
$offFiles[$ff->filename] = $ff->hash; | |||||
} | |||||
$alter = ""; | |||||
if (count($offFiles) == 0) { | |||||
$alter = <<<EOT | |||||
<div class="alert alert-danger maintable mb-2" style="margin:0 auto;" role="alert"> | |||||
无法同官方网站文件服务器通信,校验时候无法保证本地文件是否同官方服务器文件是否一致。 | |||||
</div> | |||||
EOT;; | |||||
} | |||||
function TestOneFile($f) | function TestOneFile($f) | ||||
{ | { | ||||
global $message, $info; | |||||
global $message, $info,$offFiles; | |||||
$str = ''; | $str = ''; | ||||
//排除safefile和data/tplcache目录 | //排除safefile和data/tplcache目录 | ||||
if(NotCheckFile($f) || preg_match("#data/tplcache|.svn#", $f)) return -1; | |||||
if (preg_match("#data/tplcache|.svn|data/cache#", $f)) return -1; | |||||
$fp = fopen($f, 'r'); | $fp = fopen($f, 'r'); | ||||
while(!feof($fp)) { $str .= fgets($fp,1024); } | |||||
while (!feof($fp)) { | |||||
$str .= fgets($fp, 1024); | |||||
} | |||||
fclose($fp); | fclose($fp); | ||||
if(preg_match("#(".$info.")[ \r\n\t]{0,}([\[\(])#i", $str)) | |||||
{ | |||||
$trfile = preg_replace("#^".DEDEROOT."#", '', $f); | |||||
$message .= "<div style='clear:both;border-bottom:1px dotted #B8E6A2;line-height:24px'> | |||||
if (preg_match("#(" . $info . ")[ \r\n\t]{0,}([\[\(])#i", $str)) { | |||||
$trfile = preg_replace("#^" . DEDEROOT . "#", '', $f ); | |||||
$oldTrfile = $trfile; | |||||
$trfile = substr(str_replace("/","\\",$trfile) ,1); | |||||
$localFilehash = md5_file($f); | |||||
$remoteFilehash = isset($offFiles[$trfile])? $offFiles[$trfile] : ''; | |||||
if ($localFilehash === $remoteFilehash) { | |||||
return 0; | |||||
} | |||||
$message .= "<div style='clear:both;'> | |||||
<div style='width:350px;float:left'>可疑文件:{$trfile}</div> | <div style='width:350px;float:left'>可疑文件:{$trfile}</div> | ||||
<div style='float:left'>[<a href='file_manage_view.php?fmdo=del&filename=$trfile&activepath=' target='_blank'><u>删除</u></a>] | |||||
[<a href='file_manage_view.php?fmdo=edit&filename=$trfile&activepath=' target='_blank'><u>查看源码</u></a>] | |||||
</div></div>\r\n"; | |||||
<a class='btn btn-secondary btn-sm' href='sys_safetest.php?action=viewdiff&filename=$oldTrfile' target='_blank'>更改记录</a> | |||||
<a class='btn btn-secondary btn-sm' href='file_manage_view.php?fmdo=del&filename=$oldTrfile&activepath=' target='_blank'>删除</a> | |||||
<a class='btn btn-secondary btn-sm' href='file_manage_view.php?fmdo=edit&filename=$oldTrfile&activepath=' target='_blank'>查看源码</a> | |||||
</div></div><hr>\r\n"; | |||||
return 1; | return 1; | ||||
} | } | ||||
return 0; | return 0; | ||||
} | } | ||||
function NotCheckFile($f) | |||||
{ | |||||
global $safefiles, $safefile; | |||||
if($safefile != '') | |||||
{ | |||||
foreach($safefiles as $v) | |||||
{ | |||||
//if(empty($v)) continue; | |||||
if( preg_match("#".$v."#i", $f) ) return TRUE; | |||||
} | |||||
} | |||||
return false; | |||||
} | |||||
function TestSafe($tdir) | function TestSafe($tdir) | ||||
{ | { | ||||
global $filetype; | global $filetype; | ||||
$dh = dir($tdir); | $dh = dir($tdir); | ||||
while($fname=$dh->read()) | |||||
{ | |||||
$fnamef = $tdir.'/'.$fname; | |||||
if(@is_dir($fnamef) && $fname != '.' && $fname != '..') | |||||
{ | |||||
while ($fname = $dh->read()) { | |||||
$fnamef = $tdir . '/' . $fname; | |||||
if (@is_dir($fnamef) && $fname != '.' && $fname != '..') { | |||||
TestSafe($fnamef); | TestSafe($fnamef); | ||||
} | } | ||||
if(preg_match("#\.(" . $filetype . ")#i", $fnamef)) | |||||
{ | |||||
if (preg_match("#\.(" . $filetype . ")#i", $fnamef)) { | |||||
TestOneFile($fnamef); | TestOneFile($fnamef); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
//检测 | //检测 | ||||
if($action=='test') | |||||
{ | |||||
$message = ''; | |||||
AjaxHead(); | |||||
TestSafe(DEDEROOT); | |||||
if($message=='') $message = "<font color='green' style='font-size:14px'>没发现可疑文件!</font>"; | |||||
echo $message; | |||||
exit(); | |||||
if ($action == 'test') { | |||||
$message = '<link rel="stylesheet" href="../static/css/bootstrap.min.css"><link href="../static/font-awesome/css/font-awesome.min.css" rel="stylesheet">'; | |||||
AjaxHead(); | |||||
TestSafe(DEDEROOT); | |||||
if ($message == '') $message = "<font color='green' style='font-size:14px'>没发现可疑文件!</font>"; | |||||
echo $message; | |||||
exit(); | |||||
} | } | ||||
else if($action =='viewdiff'){ | |||||
$filename = isset($filename)? $filename : ""; | |||||
if (empty($filename)) { | |||||
ShowMsg("没有选择对应的文件", "-1"); | |||||
exit; | |||||
} | |||||
$baseFile = "https://cdn.dedebiz.com/release/{$cfg_version_detail}$filename"; | |||||
$del = new DedeHttpDown(); | |||||
$del->OpenUrl($baseFile); | |||||
$base = $del->GetHTML(); | |||||
$file = "$cfg_basedir/$filename"; | |||||
$new = ""; | |||||
if(is_file($file)) | |||||
{ | |||||
$fp = fopen($file,"r"); | |||||
$new = fread($fp,filesize($file)); | |||||
fclose($fp); | |||||
} | |||||
include(dirname(__FILE__) . '/templets/sys_safetest_viewdiff.htm'); | |||||
exit(); | |||||
} | |||||
//清空模板缓存 | //清空模板缓存 | ||||
else if($action=='clear') | |||||
{ | |||||
else if ($action == 'clear') { | |||||
global $cfg_tplcache_dir; | global $cfg_tplcache_dir; | ||||
$message = ''; | $message = ''; | ||||
$d = DEDEROOT.$cfg_tplcache_dir; | |||||
$d = DEDEROOT . $cfg_tplcache_dir; | |||||
AjaxHead(); | AjaxHead(); | ||||
sleep(1); | sleep(1); | ||||
if(preg_match("#data\/#", $cfg_tplcache_dir) && file_exists($d) && is_dir($d)) | |||||
{ | |||||
if (preg_match("#data\/#", $cfg_tplcache_dir) && file_exists($d) && is_dir($d)) { | |||||
$dh = dir($d); | $dh = dir($d); | ||||
while($filename = $dh->read()) | |||||
{ | |||||
if($filename=='.'||$filename=='..'||$filename=='index.html') continue; | |||||
@unlink($d.'/'.$filename); | |||||
while ($filename = $dh->read()) { | |||||
if ($filename == '.' || $filename == '..' || $filename == 'index.html') continue; | |||||
@unlink($d . '/' . $filename); | |||||
} | } | ||||
} | } | ||||
$message = "<font color='green' style='font-size:14px'>成功清空模板缓存!</font>"; | $message = "<font color='green' style='font-size:14px'>成功清空模板缓存!</font>"; | ||||
@@ -139,4 +140,4 @@ else if($action=='clear') | |||||
exit(); | exit(); | ||||
} | } | ||||
include(dirname(__FILE__).'/templets/sys_safetest.htm'); | |||||
include(dirname(__FILE__) . '/templets/sys_safetest.htm'); |
@@ -1,470 +0,0 @@ | |||||
<?php | |||||
/** | |||||
* 系统文件校验 | |||||
* | |||||
* @version $Id: sys_verifies.php 1 23:07 2010年7月20日Z tianya $ | |||||
* @package DedeCMS.Administrator | |||||
* @copyright Copyright (c) 2020, DedeBIZ.COM | |||||
* @license https://www.dedebiz.com/license | |||||
* @link https://www.dedebiz.com | |||||
*/ | |||||
require_once(dirname(__FILE__)."/config.php"); | |||||
CheckPurview('sys_Edit'); | |||||
@set_time_limit(0); | |||||
require(DEDEINC.'/dedehttpdown.class.php'); | |||||
$action = isset($action) ? trim($action) : ''; | |||||
//当前软件版本锁定文件 | |||||
$verLockFile = DEDEDATA.'/admin/ver.txt'; | |||||
//当前软件指纹码锁定文件 | |||||
$verifiesLockFile = DEDEDATA.'/admin/verifies.txt'; | |||||
$fp = fopen($verLockFile,'r'); | |||||
$upTime = trim(fread($fp,64)); | |||||
fclose($fp); | |||||
$updateTime = substr($upTime,0,4).'-'.substr($upTime,4,2).'-'.substr($upTime,6,2); | |||||
$verifiesTime = "未同步过指纹码"; | |||||
if(file_exists($verifiesLockFile)) | |||||
{ | |||||
$fp = fopen($verifiesLockFile,'r'); | |||||
$upTime = trim(fread($fp,64)); | |||||
fclose($fp); | |||||
$verifiesTime = substr($upTime,0,4).'-'.substr($upTime,4,2).'-'.substr($upTime,6,2); | |||||
} | |||||
$tmpdir = substr(md5($cfg_cookie_encode),0,16); | |||||
//重定义file_get_contents来兼容不支持此函数的PHP | |||||
//因为有个别地方用fgets读文件生成校验码不兼容 | |||||
if(!function_exists('file_get_contents')) | |||||
{ | |||||
function file_get_contents($fname) | |||||
{ | |||||
if(!file_exists($fname) || is_dir($fname)) | |||||
{ | |||||
return ''; | |||||
} | |||||
else | |||||
{ | |||||
$fp = fopen($fname, 'r'); | |||||
$ct = fread($fp, filesize($fname)); | |||||
fclose($fp); | |||||
return $ct; | |||||
} | |||||
} | |||||
} | |||||
if($action == '') | |||||
{ | |||||
include(DEDEADMIN.'/templets/sys_verifies.htm'); | |||||
exit(); | |||||
} | |||||
/*---------------- | |||||
校验文件 | |||||
function _verify() { } | |||||
----------------*/ | |||||
else if($action == 'verify') | |||||
{ | |||||
$dsql->SetQuery("SELECT * FROM `#@__verifies` "); | |||||
$dsql->Execute(); | |||||
$filelist = array(); | |||||
while($row = $dsql->GetArray()) | |||||
{ | |||||
$turefile = str_replace('../dede', '.', $row['filename']); | |||||
//跳过不存在的文件 | |||||
if(!file_exists($turefile)) { | |||||
continue; | |||||
} | |||||
if( filesize($turefile)==0 ) { | |||||
continue; | |||||
} | |||||
$ct = file_get_contents($turefile); | |||||
$ct = preg_replace("/\/\*\*[\r\n]{1,}(.*)[\r\n]{1,} \*\//sU", '', $ct); | |||||
$cthash = md5($ct); | |||||
if($cthash != $row['cthash']) | |||||
{ | |||||
$row['localhash'] = $cthash; | |||||
$row['mtime'] = MyDate('Y-m-d H:i:s', filemtime($turefile)); | |||||
$row['turefile'] = $turefile; | |||||
$filelist[] = $row; | |||||
} | |||||
} | |||||
if(!isset($filelist[0])) | |||||
{ | |||||
ShowMsg("所有文件都通过效验证,核心文件没有被改动过!","sys_verifies.php"); | |||||
} | |||||
else | |||||
{ | |||||
include(DEDEADMIN.'/templets/sys_verifies_verify.htm'); | |||||
} | |||||
exit(); | |||||
} | |||||
/*-------------------- | |||||
查看单个本地文件 | |||||
function _view() { } | |||||
----------------------*/ | |||||
else if ($action == 'view') | |||||
{ | |||||
require_once(DEDEINC."/oxwindow.class.php"); | |||||
$filetxt = ''; | |||||
if( !preg_match("#data(.*)common.inc.php#i", $filename) ) | |||||
{ | |||||
$fp = fopen($filename, 'r'); | |||||
$filetxt = fread($fp, filesize($filename)); | |||||
fclose($fp); | |||||
} | |||||
$filetxt = str_replace('textarea', '!textarea', $filetxt); | |||||
$wintitle = "文件效验::查看文件"; | |||||
$wecome_info = "<a href='sys_verifies.php'><u>文件效验</u></a>::查看文件"; | |||||
$win = new OxWindow(); | |||||
$win->Init(); | |||||
$win->AddTitle("以下为文件 $filename 的内容,请检查是否可疑:"); | |||||
$winform = $win->GetWindow("hand","<textarea name='filetxt' style='width:100%;height:450px;word-wrap: break-word;word-break:break-all;'>".$filetxt."</textarea>"); | |||||
$win->Display(); | |||||
exit(); | |||||
} | |||||
/*----------------- | |||||
管理指纹码 | |||||
function _manage() { } | |||||
-------------------*/ | |||||
else if ($action == 'manage') | |||||
{ | |||||
$dsql->SetQuery("SELECT * FROM `#@__verifies` "); | |||||
$dsql->Execute(); | |||||
$filelist = array(); | |||||
while($row = $dsql->GetArray()) | |||||
{ | |||||
$filelist[] = $row; | |||||
} | |||||
include(DEDEADMIN.'/templets/sys_verifies_manage.htm'); | |||||
exit(); | |||||
} | |||||
/*----------------------- | |||||
下载文件 | |||||
function _getfiles() | |||||
------------------------*/ | |||||
else if ($action == 'getfiles') | |||||
{ | |||||
if(!isset($refiles)) | |||||
{ | |||||
ShowMsg("你没进行任何操作!","sys_verifies.php"); | |||||
exit(); | |||||
} | |||||
$cacheFiles = DEDEDATA.'/modifytmp.inc'; | |||||
$fp = fopen($cacheFiles, 'w'); | |||||
fwrite($fp, '<'.'?php'."\r\n"); | |||||
fwrite($fp, '$tmpdir = "'.$tmpdir.'";'."\r\n"); | |||||
$dirs = array(); | |||||
$i = -1; | |||||
$adminDir = preg_replace("#(.*)[\/\\\\]#", "", dirname(__FILE__)); | |||||
foreach($refiles as $filename) | |||||
{ | |||||
$filename = substr($filename,3,strlen($filename)-3); | |||||
if(preg_match("#^dede/#i", $filename)) | |||||
{ | |||||
$curdir = GetDirName( preg_replace("#^dede/#i", $adminDir.'/', $filename) ); | |||||
} else { | |||||
$curdir = GetDirName($filename); | |||||
} | |||||
if( !isset($dirs[$curdir]) ) | |||||
{ | |||||
$dirs[$curdir] = TestIsFileDir($curdir); | |||||
} | |||||
$i++; | |||||
fwrite($fp, '$files['.$i.'] = "'.$filename.'";'."\r\n"); | |||||
} | |||||
fwrite($fp, '$fileConut = '.$i.';'."\r\n"); | |||||
fwrite($fp, '?'.'>'); | |||||
fclose($fp); | |||||
$dirinfos = ''; | |||||
if($i > -1) | |||||
{ | |||||
$dirinfos = '<tr bgcolor="#ffffff"><td colspan="2">'; | |||||
$dirinfos .= "本次升级需要在下面文件夹写入更新文件,请注意文件夹是否有写入权限:<br />\r\n"; | |||||
foreach($dirs as $curdir) | |||||
{ | |||||
$dirinfos .= $curdir['name']." 状态:".($curdir['writeable'] ? "[√正常]" : "<font color='red'>[×不可写]</font>")."<br />\r\n"; | |||||
} | |||||
$dirinfos .= "</td></tr>\r\n"; | |||||
} | |||||
$doneStr = "<iframe name='stafrm' src='sys_verifies.php?action=down&curfile=0' frameborder='0' id='stafrm' width='100%' height='100%'></iframe>\r\n"; | |||||
include(DEDEADMIN.'/templets/sys_verifies_getfiles.htm'); | |||||
exit(); | |||||
} | |||||
/*----------------------- | |||||
下载文件 | |||||
function _down() | |||||
------------------------*/ | |||||
else if($action=='down') | |||||
{ | |||||
$cacheFiles = DEDEDATA.'/modifytmp.inc'; | |||||
require_once($cacheFiles); | |||||
if($fileConut==-1 || $curfile > $fileConut) | |||||
{ | |||||
ShowMsg("已下载所有文件<br /><a href='sys_verifies.php?action=apply'>[直接替换文件]</a> <a href='#'>[我自己手动替换文件]</a>","javascript:;"); | |||||
exit(); | |||||
} | |||||
//检查临时文件保存目录是否可用 | |||||
MkTmpDir($tmpdir, $files[$curfile]); | |||||
$downfile = UPDATEHOST.$cfg_soft_lang.'/source/'.$files[$curfile]; | |||||
$dhd = new DedeHttpDown(); | |||||
$dhd->OpenUrl($downfile); | |||||
$dhd->SaveToBin(DEDEDATA.'/'.$tmpdir.'/'.$files[$curfile]); | |||||
$dhd->Close(); | |||||
ShowMsg("成功下载文件:{$files[$curfile]}; 继续下载下一个文件。","sys_verifies.php?action=down&curfile=".($curfile+1)); | |||||
exit(); | |||||
} | |||||
/*----------------------- | |||||
修改效验方式 | |||||
function _modify() | |||||
------------------------*/ | |||||
else if($action=='modify') | |||||
{ | |||||
if(!isset($modifys)) | |||||
{ | |||||
ShowMsg("没选定要修改的文件!","-1"); | |||||
exit(); | |||||
} | |||||
else | |||||
{ | |||||
foreach($modifys as $fname) | |||||
{ | |||||
if($method=='local') | |||||
{ | |||||
$tureFilename = str_replace('../dede','./',$fname); | |||||
if(file_exists($tureFilename)) | |||||
{ | |||||
$fp = fopen($tureFilename,'r'); | |||||
$ct = fread($fp,filesize($tureFilename)); | |||||
fclose($fp); | |||||
$cthash = md5($ct); | |||||
$dsql->ExecuteNoneQuery("UPDATE `#@__verifies` SET `method`='local',cthash='$cthash' WHERE filename='$fname' "); | |||||
} | |||||
} | |||||
else | |||||
{ | |||||
$dsql->ExecuteNoneQuery("UPDATE `#@__verifies` SET `method`='offical' WHERE filename='$fname' "); | |||||
} | |||||
} | |||||
} | |||||
if($method=='local') | |||||
{ | |||||
ShowMsg("成功修改指定文件的验证方式!","sys_verifies.php?action=manage"); | |||||
} | |||||
else | |||||
{ | |||||
ShowMsg("成功修改指定文件的验证方式!<br /> 由于你修改了文件为远程验证方式,因此需进行更新操作<br /> <a href='sys_verifies.php?action=update'>[更新]</a> <a href='sys_verifies.php?action=manage'>[返回]</a>","javascript:;"); | |||||
} | |||||
exit(); | |||||
} | |||||
/*----------------------- | |||||
还原文件 | |||||
function _applyRecover() | |||||
------------------------*/ | |||||
else if ($action == 'apply') | |||||
{ | |||||
$cacheFiles = DEDEDATA.'/modifytmp.inc'; | |||||
require_once($cacheFiles); | |||||
$sDir = DEDEDATA."/$tmpdir"; | |||||
$tDir = DEDEROOT; | |||||
$badcp = 0; | |||||
$adminDir = preg_replace("#(.*)[\/\\\\]#", "", dirname(__FILE__)); | |||||
if(isset($files) && is_array($files)) | |||||
{ | |||||
foreach($files as $f) | |||||
{ | |||||
if(preg_match("#^dede#", $f)) $tf = preg_replace("#^dede#", $adminDir, $f); | |||||
else $tf = $f; | |||||
if(file_exists($sDir.'/'.$f)) | |||||
{ | |||||
//还原文件前先进行文件效验 | |||||
$ct = file_get_contents($sDir.'/'.$f); | |||||
$ct = preg_replace("/\/\*\*[\r\n]{1,}(.*)[\r\n]{1,} \*\//sU", '', $ct); | |||||
$newhash = md5($ct); | |||||
$row = $dsql->GetOne("SELECT * FROM `#@__verifies` WHERE filename='../{$f}' "); | |||||
if(is_array($row) && $row['cthash'] != $newhash) | |||||
{ | |||||
$badcp++; | |||||
} else { | |||||
$rs = @copy($sDir.'/'.$f, $tDir.'/'.$tf); | |||||
if($rs) unlink($sDir.'/'.$f); | |||||
else $badcp++; | |||||
} | |||||
} | |||||
} | |||||
} | |||||
$badmsg = '!'; | |||||
if($badcp > 0) | |||||
{ | |||||
$badmsg = ",其 {$badcp} 个文件效验码不正确或复制失败,<br />请从临时目录[../data/{$tmpdir}]中取出这几个文件手动还原。"; | |||||
} | |||||
ShowMsg("成功完成还原指定文件{$badmsg}", "javascript:;"); | |||||
exit(); | |||||
} | |||||
/*--------------- | |||||
在线更新指纹码 | |||||
function _update() | |||||
-----------------*/ | |||||
else if($action == 'update') | |||||
{ | |||||
$rmFile = UPDATEHOST.$cfg_soft_lang.'/verifys.txt'; | |||||
$dhd = new DedeHttpDown(); | |||||
$dhd->OpenUrl($rmFile); | |||||
$ct = $dhd->GetHtml(); | |||||
$dhd->Close(); | |||||
$cts = split("[\r\n]{1,}",$ct); | |||||
foreach($cts as $ct) | |||||
{ | |||||
$ct = trim($ct); | |||||
if(empty($ct)) continue; | |||||
list($nameid, $cthash, $fname) = explode("\t", $ct); | |||||
$row = $dsql->GetOne("SELECT * FROM `#@__verifies` WHERE nameid='$nameid' "); | |||||
if(!is_array($row) || ($row['method']=='official' && $row['cthash']!=$cthash )) | |||||
{ | |||||
$dsql->ExecuteNoneQuery("REPLACE INTO `#@__verifies`(nameid,cthash,method,filename) VALUES ('$nameid','$cthash','official','$fname'); "); | |||||
} | |||||
} | |||||
$fp = fopen($verifiesLockFile,'w'); | |||||
fwrite($fp, MyDate('Ymd',time())); | |||||
fclose($fp); | |||||
ShowMsg("完成效验码更新,是否马上进行效验操作?<br /> <a href='sys_verifies.php?action=verify'>[开始效验]</a> <a href='sys_verifies.php?action=manage'>[管理]</a> <a href='sys_verifies.php'>[返回]</a>","javascript:;"); | |||||
exit(); | |||||
} | |||||
/*----------------- | |||||
生成指纹码 | |||||
function _make() { } | |||||
-------------------*/ | |||||
else if ($action == 'make') | |||||
{ | |||||
$fp = fopen(DEDEROOT.'/../verifys.txt','w'); | |||||
foreach (preg_ls ('../', TRUE, "/.*\.(php|htm|html|js)$/i", 'CVS,data,html,uploads,templets,special') as $onefile) | |||||
{ | |||||
$nameid = md5($onefile); | |||||
$ctbody = file_get_contents(DEDEADMIN.'/'.$onefile); | |||||
$ctbody = preg_replace("/\/\*\*[\r\n]{1,}(.*)[\r\n]{1,} \*\//sU", '', $ctbody); | |||||
$cthash = md5($ctbody); | |||||
fwrite($fp,"{$nameid}\t{$cthash}\t{$onefile}\r\n"); | |||||
} | |||||
fclose($fp); | |||||
ShowMsg("操作成功!","sys_verifies.php"); | |||||
exit(); | |||||
} | |||||
//获取所有文件列表 | |||||
function preg_ls($path=".", $rec=FALSE, $pat="/.*/", $ignoredir='') | |||||
{ | |||||
while (substr ($path,-1,1) =="/") | |||||
{ | |||||
$path=substr ($path,0,-1); | |||||
} | |||||
if (!is_dir ($path) ) | |||||
{ | |||||
$path=dirname ($path); | |||||
} | |||||
if ($rec!==TRUE) | |||||
{ | |||||
$rec=FALSE; | |||||
} | |||||
$d=dir ($path); | |||||
$ret=Array (); | |||||
while (FALSE!== ($e=$d->read () ) ) | |||||
{ | |||||
if ( ($e==".") || ($e=="..") ) | |||||
{ | |||||
continue; | |||||
} | |||||
if ($rec && is_dir ($path."/".$e) && ($ignoredir == '' || strpos($ignoredir,$e ) === FALSE)) | |||||
{ | |||||
$ret = array_merge ($ret, preg_ls($path."/".$e, $rec, $pat, $ignoredir)); | |||||
continue; | |||||
} | |||||
if (!preg_match ($pat, $e) ) | |||||
{ | |||||
continue; | |||||
} | |||||
$ret[] = $path."/".$e; | |||||
} | |||||
return (empty ($ret) && preg_match ($pat,basename($path))) ? Array ($path."/") : $ret; | |||||
} | |||||
function TestWriteAble($d) | |||||
{ | |||||
$tfile = '_dedet.txt'; | |||||
$fp = @fopen($d.$tfile, 'w'); | |||||
if(!$fp) | |||||
{ | |||||
return FALSE; | |||||
} | |||||
else { | |||||
fclose($fp); | |||||
$rs = @unlink($d.'/'.$tfile); | |||||
return TRUE; | |||||
} | |||||
} | |||||
function GetDirName($filename) | |||||
{ | |||||
$dirname = '../'.preg_replace("#[\\\\\/]{1,}#", '/', $filename); | |||||
$dirname = preg_replace("#([^\/]*)$#", '', $dirname); | |||||
return $dirname; | |||||
} | |||||
function TestIsFileDir($dirname) | |||||
{ | |||||
$dirs = array('name'=>'','isdir'=>FALSE,'writeable'=>FALSE); | |||||
$dirs['name'] = $dirname; | |||||
if(is_dir($dirname)) | |||||
{ | |||||
$dirs['isdir'] = TRUE; | |||||
$dirs['writeable'] = TestWriteAble($dirname); | |||||
} | |||||
return $dirs; | |||||
} | |||||
function MkTmpDir($tmpdir,$filename) | |||||
{ | |||||
$basedir = DEDEDATA.'/'.$tmpdir; | |||||
$dirname = trim(preg_replace("#[\\\\\/]{1,}#", '/', $filename)); | |||||
$dirname = preg_replace("#([^\/]*)$#", "", $dirname); | |||||
if(!is_dir($basedir)) | |||||
{ | |||||
mkdir($basedir, 0777); | |||||
} | |||||
if($dirname=='') | |||||
{ | |||||
return TRUE; | |||||
} | |||||
$dirs = explode('/', $dirname); | |||||
$curdir = $basedir; | |||||
foreach($dirs as $d) | |||||
{ | |||||
$d = trim($d); | |||||
if(empty($d)) continue; | |||||
$curdir = $curdir.'/'.$d; | |||||
if(!is_dir($curdir)) | |||||
{ | |||||
mkdir($curdir,0777) or die($curdir); | |||||
} | |||||
} | |||||
return TRUE; | |||||
} |
@@ -5,8 +5,8 @@ | |||||
<head> | <head> | ||||
<meta http-equiv="Content-Type" content="text/html; charset=<?php echo $cfg_soft_lang; ?>"> | <meta http-equiv="Content-Type" content="text/html; charset=<?php echo $cfg_soft_lang; ?>"> | ||||
<title>木马自检程序</title> | <title>木马自检程序</title> | ||||
<link rel="stylesheet" href="../static/css/bootstrap.min.css"> | |||||
<link href="../static/font-awesome/css/font-awesome.min.css" rel="stylesheet"> | |||||
<link rel="stylesheet" href="../static/css/bootstrap.min.css"> | |||||
<link href="../static/font-awesome/css/font-awesome.min.css" rel="stylesheet"> | |||||
<link href="css/base.css" rel="stylesheet" type="text/css" /> | <link href="css/base.css" rel="stylesheet" type="text/css" /> | ||||
<link rel="stylesheet" type="text/css" href="css/indexbody.css" /> | <link rel="stylesheet" type="text/css" href="css/indexbody.css" /> | ||||
<style type="text/css"> | <style type="text/css"> | ||||
@@ -48,6 +48,7 @@ | |||||
<div class="bodytitleleft"></div> | <div class="bodytitleleft"></div> | ||||
<div class="bodytitletxt" style="padding-left:10px;">用户安全中心</div> | <div class="bodytitletxt" style="padding-left:10px;">用户安全中心</div> | ||||
</div> | </div> | ||||
<?php echo $alter;?> | |||||
<table width="98%" border="0" cellpadding="1" cellspacing="1" align="center" class="table maintable" | <table width="98%" border="0" cellpadding="1" cellspacing="1" align="center" class="table maintable" | ||||
style="background:#CFCFCF;"> | style="background:#CFCFCF;"> | ||||
<tr> | <tr> | ||||
@@ -70,7 +71,7 @@ | |||||
<input name="filetype" type="text" id="filetype" value="php|inc" style="width:420px" /> | <input name="filetype" type="text" id="filetype" value="php|inc" style="width:420px" /> | ||||
要检查的文件类型</p> | 要检查的文件类型</p> | ||||
<p>代码特征: | <p>代码特征: | ||||
<input name="info" type="text" id="info" value="eval|cmd|system|exec|_GET|_POST" style="width:420px" /> | |||||
<input name="info" type="text" id="info" value="eval|cmd|system|exec|_GET|_POST|_REQUEST|base64_decode" style="width:420px" /> | |||||
特征代码</p> | 特征代码</p> | ||||
</td> | </td> | ||||
</tr> | </tr> | ||||
@@ -0,0 +1,95 @@ | |||||
<!doctype html> | |||||
<html> | |||||
<head> | |||||
<meta charset="utf-8"> | |||||
<meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1"> | |||||
<title>查看差异</title> | |||||
<link rel="stylesheet" type="text/css" href="../static/css/diffview.css" /> | |||||
<script type="text/javascript" src="../static/js/jquery.js"></script> | |||||
<script type="text/javascript" src="../static/js/diffview.js"></script> | |||||
<script type="text/javascript" src="../static/js/difflib.js"></script> | |||||
<style type="text/css"> | |||||
body { | |||||
font-size: 12px; | |||||
font-family: Sans-Serif; | |||||
} | |||||
h2 { | |||||
margin: 0.5em 0 0.1em; | |||||
text-align: center; | |||||
} | |||||
.top { | |||||
text-align: center; | |||||
} | |||||
.textInput { | |||||
display: block; | |||||
width: 49%; | |||||
float: left; | |||||
} | |||||
textarea { | |||||
width: 100%; | |||||
height: 300px; | |||||
} | |||||
label:hover { | |||||
text-decoration: underline; | |||||
cursor: pointer; | |||||
} | |||||
.spacer { | |||||
margin-left: 10px; | |||||
} | |||||
.viewType { | |||||
font-size: 16px; | |||||
clear: both; | |||||
text-align: center; | |||||
padding: 1em; | |||||
} | |||||
#diffoutput { | |||||
width: 100%; | |||||
} | |||||
</style> | |||||
<script type="text/javascript"> | |||||
function diffUsingJS(viewType) { | |||||
"use strict"; | |||||
var base = difflib.stringAsLines($("#baseText").val()), | |||||
newtxt = difflib.stringAsLines($("#newText").val()), | |||||
sm = new difflib.SequenceMatcher(base, newtxt), | |||||
opcodes = sm.get_opcodes(), | |||||
diffoutputdiv = $("#diffoutput"); | |||||
diffoutputdiv.html("") | |||||
diffoutputdiv.html(diffview.buildView({ | |||||
baseTextLines: base, | |||||
newTextLines: newtxt, | |||||
opcodes: opcodes, | |||||
baseTextName: "官方服务器文件", | |||||
newTextName: "本地文件", | |||||
viewType: 0 | |||||
})); | |||||
} | |||||
</script> | |||||
</head> | |||||
<body> | |||||
<textarea id="baseText" style="display: none;"><?php echo $base ;?></textarea> | |||||
<textarea id="newText" style="display: none;"><?php echo $new ;?></textarea> | |||||
<div id="diffoutput"> </div> | |||||
<script> | |||||
$(document).ready(function () { | |||||
diffUsingJS(1); | |||||
}); | |||||
</script> | |||||
</body> | |||||
</html> |
@@ -1,78 +0,0 @@ | |||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | |||||
<html xmlns="http://www.w3.org/1999/xhtml"> | |||||
<head> | |||||
<meta http-equiv="Content-Type" content="text/html; charset=<?php echo $cfg_soft_lang; ?>"> | |||||
<title>文件校验</title> | |||||
<link href='css/base.css' rel='stylesheet' type='text/css' /> | |||||
<link rel="stylesheet" type="text/css" href="css/indexbody.css" /> | |||||
<script language='javascript'> | |||||
function Loading(surl) | |||||
{ | |||||
document.getElementById('loaddiv').style.display = 'block'; | |||||
location = surl; | |||||
} | |||||
</script> | |||||
</head> | |||||
<body background='images/allbg.gif' leftmargin='8' topmargin='8'> | |||||
<div id='loaddiv' style='display:none'> | |||||
<p align='center' style='padding-top:200px'><img src='images/loadinglit.gif' /> 请稍后,正在处理中...</p> | |||||
</div> | |||||
<table width="98%" border="0" align="center" cellpadding="3" cellspacing="1" bgcolor="#D6D6D6"> | |||||
<tr> | |||||
<td height="19" background="images/tbg.gif"> | |||||
<table width="96%" border="0" cellspacing="1" cellpadding="1"> | |||||
<tr> | |||||
<td width="24%"><strong>文件校验操作:</strong></td> | |||||
<td width="76%" align="right"> | |||||
</td> | |||||
</tr> | |||||
</table> | |||||
</td> | |||||
</tr> | |||||
<tr> | |||||
<td height="200" bgcolor="#FFFFFF" valign="top"> | |||||
<table width="100%" border="0" cellspacing="4" cellpadding="2"> | |||||
<tr> | |||||
<td height="53" align="center"> </td> | |||||
<td> | |||||
您的系统最后升级时间:<b><?php echo $updateTime; ?></b>;指纹码最后同步时间:<b><?php echo $verifiesTime; ?></b> | |||||
<br /> | |||||
第一次效验文件时或您的系统已经升级过,请先点击“在线获取最新指纹码” | |||||
<br /> | |||||
(文件校验将检查本站文件是否和DedeCMS原始文件是否完全一致,如果要替换差异文件,必须按提示设置被更改文件的目录有可写入权限) | |||||
</td> | |||||
<tr> | |||||
<td height="53" align="center"> </td> | |||||
<td> | |||||
<div style='width:80%;background:#F9FCEF;border-bottom: 1px dashed #A7BA87;padding:3px;'> <b>效对操作:</b></div> | |||||
<div style='padding:10px 0px 20px 0px;'> | |||||
<a href="javascript:Loading('sys_verifies.php?action=update');" class='np coolbg'>在线获取最新指纹码==></a> | |||||
| |||||
<a href="javascript:Loading('sys_verifies.php?action=verify');" class='np coolbg'>效对本地文件==></a> | |||||
| |||||
下载差异文件==> | |||||
| |||||
替换差异文件==> | |||||
</div> | |||||
<div style='width:80%;background:#F9FCEF;border-bottom: 1px dashed #A7BA87;padding:3px;'> <b>管理指纹码:</b>(对于您自己修改过的文件,您可以在列表中屏蔽,下次忽略这些文件的效验)</div> | |||||
<div style='padding:10px 0px 180px 0px;'> | |||||
<a href="javascript:Loading('sys_verifies.php?action=manage');" class='np coolbg'>管理现有的指纹码</a> | |||||
</div> | |||||
<!-- | |||||
<div style='width:80%;background:#D9E1CA;border-bottom: 1px dashed #A7BA87;padding:3px;'> <b>生成指纹码:</b></div> | |||||
<div style='padding:10px 0px 20px 0px;'> | |||||
<a href="javascript:Loading('sys_verifies.php?action=make');" class='np coolbg'>生成指纹码(官方使用)</a> | |||||
</div> | |||||
--> | |||||
<br /> | |||||
<br /> | |||||
<br /> | |||||
</td> | |||||
</tr> | |||||
</table> | |||||
</td> | |||||
</tr> | |||||
</table> | |||||
</body> | |||||
</html> |
@@ -1,56 +0,0 @@ | |||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | |||||
<html xmlns="http://www.w3.org/1999/xhtml"> | |||||
<head> | |||||
<meta http-equiv="Content-Type" content="text/html; charset=<?php echo $cfg_soft_lang; ?>"> | |||||
<title>文件效验程序--下载更新文件</title> | |||||
<link href="css/base.css" rel="stylesheet" type="text/css"> | |||||
</head> | |||||
<body background='images/allbg.gif' leftmargin='8' topmargin='8'> | |||||
<table width="98%" border="0" cellpadding="3" cellspacing="1" bgcolor="#D6D6D6" align="center"> | |||||
<tr> | |||||
<td height="28" colspan="2" background='images/tbg.gif'> | |||||
<div style="float:left"> | |||||
<strong><a href='sys_verifies.php'><b>文件校验操作</b></a> >> 下载差异文件</strong> | |||||
</div> | |||||
<div style="float:right;padding-right:6px;"> | |||||
<a href='index_body.php' class='np coolbg'>返回系统主页</a> | |||||
</div> | |||||
</td> | |||||
</tr> | |||||
<tr bgcolor="#ffffff"> | |||||
<td height="20" colspan="2"> | |||||
下载的文件临时存放在文件夹(<font color='red'>../data/<?php echo $tmpdir; ?></font>)内,如果某些基础类有重要的改动导致更新中途中错,您可以从这文件夹提取文件手工更新。 | |||||
</td> | |||||
</tr> | |||||
<?php echo $dirinfos; ?> | |||||
<tr bgcolor="#F8FEDA"> | |||||
<td height="20" colspan="2"> | |||||
<table width="100%"> | |||||
<tr> | |||||
<td width="74%">进行状态: </td> | |||||
<td width="26%" align="right"> | |||||
<script language='javascript'> | |||||
function ResizeDiv(obj,ty) | |||||
{ | |||||
if(ty=="+") document.all[obj].style.pixelHeight += 50; | |||||
else if(document.all[obj].style.pixelHeight>80) document.all[obj].style.pixelHeight = document.all[obj].style.pixelHeight - 50; | |||||
} | |||||
</script> | |||||
[<a href='#' onClick="ResizeDiv('mdv','+');">增大</a>] [<a href='#' onClick="ResizeDiv('mdv','-');">缩小</a>] | |||||
</td> | |||||
</tr> | |||||
</table> | |||||
</td> | |||||
</tr> | |||||
<tr bgcolor="#FFFFFF"> | |||||
<td colspan="2" id="mtd"> | |||||
<div id='mdv' style='width:100%;height:350px;'> | |||||
<?php | |||||
echo $doneStr; | |||||
?> | |||||
</div> | |||||
</td> | |||||
</tr> | |||||
</table> | |||||
</body> | |||||
</html> |
@@ -1,74 +0,0 @@ | |||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | |||||
<html xmlns="http://www.w3.org/1999/xhtml"> | |||||
<head> | |||||
<meta http-equiv="Content-Type" content="text/html; charset=<?php echo $cfg_soft_lang; ?>"> | |||||
<title>文件校验</title> | |||||
<link href='css/base.css' rel='stylesheet' type='text/css'> | |||||
</head> | |||||
<body background='images/allbg.gif' leftmargin='8' topmargin='8'> | |||||
<table width="98%" border="0" align="center" cellpadding="3" cellspacing="1" bgcolor="#D6D6D6"> | |||||
<tr> | |||||
<td height="19" background="images/tbg.gif"> | |||||
<table width="96%" border="0" cellspacing="1" cellpadding="1"> | |||||
<tr> | |||||
<td width="24%"> | |||||
<strong><a href='sys_verifies.php'><b>文件校验</b></a> >> 文件效验管理</strong> | |||||
</td> | |||||
<td width="76%" align="right"> | |||||
</td> | |||||
</tr> | |||||
</table> | |||||
</td> | |||||
</tr> | |||||
<tr> | |||||
<td height="200" bgcolor="#FFFFFF" valign="top"> | |||||
<table width="100%" border="0" cellspacing="0" cellpadding="0"> | |||||
<form action="sys_verifies.php?action=modify" method="post"> | |||||
<tr> | |||||
<td colspan="4" class='bline2' style="color:red"> 说明:这里是系统文件列表,如果本地对某些文件做过修改,但又不希望同官方服务器上面的镜像版本(发布版本)对应文件进行同步,可将文件校验方式修改为“本地(local)”,以确保不会重新下载文件修复。</td> | |||||
</tr> | |||||
<tr> | |||||
<td class='bline2'> 修改? </td> | |||||
<td class='bline2'> 文件名(用 Ctrl+F 搜索) </td> | |||||
<td class='bline2'> 文件HASH </td> | |||||
<td class='bline2'> 校验方式 </td> | |||||
</tr> | |||||
<?php | |||||
foreach ($filelist as $key => $file) | |||||
{ | |||||
?> | |||||
<tr> | |||||
<td class='bline'> | |||||
<input type="checkbox" name="modifys[]" value="<?php echo $file['filename'];?>" /> | |||||
</td> | |||||
<td class='bline'> | |||||
<?php echo $file['filename'];?> | |||||
</td> | |||||
<td class='bline'> | |||||
<?php echo $file['cthash'];?> | |||||
</td> | |||||
<td class='bline'> | |||||
<?php echo $file['method'];?> | |||||
</td> | |||||
</tr> | |||||
<?php | |||||
} | |||||
?> | |||||
<tr> | |||||
<td colspan="20" height='28'> | |||||
<label><input type="radio" name="method" value="offical" />官方(official)</label> | |||||
<label><input type="radio" name="method" value="local" checked='1' />本地(local)</label> | |||||
</td> | |||||
</tr> | |||||
<tr> | |||||
<td colspan="20" height='36'> | |||||
<input type="submit" name="submit" value="修改要文件的校验方式" class='np coolbg' /> | |||||
</td> | |||||
</tr> | |||||
</form> | |||||
</table> | |||||
</td> | |||||
</tr> | |||||
</table> | |||||
</body> | |||||
</html> |
@@ -1,73 +0,0 @@ | |||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | |||||
<html xmlns="http://www.w3.org/1999/xhtml"> | |||||
<head> | |||||
<meta http-equiv="Content-Type" content="text/html; charset=<?php echo $cfg_soft_lang; ?>"> | |||||
<title>文件校验</title> | |||||
<link href='css/base.css' rel='stylesheet' type='text/css'> | |||||
</head> | |||||
<body background='images/allbg.gif' leftmargin='8' topmargin='8'> | |||||
<table width="98%" border="0" align="center" cellpadding="3" cellspacing="1" bgcolor="#D6D6D6"> | |||||
<tr> | |||||
<td height="19" background="images/tbg.gif"> | |||||
<table width="96%" border="0" cellspacing="1" cellpadding="1"> | |||||
<tr> | |||||
<td width="24%"> | |||||
<a href='sys_verifies.php'><b>文件效验</b></a> | |||||
>> | |||||
<strong>校验结果:</strong> 共有 <?php echo count($filelist); ?> 个文件不同 | |||||
</td> | |||||
<td width="76%" align="right"> | |||||
</td> | |||||
</tr> | |||||
</table> | |||||
</td> | |||||
</tr> | |||||
<tr> | |||||
<td height="200" bgcolor="#FFFFFF" valign="top"> | |||||
<table width="100%" border="0" cellspacing="0" cellpadding="0"> | |||||
<form action="sys_verifies.php?action=getfiles" method="post"> | |||||
<tr> | |||||
<td class='bline2'> 恢复? </td> | |||||
<td class='bline2'> 文件名(Ctrl+F查找) </td> | |||||
<td class='bline2'> 校验方式 </td> | |||||
<td class='bline2'> 最后修改时间 </td> | |||||
<td class='bline2'> 指纹码/点击可浏览文件内容 </td> | |||||
</tr> | |||||
<?php | |||||
foreach ($filelist as $key => $file) | |||||
{ | |||||
?> | |||||
<tr> | |||||
<td class='bline'> | |||||
<input type="checkbox" name="refiles[]" value="<?php echo $file['filename'];?>" checked='1' /> | |||||
</td> | |||||
<td class='bline'> | |||||
<?php echo $file['filename']; ?> | |||||
</td> | |||||
<td class='bline'> | |||||
<?php echo $file['method']; ?> | |||||
</td> | |||||
<td class='bline'> | |||||
<?php echo $file['mtime']; ?> | |||||
</td> | |||||
<td class='bline'> | |||||
<a href="sys_verifies.php?action=view&filename=<?php echo $file['turefile']; ?>" target="_blank" class='coolbg' title="标准效验码为: <?php echo $file['cthash']; ?>"> | |||||
<?php echo $file['localhash']; ?> | |||||
</a> | |||||
</td> | |||||
</tr> | |||||
<?php | |||||
} | |||||
?> | |||||
<tr> | |||||
<td colspan="20" height='42'> | |||||
<input type="submit" name="submit" value="从官方下载选中的文件并恢复" class='np coolbg' /> | |||||
</td> | |||||
</tr> | |||||
</table> | |||||
</form> | |||||
</td> | |||||
</tr> | |||||
</table> | |||||
</body> | |||||
</html> |
@@ -283,6 +283,24 @@ class DedeHttpDown | |||||
return $this->m_html; | return $this->m_html; | ||||
} | } | ||||
function GetJSON() | |||||
{ | |||||
if ($this->m_html != '') { | |||||
return json_decode($this->m_html); | |||||
} | |||||
if (!$this->IsText()) { | |||||
return ''; | |||||
} | |||||
if (!$this->m_fp || @feof($this->m_fp)) { | |||||
return ''; | |||||
} | |||||
while (!feof($this->m_fp)) { | |||||
$this->m_html .= fgets($this->m_fp, 256); | |||||
} | |||||
@fclose($this->m_fp); | |||||
return json_decode($this->m_html); | |||||
} | |||||
/** | /** | ||||
* 开始HTTP会话 | * 开始HTTP会话 | ||||
* | * | ||||
@@ -0,0 +1,83 @@ | |||||
/* | |||||
This is part of jsdifflib v1.0. <http://github.com/cemerick/jsdifflib> | |||||
Copyright 2007 - 2011 Chas Emerick <cemerick@snowtide.com>. All rights reserved. | |||||
Redistribution and use in source and binary forms, with or without modification, are | |||||
permitted provided that the following conditions are met: | |||||
1. Redistributions of source code must retain the above copyright notice, this list of | |||||
conditions and the following disclaimer. | |||||
2. Redistributions in binary form must reproduce the above copyright notice, this list | |||||
of conditions and the following disclaimer in the documentation and/or other materials | |||||
provided with the distribution. | |||||
THIS SOFTWARE IS PROVIDED BY Chas Emerick ``AS IS'' AND ANY EXPRESS OR IMPLIED | |||||
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND | |||||
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Chas Emerick OR | |||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | |||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | |||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | |||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||||
The views and conclusions contained in the software and documentation are those of the | |||||
authors and should not be interpreted as representing official policies, either expressed | |||||
or implied, of Chas Emerick. | |||||
*/ | |||||
table.diff { | |||||
border-collapse:collapse; | |||||
border:1px solid darkgray; | |||||
white-space:pre-wrap | |||||
} | |||||
table.diff tbody { | |||||
font-family:Courier, monospace | |||||
} | |||||
table.diff tbody th { | |||||
font-family:verdana,arial,'Bitstream Vera Sans',helvetica,sans-serif; | |||||
background:#EED; | |||||
font-size:11px; | |||||
font-weight:normal; | |||||
border:1px solid #BBC; | |||||
color:#886; | |||||
padding:.3em .5em .1em 2em; | |||||
text-align:right; | |||||
vertical-align:top | |||||
} | |||||
table.diff thead { | |||||
border-bottom:1px solid #BBC; | |||||
background:#EFEFEF; | |||||
font-family:Verdana | |||||
} | |||||
table.diff thead th.texttitle { | |||||
text-align:left | |||||
} | |||||
table.diff tbody td { | |||||
padding:0px .4em; | |||||
padding-top:.4em; | |||||
vertical-align:top; | |||||
} | |||||
table.diff .empty { | |||||
background-color:#DDD; | |||||
} | |||||
table.diff .replace { | |||||
background-color:#FD8 | |||||
} | |||||
table.diff .delete { | |||||
background-color:#E99; | |||||
} | |||||
table.diff .skip { | |||||
background-color:#EFEFEF; | |||||
border:1px solid #AAA; | |||||
border-right:1px solid #BBC; | |||||
} | |||||
table.diff .insert { | |||||
background-color:#9E9 | |||||
} | |||||
table.diff th.author { | |||||
text-align:right; | |||||
border-top:1px solid #BBC; | |||||
background:#EFEFEF | |||||
} |
@@ -0,0 +1,411 @@ | |||||
/*** | |||||
This is part of jsdifflib v1.0. <http://snowtide.com/jsdifflib> | |||||
Copyright (c) 2007, Snowtide Informatics Systems, Inc. | |||||
All rights reserved. | |||||
Redistribution and use in source and binary forms, with or without modification, | |||||
are permitted provided that the following conditions are met: | |||||
* Redistributions of source code must retain the above copyright notice, this | |||||
list of conditions and the following disclaimer. | |||||
* Redistributions in binary form must reproduce the above copyright notice, | |||||
this list of conditions and the following disclaimer in the documentation | |||||
and/or other materials provided with the distribution. | |||||
* Neither the name of the Snowtide Informatics Systems nor the names of its | |||||
contributors may be used to endorse or promote products derived from this | |||||
software without specific prior written permission. | |||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY | |||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT | |||||
SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | |||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED | |||||
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR | |||||
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | |||||
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH | |||||
DAMAGE. | |||||
***/ | |||||
/* Author: Chas Emerick <cemerick@snowtide.com> */ | |||||
__whitespace = {" ":true, "\t":true, "\n":true, "\f":true, "\r":true}; | |||||
difflib = { | |||||
defaultJunkFunction: function (c) { | |||||
return __whitespace.hasOwnProperty(c); | |||||
}, | |||||
stripLinebreaks: function (str) { return str.replace(/^[\n\r]*|[\n\r]*$/g, ""); }, | |||||
stringAsLines: function (str) { | |||||
var lfpos = str.indexOf("\n"); | |||||
var crpos = str.indexOf("\r"); | |||||
var linebreak = ((lfpos > -1 && crpos > -1) || crpos < 0) ? "\n" : "\r"; | |||||
var lines = str.split(linebreak); | |||||
for (var i = 0; i < lines.length; i++) { | |||||
lines[i] = difflib.stripLinebreaks(lines[i]); | |||||
} | |||||
return lines; | |||||
}, | |||||
// iteration-based reduce implementation | |||||
__reduce: function (func, list, initial) { | |||||
if (initial != null) { | |||||
var value = initial; | |||||
var idx = 0; | |||||
} else if (list) { | |||||
var value = list[0]; | |||||
var idx = 1; | |||||
} else { | |||||
return null; | |||||
} | |||||
for (; idx < list.length; idx++) { | |||||
value = func(value, list[idx]); | |||||
} | |||||
return value; | |||||
}, | |||||
// comparison function for sorting lists of numeric tuples | |||||
__ntuplecomp: function (a, b) { | |||||
var mlen = Math.max(a.length, b.length); | |||||
for (var i = 0; i < mlen; i++) { | |||||
if (a[i] < b[i]) return -1; | |||||
if (a[i] > b[i]) return 1; | |||||
} | |||||
return a.length == b.length ? 0 : (a.length < b.length ? -1 : 1); | |||||
}, | |||||
__calculate_ratio: function (matches, length) { | |||||
return length ? 2.0 * matches / length : 1.0; | |||||
}, | |||||
// returns a function that returns true if a key passed to the returned function | |||||
// is in the dict (js object) provided to this function; replaces being able to | |||||
// carry around dict.has_key in python... | |||||
__isindict: function (dict) { | |||||
return function (key) { return dict.hasOwnProperty(key); }; | |||||
}, | |||||
// replacement for python's dict.get function -- need easy default values | |||||
__dictget: function (dict, key, defaultValue) { | |||||
return dict.hasOwnProperty(key) ? dict[key] : defaultValue; | |||||
}, | |||||
SequenceMatcher: function (a, b, isjunk) { | |||||
this.set_seqs = function (a, b) { | |||||
this.set_seq1(a); | |||||
this.set_seq2(b); | |||||
} | |||||
this.set_seq1 = function (a) { | |||||
if (a == this.a) return; | |||||
this.a = a; | |||||
this.matching_blocks = this.opcodes = null; | |||||
} | |||||
this.set_seq2 = function (b) { | |||||
if (b == this.b) return; | |||||
this.b = b; | |||||
this.matching_blocks = this.opcodes = this.fullbcount = null; | |||||
this.__chain_b(); | |||||
} | |||||
this.__chain_b = function () { | |||||
var b = this.b; | |||||
var n = b.length; | |||||
var b2j = this.b2j = {}; | |||||
var populardict = {}; | |||||
for (var i = 0; i < b.length; i++) { | |||||
var elt = b[i]; | |||||
if (b2j.hasOwnProperty(elt)) { | |||||
var indices = b2j[elt]; | |||||
if (n >= 200 && indices.length * 100 > n) { | |||||
populardict[elt] = 1; | |||||
delete b2j[elt]; | |||||
} else { | |||||
indices.push(i); | |||||
} | |||||
} else { | |||||
b2j[elt] = [i]; | |||||
} | |||||
} | |||||
for (var elt in populardict) { | |||||
if (populardict.hasOwnProperty(elt)) { | |||||
delete b2j[elt]; | |||||
} | |||||
} | |||||
var isjunk = this.isjunk; | |||||
var junkdict = {}; | |||||
if (isjunk) { | |||||
for (var elt in populardict) { | |||||
if (populardict.hasOwnProperty(elt) && isjunk(elt)) { | |||||
junkdict[elt] = 1; | |||||
delete populardict[elt]; | |||||
} | |||||
} | |||||
for (var elt in b2j) { | |||||
if (b2j.hasOwnProperty(elt) && isjunk(elt)) { | |||||
junkdict[elt] = 1; | |||||
delete b2j[elt]; | |||||
} | |||||
} | |||||
} | |||||
this.isbjunk = difflib.__isindict(junkdict); | |||||
this.isbpopular = difflib.__isindict(populardict); | |||||
} | |||||
this.find_longest_match = function (alo, ahi, blo, bhi) { | |||||
var a = this.a; | |||||
var b = this.b; | |||||
var b2j = this.b2j; | |||||
var isbjunk = this.isbjunk; | |||||
var besti = alo; | |||||
var bestj = blo; | |||||
var bestsize = 0; | |||||
var j = null; | |||||
var j2len = {}; | |||||
var nothing = []; | |||||
for (var i = alo; i < ahi; i++) { | |||||
var newj2len = {}; | |||||
var jdict = difflib.__dictget(b2j, a[i], nothing); | |||||
for (var jkey in jdict) { | |||||
if (jdict.hasOwnProperty(jkey)) { | |||||
j = jdict[jkey]; | |||||
if (j < blo) continue; | |||||
if (j >= bhi) break; | |||||
newj2len[j] = k = difflib.__dictget(j2len, j - 1, 0) + 1; | |||||
if (k > bestsize) { | |||||
besti = i - k + 1; | |||||
bestj = j - k + 1; | |||||
bestsize = k; | |||||
} | |||||
} | |||||
} | |||||
j2len = newj2len; | |||||
} | |||||
while (besti > alo && bestj > blo && !isbjunk(b[bestj - 1]) && a[besti - 1] == b[bestj - 1]) { | |||||
besti--; | |||||
bestj--; | |||||
bestsize++; | |||||
} | |||||
while (besti + bestsize < ahi && bestj + bestsize < bhi && | |||||
!isbjunk(b[bestj + bestsize]) && | |||||
a[besti + bestsize] == b[bestj + bestsize]) { | |||||
bestsize++; | |||||
} | |||||
while (besti > alo && bestj > blo && isbjunk(b[bestj - 1]) && a[besti - 1] == b[bestj - 1]) { | |||||
besti--; | |||||
bestj--; | |||||
bestsize++; | |||||
} | |||||
while (besti + bestsize < ahi && bestj + bestsize < bhi && isbjunk(b[bestj + bestsize]) && | |||||
a[besti + bestsize] == b[bestj + bestsize]) { | |||||
bestsize++; | |||||
} | |||||
return [besti, bestj, bestsize]; | |||||
} | |||||
this.get_matching_blocks = function () { | |||||
if (this.matching_blocks != null) return this.matching_blocks; | |||||
var la = this.a.length; | |||||
var lb = this.b.length; | |||||
var queue = [[0, la, 0, lb]]; | |||||
var matching_blocks = []; | |||||
var alo, ahi, blo, bhi, qi, i, j, k, x; | |||||
while (queue.length) { | |||||
qi = queue.pop(); | |||||
alo = qi[0]; | |||||
ahi = qi[1]; | |||||
blo = qi[2]; | |||||
bhi = qi[3]; | |||||
x = this.find_longest_match(alo, ahi, blo, bhi); | |||||
i = x[0]; | |||||
j = x[1]; | |||||
k = x[2]; | |||||
if (k) { | |||||
matching_blocks.push(x); | |||||
if (alo < i && blo < j) | |||||
queue.push([alo, i, blo, j]); | |||||
if (i+k < ahi && j+k < bhi) | |||||
queue.push([i + k, ahi, j + k, bhi]); | |||||
} | |||||
} | |||||
matching_blocks.sort(difflib.__ntuplecomp); | |||||
var i1 = j1 = k1 = block = 0; | |||||
var non_adjacent = []; | |||||
for (var idx in matching_blocks) { | |||||
if (matching_blocks.hasOwnProperty(idx)) { | |||||
block = matching_blocks[idx]; | |||||
i2 = block[0]; | |||||
j2 = block[1]; | |||||
k2 = block[2]; | |||||
if (i1 + k1 == i2 && j1 + k1 == j2) { | |||||
k1 += k2; | |||||
} else { | |||||
if (k1) non_adjacent.push([i1, j1, k1]); | |||||
i1 = i2; | |||||
j1 = j2; | |||||
k1 = k2; | |||||
} | |||||
} | |||||
} | |||||
if (k1) non_adjacent.push([i1, j1, k1]); | |||||
non_adjacent.push([la, lb, 0]); | |||||
this.matching_blocks = non_adjacent; | |||||
return this.matching_blocks; | |||||
} | |||||
this.get_opcodes = function () { | |||||
if (this.opcodes != null) return this.opcodes; | |||||
var i = 0; | |||||
var j = 0; | |||||
var answer = []; | |||||
this.opcodes = answer; | |||||
var block, ai, bj, size, tag; | |||||
var blocks = this.get_matching_blocks(); | |||||
for (var idx in blocks) { | |||||
if (blocks.hasOwnProperty(idx)) { | |||||
block = blocks[idx]; | |||||
ai = block[0]; | |||||
bj = block[1]; | |||||
size = block[2]; | |||||
tag = ''; | |||||
if (i < ai && j < bj) { | |||||
tag = 'replace'; | |||||
} else if (i < ai) { | |||||
tag = 'delete'; | |||||
} else if (j < bj) { | |||||
tag = 'insert'; | |||||
} | |||||
if (tag) answer.push([tag, i, ai, j, bj]); | |||||
i = ai + size; | |||||
j = bj + size; | |||||
if (size) answer.push(['equal', ai, i, bj, j]); | |||||
} | |||||
} | |||||
return answer; | |||||
} | |||||
// this is a generator function in the python lib, which of course is not supported in javascript | |||||
// the reimplementation builds up the grouped opcodes into a list in their entirety and returns that. | |||||
this.get_grouped_opcodes = function (n) { | |||||
if (!n) n = 3; | |||||
var codes = this.get_opcodes(); | |||||
if (!codes) codes = [["equal", 0, 1, 0, 1]]; | |||||
var code, tag, i1, i2, j1, j2; | |||||
if (codes[0][0] == 'equal') { | |||||
code = codes[0]; | |||||
tag = code[0]; | |||||
i1 = code[1]; | |||||
i2 = code[2]; | |||||
j1 = code[3]; | |||||
j2 = code[4]; | |||||
codes[0] = [tag, Math.max(i1, i2 - n), i2, Math.max(j1, j2 - n), j2]; | |||||
} | |||||
if (codes[codes.length - 1][0] == 'equal') { | |||||
code = codes[codes.length - 1]; | |||||
tag = code[0]; | |||||
i1 = code[1]; | |||||
i2 = code[2]; | |||||
j1 = code[3]; | |||||
j2 = code[4]; | |||||
codes[codes.length - 1] = [tag, i1, Math.min(i2, i1 + n), j1, Math.min(j2, j1 + n)]; | |||||
} | |||||
var nn = n + n; | |||||
var group = []; | |||||
var groups = []; | |||||
for (var idx in codes) { | |||||
if (codes.hasOwnProperty(idx)) { | |||||
code = codes[idx]; | |||||
tag = code[0]; | |||||
i1 = code[1]; | |||||
i2 = code[2]; | |||||
j1 = code[3]; | |||||
j2 = code[4]; | |||||
if (tag == 'equal' && i2 - i1 > nn) { | |||||
group.push([tag, i1, Math.min(i2, i1 + n), j1, Math.min(j2, j1 + n)]); | |||||
groups.push(group); | |||||
group = []; | |||||
i1 = Math.max(i1, i2-n); | |||||
j1 = Math.max(j1, j2-n); | |||||
} | |||||
group.push([tag, i1, i2, j1, j2]); | |||||
} | |||||
} | |||||
if (group && !(group.length == 1 && group[0][0] == 'equal')) groups.push(group) | |||||
return groups; | |||||
} | |||||
this.ratio = function () { | |||||
matches = difflib.__reduce( | |||||
function (sum, triple) { return sum + triple[triple.length - 1]; }, | |||||
this.get_matching_blocks(), 0); | |||||
return difflib.__calculate_ratio(matches, this.a.length + this.b.length); | |||||
} | |||||
this.quick_ratio = function () { | |||||
var fullbcount, elt; | |||||
if (this.fullbcount == null) { | |||||
this.fullbcount = fullbcount = {}; | |||||
for (var i = 0; i < this.b.length; i++) { | |||||
elt = this.b[i]; | |||||
fullbcount[elt] = difflib.__dictget(fullbcount, elt, 0) + 1; | |||||
} | |||||
} | |||||
fullbcount = this.fullbcount; | |||||
var avail = {}; | |||||
var availhas = difflib.__isindict(avail); | |||||
var matches = numb = 0; | |||||
for (var i = 0; i < this.a.length; i++) { | |||||
elt = this.a[i]; | |||||
if (availhas(elt)) { | |||||
numb = avail[elt]; | |||||
} else { | |||||
numb = difflib.__dictget(fullbcount, elt, 0); | |||||
} | |||||
avail[elt] = numb - 1; | |||||
if (numb > 0) matches++; | |||||
} | |||||
return difflib.__calculate_ratio(matches, this.a.length + this.b.length); | |||||
} | |||||
this.real_quick_ratio = function () { | |||||
var la = this.a.length; | |||||
var lb = this.b.length; | |||||
return _calculate_ratio(Math.min(la, lb), la + lb); | |||||
} | |||||
this.isjunk = isjunk ? isjunk : difflib.defaultJunkFunction; | |||||
this.a = this.b = null; | |||||
this.set_seqs(a, b); | |||||
} | |||||
}; | |||||
@@ -0,0 +1,194 @@ | |||||
/* | |||||
This is part of jsdifflib v1.0. <http://github.com/cemerick/jsdifflib> | |||||
Copyright 2007 - 2011 Chas Emerick <cemerick@snowtide.com>. All rights reserved. | |||||
Redistribution and use in source and binary forms, with or without modification, are | |||||
permitted provided that the following conditions are met: | |||||
1. Redistributions of source code must retain the above copyright notice, this list of | |||||
conditions and the following disclaimer. | |||||
2. Redistributions in binary form must reproduce the above copyright notice, this list | |||||
of conditions and the following disclaimer in the documentation and/or other materials | |||||
provided with the distribution. | |||||
THIS SOFTWARE IS PROVIDED BY Chas Emerick ``AS IS'' AND ANY EXPRESS OR IMPLIED | |||||
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND | |||||
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Chas Emerick OR | |||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | |||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | |||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | |||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||||
The views and conclusions contained in the software and documentation are those of the | |||||
authors and should not be interpreted as representing official policies, either expressed | |||||
or implied, of Chas Emerick. | |||||
*/ | |||||
diffview = { | |||||
/** | |||||
* Builds and returns a visual diff view. The single parameter, `params', should contain | |||||
* the following values: | |||||
* | |||||
* - baseTextLines: the array of strings that was used as the base text input to SequenceMatcher | |||||
* - newTextLines: the array of strings that was used as the new text input to SequenceMatcher | |||||
* - opcodes: the array of arrays returned by SequenceMatcher.get_opcodes() | |||||
* - baseTextName: the title to be displayed above the base text listing in the diff view; defaults | |||||
* to "Base Text" | |||||
* - newTextName: the title to be displayed above the new text listing in the diff view; defaults | |||||
* to "New Text" | |||||
* - contextSize: the number of lines of context to show around differences; by default, all lines | |||||
* are shown | |||||
* - viewType: if 0, a side-by-side diff view is generated (default); if 1, an inline diff view is | |||||
* generated | |||||
*/ | |||||
buildView: function (params) { | |||||
var baseTextLines = params.baseTextLines; | |||||
var newTextLines = params.newTextLines; | |||||
var opcodes = params.opcodes; | |||||
var baseTextName = params.baseTextName ? params.baseTextName : "Base Text"; | |||||
var newTextName = params.newTextName ? params.newTextName : "New Text"; | |||||
var contextSize = params.contextSize; | |||||
var inline = (params.viewType == 0 || params.viewType == 1) ? params.viewType : 0; | |||||
if (baseTextLines == null) | |||||
throw "Cannot build diff view; baseTextLines is not defined."; | |||||
if (newTextLines == null) | |||||
throw "Cannot build diff view; newTextLines is not defined."; | |||||
if (!opcodes) | |||||
throw "Canno build diff view; opcodes is not defined."; | |||||
function celt (name, clazz) { | |||||
var e = document.createElement(name); | |||||
e.className = clazz; | |||||
return e; | |||||
} | |||||
function telt (name, text) { | |||||
var e = document.createElement(name); | |||||
e.appendChild(document.createTextNode(text)); | |||||
return e; | |||||
} | |||||
function ctelt (name, clazz, text) { | |||||
var e = document.createElement(name); | |||||
e.className = clazz; | |||||
e.appendChild(document.createTextNode(text)); | |||||
return e; | |||||
} | |||||
var tdata = document.createElement("thead"); | |||||
var node = document.createElement("tr"); | |||||
tdata.appendChild(node); | |||||
if (inline) { | |||||
node.appendChild(document.createElement("th")); | |||||
node.appendChild(document.createElement("th")); | |||||
node.appendChild(ctelt("th", "texttitle", baseTextName + " vs. " + newTextName)); | |||||
} else { | |||||
node.appendChild(document.createElement("th")); | |||||
node.appendChild(ctelt("th", "texttitle", baseTextName)); | |||||
node.appendChild(document.createElement("th")); | |||||
node.appendChild(ctelt("th", "texttitle", newTextName)); | |||||
} | |||||
tdata = [tdata]; | |||||
var rows = []; | |||||
var node2; | |||||
/** | |||||
* Adds two cells to the given row; if the given row corresponds to a real | |||||
* line number (based on the line index tidx and the endpoint of the | |||||
* range in question tend), then the cells will contain the line number | |||||
* and the line of text from textLines at position tidx (with the class of | |||||
* the second cell set to the name of the change represented), and tidx + 1 will | |||||
* be returned. Otherwise, tidx is returned, and two empty cells are added | |||||
* to the given row. | |||||
*/ | |||||
function addCells (row, tidx, tend, textLines, change) { | |||||
if (tidx < tend) { | |||||
row.appendChild(telt("th", (tidx + 1).toString())); | |||||
row.appendChild(ctelt("td", change, textLines[tidx].replace(/\t/g, "\u00a0\u00a0\u00a0\u00a0"))); | |||||
return tidx + 1; | |||||
} else { | |||||
row.appendChild(document.createElement("th")); | |||||
row.appendChild(celt("td", "empty")); | |||||
return tidx; | |||||
} | |||||
} | |||||
function addCellsInline (row, tidx, tidx2, textLines, change) { | |||||
row.appendChild(telt("th", tidx == null ? "" : (tidx + 1).toString())); | |||||
row.appendChild(telt("th", tidx2 == null ? "" : (tidx2 + 1).toString())); | |||||
row.appendChild(ctelt("td", change, textLines[tidx != null ? tidx : tidx2].replace(/\t/g, "\u00a0\u00a0\u00a0\u00a0"))); | |||||
} | |||||
for (var idx = 0; idx < opcodes.length; idx++) { | |||||
code = opcodes[idx]; | |||||
change = code[0]; | |||||
var b = code[1]; | |||||
var be = code[2]; | |||||
var n = code[3]; | |||||
var ne = code[4]; | |||||
var rowcnt = Math.max(be - b, ne - n); | |||||
var toprows = []; | |||||
var botrows = []; | |||||
for (var i = 0; i < rowcnt; i++) { | |||||
// jump ahead if we've alredy provided leading context or if this is the first range | |||||
if (contextSize && opcodes.length > 1 && ((idx > 0 && i == contextSize) || (idx == 0 && i == 0)) && change=="equal") { | |||||
var jump = rowcnt - ((idx == 0 ? 1 : 2) * contextSize); | |||||
if (jump > 1) { | |||||
toprows.push(node = document.createElement("tr")); | |||||
b += jump; | |||||
n += jump; | |||||
i += jump - 1; | |||||
node.appendChild(telt("th", "...")); | |||||
if (!inline) node.appendChild(ctelt("td", "skip", "")); | |||||
node.appendChild(telt("th", "...")); | |||||
node.appendChild(ctelt("td", "skip", "")); | |||||
// skip last lines if they're all equal | |||||
if (idx + 1 == opcodes.length) { | |||||
break; | |||||
} else { | |||||
continue; | |||||
} | |||||
} | |||||
} | |||||
toprows.push(node = document.createElement("tr")); | |||||
if (inline) { | |||||
if (change == "insert") { | |||||
addCellsInline(node, null, n++, newTextLines, change); | |||||
} else if (change == "replace") { | |||||
botrows.push(node2 = document.createElement("tr")); | |||||
if (b < be) addCellsInline(node, b++, null, baseTextLines, "delete"); | |||||
if (n < ne) addCellsInline(node2, null, n++, newTextLines, "insert"); | |||||
} else if (change == "delete") { | |||||
addCellsInline(node, b++, null, baseTextLines, change); | |||||
} else { | |||||
// equal | |||||
addCellsInline(node, b++, n++, baseTextLines, change); | |||||
} | |||||
} else { | |||||
b = addCells(node, b, be, baseTextLines, change); | |||||
n = addCells(node, n, ne, newTextLines, change); | |||||
} | |||||
} | |||||
for (var i = 0; i < toprows.length; i++) rows.push(toprows[i]); | |||||
for (var i = 0; i < botrows.length; i++) rows.push(botrows[i]); | |||||
} | |||||
tdata.push(node = document.createElement("tbody")); | |||||
for (var idx in rows) rows.hasOwnProperty(idx) && node.appendChild(rows[idx]); | |||||
node = celt("table", "diff" + (inline ? " inlinediff" : "")); | |||||
for (var idx in tdata) tdata.hasOwnProperty(idx) && node.appendChild(tdata[idx]); | |||||
return node; | |||||
} | |||||
}; | |||||