From 450da02683c1a15a38c74c456e57531a51622963 Mon Sep 17 00:00:00 2001
From: Mergen Imeev <imeevma@tarantool.org>
Date: Tue, 12 Dec 2023 13:20:03 +0300
Subject: [PATCH] sql: properly check result of decimal parsing

This patch fixes a crash that can occur when SQL parses a decimal
literal that represents a number greater than or equal to 10^38.

Closes #9469

NO_DOC=bugfix

(cherry picked from commit 05551a556bbca9e4aa5fa910e1b62ea67e6177e6)
---
 .../unreleased/gh-9469-too-big-decimal.md     |  4 +++
 src/box/errcode.h                             |  1 +
 src/box/sql/expr.c                            |  1 +
 test/box/error.result                         |  1 +
 .../gh_9469_too_big_decimals_test.lua         | 29 +++++++++++++++++++
 5 files changed, 36 insertions(+)
 create mode 100644 changelogs/unreleased/gh-9469-too-big-decimal.md
 create mode 100644 test/sql-luatest/gh_9469_too_big_decimals_test.lua

diff --git a/changelogs/unreleased/gh-9469-too-big-decimal.md b/changelogs/unreleased/gh-9469-too-big-decimal.md
new file mode 100644
index 0000000000..641e4bde22
--- /dev/null
+++ b/changelogs/unreleased/gh-9469-too-big-decimal.md
@@ -0,0 +1,4 @@
+## bugfix/sql
+
+* Fixed a crash when a decimal literal representing a decimal number greater
+  than or equal to 10^38 was parsed in SQL (gh-9469).
diff --git a/src/box/errcode.h b/src/box/errcode.h
index 7a33db5a07..ceafd3c308 100644
--- a/src/box/errcode.h
+++ b/src/box/errcode.h
@@ -331,6 +331,7 @@ struct errcode_record {
 	/*276 */_(ER_UNUSED9,			"") \
 	/*277 */_(ER_UNUSED10,			"") \
 	/*278 */_(ER_IN_ANOTHER_PROMOTE,	"box.ctl.promote() is already running") \
+	/*279 */_(ER_INVALID_DEC,		"Invalid decimal: '%s'") \
 
 /*
  * !IMPORTANT! Please follow instructions at start of the file
diff --git a/src/box/sql/expr.c b/src/box/sql/expr.c
index 79b2400de9..95844b76c7 100644
--- a/src/box/sql/expr.c
+++ b/src/box/sql/expr.c
@@ -3152,6 +3152,7 @@ expr_code_dec(struct Parse *parser, struct Expr *expr, bool is_neg, int reg)
 	return;
 error:
 	sql_xfree(value);
+	diag_set(ClientError, ER_INVALID_DEC, str);
 	parser->is_aborted = true;
 }
 
diff --git a/test/box/error.result b/test/box/error.result
index e3268ca27b..a8f80f8275 100644
--- a/test/box/error.result
+++ b/test/box/error.result
@@ -487,6 +487,7 @@ t;
  |   272: box.error.SCHEMA_UPGRADE_IN_PROGRESS
  |   274: box.error.UNCONFIGURED
  |   278: box.error.IN_ANOTHER_PROMOTE
+ |   279: box.error.INVALID_DEC
  | ...
 
 test_run:cmd("setopt delimiter ''");
diff --git a/test/sql-luatest/gh_9469_too_big_decimals_test.lua b/test/sql-luatest/gh_9469_too_big_decimals_test.lua
new file mode 100644
index 0000000000..285609675e
--- /dev/null
+++ b/test/sql-luatest/gh_9469_too_big_decimals_test.lua
@@ -0,0 +1,29 @@
+local server = require('luatest.server')
+local t = require('luatest')
+
+local g = t.group()
+
+g.before_all(function()
+    g.server = server:new({alias = 'master'})
+    g.server:start()
+end)
+
+g.after_all(function()
+    g.server:stop()
+end)
+
+g.test_too_big_decimal = function()
+    g.server:exec(function()
+        local dec = '111111111111111111111111111111111111111.0'
+        local sql = ([[SELECT %s;]]):format(dec)
+        local exp = ([[Invalid decimal: '%s']]):format(dec)
+        local res, err = box.execute(sql)
+        t.assert(res == nil)
+        t.assert_equals(err.message, exp)
+
+        sql = ([[SELECT -%s;]]):format(dec)
+        res, err = box.execute(sql)
+        t.assert(res == nil)
+        t.assert_equals(err.message, exp)
+    end)
+end
-- 
GitLab