tony2001                Sun Oct 23 14:31:40 2005 EDT

  Modified files:              
    /php-src/ext/standard       dns.c 
  Log:
  fix #34938 (dns_get_record() doesn't resolve long hostnames and leaks)
  
  
http://cvs.php.net/diff.php/php-src/ext/standard/dns.c?r1=1.73&r2=1.74&ty=u
Index: php-src/ext/standard/dns.c
diff -u php-src/ext/standard/dns.c:1.73 php-src/ext/standard/dns.c:1.74
--- php-src/ext/standard/dns.c:1.73     Sun Oct 23 11:29:38 2005
+++ php-src/ext/standard/dns.c  Sun Oct 23 14:31:36 2005
@@ -18,7 +18,7 @@
    +----------------------------------------------------------------------+
  */
 
-/* $Id: dns.c,v 1.73 2005/10/23 15:29:38 iliaa Exp $ */
+/* $Id: dns.c,v 1.74 2005/10/23 18:31:36 tony2001 Exp $ */
 
 /* {{{ includes */
 #include "php.h"
@@ -357,9 +357,8 @@
 #define QFIXEDSZ        4       /* fixed data in query <arpa/nameser.h> */
 #endif /* QFIXEDSZ */
 
-#ifndef MAXHOSTNAMELEN
+#undef MAXHOSTNAMELEN
 #define MAXHOSTNAMELEN  1024
-#endif /* MAXHOSTNAMELEN */
 
 #ifndef MAXRESOURCERECORDS
 #define MAXRESOURCERECORDS     64
@@ -370,10 +369,25 @@
        u_char qb2[65536];
 } querybuf;
 
+/* just a hack to free resources allocated by glibc in __res_nsend() 
+ * See also: 
+ *   res_thread_freeres() in glibc/resolv/res_init.c 
+ *   __libc_res_nsend()   in resolv/res_send.c 
+ * */
+static void _php_dns_free_res(struct __res_state res) { /* {{{ */
+       int ns;
+       for (ns = 0; ns < MAXNS; ns++) {
+               if (res._u._ext.nsaddrs[ns] != NULL) {
+                       free (res._u._ext.nsaddrs[ns]);
+                       res._u._ext.nsaddrs[ns] = NULL;
+               }
+       }
+} /* }}} */
+
 /* {{{ php_parserr */
 static u_char *php_parserr(u_char *cp, querybuf *answer, int type_to_fetch, 
int store, zval **subarray)
 {
-       u_short type, class, dlen;
+       u_short type, dlen;
        u_long ttl;
        long n, i;
        u_short s;
@@ -383,14 +397,13 @@
 
        *subarray = NULL;
 
-       n = dn_expand(answer->qb2, answer->qb2+65536, cp, name, (sizeof(name)) 
- 2);
+       n = dn_expand(answer->qb2, answer->qb2+65536, cp, name, sizeof(name) - 
2);
        if (n < 0) {
                return NULL;
        }
        cp += n;
        
        GETSHORT(type, cp);
-       GETSHORT(class, cp);
        GETLONG(ttl, cp);
        GETSHORT(dlen, cp);
        if (type_to_fetch != T_ANY && type != type_to_fetch) {
@@ -650,7 +663,7 @@
        HEADER *hp;
        querybuf buf, answer;
        u_char *cp = NULL, *end = NULL;
-       long n, qd, an, ns = 0, ar = 0;
+       int n, qd, an, ns = 0, ar = 0;
        int type, first_query = 1, store_results = 1;
 
        switch (ZEND_NUM_ARGS()) {
@@ -747,6 +760,7 @@
                                break;
                }
                if (type_to_fetch) {
+                       memset(&res, 0, sizeof(res));
                        res_ninit(&res);
                        res.retrans = 5;
                        res.options &= ~RES_DEFNAMES;
@@ -756,6 +770,7 @@
                                php_error_docref(NULL TSRMLS_CC, E_WARNING, 
"res_nmkquery() failed");
                                zval_dtor(return_value);
                                res_nclose(&res);
+                               _php_dns_free_res(res);
                                RETURN_FALSE;
                        }
                        n = res_nsend(&res, buf.qb2, n, answer.qb2, sizeof 
answer);
@@ -763,6 +778,7 @@
                                php_error_docref(NULL TSRMLS_CC, E_WARNING, 
"res_nsend() failed");
                                zval_dtor(return_value);
                                res_nclose(&res);
+                               _php_dns_free_res(res);
                                RETURN_FALSE;
                        }
                
@@ -781,6 +797,7 @@
                                        php_error_docref(NULL TSRMLS_CC, 
E_WARNING, "Unable to parse DNS data received");
                                        zval_dtor(return_value);
                                        res_nclose(&res);
+                                       _php_dns_free_res(res);
                                        RETURN_FALSE;
                                }
                                cp += n + QFIXEDSZ;
@@ -796,6 +813,7 @@
                                }
                        }
                        res_nclose(&res);
+                       _php_dns_free_res(res);
                }
        }
 

-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to