I'll send a note to the git repo owner as well, but it's worth mentioning to any potential writer of custom ranking function.

Background here: We implemented a custom ranking function, let's call it XRank.  An end user complained that a query along these lines was crashing Sqlite:

CREATE VIRTUAL TABLE t USING fts4 (a,b,tokenize=porter);
INSERT INTO T(docid,a,b) VALUES(1,"gumby", "pokey");
INSERT INTO T(docid,a,b) VALUES(2,"blockhead", "pokey");
INSERT INTO T(docid, a,b) VALUES(2,"goo", "gumby");
SELECT * FROM t WHERE docid IN (1,2) ORDER BY XRank(matchinfo(t)) DESC;

Now once I thought about it, this is an absurd query -- matchinfo returns an empty array if there's no MATCH predicate.  But the standard examples of custom rank functions ASSUME that there will be non-empty match info:

static void rankfunc(sqlite3_context *pCtx, int nVal, sqlite3_value **apVal){
  unsigned int *aMatchinfo =  (unsigned int *)sqlite3_value_blob(apVal[0]);
  nPhrase = aMatchinfo[0]; // SEGFAULT HERE, sqlite3_value_blob returns NULL.

So I added a test of aMatchinfo in my custom function for NULL:
    if(aMatchInfo == 0) {
        sqlite3_result_error(cx, "matchinfo blob data is NULL", -1);

This null test is missing from the "Appendix A" custom ranking function example, as contained in this git repo:


So a naive implementer -- me for example, before this week -- will implement this in such a way that a query SQLite has no objection to will crash any program with SQLite embedded.

So this suggests A) Appendix A needs to be updated B) Any code based on this example needs to be updated.

sqlite-users mailing list

Reply via email to