php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #21033 Socket_recvfrom call will truncate returning string if data had a 0 in it.
Submitted: 2002-12-15 18:10 UTC Modified: 2002-12-16 11:52 UTC
From: aron at qvix dot biz Assigned:
Status: Closed Package: Scripting Engine problem
PHP Version: 4.2.2 OS: Linux
Private report: No CVE-ID: None
 [2002-12-15 18:10 UTC] aron at qvix dot biz
When using the socket_recvfrom call with a UDP socket - if you sent a string to the socket that was
$length = socket_recvfrom($sock, $buf, 2048, 0 , $name, $port );

pppppppp0pppppppp   - the $length would be the full amount read off the socket, but the $buf will only contain the data up to the first 0 (value is zero, i.e. NULL) and nothing beyond it. It seems that the string handling routines of the engine truncate the memory/length if the network read data contains a 0.


Attached are the server side php code that will show this and a C program to generate the packets.

The server program will printout the chars in the packet seperated by a ~

<**** begin server php script ****>
<?php
//*****
// Server Connection Script
//              Receive : UDP packets from clients and act based on control bytes.
//*****

set_time_limit(0);//***** Don't let the script stop

$addr = "192.168.1.2";//***** Server info
$port = 9000;

$sock = socket_create(AF_INET, SOCK_DGRAM, 0);  //*****Create socket for UDP
if ($sock < 0 )
        die(print $sock);

if (($ret = socket_bind($sock, $addr, $port)) < 0)              //***** Complete socket connection
        die(print $ret);

$read = socket_recvfrom($sock, $buf, 2048, 0 , $name, $port );
//process information in buffer

for ($k=0;$k < $read ;$k++)
{
        echo $buf[$k];
        echo "~";
}
print "\r\nRead $read bytes from Network\r\n";
print "IP Addy: $name\r\n";
print "Port: $port\r\n";

socket_close($sock);
?>
<****** End server php script******>

<****** begin client C program ******>
/* Generate Some udp packet for network. */

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <linux/inet.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdio.h>
#include <netdb.h>

#include <string.h>
unsigned int ConvertHostname(char *hostname);

void main(void)
{
        int connSocket;
        sockaddr_in sin_connect;

        sin_connect.sin_port = htons(9001);
        sin_connect.sin_addr.s_addr = INADDR_ANY;
        sin_connect.sin_family = AF_INET;

        connSocket = socket(AF_INET, SOCK_DGRAM, 0);
        if(bind(connSocket,(sockaddr*)&sin_connect,sizeof(sockaddr_in)) == -1)
        {
                connSocket = 0;
                printf("Socket Bind error");
                return 0;
        }
        sin_connect.sin_addr.s_addr = ConvertHostname("192.168.1.2");
        sin_connect.sin_port = htons(9000);

        int dataLength = 64
        char *data = new char[dataLength];
        memset(data,80,dataLength); // put a P in the data packet
        data[10] = 0; // put a zero in the data stream
        int a = sendto(connSocket,(char *)data,dataLength,0,(sockaddr *) &sin_connect,sizeof(struct sockaddr)$

        printf("Sendto did %d\n",a);
        delete [] data;
        close(connSocket);
}
unsigned int ConvertHostname(char *hostname)
{
        struct hostent *phost;
        struct in_addr addr;

        addr.s_addr = inet_addr(hostname);
        if(addr.s_addr == 0)
                return 0;
        if(addr.s_addr == -1)
        {
                phost = gethostbyname(hostname);
                if(phost == NULL)
                {
                        printf("Error: Couldn't resolve hostname.");
                        return 0;
                }
                memcpy((char *)&addr.s_addr, phost->h_addr,phost->h_length);
        }
        return addr.s_addr;
}
<****** end client C program ******>

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2002-12-15 21:27 UTC] iliaa@php.net
Please try using this CVS snapshot:

  http://snaps.php.net/php4-latest.tar.gz
 
For Windows:
 
  http://snaps.php.net/win32/php4-win32-latest.zip


 [2002-12-16 11:50 UTC] aron at qvix dot biz
latest version of cvs fixes the problem and the call functions correctly. Do you know when this fix was introduced?

Thank You.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Apr 26 15:01:56 2024 UTC