Fix various issues in sqlite3intck.c.
FossilOrigin-Name: 8a7bfa74525a495f45b1ea212b1718633b637295090d514dd777f9263477d514
This commit is contained in:
+138
-110
@@ -14,12 +14,25 @@
|
||||
#include "sqlite3intck.h"
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/*
|
||||
** nKeyVal:
|
||||
** The number of values that make up the 'key' for the current pCheck
|
||||
** statement.
|
||||
**
|
||||
** rc:
|
||||
** Error code returned by most recent sqlite3_intck_step() or
|
||||
** sqlite3_intck_unlock() call. This is set to SQLITE_DONE when
|
||||
** the integrity-check operation is finished.
|
||||
**
|
||||
** zErr:
|
||||
** If the object has entered the error state, this is the error message.
|
||||
** Is freed using sqlite3_free() when the object is deleted.
|
||||
**
|
||||
** zTestSql:
|
||||
** The value returned by the most recent call to sqlite3_intck_testsql().
|
||||
** Each call to testsql() frees the previous zTestSql value (using
|
||||
** sqlite3_free()) and replaces it with the new value it will return.
|
||||
*/
|
||||
struct sqlite3_intck {
|
||||
sqlite3 *db;
|
||||
@@ -52,40 +65,56 @@ static void intckSaveErrmsg(sqlite3_intck *p){
|
||||
}
|
||||
}
|
||||
|
||||
static sqlite3_stmt *intckPrepare(sqlite3_intck *p, const char *zFmt, ...){
|
||||
/*
|
||||
** If the handle passed as the first argument is already in the error state,
|
||||
** then this function is a no-op (returns NULL immediately). Otherwise, if an
|
||||
** error occurs within this function, it leaves an error in said handle.
|
||||
**
|
||||
** Otherwise, this function attempts to prepare SQL statement zSql and
|
||||
** return the resulting statement handle to the user.
|
||||
*/
|
||||
static sqlite3_stmt *intckPrepare(sqlite3_intck *p, const char *zSql){
|
||||
sqlite3_stmt *pRet = 0;
|
||||
if( p->rc==SQLITE_OK ){
|
||||
p->rc = sqlite3_prepare_v2(p->db, zSql, -1, &pRet, 0);
|
||||
if( p->rc!=SQLITE_OK ){
|
||||
intckSaveErrmsg(p);
|
||||
assert( pRet==0 );
|
||||
}
|
||||
}
|
||||
return pRet;
|
||||
}
|
||||
|
||||
/*
|
||||
** If the handle passed as the first argument is already in the error state,
|
||||
** then this function is a no-op (returns NULL immediately). Otherwise, if an
|
||||
** error occurs within this function, it leaves an error in said handle.
|
||||
**
|
||||
** Otherwise, this function treats argument zFmt as a printf() style format
|
||||
** string. It formats it according to the trailing arguments and then
|
||||
** attempts to prepare the results and return the resulting prepared
|
||||
** statement.
|
||||
*/
|
||||
static sqlite3_stmt *intckPrepareFmt(sqlite3_intck *p, const char *zFmt, ...){
|
||||
sqlite3_stmt *pRet = 0;
|
||||
va_list ap;
|
||||
char *zSql = 0;
|
||||
va_start(ap, zFmt);
|
||||
zSql = sqlite3_vmprintf(zFmt, ap);
|
||||
if( p->rc==SQLITE_OK ){
|
||||
if( zSql==0 ){
|
||||
p->rc = SQLITE_NOMEM;
|
||||
}else{
|
||||
p->rc = sqlite3_prepare_v2(p->db, zSql, -1, &pRet, 0);
|
||||
fflush(stdout);
|
||||
if( p->rc!=SQLITE_OK ){
|
||||
#if 0
|
||||
printf("ERROR: %s\n", zSql);
|
||||
printf("MSG: %s\n", sqlite3_errmsg(p->db));
|
||||
#endif
|
||||
if( sqlite3_error_offset(p->db)>=0 ){
|
||||
#if 0
|
||||
int iOff = sqlite3_error_offset(p->db);
|
||||
printf("AT: %.40s\n", &zSql[iOff]);
|
||||
#endif
|
||||
}
|
||||
fflush(stdout);
|
||||
intckSaveErrmsg(p);
|
||||
assert( pRet==0 );
|
||||
}
|
||||
}
|
||||
if( p->rc==SQLITE_OK && zSql==0 ){
|
||||
p->rc = SQLITE_NOMEM;
|
||||
}
|
||||
pRet = intckPrepare(p, zSql);
|
||||
sqlite3_free(zSql);
|
||||
va_end(ap);
|
||||
return pRet;
|
||||
}
|
||||
|
||||
/*
|
||||
** Finalize SQL statement pStmt. If an error occurs and the handle passed
|
||||
** as the first argument does not already contain an error, store the
|
||||
** error in the handle.
|
||||
*/
|
||||
static void intckFinalize(sqlite3_intck *p, sqlite3_stmt *pStmt){
|
||||
int rc = sqlite3_finalize(pStmt);
|
||||
if( p->rc==SQLITE_OK && rc!=SQLITE_OK ){
|
||||
@@ -93,6 +122,18 @@ static void intckFinalize(sqlite3_intck *p, sqlite3_stmt *pStmt){
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Execute SQL statement zSql. There is no way to obtain any results
|
||||
** returned by the statement. This function uses the sqlite3_intck error
|
||||
** code convention.
|
||||
*/
|
||||
static void intckExec(sqlite3_intck *p, const char *zSql){
|
||||
sqlite3_stmt *pStmt = 0;
|
||||
pStmt = intckPrepare(p, zSql);
|
||||
while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) );
|
||||
intckFinalize(p, pStmt);
|
||||
}
|
||||
|
||||
/*
|
||||
** Wrapper around sqlite3_malloc64() that uses the sqlite3_intck error
|
||||
** code convention.
|
||||
@@ -110,15 +151,8 @@ static void *intckMalloc(sqlite3_intck *p, sqlite3_int64 nByte){
|
||||
}
|
||||
|
||||
/*
|
||||
** If p->rc is other than SQLITE_OK when this function is called, it
|
||||
** immediately returns NULL. Otherwise, it attempts to create a copy of
|
||||
** nul-terminated string zIn in a buffer obtained from sqlite3_malloc().
|
||||
** If successful, a pointer to this buffer is returned and it becomes
|
||||
** the responsibility of the caller to release it using sqlite3_free()
|
||||
** at some point in the future.
|
||||
**
|
||||
** Or, if an allocation fails within this function, p->rc is set to
|
||||
** SQLITE_NOMEM and NULL is returned.
|
||||
** Like strdup(), but uses the sqlite3_intck error code convention. Any
|
||||
** returned buffer should eventually be freed using sqlite3_free().
|
||||
*/
|
||||
static char *intckStrdup(sqlite3_intck *p, const char *zIn){
|
||||
char *zOut = 0;
|
||||
@@ -131,10 +165,8 @@ static char *intckStrdup(sqlite3_intck *p, const char *zIn){
|
||||
}
|
||||
|
||||
/*
|
||||
** A wrapper around sqlite3_mprintf() that:
|
||||
**
|
||||
** + Always returns 0 if p->rc is other than SQLITE_OK when it is called, and
|
||||
** + Sets p->rc to SQLITE_NOMEM if an allocation fails.
|
||||
** A wrapper around sqlite3_mprintf() that uses the sqlite3_intck error
|
||||
** code convention.
|
||||
*/
|
||||
static char *intckMprintf(sqlite3_intck *p, const char *zFmt, ...){
|
||||
va_list ap;
|
||||
@@ -153,25 +185,11 @@ static char *intckMprintf(sqlite3_intck *p, const char *zFmt, ...){
|
||||
}
|
||||
|
||||
/*
|
||||
** Free the sqlite3_intck.apKeyVal, if it is allocated and populated.
|
||||
** This is used by sqlite3_intck_unlock() to save the vector key value
|
||||
** required to restart the current pCheck query as a nul-terminated string
|
||||
** in p->zKey.
|
||||
*/
|
||||
static void intckSavedKeyClear(sqlite3_intck *p){
|
||||
sqlite3_free(p->zKey);
|
||||
p->zKey = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** If the apKeyVal array is currently allocated and populated, return
|
||||
** a pointer to a buffer containing a nul-terminated string representing
|
||||
** the values as an SQL vector. e.g.
|
||||
**
|
||||
** "('abc', NULL, 2)"
|
||||
**
|
||||
** If apKeyVal is not allocated, return NULL. Or, if an error (e.g. OOM)
|
||||
** occurs within this function, set sqlite3_intck.rc before returning
|
||||
** and return NULL.
|
||||
*/
|
||||
static void intckSavedKeySave(sqlite3_intck *p){
|
||||
static void intckSaveKey(sqlite3_intck *p){
|
||||
int ii;
|
||||
const char *zSep = "SELECT '(' || ";
|
||||
char *zSql = 0;
|
||||
@@ -180,14 +198,13 @@ static void intckSavedKeySave(sqlite3_intck *p){
|
||||
assert( p->pCheck );
|
||||
assert( p->zKey==0 );
|
||||
|
||||
|
||||
for(ii=0; ii<p->nKeyVal; ii++){
|
||||
zSql = intckMprintf(p, "%z%squote(?)", zSql, zSep);
|
||||
zSep = " || ', ' || ";
|
||||
}
|
||||
zSql = intckMprintf(p, "%z || ')'", zSql);
|
||||
|
||||
pStmt = intckPrepare(p, "%s", zSql);
|
||||
pStmt = intckPrepare(p, zSql);
|
||||
if( p->rc==SQLITE_OK ){
|
||||
for(ii=0; ii<p->nKeyVal; ii++){
|
||||
sqlite3_bind_value(pStmt, ii+1, sqlite3_column_value(p->pCheck, ii+1));
|
||||
@@ -213,7 +230,7 @@ static void intckFindObject(sqlite3_intck *p){
|
||||
assert( p->rc==SQLITE_OK );
|
||||
assert( p->pCheck==0 );
|
||||
|
||||
pStmt = intckPrepare(p,
|
||||
pStmt = intckPrepareFmt(p,
|
||||
"WITH tables(table_name) AS ("
|
||||
" SELECT name"
|
||||
" FROM %Q.sqlite_schema WHERE (type='table' OR type='index') AND rootpage"
|
||||
@@ -236,7 +253,8 @@ static void intckFindObject(sqlite3_intck *p){
|
||||
|
||||
/* If this is a new object, ensure the previous key value is cleared. */
|
||||
if( sqlite3_stricmp(p->zObj, zPrev) ){
|
||||
intckSavedKeyClear(p);
|
||||
sqlite3_free(p->zKey);
|
||||
p->zKey = 0;
|
||||
}
|
||||
|
||||
sqlite3_free(zPrev);
|
||||
@@ -274,22 +292,13 @@ static int intckGetToken(const char *z){
|
||||
return iRet;
|
||||
}
|
||||
|
||||
/*
|
||||
** Return true if argument c is an ascii whitespace character.
|
||||
*/
|
||||
static int intckIsSpace(char c){
|
||||
return (c==' ' || c=='\t' || c=='\n' || c=='\r');
|
||||
}
|
||||
|
||||
static int intckTokenMatch(
|
||||
const char *zToken,
|
||||
int nToken,
|
||||
const char *z1,
|
||||
const char *z2
|
||||
){
|
||||
return (
|
||||
(strlen(z1)==nToken && 0==sqlite3_strnicmp(zToken, z1, nToken))
|
||||
|| (z2 && strlen(z2)==nToken && 0==sqlite3_strnicmp(zToken, z2, nToken))
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
** Argument z points to the text of a CREATE INDEX statement. This function
|
||||
** identifies the part of the text that contains either the index WHERE
|
||||
@@ -350,7 +359,9 @@ static const char *intckParseCreateIndex(const char *z, int iCol, int *pnByte){
|
||||
if( z[iOff]==')' ) nOpen--;
|
||||
nToken = intckGetToken(zToken);
|
||||
|
||||
if( intckTokenMatch(zToken, nToken, "ASC", "DESC") ){
|
||||
if( (nToken==3 && 0==sqlite3_strnicmp(zToken, "ASC", nToken))
|
||||
|| (nToken==4 && 0==sqlite3_strnicmp(zToken, "DESC", nToken))
|
||||
){
|
||||
iEndOfCol = iOff;
|
||||
}else if( 0==intckIsSpace(zToken[0]) ){
|
||||
iEndOfCol = 0;
|
||||
@@ -383,7 +394,12 @@ static const char *intckParseCreateIndex(const char *z, int iCol, int *pnByte){
|
||||
return zRet;
|
||||
}
|
||||
|
||||
static void parseCreateIndexFunc(
|
||||
/*
|
||||
** User-defined SQL function wrapper for intckParseCreateIndex():
|
||||
**
|
||||
** SELECT parse_create_index(<sql>, <icol>);
|
||||
*/
|
||||
static void intckParseCreateIndexFunc(
|
||||
sqlite3_context *pCtx,
|
||||
int nVal,
|
||||
sqlite3_value **apVal
|
||||
@@ -421,7 +437,7 @@ static int intckGetAutoIndex(sqlite3_intck *p){
|
||||
static int intckIsIndex(sqlite3_intck *p, const char *zObj){
|
||||
int bRet = 0;
|
||||
sqlite3_stmt *pStmt = 0;
|
||||
pStmt = intckPrepare(p,
|
||||
pStmt = intckPrepareFmt(p,
|
||||
"SELECT 1 FROM %Q.sqlite_schema WHERE name=%Q AND type='index'",
|
||||
p->zDb, zObj
|
||||
);
|
||||
@@ -432,17 +448,20 @@ static int intckIsIndex(sqlite3_intck *p, const char *zObj){
|
||||
return bRet;
|
||||
}
|
||||
|
||||
static void intckExec(sqlite3_intck *p, const char *zSql){
|
||||
sqlite3_stmt *pStmt = 0;
|
||||
pStmt = intckPrepare(p, "%s", zSql);
|
||||
while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) );
|
||||
intckFinalize(p, pStmt);
|
||||
}
|
||||
|
||||
/*
|
||||
** Return a pointer to a nul-terminated buffer containing the SQL statement
|
||||
** used to check database object zObj (a table or index) for corruption.
|
||||
** If parameter zPrev is not NULL, then it must be a string containing the
|
||||
** vector key required to restart the check where it left off last time.
|
||||
** If pnKeyVal is not NULL, then (*pnKeyVal) is set to the number of
|
||||
** columns in the vector key value for the specified object.
|
||||
**
|
||||
** This function uses the sqlite3_intck error code convention.
|
||||
*/
|
||||
static char *intckCheckObjectSql(
|
||||
sqlite3_intck *p,
|
||||
const char *zObj,
|
||||
const char *zPrev,
|
||||
sqlite3_intck *p, /* Integrity check object */
|
||||
const char *zObj, /* Object (table or index) to scan */
|
||||
const char *zPrev, /* Restart key vector, if any */
|
||||
int *pnKeyVal /* OUT: Number of key-values for this scan */
|
||||
){
|
||||
char *zRet = 0;
|
||||
@@ -563,7 +582,7 @@ static char *intckCheckObjectSql(
|
||||
|
||||
bIsIndex = intckIsIndex(p, zObj);
|
||||
if( bIsIndex ){
|
||||
pStmt = intckPrepare(p,
|
||||
pStmt = intckPrepareFmt(p,
|
||||
/* Table idxname contains a single row. The first column, "db", contains
|
||||
** the name of the db containing the table (e.g. "main") and the second,
|
||||
** "tab", the name of the table itself. */
|
||||
@@ -616,7 +635,7 @@ static char *intckCheckObjectSql(
|
||||
, zPrev, zCommon
|
||||
);
|
||||
}else{
|
||||
pStmt = intckPrepare(p,
|
||||
pStmt = intckPrepareFmt(p,
|
||||
/* Table tabname contains a single row. The first column, "db", contains
|
||||
** the name of the db containing the table (e.g. "main") and the second,
|
||||
** "tab", the name of the table itself. */
|
||||
@@ -697,22 +716,10 @@ static char *intckCheckObjectSql(
|
||||
}
|
||||
|
||||
while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
|
||||
#if 0
|
||||
int nField = sqlite3_column_count(pStmt);
|
||||
int ii;
|
||||
for(ii=0; ii<nField; ii++){
|
||||
const char *zName = sqlite3_column_name(pStmt, ii);
|
||||
const char *zVal = (const char*)sqlite3_column_text(pStmt, ii);
|
||||
printf("FIELD %s = %s\n", zName, zVal ? zVal : "(null)");
|
||||
}
|
||||
printf("\n");
|
||||
fflush(stdout);
|
||||
#else
|
||||
zRet = intckStrdup(p, (const char*)sqlite3_column_text(pStmt, 0));
|
||||
if( pnKeyVal ){
|
||||
*pnKeyVal = sqlite3_column_int(pStmt, 1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
intckFinalize(p, pStmt);
|
||||
|
||||
@@ -720,14 +727,9 @@ static char *intckCheckObjectSql(
|
||||
return zRet;
|
||||
}
|
||||
|
||||
static void intckCheckObject(sqlite3_intck *p){
|
||||
char *zSql = 0;
|
||||
zSql = intckCheckObjectSql(p, p->zObj, p->zKey, &p->nKeyVal);
|
||||
p->pCheck = intckPrepare(p, "%s", zSql);
|
||||
sqlite3_free(zSql);
|
||||
intckSavedKeyClear(p);
|
||||
}
|
||||
|
||||
/*
|
||||
** Open a new integrity-check object.
|
||||
*/
|
||||
int sqlite3_intck_open(
|
||||
sqlite3 *db, /* Database handle to operate on */
|
||||
const char *zDbArg, /* "main", "temp" etc. */
|
||||
@@ -743,7 +745,7 @@ int sqlite3_intck_open(
|
||||
rc = SQLITE_NOMEM;
|
||||
}else{
|
||||
sqlite3_create_function(db, "parse_create_index",
|
||||
2, SQLITE_UTF8, 0, parseCreateIndexFunc, 0, 0
|
||||
2, SQLITE_UTF8, 0, intckParseCreateIndexFunc, 0, 0
|
||||
);
|
||||
memset(pNew, 0, sizeof(*pNew));
|
||||
pNew->db = db;
|
||||
@@ -755,6 +757,9 @@ int sqlite3_intck_open(
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Free the integrity-check object.
|
||||
*/
|
||||
void sqlite3_intck_close(sqlite3_intck *p){
|
||||
if( p ){
|
||||
if( p->db ){
|
||||
@@ -763,13 +768,16 @@ void sqlite3_intck_close(sqlite3_intck *p){
|
||||
);
|
||||
}
|
||||
sqlite3_free(p->zObj);
|
||||
intckSavedKeyClear(p);
|
||||
sqlite3_free(p->zKey);
|
||||
sqlite3_free(p->zTestSql);
|
||||
sqlite3_free(p->zErr);
|
||||
sqlite3_free(p);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Step the integrity-check object.
|
||||
*/
|
||||
int sqlite3_intck_step(sqlite3_intck *p){
|
||||
if( p->rc==SQLITE_OK ){
|
||||
|
||||
@@ -785,7 +793,12 @@ int sqlite3_intck_step(sqlite3_intck *p){
|
||||
intckFindObject(p);
|
||||
if( p->rc==SQLITE_OK ){
|
||||
if( p->zObj ){
|
||||
intckCheckObject(p);
|
||||
char *zSql = 0;
|
||||
zSql = intckCheckObjectSql(p, p->zObj, p->zKey, &p->nKeyVal);
|
||||
p->pCheck = intckPrepare(p, zSql);
|
||||
sqlite3_free(zSql);
|
||||
sqlite3_free(p->zKey);
|
||||
p->zKey = 0;
|
||||
}else{
|
||||
p->rc = SQLITE_DONE;
|
||||
}
|
||||
@@ -819,6 +832,10 @@ int sqlite3_intck_step(sqlite3_intck *p){
|
||||
return p->rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Return a message describing the corruption encountered by the most recent
|
||||
** call to sqlite3_intck_step(), or NULL if no corruption was encountered.
|
||||
*/
|
||||
const char *sqlite3_intck_message(sqlite3_intck *p){
|
||||
assert( p->pCheck==0 || p->zMessage==0 );
|
||||
if( p->zMessage ){
|
||||
@@ -830,21 +847,32 @@ const char *sqlite3_intck_message(sqlite3_intck *p){
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** Return the error code and message.
|
||||
*/
|
||||
int sqlite3_intck_error(sqlite3_intck *p, const char **pzErr){
|
||||
if( pzErr ) *pzErr = p->zErr;
|
||||
return (p->rc==SQLITE_DONE ? SQLITE_OK : p->rc);
|
||||
}
|
||||
|
||||
/*
|
||||
** Close any read transaction the integrity-check object is holding open
|
||||
** on the database.
|
||||
*/
|
||||
int sqlite3_intck_unlock(sqlite3_intck *p){
|
||||
if( p->pCheck && p->rc==SQLITE_OK ){
|
||||
assert( p->zKey==0 && p->nKeyVal>0 );
|
||||
intckSavedKeySave(p);
|
||||
intckSaveKey(p);
|
||||
intckFinalize(p, p->pCheck);
|
||||
p->pCheck = 0;
|
||||
}
|
||||
return p->rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Return the SQL statement used to check object zObj. Or, if zObj is
|
||||
** NULL, the current SQL statement.
|
||||
*/
|
||||
const char *sqlite3_intck_test_sql(sqlite3_intck *p, const char *zObj){
|
||||
sqlite3_free(p->zTestSql);
|
||||
if( zObj ){
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
C Simplify\sthe\sway\sthe\srestart\skey\sis\ssaved\sinternally\sby\sthe\sintck\sextension.
|
||||
D 2024-02-21T19:31:00.293
|
||||
C Fix\svarious\sissues\sin\ssqlite3intck.c.
|
||||
D 2024-02-21T20:58:48.924
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
||||
@@ -252,7 +252,7 @@ F ext/intck/intck1.test 15e94ee868e939c6d3aef6884c5652d969b28d3eac940a15585511cf
|
||||
F ext/intck/intck2.test b65d7f627342f767e1d2c447d25619666cec36f516786dd56568bd741e5d7e67
|
||||
F ext/intck/intck_common.tcl b8a63ae820dbcdf50ddaba474f130b43c26ba81f4b7720ff1d8b9a6592bdd420
|
||||
F ext/intck/intckcorrupt.test 3211ef68ac53e83951b6c8f6a8d2396506d123fe5898f97f848a25837744ec56
|
||||
F ext/intck/sqlite3intck.c c437aaa1f4af77621ba984718a62c57722ad9d071151be79335fd87f2c2c2dde
|
||||
F ext/intck/sqlite3intck.c 3fa96647dde4c719a477f7dbdd1edf76b2f245549b1a4de7f7d60447b24a14df
|
||||
F ext/intck/sqlite3intck.h 2b40c38e7063ab822c974c0bd4aed97dabb579ccfe2e180a4639bb3bbef0f1c9
|
||||
F ext/intck/test_intck.c dec07fc82e2626a1450e58be474e351643627b04ee08ce8fae6495a533b87e85
|
||||
F ext/jni/GNUmakefile 59eb05f2a363bdfac8d15d66bed624bfe1ff289229184f3861b95f98a19cf4b2
|
||||
@@ -2169,8 +2169,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||
P 4cc19bd74f05fe92658cc392a1d1afa173d93181a77303af6bc5684436ae832e
|
||||
R 735ea6d5058bc579028d0f5e808c7418
|
||||
P 0e39962baae8a82a3021077676b792ac30c79426bcd8c075b5e92bee55e8c3a5
|
||||
R 2d481f6c889817bf845056ed7696633c
|
||||
U dan
|
||||
Z b84fa961179c349189e714cd49d2cd34
|
||||
Z 13c318cbe203f9a86dd5c12df0ee017f
|
||||
# Remove this line to create a well-formed Fossil manifest.
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
0e39962baae8a82a3021077676b792ac30c79426bcd8c075b5e92bee55e8c3a5
|
||||
8a7bfa74525a495f45b1ea212b1718633b637295090d514dd777f9263477d514
|
||||
Reference in New Issue
Block a user