SQLite

Check-in [9efc120a15]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Add the ability for the authorizer callback to disallow recursive queries.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | common-table-expr
Files: files | file ages | folders
SHA1: 9efc120a1548c03f3d8aabbadf1050ff2a119c31
User & Date: drh 2014-01-16 22:40:02.405
Context
2014-01-17
11:48
Remove some code from resolve.c that was only required for recursive cte references in sub-queries. Also a stray "finish_test" command in pagerfault.test. (check-in: f68c6c4d36 user: dan tags: common-table-expr)
2014-01-16
22:40
Add the ability for the authorizer callback to disallow recursive queries. (check-in: 9efc120a15 user: drh tags: common-table-expr)
21:59
Tweaks to error message text. (check-in: 090a77d978 user: drh tags: common-table-expr)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/select.c.
1810
1811
1812
1813
1814
1815
1816



1817
1818
1819
1820
1821
1822
1823
    int tmp1;                     /* Intermediate table */
    int tmp2;                     /* Next intermediate table */
    int tmp3 = 0;                 /* To ensure unique results if UNION */
    int eDest = SRT_Table;
    SelectDest tmp2dest;
    int i;




    iBreak = sqlite3VdbeMakeLabel(v);
    iCont = sqlite3VdbeMakeLabel(v);

    for(i=0; ALWAYS(i<pSrc->nSrc); i++){
      if( pSrc->a[i].isRecursive ){
        tmp1 = pSrc->a[i].iCursor;
        break;







>
>
>







1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
    int tmp1;                     /* Intermediate table */
    int tmp2;                     /* Next intermediate table */
    int tmp3 = 0;                 /* To ensure unique results if UNION */
    int eDest = SRT_Table;
    SelectDest tmp2dest;
    int i;

    if( sqlite3AuthCheck(pParse, SQLITE_RECURSIVE, 0, 0, 0) ){
      goto multi_select_end;
    }
    iBreak = sqlite3VdbeMakeLabel(v);
    iCont = sqlite3VdbeMakeLabel(v);

    for(i=0; ALWAYS(i<pSrc->nSrc); i++){
      if( pSrc->a[i].isRecursive ){
        tmp1 = pSrc->a[i].iCursor;
        break;
Changes to src/sqlite.h.in.
2557
2558
2559
2560
2561
2562
2563

2564
2565
2566
2567
2568
2569
2570
#define SQLITE_REINDEX              27   /* Index Name      NULL            */
#define SQLITE_ANALYZE              28   /* Table Name      NULL            */
#define SQLITE_CREATE_VTABLE        29   /* Table Name      Module Name     */
#define SQLITE_DROP_VTABLE          30   /* Table Name      Module Name     */
#define SQLITE_FUNCTION             31   /* NULL            Function Name   */
#define SQLITE_SAVEPOINT            32   /* Operation       Savepoint Name  */
#define SQLITE_COPY                  0   /* No longer used */


/*
** CAPI3REF: Tracing And Profiling Functions
**
** These routines register callback functions that can be used for
** tracing and profiling the execution of SQL statements.
**







>







2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
#define SQLITE_REINDEX              27   /* Index Name      NULL            */
#define SQLITE_ANALYZE              28   /* Table Name      NULL            */
#define SQLITE_CREATE_VTABLE        29   /* Table Name      Module Name     */
#define SQLITE_DROP_VTABLE          30   /* Table Name      Module Name     */
#define SQLITE_FUNCTION             31   /* NULL            Function Name   */
#define SQLITE_SAVEPOINT            32   /* Operation       Savepoint Name  */
#define SQLITE_COPY                  0   /* No longer used */
#define SQLITE_RECURSIVE            33   /* NULL            NULL            */

/*
** CAPI3REF: Tracing And Profiling Functions
**
** These routines register callback functions that can be used for
** tracing and profiling the execution of SQL statements.
**
Changes to src/tclsqlite.c.
910
911
912
913
914
915
916

917
918
919
920
921
922
923
    case SQLITE_ALTER_TABLE       : zCode="SQLITE_ALTER_TABLE"; break;
    case SQLITE_REINDEX           : zCode="SQLITE_REINDEX"; break;
    case SQLITE_ANALYZE           : zCode="SQLITE_ANALYZE"; break;
    case SQLITE_CREATE_VTABLE     : zCode="SQLITE_CREATE_VTABLE"; break;
    case SQLITE_DROP_VTABLE       : zCode="SQLITE_DROP_VTABLE"; break;
    case SQLITE_FUNCTION          : zCode="SQLITE_FUNCTION"; break;
    case SQLITE_SAVEPOINT         : zCode="SQLITE_SAVEPOINT"; break;

    default                       : zCode="????"; break;
  }
  Tcl_DStringInit(&str);
  Tcl_DStringAppend(&str, pDb->zAuth, -1);
  Tcl_DStringAppendElement(&str, zCode);
  Tcl_DStringAppendElement(&str, zArg1 ? zArg1 : "");
  Tcl_DStringAppendElement(&str, zArg2 ? zArg2 : "");







>







910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
    case SQLITE_ALTER_TABLE       : zCode="SQLITE_ALTER_TABLE"; break;
    case SQLITE_REINDEX           : zCode="SQLITE_REINDEX"; break;
    case SQLITE_ANALYZE           : zCode="SQLITE_ANALYZE"; break;
    case SQLITE_CREATE_VTABLE     : zCode="SQLITE_CREATE_VTABLE"; break;
    case SQLITE_DROP_VTABLE       : zCode="SQLITE_DROP_VTABLE"; break;
    case SQLITE_FUNCTION          : zCode="SQLITE_FUNCTION"; break;
    case SQLITE_SAVEPOINT         : zCode="SQLITE_SAVEPOINT"; break;
    case SQLITE_RECURSIVE         : zCode="SQLITE_RECURSIVE"; break;
    default                       : zCode="????"; break;
  }
  Tcl_DStringInit(&str);
  Tcl_DStringAppend(&str, pDb->zAuth, -1);
  Tcl_DStringAppendElement(&str, zCode);
  Tcl_DStringAppendElement(&str, zArg1 ? zArg1 : "");
  Tcl_DStringAppendElement(&str, zArg2 ? zArg2 : "");
Changes to test/auth.test.
2076
2077
2078
2079
2080
2081
2082




































2083
2084
2085
2086
2087
2088
2089

  do_test auth-1.308 {
    set authargs
  } {main t5 {} {}}
  execsql {DROP TABLE t5}
} ;# ifcapable altertable





































do_test auth-2.1 {
  proc auth {code arg1 arg2 arg3 arg4} {
    if {$code=="SQLITE_READ" && $arg1=="t3" && $arg2=="x"} {
      return SQLITE_DENY
    }
    return SQLITE_OK
  }







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125

  do_test auth-1.308 {
    set authargs
  } {main t5 {} {}}
  execsql {DROP TABLE t5}
} ;# ifcapable altertable

ifcapable {cte} {
  do_test auth-1.310 {
    proc auth {code arg1 arg2 arg3 arg4} {
      if {$code=="SQLITE_RECURSIVE"} {
        return SQLITE_DENY
      }
      return SQLITE_OK
    }
    db eval {
       DROP TABLE IF EXISTS t1;
       CREATE TABLE t1(a,b);
       INSERT INTO t1 VALUES(1,2),(3,4),(5,6);
    }
  } {}
  do_catchsql_test auth-1.311 {
    WITH
       auth1311(x,y) AS (SELECT a+b, b-a FROM t1)
    SELECT * FROM auth1311 ORDER BY x;
  } {0 {3 1 7 1 11 1}}
  do_catchsql_test auth-1.312 {
    WITH RECURSIVE
       auth1312(x,y) AS (SELECT a+b, b-a FROM t1)
    SELECT x, y FROM auth1312 ORDER BY x;
  } {0 {3 1 7 1 11 1}}
  do_catchsql_test auth-1.313 {
    WITH RECURSIVE
       auth1313(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM auth1313 WHERE x<5)
    SELECT * FROM t1;
  } {0 {1 2 3 4 5 6}}
  do_catchsql_test auth-1.314 {
    WITH RECURSIVE
       auth1314(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM auth1314 WHERE x<5)
    SELECT * FROM t1 LEFT JOIN auth1314;
  } {1 {not authorized}}
} ;# ifcapable cte

do_test auth-2.1 {
  proc auth {code arg1 arg2 arg3 arg4} {
    if {$code=="SQLITE_READ" && $arg1=="t3" && $arg2=="x"} {
      return SQLITE_DENY
    }
    return SQLITE_OK
  }