From 76efe1225fcd76cd10d6ea87ae9bec36b17edcfa Mon Sep 17 00:00:00 2001
From: Matt Stancliff <matt@genges.com>
Date: Tue, 10 Jun 2014 14:21:37 -0400
Subject: [PATCH] Scripting: Fix regression from #1118

The new check-for-number behavior of Lua arguments broke
users who use large strings of just integers.

The Lua number check would convert the string to a number, but
that breaks user data because
Lua numbers have limited precision compared to an arbitrarily
precise number wrapped in a string.

Regression fixed and new test added.

Fixes #1118 again.
---
 src/scripting.c          | 7 ++++++-
 tests/unit/scripting.tcl | 7 +++++++
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/src/scripting.c b/src/scripting.c
index 27964771..67b37309 100644
--- a/src/scripting.c
+++ b/src/scripting.c
@@ -200,6 +200,11 @@ void luaSortArray(lua_State *lua) {
     lua_pop(lua,1);             /* Stack: array (sorted) */
 }
 
+int luaReallyIsString(lua_State *L, int index) {
+    int t = lua_type(L, index);
+    return t == LUA_TSTRING;
+}
+
 #define LUA_CMD_OBJCACHE_SIZE 32
 #define LUA_CMD_OBJCACHE_MAX_LEN 64
 int luaRedisGenericCommand(lua_State *lua, int raise_error) {
@@ -234,7 +239,7 @@ int luaRedisGenericCommand(lua_State *lua, int raise_error) {
         size_t obj_len;
         char dbuf[64];
 
-        if (lua_isnumber(lua,j+1)) {
+        if (!luaReallyIsString(lua, j+1) && lua_isnumber(lua, j+1)) {
             /* We can't use lua_tolstring() for number -> string conversion
              * since Lua uses a format specifier that loses precision. */
             lua_Number num = lua_tonumber(lua,j+1);
diff --git a/tests/unit/scripting.tcl b/tests/unit/scripting.tcl
index d7b6d2ca..2c4171ae 100644
--- a/tests/unit/scripting.tcl
+++ b/tests/unit/scripting.tcl
@@ -347,6 +347,13 @@ start_server {tags {"scripting"}} {
               return redis.call("get","foo")
         } 0
     } {9007199254740991}
+
+    test {String containing number precision test (regression of issue #1118)} {
+        r eval {
+            redis.call("set", "key", "12039611435714932082")
+            return redis.call("get", "key")
+        } 0
+    } {12039611435714932082}
 }
 
 # Start a new server since the last test in this stanza will kill the