diff options
author | dan <dan@noemail.net> | 2018-11-07 20:07:28 +0000 |
---|---|---|
committer | dan <dan@noemail.net> | 2018-11-07 20:07:28 +0000 |
commit | 5704f455b9802a0b96220aff1ed3bd7b4664f16d (patch) | |
tree | 50f89de1cdcc675905d41d561cd46f5dc81db3fc /ext/session/changesetfuzz.c | |
parent | 7844d21536bb6d847bd7d3b6d3c74e14edcbe761 (diff) | |
download | sqlite-5704f455b9802a0b96220aff1ed3bd7b4664f16d.tar.gz sqlite-5704f455b9802a0b96220aff1ed3bd7b4664f16d.zip |
Fix minor issues in the changesetfuzz program.
FossilOrigin-Name: 5c7f024073bc93089f038b5cf122a7a9d5b933f7c1b357f6d20ae925739ffc38
Diffstat (limited to 'ext/session/changesetfuzz.c')
-rw-r--r-- | ext/session/changesetfuzz.c | 98 |
1 files changed, 87 insertions, 11 deletions
diff --git a/ext/session/changesetfuzz.c b/ext/session/changesetfuzz.c index 22458c430..9aa29e1e3 100644 --- a/ext/session/changesetfuzz.c +++ b/ext/session/changesetfuzz.c @@ -26,6 +26,10 @@ ** In the first form above, this program outputs a human-readable version ** of the same changeset. This is chiefly for debugging. ** +** As well as changesets, this program can also dump and fuzz patchsets. +** The term "changeset" is used for both patchsets and changesets from this +** point on. +** ** In the second form, arguments SEED and N must both be integers. In this ** case, this program writes N binary changesets to disk. Each output ** changeset is a slightly modified - "fuzzed" - version of the input. @@ -90,10 +94,6 @@ ** only PRIMARY KEY column in the table. In this case the corresponding ** field is removed from all records. In cases where this leaves an UPDATE ** with no non-PK, non-undefined fields, the entire change is removed. -** -** PATCHSETS -** -** As well as changesets, this program can also dump and fuzz patchsets. */ #include "sqlite3.h" @@ -430,11 +430,16 @@ static void fuzzPutU64(u8 *aRec, u64 iVal){ aRec[7] = (iVal) & 0xFF; } +/* +** Parse a single table-header from the input. Allocate a new change-group +** object with the results. Return SQLITE_OK if successful, or an error code +** otherwise. +*/ static int fuzzParseHeader( - FuzzChangeset *pParse, - u8 **ppHdr, - u8 *pEnd, - FuzzChangesetGroup **ppGrp + FuzzChangeset *pParse, /* Changeset parse object */ + u8 **ppHdr, /* IN/OUT: Iterator */ + u8 *pEnd, /* 1 byte past EOF */ + FuzzChangesetGroup **ppGrp /* OUT: New change-group object */ ){ int rc = SQLITE_OK; FuzzChangesetGroup *pGrp; @@ -472,6 +477,13 @@ static int fuzzParseHeader( return rc; } +/* +** Argument p points to a buffer containing a single changeset-record value. +** This function attempts to determine the size of the value in bytes. If +** successful, it sets (*pSz) to the size and returns SQLITE_OK. Or, if the +** buffer does not contain a valid value, SQLITE_CORRUPT is returned and +** the final value of (*pSz) is undefined. +*/ static int fuzzChangeSize(u8 *p, int *pSz){ u8 eType = p[0]; switch( eType ){ @@ -500,11 +512,24 @@ static int fuzzChangeSize(u8 *p, int *pSz){ return SQLITE_OK; } +/* +** When this function is called, (*ppRec) points to the start of a +** record in a changeset being parsed. This function adds entries +** to the pParse->apVal[] array for all values and advances (*ppRec) +** to one byte past the end of the record. Argument pEnd points to +** one byte past the end of the input changeset. +** +** Argument bPkOnly is true if the record being parsed is part of +** a DELETE record in a patchset. In this case, all non-primary-key +** fields have been omitted from the record. +** +** SQLITE_OK is returned if successful, or an SQLite error code otherwise. +*/ static int fuzzParseRecord( u8 **ppRec, /* IN/OUT: Iterator */ u8 *pEnd, /* One byte after end of input data */ - FuzzChangeset *pParse, - int bPkOnly + FuzzChangeset *pParse, /* Changeset parse context */ + int bPkOnly /* True if non-PK fields omitted */ ){ int rc = SQLITE_OK; FuzzChangesetGroup *pGrp = pParse->apGroup[pParse->nGroup-1]; @@ -534,6 +559,14 @@ static int fuzzParseRecord( return rc; } +/* +** Parse the array of changes starting at (*ppData) and add entries for +** all values to the pParse->apVal[] array. Argument pEnd points to one byte +** past the end of the input changeset. If successful, set (*ppData) to point +** to one byte past the end of the change array and return SQLITE_OK. +** Otherwise, return an SQLite error code. The final value of (*ppData) is +** undefined in this case. +*/ static int fuzzParseChanges(u8 **ppData, u8 *pEnd, FuzzChangeset *pParse){ u8 cHdr = (pParse->bPatchset ? 'P' : 'T'); FuzzChangesetGroup *pGrp = pParse->apGroup[pParse->nGroup-1]; @@ -567,6 +600,12 @@ static int fuzzParseChanges(u8 **ppData, u8 *pEnd, FuzzChangeset *pParse){ return rc; } +/* +** Parse the changeset stored in buffer pChangeset (nChangeset bytes in +** size). If successful, write the results into (*pParse) and return +** SQLITE_OK. Or, if an error occurs, return an SQLite error code. The +** final state of (*pParse) is undefined in this case. +*/ static int fuzzParseChangeset( u8 *pChangeset, /* Buffer containing changeset */ int nChangeset, /* Size of buffer in bytes */ @@ -608,6 +647,18 @@ static int fuzzParseChangeset( return rc; } +/* +** When this function is called, (*ppRec) points to the first byte of +** a record that is part of change-group pGrp. This function attempts +** to output a human-readable version of the record to stdout and advance +** (*ppRec) to point to the first byte past the end of the record before +** returning. If successful, SQLITE_OK is returned. Otherwise, an SQLite +** error code. +** +** If parameter bPkOnly is non-zero, then all non-primary-key fields have +** been omitted from the record. This occurs for records that are part +** of DELETE changes in patchsets. +*/ static int fuzzPrintRecord(FuzzChangesetGroup *pGrp, u8 **ppRec, int bPKOnly){ int rc = SQLITE_OK; u8 *p = *ppRec; @@ -676,7 +727,11 @@ static int fuzzPrintRecord(FuzzChangesetGroup *pGrp, u8 **ppRec, int bPKOnly){ return rc; } -static int fuzzPrintGroup(FuzzChangeset *pParse, FuzzChangesetGroup *pGrp){ +/* +** Print a human-readable version of the table-header and all changes in the +** change-group passed as the second argument. +*/ +static void fuzzPrintGroup(FuzzChangeset *pParse, FuzzChangesetGroup *pGrp){ int i; u8 *p; @@ -707,6 +762,16 @@ static int fuzzPrintGroup(FuzzChangeset *pParse, FuzzChangesetGroup *pGrp){ } } +/* +** Initialize the object passed as the second parameter with details +** of the change that will be attempted (type of change, to which part of the +** changeset it applies etc.). If successful, return SQLITE_OK. Or, if an +** error occurs, return an SQLite error code. +** +** If a negative value is returned, then the selected change would have +** produced a non-well-formed changeset. In this case the caller should +** call this function again. +*/ static int fuzzSelectChange(FuzzChangeset *pParse, FuzzChange *pChange){ int iSub; @@ -837,6 +902,10 @@ static int fuzzSelectChange(FuzzChangeset *pParse, FuzzChange *pChange){ return SQLITE_OK; } +/* +** Copy a single change from the input to the output changeset, making +** any modifications specified by (*pFuzz). +*/ static int fuzzCopyChange( FuzzChangeset *pParse, int iGrp, @@ -1022,6 +1091,13 @@ static int fuzzCopyChange( return SQLITE_OK; } +/* +** Fuzz the changeset parsed into object pParse and write the results +** to file zOut on disk. Argument pBuf points to a buffer that is guaranteed +** to be large enough to hold the fuzzed changeset. +** +** Return SQLITE_OK if successful, or an SQLite error code if an error occurs. +*/ static int fuzzDoOneFuzz( const char *zOut, /* Filename to write modified changeset to */ u8 *pBuf, /* Buffer to use for modified changeset */ |