FreeTDS / freetds

Official FreeTDS repository
http://www.freetds.org/
GNU General Public License v2.0
460 stars 159 forks source link

Segmentation fault when querying truncated 4 bytes unicode string #227

Open maxiwheat opened 6 years ago

maxiwheat commented 6 years ago

I already reported a bug on PHP about this bug, but it looks like the bug happens in FreeTDS rather than in PHP. So I tried to reproduce the bug, and I've been able to do so using bsqldb ; on the command line, execute :

echo "DECLARE @test AS NVARCHAR(1) = 0x3CD884DF; SELECT @test AS test;"| bsqldb -q -U mysername -P mypassword -S myserverHost 

Expanding the NVARCHAR(1) to NVARCHAR(2) in the variable declaration does not segfault and the christmas tree emoji is correctly displayed.

Note: I'm using binary hex representation of the christmas tree emoji in my bug report because sometimes it does not get displayed correctly in different environment, but could be replaced by the string literal using Unicode T-SQL notation N'🎄'

freddy77 commented 6 years ago

Confirmed. The character you are trying to manipulate requires a surrogate pair, that is cannot be stored using a NVARCHAR(1) and this cause a truncation. The error condition is correctly detected. The code then tries to report the error to user but due to a bug using a format string without arguments the program badly crash.

A temporarily workaround is

diff --git a/src/dblib/dbutil.c b/src/dblib/dbutil.c
index ac6bb7fb..378393bc 100644
--- a/src/dblib/dbutil.c
+++ b/src/dblib/dbutil.c
@@ -133,7 +133,7 @@ _dblib_handle_err_message(const TDSCONTEXT * tds_ctx, TDSSOCKET * tds, TDSMESSAG
        assert(_dblib_err_handler);
        assert(msg);

-       rc = dbperror(dbproc, msg->msgno, msg->oserr);
+       rc = dbperror(dbproc, msg->msgno, msg->oserr, 0, 0, 0, 0);

        /*
         * Preprocess the return code to handle INT_TIMEOUT/INT_CONTINUE

as pretty serious probably I'll go for the temporary solution till I don't find a proper better solution