php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #29043 php crash when --enable-memory-limit'
Submitted: 2004-07-07 04:40 UTC Modified: 2004-07-07 09:20 UTC
From: sanry at now dot net dot cn Assigned:
Status: Not a bug Package: PHP options/info functions
PHP Version: 4.3.7 OS: linux
Private report: No CVE-ID: None
View Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
If you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: sanry at now dot net dot cn
New email:
PHP Version: OS:

 

 [2004-07-07 04:40 UTC] sanry at now dot net dot cn
Description:
------------
Fatal error: Allowed memory size of 4194304 bytes exhausted (tried to allocate 168683 bytes) in /liusra2/now.net.cn/web/vip/include/fun_inc.php on line 162

Fatal error: Allowed memory size of 4194304 bytes exhausted (tried to allocate 133 bytes) in Unknown on line 0


Reproduce code:
---------------
<?
/*-
 * PROMailVIP webmail 
 * Copyright (c) 1999-2001 by PROMailVIP network system Inc.
 * All rights reserved.
 * Author: Sanry William <sanry@now.net.cn>
 * $Id: list.php,v 1.25 2003/01/15 07:10:55 sanry Exp $
 */
$DEBUG = 1;
if($DEBUG) $timebegin = gettimeofday();
include "include/login_inc.php";
include "config/config_inc.php";
include "include/fun_inc.php";
include "language/$CFG_LANGUAGE"."_inc.php";
//??ȡ??ǰ URL
$Cur_URL = $REQUEST_URI;
//?????û???ʱ?ļ?Ŀ¼
chdir("$CFG_TEMP/$G_DOMAIN/$G_USERNAME");
/* ???ڲ???: 	Sortby  	?????ؼ??ֶ?
 *				Method 		????????	Down 	Up
 *				Mailbox		????
 *				Page		ҳ??
 *				Cmd			????	Refresh none
 *				Lang		????
 */
$get_Mailbox = trim($HTTP_GET_VARS['Mailbox']);
$get_Sortby  = trim($HTTP_GET_VARS['Sortby']);
$get_Method  = trim($HTTP_GET_VARS['Method']);
$get_Page    = trim($HTTP_GET_VARS['Page']);
$get_Cmd     = trim($HTTP_GET_VARS['Cmd']);
$get_Lang    = trim($HTTP_GET_VARS['Lang']);

//???????ڲ???ȱʡֵ
if($get_Sortby=='') $get_Sortby = $CFG_List_SortBy;
if(empty($get_Sortby)) $get_Sortby = "Date";
if($get_Method=='') $get_Method = "Down";
if($get_Page==''||$get_Page <1 ) $get_Page = 1;

// ???? $get_Mailbox ?????Ŀɿ??ԣ??????????б??ļ???
if( !(list($boxlist,$mailbox) = GetMailboxFolder($get_Mailbox)) ) die("??Ч??????????");
if(!is_dir("$G_HOME/Maildir/$mailbox")){
	mkdir("$G_HOME/Maildir/$mailbox",0700);
	mkdir("$G_HOME/Maildir/$mailbox/new",0700);
	mkdir("$G_HOME/Maildir/$mailbox/cur",0700);
	mkdir("$G_HOME/Maildir/$mailbox/tmp",0700);
}

//??ʼ??ͳ?Ʊ???
$TotalSize = 0;
$list = array();
$Newfile = 0;

