From: drh Date: Thu, 6 Jan 2011 01:26:38 +0000 (+0000) Subject: Enhance the showdb tool to show a btree page layout. Add limit checks so that X-Git-Tag: version-3.7.5~49 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=5240aebdd8bfab6989f835db83b66c42a95ecdea;p=thirdparty%2Fsqlite.git Enhance the showdb tool to show a btree page layout. Add limit checks so that overflow content does not overflow the buffer. FossilOrigin-Name: 57ffa07e26a26d2f4527c8e6d7a9c1f48f380bf7 --- diff --git a/manifest b/manifest index fe4cfc2a84..6f28a148f5 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 -C Fix\sa\sbug\sin\sthe\sshowdb\sutility:\sthe\sserial\stypes\sfor\sBLOB\sand\sTEXT\swhere\nreversed. -D 2011-01-05T21:46:53 +C Enhance\sthe\sshowdb\stool\sto\sshow\sa\sbtree\spage\slayout.\s\sAdd\slimit\schecks\sso\sthat\noverflow\scontent\sdoes\snot\soverflow\sthe\sbuffer. +D 2011-01-06T01:26:38 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in de6498556d536ae60bb8bb10e8c1ba011448658c F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -886,7 +886,7 @@ F tool/shell2.test 5dc76b8005b465f420fed8241621da7513060ff3 F tool/shell3.test 4fad469e8003938426355afdf34155f08c587836 F tool/shell4.test 35f9c3d452b4e76d5013c63e1fd07478a62f14ce F tool/shell5.test 62bfaf9267296da1b91e4b1c03e44e7b393f6a94 -F tool/showdb.c 2f4d20922d1047530f3c6843a8d5973dbc7d8216 +F tool/showdb.c 65c209d59aa1e5d6c43e8d5f3a1a5d1521b83bd1 F tool/showjournal.c b62cecaab86a4053d944c276bb5232e4d17ece02 F tool/showwal.c f09e5a80a293919290ec85a6a37c85a5ddcf37d9 F tool/soak1.tcl 8d407956e1a45b485a8e072470a3e629a27037fe @@ -898,14 +898,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P e9023a4e1edd552a81dcb2dcd5a996edfa167709 -R 8dba7658a57757c37f21c1db4903dcb5 +P 65a13faf1e3cd18f3459cd410f65d334cfa7c376 +R 80317cc5c88d48103f5881daa67068e5 U drh -Z df7dfd891fb3ff873623731883eb9291 +Z 959c94bb95cb816dc6454b5126d5e277 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) -iD8DBQFNJObRoxKgR168RlERAlvgAJwJBI65HjFeJ29eAiEYGnhONZD3qgCff9Rz -zfYRaCzJT4SENwO7E6/i8Qk= -=/6Az +iD8DBQFNJRpRoxKgR168RlERAneLAJ0Ubz3gvmcO85uJHJOXqW1k9GkMcwCdE1AW +B34z8WqDcDzvAiuG+61UwD4= +=HyMh -----END PGP SIGNATURE----- diff --git a/manifest.uuid b/manifest.uuid index c7ca973cd9..a922e669e8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -65a13faf1e3cd18f3459cd410f65d334cfa7c376 \ No newline at end of file +57ffa07e26a26d2f4527c8e6d7a9c1f48f380bf7 \ No newline at end of file diff --git a/tool/showdb.c b/tool/showdb.c index cdffa82d35..8ccef76ced 100644 --- a/tool/showdb.c +++ b/tool/showdb.c @@ -57,7 +57,7 @@ static void out_of_memory(void){ */ static unsigned char *getContent(int ofst, int nByte){ unsigned char *aData; - aData = malloc(nByte); + aData = malloc(nByte+32); if( aData==0 ) out_of_memory(); lseek(db, ofst, SEEK_SET); read(db, aData, nByte); @@ -184,29 +184,33 @@ static void print_db_header(void){ ** Describe cell content. */ static int describeContent( - unsigned char *a, - char *zDesc + unsigned char *a, /* Cell content */ + int nLocal, /* Bytes in a[] */ + char *zDesc /* Write description here */ ){ int nDesc = 0; int n, i, j; i64 x, v; const unsigned char *pData; + const unsigned char *pLimit; char sep = ' '; + pLimit = &a[nLocal]; n = decodeVarint(a, &x); pData = &a[x]; a += n; i = x - n; - while( i>0 ){ + while( i>0 && pData<=pLimit ){ n = decodeVarint(a, &x); a += n; i -= n; + nLocal -= n; zDesc[0] = sep; sep = ','; nDesc++; zDesc++; if( x==0 ){ - sprintf(zDesc, "null"); + sprintf(zDesc, "*"); /* NULL is a "*" */ }else if( x>=1 && x<=6 ){ v = (signed char)pData[0]; pData++; @@ -230,7 +234,7 @@ static int describeContent( if( (x&1)==0 ){ sprintf(zDesc, "blob(%d)", size); }else{ - sprintf(zDesc, "text(%d)", size); + sprintf(zDesc, "txt(%d)", size); } pData += size; } @@ -240,10 +244,42 @@ static int describeContent( } return nDesc; } + +/* +** Compute the local payload size given the total payload size and +** the page size. +*/ +static int localPayload(i64 nPayload, char cType){ + int maxLocal; + int minLocal; + int surplus; + int nLocal; + if( cType==13 ){ + /* Table leaf */ + maxLocal = pagesize-35; + minLocal = (pagesize-12)*32/255-23; + }else{ + maxLocal = (pagesize-12)*64/255-23; + minLocal = (pagesize-12)*32/255-23; + } + if( nPayload>maxLocal ){ + surplus = minLocal + (nPayload-minLocal)%(pagesize-4); + if( surplus<=maxLocal ){ + nLocal = surplus; + }else{ + nLocal = minLocal; + } + }else{ + nLocal = nPayload; + } + return nLocal; +} /* ** Create a description for a single cell. +** +** The return value is the local cell size. */ static int describeCell( unsigned char cType, /* Page type */ @@ -273,6 +309,9 @@ static int describeCell( n += i; sprintf(&zDesc[nDesc], "n: %lld ", nPayload); nDesc += strlen(&zDesc[nDesc]); + nLocal = localPayload(nPayload, cType); + }else{ + nPayload = nLocal = 0; } if( cType==5 || cType==13 ){ i = decodeVarint(a, &rowid); @@ -282,10 +321,10 @@ static int describeCell( nDesc += strlen(&zDesc[nDesc]); } if( showCellContent && cType!=5 ){ - nDesc += describeContent(a, &zDesc[nDesc]); + nDesc += describeContent(a, nLocal, &zDesc[nDesc-1]); } *pzDesc = zDesc; - return n; + return nLocal+n; } /* @@ -299,9 +338,11 @@ static void decode_btree_page( ){ const char *zType = "unknown"; int nCell; - int i; + int i, j; int iCellPtr; int showCellContent = 0; + int showMap = 0; + char *zMap = 0; switch( a[0] ){ case 2: zType = "index interior node"; break; case 5: zType = "table interior node"; break; @@ -311,6 +352,7 @@ static void decode_btree_page( while( zArgs[0] ){ switch( zArgs[0] ){ case 'c': showCellContent = 1; break; + case 'm': showMap = 1; break; } zArgs++; } @@ -321,22 +363,46 @@ static void decode_btree_page( nCell = a[3]*256 + a[4]; print_decode_line(a, 5, 2, "Offset to cell content area"); print_decode_line(a, 7, 1, "Fragmented byte count"); - if( nCell>0 ){ - printf(" key: lx=left-child n=payload-size r=rowid\n"); - } if( a[0]==2 || a[0]==5 ){ print_decode_line(a, 8, 4, "Right child"); iCellPtr = 12; }else{ iCellPtr = 8; } + if( nCell>0 ){ + printf(" key: lx=left-child n=payload-size r=rowid\n"); + } + if( showMap ){ + zMap = malloc(pagesize); + memset(zMap, '.', pagesize); + memset(zMap, '1', hdrSize); + memset(&zMap[hdrSize], 'H', iCellPtr); + memset(&zMap[hdrSize+iCellPtr], 'P', 2*nCell); + } for(i=0; i