@@ -98,8 +98,8 @@ typedef struct {
98
98
} field_descriptor ;
99
99
100
100
#define KEY_FILL_SOCKADDR "fill_sockaddr"
101
- #define KEY_RECVMSG_RET "recvmsg_ret"
102
- #define KEY_CMSG_LEN "cmsg_len"
101
+ #define KEY_RECVMSG_RET "recvmsg_ret"
102
+ #define KEY_CMSG_LEN "cmsg_len"
103
103
104
104
const struct key_value empty_key_value_list [] = {{0 }};
105
105
@@ -223,6 +223,7 @@ static unsigned from_array_iterate(const zval *arr,
223
223
char buf [sizeof ("element #4294967295" )];
224
224
char * bufp = buf ;
225
225
226
+ /* Note i starts at 1, not 0! */
226
227
for (zend_hash_internal_pointer_reset_ex (Z_ARRVAL_P (arr ), & pos ), i = 1 ;
227
228
!ctx -> err .has_error
228
229
&& zend_hash_get_current_data_ex (Z_ARRVAL_P (arr ), (void * * )& elem , & pos ) == SUCCESS ;
@@ -666,6 +667,13 @@ static void from_zval_write_sun_path(const zval *path, char *sockaddr_un_c, ser_
666
667
path = & lzval ;
667
668
}
668
669
670
+ /* code in this file relies on the path being nul terminated, even though
671
+ * this is not required, at least on linux for abstract paths. It also
672
+ * assumes that the path is not empty */
673
+ if (Z_STRLEN_P (path ) == 0 ) {
674
+ do_from_zval_err (ctx , "%s" , "the path is cannot be empty" );
675
+ return ;
676
+ }
669
677
if (Z_STRLEN_P (path ) >= sizeof (saddr -> sun_path )) {
670
678
do_from_zval_err (ctx , "the path is too long, the maximum permitted "
671
679
"length is %ld" , sizeof (saddr -> sun_path ) - 1 );
@@ -767,10 +775,22 @@ static void from_zval_write_sockaddr_aux(const zval *container,
767
775
return ;
768
776
}
769
777
* sockaddr_ptr = accounted_ecalloc (1 , sizeof (struct sockaddr_un ), ctx );
770
- * sockaddr_len = sizeof (struct sockaddr_un );
771
778
if (fill_sockaddr ) {
779
+ struct sockaddr_un * sock_un = (struct sockaddr_un * )* sockaddr_ptr ;
780
+
772
781
from_zval_write_sockaddr_un (container , (char * )* sockaddr_ptr , ctx );
773
782
(* sockaddr_ptr )-> sa_family = AF_UNIX ;
783
+
784
+ /* calculating length is more complicated here. Giving the size of
785
+ * struct sockaddr_un here and relying on the nul termination of
786
+ * sun_path does not work for paths in the abstract namespace. Note
787
+ * that we always assume the path is not empty and nul terminated */
788
+ * sockaddr_len = offsetof(struct sockaddr_un , sun_path ) +
789
+ (sock_un -> sun_path [0 ] == '\0'
790
+ ? (1 + strlen (& sock_un -> sun_path [1 ]))
791
+ : strlen (sock_un -> sun_path ));
792
+ } else {
793
+ * sockaddr_len = sizeof (struct sockaddr_un );
774
794
}
775
795
break ;
776
796
@@ -869,7 +889,14 @@ static void from_zval_write_control(const zval *arr,
869
889
}
870
890
871
891
if (entry -> calc_space ) {
872
- data_len = entry -> calc_space (arr , ctx );
892
+ zval * * data_elem ;
893
+ /* arr must be an array at this point */
894
+ if (zend_hash_find (Z_ARRVAL_P (arr ), "data" , sizeof ("data" ),
895
+ (void * * )& data_elem ) == FAILURE ) {
896
+ do_from_zval_err (ctx , "cmsghdr should have a 'data' element here" );
897
+ return ;
898
+ }
899
+ data_len = entry -> calc_space (* data_elem , ctx );
873
900
if (ctx -> err .has_error ) {
874
901
return ;
875
902
}
@@ -1370,7 +1397,7 @@ static void from_zval_write_fd_array_aux(zval **elem, unsigned i, void **args, s
1370
1397
return ;
1371
1398
}
1372
1399
1373
- if (php_stream_cast (stream , PHP_STREAM_AS_FD , (void * * )& iarr [i ],
1400
+ if (php_stream_cast (stream , PHP_STREAM_AS_FD , (void * * )& iarr [i - 1 ],
1374
1401
REPORT_ERRORS ) == FAILURE ) {
1375
1402
do_from_zval_err (ctx , "cast stream to file descriptor failed" );
1376
1403
return ;
0 commit comments