if($get_Cmd = 'Refresh'){
	// ?????ʼ??嵥
	($FD_LIST = fopen($boxlist,"w+"))||die("Error open $boxlist!");
	$i = 0;
	list($Newfile,$list,$size) = GetFolderList($mailbox,"new",$list,$i);
	$TotalSize = $size;
	list($i,$list,$size) = GetFolderList($mailbox,"cur",$list,$Newfile);
	$TotalSize +=$size;
	//	fix the bug of array resort() when count equal to 1
	if (count($list)==1){
		$list[0] = $list[1];
		unset($list[1]);
	}
}else {
// ???ʼ??嵥
	($FD_LIST = fopen($boxlist,"r"))||die("Error open $boxlist!");
	$i = 0;
	while(($line = fgets($FD_LIST,1024)) && !feof($FD_LIST) ){
		list($n,$Key,$IsNew,$File,$FromName,$From,$Subject,$Date,$Size,$Blocks) = split("\t",$line,10);
		if($IsNew =="new") $Newfile++;
		$linelist['File'] = $File;
		$linelist['From'] = $From;
		$linelist['Subject'] = $Subject;
		$linelist['Date'] = $Date;
		$linelist['Size'] = $Size;
		$key = $linelist[$get_Sortby];
		if ($get_Sortby=='Size') $key = Num2Str(chop($key),8);
		$line = "$key\t$IsNew\t$File\t$FromName\t$From\t$Subject\t$Date\t$Size\t$Blocks";
		$list[$n] = $line;
		$TotalSize += chop($Blocks);
		$i++;
	}
	fclose($FD_LIST);
	($FD_LIST = fopen($boxlist,"w+"))||die("Error open $boxlist!");
}

// ????
if ($get_Method =="Up") {sort($list);$NextMethod="Down";}
else {rsort($list);$NextMethod="Up";}

reset($list);
for($i=0;$i<count($list);$i++){
	fputs($FD_LIST,$i."\t".$list[$i]);
}
fclose($FD_LIST);

// ?????ʼ??嵥
$totalmail = count($list);
$begin = 0;
$end = $totalmail;
$totalpage = 1;
if($CFG_List_NumPerPage>0){
	$totalpage = intval( $totalmail/$CFG_List_NumPerPage );
	if ( $totalpage * $CFG_List_NumPerPage < $totalmail ) $totalpage ++;
	if ($get_Page >$totalpage) $get_Page = $totalpage;
	if ($get_Page>0) $begin = ($get_Page -1) * $CFG_List_NumPerPage;
	$end   = $get_Page * $CFG_List_NumPerPage;
	if ($end > $totalmail) $end = $totalmail;
}

$out = "";
for($k=1,$i=$begin; $i <$end ;$i++,$k++){
	list($key,$isnew,$file,$fromname,$from,$subject,$date,$size) = split("\t",$list[$i],9);
	$j = $i +1;
	$Border = "";
	$ByBorder = "";
	if($isnew =="new") {
		$isnewstr = "<IMG SRC=images/close.gif WIDTH=16 HEIGHT=12 ALT='$LANG_LIST_NEWMAIL'>";
		$Border = "<B>";
		$ByBorder = "</B>";
	} else 
		$isnewstr = "<IMG SRC=images/open.gif WIDTH=16 HEIGHT=14>";
	
	$size = chop($size);
	list($time1,$time2) = Date2Str($date,$CFG_GMT);
	
	$subject = str_replace('"','',$subject);	//ȥ???ַ????е?"???ţ??Ա?????html ???Ƿ?????ͻ
	$from = str_replace('"','',$from);
	
	$out .= "<TR OnMouseOver=\"setPointer(this, 'over')\" OnMouseOut=\"setPointer(this, 'out')\" OnMouseDown=\"setPointer(this,'click')\">\n".
			"<TD NOWRAP OnMouseDown=Flag($k) ALIGN=right style='font-family:Tahoma'>$j</TD>\n".
			"<TD NOWRAP><INPUT TYPE=checkbox>$isnewstr</TD>\n".
			"<TD></TD>\n".
			"<TD NOWRAP TITLE=\"$from\" OnMouseDown='Flag($k)'>";

	$out .="<A href=# OnClick=\"Read('$get_Mailbox',$j);return false;\">";
			
	$out .=	$Border." ".TrimStr($fromname,16)." ".$ByBorder."</A></TD>\n".
			"<TD NOWRAP OnMouseDown=Flag($k)><A href=# OnClick=\"Read('$get_Mailbox',$j);return false;\" title=\" ".$subject." \" >".$Border." ".TrimStr($subject,52)." ".$ByBorder."</A></TD>\n".
			"<TD NOWRAP TITLE='$time2' style='font-family:Tahoma'>$time1</td>\n".
			"<TD NOWRAP ALIGN=right style='font-family:Tahoma'>$size</td>\n".
			"</TR>\n";
}
// ????????ͼ??
	$FromArr = "";
	if($get_Sortby=="From"){
		$FromArr = "<IMG SRC=images/up.gif>";
		if ($get_Method=="Down") $FromArr = "<IMG SRC=images/down.gif>";
	}
	$SubjectArr = "";
	if($get_Sortby=="Subject"){
		$SubjectArr = "<IMG SRC=images/up.gif>";
		if ($get_Method=="Down") $SubjectArr = "<IMG SRC=images/down.gif>";
	}
	$DateArr = "";
	if($get_Sortby=="Date"){
		$DateArr = "<img src=images/up.gif>";
		if ($get_Method=="Down") $DateArr = "<IMG SRC=images/down.gif>";
	}
	$SizeArr = "";
	if($get_Sortby=="Size"){
		$SizeArr = "<IMG SRC=images/up.gif>";
		if ($get_Method=="Down") $SizeArr = "<IMG SRC=images/down.gif>";
	}

