fix leaks
[m6w6/ext-psi] / src / types / decl.c
index 85d93d40cd63243cb93c6e3a15c240f27a8b314c..581eadd95d01858261b846ea76b1c99b2aaef702 100644 (file)
  *******************************************************************************/
 
 #include "php_psi_stdinc.h"
-
 #include "php_psi.h"
 
 #include <dlfcn.h>
 #include <fnmatch.h>
 
+#include <Zend/zend_smart_str.h>
+
 #include "data.h"
 
 #define PSI_FUNC_REDIRS
@@ -58,7 +59,7 @@ void psi_decl_free(struct psi_decl **d_ptr)
                        psi_plist_free(d->args);
                }
                if (d->redir) {
-                       free(d->redir);
+                       zend_string_release(d->redir);
                }
                free(d);
        }
@@ -66,7 +67,9 @@ void psi_decl_free(struct psi_decl **d_ptr)
 
 void psi_decl_dump(int fd, struct psi_decl *decl)
 {
-       psi_decl_abi_dump(fd, decl->abi);
+       if (decl->abi) {
+               psi_decl_abi_dump(fd, decl->abi);
+       }
        dprintf(fd, " ");
        /* FIXME: functions returning arrays */
        psi_decl_arg_dump(fd, decl->func, 0);
@@ -85,15 +88,18 @@ void psi_decl_dump(int fd, struct psi_decl *decl)
                        dprintf(fd, ", ...");
                }
        }
+       if (decl->func->var->array_size) {
+               dprintf(fd, ")[%u]", decl->func->var->array_size);
+       }
        if (decl->redir) {
-               dprintf(fd, ") __asm__ (\"%s\");", decl->redir);
+               dprintf(fd, ") __asm__ (\"%s\");", decl->redir->val);
        } else {
                dprintf(fd, ");");
        }
 }
 
 static inline bool psi_decl_validate_func(struct psi_data *data,
-               struct psi_decl *decl, struct psi_decl_arg *func, void *dl)
+               struct psi_decl *decl, struct psi_decl_arg *func)
 {
        struct psi_func_redir *redir;
 
@@ -103,10 +109,18 @@ static inline bool psi_decl_validate_func(struct psi_data *data,
        }
 
        for (redir = &psi_func_redirs[0]; redir->name; ++redir) {
-               if (!strcmp(func->var->name, redir->name)) {
+               if (!strcmp(func->var->name->val, redir->name)) {
                        decl->sym = redir->func;
                }
        }
+       if (!decl->sym) {
+               size_t i = 0;
+               void *dl;
+
+               while (!decl->sym && psi_plist_get(data->file.dlopened, i++, &dl)) {
+                       decl->sym = dlsym(dl, decl->redir ? decl->redir->val : func->var->name->val);
+               }
+       }
        if (!decl->sym) {
 #ifndef RTLD_NEXT
 # define RTLD_NEXT ((void *) -1l)
@@ -114,11 +128,12 @@ static inline bool psi_decl_validate_func(struct psi_data *data,
 #ifndef RTLD_DEFAULT
 # define RTLD_DEFAULT ((void *) 0)
 #endif
-               decl->sym = dlsym(dl ?: RTLD_DEFAULT, decl->redir ?: func->var->name);
+               decl->sym = dlsym(RTLD_DEFAULT, decl->redir ? decl->redir->val : func->var->name->val);
                if (!decl->sym) {
                        data->error(data, func->token, PSI_WARNING,
                                        "Failed to locate symbol '%s(%s)': %s",
-                                       func->var->name, decl->redir ?: "",
+                                       func->var->name->val,
+                                       decl->redir ? decl->redir->val : "",
                                        dlerror() ?: "not found");
                        return false;
                }
@@ -132,7 +147,7 @@ bool psi_decl_validate(struct psi_data *data, struct psi_decl *decl,
        if (!psi_decl_validate_nodl(data, decl, scope)) {
                return false;
        }
-       if (!psi_decl_validate_func(data, decl, decl->func, scope->dlopened)) {
+       if (!psi_decl_validate_func(data, decl, decl->func)) {
                return false;
        }
 
@@ -143,10 +158,11 @@ bool psi_decl_validate_nodl(struct psi_data *data, struct psi_decl *decl,
                struct psi_validate_scope *scope)
 {
        if (!decl->abi) {
-               decl->abi = psi_decl_abi_init("default");
+               decl->abi = psi_decl_abi_init(NULL);
        } else if (!psi_decl_abi_validate(data, decl->abi)) {
                data->error(data, decl->abi->token, PSI_WARNING,
-                               "Invalid calling convention: '%s'", decl->abi->token->text);
+                               "Invalid calling convention: '%s'",
+                               decl->abi->token->text->val);
                return false;
        }
        if (!psi_decl_arg_validate(data, decl->func, scope)) {
@@ -158,9 +174,13 @@ bool psi_decl_validate_nodl(struct psi_data *data, struct psi_decl *decl,
 
                while (psi_plist_get(decl->args, i++, &arg)) {
                        if (!arg->var->name) {
-                               arg->var->name = malloc(7);
-                               snprintf(arg->var->name, 6, "arg%zu", i);
-                               arg->var->fqn = strdup(arg->var->name);
+                               smart_str name = {0};
+
+                               smart_str_appendl_ex(&name, ZEND_STRL("arg"), 1);
+                               smart_str_append_unsigned_ex(&name, i, 1);
+
+                               arg->var->name = smart_str_extract(&name);
+                               arg->var->fqn = zend_string_copy(arg->var->name);
                        }
                        if (!psi_decl_arg_validate(data, arg, scope)) {
                                return false;