Skip to content

Commit e567a44

Browse files
committed
throw out exceptions when error happens, and add tests for that
1 parent ccaae95 commit e567a44

File tree

4 files changed

+151
-29
lines changed

4 files changed

+151
-29
lines changed

php_bsdiff.c

Lines changed: 46 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ static int bz2_read(const struct bspatch_stream* stream, void* buffer, int lengt
5656
return 0;
5757
}
5858

59-
/* {{{ bool bsdiff_diff( string $oldFile, string $newFile, string $patchFile ) */
59+
/* {{{ void bsdiff_diff( string $old_file, string $new_file, string $patch_file ) */
6060
PHP_FUNCTION(bsdiff_diff)
6161
{
6262
char *old_file, *new_file, *diff_file;
@@ -89,8 +89,10 @@ PHP_FUNCTION(bsdiff_diff)
8989
((old=malloc(oldsize+1))==NULL) ||
9090
(lseek(fd,0,SEEK_SET)!=0) ||
9191
(read(fd,old,oldsize)!=oldsize) ||
92-
(close(fd)==-1)) err(1,"%s",old_file);
93-
92+
(close(fd)==-1)) {
93+
zend_throw_exception_ex(ce_bsdiff_exception, 0, "Failed to read data from the old file \"%s\"", old_file);
94+
RETURN_THROWS();
95+
}
9496

9597
/* Allocate newsize+1 bytes instead of newsize bytes to ensure
9698
that we never try to malloc(0) and get a NULL pointer */
@@ -99,48 +101,55 @@ PHP_FUNCTION(bsdiff_diff)
99101
((new=malloc(newsize+1))==NULL) ||
100102
(lseek(fd,0,SEEK_SET)!=0) ||
101103
(read(fd,new,newsize)!=newsize) ||
102-
(close(fd)==-1)) err(1,"%s",new_file);
104+
(close(fd)==-1)) {
105+
zend_throw_exception_ex(ce_bsdiff_exception, 0, "Failed to read data from the new file \"%s\"", new_file);
106+
RETURN_THROWS();
107+
}
103108

104109
/* Create the patch file */
105110
if ((pf = fopen(diff_file, "w")) == NULL) {
106-
err(1, "%s", diff_file);
111+
zend_throw_exception_ex(ce_bsdiff_exception, 0, "Cannot open the diff file \"%s\" in write mode", diff_file);
112+
RETURN_THROWS();
107113
}
108114

109115
/* Write header (signature+newsize)*/
110116
offtout(newsize, buf);
111117
if (fwrite("ENDSLEY/BSDIFF43", 16, 1, pf) != 1 ||
112118
fwrite(buf, sizeof(buf), 1, pf) != 1) {
113-
err(1, "Failed to write header");
119+
zend_throw_exception_ex(ce_bsdiff_exception, 0, "Failed to write header to the diff file");
120+
RETURN_THROWS();
114121
}
115122

116123

117124
if (NULL == (bz2 = BZ2_bzWriteOpen(&bz2err, pf, 9, 0, 0))) {
118-
errx(1, "BZ2_bzWriteOpen, bz2err=%d", bz2err);
125+
zend_throw_exception_ex(ce_bsdiff_exception, 0, "Failed to prepare to write data to the diff file (bz2err=%d)", bz2err);
126+
RETURN_THROWS();
119127
}
120128

121129
stream.opaque = bz2;
122130
if (bsdiff(old, oldsize, new, newsize, &stream)) {
123-
err(1, "bsdiff");
131+
zend_throw_exception_ex(ce_bsdiff_exception, 0, "Failed to create diff data");
132+
RETURN_THROWS();
124133
}
125134

126135
BZ2_bzWriteClose(&bz2err, bz2, 0, NULL, NULL);
127136
if (bz2err != BZ_OK) {
128-
err(1, "BZ2_bzWriteClose, bz2err=%d", bz2err);
137+
zend_throw_exception_ex(ce_bsdiff_exception, 0, "Failed to complete writing data to the diff file (bz2err=%d)", bz2err);
138+
RETURN_THROWS();
129139
}
130140

131141
if (fclose(pf)) {
132-
err(1, "fclose");
142+
zend_throw_exception_ex(ce_bsdiff_exception, 0, "Failed to close the diff file");
143+
RETURN_THROWS();
133144
}
134145

135146
/* Free the memory we used */
136147
free(old);
137148
free(new);
138-
139-
RETURN_TRUE;
140149
}
141150
/* }}} */
142151