$TotalSize = intval($TotalSize /2)."kB";
$CurMailboxName = $LANG_MAILBOX_NAME[$get_Mailbox];
if( is_file("$CFG_USERBOX_LIST") ){
	($FD_BOXLIST = fopen("$CFG_USERBOX_LIST","r")) || die("Error open .box_list!");
	while ( !feof($FD_BOXLIST) ) {
    	$buffer = fgets($FD_BOXLIST, 128);
    	$buffer = chop($buffer);
    	list($foldername,$folder) = split("\t",$buffer);
    	if($CurMailboxName=='') $CurMailboxName=$foldername;
       	if( $folder!='' && $foldername!='' ){
          	$UserFolder_Out .= "<OPTION VALUE='$folder'>$foldername</OPTION>\n";
		}
	}
	fclose($FD_BOXLIST);
}

// Main exit;

// ȡ????Ŀ¼?б�?ʼ???ϸ?б?
// ??????(Ŀ¼??,??Ŀ¼,?б?????,??????ָ??) 
// ???أ?array(?ʼ???,?б?????)
function GetFolderList($mailbox,$home,$list,$i){
	global $G_HOME,$get_Sortby,$get_Mailbox;
	global $CFG_List_MailTime;
	
	$myhome = "$G_HOME/Maildir/$mailbox/$home";
	$handle=opendir($myhome);
	while (($file = readdir($handle))!==false){
	//	echo $file;
    	if ($file !='.' && $file !='..'){
			if (!($fd = fopen($myhome."/".$file,'r'))){
				echo "error open file";
			}
			$i ++;
			$header = array();
			$header = Parse_head_List($fd);
			
			$Fstat = fstat($fd);
			fclose($fd);

			if(empty($header['subject'])) $header['subject'] = "-None subject-";
			if(empty($header['fromname'])) $header['fromname'] = "-None form-";

//			print_r($header);
			$TotalSize += $Fstat[blocks];			
			$header['size'] = $Fstat['size'];

			//ת?????????ݸ?ʽ
			$header['date'] = Date2stamp($header['date']);
	
			$out = "\t$home\t".$file."\t";
			if($get_Mailbox=='draft' || $get_Mailbox=='outbox'){
				$out .= $header['to']."\t".$header['to']."\t";
			}
			else $out .= $header['fromname']."\t".$header['fromemail']."\t";
			
			$out .= trim($header['subject'])."\t".
				$header['date']."\t".$Fstat['size']."\t".$Fstat[blocks]."\n";
			$Sortkey = $header[strtolower($get_Sortby)];
			if ($get_Sortby=="Size") $Sortkey = Num2Str($Sortkey,8);
			if ($get_Sortby=="Date") $Sortkey = Num2Str($Sortkey,10);
			$list[$i] = $Sortkey.$out;
    	}
	}
	closedir($handle);
	return array($i,$list,$TotalSize);
}
?>
<HTML>
<HEAD>
<TITLE></TITLE>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=<?php echo $CFG_CHARSET[$CFG_LANGUAGE];?>">
<META HTTP-EQUIV="refresh" CONTENT="<?php echo $CFG_List_AutoRefresh;?>">
<LINK REL="stylesheet" HREF="css/provip.css" TYPE="TEXT/CSS">
<style>
<!--
BODY {
background-position:bottom right;
background-repeat:no-repeat;
}
-->
</style>
</HEAD>
<SCRIPT>
<!--
var Alert_Invalid_Target = "<?php echo $LANG_LIST_MOVE_ALERT_MSG3;?>";	//??Ч???ƶ?????ѡ??Ŀ??????!
var Alert_Invalid_Select = "<?php echo $LANG_LIST_MOVE_ALERT_MSG1;?>";	//??Ч???ƶ?????ѡ??Ŀ??????!
var Confirm_Move = "<?php echo $LANG_LIST_MOVE_ALERT_MSG2;?> ";	//?Ƿ?????ѡ?????ʼ??ƶ???

