php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #11021 apache crash when mail with linked files over 2 ko
Submitted: 2001-05-22 12:21 UTC Modified: 2002-08-23 21:27 UTC
From: solrieur at caramail dot com Assigned: hholzgra (profile)
Status: Closed Package: Mail related
PHP Version: 4.0.5 OS: windows 98 SE
Private report: No CVE-ID: None
 [2001-05-22 12:21 UTC] solrieur at caramail dot com
I work with apache 1.3.19, with php 4.0.5 downloaded here

I can't send any linked files with mail() when they are over about 2 ko...


no error log


apache crash :
Ce programme va ?tre arr?t? car il a effectu? une op?ration non conforme (this program will be stopped because it made a non-conform error)
APACHE a caus? une d?faillance de page dans
 le module MSVCRT.DLL ? 0167:78004c96.

APACHE a caus? une d?faillance de page dans
 le module PHP4TS.DLL ? 0167:00bee5ea.

APACHE a caus? une d?faillance de page dans
 le module PHP4TS.DLL ? 0167:00c1d86d.


the code :
*****************************************************
*****************************************************

class Email 
{ 
    //---Global Variables 
    var $mailTo                = "";                        // array of To addresses 
    var $mailFrom            = "";                        // from address 
    var $mailSubject        = "";                        // email subject 
    var $mailText            = "";                        // plain text message 
    var $mailAttachments    = "";                        // array of attachments 

/*#########################Fonction rajout?e , le constructeur###################*/
function EMail($mailTo, $mailFrom, $mailSubject, $mailText, $mailAttachments) {
	$this->mailTo = $mailTo;
	$this->mailFrom = $mailFrom;
	$this->mailSubject = $mailSubject;
	$this->mailText = $mailText;
	$this->mailAttachments = $mailAttachments;
}




/******************************************************************************* 
    Function:        setTo($inAddress) 
    Description:    sets the email To address 
    Arguments:        $inAddress as string 
                    separate multiple values with comma 
    Returns:        true if set 
*******************************************************************************/ 
    function setTo($inAddress){ 
        //--split addresses at commas 
        $addressArray = explode(",",$inAddress); 
        //--loop through each address and exit on error 
        for($i=0;$i<count($addressArray);$i++){ 
            if($this->checkEmail($addressArray[$i])==false) return false; 
        } 
        //--all values are OK so implode array into string 
        $this->mailTo = implode($addressArray,","); 
        return true; 
    } 
/******************************************************************************* 
    Function:        setFrom($inAddress) 
    Description:    sets the email FROM address 
    Arguments:        $inAddress as string (takes single email address) 
    Returns:        true if set 
*******************************************************************************/ 
    function setFrom($inAddress){ 
        if($this->checkEmail($inAddress)){ 
            $this->mailFrom = $inAddress; 
            return true; 
        } 
        return false; 
    } 
/******************************************************************************* 
    Function:        setSubject($inSubject) 
    Description:    sets the email subject 
    Arguments:        $inSubject as string 
    Returns:        true if set 
*******************************************************************************/ 
    function setSubject($inSubject){ 
        if(strlen(trim($inSubject)) > 0){ 
            $this->mailSubject = ereg_replace("\n","",$inSubject); 
            return true; 
        } 
        return false; 
    } 
/******************************************************************************* 
    Function:        setText($inText) 
    Description:    sets the email text 
    Arguments:        $inText as string 
    Returns:        true if set 
*******************************************************************************/ 
    function setText($inText){ 
        if(strlen(trim($inText)) > 0){ 
            $this->mailText = $inText; 
            return true; 
        } 
        return false; 
    } 
/******************************************************************************* 
    Function:        setAttachments($inAttachments) 
    Description:    stores the Attachment string 
    Arguments:        $inAttachments as string with directory included 
                    separate multiple values with comma 
    Returns:        true if stored 
*******************************************************************************/ 
    function setAttachments($inAttachments){ 
        if(strlen(trim($inAttachments)) > 0){ 
            $this->mailAttachments = $inAttachments; 
            return true; 
        }         
        return false; 
    } 
/******************************************************************************* 
    Function:        checkEmail($inAddress) 
    Description:    checks for valid email 
    Arguments:        $inAddress as string 
    Returns:        true if valid 
*******************************************************************************/ 
    function checkEmail($inAddress){ 
        return (ereg( "^[^@ ]+@([a-zA-Z0-9\-]+\.)+([a-zA-Z0-9\-]{2}|net|com|gov|mil|org|edu|int)\$",$inAddress)); 
    } 
/******************************************************************************* 
    Function:        loadTemplate($inFileLocation,$inHash,$inFormat) 
    Description:    reads in a template file and replaces hash values 
    Arguments:        $inFileLocation as string with relative directory 
                    $inHash as Hash with populated values 
                    $inFormat as string either "text" or "html" 
    Returns:        true if loaded 
*******************************************************************************/ 
    function loadTemplate($inFileLocation,$inHash,$inFormat){ 
        /* 
        template files have lines such as: 
            Dear ~!UserName~, 
            Your address is ~!UserAddress~ 
        */ 
        //--specify template delimeters 
        $templateDelim = "~"; 
        $templateNameStart = "!"; 
        //--set out string 
        $templateLineOut = ""; 
        //--open template file 
        if($templateFile = fopen($inFileLocation,"r")){ 
            //--loop through file, line by line 
            while(!feof($templateFile)){ 
                //--get 1000 chars or (line break internal to fgets) 
                $templateLine = fgets($templateFile,1000); 
                //--split line into array of hashNames and regular sentences 
                $templateLineArray = explode($templateDelim,$templateLine); 
                //--loop through array  
                for( $i=0; $i<count($templateLineArray);$i++){ 
                    //--look for $templateNameStart at position 0 
                    if(strcspn($templateLineArray[$i],$templateNameStart)==0){ 
                        //--get hashName after $templateNameStart 
                        $hashName = substr($templateLineArray[$i],1); 
                        //--replace hashName with acual value in $inHash 
                        //--(string) casts all values as "strings" 
                        $templateLineArray[$i] = ereg_replace($hashName,(string)$inHash[$hashName],$hashName); 
                    } 
                } 
                //--output array as string and add to out string 
                $templateLineOut .= implode($templateLineArray,"");         
            } 
            //--close file         
            fclose($templateFile); 
            //--set Mail body to proper format 
            if( strtoupper($inFormat)=="TEXT" ) return($this->setText($templateLineOut)); 
            else if( strtoupper($inFormat)=="HTML" ) return($this->setHTML($templateLineOut)); 
        } 
        return false; 
    } 
/******************************************************************************* 
    Function:        getRandomBoundary($offset) 
    Description:    returns a random boundary 
    Arguments:        $offset as integer - used for multiple calls 
    Returns:        string 
*******************************************************************************/ 
    function getRandomBoundary($offset = 0){ 
        //--seed random number generator 
        srand(time()+$offset); 
        //--return md5 32 bits plus 4 dashes to make 38 chars 
        return ("----".(md5(rand()))); 
    } 
/******************************************************************************* 
    Function:        getContentType($inFileName) 
    Description:    returns content type for the file type 
    Arguments:        $inFileName as file name string (can include path) 
    Returns:        string 
*******************************************************************************/ 
    function getContentType($inFileName){ 
        //--strip path 
        $inFileName = basename($inFileName); 
        //--check for no extension 
        if(strrchr($inFileName,".") == false){ 
            return "application/octet-stream"; 
        } 
        //--get extension and check cases 
        $extension = strrchr($inFileName,"."); 
        switch($extension){ 
            case ".gif":    return "image/gif"; 
            case ".gz":     return "application/x-gzip"; 
            case ".htm":    return "text/html"; 
            case ".html":   return "text/html"; 
            case ".jpg":    return "image/jpeg"; 
            case ".tar":    return "application/x-tar"; 
            case ".txt":    return "text/plain"; 
            case ".zip":    return "application/zip";
			case ".pdf":	return "application/pdf";
			case ".doc":	return "application/msword";
			case ".ai":		return "application/postscript"; 
            default:        return "application/octet-stream"; 
        } 
        return "application/octet-stream"; 
    } 
/******************************************************************************* 
    Function:        formatTextHeader 
    Description:    returns a formated header for text 
    Arguments:        none 
    Returns:        string 
*******************************************************************************/ 
    function formatTextHeader(){ 
        $outTextHeader = ""; 
        $outTextHeader .= "Content-Type: text/plain; charset=us-ascii\n"; 
        $outTextHeader .= "Content-Transfer-Encoding: 7bit\n\n"; 
        $outTextHeader .= $this->mailText."\n"; 
        return $outTextHeader; 
    } 
/******************************************************************************* 
    Function:        formatAttachmentHeader($inFileLocation) 
    Description:    returns a formated header for an attachment 
    Arguments:        $inFileLocation as string with relative directory 
    Returns:        string 
*******************************************************************************/ 
    function formatAttachmentHeader($inFileLocation){ 
        $outAttachmentHeader = ""; 
        //--get content type based on file extension 
        $contentType = $this->getContentType($inFileLocation); 
        //--if content type is TEXT the standard 7bit encoding 
        if(ereg("text",$contentType)){ 
            //--format header 
            $outAttachmentHeader .= "Content-Type: ".$contentType.";\n"; 
            $outAttachmentHeader .= ' name="'.basename($inFileLocation).'"'."\n"; 
            $outAttachmentHeader .= "Content-Transfer-Encoding: 7bit\n"; 
            $outAttachmentHeader .= "Content-Disposition: attachment;\n";    //--other: inline 
            $outAttachmentHeader .= ' filename="'.basename($inFileLocation).'"'."\n\n"; 
            $textFile = fopen($inFileLocation,"rb"); 
            //--loop through file, line by line 
            while(!feof($textFile)){ 
                //--get 1000 chars or (line break internal to fgets) 
                $outAttachmentHeader .= fgets($textFile,1000); 
            } 
            //--close file         
            fclose($textFile); 
            $outAttachmentHeader .= "\n"; 
        } 
        //--NON-TEXT use 64-bit encoding 
        else{ 
            //--format header 
            $outAttachmentHeader .= "Content-Type: ".$contentType.";\n"; 
            $outAttachmentHeader .= ' name="'.basename($inFileLocation).'"'."\n"; 
            $outAttachmentHeader .= "Content-Transfer-Encoding: base64\n"; 
            $outAttachmentHeader .= "Content-Disposition: attachment;\n";    //--other: inline 
            $outAttachmentHeader .= ' filename="'.basename($inFileLocation).'"'."\n\n"; 

			$fd = fopen($inFileLocation, "rb");
			$contents = fread($fd, filesize($inFileLocation));
			$encoded = chunk_split(base64_encode($contents));
            //--close file         
            fclose($fd);
			$outAttachmentHeader .= $encoded . "\n";
        }
        return $outAttachmentHeader; 
    } 
/******************************************************************************* 
    Function:        send() 
    Description:    sends the email 
    Arguments:        none 
    Returns:        true if sent 
*******************************************************************************/ 
    function send(){ 
        //--set  mail header to blank 
        $mailHeader = ""; 
        //--add From 
        if($this->mailFrom != "") $mailHeader .= "FROM: ".$this->mailFrom."\n"; 

        //---------------------------MESSAGE TYPE------------------------------- 
        //--TEXT ONLY 
        if($this->mailAttachments == ""){ 
            return mail($this->mailTo,$this->mailSubject,$this->mailText,$mailHeader); 
        }         
	    //--TEXT AND ATTACHMENTS
		else { 
             
            //--get random boundary for attachments 
            $attachmentBoundary = $this->getRandomBoundary(); 
            //--set main header for all parts and boundary 
            $mailHeader .= "Content-Type: multipart/mixed;\n"; 
            $mailHeader .= ' boundary="'.$attachmentBoundary.'"'."\n\n"; 
            $mailHeader .= "This is a multi-part message in MIME format.\n"; 
            $mailHeader .= "--".$attachmentBoundary."\n"; 
             
            //--TEXT -- 
            //--get random boundary for content types 
            $bodyBoundary = $this->getRandomBoundary(1); 
            //--format headers 
            $textHeader = $this->formatTextHeader(); 
            //--set MIME-Version 
            $mailHeader .= "MIME-Version: 1.0\n"; 
            //--set up main content header with boundary 
            $mailHeader .= "Content-Type: multipart/alternative;\n"; 
            $mailHeader .= ' boundary="'.$bodyBoundary.'"'; 
            $mailHeader .= "\n\n\n"; 
            //--add body and boundaries 
            $mailHeader .= "--".$bodyBoundary."\n"; 
            $mailHeader .= $textHeader; 
            $mailHeader .= "--".$bodyBoundary."\n"; 
            $mailHeader .= "\n--".$bodyBoundary."--"; 
            //--send message 
            //--END TEXT 
             
            //--get array of attachment filenames 
            $attachmentArray = explode(",",$this->mailAttachments); 
            //--loop through each attachment 
            for($i=0;$i<count($attachmentArray);$i++){ 
                //--attachment separator 
                $mailHeader .= "\n--".$attachmentBoundary."\n"; 
                //--get attachment info 
                $mailHeader .= $this->formatAttachmentHeader($attachmentArray[$i]); 
            } 
            $mailHeader .= "--".$attachmentBoundary."--"; 
            return mail($this->mailTo,$this->mailSubject,"",$mailHeader); 
        } 
        return false; 
    } 
} 
$monmail = new EMail("him@caramail.com", "me@caramail.com", "Trying to link files", "Here is the body", "C:\php4.gif");
$monmail->send();