143-
/* {{{ bool bsdiff_patch( string $oldFile, string $newFile, string $patchFile ) */
152+
/* {{{ void bsdiff_patch( string $old_file, string $new_file, string $patch_file ) */
144153
PHP_FUNCTION(bsdiff_patch)
145154
{
146155
char *old_file, *new_file, *diff_file;
@@ -164,26 +173,31 @@ PHP_FUNCTION(bsdiff_patch)
164173

165174
/* Open patch file */
166175
if ((f = fopen(diff_file, "r")) == NULL) {
167-
err(1, "fopen(%s)", diff_file);
176+
zend_throw_exception_ex(ce_bsdiff_exception, 0, "Cannot open diff file \"%s\" in read mode", diff_file);
177+
RETURN_THROWS();
168178
}
169179

170180
/* Read header */
171181
if (fread(header, 1, 24, f) != 24) {
172182
if (feof(f)) {
173-
errx(1, "Corrupt patch\n");
183+
zend_throw_exception_ex(ce_bsdiff_exception, 0, "The diff file is corrupted (missing header information)");
184+
RETURN_THROWS();
174185
}
175-
err(1, "fread(%s)", diff_file);
186+
zend_throw_exception_ex(ce_bsdiff_exception, 0, "Failed to read data from the diff file");
187+
RETURN_THROWS();
176188
}
177189

178190
/* Check for appropriate magic */
179191
if (memcmp(header, "ENDSLEY/BSDIFF43", 16) != 0) {
180-
errx(1, "Corrupt patch\n");
192+
zend_throw_exception_ex(ce_bsdiff_exception, 0, "The diff file is corrupted (invalid header information)");
193+
RETURN_THROWS();
181194
}
182195

183196
/* Read lengths from header */
184197
newsize=offtin(header+16);
185198
if(newsize<0) {
186-
errx(1,"Corrupt patch\n");
199+
zend_throw_exception_ex(ce_bsdiff_exception, 0, "The diff file is corrupted (invalid length information)");
200+
RETURN_THROWS();
187201
}
188202

189203
/* Close patch file and re-open it via libbzip2 at the right places */
@@ -193,17 +207,25 @@ PHP_FUNCTION(bsdiff_patch)
193207
(lseek(fd,0,SEEK_SET)!=0) ||
194208
(read(fd,old,oldsize)!=oldsize) ||
195209
(fstat(fd, &sb)) ||
196-
(close(fd)==-1)) err(1,"%s",old_file);
197-
if((new=malloc(newsize+1))==NULL) err(1,NULL);
210+
(close(fd)==-1)) {
211+
zend_throw_exception_ex(ce_bsdiff_exception, 0, "Failed to read data from the old file \"%s\"", old_file);
212+
RETURN_THROWS();
213+
}
214+
if((new=malloc(newsize+1))==NULL) {
215+
zend_throw_exception_ex(ce_bsdiff_exception, 0, "Failed to allocate memory to store patched data");
216+
RETURN_THROWS();
217+
}
198218

199219
if (NULL == (bz2 = BZ2_bzReadOpen(&bz2err, f, 0, 0, NULL, 0))) {
200-
errx(1, "BZ2_bzReadOpen, bz2err=%d", bz2err);
220+
zend_throw_exception_ex(ce_bsdiff_exception, 0, "Failed to read data from the diff file (bz2err=%d)", bz2err);
221+
RETURN_THROWS();
201222
}
202223

203224
stream.read = bz2_read;
204225
stream.opaque = bz2;
205226
if (bspatch(old, oldsize, new, newsize, &stream)) {
206-
errx(1, "bspatch");
227+
zend_throw_exception_ex(ce_bsdiff_exception, 0, "Failed to apply diff data");
228+
RETURN_THROWS();
207229
}
208230

209231
/* Clean up the bzip2 reads */
@@ -213,13 +235,12 @@ PHP_FUNCTION(bsdiff_patch)
213235
/* Write the new file */
214236
if(((fd=open(new_file,O_CREAT|O_TRUNC|O_WRONLY,sb.st_mode))<0) ||
215237
(write(fd,new,newsize)!=newsize) || (close(fd)==-1)) {
216-
err(1,"%s",new_file);
238+
zend_throw_exception_ex(ce_bsdiff_exception, 0, "Failed to create the new file \"%s\"", new_file);
239+
RETURN_THROWS();
217240
}
218241

219242
free(new);
220243
free(old);
221-
222-
RETURN_TRUE;
223244
}
224245
/* }}}*/
225246

tests/002_basic.phpt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ Basic test on bsdiff functions
44
bsdiff
55
--FILE--
66
<?php
7-
$old_file = __DIR__ . '/old.out';
8-
$new_file = __DIR__ . '/new.out';
9-
$diff_file = __DIR__ . '/diff.out';
10-
$patched_file = __DIR__ . '/patched.out';
7+
$old_file = __DIR__ . '/002_old.out';
8+
$new_file = __DIR__ . '/002_new.out';
9+
$diff_file = __DIR__ . '/002_diff.out';
10+
$patched_file = __DIR__ . '/002_patched.out';
1111

