Fossil SCM
The vfile.c modules uses the display hash to verify whether or not files have changed on disk.
Commit
ac279fa0190cd912905d17b8c7b749904ae0b8cf
Parent
9a8986b791ca171…
2 files changed
+36
+11
-21
+36
| --- src/hname.c | ||
| +++ src/hname.c | ||
| @@ -112,8 +112,44 @@ | ||
| 112 | 112 | if( memcmp(sha3sum_finish(0),zHash,nHash)==0 ){ |
| 113 | 113 | id = nHash==HNAME_LEN_K224 ? HNAME_K224 : HNAME_K256; |
| 114 | 114 | } |
| 115 | 115 | break; |
| 116 | 116 | } |
| 117 | + } | |
| 118 | + return id; | |
| 119 | +} | |
| 120 | + | |
| 121 | +/* | |
| 122 | +** Verify that zHash is a valid hash for the content of a file on | |
| 123 | +** disk named zFile. | |
| 124 | +** | |
| 125 | +** Return true if the hash is correct. Return false if the content | |
| 126 | +** does not match the hash. | |
| 127 | +** | |
| 128 | +** Actually, the returned value is one of the hash algorithm constants | |
| 129 | +** corresponding to the hash that matched if the hash is correct. | |
| 130 | +** (Examples: HNAME_SHA1 or HNAME_K224). And the return is HNAME_ERROR | |
| 131 | +** if the hash does not match. | |
| 132 | +*/ | |
| 133 | +int hname_verify_file_hash(const char *zFile, const char *zHash, int nHash){ | |
| 134 | + int id = HNAME_ERROR; | |
| 135 | + switch( nHash ){ | |
| 136 | + case HNAME_LEN_SHA1: { | |
| 137 | + Blob hash; | |
| 138 | + sha1sum_file(zFile, &hash); | |
| 139 | + if( memcmp(blob_buffer(&hash),zHash,HNAME_LEN_SHA1)==0 ) id = HNAME_SHA1; | |
| 140 | + blob_reset(&hash); | |
| 141 | + break; | |
| 142 | + } | |
| 143 | + case HNAME_LEN_K224: | |
| 144 | + case HNAME_LEN_K256: { | |
| 145 | + Blob hash; | |
| 146 | + sha3sum_file(zFile, nHash*4, &hash); | |
| 147 | + if( memcmp(blob_buffer(&hash),zHash,nHash)==0 ){ | |
| 148 | + id = nHash==HNAME_LEN_K224 ? HNAME_K224 : HNAME_K256; | |
| 149 | + } | |
| 150 | + blob_reset(&hash); | |
| 151 | + break; | |
| 152 | + } | |
| 117 | 153 | } |
| 118 | 154 | return id; |
| 119 | 155 | } |
| 120 | 156 |
| --- src/hname.c | |
| +++ src/hname.c | |
| @@ -112,8 +112,44 @@ | |
| 112 | if( memcmp(sha3sum_finish(0),zHash,nHash)==0 ){ |
| 113 | id = nHash==HNAME_LEN_K224 ? HNAME_K224 : HNAME_K256; |
| 114 | } |
| 115 | break; |
| 116 | } |
| 117 | } |
| 118 | return id; |
| 119 | } |
| 120 |
| --- src/hname.c | |
| +++ src/hname.c | |
| @@ -112,8 +112,44 @@ | |
| 112 | if( memcmp(sha3sum_finish(0),zHash,nHash)==0 ){ |
| 113 | id = nHash==HNAME_LEN_K224 ? HNAME_K224 : HNAME_K256; |
| 114 | } |
| 115 | break; |
| 116 | } |
| 117 | } |
| 118 | return id; |
| 119 | } |
| 120 | |
| 121 | /* |
| 122 | ** Verify that zHash is a valid hash for the content of a file on |
| 123 | ** disk named zFile. |
| 124 | ** |
| 125 | ** Return true if the hash is correct. Return false if the content |
| 126 | ** does not match the hash. |
| 127 | ** |
| 128 | ** Actually, the returned value is one of the hash algorithm constants |
| 129 | ** corresponding to the hash that matched if the hash is correct. |
| 130 | ** (Examples: HNAME_SHA1 or HNAME_K224). And the return is HNAME_ERROR |
| 131 | ** if the hash does not match. |
| 132 | */ |
| 133 | int hname_verify_file_hash(const char *zFile, const char *zHash, int nHash){ |
| 134 | int id = HNAME_ERROR; |
| 135 | switch( nHash ){ |
| 136 | case HNAME_LEN_SHA1: { |
| 137 | Blob hash; |
| 138 | sha1sum_file(zFile, &hash); |
| 139 | if( memcmp(blob_buffer(&hash),zHash,HNAME_LEN_SHA1)==0 ) id = HNAME_SHA1; |
| 140 | blob_reset(&hash); |
| 141 | break; |
| 142 | } |
| 143 | case HNAME_LEN_K224: |
| 144 | case HNAME_LEN_K256: { |
| 145 | Blob hash; |
| 146 | sha3sum_file(zFile, nHash*4, &hash); |
| 147 | if( memcmp(blob_buffer(&hash),zHash,nHash)==0 ){ |
| 148 | id = nHash==HNAME_LEN_K224 ? HNAME_K224 : HNAME_K256; |
| 149 | } |
| 150 | blob_reset(&hash); |
| 151 | break; |
| 152 | } |
| 153 | } |
| 154 | return id; |
| 155 | } |
| 156 |
+11
-21
| --- src/vfile.c | ||
| +++ src/vfile.c | ||
| @@ -159,12 +159,12 @@ | ||
| 159 | 159 | ** |
| 160 | 160 | ** If the size of the file has changed, then we always know that the file |
| 161 | 161 | ** changed without having to look at the mtime or on-disk content. |
| 162 | 162 | ** |
| 163 | 163 | ** The mtime of the file is only a factor if the mtime-changes setting |
| 164 | -** is false and the useSha1sum flag is false. If the mtime-changes | |
| 165 | -** setting is true (or undefined - it defaults to true) or if useSha1sum | |
| 164 | +** is false and the CKSIG_HASH flag is false. If the mtime-changes | |
| 165 | +** setting is true (or undefined - it defaults to true) or if CKSIG_HASH | |
| 166 | 166 | ** is true, then we do not trust the mtime and will examine the on-disk |
| 167 | 167 | ** content to determine if a file really is the same. |
| 168 | 168 | ** |
| 169 | 169 | ** If the mtime is used, it is used only to determine if files are the same. |
| 170 | 170 | ** If the mtime of a file has changed, we still examine the on-disk content |
| @@ -222,40 +222,30 @@ | ||
| 222 | 222 | chnged = 1; |
| 223 | 223 | } |
| 224 | 224 | if( origSize!=currentSize ){ |
| 225 | 225 | if( chnged!=1 ){ |
| 226 | 226 | /* A file size change is definitive - the file has changed. No |
| 227 | - ** need to check the mtime or sha1sum */ | |
| 227 | + ** need to check the mtime or hash */ | |
| 228 | 228 | chnged = 1; |
| 229 | 229 | } |
| 230 | 230 | }else if( chnged==1 && rid!=0 && !isDeleted ){ |
| 231 | 231 | /* File is believed to have changed but it is the same size. |
| 232 | 232 | ** Double check that it really has changed by looking at content. */ |
| 233 | + const char *zUuid = db_column_text(&q, 5); | |
| 234 | + int nUuid = db_column_bytes(&q, 5); | |
| 233 | 235 | assert( origSize==currentSize ); |
| 234 | - db_ephemeral_blob(&q, 5, &origCksum); | |
| 235 | - if( sha1sum_file(zName, &fileCksum) ){ | |
| 236 | - blob_zero(&fileCksum); | |
| 237 | - } | |
| 238 | - if( blob_compare(&fileCksum, &origCksum)==0 ) chnged = 0; | |
| 239 | - blob_reset(&origCksum); | |
| 240 | - blob_reset(&fileCksum); | |
| 236 | + if( hname_verify_file_hash(zName, zUuid, nUuid) ) chnged = 0; | |
| 241 | 237 | }else if( (chnged==0 || chnged==2 || chnged==4) |
| 242 | 238 | && (useMtime==0 || currentMtime!=oldMtime) ){ |
| 243 | 239 | /* For files that were formerly believed to be unchanged or that were |
| 244 | 240 | ** changed by merging, if their mtime changes, or unconditionally |
| 245 | - ** if --sha1sum is used, check to see if they have been edited by | |
| 246 | - ** looking at their SHA1 sum */ | |
| 241 | + ** if --hash is used, check to see if they have been edited by | |
| 242 | + ** looking at their artifact hashes */ | |
| 243 | + const char *zUuid = db_column_text(&q, 5); | |
| 244 | + int nUuid = db_column_bytes(&q, 5); | |
| 247 | 245 | assert( origSize==currentSize ); |
| 248 | - db_ephemeral_blob(&q, 5, &origCksum); | |
| 249 | - if( sha1sum_file(zName, &fileCksum) ){ | |
| 250 | - blob_zero(&fileCksum); | |
| 251 | - } | |
| 252 | - if( blob_compare(&fileCksum, &origCksum) ){ | |
| 253 | - chnged = 1; | |
| 254 | - } | |
| 255 | - blob_reset(&origCksum); | |
| 256 | - blob_reset(&fileCksum); | |
| 246 | + if( !hname_verify_file_hash(zName, zUuid, nUuid) ) chnged = 1; | |
| 257 | 247 | } |
| 258 | 248 | if( (cksigFlags & CKSIG_SETMTIME) && (chnged==0 || chnged==2 || chnged==4) ){ |
| 259 | 249 | i64 desiredMtime; |
| 260 | 250 | if( mtime_of_manifest_file(vid,rid,&desiredMtime)==0 ){ |
| 261 | 251 | if( currentMtime!=desiredMtime ){ |
| 262 | 252 |
| --- src/vfile.c | |
| +++ src/vfile.c | |
| @@ -159,12 +159,12 @@ | |
| 159 | ** |
| 160 | ** If the size of the file has changed, then we always know that the file |
| 161 | ** changed without having to look at the mtime or on-disk content. |
| 162 | ** |
| 163 | ** The mtime of the file is only a factor if the mtime-changes setting |
| 164 | ** is false and the useSha1sum flag is false. If the mtime-changes |
| 165 | ** setting is true (or undefined - it defaults to true) or if useSha1sum |
| 166 | ** is true, then we do not trust the mtime and will examine the on-disk |
| 167 | ** content to determine if a file really is the same. |
| 168 | ** |
| 169 | ** If the mtime is used, it is used only to determine if files are the same. |
| 170 | ** If the mtime of a file has changed, we still examine the on-disk content |
| @@ -222,40 +222,30 @@ | |
| 222 | chnged = 1; |
| 223 | } |
| 224 | if( origSize!=currentSize ){ |
| 225 | if( chnged!=1 ){ |
| 226 | /* A file size change is definitive - the file has changed. No |
| 227 | ** need to check the mtime or sha1sum */ |
| 228 | chnged = 1; |
| 229 | } |
| 230 | }else if( chnged==1 && rid!=0 && !isDeleted ){ |
| 231 | /* File is believed to have changed but it is the same size. |
| 232 | ** Double check that it really has changed by looking at content. */ |
| 233 | assert( origSize==currentSize ); |
| 234 | db_ephemeral_blob(&q, 5, &origCksum); |
| 235 | if( sha1sum_file(zName, &fileCksum) ){ |
| 236 | blob_zero(&fileCksum); |
| 237 | } |
| 238 | if( blob_compare(&fileCksum, &origCksum)==0 ) chnged = 0; |
| 239 | blob_reset(&origCksum); |
| 240 | blob_reset(&fileCksum); |
| 241 | }else if( (chnged==0 || chnged==2 || chnged==4) |
| 242 | && (useMtime==0 || currentMtime!=oldMtime) ){ |
| 243 | /* For files that were formerly believed to be unchanged or that were |
| 244 | ** changed by merging, if their mtime changes, or unconditionally |
| 245 | ** if --sha1sum is used, check to see if they have been edited by |
| 246 | ** looking at their SHA1 sum */ |
| 247 | assert( origSize==currentSize ); |
| 248 | db_ephemeral_blob(&q, 5, &origCksum); |
| 249 | if( sha1sum_file(zName, &fileCksum) ){ |
| 250 | blob_zero(&fileCksum); |
| 251 | } |
| 252 | if( blob_compare(&fileCksum, &origCksum) ){ |
| 253 | chnged = 1; |
| 254 | } |
| 255 | blob_reset(&origCksum); |
| 256 | blob_reset(&fileCksum); |
| 257 | } |
| 258 | if( (cksigFlags & CKSIG_SETMTIME) && (chnged==0 || chnged==2 || chnged==4) ){ |
| 259 | i64 desiredMtime; |
| 260 | if( mtime_of_manifest_file(vid,rid,&desiredMtime)==0 ){ |
| 261 | if( currentMtime!=desiredMtime ){ |
| 262 |
| --- src/vfile.c | |
| +++ src/vfile.c | |
| @@ -159,12 +159,12 @@ | |
| 159 | ** |
| 160 | ** If the size of the file has changed, then we always know that the file |
| 161 | ** changed without having to look at the mtime or on-disk content. |
| 162 | ** |
| 163 | ** The mtime of the file is only a factor if the mtime-changes setting |
| 164 | ** is false and the CKSIG_HASH flag is false. If the mtime-changes |
| 165 | ** setting is true (or undefined - it defaults to true) or if CKSIG_HASH |
| 166 | ** is true, then we do not trust the mtime and will examine the on-disk |
| 167 | ** content to determine if a file really is the same. |
| 168 | ** |
| 169 | ** If the mtime is used, it is used only to determine if files are the same. |
| 170 | ** If the mtime of a file has changed, we still examine the on-disk content |
| @@ -222,40 +222,30 @@ | |
| 222 | chnged = 1; |
| 223 | } |
| 224 | if( origSize!=currentSize ){ |
| 225 | if( chnged!=1 ){ |
| 226 | /* A file size change is definitive - the file has changed. No |
| 227 | ** need to check the mtime or hash */ |
| 228 | chnged = 1; |
| 229 | } |
| 230 | }else if( chnged==1 && rid!=0 && !isDeleted ){ |
| 231 | /* File is believed to have changed but it is the same size. |
| 232 | ** Double check that it really has changed by looking at content. */ |
| 233 | const char *zUuid = db_column_text(&q, 5); |
| 234 | int nUuid = db_column_bytes(&q, 5); |
| 235 | assert( origSize==currentSize ); |
| 236 | if( hname_verify_file_hash(zName, zUuid, nUuid) ) chnged = 0; |
| 237 | }else if( (chnged==0 || chnged==2 || chnged==4) |
| 238 | && (useMtime==0 || currentMtime!=oldMtime) ){ |
| 239 | /* For files that were formerly believed to be unchanged or that were |
| 240 | ** changed by merging, if their mtime changes, or unconditionally |
| 241 | ** if --hash is used, check to see if they have been edited by |
| 242 | ** looking at their artifact hashes */ |
| 243 | const char *zUuid = db_column_text(&q, 5); |
| 244 | int nUuid = db_column_bytes(&q, 5); |
| 245 | assert( origSize==currentSize ); |
| 246 | if( !hname_verify_file_hash(zName, zUuid, nUuid) ) chnged = 1; |
| 247 | } |
| 248 | if( (cksigFlags & CKSIG_SETMTIME) && (chnged==0 || chnged==2 || chnged==4) ){ |
| 249 | i64 desiredMtime; |
| 250 | if( mtime_of_manifest_file(vid,rid,&desiredMtime)==0 ){ |
| 251 | if( currentMtime!=desiredMtime ){ |
| 252 |