Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 --- work/bsdiff-4.3/bspatch.c» 2005-08-16 15:14:00.000000000 -0700 | 1 --- bsdiff-4.3/bspatch.c» 2005-08-16 15:14:00.000000000 -0700 |
| 2 +++ work/bsdiff-4.3-new/bspatch.c» 2010-08-04 10:07:05.000000000 -0700 | 2 +++ bsdiff-4.3-new/bspatch.c» 2010-10-12 13:57:08.000000000 -0700 |
| 3 @@ -3,7 +3,7 @@ | 3 @@ -3,7 +3,7 @@ |
| 4 * All rights reserved | 4 * All rights reserved |
| 5 * | 5 * |
| 6 * Redistribution and use in source and binary forms, with or without | 6 * Redistribution and use in source and binary forms, with or without |
| 7 - * modification, are permitted providing that the following conditions | 7 - * modification, are permitted providing that the following conditions |
| 8 + * modification, are permitted providing that the following conditions | 8 + * modification, are permitted providing that the following conditions |
| 9 * are met: | 9 * are met: |
| 10 * 1. Redistributions of source code must retain the above copyright | 10 * 1. Redistributions of source code must retain the above copyright |
| 11 * notice, this list of conditions and the following disclaimer. | 11 * notice, this list of conditions and the following disclaimer. |
| 12 @@ -29,6 +29,9 @@ __FBSDID("$FreeBSD: src/usr.bin/bsdiff/b | 12 @@ -29,6 +29,9 @@ |
| 13 #endif | 13 #endif |
| 14 | 14 |
| 15 #include <bzlib.h> | 15 #include <bzlib.h> |
| 16 +#include <errno.h> | 16 +#include <errno.h> |
| 17 +#include <inttypes.h> | 17 +#include <inttypes.h> |
| 18 +#include <stdint.h> | 18 +#include <stdint.h> |
| 19 #include <stdlib.h> | 19 #include <stdlib.h> |
| 20 #include <stdio.h> | 20 #include <stdio.h> |
| 21 #include <string.h> | 21 #include <string.h> |
| 22 @@ -36,6 +39,244 @@ __FBSDID("$FreeBSD: src/usr.bin/bsdiff/b | 22 @@ -36,6 +39,264 @@ |
| 23 #include <unistd.h> | 23 #include <unistd.h> |
| 24 #include <fcntl.h> | 24 #include <fcntl.h> |
| 25 | 25 |
| 26 +#define JOIN(a, b) __JOIN(a, b) | 26 +#define JOIN(a, b) __JOIN(a, b) |
| 27 +#define __JOIN(a, b) a ## b | 27 +#define __JOIN(a, b) a ## b |
| 28 +#define COMPILE_ASSERT(expr, message) \ | 28 +#define COMPILE_ASSERT(expr, message) \ |
| 29 + typedef char JOIN(message, JOIN(_, __LINE__)) [(expr) ? 1 : -1] | 29 + typedef char JOIN(message, JOIN(_, __LINE__)) [(expr) ? 1 : -1] |
| 30 + | 30 + |
| 31 +COMPILE_ASSERT(sizeof(int64_t) == 8, int64_t_64_bit); | 31 +COMPILE_ASSERT(sizeof(int64_t) == 8, int64_t_64_bit); |
| 32 +COMPILE_ASSERT(sizeof(off_t) == 8, off_t_64_bit); | 32 +COMPILE_ASSERT(sizeof(off_t) == 8, off_t_64_bit); |
| 33 + | 33 + |
| 34 +#define MIN(a, b) \ | 34 +#define MIN(a, b) \ |
| 35 + ((a) < (b) ? (a) : (b)) | 35 + ((a) < (b) ? (a) : (b)) |
| 36 + | 36 + |
| 37 +static const char kFdFilePrefix[] = "/dev/fd/"; | |
| 38 + | |
| 37 +// Reads next int from *ints. The int should be terminated with a comma | 39 +// Reads next int from *ints. The int should be terminated with a comma |
| 38 +// or NULL char. *ints will be updated to the space right after the comma | 40 +// or NULL char. *ints will be updated to the space right after the comma |
| 39 +// or set to NULL if this was the last number. This assumes the input is | 41 +// or set to NULL if this was the last number. This assumes the input is |
| 40 +// a valid string, as validated with PositionsStringIsValid(). | 42 +// a valid string, as validated with PositionsStringIsValid(). |
| 41 +// Returns 1 on success. | 43 +// Returns 1 on success. |
| 42 +int NextInt64(const char** ints, int64_t *out) { | 44 +int NextInt64(const char** ints, int64_t *out) { |
| 43 + if (!ints[0]) | 45 + if (!ints[0]) |
| 44 + return 0; | 46 + return 0; |
| 45 + int r = sscanf(*ints, "%" PRIi64, out); | 47 + int r = sscanf(*ints, "%" PRIi64, out); |
| 46 + if (r == 1) { | 48 + if (r == 1) { |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 58 + } | 60 + } |
| 59 + return 0; | 61 + return 0; |
| 60 +} | 62 +} |
| 61 + | 63 + |
| 62 +COMPILE_ASSERT(sizeof(intmax_t) == 8, intmax_t_not_64_bit); | 64 +COMPILE_ASSERT(sizeof(intmax_t) == 8, intmax_t_not_64_bit); |
| 63 + | 65 + |
| 64 +// Returns 1 if str can be converted to int64_t without over/underflowing. | 66 +// Returns 1 if str can be converted to int64_t without over/underflowing. |
| 65 +// str is assumed to point to an optional negative sign followed by numbers, | 67 +// str is assumed to point to an optional negative sign followed by numbers, |
| 66 +// optionally followed by non-numeric characters, followed by '\0'. | 68 +// optionally followed by non-numeric characters, followed by '\0'. |
| 67 +int IsValidInt64(const char* str) { | 69 +int IsValidInt64(const char* str) { |
| 68 +» const char* end_ptr = 0; | 70 +» char* end_ptr = 0; |
| 69 + errno = 0; | 71 + errno = 0; |
| 70 + intmax_t result = strtoimax(str, &end_ptr, /* base: */ 10); | 72 + intmax_t result = strtoimax(str, &end_ptr, /* base: */ 10); |
| 71 + return errno == 0; | 73 + return errno == 0; |
| 72 +} | 74 +} |
| 73 + | 75 + |
| 74 +// Input validator. Make sure the positions string is well formatted. | 76 +// Input validator. Make sure the positions string is well formatted. |
| 75 +// All numerical values are checked to make sure they don't over/underflow | 77 +// All numerical values are checked to make sure they don't over/underflow |
| 76 +// int64_t. Returns 1 if valid. | 78 +// int64_t. Returns 1 if valid. |
| 77 +int PositionsStringIsValid(const char* positions) { | 79 +int PositionsStringIsValid(const char* positions) { |
| 78 + if (positions == NULL) | 80 + if (positions == NULL) |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 173 + if (length > 0x40000000) { // 1 GiB; sanity check | 175 + if (length > 0x40000000) { // 1 GiB; sanity check |
| 174 + errx(1, "Read length too long (exceeds 1 GiB)"); | 176 + errx(1, "Read length too long (exceeds 1 GiB)"); |
| 175 + } | 177 + } |
| 176 + // Following bsdiff convention, allocate length + 1 to avoid malloc(0) | 178 + // Following bsdiff convention, allocate length + 1 to avoid malloc(0) |
| 177 + char* buf = malloc(length + 1); | 179 + char* buf = malloc(length + 1); |
| 178 + if (buf == NULL) { | 180 + if (buf == NULL) { |
| 179 + errx(1, "malloc failed\n"); | 181 + errx(1, "malloc failed\n"); |
| 180 + } | 182 + } |
| 181 + char* buf_tail = buf; | 183 + char* buf_tail = buf; |
| 182 + | 184 + |
| 183 +» int fd = open(filename, O_RDONLY); | 185 +» int fd = -1; |
| 186 +» int should_close = 1; | |
| 187 +» if (strlen(filename) > strlen(kFdFilePrefix) && | |
| 188 +» » !strncmp(filename, kFdFilePrefix, strlen(kFdFilePrefix))) { | |
| 189 +» » sscanf(filename + strlen(kFdFilePrefix), "%d", &fd); | |
|
petkov
2010/10/12 21:53:23
given that you're not detecting errors, why not us
| |
| 190 +» » should_close = 0; | |
| 191 +» } else { | |
| 192 +» » fd = open(filename, O_RDONLY); | |
| 193 +» } | |
| 184 + if (fd < 0) { | 194 + if (fd < 0) { |
| 185 + errx(1, "open failed for read\n"); | 195 + errx(1, "open failed for read\n"); |
| 186 + } | 196 + } |
| 187 + | 197 + |
| 188 + // Read bytes | 198 + // Read bytes |
| 189 + p = positions; | 199 + p = positions; |
| 190 + for (;;) { | 200 + for (;;) { |
| 191 + int64_t offset, read_length; | 201 + int64_t offset, read_length; |
| 192 + if (NextInt64(&p, &offset) == 0) { | 202 + if (NextInt64(&p, &offset) == 0) { |
| 193 + break; | 203 + break; |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 205 + } | 215 + } |
| 206 + if (read_length > kMaxLength) { | 216 + if (read_length > kMaxLength) { |
| 207 + errx(1, "read length too large\n"); | 217 + errx(1, "read length too large\n"); |
| 208 + } | 218 + } |
| 209 + ssize_t rc = pread(fd, buf_tail, (size_t)read_length, (off_t)off set); | 219 + ssize_t rc = pread(fd, buf_tail, (size_t)read_length, (off_t)off set); |
| 210 + if (rc != read_length) { | 220 + if (rc != read_length) { |
| 211 + errx(1, "read failed\n"); | 221 + errx(1, "read failed\n"); |
| 212 + } | 222 + } |
| 213 + buf_tail += rc; | 223 + buf_tail += rc; |
| 214 + } | 224 + } |
| 215 +» close(fd); | 225 +» if (should_close) |
| 226 +» » close(fd); | |
| 216 + *old_size = length; | 227 + *old_size = length; |
| 217 + return buf; | 228 + return buf; |
| 218 +} | 229 +} |
| 219 + | 230 + |
| 220 +static void PositionedWrite(const char* filename, | 231 +static void PositionedWrite(const char* filename, |
| 221 + const char* positions, | 232 + const char* positions, |
| 222 + const char* buf, | 233 + const char* buf, |
| 223 + ssize_t new_size) { | 234 + ssize_t new_size) { |
| 224 + if (!PositionsStringIsValid(positions)) { | 235 + if (!PositionsStringIsValid(positions)) { |
| 225 + errx(1, "invalid positions string for write\n"); | 236 + errx(1, "invalid positions string for write\n"); |
| 226 + } | 237 + } |
| 227 +» int fd = open(filename, O_WRONLY | O_CREAT, 0666); | 238 +» int fd = -1; |
| 239 +» int should_close = 1; | |
| 240 +» if (strlen(filename) > strlen(kFdFilePrefix) && | |
| 241 +» » !strncmp(filename, kFdFilePrefix, strlen(kFdFilePrefix))) { | |
| 242 +» » sscanf(filename + strlen(kFdFilePrefix), "%d", &fd); | |
| 243 +» » should_close = 0; | |
| 244 +» } else { | |
| 245 +» » fd = open(filename, O_WRONLY | O_CREAT, 0666); | |
| 246 +» } | |
| 228 + if (fd < 0) { | 247 + if (fd < 0) { |
| 229 + errx(1, "open failed for write\n"); | 248 + errx(1, "open failed for write\n"); |
| 230 + } | 249 + } |
| 231 + | 250 + |
| 232 + for (;;) { | 251 + for (;;) { |
| 233 + int64_t offset, length; | 252 + int64_t offset, length; |
| 234 + if (NextInt64(&positions, &offset) == 0) { | 253 + if (NextInt64(&positions, &offset) == 0) { |
| 235 + break; | 254 + break; |
| 236 + } | 255 + } |
| 237 + if (NextInt64(&positions, &length) == 0) { | 256 + if (NextInt64(&positions, &length) == 0) { |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 251 + if (rc != length) { | 270 + if (rc != length) { |
| 252 + errx(1, "write failed\n"); | 271 + errx(1, "write failed\n"); |
| 253 + } | 272 + } |
| 254 + } | 273 + } |
| 255 + buf += length; | 274 + buf += length; |
| 256 + new_size -= length; | 275 + new_size -= length; |
| 257 + } | 276 + } |
| 258 + if (new_size != 0) { | 277 + if (new_size != 0) { |
| 259 + errx(1, "output position length doesn't match new size\n"); | 278 + errx(1, "output position length doesn't match new size\n"); |
| 260 + } | 279 + } |
| 261 +» close(fd); | 280 +» if (should_close) |
| 281 +» » close(fd); | |
| 262 +} | 282 +} |
| 263 + | 283 + |
| 264 static off_t offtin(u_char *buf) | 284 static off_t offtin(u_char *buf) |
| 265 { | 285 { |
| 266 off_t y; | 286 off_t y; |
| 267 @@ -69,7 +310,13 @@ int main(int argc,char * argv[]) | 287 @@ -69,7 +330,13 @@ |
| 268 off_t lenread; | 288 off_t lenread; |
| 269 off_t i; | 289 off_t i; |
| 270 | 290 |
| 271 - if(argc!=4) errx(1,"usage: %s oldfile newfile patchfile\n",argv[0]); | 291 - if(argc!=4) errx(1,"usage: %s oldfile newfile patchfile\n",argv[0]); |
| 272 + if ((argc != 6) && (argc != 4)) { | 292 + if ((argc != 6) && (argc != 4)) { |
| 273 + errx(1,"usage: %s oldfile newfile patchfile \\\n" | 293 + errx(1,"usage: %s oldfile newfile patchfile \\\n" |
| 274 + " [in_offset,in_length,in_offset,in_length,... \\\n" | 294 + " [in_offset,in_length,in_offset,in_length,... \\\n" |
| 275 + " out_offset,out_length," | 295 + " out_offset,out_length," |
| 276 + "out_offset,out_length,...]\n",argv[0]); | 296 + "out_offset,out_length,...]\n",argv[0]); |
| 277 + } | 297 + } |
| 278 + int using_positioning = (argc == 6); | 298 + int using_positioning = (argc == 6); |
| 279 | 299 |
| 280 /* Open patch file */ | 300 /* Open patch file */ |
| 281 if ((f = fopen(argv[3], "r")) == NULL) | 301 if ((f = fopen(argv[3], "r")) == NULL) |
| 282 @@ -132,12 +379,18 @@ int main(int argc,char * argv[]) | 302 @@ -132,12 +399,18 @@ |
| 283 if ((epfbz2 = BZ2_bzReadOpen(&ebz2err, epf, 0, 0, NULL, 0)) == NULL) | 303 if ((epfbz2 = BZ2_bzReadOpen(&ebz2err, epf, 0, 0, NULL, 0)) == NULL) |
| 284 errx(1, "BZ2_bzReadOpen, bz2err = %d", ebz2err); | 304 errx(1, "BZ2_bzReadOpen, bz2err = %d", ebz2err); |
| 285 | 305 |
| 286 - if(((fd=open(argv[1],O_RDONLY,0))<0) || | 306 - if(((fd=open(argv[1],O_RDONLY,0))<0) || |
| 287 - ((oldsize=lseek(fd,0,SEEK_END))==-1) || | 307 - ((oldsize=lseek(fd,0,SEEK_END))==-1) || |
| 288 - ((old=malloc(oldsize+1))==NULL) || | 308 - ((old=malloc(oldsize+1))==NULL) || |
| 289 - (lseek(fd,0,SEEK_SET)!=0) || | 309 - (lseek(fd,0,SEEK_SET)!=0) || |
| 290 - (read(fd,old,oldsize)!=oldsize) || | 310 - (read(fd,old,oldsize)!=oldsize) || |
| 291 - (close(fd)==-1)) err(1,"%s",argv[1]); | 311 - (close(fd)==-1)) err(1,"%s",argv[1]); |
| 292 + // Read | 312 + // Read |
| 293 + | 313 + |
| 294 + if (!using_positioning) { | 314 + if (!using_positioning) { |
| 295 + if(((fd=open(argv[1],O_RDONLY,0))<0) || | 315 + if(((fd=open(argv[1],O_RDONLY,0))<0) || |
| 296 + ((oldsize=lseek(fd,0,SEEK_END))==-1) || | 316 + ((oldsize=lseek(fd,0,SEEK_END))==-1) || |
| 297 + ((old=malloc(oldsize+1))==NULL) || | 317 + ((old=malloc(oldsize+1))==NULL) || |
| 298 + (lseek(fd,0,SEEK_SET)!=0) || | 318 + (lseek(fd,0,SEEK_SET)!=0) || |
| 299 + (read(fd,old,oldsize)!=oldsize) || | 319 + (read(fd,old,oldsize)!=oldsize) || |
| 300 + (close(fd)==-1)) err(1,"%s",argv[1]); | 320 + (close(fd)==-1)) err(1,"%s",argv[1]); |
| 301 + } else { | 321 + } else { |
| 302 + old = PositionedRead(argv[1], argv[4], &oldsize); | 322 + old = PositionedRead(argv[1], argv[4], &oldsize); |
| 303 + } | 323 + } |
| 304 if((new=malloc(newsize+1))==NULL) err(1,NULL); | 324 if((new=malloc(newsize+1))==NULL) err(1,NULL); |
| 305 | 325 |
| 306 oldpos=0;newpos=0; | 326 oldpos=0;newpos=0; |
| 307 @@ -193,9 +446,13 @@ int main(int argc,char * argv[]) | 327 @@ -193,9 +466,13 @@ |
| 308 err(1, "fclose(%s)", argv[3]); | 328 err(1, "fclose(%s)", argv[3]); |
| 309 | 329 |
| 310 /* Write the new file */ | 330 /* Write the new file */ |
| 311 - if(((fd=open(argv[2],O_CREAT|O_TRUNC|O_WRONLY,0666))<0) || | 331 - if(((fd=open(argv[2],O_CREAT|O_TRUNC|O_WRONLY,0666))<0) || |
| 312 - (write(fd,new,newsize)!=newsize) || (close(fd)==-1)) | 332 - (write(fd,new,newsize)!=newsize) || (close(fd)==-1)) |
| 313 - err(1,"%s",argv[2]); | 333 - err(1,"%s",argv[2]); |
| 314 + if (!using_positioning) { | 334 + if (!using_positioning) { |
| 315 + if(((fd=open(argv[2],O_CREAT|O_TRUNC|O_WRONLY,0666))<0) || | 335 + if(((fd=open(argv[2],O_CREAT|O_TRUNC|O_WRONLY,0666))<0) || |
| 316 + (write(fd,new,newsize)!=newsize) || (close(fd)==-1)) | 336 + (write(fd,new,newsize)!=newsize) || (close(fd)==-1)) |
| 317 + err(1,"%s",argv[2]); | 337 + err(1,"%s",argv[2]); |
| 318 + } else { | 338 + } else { |
| 319 + PositionedWrite(argv[2], argv[5], new, newsize); | 339 + PositionedWrite(argv[2], argv[5], new, newsize); |
| 320 + } | 340 + } |
| 321 | 341 |
| 322 free(new); | 342 free(new); |
| 323 free(old); | 343 free(old); |
| OLD | NEW |