Skip to content

Commit 28a1a6b

Browse files
authored
phar: use crc32 bulk method instead. (#6099)
phar: use crc32 bulk method instead. Benefit from the hardware crc32 computing. Signed-off-by: Frank Du <[email protected]>
1 parent 578b67d commit 28a1a6b

File tree

4 files changed

+55
-28
lines changed

4 files changed

+55
-28
lines changed

ext/phar/phar.c

+5-10
Original file line numberDiff line numberDiff line change
@@ -2374,7 +2374,7 @@ int phar_open_executed_filename(char *alias, size_t alias_len, char **error) /*
23742374
int phar_postprocess_file(phar_entry_data *idata, uint32_t crc32, char **error, int process_zip) /* {{{ */
23752375
{
23762376
uint32_t crc = ~0;
2377-
int len = idata->internal_file->uncompressed_filesize;
2377+
int len = idata->internal_file->uncompressed_filesize, ret;
23782378
php_stream *fp = idata->fp;
23792379
phar_entry_info *entry = idata->internal_file;
23802380

@@ -2439,13 +2439,11 @@ int phar_postprocess_file(phar_entry_data *idata, uint32_t crc32, char **error,
24392439

24402440
php_stream_seek(fp, idata->zero, SEEK_SET);
24412441

2442-
while (len--) {
2443-
CRC32(crc, php_stream_getc(fp));
2444-
}
2442+
ret = crc32_stream_bulk_update(&crc, fp, len);
24452443

24462444
php_stream_seek(fp, idata->zero, SEEK_SET);
24472445

2448-
if (~crc == crc32) {
2446+
if (SUCCESS == ret && ~crc == crc32) {
24492447
entry->is_crc_checked = 1;
24502448
return SUCCESS;
24512449
} else {
@@ -2539,7 +2537,7 @@ int phar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int conv
25392537
zend_off_t manifest_ftell;
25402538
zend_long offset;
25412539
size_t wrote;
2542-
uint32_t manifest_len, mytime, loc, new_manifest_count;
2540+
uint32_t manifest_len, mytime, new_manifest_count;
25432541
uint32_t newcrc32;
25442542
php_stream *file, *oldfile, *newfile, *stubfile;
25452543
php_stream_filter *filter;
@@ -2796,10 +2794,7 @@ int phar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int conv
27962794
return EOF;
27972795
}
27982796
newcrc32 = ~0;
2799-
mytime = entry->uncompressed_filesize;
2800-
for (loc = 0;loc < mytime; ++loc) {
2801-
CRC32(newcrc32, php_stream_getc(file));
2802-
}
2797+
crc32_stream_bulk_update(&newcrc32, file, entry->uncompressed_filesize);
28032798
entry->crc32 = ~newcrc32;
28042799
entry->is_crc_checked = 1;
28052800
if (!(entry->flags & PHAR_ENT_COMPRESSION_MASK)) {

ext/phar/zip.c

+1-4
Original file line numberDiff line numberDiff line change
@@ -882,7 +882,6 @@ static int phar_zip_changed_apply_int(phar_entry_info *entry, void *arg) /* {{{
882882

883883
/* do extra field for perms later */
884884
if (entry->is_modified) {
885-
uint32_t loc;
886885
php_stream_filter *filter;
887886
php_stream *efp;
888887

@@ -915,9 +914,7 @@ static int phar_zip_changed_apply_int(phar_entry_info *entry, void *arg) /* {{{
915914
efp = phar_get_efp(entry, 0);
916915
newcrc32 = ~0;
917916

918-
for (loc = 0;loc < entry->uncompressed_filesize; ++loc) {
919-
CRC32(newcrc32, php_stream_getc(efp));
920-
}
917+
crc32_stream_bulk_update(&newcrc32, efp, entry->uncompressed_filesize);
921918

922919
entry->crc32 = ~newcrc32;
923920
PHAR_SET_32(central.uncompsize, entry->uncompressed_filesize);

ext/standard/crc32.c

+44-14
Original file line numberDiff line numberDiff line change
@@ -89,24 +89,12 @@ static uint32_t crc32_aarch64(uint32_t crc, char *p, size_t nr) {
8989
# endif
9090
#endif
9191

92-
/* {{{ Calculate the crc32 polynomial of a string */
93-
PHP_FUNCTION(crc32)
92+
uint32_t crc32_bulk_update(uint32_t crc, const char *p, size_t nr)
9493
{
95-
char *p;
96-
size_t nr;
97-
uint32_t crcinit = 0;
98-
uint32_t crc;
99-
100-
ZEND_PARSE_PARAMETERS_START(1, 1)
101-
Z_PARAM_STRING(p, nr)
102-
ZEND_PARSE_PARAMETERS_END();
103-
104-
crc = crcinit^0xFFFFFFFF;
105-
10694
#if HAVE_AARCH64_CRC32
10795
if (has_crc32_insn()) {
10896
crc = crc32_aarch64(crc, p, nr);
109-
RETURN_LONG(crc^0xFFFFFFFF);
97+
return crc;
11098
}
11199
#endif
112100

@@ -116,9 +104,51 @@ PHP_FUNCTION(crc32)
116104
p += nr_simd;
117105
#endif
118106

107+
/* The trailing part */
119108
for (; nr--; ++p) {
120109
crc = ((crc >> 8) & 0x00FFFFFF) ^ crc32tab[(crc ^ (*p)) & 0xFF ];
121110
}
111+
112+
return crc;
113+
}
114+
115+
int crc32_stream_bulk_update(uint32_t *crc, php_stream *fp, size_t nr)
116+
{
117+
size_t handled = 0, n;
118+
char buf[1024];
119+
120+
while (handled < nr) {
121+
n = nr - handled;
122+
n = (n < sizeof(buf)) ? n : sizeof(buf); /* tweak to buf size */
123+
124+
n = php_stream_read(fp, buf, n);
125+
if (n > 0) {
126+
*crc = crc32_bulk_update(*crc, buf, n);
127+
handled += n;
128+
} else { /* EOF */
129+
return FAILURE;
130+
}
131+
}
132+
133+
return SUCCESS;
134+
}
135+
136+
/* {{{ Calculate the crc32 polynomial of a string */
137+
PHP_FUNCTION(crc32)
138+
{
139+
char *p;
140+
size_t nr;
141+
uint32_t crcinit = 0;
142+
uint32_t crc;
143+
144+
ZEND_PARSE_PARAMETERS_START(1, 1)
145+
Z_PARAM_STRING(p, nr)
146+
ZEND_PARSE_PARAMETERS_END();
147+
148+
crc = crcinit^0xFFFFFFFF;
149+
150+
crc = crc32_bulk_update(crc, p, nr);
151+
122152
RETURN_LONG(crc^0xFFFFFFFF);
123153
}
124154
/* }}} */

ext/standard/crc32.h

+5
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@
2323

2424
#define CRC32(crc, ch) (crc = (crc >> 8) ^ crc32tab[(crc ^ (ch)) & 0xff])
2525

26+
uint32_t crc32_bulk_update(uint32_t crc, const char *p, size_t nr);
27+
28+
/* Return FAILURE if stream reading fail */
29+
int crc32_stream_bulk_update(uint32_t *crc, php_stream *fp, size_t nr);
30+
2631
/* generated using the AUTODIN II polynomial
2732
* x^32 + x^26 + x^23 + x^22 + x^16 +
2833
* x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x^1 + 1

0 commit comments

Comments
 (0)