Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fix parsing of %00 in uri handling code. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | uri |
Files: | files | file ages | folders |
SHA1: |
44f0874a95408c75a296964a04eef003 |
User & Date: | dan 2011-04-23 10:12:30.605 |
Context
2011-04-23
| ||
15:54 | Have the ATTACH command do URI interpretation in the same way as sqlite3_open() and sqlite3_open_v2() do. (check-in: 68240e75e8 user: dan tags: uri) | |
10:12 | Fix parsing of %00 in uri handling code. (check-in: 44f0874a95 user: dan tags: uri) | |
2011-04-22
| ||
19:37 | Add the start of the "uri-filenames" feature. (check-in: b8a8132e71 user: dan tags: uri) | |
Changes
Changes to src/main.c.
︙ | ︙ | |||
1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 | const char *zDefaultVfs, /* VFS to use if no "vfs=xxx" query option */ const char *zUri, /* Nul-terminated URI to parse */ int *pFlags, /* IN/OUT: SQLITE_OPEN_XXX flags */ sqlite3_vfs **ppVfs, /* OUT: VFS to use */ char **pzFile, /* OUT: Filename component of URI */ char **pzErrMsg /* OUT: Error message (if rc!=SQLITE_OK) */ ){ int flags = *pFlags; const char *zVfs = zDefaultVfs; char *zFile; int nUri = sqlite3Strlen30(zUri); assert( *pzErrMsg==0 ); if( ((flags & SQLITE_OPEN_URI) || sqlite3GlobalConfig.bOpenUri) && nUri>=5 && memcmp(zUri, "file:", 5)==0 ){ | > > > > > > > > > > > > | | 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 | const char *zDefaultVfs, /* VFS to use if no "vfs=xxx" query option */ const char *zUri, /* Nul-terminated URI to parse */ int *pFlags, /* IN/OUT: SQLITE_OPEN_XXX flags */ sqlite3_vfs **ppVfs, /* OUT: VFS to use */ char **pzFile, /* OUT: Filename component of URI */ char **pzErrMsg /* OUT: Error message (if rc!=SQLITE_OK) */ ){ struct UriOption { const char *zOption; int mask; } aOpt [] = { { "vfs", 0 }, { "readonly", SQLITE_OPEN_READONLY }, { "readwrite", SQLITE_OPEN_READWRITE }, { "create", SQLITE_OPEN_CREATE }, { "sharedcache", SQLITE_OPEN_SHAREDCACHE }, { "privatecache", SQLITE_OPEN_PRIVATECACHE } }; int flags = *pFlags; const char *zVfs = zDefaultVfs; char *zFile; int nUri = sqlite3Strlen30(zUri); assert( *pzErrMsg==0 ); if( ((flags & SQLITE_OPEN_URI) || sqlite3GlobalConfig.bOpenUri) && nUri>=5 && memcmp(zUri, "file:", 5)==0 ){ char *zOpt; int eState; /* Parser state when parsing URI */ int iIn; /* Input character index */ int iOut = 0; /* Output character index */ int nByte = nUri+2; /* Bytes of space to allocate */ for(iIn=0; iIn<nUri; iIn++) nByte += (zUri[iIn]=='&'); zFile = sqlite3_malloc(nByte); |
︙ | ︙ | |||
1848 1849 1850 1851 1852 1853 1854 | && sqlite3Isxdigit(zUri[iIn]) && sqlite3Isxdigit(zUri[iIn+1]) ){ int codepoint = (sqlite3HexToInt(zUri[iIn++]) << 4); codepoint += sqlite3HexToInt(zUri[iIn++]); assert( codepoint>=0 && codepoint<256 ); | | > > > > > > > > > > > > > < | | > > > > > > | > | | < < < < < < < < < < < < < | | | | | | | | | | | | | | | | | | | | | | < < > | 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 | && sqlite3Isxdigit(zUri[iIn]) && sqlite3Isxdigit(zUri[iIn+1]) ){ int codepoint = (sqlite3HexToInt(zUri[iIn++]) << 4); codepoint += sqlite3HexToInt(zUri[iIn++]); assert( codepoint>=0 && codepoint<256 ); if( codepoint==0 ){ /* This branch is taken when "%00" appears within the URI. In this ** case we ignore all text in the remainder of the path, name or ** value currently being parsed. So ignore the current character ** and skip to the next "?", "=" or "&", as appropriate. */ while( zUri[iIn] && zUri[iIn]!='#' && (eState!=0 || zUri[iIn]!='?') && (eState!=1 || (zUri[iIn]!='=' && zUri[iIn]!='&')) && (eState!=2 || zUri[iIn]!='&') ){ iIn++; } continue; } c = codepoint; }else if( eState==1 && (c=='&' || c=='=') ){ if( zFile[iOut-1]==0 ){ /* An empty option name. Ignore this option altogether. */ while( zUri[iIn] && zUri[iIn]!='#' && zUri[iIn-1]!='&' ) iIn++; continue; } if( c=='&' ){ zFile[iOut++] = '\0'; }else{ eState = 2; } c = 0; }else if( (eState==0 && c=='?') || (eState==2 && c=='&') ){ c = 0; eState = 1; } zFile[iOut++] = c; } if( eState==1 ) zFile[iOut++] = '\0'; zFile[iOut++] = '\0'; zFile[iOut++] = '\0'; /* Check if there were any options specified that should be interpreted ** here. Options that are interpreted here include "vfs" and those that ** correspond to flags that may be passed to the sqlite3_open_v2() ** method. */ zOpt = &zFile[sqlite3Strlen30(zFile)+1]; while( zOpt[0] ){ int nOpt = sqlite3Strlen30(zOpt); char *zVal = &zOpt[nOpt+1]; int nVal = sqlite3Strlen30(zVal); int i; for(i=0; i<ArraySize(aOpt); i++){ const char *z = aOpt[i].zOption; if( nOpt==sqlite3Strlen30(z) && 0==memcmp(zOpt, z, nOpt) ){ int mask = aOpt[i].mask; if( mask==0 ){ zVfs = zVal; }else{ if( zVal[0]=='\0' || sqlite3GetBoolean(zVal) ){ flags |= mask; }else{ flags &= ~mask; } } } } zOpt = &zVal[nVal+1]; } }else{ zFile = sqlite3_malloc(nUri+2); if( !zFile ) return SQLITE_NOMEM; memcpy(zFile, zUri, nUri); zFile[nUri] = '\0'; zFile[nUri+1] = '\0'; } *ppVfs = sqlite3_vfs_find(zVfs); if( *ppVfs==0 ){ *pzErrMsg = sqlite3_mprintf("no such vfs: %s", zVfs); sqlite3_free(zFile); return SQLITE_ERROR; } *pFlags = flags; *pzFile = zFile; return SQLITE_OK; } |
︙ | ︙ |
Changes to test/fts3atoken.test.
︙ | ︙ | |||
163 164 165 166 167 168 169 | append output "1 tokens tokens " append output "2 then then " append output "3 [string tolower $longtoken] $longtoken" do_icu_test fts3token-4.6 MiddleOfTheOcean $input $output do_icu_test fts3token-4.7 th_TH $input $output do_icu_test fts3token-4.8 en_US $input $output | | < | | | | | | > > | 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 | append output "1 tokens tokens " append output "2 then then " append output "3 [string tolower $longtoken] $longtoken" do_icu_test fts3token-4.6 MiddleOfTheOcean $input $output do_icu_test fts3token-4.7 th_TH $input $output do_icu_test fts3token-4.8 en_US $input $output do_execsql_test 5.1 { CREATE VIRTUAL TABLE x1 USING fts3(name,TOKENIZE icu en_US); insert into x1 (name) values (NULL); insert into x1 (name) values (NULL); delete from x1; } } do_test fts3token-internal { execsql { SELECT fts3_tokenizer_internal_test() } } {ok} finish_test |
︙ | ︙ |
Changes to test/pager1.test.
︙ | ︙ | |||
1649 1650 1651 1652 1653 1654 1655 | #------------------------------------------------------------------------- # Check that it is not possible to open a database file if the full path # to the associated journal file will be longer than sqlite3_vfs.mxPathname. # testvfs tv -default 1 tv script xOpenCb tv filter xOpen | | | 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 | #------------------------------------------------------------------------- # Check that it is not possible to open a database file if the full path # to the associated journal file will be longer than sqlite3_vfs.mxPathname. # testvfs tv -default 1 tv script xOpenCb tv filter xOpen proc xOpenCb {method filename args} { set ::file_len [string length $filename] } sqlite3 db test.db db close tv delete for {set ii [expr $::file_len-5]} {$ii < [expr $::file_len+20]} {incr ii} { |
︙ | ︙ |
Changes to test/uri.test.
︙ | ︙ | |||
11 12 13 14 15 16 17 | # set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix uri db close | < > > > | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | # set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix uri db close sqlite3_shutdown sqlite3_config_uri 1 #------------------------------------------------------------------------- # Test that file names are correctly extracted from URIs. # foreach {tn uri file} { 1 test.db test.db 2 file:test.db test.db 3 file://an-authorityPWD/test.db test.db 4 file:PWD/test.db test.db 5 file:test.db?mork=1 test.db 6 file:test.db?mork=1&tonglor=2 test.db 7 file:test.db?mork=1#boris test.db 8 file:test.db#boris test.db 9 test.db#boris test.db#boris 10 test.db?mork=1#boris test.db?mork=1#boris 11 file:test%2Edb test.db 12 file file 13 http:test.db http:test.db 14 file://xyzPWD/test.db%3Fhello test.db?hello 15 file:test.db%00extra test.db 16 file:test%00.db%00extra test } { set uri [string map [list PWD [pwd]] $uri] set file [string map [list PWD [pwd]] $file] forcedelete $file do_test 1.$tn.1 { file exists $file } 0 set DB [sqlite3_open $uri] |
︙ | ︙ | |||
54 55 56 57 58 59 60 | # testvfs tvfs -default 1 tvfs filter xOpen tvfs script open_method proc open_method {method file arglist} { set ::arglist $arglist } | < | | | | > > > > > > > > > > > > > > > > | 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | # testvfs tvfs -default 1 tvfs filter xOpen tvfs script open_method proc open_method {method file arglist} { set ::arglist $arglist } foreach {tn uri kvlist} { 1 file:test.db?hello=world {hello world} 2 file:test.db?hello&world {hello {} world {}} 3 file:test.db?hello=1&world=2&vfs=tvfs {hello 1 world 2 vfs tvfs} 4 file:test.db?hello=1&world=2&vfs=unix {} 5 file:test.db?%68%65%6C%6C%6F=%77%6F%72%6C%64 {hello world} 6 file:test%00.db?hello%00extra=world%00ex {hello world} 7 file:test%00.db?hello%00=world%00 {hello world} 8 file:test%00.db?=world&xyz=abc {xyz abc} 9 file:test.db?%00hello=world&xyz=abc {xyz abc} 10 file:test.db?hello=%00world&xyz= {hello {} xyz {}} 11 file:test.db?=#ravada {} 12 file:test.db?&&&&&&&&hello=world&&&&&&& {hello world} } { set ::arglist "" set DB [sqlite3_open $uri] do_test 2.$tn { set ::arglist } $kvlist sqlite3_close $DB } tvfs delete #------------------------------------------------------------------------- # Test that specifying a non-existent VFS raises an error. # do_test 3.1 { list [catch { sqlite3 db "file:test.db?vfs=nosuchvfs" } msg] $msg } {1 {no such vfs: nosuchvfs}} finish_test |