From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from localhost (localhost [127.0.0.1]) by turing.freelists.org (Avenir Technologies Mail Multiplex) with ESMTP id 9C2822193D for ; Sat, 15 Dec 2018 05:57:47 -0500 (EST) Received: from turing.freelists.org ([127.0.0.1]) by localhost (turing.freelists.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 2CPh0FM7zeIW for ; Sat, 15 Dec 2018 05:57:47 -0500 (EST) Received: from smtp38.i.mail.ru (smtp38.i.mail.ru [94.100.177.98]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by turing.freelists.org (Avenir Technologies Mail Multiplex) with ESMTPS id D0360219B2 for ; Sat, 15 Dec 2018 05:57:46 -0500 (EST) From: Roman Khabibov Subject: [tarantool-patches] [PATCH] sql: fix bug with BLOB TRIM() when X'00' in char set Date: Sat, 15 Dec 2018 13:57:41 +0300 Message-Id: <20181215105741.28464-1-roman.habibov@tarantool.org> Sender: tarantool-patches-bounce@freelists.org Errors-to: tarantool-patches-bounce@freelists.org Reply-To: tarantool-patches@freelists.org List-help: List-unsubscribe: List-software: Ecartis version 1.0.0 List-Id: tarantool-patches List-subscribe: List-owner: List-post: List-archive: To: tarantool-patches@freelists.org Cc: v.shpilevoy@tarantool.org The reason for the bug was that X'00' is a terminal symbol. If the char set contained X'00', all other characters after its (inculding itself) are then ignored. Closes #3543 Branch: https://github.com/tarantool/tarantool/tree/romankhabibov/gh-3543-trim-terminal Issue: https://github.com/tarantool/tarantool/issues/3543 --- src/box/sql/func.c | 18 +++++- test/sql-tap/func.test.lua | 126 ++++++++++++++++++++++++++++++++++++- 2 files changed, 140 insertions(+), 4 deletions(-) diff --git a/src/box/sql/func.c b/src/box/sql/func.c index 9667aead5..5beba7bd2 100644 --- a/src/box/sql/func.c +++ b/src/box/sql/func.c @@ -1224,8 +1224,16 @@ trimFunc(sqlite3_context * context, int argc, sqlite3_value ** argv) return; } else { const unsigned char *z; - for (z = zCharSet, nChar = 0; *z; nChar++) { + int sizeInChar = sqlite3_value_bytes(argv[1]); + int length = 0; + z = zCharSet; + nChar = 0; + const unsigned char *zStepBack; + while(sizeInChar - length) { + zStepBack = z; SQLITE_SKIP_UTF8(z); + length += z - zStepBack; + nChar++; } if (nChar > 0) { azChar = @@ -1235,10 +1243,16 @@ trimFunc(sqlite3_context * context, int argc, sqlite3_value ** argv) return; } aLen = (unsigned char *)&azChar[nChar]; - for (z = zCharSet, nChar = 0; *z; nChar++) { + z = zCharSet; + nChar = 0; + length = 0; + while(sizeInChar - length) { azChar[nChar] = (unsigned char *)z; + zStepBack = z; SQLITE_SKIP_UTF8(z); + length += z - zStepBack; aLen[nChar] = (u8) (z - azChar[nChar]); + nChar++; } } } diff --git a/test/sql-tap/func.test.lua b/test/sql-tap/func.test.lua index 393212968..b7b8e7c4c 100755 --- a/test/sql-tap/func.test.lua +++ b/test/sql-tap/func.test.lua @@ -1,6 +1,6 @@ #!/usr/bin/env tarantool test = require("sqltester") -test:plan(14535) +test:plan(14547) --!./tcltestrunner.lua -- 2001 September 15 @@ -2100,11 +2100,133 @@ test:do_execsql_test( -- }) +-- gh-3543 Check trimming of binary string when X'00' in trimming char set. + +test:do_execsql_test( + "func-22.23", + [[ + SELECT TRIM(X'004100', X'00'); + ]], { + -- + "A" + -- + }) + +test:do_execsql_test( + "func-22.24", + [[ + SELECT TRIM(X'004100', X'0000'); + ]], { + -- + "A" + -- + }) + +test:do_execsql_test( + "func-22.25", + [[ + SELECT TRIM(X'004100', X'0042'); + ]], { + -- + "A" + -- + }) + +test:do_execsql_test( + "func-22.26", + [[ + SELECT TRIM(X'00004100420000', X'00'); + ]], { + -- + "A\0B" + -- + }) + +test:do_execsql_test( + "func-22.27", + [[ + SELECT LTRIM(X'004100', X'00'); + ]], { + -- + "A\0" + -- + }) + +test:do_execsql_test( + "func-22.28", + [[ + SELECT LTRIM(X'004100', X'0000'); + ]], { + -- + "A\0" + -- + }) + +test:do_execsql_test( + "func-22.29", + [[ + SELECT LTRIM(X'004100', X'0042'); + ]], { + -- + "A\0" + -- + }) + +test:do_execsql_test( + "func-22.30", + [[ + SELECT LTRIM(X'00004100420000', X'00'); + ]], { + -- + "A\0B\0\0" + -- + }) + +test:do_execsql_test( + "func-22.31", + [[ + SELECT RTRIM(X'004100', X'00'); + ]], { + -- + "\0A" + -- + }) + +test:do_execsql_test( + "func-22.32", + [[ + SELECT RTRIM(X'004100', X'0000'); + ]], { + -- + "\0A" + -- + }) + +test:do_execsql_test( + "func-22.33", + [[ + SELECT RTRIM(X'004100', X'0042'); + ]], { + -- + "\0A" + -- + }) + +test:do_execsql_test( + "func-22.34", + [[ + SELECT RTRIM(X'00004100420000', X'00'); + ]], { + -- + "\0\0A\0B" + -- + }) + -- This is to test the deprecated sqlite3_aggregate_count() API. -- --test:do_test( -- "func-23.1", --- function() +-- function()S -- sqlite3_create_aggregate("db") -- return test:execsql([[ -- SELECT legacy_count() FROM t6; -- 2.17.1