@@ -64,6 +64,7 @@ OF SUCH DAMAGE.
6464
6565#include < cmath>
6666#include < ctime>
67+ #include < fstream>
6768#include < grp.h>
6869#include < pwd.h>
6970#include < stdlib.h>
@@ -533,38 +534,72 @@ static int copy_blob_column_callback(void *args, int count, char **data, char **
533534}
534535
535536TEST (addqueryfuncs, blobop) {
536- const char data[] = " abc def\n\x00\x01\x02 \x03\x04\x05\n ghi jkl" ;
537- const std::size_t len = sizeof (data) - 1 ;
538-
539537 // sqlite3 does not like binary in SQL statements, so write contents to temp file first
540538 char temp[] = " XXXXXX" ;
541- int fd = mkstemp (temp);
542- ASSERT_GT (fd, -1 );
543- ASSERT_EQ (write (fd, data, len), (ssize_t ) len);
544- close (fd);
539+ {
540+ const int fd = mkstemp (temp);
541+ ASSERT_GT (fd, -1 );
542+ close (fd);
543+ }
545544
546545 sqlite3 *db = nullptr ;
547546 ASSERT_EQ (sqlite3_open (SQLITE_MEMORY, &db), SQLITE_OK);
548547 ASSERT_NE (db, nullptr );
549-
550548 ASSERT_EQ (addqueryfuncs (db), 0 );
551549
552- // have to insert into table to get length later without opening file twice
553550 char cmd[1024 ];
554- snprintf (cmd, sizeof (cmd), " CREATE TABLE data(col BLOB); INSERT INTO data SELECT blobop('cat %s');" , temp);
555- ASSERT_EQ (sqlite3_exec (db, cmd, nullptr , nullptr , nullptr ), SQLITE_OK);
556-
557551 str_t output;
552+ memset (&output, 0 , sizeof (output));
558553 char *err = nullptr ;
559- ASSERT_EQ (sqlite3_exec (db, " SELECT length(col), col FROM data;" ,
560- copy_blob_column_callback, &output, &err), SQLITE_OK);
561- EXPECT_EQ (err, nullptr );
562- EXPECT_EQ (output.len , len);
563- ASSERT_NE (output.data , nullptr );
564- EXPECT_EQ (memcmp (output.data , data, len), 0 );
565- str_free_existing (&output);
566- sqlite3_free (err);
567- err = nullptr ;
554+
555+ // have to insert into table to get length later without opening file twice
556+
557+ // empty file
558+ {
559+ snprintf (cmd, sizeof (cmd), " CREATE TABLE data(col BLOB); INSERT INTO data SELECT blobop('cat %s');" , temp);
560+ ASSERT_EQ (sqlite3_exec (db, cmd, nullptr , nullptr , nullptr ), SQLITE_OK);
561+
562+ ASSERT_EQ (sqlite3_exec (db, " SELECT length(col), col FROM data; DROP TABLE data;" ,
563+ copy_blob_column_callback, &output, &err), SQLITE_OK);
564+ EXPECT_EQ (err, nullptr );
565+ EXPECT_EQ (output.len , (std::size_t ) 0 );
566+ ASSERT_NE (output.data , nullptr );
567+ str_free_existing (&output);
568+ }
569+
570+ // short result
571+ {
572+ const char data[] = " abc def\n\x00\x01\x02 \x03\x04\x05\n ghi jkl" ;
573+ const std::size_t len = sizeof (data) - 1 ;
574+ std::ofstream (temp).write (data, len);
575+ snprintf (cmd, sizeof (cmd), " CREATE TABLE data(col BLOB); INSERT INTO data SELECT blobop('cat %s');" , temp);
576+ ASSERT_EQ (sqlite3_exec (db, cmd, nullptr , nullptr , nullptr ), SQLITE_OK);
577+
578+ ASSERT_EQ (sqlite3_exec (db, " SELECT length(col), col FROM data; DROP TABLE data;" ,
579+ copy_blob_column_callback, &output, &err), SQLITE_OK);
580+ EXPECT_EQ (err, nullptr );
581+ EXPECT_EQ (output.len , len);
582+ ASSERT_NE (output.data , nullptr );
583+ EXPECT_EQ (memcmp (output.data , data, len), 0 );
584+ str_free_existing (&output);
585+ }
586+
587+ // "long" result (force a reallocation)
588+ {
589+ const std::size_t len = 256 ;
590+ const std::string A (len, ' a' );
591+ std::ofstream (temp) << A;
592+ snprintf (cmd, sizeof (cmd), " CREATE TABLE data(col BLOB); INSERT INTO data SELECT blobop('cat %s');" , temp);
593+ ASSERT_EQ (sqlite3_exec (db, cmd, NULL , NULL , NULL ), SQLITE_OK);
594+
595+ ASSERT_EQ (sqlite3_exec (db, " SELECT length(col), col FROM data; DROP TABLE data;" ,
596+ copy_blob_column_callback, &output, &err), SQLITE_OK);
597+ EXPECT_EQ (err, nullptr );
598+ EXPECT_EQ (output.len , len);
599+ ASSERT_NE (output.data , nullptr );
600+ EXPECT_EQ (memcmp (output.data , A.c_str (), len), 0 );
601+ str_free_existing (&output);
602+ }
568603
569604 // not enough file descriptors
570605 {
@@ -575,7 +610,8 @@ TEST(addqueryfuncs, blobop) {
575610 fewer_fds.rlim_cur = 3 ;
576611 ASSERT_EQ (setrlimit (RLIMIT_NOFILE, &fewer_fds), 0 );
577612
578- ASSERT_EQ (sqlite3_exec (db, " SELECT blobop('echo blob');" , copy_columns_callback, &output, &err), SQLITE_ERROR);
613+ ASSERT_EQ (sqlite3_exec (db, " SELECT blobop('echo blob');" ,
614+ copy_columns_callback, &output, &err), SQLITE_ERROR);
579615 EXPECT_NE (err, nullptr );
580616 sqlite3_free (err);
581617 err = nullptr ;
0 commit comments