18 Commits

Author SHA1 Message Date
Xinchen Hui
15f58c43fb releasing 2.0.5 2017-12-31 12:33:16 +08:00
Xinchen Hui
c4c61f05bf Revert the last merge 2017-10-18 13:05:38 +08:00
Xinchen Hui
9ef044896a Merge pull request #31 from sgolemon/callback.refcount
Explicitly release held references to PHP callbacks
2017-10-18 12:56:28 +08:00
Xinchen Hui
feb39efa86 Merge pull request #32 from sgolemon/gitignore
Add a .gitignore to disregard build artifacts
2017-10-18 12:56:02 +08:00
Xinchen Hui
4438a88e85 Merge pull request #33 from sgolemon/object.alloc
Fix allocation of lua object.
2017-10-18 12:55:49 +08:00
Xinchen Hui
0c6a60d21b Merge pull request #34 from sgolemon/php_printf
Prefer php_printf() over printf()
2017-10-18 12:55:26 +08:00
Xinchen Hui
db95520d2f Merge pull request #35 from sgolemon/non-string.accessor
Fix non-string member access in read/write prop.
2017-10-18 12:55:10 +08:00
Xinchen Hui
8afc555bce Merge pull request #36 from sgolemon/closure.refactor
Refactor LuaClosure
2017-10-18 12:53:50 +08:00
Sara Golemon
486de80ebf Refactor LuaClosure
Use proper internal object storage rather than private props.
Favor NULL clone_obj handler over empty private __clone method.
Favor free_obj handler over __destruct() method.
2017-10-03 10:09:53 -04:00
Sara Golemon
1813b36307 Fix non-string member access in read/write prop.
These both have a null pointer deref waiting to happen
and are coincidentally more complex than they need to be.

zval_get_string() will incref any IS_STRING zval,
or copy/convert any non-string zval.

zend_string_release() will then decref or free as appropriate.
2017-10-03 08:51:02 -04:00
Sara Golemon
a2be2c935b Prefer php_printf() over printf()
On CLI the distinction doesn't matter, but in a web sapi this
will ensure the output goes to the right place.
2017-10-03 08:37:13 -04:00
Sara Golemon
6690ee0c70 Fix allocation of lua object.
Size the malloc using zend's helper.
Use ecalloc over emalloc to make sure uninit'd structs are clear.
No need to check return value as e*alloc() funcs can't fail.
2017-10-03 08:32:51 -04:00
Sara Golemon
f64a8d6d27 Add a .gitignore to disregard build artifacts 2017-10-02 19:01:00 -04:00
Sara Golemon
d6c7850afa Explicitly release held references to PHP callbacks 2017-10-02 18:52:01 -04:00
Xinchen Hui
257d46c1e4 back to dev 2017-07-12 11:42:28 +08:00
Xinchen Hui
e350b425f4 release 2.0.4 2017-07-12 11:42:06 +08:00
Xinchen Hui
527f927ead Fixed bug #73964 (Segmentation fault (11)) 2017-02-12 10:53:36 +08:00
Xinchen Hui
9be57325c6 back to dev 2017-02-10 19:14:10 +08:00
7 changed files with 195 additions and 125 deletions

37
.gitignore vendored Normal file
View File

