fts5secure.test 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
  1. # 2023 Feb 17
  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. #
  12. source [file join [file dirname [info script]] fts5_common.tcl]
  13. ifcapable !fts5 { finish_test ; return }
  14. set ::testprefix fts5secure
  15. proc dump {tname} {
  16. execsql_pp "SELECT * FROM ${tname}_idx"
  17. execsql_pp "SELECT id, quote(block), fts5_decode(id,block) FROM ${tname}_data"
  18. }
  19. do_execsql_test 0.0 {
  20. CREATE VIRTUAL TABLE t1 USING fts5(ab);
  21. CREATE VIRTUAL TABLE v1 USING fts5vocab('t1', 'instance');
  22. INSERT INTO t1(rowid, ab) VALUES
  23. (0,'abc'), (1,'abc'), (2,'abc'), (3,'abc'), (4,'def');
  24. }
  25. do_execsql_test 0.1 {
  26. INSERT INTO t1(t1, rank) VALUES('secure-delete', 1);
  27. }
  28. do_execsql_test 0.2 {
  29. DELETE FROM t1 WHERE rowid=2;
  30. }
  31. do_execsql_test 0.3 {
  32. SELECT count(*) FROM t1_data
  33. } 3
  34. do_execsql_test 0.4 {
  35. INSERT INTO t1(t1) VALUES('integrity-check');
  36. }
  37. do_execsql_test 0.5 {
  38. DELETE FROM t1 WHERE rowid=3;
  39. }
  40. do_execsql_test 0.6 {
  41. INSERT INTO t1(t1) VALUES('integrity-check');
  42. }
  43. do_execsql_test 0.7 {
  44. DELETE FROM t1 WHERE rowid=0;
  45. }
  46. do_execsql_test 0.8 {
  47. INSERT INTO t1(t1) VALUES('integrity-check');
  48. }
  49. #----------------------------------
  50. do_execsql_test 1.0 {
  51. CREATE VIRTUAL TABLE t2 USING fts5(ab);
  52. INSERT INTO t2(rowid, ab) VALUES (5, 'key'), (6, 'value');
  53. INSERT INTO t2(t2, rank) VALUES('secure-delete', 1);
  54. }
  55. #execsql_pp { SELECT id, quote(block) FROM t1_data }
  56. #execsql_pp { SELECT segid, quote(term), pgno FROM t1_idx }
  57. do_execsql_test 1.1 {
  58. DELETE FROM t2 WHERE rowid = 5;
  59. }
  60. do_execsql_test 1.2 {
  61. INSERT INTO t2(t2) VALUES('integrity-check');
  62. }
  63. do_execsql_test 1.3 {
  64. DELETE FROM t2 WHERE rowid = 6;
  65. }
  66. do_execsql_test 1.4 {
  67. INSERT INTO t2(t2) VALUES('integrity-check');
  68. }
  69. do_execsql_test 1.5 {
  70. SELECT * FROM t2('value');
  71. SELECT * FROM t2('v*');
  72. }
  73. do_execsql_test 1.6 {
  74. SELECT * FROM t2('value') ORDER BY rowid DESC;
  75. SELECT * FROM t2('v*') ORDER BY rowid DESC;
  76. }
  77. execsql_pp {
  78. SELECT id, quote(block) FROM t2_data;
  79. }
  80. #----------------------------------
  81. do_execsql_test 2.0 {
  82. CREATE VIRTUAL TABLE ft USING fts5(ab);
  83. CREATE VIRTUAL TABLE vocab USING fts5vocab('ft', 'instance');
  84. INSERT INTO ft(rowid, ab) VALUES
  85. (1, 'one'),
  86. (2, 'two'),
  87. (3, 'three'),
  88. (4, 'four'),
  89. (5, 'one one'),
  90. (6, 'one two'),
  91. (7, 'one three'),
  92. (8, 'one four'),
  93. (9, 'two one'),
  94. (10, 'two two'),
  95. (11, 'two three'),
  96. (12, 'two four'),
  97. (13, 'three one'),
  98. (14, 'three two'),
  99. (15, 'three three'),
  100. (16, 'three four');
  101. }
  102. do_execsql_test 2.1 {
  103. SELECT count(*) FROM ft_data;
  104. } {3}
  105. do_execsql_test 2.2 {
  106. INSERT INTO ft(ft, rank) VALUES('secure-delete', 1);
  107. }
  108. do_execsql_test 2.3 {
  109. DELETE FROM ft WHERE rowid=9;
  110. }
  111. do_execsql_test 2.4 {
  112. INSERT INTO ft(ft) VALUES('integrity-check');
  113. }
  114. do_execsql_test 2.5 {
  115. DELETE FROM ft WHERE ab LIKE '%two%'
  116. }
  117. do_execsql_test 2.6 {
  118. INSERT INTO ft(ft) VALUES('integrity-check');
  119. }
  120. do_execsql_test 2.7 {
  121. SELECT count(*) FROM ft_data;
  122. } {3}
  123. #----------------------------------
  124. reset_db
  125. set ::vocab {
  126. one two three four five six seven eight nine ten
  127. eleven twelve thirteen fourteen fifteen sixteen
  128. seventeen eighteen nineteen twenty
  129. }
  130. proc rnddoc {} {
  131. set nVocab [llength $::vocab]
  132. set ret [list]
  133. for {set ii 0} {$ii < 8} {incr ii} {
  134. lappend ret [lindex $::vocab [expr int(abs(rand()) * $nVocab)]]
  135. }
  136. set ret
  137. }
  138. proc contains {list val} {
  139. expr {[lsearch $list $val]>=0}
  140. }
  141. foreach {tn pgsz} {
  142. 2 64
  143. 1 1000
  144. } {
  145. reset_db
  146. db function rnddoc rnddoc
  147. db function contains contains
  148. expr srand(1)
  149. do_execsql_test 3.$tn.0 {
  150. CREATE VIRTUAL TABLE t1 USING fts5(x);
  151. INSERT INTO t1(t1, rank) VALUES('pgsz', $pgsz);
  152. WITH s(i) AS (
  153. VALUES(1) UNION SELECT i+1 FROM s WHERE i<20
  154. )
  155. INSERT INTO t1 SELECT rnddoc() FROM s;
  156. }
  157. do_execsql_test 3.$tn.1 {
  158. INSERT INTO t1(t1, rank) VALUES('secure-delete', 1);
  159. }
  160. foreach {rowid} {
  161. 6 16 3 4 9 14 13 7 20 15 19 10 11 2 5 18 17 1 12 8
  162. } {
  163. do_execsql_test 3.$tn.2.$rowid {
  164. DELETE FROM t1 WHERE rowid=$rowid;
  165. }
  166. do_execsql_test 3.$tn.2.$rowid.ic {
  167. INSERT INTO t1(t1) VALUES('integrity-check');
  168. }
  169. foreach v $::vocab {
  170. do_execsql_test 3.$tn.2.$rowid.q.$v {
  171. SELECT rowid FROM t1($v)
  172. } [db eval {SELECT rowid FROM t1 WHERE contains(x, $v)}]
  173. do_execsql_test 3.$tn.2.$rowid.q.$v.DESC {
  174. SELECT rowid FROM t1($v) ORDER BY 1 DESC
  175. } [db eval {SELECT rowid FROM t1 WHERE contains(x, $v) ORDER BY 1 DESC}]
  176. }
  177. }
  178. }
  179. do_execsql_test 3.3 {
  180. INSERT INTO t1(x) VALUES('optimize');
  181. INSERT INTO t1(t1) VALUES('optimize');
  182. SELECT count(*) FROM t1_data;
  183. } {3}
  184. #----------------------------------
  185. reset_db
  186. do_execsql_test 4.0 {
  187. CREATE VIRTUAL TABLE t1 USING fts5(x);
  188. INSERT INTO t1(t1, rank) VALUES('pgsz', 32);
  189. INSERT INTO t1(t1, rank) VALUES('secure-delete', 1);
  190. }
  191. set L1 [string repeat abcdefghij 10]
  192. set L2 [string repeat 1234567890 10]
  193. do_execsql_test 4.1 {
  194. INSERT INTO t1 VALUES('aa' || $L1 || ' ' || $L2);
  195. }
  196. do_execsql_test 4.2 {
  197. DELETE FROM t1 WHERE rowid=1
  198. }
  199. do_execsql_test 4.3 {
  200. INSERT INTO t1(t1) VALUES('integrity-check');
  201. }
  202. #----------------------------------
  203. reset_db
  204. do_execsql_test 5.0 {
  205. CREATE VIRTUAL TABLE t1 USING fts5(x);
  206. INSERT INTO t1(t1, rank) VALUES('pgsz', 32);
  207. INSERT INTO t1(t1, rank) VALUES('secure-delete', 1);
  208. }
  209. set doc "aa [string repeat {abc } 60]"
  210. do_execsql_test 5.1 {
  211. BEGIN;
  212. INSERT INTO t1 VALUES($doc);
  213. INSERT INTO t1 VALUES('aa abc');
  214. COMMIT;
  215. }
  216. do_execsql_test 5.2 {
  217. DELETE FROM t1 WHERE rowid = 1;
  218. }
  219. do_execsql_test 5.3 {
  220. INSERT INTO t1(t1) VALUES('integrity-check');
  221. }
  222. do_execsql_test 5.4 { SELECT rowid FROM t1('abc'); } 2
  223. do_execsql_test 5.5 { SELECT rowid FROM t1('aa'); } 2
  224. #-------------------------------------------------------------------------
  225. # Tests for the bug fixed by https://sqlite.org/src/info/4b60a1c3
  226. #
  227. reset_db
  228. do_execsql_test 6.0 {
  229. CREATE VIRTUAL TABLE fts USING fts5(content);
  230. INSERT INTO fts(fts, rank) VALUES ('secure-delete', 1);
  231. INSERT INTO fts(rowid, content) VALUES
  232. (3407, 'profile profile profile profile profile profile profile profile pull pulling pulling really');
  233. DELETE FROM fts WHERE rowid IS 3407;
  234. INSERT INTO fts(fts) VALUES ('integrity-check');
  235. }
  236. foreach {tn detail} {
  237. 1 full
  238. 2 column
  239. 3 none
  240. } {
  241. do_execsql_test 6.1.$detail "
  242. DROP TABLE IF EXISTS t1;
  243. CREATE VIRTUAL TABLE t1 USING fts5(x, detail=$detail);
  244. "
  245. do_execsql_test 6.2.$detail {
  246. INSERT INTO t1(t1, rank) VALUES('secure-delete', 1);
  247. }
  248. for {set ii 1} {$ii < 100} {incr ii} {
  249. do_execsql_test 6.3.$detail.$ii.1 {
  250. BEGIN;
  251. INSERT INTO t1(rowid, x) VALUES(10, 'word1');
  252. WITH s(i) AS (
  253. SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<CAST($ii AS integer)
  254. )
  255. INSERT INTO t1(x) SELECT 'word3' FROM s;
  256. COMMIT;
  257. INSERT INTO t1(t1) VALUES('optimize');
  258. }
  259. do_execsql_test 6.3.$detail.$ii.2 {
  260. DELETE FROM t1 WHERE rowid=10;
  261. INSERT INTO t1(t1) VALUES ('integrity-check');
  262. }
  263. do_execsql_test 6.3.$detail.$ii.3 {
  264. DELETE FROM t1;
  265. }
  266. do_execsql_test 6.3.$detail.$ii.4 {
  267. BEGIN;
  268. INSERT INTO t1(rowid, x) VALUES(10, 'tokenA');
  269. WITH s(i) AS (
  270. SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<CAST($ii AS integer)
  271. )
  272. INSERT INTO t1(x) SELECT group_concat('tokenB ') FROM s;
  273. COMMIT;
  274. INSERT INTO t1(t1) VALUES('optimize');
  275. }
  276. do_execsql_test 6.3.$detail.$ii.5 {
  277. DELETE FROM t1 WHERE rowid=10;
  278. INSERT INTO t1(t1) VALUES ('integrity-check');
  279. }
  280. do_execsql_test 6.3.$detail.$ii.6 {
  281. DELETE FROM t1;
  282. }
  283. }
  284. }
  285. finish_test