diff --git a/core/smn_string.cpp b/core/smn_string.cpp
index f9ba1140..d01f0e3e 100644
--- a/core/smn_string.cpp
+++ b/core/smn_string.cpp
@@ -192,7 +192,31 @@ static cell_t sm_formatex(IPluginContext *pCtx, const cell_t *params)
 	return static_cast<cell_t>(res);
 }
 
+class StaticCharBuf
+{
+    char *buffer;
+    size_t max_size;
+public:
+    StaticCharBuf() : buffer(NULL), max_size(0)
+    {
+    }
+    ~StaticCharBuf()
+    {
+        delete [] buffer;
+    }
+    char* GetWithSize(size_t len)
+    {
+        if (len > max_size)
+        {
+            buffer = (char *)realloc(buffer, len);
+            max_size = len;
+        }
+        return buffer;
+    }
+};
+
 static char g_formatbuf[2048];
+static StaticCharBuf g_extrabuf;
 static cell_t sm_format(IPluginContext *pCtx, const cell_t *params)
 {
 	char *buf, *fmt, *destbuf;
@@ -200,6 +224,7 @@ static cell_t sm_format(IPluginContext *pCtx, const cell_t *params)
 	size_t res, maxlen;
 	int arg = 4;
 	bool copy = false;
+    char *__copy_buf;
 
 	pCtx->LocalToString(params[1], &destbuf);
 	pCtx->LocalToString(params[3], &fmt);
@@ -217,12 +242,25 @@ static cell_t sm_format(IPluginContext *pCtx, const cell_t *params)
 			break;
 		}
 	}
-	buf = (copy) ? g_formatbuf : destbuf;
+
+    if (copy)
+    {
+        if (maxlen > sizeof(g_formatbuf))
+        {
+            __copy_buf = g_extrabuf.GetWithSize(maxlen);
+        }
+        else
+        {
+            __copy_buf = g_formatbuf;
+        }
+    }
+
+	buf = (copy) ? __copy_buf : destbuf;
 	res = atcprintf(buf, maxlen, fmt, pCtx, params, &arg);
 
 	if (copy)
 	{
-		memcpy(destbuf, g_formatbuf, res+1);
+		memcpy(destbuf, __copy_buf, res+1);
 	}
 
 	return static_cast<cell_t>(res);