@@ -0,0 +1,37 @@
*.lo
*.la
.*.swp
.deps
.libs/
include/
tests/*.diff
tests/*.exp
tests/*.log
tests/*.php
tests/*.out
tests/*.sh
Makefile
Makefile.fragments
Makefile.global
Makefile.objects
acinclude.m4
aclocal.m4
autom4te.cache/
build/
config.guess
config.h
config.h.in
config.log
config.nice
config.status
config.sub
configure
configure.ac
configure.in
install-sh
libtool
ltmain.sh
missing
mkinstalldirs
modules/
run-tests.php

74
lua.c
View File

@@ -93,31 +93,31 @@ ZEND_GET_MODULE(lua)
static void php_lua_stack_dump(lua_State* L) { static void php_lua_stack_dump(lua_State* L) {
int i = 1; int i = 1;
int n = lua_gettop(L); int n = lua_gettop(L);
printf("The Length of stack is %d\n", n); php_printf("The Length of stack is %d\n", n);
for (; i <= n; ++i) { for (; i <= n; ++i) {
int t = lua_type(L, i); int t = lua_type(L, i);
printf("%s:", lua_typename(L, t)); php_printf("%s:", lua_typename(L, t));
switch(t) { switch(t) {
case LUA_TNUMBER: case LUA_TNUMBER:
printf("%f", lua_tonumber(L, i)); php_printf("%f", lua_tonumber(L, i));
break; break;
case LUA_TSTRING: case LUA_TSTRING:
printf("%s", lua_tostring(L, i)); php_printf("%s", lua_tostring(L, i));
break; break;
case LUA_TTABLE: case LUA_TTABLE:
break; break;
case LUA_TFUNCTION: case LUA_TFUNCTION:
break; break;
case LUA_TNIL: case LUA_TNIL:
printf("NULL"); php_printf("NULL");
break; break;
case LUA_TBOOLEAN: case LUA_TBOOLEAN:
printf("%s", lua_toboolean(L, i) ? "TRUE" : "FALSE"); php_printf("%s", lua_toboolean(L, i) ? "TRUE" : "FALSE");
break; break;
default: default:
break; break;
} }
printf("\n"); php_printf("\n");
} }
} }
/* }}} */ /* }}} */
@@ -174,6 +174,11 @@ static void php_lua_dtor_object(zend_object *object) /* {{{ */ {
php_lua_object *lua_obj = php_lua_obj_from_obj(object); php_lua_object *lua_obj = php_lua_obj_from_obj(object);
zend_object_std_dtor(&(lua_obj->obj)); zend_object_std_dtor(&(lua_obj->obj));
}
/* }}} */
static void php_lua_free_object(zend_object *object) /* {{{ */ {
php_lua_object *lua_obj = php_lua_obj_from_obj(object);
if (lua_obj->L) { if (lua_obj->L) {
lua_close(lua_obj->L); lua_close(lua_obj->L);
@@ -192,12 +197,7 @@ zend_object *php_lua_create_object(zend_class_entry *ce)
lua_atpanic(L, php_lua_atpanic); lua_atpanic(L, php_lua_atpanic);
intern = emalloc(sizeof(php_lua_object) + sizeof(zval) * (ce->default_properties_count - 1)); intern = ecalloc(1, sizeof(php_lua_object) + zend_object_properties_size(ce));
if (!intern) {
php_error_docref(NULL, E_ERROR, "alloc memory for lua object failed");
}
intern->L = L; intern->L = L;
zend_object_std_init(&intern->obj, ce); zend_object_std_init(&intern->obj, ce);
@@ -212,27 +212,22 @@ zend_object *php_lua_create_object(zend_class_entry *ce)
/** {{{ static zval * php_lua_read_property(zval *object, zval *member, int type) /** {{{ static zval * php_lua_read_property(zval *object, zval *member, int type)
*/ */
zval *php_lua_read_property(zval *object, zval *member, int type, void **cache_slot, zval *rv){ zval *php_lua_read_property(zval *object, zval *member, int type, void **cache_slot, zval *rv){
lua_State *L = NULL; lua_State *L = (Z_LUAVAL_P(object))->L;
zval *tmp_member = NULL; zend_string *str_member;
if (type != BP_VAR_R) { if (type != BP_VAR_R) {
ZVAL_NULL(rv); ZVAL_NULL(rv);
return rv; return rv;
} }
if (Z_TYPE_P(member) != IS_STRING) { str_member = zval_get_string(member);
*tmp_member = *member;
zval_copy_ctor(tmp_member);
convert_to_string(tmp_member);
member = tmp_member;
}
L = (Z_LUAVAL_P(object))->L;
#if (LUA_VERSION_NUM < 502) #if (LUA_VERSION_NUM < 502)
lua_getfield(L, LUA_GLOBALSINDEX, Z_STRVAL_P(member)); lua_getfield(L, LUA_GLOBALSINDEX, ZSTR_VAL(str_member));
#else #else
lua_getglobal(L, Z_STRVAL_P(member)); lua_getglobal(L, ZSTR_VAL(str_member));
#endif #endif
zend_string_release(str_member);
php_lua_get_zval_from_lua(L, -1, object, rv); php_lua_get_zval_from_lua(L, -1, object, rv);
lua_pop(L, 1); lua_pop(L, 1);
return rv; return rv;
@@ -242,17 +237,8 @@ zval *php_lua_read_property(zval *object, zval *member, int type, void **cache_s
/** {{{ static void php_lua_write_property(zval *object, zval *member, zval *value) /** {{{ static void php_lua_write_property(zval *object, zval *member, zval *value)
*/ */
static void php_lua_write_property(zval *object, zval *member, zval *value, void ** key) { static void php_lua_write_property(zval *object, zval *member, zval *value, void ** key) {
lua_State *L = NULL; lua_State *L = (Z_LUAVAL_P(object))->L;
zval *tmp_member = NULL; zend_string *str_member = zval_get_string(member);
if (Z_TYPE_P(member) != IS_STRING) {
*tmp_member = *member;
zval_copy_ctor(tmp_member);
convert_to_string(tmp_member);
member = tmp_member;
}
L = (Z_LUAVAL_P(object))->L;
#if (LUA_VERSION_NUM < 502) #if (LUA_VERSION_NUM < 502)
php_lua_send_zval_to_lua(L, member); php_lua_send_zval_to_lua(L, member);
@@ -264,9 +250,7 @@ static void php_lua_write_property(zval *object, zval *member, zval *value, void
lua_setglobal(L, Z_STRVAL_P(member)); lua_setglobal(L, Z_STRVAL_P(member));
#endif #endif
if (tmp_member) { zend_string_release(str_member);
zval_ptr_dtor(tmp_member);
}
} }
/* }}} */ /* }}} */
@@ -551,13 +535,9 @@ static zval *php_lua_call_lua_function(zval *lua_obj, zval *func, zval *args, in
} }
} else if (IS_OBJECT == Z_TYPE_P(func) } else if (IS_OBJECT == Z_TYPE_P(func)
&& instanceof_function(Z_OBJCE_P(func), php_lua_get_closure_ce())) { && instanceof_function(Z_OBJCE_P(func), php_lua_get_closure_ce())) {
zval *closure = zend_read_property(php_lua_get_closure_ce(), func, ZEND_STRL("_closure"), 1, &rv); lua_closure_object *closure_obj = php_lua_closure_object_from_zend_object(Z_OBJ_P(func));
if (!Z_LVAL_P(closure)) {
zend_throw_exception_ex(lua_exception_ce, 0, "invalid lua closure");
return NULL;
}
bp = lua_gettop(L); bp = lua_gettop(L);
lua_rawgeti(L, LUA_REGISTRYINDEX, Z_LVAL_P(closure)); lua_rawgeti(L, LUA_REGISTRYINDEX, closure_obj->closure);
if (LUA_TFUNCTION != lua_type(L, lua_gettop(L))) { if (LUA_TFUNCTION != lua_type(L, lua_gettop(L))) {
lua_pop(L, -1); lua_pop(L, -1);
zend_throw_exception_ex(lua_exception_ce, 0, "call to lua closure failed"); zend_throw_exception_ex(lua_exception_ce, 0, "call to lua closure failed");
@@ -802,7 +782,7 @@ zend_function_entry lua_class_methods[] = {
PHP_ME(lua, getVersion, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_ALLOW_STATIC) PHP_ME(lua, getVersion, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_ALLOW_STATIC)
PHP_ME(lua, registerCallback, arginfo_lua_register, ZEND_ACC_PUBLIC) PHP_ME(lua, registerCallback, arginfo_lua_register, ZEND_ACC_PUBLIC)
PHP_MALIAS(lua, __call, call, arginfo_lua_call, ZEND_ACC_PUBLIC) PHP_MALIAS(lua, __call, call, arginfo_lua_call, ZEND_ACC_PUBLIC)
{NULL, NULL, NULL} PHP_FE_END
}; };
/* }}} */ /* }}} */
@@ -831,7 +811,7 @@ PHP_MINIT_FUNCTION(lua) {
memcpy(&lua_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); memcpy(&lua_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
lua_object_handlers.offset = XtOffsetOf(php_lua_object, obj); lua_object_handlers.offset = XtOffsetOf(php_lua_object, obj);
lua_object_handlers.dtor_obj = php_lua_dtor_object; lua_object_handlers.dtor_obj = php_lua_dtor_object;
lua_object_handlers.free_obj = NULL; lua_object_handlers.free_obj = php_lua_free_object;
lua_object_handlers.clone_obj = NULL; lua_object_handlers.clone_obj = NULL;
lua_object_handlers.write_property = php_lua_write_property; lua_object_handlers.write_property = php_lua_write_property;
lua_object_handlers.read_property = php_lua_read_property; lua_object_handlers.read_property = php_lua_read_property;

View File

@@ -25,6 +25,7 @@
#include "Zend/zend_exceptions.h" #include "Zend/zend_exceptions.h"
#include "lua.h" #include "lua.h"
#include "lua_closure.h"
#include "lauxlib.h" #include "lauxlib.h"
#include "lualib.h" #include "lualib.h"
@@ -33,6 +34,7 @@
static zend_class_entry *lua_closure_ce; static zend_class_entry *lua_closure_ce;
extern zend_class_entry *lua_ce; extern zend_class_entry *lua_ce;
extern zend_class_entry *lua_exception_ce; extern zend_class_entry *lua_exception_ce;
static zend_object_handlers lua_closure_handlers;
/** {{{ ARG_INFO /** {{{ ARG_INFO
* *
@@ -45,10 +47,13 @@ ZEND_END_ARG_INFO()
/** {{{ zval * php_lua_closure_instance(zval *instance, long ref_id, zval *lua_obj) /** {{{ zval * php_lua_closure_instance(zval *instance, long ref_id, zval *lua_obj)
*/ */
zval * php_lua_closure_instance(zval *instance, long ref_id, zval *lua_obj) { zval* php_lua_closure_instance(zval *instance, long ref_id, zval *lua_obj) {
lua_closure_object *objval;
object_init_ex(instance, lua_closure_ce); object_init_ex(instance, lua_closure_ce);
zend_update_property_long(lua_closure_ce, instance, ZEND_STRL("_closure"), ref_id); objval = php_lua_closure_object_from_zend_object(Z_OBJ_P(instance));
zend_update_property(lua_closure_ce, instance, ZEND_STRL("_lua_object"), lua_obj); objval->closure = ref_id;
ZVAL_ZVAL(&(objval->lua), lua_obj, 1, 0);
return instance; return instance;
} }
@@ -60,35 +65,13 @@ PHP_METHOD(lua_closure, __construct) {
} }
/* }}} */ /* }}} */
/** {{{ proto LuaClosure::__destruct()
*/
PHP_METHOD(lua_closure, __destruct) {
zval *lua_obj, *closure, rv;
lua_obj = zend_read_property(lua_closure_ce, getThis(), ZEND_STRL("_lua_object"), 1, &rv);
if (ZVAL_IS_NULL(lua_obj)
|| Z_TYPE_P(lua_obj) != IS_OBJECT
|| !instanceof_function(Z_OBJCE_P(lua_obj), lua_ce)) {
RETURN_FALSE;
}
closure = zend_read_property(lua_closure_ce, getThis(), ZEND_STRL("_closure"), 1, &rv);
if (!Z_LVAL_P(closure)) {
RETURN_FALSE;
}
luaL_unref((Z_LUAVAL_P(lua_obj))->L, LUA_REGISTRYINDEX, Z_LVAL_P(closure));
}
/* }}} */
/** {{{ proto LuaClosure::invoke(mxied $args) /** {{{ proto LuaClosure::invoke(mxied $args)
*/ */
PHP_METHOD(lua_closure, invoke) { PHP_METHOD(lua_closure, invoke) {
lua_closure_object *objval = php_lua_closure_object_from_zend_object(Z_OBJ_P(getThis()));
int bp, sp; int bp, sp;
zval *arguments = NULL; zval *arguments = NULL;
zval *lua_obj = NULL;
lua_State *L = NULL; lua_State *L = NULL;
zval *closure = NULL;
zval rv; zval rv;
if (ZEND_NUM_ARGS()) { if (ZEND_NUM_ARGS()) {
@@ -100,25 +83,16 @@ PHP_METHOD(lua_closure, invoke) {
} }
} }
lua_obj = zend_read_property(lua_closure_ce, getThis(), ZEND_STRL("_lua_object"), 1, &rv); if (Z_TYPE(objval->lua) != IS_OBJECT
|| !instanceof_function(Z_OBJCE(objval->lua), lua_ce)) {
if (ZVAL_IS_NULL(lua_obj)
|| Z_TYPE_P(lua_obj) != IS_OBJECT
|| !instanceof_function(Z_OBJCE_P(lua_obj), lua_ce)) {
zend_throw_exception_ex(NULL, 0, "corrupted Lua object"); zend_throw_exception_ex(NULL, 0, "corrupted Lua object");
return; return;
} }
closure = zend_read_property(lua_closure_ce, getThis(), ZEND_STRL("_closure"), 1, &rv); L = (Z_LUAVAL(objval->lua))->L;
if (!Z_LVAL_P(closure)) {
zend_throw_exception_ex(NULL, 0, "invalid lua closure");
return;
}
L = (Z_LUAVAL_P(lua_obj))->L;
bp = lua_gettop(L); bp = lua_gettop(L);
lua_rawgeti(L, LUA_REGISTRYINDEX, Z_LVAL_P(closure)); lua_rawgeti(L, LUA_REGISTRYINDEX, objval->closure);
if (LUA_TFUNCTION != lua_type(L, lua_gettop(L))) { if (LUA_TFUNCTION != lua_type(L, lua_gettop(L))) {
lua_pop(L, -1); lua_pop(L, -1);
zend_throw_exception_ex(NULL, 0, "call to lua closure failed"); zend_throw_exception_ex(NULL, 0, "call to lua closure failed");
@@ -147,13 +121,13 @@ PHP_METHOD(lua_closure, invoke) {
if (!sp) { if (!sp) {
RETURN_NULL(); RETURN_NULL();
} else if (sp == 1) { } else if (sp == 1) {
php_lua_get_zval_from_lua(L, -1, lua_obj, return_value); php_lua_get_zval_from_lua(L, -1, &(objval->lua), return_value);
} else { } else {
zval rv; zval rv;
int i = 0; int i = 0;
array_init(return_value); array_init(return_value);
for (i = -sp; i < 0; i++) { for (i = -sp; i < 0; i++) {
php_lua_get_zval_from_lua(L, i, lua_obj, &rv); php_lua_get_zval_from_lua(L, i, &(objval->lua), &rv);
add_next_index_zval(return_value, &rv); add_next_index_zval(return_value, &rv);
} }
} }
@@ -166,51 +140,37 @@ PHP_METHOD(lua_closure, invoke) {
} }
/* }}} */ /* }}} */
/** {{{ proto LuaClosure::__clone()
*/
PHP_METHOD(lua_closure, __clone) {
}
/* }}} */
/* {{{ lua_class_methods[] /* {{{ lua_class_methods[]
*
*/ */
zend_function_entry lua_closure_methods[] = { zend_function_entry lua_closure_methods[] = {
PHP_ME(lua_closure, __construct, NULL, ZEND_ACC_PRIVATE|ZEND_ACC_CTOR) PHP_ME(lua_closure, __construct, NULL, ZEND_ACC_PRIVATE|ZEND_ACC_CTOR)
PHP_ME(lua_closure, __destruct, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_DTOR)
PHP_ME(lua_closure, __clone, NULL, ZEND_ACC_PRIVATE)
PHP_ME(lua_closure, invoke, arginfo_lua_invoke, ZEND_ACC_PUBLIC) PHP_ME(lua_closure, invoke, arginfo_lua_invoke, ZEND_ACC_PUBLIC)
PHP_MALIAS(lua_closure, __invoke, invoke, arginfo_lua_invoke, ZEND_ACC_PUBLIC) PHP_MALIAS(lua_closure, __invoke, invoke, arginfo_lua_invoke, ZEND_ACC_PUBLIC)
{NULL, NULL, NULL} PHP_FE_END
}; };
/* }}} */ /* }}} */
static void php_lua_closure_dtor_object(void *object, zend_object_handlers handle) /* {{{ */ static void php_lua_closure_free_obj(zend_object *zobj) /* {{{ */
{ {
zend_object *obj = (zend_object*)object; lua_closure_object *objval = php_lua_closure_object_from_zend_object(zobj);
zend_object_std_dtor(obj); if ((Z_TYPE(objval->lua) == IS_OBJECT) &&
instanceof_function(Z_OBJCE(objval->lua), lua_ce)) {
efree(obj); luaL_unref((Z_LUAVAL(objval->lua))->L, LUA_REGISTRYINDEX, objval->closure);
}
zval_dtor(&(objval->lua));
zend_object_std_dtor(zobj);
} /* }}} */ } /* }}} */
zend_object *php_lua_closure_create_object(zend_class_entry *ce) /* {{{ */ zend_object *php_lua_closure_create_object(zend_class_entry *ce) /* {{{ */
{ {
zend_object *intern; lua_closure_object *objval = ecalloc(1, sizeof(lua_closure_object) + zend_object_properties_size(ce));
zend_object *zobj = &(objval->std);
intern = emalloc(sizeof(zend_object)+ sizeof(zval) * (ce->default_properties_count - 1));
if (!intern) { zend_object_std_init(zobj, ce);
php_error_docref(NULL, E_ERROR, "alloc memory for lua object failed"); zobj->handlers = &lua_closure_handlers;
}
zend_object_std_init(intern, ce);
object_properties_init(intern, ce);
intern->handlers = zend_get_std_object_handlers();
return intern;
return zobj;
} /* }}} */ } /* }}} */
void php_lua_closure_register() /* {{{ */ void php_lua_closure_register() /* {{{ */
@@ -222,10 +182,10 @@ void php_lua_closure_register() /* {{{ */
lua_closure_ce->create_object = php_lua_closure_create_object; lua_closure_ce->create_object = php_lua_closure_create_object;
lua_closure_ce->ce_flags |= ZEND_ACC_FINAL; lua_closure_ce->ce_flags |= ZEND_ACC_FINAL;
zend_declare_property_long(lua_closure_ce, ZEND_STRL("_closure"), 0, ZEND_ACC_PRIVATE); memcpy(&lua_closure_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
zend_declare_property_null(lua_closure_ce, ZEND_STRL("_lua_object"), ZEND_ACC_PRIVATE); lua_closure_handlers.offset = XtOffsetOf(lua_closure_object, std);
lua_closure_handlers.clone_obj = NULL;
lua_closure_handlers.free_obj = php_lua_closure_free_obj;
} /* }}} */ } /* }}} */
zend_class_entry *php_lua_get_closure_ce() /* {{{ */ zend_class_entry *php_lua_get_closure_ce() /* {{{ */

View File

@@ -19,6 +19,17 @@
#ifndef LUA_CLOSURE_H #ifndef LUA_CLOSURE_H
#define LUA_CLOSURE_H #define LUA_CLOSURE_H
typedef struct _lua_closure_object {
long closure;
zval lua;
zend_object std;
} lua_closure_object;
static inline lua_closure_object* php_lua_closure_object_from_zend_object(zend_object *zobj) {
return ((lua_closure_object*)(zobj + 1)) - 1;
}
void php_lua_closure_register(); void php_lua_closure_register();
zend_class_entry *php_lua_get_closure_ce(); zend_class_entry *php_lua_get_closure_ce();
zval * php_lua_closure_instance(zval *instance, long ref_id, zval *lua_obj); zval * php_lua_closure_instance(zval *instance, long ref_id, zval *lua_obj);

View File

@@ -23,11 +23,11 @@
<email>msaraujo@php.net</email> <email>msaraujo@php.net</email>
<active>yes</active> <active>yes</active>
</developer> </developer>
<date>2017-02-10</date> <date>2017-12-31</date>
<time>19:15:00</time> <time>19:15:00</time>
<version> <version>
<release>2.0.3</release> <release>2.0.5</release>
<api>2.0.3</api> <api>2.0.5</api>
</version> </version>
<stability> <stability>
<release>stable</release> <release>stable</release>
@@ -35,7 +35,9 @@
</stability> </stability>
<license uri="http://www.php.net/license">PHP</license> <license uri="http://www.php.net/license">PHP</license>
<notes> <notes>
- Fixed issue #20 (PHP 7: Lua::eval(): unsupported type `unknown' for lua) - Refactor LuaClosure. (SaraG)
- Fix non-string member access in read/write prop. (SaraG)
- Fix allocation of lua object. (SaraG)
</notes> </notes>
<contents> <contents>
<dir name="/"> <dir name="/">
@@ -65,6 +67,7 @@
<file name="issue012.phpt" role="test" /> <file name="issue012.phpt" role="test" />
<file name="bug65097.phpt" role="test" /> <file name="bug65097.phpt" role="test" />
<file name="bug71997.phpt" role="test" /> <file name="bug71997.phpt" role="test" />
<file name="bug73964.phpt" role="test" />
</dir> </dir>
</dir> </dir>
</contents> </contents>
@@ -81,6 +84,39 @@
<providesextension>lua</providesextension> <providesextension>lua</providesextension>
<extsrcrelease /> <extsrcrelease />
<changelog> <changelog>
<release>
<date>2017-12-31</date>
<version>
<release>2.0.5</release>
<api>2.0.5</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<license uri="http://www.php.net/license">PHP License</license>
<notes>
- Refactor LuaClosure. (SaraG)
- Fix non-string member access in read/write prop. (SaraG)
- Fix allocation of lua object. (SaraG)
</notes>
</release>
<release>
<date>2017-07-12</date>
<version>
<release>2.0.4</release>
<api>2.0.4</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<license uri="http://www.php.net/license">PHP License</license>
<notes>
- Fixed bug #73964 (Segmentation fault)
</notes>
</release>
<release> <release>
<date>2017-02-10</date> <date>2017-02-10</date>
<version> <version>

View File

@@ -48,7 +48,7 @@ extern zend_module_entry lua_module_entry;
#define LUA_G(v) (lua_globals.v) #define LUA_G(v) (lua_globals.v)
#endif #endif
#define PHP_LUA_VERSION "2.0.3" #define PHP_LUA_VERSION "2.0.5"
struct _php_lua_object { struct _php_lua_object {
lua_State *L; lua_State *L;
@@ -61,6 +61,7 @@ static inline php_lua_object *php_lua_obj_from_obj(zend_object *obj) {
return (php_lua_object*)((char*)(obj)-XtOffsetOf(php_lua_object, obj)); return (php_lua_object*)((char*)(obj)-XtOffsetOf(php_lua_object, obj));
} }
#define Z_LUAVAL(obj) php_lua_obj_from_obj(Z_OBJ((obj)))
#define Z_LUAVAL_P(obj) php_lua_obj_from_obj(Z_OBJ_P((obj))) #define Z_LUAVAL_P(obj) php_lua_obj_from_obj(Z_OBJ_P((obj)))
zval *php_lua_get_zval_from_lua(lua_State *L, int index, zval *lua_obj, zval *rv); zval *php_lua_get_zval_from_lua(lua_State *L, int index, zval *lua_obj, zval *rv);

45
tests/bug73964.phpt Normal file
View File

@@ -0,0 +1,45 @@
--TEST--
Bug #73964 (Segmentation fault (11))
--SKIPIF--
<?php
if (!extension_loaded("lua")) print "skip lua extension missing";
?>
--FILE--
<?php
class LuaTest
{
function __construct()
{
$this->lua = new Lua();
$this->lua->registerCallback("log", array($this, "API_LuaLog"));
}
function API_LuaLog( $entry)
{
echo("from lua: $entry");
}
public function RunTest()
{
$this->lua->eval(<<<CODE
function TestFunc(str)
log(str)
end
CODE
);
$GamePackage = $this->lua->RootTable;
$this->lua->call("TestFunc", array("okey"));
}
}
$a = new LuaTest();
$a->runtest();
?>
--EXPECT--
from lua: okey