Handle parser stack overflow when parsing fts5 query expressions. Fix some compiler warnings in fts5 code.
FossilOrigin-Name: bc3f7900d5a06829d123814a5ac7b951bcfc1560
This commit is contained in:
parent
df3a907ecc
commit
22e8356368
@ -86,6 +86,10 @@ extern int sqlite3_fts5_may_be_corrupt;
|
||||
# define UNUSED_PARAM(X) (void)(X)
|
||||
#endif
|
||||
|
||||
#ifndef UNUSED_PARAM2
|
||||
# define UNUSED_PARAM2(X, Y) (void)(X), (void)(Y)
|
||||
#endif
|
||||
|
||||
typedef struct Fts5Global Fts5Global;
|
||||
typedef struct Fts5Colset Fts5Colset;
|
||||
|
||||
@ -676,7 +680,7 @@ int sqlite3Fts5ExprPopulatePoslists(
|
||||
void sqlite3Fts5ExprCheckPoslists(Fts5Expr*, i64);
|
||||
void sqlite3Fts5ExprClearEof(Fts5Expr*);
|
||||
|
||||
int sqlite3Fts5ExprClonePhrase(Fts5Config*, Fts5Expr*, int, Fts5Expr**);
|
||||
int sqlite3Fts5ExprClonePhrase(Fts5Expr*, int, Fts5Expr**);
|
||||
|
||||
int sqlite3Fts5ExprPhraseCollist(Fts5Expr *, int, const u8 **, int *);
|
||||
|
||||
|
@ -158,6 +158,8 @@ static int fts5HighlightCb(
|
||||
int rc = SQLITE_OK;
|
||||
int iPos;
|
||||
|
||||
UNUSED_PARAM2(pToken, nToken);
|
||||
|
||||
if( tflags & FTS5_TOKEN_COLOCATED ) return SQLITE_OK;
|
||||
iPos = p->iPos++;
|
||||
|
||||
@ -391,6 +393,7 @@ static int fts5CountCb(
|
||||
void *pUserData /* Pointer to sqlite3_int64 variable */
|
||||
){
|
||||
sqlite3_int64 *pn = (sqlite3_int64*)pUserData;
|
||||
UNUSED_PARAM2(pApi, pFts);
|
||||
(*pn)++;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
@ -320,8 +320,6 @@ static i64 fts5ExprSynonymRowid(Fts5ExprTerm *pTerm, int bDesc, int *pbEof){
|
||||
*/
|
||||
static int fts5ExprSynonymList(
|
||||
Fts5ExprTerm *pTerm,
|
||||
int bCollist,
|
||||
Fts5Colset *pColset,
|
||||
i64 iRowid,
|
||||
Fts5Buffer *pBuf, /* Use this buffer for space if required */
|
||||
u8 **pa, int *pn
|
||||
@ -405,7 +403,6 @@ static int fts5ExprSynonymList(
|
||||
*/
|
||||
static int fts5ExprPhraseIsMatch(
|
||||
Fts5ExprNode *pNode, /* Node pPhrase belongs to */
|
||||
Fts5Colset *pColset, /* Restrict matches to these columns */
|
||||
Fts5ExprPhrase *pPhrase, /* Phrase object to initialize */
|
||||
int *pbMatch /* OUT: Set to true if really a match */
|
||||
){
|
||||
@ -434,9 +431,7 @@ static int fts5ExprPhraseIsMatch(
|
||||
u8 *a = 0;
|
||||
if( pTerm->pSynonym ){
|
||||
Fts5Buffer buf = {0, 0, 0};
|
||||
rc = fts5ExprSynonymList(
|
||||
pTerm, 0, pColset, pNode->iRowid, &buf, &a, &n
|
||||
);
|
||||
rc = fts5ExprSynonymList(pTerm, pNode->iRowid, &buf, &a, &n);
|
||||
if( rc ){
|
||||
sqlite3_free(a);
|
||||
goto ismatch_out;
|
||||
@ -727,7 +722,7 @@ static int fts5ExprNearTest(
|
||||
Fts5ExprPhrase *pPhrase = pNear->apPhrase[i];
|
||||
if( pPhrase->nTerm>1 || pPhrase->aTerm[0].pSynonym || pNear->pColset ){
|
||||
int bMatch = 0;
|
||||
rc = fts5ExprPhraseIsMatch(pNode, pNear->pColset, pPhrase, &bMatch);
|
||||
rc = fts5ExprPhraseIsMatch(pNode, pPhrase, &bMatch);
|
||||
if( bMatch==0 ) break;
|
||||
}else{
|
||||
Fts5IndexIter *pIter = pPhrase->aTerm[0].pIter;
|
||||
@ -1476,6 +1471,8 @@ static int fts5ParseTokenize(
|
||||
TokenCtx *pCtx = (TokenCtx*)pContext;
|
||||
Fts5ExprPhrase *pPhrase = pCtx->pPhrase;
|
||||
|
||||
UNUSED_PARAM2(iUnused1, iUnused2);
|
||||
|
||||
/* If an error has already occurred, this is a no-op */
|
||||
if( pCtx->rc!=SQLITE_OK ) return pCtx->rc;
|
||||
|
||||
@ -1611,7 +1608,6 @@ Fts5ExprPhrase *sqlite3Fts5ParseTerm(
|
||||
** expression passed as the second argument.
|
||||
*/
|
||||
int sqlite3Fts5ExprClonePhrase(
|
||||
Fts5Config *pConfig,
|
||||
Fts5Expr *pExpr,
|
||||
int iPhrase,
|
||||
Fts5Expr **ppNew
|
||||
@ -1619,14 +1615,10 @@ int sqlite3Fts5ExprClonePhrase(
|
||||
int rc = SQLITE_OK; /* Return code */
|
||||
Fts5ExprPhrase *pOrig; /* The phrase extracted from pExpr */
|
||||
int i; /* Used to iterate through phrase terms */
|
||||
|
||||
Fts5Expr *pNew = 0; /* Expression to return via *ppNew */
|
||||
|
||||
TokenCtx sCtx = {0,0}; /* Context object for fts5ParseTokenize */
|
||||
|
||||
|
||||
pOrig = pExpr->apExprPhrase[iPhrase];
|
||||
|
||||
pNew = (Fts5Expr*)sqlite3Fts5MallocZero(&rc, sizeof(Fts5Expr));
|
||||
if( rc==SQLITE_OK ){
|
||||
pNew->apExprPhrase = (Fts5ExprPhrase**)sqlite3Fts5MallocZero(&rc,
|
||||
@ -2399,13 +2391,15 @@ static int fts5ExprPopulatePoslistsCb(
|
||||
int tflags, /* Mask of FTS5_TOKEN_* flags */
|
||||
const char *pToken, /* Pointer to buffer containing token */
|
||||
int nToken, /* Size of token in bytes */
|
||||
int iStart, /* Byte offset of token within input text */
|
||||
int iEnd /* Byte offset of end of token within input text */
|
||||
int iUnused1, /* Byte offset of token within input text */
|
||||
int iUnused2 /* Byte offset of end of token within input text */
|
||||
){
|
||||
Fts5ExprCtx *p = (Fts5ExprCtx*)pCtx;
|
||||
Fts5Expr *pExpr = p->pExpr;
|
||||
int i;
|
||||
|
||||
UNUSED_PARAM2(iUnused1, iUnused2);
|
||||
|
||||
if( (tflags & FTS5_TOKEN_COLOCATED)==0 ) p->iOff++;
|
||||
for(i=0; i<pExpr->nPhrase; i++){
|
||||
Fts5ExprTerm *pTerm;
|
||||
@ -2550,7 +2544,7 @@ int sqlite3Fts5ExprPhraseCollist(
|
||||
if( pTerm->pSynonym ){
|
||||
Fts5Buffer *pBuf = (Fts5Buffer*)&pTerm->pSynonym[1];
|
||||
rc = fts5ExprSynonymList(
|
||||
pTerm, 1, 0, pNode->iRowid, pBuf, (u8**)ppCollist, pnCollist
|
||||
pTerm, pNode->iRowid, pBuf, (u8**)ppCollist, pnCollist
|
||||
);
|
||||
}else{
|
||||
*ppCollist = pPhrase->aTerm[0].pIter->pData;
|
||||
|
@ -1770,10 +1770,12 @@ static int fts5MultiIterIsEmpty(Fts5Index *p, Fts5Iter *pIter){
|
||||
static void fts5SegIterNext_Reverse(
|
||||
Fts5Index *p, /* FTS5 backend object */
|
||||
Fts5SegIter *pIter, /* Iterator to advance */
|
||||
int *pbNewTerm /* OUT: Set for new term */
|
||||
int *pbUnused /* Unused */
|
||||
){
|
||||
assert( pIter->flags & FTS5_SEGITER_REVERSE );
|
||||
assert( pIter->pNextLeaf==0 );
|
||||
UNUSED_PARAM(pbUnused);
|
||||
|
||||
if( pIter->iRowidOffset>0 ){
|
||||
u8 *a = pIter->pLeaf->p;
|
||||
int iOff;
|
||||
@ -2250,7 +2252,6 @@ static void fts5LeafSeek(
|
||||
*/
|
||||
static void fts5SegIterSeekInit(
|
||||
Fts5Index *p, /* FTS5 backend */
|
||||
Fts5Buffer *pBuf, /* Buffer to use for loading pages */
|
||||
const u8 *pTerm, int nTerm, /* Term to seek to */
|
||||
int flags, /* Mask of FTS5INDEX_XXX flags */
|
||||
Fts5StructureSegment *pSeg, /* Description of segment */
|
||||
@ -2637,7 +2638,7 @@ static void fts5SegIterNextFrom(
|
||||
/*
|
||||
** Free the iterator object passed as the second argument.
|
||||
*/
|
||||
static void fts5MultiIterFree(Fts5Index *p, Fts5Iter *pIter){
|
||||
static void fts5MultiIterFree(Fts5Iter *pIter){
|
||||
if( pIter ){
|
||||
int i;
|
||||
for(i=0; i<pIter->nSeg; i++){
|
||||
@ -2678,7 +2679,6 @@ static void fts5MultiIterAdvanced(
|
||||
** that it deals with more complicated cases as well.
|
||||
*/
|
||||
static int fts5MultiIterAdvanceRowid(
|
||||
Fts5Index *p, /* FTS5 backend to iterate within */
|
||||
Fts5Iter *pIter, /* Iterator to update aFirst[] array for */
|
||||
int iChanged, /* Index of sub-iterator just advanced */
|
||||
Fts5SegIter **ppFirst
|
||||
@ -2753,7 +2753,7 @@ static void fts5MultiIterNext(
|
||||
}
|
||||
|
||||
if( pSeg->pLeaf==0 || bNewTerm
|
||||
|| fts5MultiIterAdvanceRowid(p, pIter, iFirst, &pSeg)
|
||||
|| fts5MultiIterAdvanceRowid(pIter, iFirst, &pSeg)
|
||||
){
|
||||
fts5MultiIterAdvanced(p, pIter, iFirst, 1);
|
||||
fts5MultiIterSetEof(pIter);
|
||||
@ -2786,7 +2786,7 @@ static void fts5MultiIterNext2(
|
||||
assert( p->rc==SQLITE_OK );
|
||||
pSeg->xNext(p, pSeg, &bNewTerm);
|
||||
if( pSeg->pLeaf==0 || bNewTerm
|
||||
|| fts5MultiIterAdvanceRowid(p, pIter, iFirst, &pSeg)
|
||||
|| fts5MultiIterAdvanceRowid(pIter, iFirst, &pSeg)
|
||||
){
|
||||
fts5MultiIterAdvanced(p, pIter, iFirst, 1);
|
||||
fts5MultiIterSetEof(pIter);
|
||||
@ -2800,7 +2800,8 @@ static void fts5MultiIterNext2(
|
||||
}
|
||||
}
|
||||
|
||||
static void fts5IterSetOutputs_Noop(Fts5Iter *pIter, Fts5SegIter *pSeg){
|
||||
static void fts5IterSetOutputs_Noop(Fts5Iter *pUnused1, Fts5SegIter *pUnused2){
|
||||
UNUSED_PARAM2(pUnused1, pUnused2);
|
||||
}
|
||||
|
||||
static Fts5Iter *fts5MultiIterAlloc(
|
||||
@ -2826,10 +2827,11 @@ static Fts5Iter *fts5MultiIterAlloc(
|
||||
}
|
||||
|
||||
static void fts5PoslistCallback(
|
||||
Fts5Index *p,
|
||||
Fts5Index *pUnused,
|
||||
void *pContext,
|
||||
const u8 *pChunk, int nChunk
|
||||
){
|
||||
UNUSED_PARAM(pUnused);
|
||||
assert_nc( nChunk>=0 );
|
||||
if( nChunk>0 ){
|
||||
fts5BufferSafeAppendBlob((Fts5Buffer*)pContext, pChunk, nChunk);
|
||||
@ -2863,11 +2865,12 @@ static int fts5IndexColsetTest(Fts5Colset *pColset, int iCol){
|
||||
}
|
||||
|
||||
static void fts5PoslistOffsetsCallback(
|
||||
Fts5Index *p,
|
||||
Fts5Index *pUnused,
|
||||
void *pContext,
|
||||
const u8 *pChunk, int nChunk
|
||||
){
|
||||
PoslistOffsetsCtx *pCtx = (PoslistOffsetsCtx*)pContext;
|
||||
UNUSED_PARAM(pUnused);
|
||||
assert_nc( nChunk>=0 );
|
||||
if( nChunk>0 ){
|
||||
int i = 0;
|
||||
@ -2885,11 +2888,12 @@ static void fts5PoslistOffsetsCallback(
|
||||
}
|
||||
|
||||
static void fts5PoslistFilterCallback(
|
||||
Fts5Index *p,
|
||||
Fts5Index *pUnused,
|
||||
void *pContext,
|
||||
const u8 *pChunk, int nChunk
|
||||
){
|
||||
PoslistCallbackCtx *pCtx = (PoslistCallbackCtx*)pContext;
|
||||
UNUSED_PARAM(pUnused);
|
||||
assert_nc( nChunk>=0 );
|
||||
if( nChunk>0 ){
|
||||
/* Search through to find the first varint with value 1. This is the
|
||||
@ -3253,7 +3257,6 @@ static void fts5MultiIterNew(
|
||||
int nSeg = 0; /* Number of segment-iters in use */
|
||||
int iIter = 0; /* */
|
||||
int iSeg; /* Used to iterate through segments */
|
||||
Fts5Buffer buf = {0,0,0}; /* Buffer used by fts5SegIterSeekInit() */
|
||||
Fts5StructureLevel *pLvl;
|
||||
Fts5Iter *pNew;
|
||||
|
||||
@ -3296,7 +3299,7 @@ static void fts5MultiIterNew(
|
||||
if( pTerm==0 ){
|
||||
fts5SegIterInit(p, pSeg, pIter);
|
||||
}else{
|
||||
fts5SegIterSeekInit(p, &buf, pTerm, nTerm, flags, pSeg, pIter);
|
||||
fts5SegIterSeekInit(p, pTerm, nTerm, flags, pSeg, pIter);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3333,11 +3336,9 @@ static void fts5MultiIterNew(
|
||||
}
|
||||
|
||||
}else{
|
||||
fts5MultiIterFree(p, pNew);
|
||||
fts5MultiIterFree(pNew);
|
||||
*ppOut = 0;
|
||||
}
|
||||
fts5BufferFree(&buf);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
@ -3475,15 +3476,14 @@ static void fts5IndexDiscardData(Fts5Index *p){
|
||||
}
|
||||
|
||||
/*
|
||||
** Return the size of the prefix, in bytes, that buffer (nNew/pNew) shares
|
||||
** with buffer (nOld/pOld).
|
||||
** Return the size of the prefix, in bytes, that buffer
|
||||
** (pNew/<length-unknown>) shares with buffer (pOld/nOld).
|
||||
**
|
||||
** Buffer (pNew/<length-unknown>) is guaranteed to be greater
|
||||
** than buffer (pOld/nOld).
|
||||
*/
|
||||
static int fts5PrefixCompress(
|
||||
int nOld, const u8 *pOld,
|
||||
int nNew, const u8 *pNew
|
||||
){
|
||||
static int fts5PrefixCompress(int nOld, const u8 *pOld, const u8 *pNew){
|
||||
int i;
|
||||
assert( fts5BlobCompare(pOld, nOld, pNew, nNew)<0 );
|
||||
for(i=0; i<nOld; i++){
|
||||
if( pOld[i]!=pNew[i] ) break;
|
||||
}
|
||||
@ -3793,13 +3793,13 @@ static void fts5WriteAppendTerm(
|
||||
** inefficient, but still correct. */
|
||||
int n = nTerm;
|
||||
if( pPage->term.n ){
|
||||
n = 1 + fts5PrefixCompress(pPage->term.n, pPage->term.p, nTerm, pTerm);
|
||||
n = 1 + fts5PrefixCompress(pPage->term.n, pPage->term.p, pTerm);
|
||||
}
|
||||
fts5WriteBtreeTerm(p, pWriter, n, pTerm);
|
||||
pPage = &pWriter->writer;
|
||||
}
|
||||
}else{
|
||||
nPrefix = fts5PrefixCompress(pPage->term.n, pPage->term.p, nTerm, pTerm);
|
||||
nPrefix = fts5PrefixCompress(pPage->term.n, pPage->term.p, pTerm);
|
||||
fts5BufferAppendVarint(&p->rc, &pPage->buf, nPrefix);
|
||||
}
|
||||
|
||||
@ -4165,7 +4165,7 @@ static void fts5IndexMergeLevel(
|
||||
pLvl->nMerge = nInput;
|
||||
}
|
||||
|
||||
fts5MultiIterFree(p, pIter);
|
||||
fts5MultiIterFree(pIter);
|
||||
fts5BufferFree(&term);
|
||||
if( pnRem ) *pnRem -= writer.nLeafWritten;
|
||||
}
|
||||
@ -4541,9 +4541,10 @@ int sqlite3Fts5IndexMerge(Fts5Index *p, int nMerge){
|
||||
static void fts5AppendRowid(
|
||||
Fts5Index *p,
|
||||
i64 iDelta,
|
||||
Fts5Iter *pMulti,
|
||||
Fts5Iter *pUnused,
|
||||
Fts5Buffer *pBuf
|
||||
){
|
||||
UNUSED_PARAM(pUnused);
|
||||
fts5BufferAppendVarint(&p->rc, pBuf, iDelta);
|
||||
}
|
||||
|
||||
@ -4886,7 +4887,7 @@ static void fts5SetupPrefixIter(
|
||||
}
|
||||
fts5BufferFree(&aBuf[i]);
|
||||
}
|
||||
fts5MultiIterFree(p, p1);
|
||||
fts5MultiIterFree(p1);
|
||||
|
||||
pData = fts5IdxMalloc(p, sizeof(Fts5Data) + doclist.n);
|
||||
if( pData ){
|
||||
@ -5167,7 +5168,7 @@ int sqlite3Fts5IndexQuery(
|
||||
int bDesc = (flags & FTS5INDEX_QUERY_DESC)!=0;
|
||||
buf.p[0] = FTS5_MAIN_PREFIX;
|
||||
fts5SetupPrefixIter(p, bDesc, buf.p, nToken+1, pColset, &pRet);
|
||||
assert( pRet->pColset==0 );
|
||||
assert( p->rc!=SQLITE_OK || pRet->pColset==0 );
|
||||
fts5IterSetOutputCb(&p->rc, pRet);
|
||||
if( p->rc==SQLITE_OK ){
|
||||
Fts5SegIter *pSeg = &pRet->aSeg[pRet->aFirst[1].iFirst];
|
||||
@ -5250,7 +5251,7 @@ void sqlite3Fts5IterClose(Fts5IndexIter *pIndexIter){
|
||||
if( pIndexIter ){
|
||||
Fts5Iter *pIter = (Fts5Iter*)pIndexIter;
|
||||
Fts5Index *pIndex = pIter->pIndex;
|
||||
fts5MultiIterFree(pIter->pIndex, pIter);
|
||||
fts5MultiIterFree(pIter);
|
||||
fts5CloseReader(pIndex);
|
||||
}
|
||||
}
|
||||
@ -5809,7 +5810,7 @@ int sqlite3Fts5IndexIntegrityCheck(Fts5Index *p, u64 cksum){
|
||||
}
|
||||
fts5TestTerm(p, &term, 0, 0, cksum2, &cksum3);
|
||||
|
||||
fts5MultiIterFree(p, pIter);
|
||||
fts5MultiIterFree(pIter);
|
||||
if( p->rc==SQLITE_OK && cksum!=cksum2 ) p->rc = FTS5_CORRUPT;
|
||||
|
||||
fts5StructureRelease(pStruct);
|
||||
@ -6046,6 +6047,7 @@ static void fts5DecodeFunction(
|
||||
int eDetailNone = (sqlite3_user_data(pCtx)!=0);
|
||||
|
||||
assert( nArg==2 );
|
||||
UNUSED_PARAM(nArg);
|
||||
memset(&s, 0, sizeof(Fts5Buffer));
|
||||
iRowid = sqlite3_value_int64(apVal[0]);
|
||||
|
||||
|
@ -1096,7 +1096,7 @@ static i64 fts5GetRowidLimit(sqlite3_value *pVal, i64 iDefault){
|
||||
static int fts5FilterMethod(
|
||||
sqlite3_vtab_cursor *pCursor, /* The cursor used for this query */
|
||||
int idxNum, /* Strategy index */
|
||||
const char *idxStr, /* Unused */
|
||||
const char *zUnused, /* Unused */
|
||||
int nVal, /* Number of elements in apVal */
|
||||
sqlite3_value **apVal /* Arguments for the indexing scheme */
|
||||
){
|
||||
@ -1114,6 +1114,9 @@ static int fts5FilterMethod(
|
||||
sqlite3_value *pRowidGe = 0; /* rowid >= ? expression (or NULL) */
|
||||
char **pzErrmsg = pConfig->pzErrmsg;
|
||||
|
||||
UNUSED_PARAM(zUnused);
|
||||
UNUSED_PARAM(nVal);
|
||||
|
||||
if( pCsr->ePlan ){
|
||||
fts5FreeCursorComponents(pCsr);
|
||||
memset(&pCsr->ePlan, 0, sizeof(Fts5Cursor) - ((u8*)&pCsr->ePlan-(u8*)pCsr));
|
||||
@ -1398,8 +1401,7 @@ static int fts5SpecialInsert(
|
||||
|
||||
static int fts5SpecialDelete(
|
||||
Fts5Table *pTab,
|
||||
sqlite3_value **apVal,
|
||||
sqlite3_int64 *piRowid
|
||||
sqlite3_value **apVal
|
||||
){
|
||||
int rc = SQLITE_OK;
|
||||
int eType1 = sqlite3_value_type(apVal[1]);
|
||||
@ -1475,7 +1477,7 @@ static int fts5UpdateMethod(
|
||||
if( pConfig->eContent!=FTS5_CONTENT_NORMAL
|
||||
&& 0==sqlite3_stricmp("delete", z)
|
||||
){
|
||||
rc = fts5SpecialDelete(pTab, apVal, pRowid);
|
||||
rc = fts5SpecialDelete(pTab, apVal);
|
||||
}else{
|
||||
rc = fts5SpecialInsert(pTab, z, apVal[2 + pConfig->nCol + 1]);
|
||||
}
|
||||
@ -1576,6 +1578,7 @@ static int fts5SyncMethod(sqlite3_vtab *pVtab){
|
||||
** Implementation of xBegin() method.
|
||||
*/
|
||||
static int fts5BeginMethod(sqlite3_vtab *pVtab){
|
||||
UNUSED_PARAM(pVtab); /* Call below is a no-op for NDEBUG builds */
|
||||
fts5CheckTransactionState((Fts5Table*)pVtab, FTS5_BEGIN, 0);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
@ -1586,6 +1589,7 @@ static int fts5BeginMethod(sqlite3_vtab *pVtab){
|
||||
** by fts5SyncMethod().
|
||||
*/
|
||||
static int fts5CommitMethod(sqlite3_vtab *pVtab){
|
||||
UNUSED_PARAM(pVtab); /* Call below is a no-op for NDEBUG builds */
|
||||
fts5CheckTransactionState((Fts5Table*)pVtab, FTS5_COMMIT, 0);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
@ -1839,12 +1843,14 @@ static sqlite3_int64 fts5ApiRowid(Fts5Context *pCtx){
|
||||
static int fts5ColumnSizeCb(
|
||||
void *pContext, /* Pointer to int */
|
||||
int tflags,
|
||||
const char *pToken, /* Buffer containing token */
|
||||
int nToken, /* Size of token in bytes */
|
||||
int iStart, /* Start offset of token */
|
||||
int iEnd /* End offset of token */
|
||||
const char *pUnused, /* Buffer containing token */
|
||||
int nUnused, /* Size of token in bytes */
|
||||
int iUnused1, /* Start offset of token */
|
||||
int iUnused2 /* End offset of token */
|
||||
){
|
||||
int *pCnt = (int*)pContext;
|
||||
UNUSED_PARAM2(pUnused, nUnused);
|
||||
UNUSED_PARAM2(iUnused1, iUnused2);
|
||||
if( (tflags & FTS5_TOKEN_COLOCATED)==0 ){
|
||||
(*pCnt)++;
|
||||
}
|
||||
@ -1960,10 +1966,11 @@ static void *fts5ApiGetAuxdata(Fts5Context *pCtx, int bClear){
|
||||
}
|
||||
|
||||
static void fts5ApiPhraseNext(
|
||||
Fts5Context *pCtx,
|
||||
Fts5Context *pUnused,
|
||||
Fts5PhraseIter *pIter,
|
||||
int *piCol, int *piOff
|
||||
){
|
||||
UNUSED_PARAM(pUnused);
|
||||
if( pIter->a>=pIter->b ){
|
||||
*piCol = -1;
|
||||
*piOff = -1;
|
||||
@ -2115,12 +2122,11 @@ static int fts5ApiQueryPhrase(
|
||||
|
||||
rc = fts5OpenMethod(pCsr->base.pVtab, (sqlite3_vtab_cursor**)&pNew);
|
||||
if( rc==SQLITE_OK ){
|
||||
Fts5Config *pConf = pTab->pConfig;
|
||||
pNew->ePlan = FTS5_PLAN_MATCH;
|
||||
pNew->iFirstRowid = SMALLEST_INT64;
|
||||
pNew->iLastRowid = LARGEST_INT64;
|
||||
pNew->base.pVtab = (sqlite3_vtab*)pTab;
|
||||
rc = sqlite3Fts5ExprClonePhrase(pConf, pCsr->pExpr, iPhrase, &pNew->pExpr);
|
||||
rc = sqlite3Fts5ExprClonePhrase(pCsr->pExpr, iPhrase, &pNew->pExpr);
|
||||
}
|
||||
|
||||
if( rc==SQLITE_OK ){
|
||||
@ -2333,7 +2339,7 @@ static int fts5ColumnMethod(
|
||||
*/
|
||||
static int fts5FindFunctionMethod(
|
||||
sqlite3_vtab *pVtab, /* Virtual table handle */
|
||||
int nArg, /* Number of SQL function arguments */
|
||||
int nUnused, /* Number of SQL function arguments */
|
||||
const char *zName, /* Name of SQL function */
|
||||
void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), /* OUT: Result */
|
||||
void **ppArg /* OUT: User data for *pxFunc */
|
||||
@ -2341,6 +2347,7 @@ static int fts5FindFunctionMethod(
|
||||
Fts5Table *pTab = (Fts5Table*)pVtab;
|
||||
Fts5Auxiliary *pAux;
|
||||
|
||||
UNUSED_PARAM(nUnused);
|
||||
pAux = fts5FindAuxiliary(pTab, zName);
|
||||
if( pAux ){
|
||||
*pxFunc = fts5ApiCallback;
|
||||
@ -2370,6 +2377,7 @@ static int fts5RenameMethod(
|
||||
*/
|
||||
static int fts5SavepointMethod(sqlite3_vtab *pVtab, int iSavepoint){
|
||||
Fts5Table *pTab = (Fts5Table*)pVtab;
|
||||
UNUSED_PARAM(iSavepoint); /* Call below is a no-op for NDEBUG builds */
|
||||
fts5CheckTransactionState(pTab, FTS5_SAVEPOINT, iSavepoint);
|
||||
fts5TripCursors(pTab);
|
||||
return sqlite3Fts5StorageSync(pTab->pStorage, 0);
|
||||
@ -2382,6 +2390,7 @@ static int fts5SavepointMethod(sqlite3_vtab *pVtab, int iSavepoint){
|
||||
*/
|
||||
static int fts5ReleaseMethod(sqlite3_vtab *pVtab, int iSavepoint){
|
||||
Fts5Table *pTab = (Fts5Table*)pVtab;
|
||||
UNUSED_PARAM(iSavepoint); /* Call below is a no-op for NDEBUG builds */
|
||||
fts5CheckTransactionState(pTab, FTS5_RELEASE, iSavepoint);
|
||||
fts5TripCursors(pTab);
|
||||
return sqlite3Fts5StorageSync(pTab->pStorage, 0);
|
||||
@ -2394,6 +2403,7 @@ static int fts5ReleaseMethod(sqlite3_vtab *pVtab, int iSavepoint){
|
||||
*/
|
||||
static int fts5RollbackToMethod(sqlite3_vtab *pVtab, int iSavepoint){
|
||||
Fts5Table *pTab = (Fts5Table*)pVtab;
|
||||
UNUSED_PARAM(iSavepoint); /* Call below is a no-op for NDEBUG builds */
|
||||
fts5CheckTransactionState(pTab, FTS5_ROLLBACKTO, iSavepoint);
|
||||
fts5TripCursors(pTab);
|
||||
return sqlite3Fts5StorageRollback(pTab->pStorage);
|
||||
@ -2573,10 +2583,11 @@ static void fts5ModuleDestroy(void *pCtx){
|
||||
static void fts5Fts5Func(
|
||||
sqlite3_context *pCtx, /* Function call context */
|
||||
int nArg, /* Number of args */
|
||||
sqlite3_value **apVal /* Function arguments */
|
||||
sqlite3_value **apUnused /* Function arguments */
|
||||
){
|
||||
Fts5Global *pGlobal = (Fts5Global*)sqlite3_user_data(pCtx);
|
||||
char buf[8];
|
||||
UNUSED_PARAM2(nArg, apUnused);
|
||||
assert( nArg==0 );
|
||||
assert( sizeof(buf)>=sizeof(pGlobal) );
|
||||
memcpy(buf, (void*)&pGlobal, sizeof(pGlobal));
|
||||
@ -2589,9 +2600,10 @@ static void fts5Fts5Func(
|
||||
static void fts5SourceIdFunc(
|
||||
sqlite3_context *pCtx, /* Function call context */
|
||||
int nArg, /* Number of args */
|
||||
sqlite3_value **apVal /* Function arguments */
|
||||
sqlite3_value **apUnused /* Function arguments */
|
||||
){
|
||||
assert( nArg==0 );
|
||||
UNUSED_PARAM2(nArg, apUnused);
|
||||
sqlite3_result_text(pCtx, "--FTS5-SOURCE-ID--", -1, SQLITE_TRANSIENT);
|
||||
}
|
||||
|
||||
|
@ -362,11 +362,12 @@ static int fts5StorageInsertCallback(
|
||||
int tflags,
|
||||
const char *pToken, /* Buffer containing token */
|
||||
int nToken, /* Size of token in bytes */
|
||||
int iStart, /* Start offset of token */
|
||||
int iEnd /* End offset of token */
|
||||
int iUnused1, /* Start offset of token */
|
||||
int iUnused2 /* End offset of token */
|
||||
){
|
||||
Fts5InsertCtx *pCtx = (Fts5InsertCtx*)pContext;
|
||||
Fts5Index *pIdx = pCtx->pStorage->pIndex;
|
||||
UNUSED_PARAM2(iUnused1, iUnused2);
|
||||
if( (tflags & FTS5_TOKEN_COLOCATED)==0 || pCtx->szCol==0 ){
|
||||
pCtx->szCol++;
|
||||
}
|
||||
@ -797,8 +798,8 @@ static int fts5StorageIntegrityCallback(
|
||||
int tflags,
|
||||
const char *pToken, /* Buffer containing token */
|
||||
int nToken, /* Size of token in bytes */
|
||||
int iStart, /* Start offset of token */
|
||||
int iEnd /* End offset of token */
|
||||
int iUnused1, /* Start offset of token */
|
||||
int iUnused2 /* End offset of token */
|
||||
){
|
||||
Fts5IntegrityCtx *pCtx = (Fts5IntegrityCtx*)pContext;
|
||||
Fts5Termset *pTermset = pCtx->pTermset;
|
||||
@ -808,6 +809,8 @@ static int fts5StorageIntegrityCallback(
|
||||
int iPos;
|
||||
int iCol;
|
||||
|
||||
UNUSED_PARAM2(iUnused1, iUnused2);
|
||||
|
||||
if( (tflags & FTS5_TOKEN_COLOCATED)==0 || pCtx->szCol==0 ){
|
||||
pCtx->szCol++;
|
||||
}
|
||||
|
@ -62,12 +62,13 @@ static void fts5AsciiDelete(Fts5Tokenizer *p){
|
||||
** Create an "ascii" tokenizer.
|
||||
*/
|
||||
static int fts5AsciiCreate(
|
||||
void *pCtx,
|
||||
void *pUnused,
|
||||
const char **azArg, int nArg,
|
||||
Fts5Tokenizer **ppOut
|
||||
){
|
||||
int rc = SQLITE_OK;
|
||||
AsciiTokenizer *p = 0;
|
||||
UNUSED_PARAM(pUnused);
|
||||
if( nArg%2 ){
|
||||
rc = SQLITE_ERROR;
|
||||
}else{
|
||||
@ -116,7 +117,7 @@ static void asciiFold(char *aOut, const char *aIn, int nByte){
|
||||
static int fts5AsciiTokenize(
|
||||
Fts5Tokenizer *pTokenizer,
|
||||
void *pCtx,
|
||||
int flags,
|
||||
int iUnused,
|
||||
const char *pText, int nText,
|
||||
int (*xToken)(void*, int, const char*, int nToken, int iStart, int iEnd)
|
||||
){
|
||||
@ -130,6 +131,8 @@ static int fts5AsciiTokenize(
|
||||
char *pFold = aFold;
|
||||
unsigned char *a = p->aTokenChar;
|
||||
|
||||
UNUSED_PARAM(iUnused);
|
||||
|
||||
while( is<nText && rc==SQLITE_OK ){
|
||||
int nByte;
|
||||
|
||||
@ -323,13 +326,15 @@ static void fts5UnicodeDelete(Fts5Tokenizer *pTok){
|
||||
** Create a "unicode61" tokenizer.
|
||||
*/
|
||||
static int fts5UnicodeCreate(
|
||||
void *pCtx,
|
||||
void *pUnused,
|
||||
const char **azArg, int nArg,
|
||||
Fts5Tokenizer **ppOut
|
||||
){
|
||||
int rc = SQLITE_OK; /* Return code */
|
||||
Unicode61Tokenizer *p = 0; /* New tokenizer object */
|
||||
|
||||
UNUSED_PARAM(pUnused);
|
||||
|
||||
if( nArg%2 ){
|
||||
rc = SQLITE_ERROR;
|
||||
}else{
|
||||
@ -386,7 +391,7 @@ static int fts5UnicodeIsAlnum(Unicode61Tokenizer *p, int iCode){
|
||||
static int fts5UnicodeTokenize(
|
||||
Fts5Tokenizer *pTokenizer,
|
||||
void *pCtx,
|
||||
int flags,
|
||||
int iUnused,
|
||||
const char *pText, int nText,
|
||||
int (*xToken)(void*, int, const char*, int nToken, int iStart, int iEnd)
|
||||
){
|
||||
@ -402,6 +407,8 @@ static int fts5UnicodeTokenize(
|
||||
int nFold = p->nFold;
|
||||
const char *pEnd = &aFold[nFold-6];
|
||||
|
||||
UNUSED_PARAM(iUnused);
|
||||
|
||||
/* Each iteration of this loop gobbles up a contiguous run of separators,
|
||||
** then the next token. */
|
||||
while( rc==SQLITE_OK ){
|
||||
|
@ -237,7 +237,7 @@ static int fts5VocabCreateMethod(
|
||||
** Implementation of the xBestIndex method.
|
||||
*/
|
||||
static int fts5VocabBestIndexMethod(
|
||||
sqlite3_vtab *pVTab,
|
||||
sqlite3_vtab *pUnused,
|
||||
sqlite3_index_info *pInfo
|
||||
){
|
||||
int i;
|
||||
@ -247,6 +247,8 @@ static int fts5VocabBestIndexMethod(
|
||||
int idxNum = 0;
|
||||
int nArg = 0;
|
||||
|
||||
UNUSED_PARAM(pUnused);
|
||||
|
||||
for(i=0; i<pInfo->nConstraint; i++){
|
||||
struct sqlite3_index_constraint *p = &pInfo->aConstraint[i];
|
||||
if( p->usable==0 ) continue;
|
||||
@ -488,8 +490,8 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){
|
||||
static int fts5VocabFilterMethod(
|
||||
sqlite3_vtab_cursor *pCursor, /* The cursor used for this query */
|
||||
int idxNum, /* Strategy index */
|
||||
const char *idxStr, /* Unused */
|
||||
int nVal, /* Number of elements in apVal */
|
||||
const char *zUnused, /* Unused */
|
||||
int nUnused, /* Number of elements in apVal */
|
||||
sqlite3_value **apVal /* Arguments for the indexing scheme */
|
||||
){
|
||||
Fts5VocabCursor *pCsr = (Fts5VocabCursor*)pCursor;
|
||||
@ -504,6 +506,8 @@ static int fts5VocabFilterMethod(
|
||||
sqlite3_value *pGe = 0;
|
||||
sqlite3_value *pLe = 0;
|
||||
|
||||
UNUSED_PARAM2(zUnused, nUnused);
|
||||
|
||||
fts5VocabResetCursor(pCsr);
|
||||
if( idxNum & FTS5_VOCAB_TERM_EQ ) pEq = apVal[iVal++];
|
||||
if( idxNum & FTS5_VOCAB_TERM_GE ) pGe = apVal[iVal++];
|
||||
|
@ -33,7 +33,8 @@
|
||||
);
|
||||
}
|
||||
%stack_overflow {
|
||||
assert( 0 );
|
||||
UNUSED_PARAM(yypMinor); /* Silence some compiler warnings */
|
||||
sqlite3Fts5ParseError(pParse, "fts5: parser stack overflow");
|
||||
}
|
||||
|
||||
// The name of the generated procedure that implements the parser
|
||||
|
@ -399,5 +399,15 @@ do_execsql_test 18.1 {
|
||||
SELECT rowid FROM x4('""');
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
do_execsql_test 19.1 {
|
||||
CREATE VIRTUAL TABLE x1 USING fts5(a,b,c);
|
||||
}
|
||||
|
||||
do_catchsql_test 19.2 {
|
||||
SELECT * FROM x1 WHERE x1 MATCH 'c0 AND (c1 AND (c2 AND (c3 AND (c4 AND (c5 AND (c6 AND (c7 AND (c8 AND (c9 AND (c10 AND (c11 AND (c12 AND (c13 AND (c14 AND (c15 AND (c16 AND (c17 AND (c18 AND (c19 AND (c20 AND (c21 AND (c22 AND (c23 AND (c24 AND (c25 AND (c26 AND (c27 AND (c28 AND (c29 AND (c30 AND (c31 AND (c32 AND (c33 AND (c34 AND (c35 AND (c36 AND (c37 AND (c38 AND (c39 AND (c40 AND (c41 AND (c42 AND (c43 AND (c44 AND (c45 AND (c46 AND (c47 AND (c48 AND (c49 AND (c50 AND (c51 AND (c52 AND (c53 AND (c54 AND (c55 AND (c56 AND (c57 AND (c58 AND (c59 AND (c60 AND (c61 AND (c62 AND (c63 AND (c64 AND (c65 AND (c66 AND (c67 AND (c68 AND (c69 AND (c70 AND (c71 AND (c72 AND (c73 AND (c74 AND (c75 AND (c76 AND (c77 AND (c78 AND (c79 AND (c80 AND (c81 AND (c82 AND (c83 AND (c84 AND (c85 AND (c86 AND (c87 AND (c88 AND (c89 AND (c90 AND (c91 AND (c92 AND (c93 AND (c94 AND (c95 AND (c96 AND (c97 AND (c98 AND (c99 AND (c100 AND (c101 AND (c102 AND (c103 AND (c104 AND (c105 AND (c106 AND (c107 AND (c108 AND (c109 AND (c110 AND (c111 AND (c112 AND (c113 AND (c114 AND (c115 AND (c116 AND (c117 AND (c118 AND (c119 AND (c120 AND (c121 AND (c122 AND (c123 AND (c124 AND (c125 AND (c126 AND (c127 AND (c128 AND (c129 AND (c130 AND (c131 AND (c132 AND (c133 AND (c134 AND (c135 AND (c136 AND (c137 AND (c138 AND (c139 AND (c140 AND (c141 AND (c142 AND (c143 AND (c144 AND (c145 AND (c146 AND (c147 AND (c148 AND (c149 AND (c150 AND (c151 AND (c152 AND (c153 AND (c154 AND (c155 AND (c156 AND (c157 AND (c158 AND (c159 AND (c160 AND (c161 AND (c162 AND (c163 AND (c164 AND (c165 AND (c166 AND (c167 AND (c168 AND (c169 AND (c170 AND (c171 AND (c172 AND (c173 AND (c174 AND (c175 AND (c176 AND (c177 AND (c178 AND (c179 AND (c180 AND (c181 AND (c182 AND (c183 AND (c184 AND (c185 AND (c186 AND (c187 AND (c188 AND (c189 AND (c190 AND (c191 AND (c192 AND (c193 AND (c194 AND (c195 AND (c196 AND (c197 AND (c198 AND (c199 AND c200)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))';
|
||||
} {1 {fts5: parser stack overflow}}
|
||||
|
||||
finish_test
|
||||
|
||||
|
32
manifest
32
manifest
@ -1,5 +1,5 @@
|
||||
C Add\sJSON1\sand\sFTS5\sto\sthe\sset\sof\sextensions\ssubject\sto\sclose\scompiler\swarning\nanalysis.\s\sFix\ssome\swarnings\sin\seach.\s\s\sMore\s(harmless)\swarnings\sstill\sexist\nin\sFTS5.
|
||||
D 2016-02-11T15:37:18.370
|
||||
C Handle\sparser\sstack\soverflow\swhen\sparsing\sfts5\squery\sexpressions.\sFix\ssome\scompiler\swarnings\sin\sfts5\scode.
|
||||
D 2016-02-11T17:01:32.344
|
||||
F Makefile.in 4e90dc1521879022aa9479268a4cd141d1771142
|
||||
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
|
||||
F Makefile.msc 463edfba5c6fccebc61d8c094ccd463a6a55becb
|
||||
@ -98,23 +98,23 @@ F ext/fts3/unicode/mkunicode.tcl 95cf7ec186e48d4985e433ff8a1c89090a774252
|
||||
F ext/fts3/unicode/parseunicode.tcl da577d1384810fb4e2b209bf3313074353193e95
|
||||
F ext/fts5/extract_api_docs.tcl a36e54ec777172ddd3f9a88daf593b00848368e0
|
||||
F ext/fts5/fts5.h ff9c2782e8ed890b0de2f697a8d63971939e70c7
|
||||
F ext/fts5/fts5Int.h cb495e7cb2d140ab3fc3547750e14d1feeec1ca8
|
||||
F ext/fts5/fts5_aux.c b9bcce753ef5b451267b2232f0ca153ddeb3951d
|
||||
F ext/fts5/fts5Int.h f9e7772d3ad2b8aac6ad77a5867a254f4422992e
|
||||
F ext/fts5/fts5_aux.c daa57fb45216491814520bbb587e97bf81ced458
|
||||
F ext/fts5/fts5_buffer.c 4c1502d4c956cd092c89ce4480867f9d8bf325cd
|
||||
F ext/fts5/fts5_config.c 35c5173cae4eb17e82164a7f5aeef56a48903079
|
||||
F ext/fts5/fts5_expr.c ff5c451a6d025909639ac0f0d0af0cc595b50feb
|
||||
F ext/fts5/fts5_expr.c 8e8e4635f655133eb39018072fc0f0942a2c4337
|
||||
F ext/fts5/fts5_hash.c 1b113977296cf4212c6ec667d5e3f2bd18036955
|
||||
F ext/fts5/fts5_index.c 28f72130400cb54d179a9a120b7232915e3e7a4e
|
||||
F ext/fts5/fts5_main.c 6e23df904049edb498538bd3e22e53ec1ab6f4f7
|
||||
F ext/fts5/fts5_storage.c 2a1f44deae090cd711f02cec0c2af8e660360d24
|
||||
F ext/fts5/fts5_index.c 12354c3871dc0e84621449ab52e8dc26ada82294
|
||||
F ext/fts5/fts5_main.c 0e01ead4e817483e378e7e38e6d902f50b68d29e
|
||||
F ext/fts5/fts5_storage.c f8343db90d8c95a4d4b52f6676e354b4649ffd6e
|
||||
F ext/fts5/fts5_tcl.c f8731e0508299bd43f1a2eff7dbeaac870768966
|
||||
F ext/fts5/fts5_test_mi.c 1ec66ffdf7632077fbd773b7a6df5153272ec070
|
||||
F ext/fts5/fts5_test_tok.c db08af63673c3a7d39f053b36fd6e065017706be
|
||||
F ext/fts5/fts5_tokenize.c 4d5c4f183c7d07d144bc219b92da1ea0e962fae3
|
||||
F ext/fts5/fts5_tokenize.c 2ce7b44183538ec46b7907726262ee43ffdd39a8
|
||||
F ext/fts5/fts5_unicode2.c 78273fbd588d1d9bd0a7e4e0ccc9207348bae33c
|
||||
F ext/fts5/fts5_varint.c a5aceacda04dafcbae725413d7a16818ecd65738
|
||||
F ext/fts5/fts5_vocab.c 3ef401a8d6932db56368de32f446eb9fe73aa623
|
||||
F ext/fts5/fts5parse.y 1647eba089b9b3fc058b4dc989d9da87d15b9580
|
||||
F ext/fts5/fts5_vocab.c dba72ca393d71c2588548b51380387f6b44c77a8
|
||||
F ext/fts5/fts5parse.y 9f4786e16ff2ce16c27552fb4911dc0a033472ef
|
||||
F ext/fts5/mkportersteps.tcl 5acf962d2e0074f701620bb5308155fa1e4a63ba
|
||||
F ext/fts5/test/fts5_common.tcl 61ff0d1a29d98a91c4553b20b3f410d858834ee9
|
||||
F ext/fts5/test/fts5aa.test 7e814df4a0e6c22a6fe2d84f210fdc0b5068a084
|
||||
@ -176,7 +176,7 @@ F ext/fts5/test/fts5rank.test 7e9e64eac7245637f6f2033aec4b292aaf611aab
|
||||
F ext/fts5/test/fts5rebuild.test 03935f617ace91ed23a6099c7c74d905227ff29b
|
||||
F ext/fts5/test/fts5restart.test c17728fdea26e7d0f617d22ad5b4b2862b994c17
|
||||
F ext/fts5/test/fts5rowid.test 16908a99d6efc9ba21081b4f2b86b3fc699839a6
|
||||
F ext/fts5/test/fts5simple.test 7fcacfa473a37355af2e60096650c87b5ba8f3ba
|
||||
F ext/fts5/test/fts5simple.test e6fe2fb10a2b9193648b32bbc2caecabdf8c333d
|
||||
F ext/fts5/test/fts5simple2.test 98377ae1ff7749a42c21fe1a139c1ed312522c46
|
||||
F ext/fts5/test/fts5simple3.test 8e71733b3d1b0e695011d02c68ebc5ca40b6124e
|
||||
F ext/fts5/test/fts5synonym.test 6475d189c2e20d60795808f83e36bf9318708d48
|
||||
@ -1427,7 +1427,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f
|
||||
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||
F tool/warnings.sh ef6ebc6fd8d2dc35db3b622015c16a023d4fef4f
|
||||
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
||||
P e9e6000bd2f7e0ef85178db2b5b8f20e4cf0093c
|
||||
R 203364b475629e5387d880c7b72b1d29
|
||||
U drh
|
||||
Z 7bc360a50dcd258c28a9003183e0bafc
|
||||
P cfe2eb88b504f5e9b1351022036641b1ac4c3e78
|
||||
R ecfecabfdc2e20b17daae28f5e9c8aee
|
||||
U dan
|
||||
Z 2089f51bfc7049c8d149969b8c7916a9
|
||||
|
@ -1 +1 @@
|
||||
cfe2eb88b504f5e9b1351022036641b1ac4c3e78
|
||||
bc3f7900d5a06829d123814a5ac7b951bcfc1560
|
Loading…
Reference in New Issue
Block a user