php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #7290 AF_UNIX connect segfaults + sockets.c read is not binary safe (why?)
Submitted: 2000-10-17 13:46 UTC Modified: 2001-06-02 20:59 UTC
From: gp at iws dot it Assigned:
Status: Closed Package: Sockets related
PHP Version: 4.0.3pl1 OS: Any
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: gp at iws dot it
New email:
PHP Version: OS:

 

 [2000-10-17 13:46 UTC] gp at iws dot it
I patched php-4.0.4pl1/ext/sockets/sockets.c
in order to solve these problems.
If you want I can send you the patch.
I will be happy to use PHP but it has severe
problems with sockets (fsockopen , fread etc. dont behave well).


Thank you

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2000-10-19 09:51 UTC] gp at iws dot it
I apologize if my arguments are not pertinent. Hope to not bother anybody. I'm a php newbie.

I attach below  the patch I made to fix the problems I found. I added a function named readfully in order to have
a php function able to read exactly n bytes from a 
stream. I think it is wery useful to have one. 


Cheers,

diff -u php-4.0.3pl1/ext/sockets/php_sockets.h php-4.0.3pl1-gp1/ext/sockets/php_sockets.h
--- php-4.0.3pl1/ext/sockets/php_sockets.h	Thu Sep  7 14:32:47 2000
+++ php-4.0.3pl1-gp1/ext/sockets/php_sockets.h	Thu Oct 19 15:10:22 2000
@@ -49,6 +49,7 @@
 PHP_FUNCTION(close);
 PHP_FUNCTION(write);
 PHP_FUNCTION(read);
+PHP_FUNCTION(readfully);
 PHP_FUNCTION(getsockname);
 PHP_FUNCTION(getpeername);
 PHP_FUNCTION(socket);
diff -u php-4.0.3pl1/ext/sockets/sockets.c php-4.0.3pl1-gp1/ext/sockets/sockets.c
--- php-4.0.3pl1/ext/sockets/sockets.c	Sat Sep 16 01:44:30 2000
+++ php-4.0.3pl1-gp1/ext/sockets/sockets.c	Thu Oct 19 15:14:26 2000
@@ -27,6 +27,7 @@
 #include "ext/standard/info.h"
 #include "php_sockets.h"
 
+#include <string.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <netdb.h>
@@ -91,7 +92,8 @@
 	PHP_FE(listen, 				NULL)	/* OK */
 	PHP_FE(close, 				NULL)	/* OK */
 	PHP_FE(write, 				NULL)	/* OK */
-	PHP_FE(read, 				second_arg_force_ref)	/* OK */+	PHP_FE(read,                         second_arg_force_ref)	/* OK */+	PHP_FE(readfully,                    second_arg_force_ref)	/* OK */ #if 0
 /* 
  * If and when asynchronous context switching is avaliable, 
@@ -646,6 +648,70 @@
 }
 /* }}} */
 
+/* G.Gallo - gp@iws.it - 20001017
+ * The two following function are the implementation of 
+ * a binary safe read from a socket. It is modeled after
+ * the readFully java method.
+ */
+size_t 
+_php_readfully(int fd, char *buf, size_t len) {
+    struct timeval tv;
+    fd_set rfds;
+    size_t n;
+    char *pb = buf;
+
+    tv.tv_sec = 600;
+    tv.tv_usec = 0;
+    FD_ZERO(&rfds);
+    FD_SET(fd, &rfds);
+    while (len) {
+        if (select(fd + 1, &rfds, NULL, NULL, &tv) == -1)
+            return -2;
+        if (FD_ISSET(fd, &rfds)) {
+            if ((n = read(fd, pb, len)) < 0 || (n == 0 && len > 0))
+                return -1;
+            len -= n;
+            pb += n;
+        } else
+            return -1;
+    }
+    return 0;
+}
+PHP_FUNCTION(readfully)
+{
+	zval **fd, **buf, **length;
+	char *tmpbuf;
+	int ret,rc;
+
+	if (ZEND_NUM_ARGS() != 3 || 
+	    zend_get_parameters_ex(3, &fd, &buf, &length) == FAILURE) {
+		WRONG_PARAM_COUNT;
+	}
+	v_convert_to_long_ex(2, fd, length);
+	convert_to_string_ex(buf);+
+	tmpbuf = emalloc(Z_LVAL_PP(length)*sizeof(char));
+	if (tmpbuf == NULL) {
+		php_error(E_WARNING, "Couldn't allocate memory from %s()", get_active_function_name());
+		RETURN_FALSE;
+	}
+	
+	rc = _php_readfully(Z_LVAL_PP(fd), tmpbuf, ret = Z_LVAL_PP(length));
+	if (rc == 0) {
+		Z_STRVAL_PP(buf) = emalloc(ret * sizeof(char));
+		memcpy(Z_STRVAL_PP(buf),tmpbuf,ret);
+		Z_STRLEN_PP(buf) = ret;
+		
+		efree(tmpbuf);
+
+		RETURN_LONG(ret);
+	} else {
+		efree(tmpbuf);
+		RETURN_LONG(-errno);
+	}
+}
+/* }}} */
+
 /* {{{ proto int getsockname(int fd, string &addr, int &port)
    Given an fd, stores a string representing sa.sin_addr and the value of sa.sin_port into addr and port describing the local side of a socket */
 
@@ -931,9 +997,11 @@
 			break;
 		}
 	case AF_UNIX: {
-			sun = (struct sockaddr_un *)&sa;
-			snprintf(sun->sun_path, 108, "%s", Z_STRVAL_PP(addr));
-			ret = connect(Z_LVAL_PP(sockfd), (struct sockaddr *) sun, SUN_LEN(sun));
+                        struct sockaddr_un sun;
+                        memset((char *)&sun,0,sizeof(sun));
+                        sun.sun_family = AF_UNIX;
+                        strncpy(sun.sun_path,Z_STRVAL_PP(addr),108);
+			ret = connect(Z_LVAL_PP(sockfd), (struct sockaddr *) &sun, SUN_LEN(&sun));
 			break;
 	}
 	default:

 [2001-06-02 20:59 UTC] sniper@php.net
This should be fixed with PHP 4.0.6, please try the 
latest release candidate:

http://www.php.net/~andi/php-4.0.6RC2.tar.gz

And note that using the undocumented 4th parameter
will make it behave like the system read():

read($sock, $buff, $length, PHP_BINARY_READ)

-Jani

 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Mon Oct 07 01:01:27 2024 UTC