*****************************************************
*****************************************************

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2001-06-22 18:32 UTC] hholzgra@php.net
see #11165
 [2002-03-12 11:56 UTC] sadara at dds dot nl
Same result:

"APACHE caused an invalid page fault in
module MSVCRT.DLL at 017f:780035d7."

Windows 98SE
Apache 1.3.20
PHP 4.1.0

Code:

<?php

define ('CRLF', chr(13).chr(10));

$to = 'sadara@localhost';
$subject = 'test msg';
$headers = "From: sadara@localhost".CRLF;
$headers .= "Return-Path: sadara@localhost" . CRLF;
$headers .= "X-Sender: sadara@localhost" .CRLF; 
$headers .= "X-Mailer: PHP/" . phpversion() . CRLF; 

$boundary = "b" . md5 (uniqid(time()));

$mime = "Content-type: multipart/mixed; ";
$mime .= "boundary = ".$boundary.CRLF;
$mime .= "This is a MIME encoded message".CRLF.CRLF ;

$mime2 = "--".$boundary.CRLF ;
$mime2 .= "Content-type: text/plain".CRLF;
$mime2 .= "Content-Transfer-Encoding: base64".CRLF;

{$textarea = 'dummy';}
$mime2 .= CRLF.CRLF . chunk_split(base64_encode($textarea)) . CRLF ;

$mime2 .= "--".$boundary.CRLF ;
$mime2 .= "Content-type: text/plain".CRLF;
$mime2 .= "Content-Transfer-Encoding: base64".CRLF;
$fileattach = 'big.txt' ;
//$fileattach = 'small.txt' ;
$attach = chunk_split(base64_encode(implode('', file($fileattach))));

$mime2 .= CRLF.CRLF.$attach.CRLF.CRLF;

mail ($to, $subject, "", $headers . $mime . $mime2) ;

?>

big.txt is a 15k csv file.

Identical code with identical attachment runs fine under FreeBSD 3.0/Apache 1.3.6/PHP 4.0.1pl2
 [2002-08-23 21:27 UTC] sniper@php.net
Try this snapshot:
http://snaps.php.net/win32/php4-win32-STABLE-latest.zip

Reopen if problem still exists in it.

 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Dec 26 18:01:31 2024 UTC