//-->
</SCRIPT>
<SCRIPT SRC=script/list.js></SCRIPT>
<SCRIPT SRC=script/color.js></SCRIPT>
<BODY BGCOLOR="#FFFFFF" TEXT="#000000" LEFTMARGIN="0" TOPMARGIN="0" background="images/bg_globe.jpg">
<?include "$CFG_BASEPATH/adv.php";?>
<table width="100%" border="0" cellspacing="0" cellpadding="0">
  <tr> 
    <td width="50" rowspan="2" align="right"><img src="images/mailbox.gif" width="45" height="42"></td>
    <td height="20">&nbsp;</td>
  </tr>
  <tr> 
    <td height="22" background="images/bglinner.jpg"><TABLE WIDTH="100%" cellpadding cellspacing>
        <FORM NAME="head" METHOD=post>
		
          <TR ALIGN="center"> 
            <TD> <B><?php echo $LANG_LIST_CURRENT_MAILBOX;?>: </B><U><?php echo $CurMailboxName;?></U> 
              <U><?php echo $TotalSize;?></U> </TD>
            <TD> <B><?php echo $LANG_LIST_TOTAL;?>: </B> <U><?php echo $totalmail;?></U> 
              <B><?php echo $LANG_LIST_NEWMAIL;?>: </B> <U><?php echo $Newfile;?></U> 
            </TD>
            <TD> <B><?php echo $LANG_LIST_PAGE_TOTAL;?>: </B><U><?php echo $totalpage;?></U> 
              <?php echo $LANG_LIST_PAGE;?> </TD>
            <TD VALIGN="TOP"> <B><?php echo $LANG_LIST_CURRENT_PAGE;?>: </B> <SELECT NAME="page" onChange="GotoPage(this.form);" CLASS="myselect">
                <OPTION VALUE=<?php echo $get_Page;?>><?php echo $get_Page;?></OPTION>
                <OPTION VALUE=->-</OPTION>
                <?php
          	for($i=1;$i<=$totalpage;$i++){
          		echo "<OPTION VALUE=?Mailbox=$get_Mailbox&Page=$i&Sortby=$get_Sortby&Method=$get_Method>$i</OPTION>\n";
          	}
          ?>
              </SELECT> </TD>
            <TD> 
              <?php if (($get_Page-1) >0){ ?>
              <A CLASS=standard HREF=<?php echo "?Mailbox=$get_Mailbox&Page=".($get_Page-1)."&Sortby=$get_Sortby&Method=$get_Method";?> > 
              &lt;&lt;<?php echo $LANG_LIST_PREV;?></A> 
              <?php };?>
              <?php if (($get_Page+1)<=$totalpage) {?>
              <A CLASS=standard HREF=<?php echo "?Mailbox=$get_Mailbox&Page=".($get_Page+1)."&Sortby=$get_Sortby&Method=$get_Method";?>>&gt;&gt;<?php echo $LANG_LIST_NEXT;?></A> 
              <?php };?>
            </TD>
            <TD> <A CLASS=standard HREF="<?php
	echo "?Mailbox=$get_Mailbox&Cmd=Refresh&Page=$get_Page&Sortby=$get_Sortby&Method=$get_Method";
	?>">[<?php echo $LANG_LIST_REFRESH;?>]</A> </TD>
          </TR>
        </FORM>
      </TABLE></td>
  </tr>