1212
file_put_contents($old_file, str_repeat("Hello World", 1997));
1313
file_put_contents($new_file, str_repeat("Hello PHP", 1999));

tests/003_bsdiff_exceptions.phpt

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
--TEST--
2+
Test exceptions thrown from function bsdiff_diff()
3+
--EXTENSIONS--
4+
bsdiff
5+
--FILE--
6+
<?php
7+
$old_file = __DIR__ . '/003_old.out';
8+
$new_file = __DIR__ . '/003_new.out';
9+
$diff_file = __DIR__ . '/003_diff.out';
10+
11+
foreach ([$old_file, $new_file, $diff_file] as $file) {
12+
if (file_exists($file)) unlink($file);
13+
}
14+
15+
try {
16+
bsdiff_diff($old_file, $new_file, $diff_file);
17+
} catch (BsdiffException $e) {
18+
var_dump($e->getMessage());
19+
}
20+
21+
file_put_contents($old_file, str_repeat("Hello World", 1997));
22+
try {
23+
bsdiff_diff($old_file, $new_file, $diff_file);
24+
} catch (BsdiffException $e) {
25+
var_dump($e->getMessage());
26+
}
27+
28+
file_put_contents($new_file, str_repeat("Hello PHP", 1999));
29+
touch($diff_file);
30+
chmod($diff_file, 0444);
31+
try {
32+
bsdiff_diff($old_file, $new_file, $diff_file);
33+
} catch (BsdiffException $e) {
34+
var_dump($e->getMessage());
35+
}
36+
?>
37+
--EXPECTF--
38+
string(%d) "Failed to read data from the old file "%s/tests/003_old.out""
39+
string(%d) "Failed to read data from the new file "%s/tests/003_new.out""
40+
string(%d) "Cannot open the diff file "%s/tests/003_diff.out" in write mode"

tests/004_bspatch_exceptions.phpt

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
--TEST--
2+
Test exceptions thrown from function bsdiff_patch()
3+
--EXTENSIONS--
4+
bsdiff
5+
--FILE--
6+
<?php
7+
$old_file = __DIR__ . '/004_old.out';
8+
$new_file = __DIR__ . '/004_new.out';
9+
$diff_file = __DIR__ . '/004_diff.out';
10+
$patched_file = __DIR__ . '/004_patched.out';
11+
12+
foreach ([$old_file, $new_file, $diff_file, $patched_file] as $file) {
13+
if (file_exists($file)) unlink($file);
14+
}
15+
16+
try {
17+
bsdiff_patch($old_file, $patched_file, $diff_file);
18+
} catch (BsdiffException $e) {
19+
var_dump($e->getMessage());
20+
}
21+
22+
touch($diff_file);
23+
try {
24+
bsdiff_patch($old_file, $patched_file, $diff_file);
25+
} catch (BsdiffException $e) {
26+
var_dump($e->getMessage());
27+
}
28+
29+
file_put_contents($diff_file, "DEMINY/BSDIFF43**********");
30+
try {
31+
bsdiff_patch($old_file, $patched_file, $diff_file);
32+
} catch (BsdiffException $e) {
33+
var_dump($e->getMessage());
34+
}
35+
36+
file_put_contents($old_file, str_repeat("Hello World", 1997));
37+
file_put_contents($new_file, str_repeat("Hello PHP", 1999));
38+
bsdiff_diff($old_file, $new_file, $diff_file);
39+
40+
unlink($old_file);
41+
try {
42+
bsdiff_patch($old_file, $patched_file, $diff_file);
43+
} catch (BsdiffException $e) {
44+
var_dump($e->getMessage());
45+
}
46+
file_put_contents($old_file, str_repeat("Hello World", 1997));
47+
48+
touch($patched_file);
49+
chmod($patched_file, 0444);
50+
try {
51+
bsdiff_patch($old_file, $patched_file, $diff_file);
52+
} catch (BsdiffException $e) {
53+
var_dump($e->getMessage());
54+
}
55+
?>
56+
--EXPECTF--
57+
string(%d) "Cannot open diff file "%s/tests/004_diff.out" in read mode"
58+
string(%d) "The diff file is corrupted (missing header information)"
59+
string(%d) "The diff file is corrupted (invalid header information)"
60+
string(%d) "Failed to read data from the old file "%s/tests/004_old.out""
61+
string(%d) "Failed to create the new file "%s/tests/004_patched.out""

0 commit comments

Comments
 (0)