From 35af5d329c2e4e327d0b6962796840b724bf10cc Mon Sep 17 00:00:00 2001
From: Roman Tsisyk <roman@tsisyk.com>
Date: Wed, 11 Jun 2014 15:16:03 +0400
Subject: [PATCH] Fix #346: yaml.null() crases server

This patch also adds NULL constant to yaml, msgpack, msgpackffi
and json serializers.
---
 src/lua/cjson.cc          |  4 ++++
 src/lua/msgpack.cc        |  4 ++++
 src/lua/yaml.cc           |  6 ++++++
 test/box/cjson.result     |  8 ++++++++
 test/box/cjson.test.lua   |  3 +++
 test/box/misc.result      | 25 +++++++++++++++++++++++++
 test/box/misc.test.lua    | 13 +++++++++++++
 test/box/msgpack.result   | 24 ++++++++++++++++++++++++
 test/box/msgpack.test.lua |  6 ++++++
 9 files changed, 93 insertions(+)

diff --git a/src/lua/cjson.cc b/src/lua/cjson.cc
index d1f3a32695..2ad3c2f2f5 100644
--- a/src/lua/cjson.cc
+++ b/src/lua/cjson.cc
@@ -41,6 +41,10 @@ int
 tarantool_lua_cjson_init(struct lua_State *L)
 {
 	luaopen_cjson(L);
+	/* Add NULL constant */
+	lua_pushlightuserdata(L, NULL);
+	lua_setfield(L, -2, "NULL");
+	/* Register module */
 	lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
 	lua_pushstring(L, jsonlib_name); /* add alias */
 	lua_pushvalue(L, -3);
diff --git a/src/lua/msgpack.cc b/src/lua/msgpack.cc
index 0ce4a321e8..dc85b1137e 100644
--- a/src/lua/msgpack.cc
+++ b/src/lua/msgpack.cc
@@ -417,5 +417,9 @@ luaopen_msgpack(lua_State *L)
 	};
 
 	luaL_register_module(L, "msgpack", msgpacklib);
+	/* Add NULL constant */
+	luaL_loadstring(L, "return require('ffi').cast('void *', 0)");
+	lua_call(L, 0, 1);
+	lua_setfield(L, -2, "NULL");
 	return 1;
 }
diff --git a/src/lua/yaml.cc b/src/lua/yaml.cc
index a909c7894b..871cbb7466 100644
--- a/src/lua/yaml.cc
+++ b/src/lua/yaml.cc
@@ -39,6 +39,12 @@ int
 tarantool_lua_yaml_init(struct lua_State *L)
 {
 	luaopen_yaml(L);
+	/* Fix buggy null() function and add NULL constant */
+	luaL_loadstring(L, "return require('ffi').cast('void *', 0)");
+	lua_pushvalue(L, -1);
+	lua_setfield(L, -3, "null");
+	lua_call(L, 0, 1);
+	lua_setfield(L, -2, "NULL");
 	lua_pop(L, 1); /* yaml module */
 	/* Remove global variable */
 	lua_pushnil(L);
diff --git a/test/box/cjson.result b/test/box/cjson.result
index e7fe97873b..3288c99e58 100644
--- a/test/box/cjson.result
+++ b/test/box/cjson.result
@@ -43,3 +43,11 @@ json.decode('{\"test\": \"Результат\"}').test
 ---
 - !!binary U5UBCw==
 ...
+json.encode(json.NULL)
+---
+- 'null'
+...
+json.decode(json.encode(json.NULL))
+---
+- null
+...
diff --git a/test/box/cjson.test.lua b/test/box/cjson.test.lua
index 20970e8259..f679c24f9a 100644
--- a/test/box/cjson.test.lua
+++ b/test/box/cjson.test.lua
@@ -13,3 +13,6 @@ json.decode('[123, \"Кудыкины горы\"]')[2]
 json.decode('{\"test\": \"Результат\"}').test
 -- parser test to recognize binary stream
 '\83\149\1\11'
+
+json.encode(json.NULL)
+json.decode(json.encode(json.NULL))
diff --git a/test/box/misc.result b/test/box/misc.result
index 997b8b00a7..9a274fbb14 100644
--- a/test/box/misc.result
+++ b/test/box/misc.result
@@ -602,3 +602,28 @@ ffi.new('struct test', { a = 15 })
 ---
 - - yaml totable test = 15
 ...
+-------------------------------------------------------------------------------
+-- #346 yaml.null() crases server
+-------------------------------------------------------------------------------
+yaml = require('yaml')
+---
+...
+type(yaml.NULL)
+---
+- cdata
+...
+yaml.NULL
+---
+- null
+...
+yaml.NULL == nil
+---
+- true
+...
+yaml.null() -- for compatibility with luaYAML
+---
+- null
+...
+yaml = nil
+---
+...
diff --git a/test/box/misc.test.lua b/test/box/misc.test.lua
index 024806cf08..ef01d7bd37 100644
--- a/test/box/misc.test.lua
+++ b/test/box/misc.test.lua
@@ -202,3 +202,16 @@ type(ffi.metatype('struct test', {
 --# setopt delimiter ''
 -- custom totable function will be called by yaml.encode
 ffi.new('struct test', { a = 15 })
+
+
+
+-------------------------------------------------------------------------------
+-- #346 yaml.null() crases server
+-------------------------------------------------------------------------------
+
+yaml = require('yaml')
+type(yaml.NULL)
+yaml.NULL
+yaml.NULL == nil
+yaml.null() -- for compatibility with luaYAML
+yaml = nil
diff --git a/test/box/msgpack.result b/test/box/msgpack.result
index 8a3da18a46..34b33ed46b 100644
--- a/test/box/msgpack.result
+++ b/test/box/msgpack.result
@@ -286,6 +286,30 @@ test(nil)
 ---
 - nil ok
 ...
+type(msgpack.NULL)
+---
+- cdata
+...
+type(msgpackffi.NULL)
+---
+- cdata
+...
+msgpack.NULL == nil
+---
+- true
+...
+msgpackffi.NULL == nil
+---
+- true
+...
+test(msgpack.NULL)
+---
+- 'cdata<void *>: NULL ok'
+...
+test(msgpackffi.NULL)
+---
+- 'cdata<void *>: NULL ok'
+...
 test(ffi.cast('void *', 0))
 ---
 - 'cdata<void *>: NULL ok'
diff --git a/test/box/msgpack.test.lua b/test/box/msgpack.test.lua
index 34091278a7..7d97dcdc98 100644
--- a/test/box/msgpack.test.lua
+++ b/test/box/msgpack.test.lua
@@ -158,6 +158,12 @@ test(ffi.new('double', 12.121))
 --------------------------------------------------------------------------------
 
 test(nil)
+type(msgpack.NULL)
+type(msgpackffi.NULL)
+msgpack.NULL == nil
+msgpackffi.NULL == nil
+test(msgpack.NULL)
+test(msgpackffi.NULL)
 
 test(ffi.cast('void *', 0))
 
-- 
GitLab