</table>
<TABLE WIDTH="100%" BORDER="0" CELLSPACING="0" CELLPADDING="0">
<TR><TD HEIGHT="5"></TD>
</TR>
</TABLE>
<br>
<TABLE WIDTH="98%" BORDER="1" CELLSPACING="0" CELLPADDING="0" BORDERCOLOR="#FFFFFF" BGCOLOR="#Efefef" ALIGN="center">
  <FORM NAME="list" METHOD="post" ACTION=<?php echo "folder.php?Mailbox=$get_Mailbox&Page=$get_Page&Sortby=$get_Sortby&Method=$get_Method";?>>
    <TR BGCOLOR="#ADB6BD" HEIGHT="22"> 
      <TD WIDTH=""></TD>
	  <TD WIDTH="5%" align="center" bgcolor="#ADB6BD"><B><?php echo $LNAG_LIST_NUM;?></B></TD>
	  <TD WIDTH="4"></TD>
      <TD align="center" BGCOLOR="#ADB6BD" TITLE='<?php
	if($get_Mailbox=='outbox' || $get_Mailbox=='draft') echo $LANG_LIST_SORTBY_TO;
	else echo $LANG_LIST_SORTBY_FROM;
	?>'> 
        <A HREF=?Mailbox=<?php echo "$get_Mailbox&Sortby=From&Method=$NextMethod";?>> 
        <B> 
        <?php
	switch($get_Mailbox){
		case 'outbox':
		echo $LANG_LIST_TO_AGAIN;
		break;
		case 'draft':
		echo $LANG_LIST_TO_CONTINUE;
		break;
		default: 
		echo $LANG_LIST_FROM_PREVIEW;
	}?>
        </B></A> <?php echo $FromArr;?> </TD>
	  <TD width="50%" align="center" bgcolor="#ADB6BD" TITLE='<?php echo $LANG_LIST_SORTBY_SUBJECT;?>'> 
        <A HREF=?Mailbox=<?php echo "$get_Mailbox&Sortby=Subject&Method=$NextMethod";?>> 
        <B><?php echo $LANG_LIST_SUBJECT_READ;?></B></A> <?php echo $SubjectArr;?> 
      </TD>
	  <TD WIDTH="15%" align="center" TITLE='<?php echo $LANG_LIST_SORTBY_DATE;?>'> 
        <A HREF=?Mailbox=<?php echo "$get_Mailbox&Sortby=Date&Method=$NextMethod";?>> 
        <B><?php echo $LANG_LIST_DATE;?></B></A> <?php echo $DateArr;?> </TD>
	  <TD WIDTH="12%" ALIGN="center" NOWRAP TITLE='<?php echo $LANG_LIST_SORTBY_SIZE;?>'> 
        <A HREF=?Mailbox=<?php echo "$get_Mailbox&Sortby=Size&Method=$NextMethod";?>> 
        <B><?php echo $LANG_LIST_SIZE;?></B></A><?php echo $SizeArr;?> </TD>
  </TR>
<?php echo $out;?>
</FORM>
</TABLE>
<br>
<TABLE WIDTH="98%" BORDER="0" CELLSPACING="0" CELLPADDING="0" ALIGN="CENTER">
  <FORM NAME="bottom" METHOD=post>
    <TR>
      <TD WIDTH="3%" ALIGN="RIGHT">
        <INPUT TYPE="hidden" NAME=all>
      </TD>
      <TD WIDTH="47%"> 
        <INPUT TYPE="BUTTON" VALUE="<?php echo $LANG_LIST_SELECTALL;?>" CLASS="myinput" onClick="SelectAll();">
