mirror of
https://github.com/php/pecl-database-dbase.git
synced 2026-03-23 23:12:08 +01:00
Fix #81563: SIGSEGV reading dbase file with few data
When reading a field descriptor array, we must not assume to actually read the full array, but rather be prepared to only read the field terminator. We also must not return arbitrary values, since the caller is not prepared for that; only `0`, `2` and negative values are supported.
This commit is contained in:
@@ -165,14 +165,15 @@ int put_dbf_head(dbhead_t *dbh)
|
||||
|
||||
/*
|
||||
* get a field off the disk from the current file offset
|
||||
* returns 0 on success, 2 on field terminator and -1 on failure
|
||||
*/
|
||||
int get_dbf_field(dbhead_t *dbh, dbfield_t *dbf)
|
||||
{
|
||||
struct dbf_dfield dbfield;
|
||||
int ret;
|
||||
|
||||
if ((ret = read(dbh->db_fd, &dbfield, sizeof(dbfield))) != sizeof(dbfield)) {
|
||||
return ret;
|
||||
if ((ret = read(dbh->db_fd, &dbfield, sizeof(dbfield))) <= 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Check for the '0Dh' field terminator , if found return '2'
|
||||
@@ -181,6 +182,10 @@ int get_dbf_field(dbhead_t *dbh, dbfield_t *dbf)
|
||||
return 2;
|
||||
}
|
||||
|
||||
if (ret != sizeof(dbfield)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* build the field name */
|
||||
copy_crimp(dbf->db_fname, dbfield.dbf_name, DBF_NAMELEN);
|
||||
|
||||
|
||||
@@ -53,6 +53,7 @@ are kept until you call dbase_pack().
|
||||
Bug Fixes
|
||||
|
||||
- Fixed GH-1 (dbase_add_record() converts passed floats and leaks memory)
|
||||
- Fixed #81563 (SIGSEGV reading dbase file with few data)
|
||||
]]>
|
||||
</notes>
|
||||
|
||||
@@ -96,6 +97,8 @@ Bug Fixes
|
||||
<file name="bug78668.phpt" role="test" />
|
||||
<file name="bug78668_8.phpt" role="test" />
|
||||
<file name="bug80156.phpt" role="test" />
|
||||
<file name="bug81563.dbf" role="test" />
|
||||
<file name="bug81563.phpt" role="test" />
|
||||
<file name="dbase_add_record_basic.phpt" role="test" />
|
||||
<file name="dbase_add_record_error.phpt" role="test" />
|
||||
<file name="dbase_add_record_error-8.phpt" role="test" />
|
||||
|
||||
BIN
tests/bug81563.dbf
Normal file
BIN
tests/bug81563.dbf
Normal file
Binary file not shown.
29
tests/bug81563.phpt
Normal file
29
tests/bug81563.phpt
Normal file
@@ -0,0 +1,29 @@
|
||||
--TEST--
|
||||
Bug #81563 (SIGSEGV reading dbase file with few data)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded("dbase")) die("skip dbase extension not available");
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
$filename = __DIR__ . "/bug81563.dbf";
|
||||
|
||||
$db = dbase_open($filename, 0);
|
||||
$n = dbase_numrecords($db);
|
||||
for ($index = 1; $index <= $n; $index++) {
|
||||
$record = dbase_get_record_with_names($db, $index);
|
||||
var_dump($record);
|
||||
}
|
||||
dbase_close($db);
|
||||
?>
|
||||
--EXPECT--
|
||||
array(4) {
|
||||
["SCHLAGNR"]=>
|
||||
int(12345)
|
||||
["TEILSCHLAG"]=>
|
||||
string(2) "a "
|
||||
["FLIK"]=>
|
||||
string(16) "DENWLI0546132777"
|
||||
["deleted"]=>
|
||||
int(0)
|
||||
}
|
||||
Reference in New Issue
Block a user