immunio 0.15.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (157) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +234 -0
  3. data/README.md +147 -0
  4. data/bin/immunio +5 -0
  5. data/lib/immunio.rb +29 -0
  6. data/lib/immunio/agent.rb +260 -0
  7. data/lib/immunio/authentication.rb +96 -0
  8. data/lib/immunio/blocked_app.rb +38 -0
  9. data/lib/immunio/channel.rb +432 -0
  10. data/lib/immunio/cli.rb +39 -0
  11. data/lib/immunio/context.rb +114 -0
  12. data/lib/immunio/errors.rb +43 -0
  13. data/lib/immunio/immunio_ca.crt +45 -0
  14. data/lib/immunio/logger.rb +87 -0
  15. data/lib/immunio/plugins/action_dispatch.rb +45 -0
  16. data/lib/immunio/plugins/action_view.rb +431 -0
  17. data/lib/immunio/plugins/active_record.rb +707 -0
  18. data/lib/immunio/plugins/active_record_relation.rb +370 -0
  19. data/lib/immunio/plugins/authlogic.rb +80 -0
  20. data/lib/immunio/plugins/csrf.rb +24 -0
  21. data/lib/immunio/plugins/devise.rb +40 -0
  22. data/lib/immunio/plugins/environment_reporter.rb +69 -0
  23. data/lib/immunio/plugins/eval.rb +51 -0
  24. data/lib/immunio/plugins/exception_handler.rb +55 -0
  25. data/lib/immunio/plugins/gems_tracker.rb +5 -0
  26. data/lib/immunio/plugins/haml.rb +36 -0
  27. data/lib/immunio/plugins/http_finisher.rb +50 -0
  28. data/lib/immunio/plugins/http_tracker.rb +203 -0
  29. data/lib/immunio/plugins/io.rb +96 -0
  30. data/lib/immunio/plugins/redirect.rb +42 -0
  31. data/lib/immunio/plugins/warden.rb +66 -0
  32. data/lib/immunio/processor.rb +234 -0
  33. data/lib/immunio/rails.rb +26 -0
  34. data/lib/immunio/request.rb +139 -0
  35. data/lib/immunio/rufus_lua_ext/ref.rb +27 -0
  36. data/lib/immunio/rufus_lua_ext/state.rb +157 -0
  37. data/lib/immunio/rufus_lua_ext/table.rb +137 -0
  38. data/lib/immunio/rufus_lua_ext/utils.rb +13 -0
  39. data/lib/immunio/version.rb +5 -0
  40. data/lib/immunio/vm.rb +291 -0
  41. data/lua-hooks/ext/all.c +78 -0
  42. data/lua-hooks/ext/bitop/README +22 -0
  43. data/lua-hooks/ext/bitop/bit.c +189 -0
  44. data/lua-hooks/ext/extconf.rb +38 -0
  45. data/lua-hooks/ext/libinjection/COPYING +37 -0
  46. data/lua-hooks/ext/libinjection/libinjection.h +65 -0
  47. data/lua-hooks/ext/libinjection/libinjection_html5.c +847 -0
  48. data/lua-hooks/ext/libinjection/libinjection_html5.h +54 -0
  49. data/lua-hooks/ext/libinjection/libinjection_sqli.c +2301 -0
  50. data/lua-hooks/ext/libinjection/libinjection_sqli.h +295 -0
  51. data/lua-hooks/ext/libinjection/libinjection_sqli_data.h +9349 -0
  52. data/lua-hooks/ext/libinjection/libinjection_xss.c +531 -0
  53. data/lua-hooks/ext/libinjection/libinjection_xss.h +21 -0
  54. data/lua-hooks/ext/libinjection/lualib.c +109 -0
  55. data/lua-hooks/ext/lpeg/HISTORY +90 -0
  56. data/lua-hooks/ext/lpeg/lpcap.c +537 -0
  57. data/lua-hooks/ext/lpeg/lpcap.h +43 -0
  58. data/lua-hooks/ext/lpeg/lpcode.c +986 -0
  59. data/lua-hooks/ext/lpeg/lpcode.h +34 -0
  60. data/lua-hooks/ext/lpeg/lpeg-128.gif +0 -0
  61. data/lua-hooks/ext/lpeg/lpeg.html +1429 -0
  62. data/lua-hooks/ext/lpeg/lpprint.c +244 -0
  63. data/lua-hooks/ext/lpeg/lpprint.h +35 -0
  64. data/lua-hooks/ext/lpeg/lptree.c +1238 -0
  65. data/lua-hooks/ext/lpeg/lptree.h +77 -0
  66. data/lua-hooks/ext/lpeg/lptypes.h +149 -0
  67. data/lua-hooks/ext/lpeg/lpvm.c +355 -0
  68. data/lua-hooks/ext/lpeg/lpvm.h +58 -0
  69. data/lua-hooks/ext/lpeg/makefile +55 -0
  70. data/lua-hooks/ext/lpeg/re.html +498 -0
  71. data/lua-hooks/ext/lpeg/test.lua +1409 -0
  72. data/lua-hooks/ext/lua-cmsgpack/CMakeLists.txt +45 -0
  73. data/lua-hooks/ext/lua-cmsgpack/README.md +115 -0
  74. data/lua-hooks/ext/lua-cmsgpack/lua_cmsgpack.c +957 -0
  75. data/lua-hooks/ext/lua-cmsgpack/test.lua +570 -0
  76. data/lua-hooks/ext/lua-snapshot/LICENSE +7 -0
  77. data/lua-hooks/ext/lua-snapshot/Makefile +12 -0
  78. data/lua-hooks/ext/lua-snapshot/README.md +18 -0
  79. data/lua-hooks/ext/lua-snapshot/dump.lua +15 -0
  80. data/lua-hooks/ext/lua-snapshot/snapshot.c +455 -0
  81. data/lua-hooks/ext/lua/COPYRIGHT +34 -0
  82. data/lua-hooks/ext/lua/lapi.c +1087 -0
  83. data/lua-hooks/ext/lua/lapi.h +16 -0
  84. data/lua-hooks/ext/lua/lauxlib.c +652 -0
  85. data/lua-hooks/ext/lua/lauxlib.h +174 -0
  86. data/lua-hooks/ext/lua/lbaselib.c +659 -0
  87. data/lua-hooks/ext/lua/lcode.c +831 -0
  88. data/lua-hooks/ext/lua/lcode.h +76 -0
  89. data/lua-hooks/ext/lua/ldblib.c +398 -0
  90. data/lua-hooks/ext/lua/ldebug.c +638 -0
  91. data/lua-hooks/ext/lua/ldebug.h +33 -0
  92. data/lua-hooks/ext/lua/ldo.c +519 -0
  93. data/lua-hooks/ext/lua/ldo.h +57 -0
  94. data/lua-hooks/ext/lua/ldump.c +164 -0
  95. data/lua-hooks/ext/lua/lfunc.c +174 -0
  96. data/lua-hooks/ext/lua/lfunc.h +34 -0
  97. data/lua-hooks/ext/lua/lgc.c +710 -0
  98. data/lua-hooks/ext/lua/lgc.h +110 -0
  99. data/lua-hooks/ext/lua/linit.c +38 -0
  100. data/lua-hooks/ext/lua/liolib.c +556 -0
  101. data/lua-hooks/ext/lua/llex.c +463 -0
  102. data/lua-hooks/ext/lua/llex.h +81 -0
  103. data/lua-hooks/ext/lua/llimits.h +128 -0
  104. data/lua-hooks/ext/lua/lmathlib.c +263 -0
  105. data/lua-hooks/ext/lua/lmem.c +86 -0
  106. data/lua-hooks/ext/lua/lmem.h +49 -0
  107. data/lua-hooks/ext/lua/loadlib.c +705 -0
  108. data/lua-hooks/ext/lua/loadlib_rel.c +760 -0
  109. data/lua-hooks/ext/lua/lobject.c +214 -0
  110. data/lua-hooks/ext/lua/lobject.h +381 -0
  111. data/lua-hooks/ext/lua/lopcodes.c +102 -0
  112. data/lua-hooks/ext/lua/lopcodes.h +268 -0
  113. data/lua-hooks/ext/lua/loslib.c +243 -0
  114. data/lua-hooks/ext/lua/lparser.c +1339 -0
  115. data/lua-hooks/ext/lua/lparser.h +82 -0
  116. data/lua-hooks/ext/lua/lstate.c +214 -0
  117. data/lua-hooks/ext/lua/lstate.h +169 -0
  118. data/lua-hooks/ext/lua/lstring.c +111 -0
  119. data/lua-hooks/ext/lua/lstring.h +31 -0
  120. data/lua-hooks/ext/lua/lstrlib.c +871 -0
  121. data/lua-hooks/ext/lua/ltable.c +588 -0
  122. data/lua-hooks/ext/lua/ltable.h +40 -0
  123. data/lua-hooks/ext/lua/ltablib.c +287 -0
  124. data/lua-hooks/ext/lua/ltm.c +75 -0
  125. data/lua-hooks/ext/lua/ltm.h +54 -0
  126. data/lua-hooks/ext/lua/lua.c +392 -0
  127. data/lua-hooks/ext/lua/lua.def +131 -0
  128. data/lua-hooks/ext/lua/lua.h +388 -0
  129. data/lua-hooks/ext/lua/lua.rc +28 -0
  130. data/lua-hooks/ext/lua/lua_dll.rc +26 -0
  131. data/lua-hooks/ext/lua/luac.c +200 -0
  132. data/lua-hooks/ext/lua/luac.rc +1 -0
  133. data/lua-hooks/ext/lua/luaconf.h +763 -0
  134. data/lua-hooks/ext/lua/luaconf.h.in +724 -0
  135. data/lua-hooks/ext/lua/luaconf.h.orig +763 -0
  136. data/lua-hooks/ext/lua/lualib.h +53 -0
  137. data/lua-hooks/ext/lua/lundump.c +227 -0
  138. data/lua-hooks/ext/lua/lundump.h +36 -0
  139. data/lua-hooks/ext/lua/lvm.c +767 -0
  140. data/lua-hooks/ext/lua/lvm.h +36 -0
  141. data/lua-hooks/ext/lua/lzio.c +82 -0
  142. data/lua-hooks/ext/lua/lzio.h +67 -0
  143. data/lua-hooks/ext/lua/print.c +227 -0
  144. data/lua-hooks/ext/luautf8/README.md +152 -0
  145. data/lua-hooks/ext/luautf8/lutf8lib.c +1274 -0
  146. data/lua-hooks/ext/luautf8/unidata.h +3064 -0
  147. data/lua-hooks/lib/boot.lua +254 -0
  148. data/lua-hooks/lib/encode.lua +4 -0
  149. data/lua-hooks/lib/lexers/LICENSE +21 -0
  150. data/lua-hooks/lib/lexers/bash.lua +134 -0
  151. data/lua-hooks/lib/lexers/bash_dqstr.lua +62 -0
  152. data/lua-hooks/lib/lexers/css.lua +216 -0
  153. data/lua-hooks/lib/lexers/html.lua +106 -0
  154. data/lua-hooks/lib/lexers/javascript.lua +68 -0
  155. data/lua-hooks/lib/lexers/lexer.lua +1575 -0
  156. data/lua-hooks/lib/lexers/markers.lua +33 -0
  157. metadata +308 -0