<?php if($get_Mailbox=='inbox'){ ?>        
        <INPUT TYPE="BUTTON" VALUE="<?php echo $LANG_LIST_CHECKPOP;?>" CLASS="myinput" onClick="GetPopMail();">
<?php } ?>        
        <INPUT TYPE="hidden" NAME="begin" VALUE="<?php echo $begin;?>">
        <INPUT TYPE="hidden" NAME="end" VALUE="<?php echo $end;?>">
        <INPUT TYPE="hidden" NAME="page" VALUE="<?php echo $get_Page;?>">
        <INPUT TYPE="hidden" NAME="totalmail" VALUE="<?php echo $totalmail;?>">
        <INPUT TYPE="hidden" NAME="loca" VALUE=<?php echo "list.php?Mailbox=$get_Mailbox&Sortby=$get_Sortby&Method=$get_Method";?>>
      </TD>
      <TD WIDTH="50%"> 
        <INPUT TYPE="BUTTON" VALUE="<?php echo $LANG_LIST_DELETE;?>" CLASS="myinput" 
        onClick="DelMail('',<?php echo "'$LANG_LIST_DELETE_ALERT_MSG1','$LANG_LIST_DELETE_ALERT_MSG2','$LANG_LIST_DELETE_ALERT_MSG3'";?>)">
        <INPUT TYPE="BUTTON" VALUE="<?php echo $LANG_LIST_DELETE_FORCE;?>" CLASS="myinput" 
        onClick="DelMail('force',<?php echo "'$LANG_LIST_DELETE_ALERT_MSG1','$LANG_LIST_DELETE_ALERT_MSG2','$LANG_LIST_DELETE_ALERT_MSG3'";?>)">
        <INPUT TYPE="BUTTON" VALUE="<?php echo $LANG_LIST_MOVE;?>" CLASS="myinput" 
        onClick="MoveTo('<?php echo $get_Mailbox;?>')">
        -&gt; 
        <SELECT NAME="TargetFolder" CLASS="myselect">
          <OPTION VALUE="-"><?php echo $LANG_MAILBOX_SELECT;?></OPTION>
          <OPTION VALUE="-">--</OPTION>
          <OPTION VALUE="inbox"><?php echo $LANG_MAILBOX_NAME['inbox'];?></OPTION>
          <OPTION VALUE="outbox"><?php echo $LANG_MAILBOX_NAME['outbox'];?></OPTION>
          <OPTION VALUE="draft"><?php echo $LANG_MAILBOX_NAME['draft'];?></OPTION>
          <OPTION VALUE="trash"><?php echo $LANG_MAILBOX_NAME['trash'];?></OPTION>
          <OPTION VALUE="-">--</OPTION>
<?php
//ȡ?û??????????б?
echo $UserFolder_Out;
?>
        </SELECT>
      </TD>
      <TD WIDTH="50%" ALIGN="RIGHT">
        <SELECT NAME="language" CLASS="myselect"
        onChange=SelectLang("<?php echo "Mailbox=$get_Mailbox&Sortby=$get_Sortby&Method=$get_Method&Page=$get_Page";?>")>
          <OPTION VALUE="-">
          <?php echo $LANG_LIST_SELECT_LANG;?>
          </OPTION>
          <OPTION VALUE="-">--</OPTION>
          <OPTION VALUE="en"><?php echo $LANG_LIST_ENGLISH;?></OPTION>
          <OPTION VALUE="gb"><?php echo $LANG_LIST_CHINESE_GB;?></OPTION>
          <OPTION VALUE="big"><?php echo $LANG_LIST_CHINESE_BIG;?></OPTION>
        </SELECT>
      </TD>
    </TR>
  </FORM>
</TABLE>
<br>
<br>
<span class="english"> 
<?php
if ($DEBUG){
	$timeend = gettimeofday();
	$time = $timeend['sec'] - $timebegin['sec'];
	$time3 = $time + ($timeend['usec']-$timebegin['usec'])/1000000;
	echo "<CENTER><FONT color=#666666>"."Refresh Time: $time3"."</FONT></CENTER>";
}
if($CFG_List_AutoPOP=='yes' && $get_Mailbox=='inbox'){
	echo "<SCRIPT>
<!--
GetPopMail();
//-->
</SCRIPT>";
}
?>
</span> 
</BODY>
</HTML>

Expected result:
----------------
Wed Jul 07 10:31:31 2004] [warn] pid file /usr/local/apache2/logs/httpd.pid overwritten -- Unclean shutdown of previous Apache run?
[Wed Jul 07 10:31:31 2004] [notice] Apache/2.0.50 (Unix) PHP/4.3.7 configured -- resuming normal operations


Actual result:
--------------
php crash 

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2004-07-07 09:20 UTC] derick@php.net
Sorry, but your problem does not imply a bug in PHP itself.  For a
list of more appropriate places to ask for help using PHP, please
visit http://www.php.net/support.php as this bug system is not the
appropriate forum for asking support questions. 

Thank you for your interest in PHP.

.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Dec 21 16:01:28 2024 UTC