github.com/jdgcs/sqlite3@v1.12.1-0.20210908114423-bc5f96e4dd51/testdata/tcl/loadext.test (about) 1 # 2006 July 14 2 # 3 # The author disclaims copyright to this source code. In place of 4 # a legal notice, here is a blessing: 5 # 6 # May you do good and not evil. 7 # May you find forgiveness for yourself and forgive others. 8 # May you share freely, never taking more than you give. 9 # 10 #*********************************************************************** 11 # This file implements regression tests for SQLite library. The 12 # focus of this script is extension loading. 13 # 14 # $Id: loadext.test,v 1.17 2009/03/20 09:09:37 danielk1977 Exp $ 15 16 set testdir [file dirname $argv0] 17 source $testdir/tester.tcl 18 19 ifcapable !load_ext { 20 finish_test 21 return 22 } 23 24 # The name of the test extension varies by operating system. 25 # 26 if {$::tcl_platform(platform) eq "windows"} { 27 set testextension ./testloadext.dll 28 } else { 29 set testextension ./libtestloadext.so 30 } 31 set gcc_shared "-shared -fPIC" 32 if {$::tcl_platform(os) eq "Darwin"} { 33 set gcc_shared -dynamiclib 34 } 35 36 # The error messages tested by this file are operating system dependent 37 # (because they are returned by sqlite3OsDlError()). For now, they only 38 # work with UNIX (and probably only certain kinds of UNIX). 39 # 40 # When a shared-object cannot be opened because it does not exist, the 41 # format of the message returned is: 42 # 43 # [format $dlerror_nosuchfile <shared-object-name>] 44 # 45 # When a shared-object cannot be opened because it consists of the 4 46 # characters "blah" only, we expect the error message to be: 47 # 48 # [format $dlerror_notadll <shared-object-name>] 49 # 50 # When a symbol cannot be found within an open shared-object, the error 51 # message should be: 52 # 53 # [format $dlerror_nosymbol <shared-object-name> <symbol-name>] 54 # 55 # The exact error messages are not important. The important bit is 56 # that SQLite is correctly copying the message from xDlError(). 57 # 58 set dlerror_nosuchfile \ 59 {%s: cannot open shared object file: No such file or directory} 60 set dlerror_notadll {%s: file too short} 61 set dlerror_nosymbol {%s: undefined symbol: %s} 62 63 if {$::tcl_platform(os) eq "Darwin"} { 64 set dlerror_nosuchfile {dlopen.%s, 10.: .*image.*found.*} 65 set dlerror_notadll {dlopen.%1$s, 10.: .*image.*found.*} 66 set dlerror_nosymbol {dlsym.XXX, %2$s.: symbol not found} 67 } 68 69 if {$::tcl_platform(platform) eq "windows"} { 70 set dlerror_nosuchfile {The specified module could not be found.*} 71 set dlerror_notadll {%%1 is not a valid Win32 application.*} 72 set dlerror_nosymbol {The specified procedure could not be found.*} 73 } 74 75 # Make sure the test extension actually exists. If it does not 76 # exist, try to create it. If unable to create it, then skip this 77 # test file. 78 # 79 if {![file exists $testextension]} { 80 set srcdir [file dir $testdir]/src 81 set testextsrc $srcdir/test_loadext.c 82 83 set cmdline [concat exec gcc $gcc_shared] 84 lappend cmdline -Wall -I$srcdir -I. -I.. -g $testextsrc -o $testextension 85 86 if {[catch $cmdline msg]} { 87 puts "Skipping loadext tests: Test extension not built..." 88 puts $msg 89 finish_test 90 return 91 } 92 } 93 94 # Test that loading the extension produces the expected results - adding 95 # the half() function to the specified database handle. 96 # 97 do_test loadext-1.1 { 98 catchsql { 99 SELECT half(1.0); 100 } 101 } {1 {no such function: half}} 102 do_test loadext-1.2 { 103 db enable_load_extension 1 104 sqlite3_load_extension db $testextension testloadext_init 105 catchsql { 106 SELECT half(1.0); 107 } 108 } {0 0.5} 109 110 # Test that a second database connection (db2) can load the extension also. 111 # 112 do_test loadext-1.3 { 113 sqlite3 db2 test.db 114 sqlite3_db_config db2 SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION 1 115 catchsql { 116 SELECT half(1.0); 117 } db2 118 } {1 {no such function: half}} 119 do_test loadext-1.4 { 120 sqlite3_load_extension db2 $testextension testloadext_init 121 catchsql { 122 SELECT half(1.0); 123 } db2 124 } {0 0.5} 125 126 # Close the first database connection. Then check that the second database 127 # can still use the half() function without a problem. 128 # 129 do_test loadext-1.5 { 130 db close 131 catchsql { 132 SELECT half(1.0); 133 } db2 134 } {0 0.5} 135 136 db2 close 137 sqlite3 db test.db 138 sqlite3_enable_load_extension db 1 139 140 # Try to load an extension for which the file does not exist. 141 # 142 do_test loadext-2.1 { 143 forcedelete ${testextension}xx 144 set rc [catch { 145 sqlite3_load_extension db "${testextension}xx" 146 } msg] 147 list $rc $msg 148 } /[list 1 [format $dlerror_nosuchfile ${testextension}xx.*]]/ 149 150 # Try to load an extension for which the file is not a shared object 151 # 152 do_test loadext-2.2 { 153 set fd [open "./notasharedlib.so" w] 154 puts $fd blah 155 close $fd 156 set fd [open "./notasharedlib.dll" w] 157 puts $fd blah 158 close $fd 159 set rc [catch { 160 sqlite3_load_extension db "./notasharedlib" 161 } msg] 162 list $rc $msg 163 } /[list 1 [format $dlerror_notadll ./notasharedlib.*]]/ 164 165 # Try to load an extension for which the file is present but the 166 # entry point is not. 167 # 168 do_test loadext-2.3 { 169 set rc [catch { 170 sqlite3_load_extension db $testextension icecream 171 } msg] 172 if {$::tcl_platform(os) eq "Darwin"} { 173 regsub {0x[1234567890abcdefABCDEF]*} $msg XXX msg 174 } 175 list $rc $msg 176 } /[list 1 [format $dlerror_nosymbol $testextension icecream]]/ 177 178 # Try to load an extension for which the entry point fails (returns non-zero) 179 # 180 do_test loadext-2.4 { 181 set rc [catch { 182 sqlite3_load_extension db $testextension testbrokenext_init 183 } msg] 184 list $rc $msg 185 } {1 {error during initialization: broken!}} 186 187 ############################################################################ 188 # Tests for the load_extension() SQL function 189 # 190 191 db close 192 sqlite3 db test.db 193 sqlite3_enable_load_extension db 1 194 do_test loadext-3.1 { 195 catchsql { 196 SELECT half(5); 197 } 198 } {1 {no such function: half}} 199 do_test loadext-3.2 { 200 set res [catchsql { 201 SELECT load_extension($::testextension) 202 }] 203 if {$::tcl_platform(os) eq "Darwin"} { 204 regsub {0x[1234567890abcdefABCDEF]*} $res XXX res 205 } 206 set res 207 } /[list 1 [format $dlerror_nosymbol $testextension sqlite3_.*_init]]/ 208 do_test loadext-3.3 { 209 catchsql { 210 SELECT load_extension($::testextension,'testloadext_init') 211 } 212 } {0 {{}}} 213 do_test loadext-3.4 { 214 catchsql { 215 SELECT half(5); 216 } 217 } {0 2.5} 218 do_test loadext-3.5 { 219 db eval { 220 SELECT sqlite3_status('MEMORY_USED') AS mused 221 } break 222 puts -nonewline " (memory_used=$mused) " 223 expr {$mused>0} 224 } {1} 225 do_test loadext-3.6 { 226 catchsql { 227 SELECT sqlite3_status('MEMORY_USED_X') AS mused 228 } 229 } {1 {unknown status property: MEMORY_USED_X}} 230 do_test loadext-3.7 { 231 catchsql { 232 SELECT sqlite3_status(4.53) AS mused 233 } 234 } {1 {unknown status type}} 235 do_test loadext-3.8 { 236 catchsql { 237 SELECT sqlite3_status(23) AS mused 238 } 239 } {1 {sqlite3_status(23,...) returns 21}} 240 241 # Ticket #1863 242 # Make sure the extension loading mechanism will not work unless it 243 # is explicitly enabled. 244 # 245 db close 246 sqlite3 db test.db 247 do_test loadext-4.1 { 248 catchsql { 249 SELECT load_extension($::testextension,'testloadext_init') 250 } 251 } {1 {not authorized}} 252 do_test loadext-4.2 { 253 sqlite3_enable_load_extension db 1 254 catchsql { 255 SELECT load_extension($::testextension,'testloadext_init') 256 } 257 } {0 {{}}} 258 259 # disable all extension loading 260 do_test loadext-4.3 { 261 sqlite3_enable_load_extension db 0 262 catchsql { 263 SELECT load_extension($::testextension,'testloadext_init') 264 } 265 } {1 {not authorized}} 266 267 # enable C-api extension loading only. Show that the SQL function 268 # still does not work. 269 do_test loadext-4.4 { 270 sqlite3_db_config db SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION 1 271 catchsql { 272 SELECT load_extension($::testextension,'testloadext_init') 273 } 274 } {1 {not authorized}} 275 276 source $testdir/malloc_common.tcl 277 278 279 # Malloc failure in sqlite3_auto_extension and sqlite3_load_extension 280 # 281 do_malloc_test loadext-5 -tclprep { 282 sqlite3_reset_auto_extension 283 } -tclbody { 284 if {[autoinstall_test_functions]==7} {error "out of memory"} 285 } 286 287 # On Windows, this malloc test must be skipped because the winDlOpen 288 # function itself can fail due to "out of memory" conditions. 289 # 290 if {$::tcl_platform(platform) ne "windows"} { 291 do_malloc_test loadext-6 -tclbody { 292 db enable_load_extension 1 293 sqlite3_load_extension db $::testextension testloadext_init 294 } 295 } 296 297 autoinstall_test_functions 298 299 finish_test