@@ -0,0 +1,45 @@
1
+ # If Lua is installed in a non-standard location, please set the LUA_DIR
2
+ # environment variable to point to prefix for the install. Eg:
3
+ # Unix: export LUA_DIR=/home/user/pkg
4
+ # Windows: set LUA_DIR=c:\lua51
5
+
6
+ project(lua-cmsgpack C)
7
+ cmake_minimum_required(VERSION 2.6)
8
+
9
+ if(NOT CMAKE_BUILD_TYPE)
10
+ set(CMAKE_BUILD_TYPE Release CACHE STRING
11
+ "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel."
12
+ FORCE)
13
+ endif()
14
+
15
+ find_package(Lua51 REQUIRED)
16
+ include_directories(${LUA_INCLUDE_DIR})
17
+
18
+ if(APPLE)
19
+ set(CMAKE_SHARED_MODULE_CREATE_C_FLAGS
20
+ "${CMAKE_SHARED_MODULE_CREATE_C_FLAGS} -undefined dynamic_lookup")
21
+ endif()
22
+
23
+ if(WIN32)
24
+ # Win32 modules need to be linked to the Lua library.
25
+ set(_MODULE_LINK ${LUA_LIBRARY} ${_MODULE_LINK})
26
+ set(_lua_module_dir "${_lua_lib_dir}")
27
+ else()
28
+ set(_lua_module_dir "${_lua_lib_dir}/lua/5.1")
29
+ endif()
30
+
31
+ option(Build32Bit "Build 32-bit Library" OFF)
32
+
33
+ set(CMAKE_C_FLAGS "-O2 -g -ggdb -Wall -pedantic -std=c99")
34
+ add_library(cmsgpack MODULE lua_cmsgpack.c)
35
+ set_target_properties(cmsgpack PROPERTIES PREFIX "")
36
+
37
+ if(Build32Bit)
38
+ set_target_properties(cmsgpack
39
+ PROPERTIES COMPILE_FLAGS "-m32" LINK_FLAGS "-m32")
40
+ endif()
41
+
42
+ target_link_libraries(cmsgpack ${_MODULE_LINK})
43
+ install(TARGETS cmsgpack DESTINATION "${_lua_module_dir}")
44
+
45
+ # vi:ai et sw=4 ts=4:
@@ -0,0 +1,115 @@
1
+ README for lua-cmsgpack.c
2
+ ===
3
+
4
+ Lua-cmsgpack is a [MessagePack](http://msgpack.org) implementation and bindings for
5
+ Lua 5.1/5.2/5.3 in a self contained C file without external dependencies.
6
+
7
+ This library is open source software licensed under the BSD two-clause license.
8
+
9
+ INSTALLATION
10
+ ---
11
+
12
+ Using LuaRocks (http://luarocks.org):
13
+
14
+ * Install current stable release:
15
+
16
+ sudo luarocks install lua-cmsgpack
17
+
18
+ * Install current Git master head from GitHub:
19
+
20
+ sudo luarocks install lua-cmsgpack --from=rocks-cvs
21
+
22
+ * Install from current working copy
23
+
24
+ cd lua-cmsgpack/
25
+ sudo luarocks make rockspec/lua-cmsgpack-scm-1.rockspec
26
+
27
+ If you embed Lua and all modules into your C project, just add the
28
+ `lua_cmsgpack.c` file and call the following function after creating the Lua
29
+ interpreter:
30
+
31
+ luaopen_cmsgpack(L);
32
+
33
+ USAGE
34
+ ---
35
+
36
+ The exported API is very simple, consisting of four functions:
37
+
38
+ Basic API:
39
+
40
+ msgpack = cmsgpack.pack(lua_object1, lua_object2, ..., lua_objectN)
41
+ lua_object1, lua_object2, ..., lua_objectN = cmsgpack.unpack(msgpack)
42
+
43
+ Detailed API giving you more control over unpacking multiple values:
44
+
45
+ resume_offset, lua_object1 = cmsgpack.unpack_one(msgpack)
46
+ resume_offset1, lua_object2 = cmsgpack.unpack_one(msgpack, resume_offset)
47
+ ...
48
+ -1, lua_objectN = cmsgpack.unpack_one(msgpack, resume_offset_previous)
49
+
50
+ resume_offset, lua_object1, lua_object2 = cmsgpack.unpack_limit(msgpack, 2)
51
+ resume_offset2, lua_object3 = cmsgpack.unpack_limit(msgpack, 1, resume_offset1)
52
+
53
+ Functions:
54
+
55
+ - `pack(arg1, arg2, ..., argn)` - pack any number of lua objects into one msgpack stream. returns: msgpack
56
+ - `unpack(msgpack)` - unpack all objects in msgpack to individual return values. returns: object1, object2, ..., objectN
57
+ - `unpack_one(msgpack); unpack_one(msgpack, offset)` - unpacks the first object after offset. returns: offset, object
58
+ - `unpack_limit(msgpack, limit); unpack_limit(msgpack, limit, offset)` - unpacks the first `limit` objects and returns: offset, object1, objet2, ..., objectN (up to limit, but may return fewer than limit if not that many objects remain to be unpacked)
59
+
60
+ When you reach the end of your input stream with `unpack_one` or `unpack_limit`, an offset of `-1` is returned.
61
+
62
+ You may `require "msgpack"` or you may `require "msgpack.safe"`. The safe version returns errors as (nil, errstring).
63
+
64
+ However because of the nature of Lua numerical and table type a few behavior
65
+ of the library must be well understood to avoid problems:
66
+
67
+ * A table is converted into a MessagePack array type only if *all* the keys are
68
+ composed of incrementing integers starting at 1 end ending at N, without holes,
69
+ without additional non numerical keys. All the other tables are converted into
70
+ maps.
71
+ * An empty table is always converted into a MessagePack array, the rationale is that empty lists are much more common than empty maps (usually used to represent objects with fields).
72
+ * A Lua number is converted into an integer type if floor(number) == number, otherwise it is converted into the MessagePack float or double value.
73
+ * When a Lua number is converted to float or double, the former is preferred if there is no loss of precision compared to the double representation.
74
+ * When a MessagePack big integer (64 bit) is converted to a Lua number it is possible that the resulting number will not represent the original number but just an approximation. This is unavoidable because the Lua numerical type is usually a double precision floating point type.
75
+
76
+ TESTING
77
+ ---
78
+
79
+ Build and test:
80
+
81
+ mkdir build; cd build
82
+ cmake ..
83
+ make
84
+ lua ../test.lua
85
+
86
+ You can build a 32-bit module on a 64-bit platform with:
87
+
88
+ mkdir build; cd build
89
+ cmake -DBuild32Bit=ON ..
90
+ make
91
+ lua ../test.lua
92
+
93
+ NESTED TABLES
94
+ ---
95
+ Nested tables are handled correctly up to `LUACMSGPACK_MAX_NESTING` levels of
96
+ nesting (that is set to 16 by default).
97
+ Every table that is nested at a greater level than the maxium is encoded
98
+ as MessagePack nil value.
99
+
100
+ It is worth to note that in Lua it is possible to create tables that mutually
101
+ refer to each other, creating a cycle. For example:
102
+
103
+ a = {x=nil,y=5}
104
+ b = {x=a}
105
+ a['x'] = b
106
+
107
+ This condition will simply make the encoder reach the max level of nesting,
108
+ thus avoiding an infinite loop.
109
+
110
+ CREDITS
111
+ ---
112
+
113
+ This library was written by Salvatore Sanfilippo for Redis, but is maintained as a separated project by the author.
114
+
115
+ Some of the test vectors in "test.lua" are obtained from the Javascript [MessagePack-JS library](https://github.com/cuzic/MessagePack-JS).
@@ -0,0 +1,957 @@
1
+ #include <math.h>
2
+ #include <stdlib.h>
3
+ #include <stdint.h>
4
+ #include <string.h>
5
+ #include <assert.h>
6
+
7
+ #include "lua/lua.h"
8
+ #include "lua/lauxlib.h"
9
+
10
+ #define LUACMSGPACK_NAME "cmsgpack"
11
+ #define LUACMSGPACK_SAFE_NAME "cmsgpack_safe"
12
+ #define LUACMSGPACK_VERSION "lua-cmsgpack 0.4.0"
13
+ #define LUACMSGPACK_COPYRIGHT "Copyright (C) 2012, Salvatore Sanfilippo"
14
+ #define LUACMSGPACK_DESCRIPTION "MessagePack C implementation for Lua"
15
+
16
+ /* Allows a preprocessor directive to override MAX_NESTING */
17
+ #ifndef LUACMSGPACK_MAX_NESTING
18
+ #define LUACMSGPACK_MAX_NESTING 16 /* Max tables nesting. */
19
+ #endif
20
+
21
+ /* Check if float or double can be an integer without loss of precision */
22
+ #define IS_INT_TYPE_EQUIVALENT(x, T) (!isinf(x) && (T)(x) == (x))
23
+
24
+ #define IS_INT64_EQUIVALENT(x) IS_INT_TYPE_EQUIVALENT(x, int64_t)
25
+ #define IS_INT_EQUIVALENT(x) IS_INT_TYPE_EQUIVALENT(x, int)
26
+
27
+ /* If size of pointer is equal to a 4 byte integer, we're on 32 bits. */
28
+ #if UINTPTR_MAX == UINT_MAX
29
+ #define BITS_32 1
30
+ #else
31
+ #define BITS_32 0
32
+ #endif
33
+
34
+ #if BITS_32
35
+ #define lua_pushunsigned(L, n) lua_pushnumber(L, n)
36
+ #else
37
+ #define lua_pushunsigned(L, n) lua_pushinteger(L, n)
38
+ #endif
39
+
40
+ /* =============================================================================
41
+ * MessagePack implementation and bindings for Lua 5.1/5.2.
42
+ * Copyright(C) 2012 Salvatore Sanfilippo <antirez@gmail.com>
43
+ *
44
+ * http://github.com/antirez/lua-cmsgpack
45
+ *
46
+ * For MessagePack specification check the following web site:
47
+ * http://wiki.msgpack.org/display/MSGPACK/Format+specification
48
+ *
49
+ * See Copyright Notice at the end of this file.
50
+ *
51
+ * CHANGELOG:
52
+ * 19-Feb-2012 (ver 0.1.0): Initial release.
53
+ * 20-Feb-2012 (ver 0.2.0): Tables encoding improved.
54
+ * 20-Feb-2012 (ver 0.2.1): Minor bug fixing.
55
+ * 20-Feb-2012 (ver 0.3.0): Module renamed lua-cmsgpack (was lua-msgpack).
56
+ * 04-Apr-2014 (ver 0.3.1): Lua 5.2 support and minor bug fix.
57
+ * 07-Apr-2014 (ver 0.4.0): Multiple pack/unpack, lua allocator, efficiency.
58
+ * ========================================================================== */
59
+
60
+ /* -------------------------- Endian conversion --------------------------------
61
+ * We use it only for floats and doubles, all the other conversions performed
62
+ * in an endian independent fashion. So the only thing we need is a function
63
+ * that swaps a binary string if arch is little endian (and left it untouched
64
+ * otherwise). */
65
+
66
+ /* Reverse memory bytes if arch is little endian. Given the conceptual
67
+ * simplicity of the Lua build system we prefer check for endianess at runtime.
68
+ * The performance difference should be acceptable. */
69
+ void memrevifle(void *ptr, size_t len) {
70
+ unsigned char *p = (unsigned char *)ptr,
71
+ *e = (unsigned char *)p+len-1,
72
+ aux;
73
+ int test = 1;
74
+ unsigned char *testp = (unsigned char*) &test;
75
+
76
+ if (testp[0] == 0) return; /* Big endian, nothing to do. */
77
+ len /= 2;
78
+ while(len--) {
79
+ aux = *p;
80
+ *p = *e;
81
+ *e = aux;
82
+ p++;
83
+ e--;
84
+ }
85
+ }
86
+
87
+ /* ---------------------------- String buffer ----------------------------------
88
+ * This is a simple implementation of string buffers. The only operation
89
+ * supported is creating empty buffers and appending bytes to it.
90
+ * The string buffer uses 2x preallocation on every realloc for O(N) append
91
+ * behavior. */
92
+
93
+ typedef struct mp_buf {
94
+ lua_State *L;
95
+ unsigned char *b;
96
+ size_t len, free;
97
+ } mp_buf;
98
+
99
+ void *mp_realloc(lua_State *L, void *target, size_t osize,size_t nsize) {
100
+ void *(*local_realloc) (void *, void *, size_t osize, size_t nsize) = NULL;
101
+ void *ud;
102
+
103
+ local_realloc = lua_getallocf(L, &ud);
104
+
105
+ return local_realloc(ud, target, osize, nsize);
106
+ }
107
+
108
+ mp_buf *mp_buf_new(lua_State *L) {
109
+ mp_buf *buf = NULL;
110
+
111
+ /* Old size = 0; new size = sizeof(*buf) */
112
+ buf = (mp_buf*)mp_realloc(L, NULL, 0, sizeof(*buf));
113
+
114
+ buf->L = L;
115
+ buf->b = NULL;
116
+ buf->len = buf->free = 0;
117
+ return buf;
118
+ }
119
+
120
+ void mp_buf_append(mp_buf *buf, const unsigned char *s, size_t len) {
121
+ if (buf->free < len) {
122
+ size_t newlen = buf->len+len;
123
+
124
+ buf->b = (unsigned char*)mp_realloc(buf->L, buf->b, buf->len, newlen*2);
125
+ buf->free = newlen;
126
+ }
127
+ memcpy(buf->b+buf->len,s,len);
128
+ buf->len += len;
129
+ buf->free -= len;
130
+ }
131
+
132
+ void mp_buf_free(mp_buf *buf) {
133
+ mp_realloc(buf->L, buf->b, buf->len, 0); /* realloc to 0 = free */
134
+ mp_realloc(buf->L, buf, sizeof(*buf), 0);
135
+ }
136
+
137
+ /* ---------------------------- String cursor ----------------------------------
138
+ * This simple data structure is used for parsing. Basically you create a cursor
139
+ * using a string pointer and a length, then it is possible to access the
140
+ * current string position with cursor->p, check the remaining length
141
+ * in cursor->left, and finally consume more string using
142
+ * mp_cur_consume(cursor,len), to advance 'p' and subtract 'left'.
143
+ * An additional field cursor->error is set to zero on initialization and can
144
+ * be used to report errors. */
145
+
146
+ #define MP_CUR_ERROR_NONE 0
147
+ #define MP_CUR_ERROR_EOF 1 /* Not enough data to complete operation. */
148
+ #define MP_CUR_ERROR_BADFMT 2 /* Bad data format */
149
+
150
+ typedef struct mp_cur {
151
+ const unsigned char *p;
152
+ size_t left;
153
+ int err;
154
+ } mp_cur;
155
+
156
+ void mp_cur_init(mp_cur *cursor, const unsigned char *s, size_t len) {
157
+ cursor->p = s;
158
+ cursor->left = len;
159
+ cursor->err = MP_CUR_ERROR_NONE;
160
+ }
161
+
162
+ #define mp_cur_consume(_c,_len) do { _c->p += _len; _c->left -= _len; } while(0)
163
+
164
+ /* When there is not enough room we set an error in the cursor and return. This
165
+ * is very common across the code so we have a macro to make the code look
166
+ * a bit simpler. */
167
+ #define mp_cur_need(_c,_len) do { \
168
+ if (_c->left < _len) { \
169
+ _c->err = MP_CUR_ERROR_EOF; \
170
+ return; \
171
+ } \
172
+ } while(0)
173
+
174
+ /* ------------------------- Low level MP encoding -------------------------- */
175
+
176
+ void mp_encode_bytes(mp_buf *buf, const unsigned char *s, size_t len) {
177
+ unsigned char hdr[5];
178
+ int hdrlen;
179
+
180
+ if (len < 32) {
181
+ hdr[0] = 0xa0 | (len&0xff); /* fix raw */
182
+ hdrlen = 1;
183
+ } else if (len <= 0xffff) {
184
+ hdr[0] = 0xda;
185
+ hdr[1] = (len&0xff00)>>8;
186
+ hdr[2] = len&0xff;
187
+ hdrlen = 3;
188
+ } else {
189
+ hdr[0] = 0xdb;
190
+ hdr[1] = (len&0xff000000)>>24;
191
+ hdr[2] = (len&0xff0000)>>16;
192
+ hdr[3] = (len&0xff00)>>8;
193
+ hdr[4] = len&0xff;
194
+ hdrlen = 5;
195
+ }
196
+ mp_buf_append(buf,hdr,hdrlen);
197
+ mp_buf_append(buf,s,len);
198
+ }
199
+
200
+ /* we assume IEEE 754 internal format for single and double precision floats. */
201
+ void mp_encode_double(mp_buf *buf, double d) {
202
+ unsigned char b[9];
203
+ float f = d;
204
+
205
+ assert(sizeof(f) == 4 && sizeof(d) == 8);
206
+ if (d == (double)f) {
207
+ b[0] = 0xca; /* float IEEE 754 */
208
+ memcpy(b+1,&f,4);
209
+ memrevifle(b+1,4);
210
+ mp_buf_append(buf,b,5);
211
+ } else if (sizeof(d) == 8) {
212
+ b[0] = 0xcb; /* double IEEE 754 */
213
+ memcpy(b+1,&d,8);
214
+ memrevifle(b+1,8);
215
+ mp_buf_append(buf,b,9);
216
+ }
217
+ }
218
+
219
+ void mp_encode_int(mp_buf *buf, int64_t n) {
220
+ unsigned char b[9];
221
+ int enclen;
222
+
223
+ if (n >= 0) {
224
+ if (n <= 127) {
225
+ b[0] = n & 0x7f; /* positive fixnum */
226
+ enclen = 1;
227
+ } else if (n <= 0xff) {
228
+ b[0] = 0xcc; /* uint 8 */
229
+ b[1] = n & 0xff;
230
+ enclen = 2;
231
+ } else if (n <= 0xffff) {
232
+ b[0] = 0xcd; /* uint 16 */
233
+ b[1] = (n & 0xff00) >> 8;
234
+ b[2] = n & 0xff;
235
+ enclen = 3;
236
+ } else if (n <= 0xffffffffLL) {
237
+ b[0] = 0xce; /* uint 32 */
238
+ b[1] = (n & 0xff000000) >> 24;
239
+ b[2] = (n & 0xff0000) >> 16;
240
+ b[3] = (n & 0xff00) >> 8;
241
+ b[4] = n & 0xff;
242
+ enclen = 5;
243
+ } else {
244
+ b[0] = 0xcf; /* uint 64 */
245
+ b[1] = (n & 0xff00000000000000LL) >> 56;
246
+ b[2] = (n & 0xff000000000000LL) >> 48;
247
+ b[3] = (n & 0xff0000000000LL) >> 40;
248
+ b[4] = (n & 0xff00000000LL) >> 32;
249
+ b[5] = (n & 0xff000000) >> 24;
250
+ b[6] = (n & 0xff0000) >> 16;
251
+ b[7] = (n & 0xff00) >> 8;
252
+ b[8] = n & 0xff;
253
+ enclen = 9;
254
+ }
255
+ } else {
256
+ if (n >= -32) {
257
+ b[0] = ((signed char)n); /* negative fixnum */
258
+ enclen = 1;
259
+ } else if (n >= -128) {
260
+ b[0] = 0xd0; /* int 8 */
261
+ b[1] = n & 0xff;
262
+ enclen = 2;
263
+ } else if (n >= -32768) {
264
+ b[0] = 0xd1; /* int 16 */
265
+ b[1] = (n & 0xff00) >> 8;
266
+ b[2] = n & 0xff;
267
+ enclen = 3;
268
+ } else if (n >= -2147483648LL) {
269
+ b[0] = 0xd2; /* int 32 */
270
+ b[1] = (n & 0xff000000) >> 24;
271
+ b[2] = (n & 0xff0000) >> 16;
272
+ b[3] = (n & 0xff00) >> 8;
273
+ b[4] = n & 0xff;
274
+ enclen = 5;
275
+ } else {
276
+ b[0] = 0xd3; /* int 64 */
277
+ b[1] = (n & 0xff00000000000000LL) >> 56;
278
+ b[2] = (n & 0xff000000000000LL) >> 48;
279
+ b[3] = (n & 0xff0000000000LL) >> 40;
280
+ b[4] = (n & 0xff00000000LL) >> 32;
281
+ b[5] = (n & 0xff000000) >> 24;
282
+ b[6] = (n & 0xff0000) >> 16;
283
+ b[7] = (n & 0xff00) >> 8;
284
+ b[8] = n & 0xff;
285
+ enclen = 9;
286
+ }
287
+ }
288
+ mp_buf_append(buf,b,enclen);
289
+ }
290
+
291
+ void mp_encode_array(mp_buf *buf, int64_t n) {
292
+ unsigned char b[5];
293
+ int enclen;
294
+
295
+ if (n <= 15) {
296
+ b[0] = 0x90 | (n & 0xf); /* fix array */
297
+ enclen = 1;
298
+ } else if (n <= 65535) {
299
+ b[0] = 0xdc; /* array 16 */
300
+ b[1] = (n & 0xff00) >> 8;
301
+ b[2] = n & 0xff;
302
+ enclen = 3;
303
+ } else {
304
+ b[0] = 0xdd; /* array 32 */
305
+ b[1] = (n & 0xff000000) >> 24;
306
+ b[2] = (n & 0xff0000) >> 16;
307
+ b[3] = (n & 0xff00) >> 8;
308
+ b[4] = n & 0xff;
309
+ enclen = 5;
310
+ }
311
+ mp_buf_append(buf,b,enclen);
312
+ }
313
+
314
+ void mp_encode_map(mp_buf *buf, int64_t n) {
315
+ unsigned char b[5];
316
+ int enclen;
317
+
318
+ if (n <= 15) {
319
+ b[0] = 0x80 | (n & 0xf); /* fix map */
320
+ enclen = 1;
321
+ } else if (n <= 65535) {
322
+ b[0] = 0xde; /* map 16 */
323
+ b[1] = (n & 0xff00) >> 8;
324
+ b[2] = n & 0xff;
325
+ enclen = 3;
326
+ } else {
327
+ b[0] = 0xdf; /* map 32 */
328
+ b[1] = (n & 0xff000000) >> 24;
329
+ b[2] = (n & 0xff0000) >> 16;
330
+ b[3] = (n & 0xff00) >> 8;
331
+ b[4] = n & 0xff;
332
+ enclen = 5;
333
+ }
334
+ mp_buf_append(buf,b,enclen);
335
+ }
336
+
337
+ /* --------------------------- Lua types encoding --------------------------- */
338
+
339
+ void mp_encode_lua_string(lua_State *L, mp_buf *buf) {
340
+ size_t len;
341
+ const char *s;
342
+
343
+ s = lua_tolstring(L,-1,&len);
344
+ mp_encode_bytes(buf,(const unsigned char*)s,len);
345
+ }
346
+
347
+ void mp_encode_lua_bool(lua_State *L, mp_buf *buf) {
348
+ unsigned char b = lua_toboolean(L,-1) ? 0xc3 : 0xc2;
349
+ mp_buf_append(buf,&b,1);
350
+ }
351
+
352
+ /* Lua 5.3 has a built in 64-bit integer type */
353
+ void mp_encode_lua_integer(lua_State *L, mp_buf *buf) {
354
+ #if (LUA_VERSION_NUM < 503) && BITS_32
355
+ lua_Number i = lua_tonumber(L,-1);
356
+ #else
357
+ lua_Integer i = lua_tointeger(L,-1);
358
+ #endif
359
+ mp_encode_int(buf, (int64_t)i);
360
+ }
361
+
362
+ /* Lua 5.2 and lower only has 64-bit doubles, so we need to
363
+ * detect if the double may be representable as an int
364
+ * for Lua < 5.3 */
365
+ void mp_encode_lua_number(lua_State *L, mp_buf *buf) {
366
+ lua_Number n = lua_tonumber(L,-1);
367
+
368
+ if (IS_INT64_EQUIVALENT(n)) {
369
+ mp_encode_lua_integer(L, buf);
370
+ } else {
371
+ mp_encode_double(buf,(double)n);
372
+ }
373
+ }
374
+
375
+ void mp_encode_lua_type(lua_State *L, mp_buf *buf, int level);
376
+
377
+ /* Convert a lua table into a message pack list. */
378
+ void mp_encode_lua_table_as_array(lua_State *L, mp_buf *buf, int level) {
379
+ #if LUA_VERSION_NUM < 502
380
+ size_t len = lua_objlen(L,-1), j;
381
+ #else
382
+ size_t len = lua_rawlen(L,-1), j;
383
+ #endif
384
+
385
+ mp_encode_array(buf,len);
386
+ for (j = 1; j <= len; j++) {
387
+ lua_pushnumber(L,j);
388
+ lua_gettable(L,-2);
389
+ mp_encode_lua_type(L,buf,level+1);
390
+ }
391
+ }
392
+
393
+ /* Convert a lua table into a message pack key-value map. */
394
+ void mp_encode_lua_table_as_map(lua_State *L, mp_buf *buf, int level) {
395
+ size_t len = 0;
396
+
397
+ /* First step: count keys into table. No other way to do it with the
398
+ * Lua API, we need to iterate a first time. Note that an alternative
399
+ * would be to do a single run, and then hack the buffer to insert the
400
+ * map opcodes for message pack. Too hackish for this lib. */
401
+ lua_pushnil(L);
402
+ while(lua_next(L,-2)) {
403
+ lua_pop(L,1); /* remove value, keep key for next iteration. */
404
+ len++;
405
+ }
406
+
407
+ /* Step two: actually encoding of the map. */
408
+ mp_encode_map(buf,len);
409
+ lua_pushnil(L);
410
+ while(lua_next(L,-2)) {
411
+ /* Stack: ... key value */
412
+ lua_pushvalue(L,-2); /* Stack: ... key value key */
413
+ mp_encode_lua_type(L,buf,level+1); /* encode key */
414
+ mp_encode_lua_type(L,buf,level+1); /* encode val */
415
+ }
416
+ }
417
+
418
+ /* Returns true if the Lua table on top of the stack is exclusively composed
419
+ * of keys from numerical keys from 1 up to N, with N being the total number
420
+ * of elements, without any hole in the middle. */
421
+ int table_is_an_array(lua_State *L) {
422
+ int count = 0, max = 0;
423
+ #if LUA_VERSION_NUM < 503
424
+ lua_Number n;
425
+ #else
426
+ lua_Integer n;
427
+ #endif
428
+
429
+ /* Stack top on function entry */
430
+ int stacktop;
431
+
432
+ stacktop = lua_gettop(L);
433
+
434
+ lua_pushnil(L);
435
+ while(lua_next(L,-2)) {
436
+ /* Stack: ... key value */
437
+ lua_pop(L,1); /* Stack: ... key */
438
+ /* The <= 0 check is valid here because we're comparing indexes. */
439
+ #if LUA_VERSION_NUM < 503
440
+ if ((LUA_TNUMBER != lua_type(L,-1)) || (n = lua_tonumber(L, -1)) <= 0 ||
441
+ !IS_INT_EQUIVALENT(n))
442
+ #else
443
+ if (!lua_isinteger(L,-1) || (n = lua_tointeger(L, -1)) <= 0)
444
+ #endif
445
+ {
446
+ lua_settop(L, stacktop);
447
+ return 0;
448
+ }
449
+ max = (n > max ? n : max);
450
+ count++;
451
+ }
452
+ /* We have the total number of elements in "count". Also we have
453
+ * the max index encountered in "max". We can't reach this code
454
+ * if there are indexes <= 0. If you also note that there can not be
455
+ * repeated keys into a table, you have that if max==count you are sure
456
+ * that there are all the keys form 1 to count (both included). */
457
+ lua_settop(L, stacktop);
458
+ return max == count;
459
+ }
460
+
461
+ /* If the length operator returns non-zero, that is, there is at least
462
+ * an object at key '1', we serialize to message pack list. Otherwise
463
+ * we use a map. */
464
+ void mp_encode_lua_table(lua_State *L, mp_buf *buf, int level) {
465
+ if (table_is_an_array(L))
466
+ mp_encode_lua_table_as_array(L,buf,level);
467
+ else
468
+ mp_encode_lua_table_as_map(L,buf,level);
469
+ }
470
+
471
+ void mp_encode_lua_null(lua_State *L, mp_buf *buf) {
472
+ unsigned char b[1];
473
+ (void)L;
474
+
475
+ b[0] = 0xc0;
476
+ mp_buf_append(buf,b,1);
477
+ }
478
+
479
+ void mp_encode_lua_type(lua_State *L, mp_buf *buf, int level) {
480
+ int t = lua_type(L,-1);
481
+
482
+ /* Limit the encoding of nested tables to a specified maximum depth, so that
483
+ * we survive when called against circular references in tables. */
484
+ if (t == LUA_TTABLE && level == LUACMSGPACK_MAX_NESTING) t = LUA_TNIL;
485
+ switch(t) {
486
+ case LUA_TSTRING: mp_encode_lua_string(L,buf); break;
487
+ case LUA_TBOOLEAN: mp_encode_lua_bool(L,buf); break;
488
+ case LUA_TNUMBER:
489
+ #if LUA_VERSION_NUM < 503
490
+ mp_encode_lua_number(L,buf); break;
491
+ #else
492
+ if (lua_isinteger(L, -1)) {
493
+ mp_encode_lua_integer(L, buf);
494
+ } else {
495
+ mp_encode_lua_number(L, buf);
496
+ }
497
+ break;
498
+ #endif
499
+ case LUA_TTABLE: mp_encode_lua_table(L,buf,level); break;
500
+ default: mp_encode_lua_null(L,buf); break;
501
+ }
502
+ lua_pop(L,1);
503
+ }
504
+
505
+ /*
506
+ * Packs all arguments as a stream for multiple upacking later.
507
+ * Returns error if no arguments provided.
508
+ */
509
+ int mp_pack(lua_State *L) {
510
+ int nargs = lua_gettop(L);
511
+ int i;
512
+ mp_buf *buf;
513
+
514
+ if (nargs == 0)
515
+ return luaL_argerror(L, 0, "MessagePack pack needs input.");
516
+
517
+ buf = mp_buf_new(L);
518
+ for(i = 1; i <= nargs; i++) {
519
+ /* Copy argument i to top of stack for _encode processing;
520
+ * the encode function pops it from the stack when complete. */
521
+ lua_pushvalue(L, i);
522
+
523
+ mp_encode_lua_type(L,buf,0);
524
+
525
+ lua_pushlstring(L,(char*)buf->b,buf->len);
526
+
527
+ /* Reuse the buffer for the next operation by
528
+ * setting its free count to the total buffer size
529
+ * and the current position to zero. */
530
+ buf->free += buf->len;
531
+ buf->len = 0;
532
+ }
533
+ mp_buf_free(buf);
534
+
535
+ /* Concatenate all nargs buffers together */
536
+ lua_concat(L, nargs);
537
+ return 1;
538
+ }
539
+
540
+ /* ------------------------------- Decoding --------------------------------- */
541
+
542
+ void mp_decode_to_lua_type(lua_State *L, mp_cur *c);
543
+
544
+ void mp_decode_to_lua_array(lua_State *L, mp_cur *c, size_t len) {
545
+ assert(len <= UINT_MAX);
546
+ int index = 1;
547
+
548
+ lua_newtable(L);
549
+ while(len--) {
550
+ lua_pushnumber(L,index++);
551
+ mp_decode_to_lua_type(L,c);
552
+ if (c->err) return;
553
+ lua_settable(L,-3);
554
+ }
555
+ }
556
+
557
+ void mp_decode_to_lua_hash(lua_State *L, mp_cur *c, size_t len) {
558
+ assert(len <= UINT_MAX);
559
+ lua_newtable(L);
560
+ while(len--) {
561
+ mp_decode_to_lua_type(L,c); /* key */
562
+ if (c->err) return;
563
+ mp_decode_to_lua_type(L,c); /* value */
564
+ if (c->err) return;
565
+ lua_settable(L,-3);
566
+ }
567
+ }
568
+
569
+ /* Decode a Message Pack raw object pointed by the string cursor 'c' to
570
+ * a Lua type, that is left as the only result on the stack. */
571
+ void mp_decode_to_lua_type(lua_State *L, mp_cur *c) {
572
+ mp_cur_need(c,1);
573
+
574
+ /* If we return more than 18 elements, we must resize the stack to
575
+ * fit all our return values. But, there is no way to
576
+ * determine how many objects a msgpack will unpack to up front, so
577
+ * we request a +1 larger stack on each iteration (noop if stack is
578
+ * big enough, and when stack does require resize it doubles in size) */
579
+ luaL_checkstack(L, 1,
580
+ "too many return values at once; "
581
+ "use unpack_one or unpack_limit instead.");
582
+
583
+ switch(c->p[0]) {
584
+ case 0xcc: /* uint 8 */
585
+ mp_cur_need(c,2);
586
+ lua_pushunsigned(L,c->p[1]);
587
+ mp_cur_consume(c,2);
588
+ break;
589
+ case 0xd0: /* int 8 */
590
+ mp_cur_need(c,2);
591
+ lua_pushinteger(L,(signed char)c->p[1]);
592
+ mp_cur_consume(c,2);
593
+ break;
594
+ case 0xcd: /* uint 16 */
595
+ mp_cur_need(c,3);
596
+ lua_pushunsigned(L,
597
+ (c->p[1] << 8) |
598
+ c->p[2]);
599
+ mp_cur_consume(c,3);
600
+ break;
601
+ case 0xd1: /* int 16 */
602
+ mp_cur_need(c,3);
603
+ lua_pushinteger(L,(int16_t)
604
+ (c->p[1] << 8) |
605
+ c->p[2]);
606
+ mp_cur_consume(c,3);
607
+ break;
608
+ case 0xce: /* uint 32 */
609
+ mp_cur_need(c,5);
610
+ lua_pushunsigned(L,
611
+ ((uint32_t)c->p[1] << 24) |
612
+ ((uint32_t)c->p[2] << 16) |
613
+ ((uint32_t)c->p[3] << 8) |
614
+ (uint32_t)c->p[4]);
615
+ mp_cur_consume(c,5);
616
+ break;
617
+ case 0xd2: /* int 32 */
618
+ mp_cur_need(c,5);
619
+ lua_pushinteger(L,
620
+ ((int32_t)c->p[1] << 24) |
621
+ ((int32_t)c->p[2] << 16) |
622
+ ((int32_t)c->p[3] << 8) |
623
+ (int32_t)c->p[4]);
624
+ mp_cur_consume(c,5);
625
+ break;
626
+ case 0xcf: /* uint 64 */
627
+ mp_cur_need(c,9);
628
+ lua_pushunsigned(L,
629
+ ((uint64_t)c->p[1] << 56) |
630
+ ((uint64_t)c->p[2] << 48) |
631
+ ((uint64_t)c->p[3] << 40) |
632
+ ((uint64_t)c->p[4] << 32) |
633
+ ((uint64_t)c->p[5] << 24) |
634
+ ((uint64_t)c->p[6] << 16) |
635
+ ((uint64_t)c->p[7] << 8) |
636
+ (uint64_t)c->p[8]);
637
+ mp_cur_consume(c,9);
638
+ break;
639
+ case 0xd3: /* int 64 */
640
+ mp_cur_need(c,9);
641
+ #if LUA_VERSION_NUM < 503
642
+ lua_pushnumber(L,
643
+ #else
644
+ lua_pushinteger(L,
645
+ #endif
646
+ ((int64_t)c->p[1] << 56) |
647
+ ((int64_t)c->p[2] << 48) |
648
+ ((int64_t)c->p[3] << 40) |
649
+ ((int64_t)c->p[4] << 32) |
650
+ ((int64_t)c->p[5] << 24) |
651
+ ((int64_t)c->p[6] << 16) |
652
+ ((int64_t)c->p[7] << 8) |
653
+ (int64_t)c->p[8]);
654
+ mp_cur_consume(c,9);
655
+ break;
656
+ case 0xc0: /* nil */
657
+ lua_pushnil(L);
658
+ mp_cur_consume(c,1);
659
+ break;
660
+ case 0xc3: /* true */
661
+ lua_pushboolean(L,1);
662
+ mp_cur_consume(c,1);
663
+ break;
664
+ case 0xc2: /* false */
665
+ lua_pushboolean(L,0);
666
+ mp_cur_consume(c,1);
667
+ break;
668
+ case 0xca: /* float */
669
+ mp_cur_need(c,5);
670
+ assert(sizeof(float) == 4);
671
+ {
672
+ float f;
673
+ memcpy(&f,c->p+1,4);
674
+ memrevifle(&f,4);
675
+ lua_pushnumber(L,f);
676
+ mp_cur_consume(c,5);
677
+ }
678
+ break;
679
+ case 0xcb: /* double */
680
+ mp_cur_need(c,9);
681
+ assert(sizeof(double) == 8);
682
+ {
683
+ double d;
684
+ memcpy(&d,c->p+1,8);
685
+ memrevifle(&d,8);
686
+ lua_pushnumber(L,d);
687
+ mp_cur_consume(c,9);
688
+ }
689
+ break;
690
+ case 0xda: /* raw 16 */
691
+ mp_cur_need(c,3);
692
+ {
693
+ size_t l = (c->p[1] << 8) | c->p[2];
694
+ mp_cur_need(c,3+l);
695
+ lua_pushlstring(L,(char*)c->p+3,l);
696
+ mp_cur_consume(c,3+l);
697
+ }
698
+ break;
699
+ case 0xdb: /* raw 32 */
700
+ mp_cur_need(c,5);
701
+ {
702
+ size_t l = ((size_t)c->p[1] << 24) |
703
+ ((size_t)c->p[2] << 16) |
704
+ ((size_t)c->p[3] << 8) |
705
+ (size_t)c->p[4];
706
+ mp_cur_consume(c,5);
707
+ mp_cur_need(c,l);
708
+ lua_pushlstring(L,(char*)c->p,l);
709
+ mp_cur_consume(c,l);
710
+ }
711
+ break;
712
+ case 0xdc: /* array 16 */
713
+ mp_cur_need(c,3);
714
+ {
715
+ size_t l = (c->p[1] << 8) | c->p[2];
716
+ mp_cur_consume(c,3);
717
+ mp_decode_to_lua_array(L,c,l);
718
+ }
719
+ break;
720
+ case 0xdd: /* array 32 */
721
+ mp_cur_need(c,5);
722
+ {
723
+ size_t l = ((size_t)c->p[1] << 24) |
724
+ ((size_t)c->p[2] << 16) |
725
+ ((size_t)c->p[3] << 8) |
726
+ (size_t)c->p[4];
727
+ mp_cur_consume(c,5);
728
+ mp_decode_to_lua_array(L,c,l);
729
+ }
730
+ break;
731
+ case 0xde: /* map 16 */
732
+ mp_cur_need(c,3);
733
+ {
734
+ size_t l = (c->p[1] << 8) | c->p[2];
735
+ mp_cur_consume(c,3);
736
+ mp_decode_to_lua_hash(L,c,l);
737
+ }
738
+ break;
739
+ case 0xdf: /* map 32 */
740
+ mp_cur_need(c,5);
741
+ {
742
+ size_t l = ((size_t)c->p[1] << 24) |
743
+ ((size_t)c->p[2] << 16) |
744
+ ((size_t)c->p[3] << 8) |
745
+ (size_t)c->p[4];
746
+ mp_cur_consume(c,5);
747
+ mp_decode_to_lua_hash(L,c,l);
748
+ }
749
+ break;
750
+ default: /* types that can't be idenitified by first byte value. */
751
+ if ((c->p[0] & 0x80) == 0) { /* positive fixnum */
752
+ lua_pushunsigned(L,c->p[0]);
753
+ mp_cur_consume(c,1);
754
+ } else if ((c->p[0] & 0xe0) == 0xe0) { /* negative fixnum */
755
+ lua_pushinteger(L,(signed char)c->p[0]);
756
+ mp_cur_consume(c,1);
757
+ } else if ((c->p[0] & 0xe0) == 0xa0) { /* fix raw */
758
+ size_t l = c->p[0] & 0x1f;
759
+ mp_cur_need(c,1+l);
760
+ lua_pushlstring(L,(char*)c->p+1,l);
761
+ mp_cur_consume(c,1+l);
762
+ } else if ((c->p[0] & 0xf0) == 0x90) { /* fix map */
763
+ size_t l = c->p[0] & 0xf;
764
+ mp_cur_consume(c,1);
765
+ mp_decode_to_lua_array(L,c,l);
766
+ } else if ((c->p[0] & 0xf0) == 0x80) { /* fix map */
767
+ size_t l = c->p[0] & 0xf;
768
+ mp_cur_consume(c,1);
769
+ mp_decode_to_lua_hash(L,c,l);
770
+ } else {
771
+ c->err = MP_CUR_ERROR_BADFMT;
772
+ }
773
+ }
774
+ }
775
+
776
+ int mp_unpack_full(lua_State *L, int limit, int offset) {
777
+ size_t len;
778
+ const char *s;
779
+ mp_cur c;
780
+ int cnt; /* Number of objects unpacked */
781
+ int decode_all = (!limit && !offset);
782
+
783
+ s = luaL_checklstring(L,1,&len); /* if no match, exits */
784
+
785
+ if (offset < 0 || limit < 0) /* requesting negative off or lim is invalid */
786
+ return luaL_error(L,
787
+ "Invalid request to unpack with offset of %d and limit of %d.",
788
+ offset, len);
789
+ else if (offset > len)
790
+ return luaL_error(L,
791
+ "Start offset %d greater than input length %d.", offset, len);
792
+
793
+ if (decode_all) limit = INT_MAX;
794
+
795
+ mp_cur_init(&c,(const unsigned char *)s+offset,len-offset);
796
+
797
+ /* We loop over the decode because this could be a stream
798
+ * of multiple top-level values serialized together */
799
+ for(cnt = 0; c.left > 0 && cnt < limit; cnt++) {
800
+ mp_decode_to_lua_type(L,&c);
801
+
802
+ if (c.err == MP_CUR_ERROR_EOF) {
803
+ return luaL_error(L,"Missing bytes in input.");
804
+ } else if (c.err == MP_CUR_ERROR_BADFMT) {
805
+ return luaL_error(L,"Bad data format in input.");
806
+ }
807
+ }
808
+
809
+ if (!decode_all) {
810
+ /* c->left is the remaining size of the input buffer.
811
+ * subtract the entire buffer size from the unprocessed size
812
+ * to get our next start offset */
813
+ int offset = len - c.left;
814
+ /* Return offset -1 when we have have processed the entire buffer. */
815
+ lua_pushinteger(L, c.left == 0 ? -1 : offset);
816
+ /* Results are returned with the arg elements still
817
+ * in place. Lua takes care of only returning
818
+ * elements above the args for us.
819
+ * In this case, we have one arg on the stack
820
+ * for this function, so we insert our first return
821
+ * value at position 2. */
822
+ lua_insert(L, 2);
823
+ cnt += 1; /* increase return count by one to make room for offset */
824
+ }
825
+
826
+ return cnt;
827
+ }
828
+
829
+ int mp_unpack(lua_State *L) {
830
+ return mp_unpack_full(L, 0, 0);
831
+ }
832
+
833
+ int mp_unpack_one(lua_State *L) {
834
+ int offset = luaL_optinteger(L, 2, 0);
835
+ /* Variable pop because offset may not exist */
836
+ lua_pop(L, lua_gettop(L)-1);
837
+ return mp_unpack_full(L, 1, offset);
838
+ }
839
+
840
+ int mp_unpack_limit(lua_State *L) {
841
+ int limit = luaL_checkinteger(L, 2);
842
+ int offset = luaL_optinteger(L, 3, 0);
843
+ /* Variable pop because offset may not exist */
844
+ lua_pop(L, lua_gettop(L)-1);
845
+
846
+ return mp_unpack_full(L, limit, offset);
847
+ }
848
+
849
+ int mp_safe(lua_State *L) {
850
+ int argc, err, total_results;
851
+
852
+ argc = lua_gettop(L);
853
+
854
+ /* This adds our function to the bottom of the stack
855
+ * (the "call this function" position) */
856
+ lua_pushvalue(L, lua_upvalueindex(1));
857
+ lua_insert(L, 1);
858
+
859
+ err = lua_pcall(L, argc, LUA_MULTRET, 0);
860
+ total_results = lua_gettop(L);
861
+
862
+ if (!err) {
863
+ return total_results;
864
+ } else {
865
+ lua_pushnil(L);
866
+ lua_insert(L,-2);
867
+ return 2;
868
+ }
869
+ }
870
+
871
+ /* -------------------------------------------------------------------------- */
872
+ const struct luaL_Reg cmds[] = {
873
+ {"pack", mp_pack},
874
+ {"unpack", mp_unpack},
875
+ {"unpack_one", mp_unpack_one},
876
+ {"unpack_limit", mp_unpack_limit},
877
+ {0}
878
+ };
879
+
880
+ int luaopen_create(lua_State *L) {
881
+ int i;
882
+ /* Manually construct our module table instead of
883
+ * relying on _register or _newlib */
884
+ lua_newtable(L);
885
+
886
+ for (i = 0; i < (sizeof(cmds)/sizeof(*cmds) - 1); i++) {
887
+ lua_pushcfunction(L, cmds[i].func);
888
+ lua_setfield(L, -2, cmds[i].name);
889
+ }
890
+
891
+ /* Add metadata */
892
+ lua_pushliteral(L, LUACMSGPACK_NAME);
893
+ lua_setfield(L, -2, "_NAME");
894
+ lua_pushliteral(L, LUACMSGPACK_VERSION);
895
+ lua_setfield(L, -2, "_VERSION");
896
+ lua_pushliteral(L, LUACMSGPACK_COPYRIGHT);
897
+ lua_setfield(L, -2, "_COPYRIGHT");
898
+ lua_pushliteral(L, LUACMSGPACK_DESCRIPTION);
899
+ lua_setfield(L, -2, "_DESCRIPTION");
900
+ return 1;
901
+ }
902
+
903
+ LUALIB_API int luaopen_cmsgpack(lua_State *L) {
904
+ luaopen_create(L);
905
+
906
+ #if LUA_VERSION_NUM < 502
907
+ /* Register name globally for 5.1 */
908
+ lua_pushvalue(L, -1);
909
+ lua_setglobal(L, LUACMSGPACK_NAME);
910
+ #endif
911
+
912
+ return 1;
913
+ }
914
+
915
+ LUALIB_API int luaopen_cmsgpack_safe(lua_State *L) {
916
+ int i;
917
+
918
+ luaopen_cmsgpack(L);
919
+
920
+ /* Wrap all functions in the safe handler */
921
+ for (i = 0; i < (sizeof(cmds)/sizeof(*cmds) - 1); i++) {
922
+ lua_getfield(L, -1, cmds[i].name);
923
+ lua_pushcclosure(L, mp_safe, 1);
924
+ lua_setfield(L, -2, cmds[i].name);
925
+ }
926
+
927
+ #if LUA_VERSION_NUM < 502
928
+ /* Register name globally for 5.1 */
929
+ lua_pushvalue(L, -1);
930
+ lua_setglobal(L, LUACMSGPACK_SAFE_NAME);
931
+ #endif
932
+
933
+ return 1;
934
+ }
935
+
936
+ /******************************************************************************
937
+ * Copyright (C) 2012 Salvatore Sanfilippo. All rights reserved.
938
+ *
939
+ * Permission is hereby granted, free of charge, to any person obtaining
940
+ * a copy of this software and associated documentation files (the
941
+ * "Software"), to deal in the Software without restriction, including
942
+ * without limitation the rights to use, copy, modify, merge, publish,
943
+ * distribute, sublicense, and/or sell copies of the Software, and to
944
+ * permit persons to whom the Software is furnished to do so, subject to
945
+ * the following conditions:
946
+ *
947
+ * The above copyright notice and this permission notice shall be
948
+ * included in all copies or substantial portions of the Software.
949
+ *
950
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
951
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
952
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
953
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
954
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
955
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
956
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
957
+ ******************************************************************************/