/home/lnzliplg/public_html/alt-php80-pecl-dbase_7.1.1-1.el8.tar
tests/dbase_replace_record_error_1_64bit_8.phpt000064400000002656151731701500015613 0ustar00--TEST--
dbase_replace_record(): error conditions
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
if (PHP_INT_SIZE != 8) die('skip for 64bit platforms only');
if (version_compare(PHP_VERSION, '8', '<')) die('skip for PHP 8 only');
?>
--FILE--
<?php
$filename = __DIR__ . DIRECTORY_SEPARATOR . 'dbase_replace_record_error_1.dbf';
copy(__DIR__ . DIRECTORY_SEPARATOR . 'example.dbf', $filename);

$db = dbase_open($filename, DBASE_RDWR);

try {
    dbase_replace_record($db, 'no array', 1);
} catch (TypeError $ex) {
    echo $ex->getMessage(), PHP_EOL;
}

try {
	var_dump(dbase_replace_record($db, [], -1));
} catch (ValueError $ex) {
    echo $ex->getMessage(), PHP_EOL;
}
try {
	var_dump(dbase_replace_record($db, [], 2147483648));
} catch (ValueError $ex) {
    echo $ex->getMessage(), PHP_EOL;
}

var_dump(dbase_replace_record($db, [], 1));
?>
===DONE===
--EXPECTF--
dbase_replace_record(): Argument #2 ($data) must be of type array, string given
dbase_replace_record(): Argument #3 ($number) record number has to be in range 1..2147483647, but is -1
dbase_replace_record(): Argument #3 ($number) record number has to be in range 1..2147483647, but is 2147483648

Warning: dbase_replace_record(): expected 7 fields, but got 0 in %s on line %d
bool(false)
===DONE===
--CLEAN--
<?php
unlink(__DIR__ . DIRECTORY_SEPARATOR . 'dbase_replace_record_error_1.dbf');
?>
tests/dbase_replace_record_error_1_32bit_8.phpt000064400000002622151731701500015577 0ustar00--TEST--
dbase_replace_record(): error conditions
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
if (PHP_INT_SIZE != 4) die('skip for 32bit platforms only');
if (version_compare(PHP_VERSION, '8', '<')) die('skip for PHP 8 only');
?>
--FILE--
<?php
$filename = __DIR__ . DIRECTORY_SEPARATOR . 'dbase_replace_record_error_1.dbf';
copy(__DIR__ . DIRECTORY_SEPARATOR . 'example.dbf', $filename);

$db = dbase_open($filename, DBASE_RDWR);

try {
    dbase_replace_record($db, 'no array', 1);
} catch (TypeError $ex) {
    echo $ex->getMessage(), PHP_EOL;
}

try {
    var_dump(dbase_replace_record($db, [], -1));
} catch (ValueError $ex) {
    echo $ex->getMessage(), PHP_EOL;
}
try {
    var_dump(dbase_replace_record($db, [], 2147483648));
} catch (TypeError $ex) {
    echo $ex->getMessage(), PHP_EOL;
}

var_dump(dbase_replace_record($db, [], 1));
?>
===DONE===
--EXPECTF--
dbase_replace_record(): Argument #2 ($data) must be of type array, string given
dbase_replace_record(): Argument #3 ($number) record number has to be in range 1..2147483647, but is -1
dbase_replace_record(): Argument #3 ($number) must be of type int, float given

Warning: dbase_replace_record(): expected 7 fields, but got 0 in %s on line %d
bool(false)
===DONE===
--CLEAN--
<?php
unlink(__DIR__ . DIRECTORY_SEPARATOR . 'dbase_replace_record_error_1.dbf');
?>
tests/dbase_delete_record_error_32bit.phpt000064400000002512151731701500014755 0ustar00--TEST--
dbase_delete_record(): error conditions
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
if (PHP_INT_SIZE != 4) die('skip for 32bit platforms only');
if (version_compare(PHP_VERSION, '8', '>')) die('skip for PHP 7 only');
?>
--INI--
allow_url_fopen=1
--FILE--
<?php
$filename = __DIR__ . DIRECTORY_SEPARATOR . 'dbase_delete_record_error.dbf';
$db = dbase_create($filename, [['foo', 'C', 15]]);
var_dump(dbase_delete_record($db));
var_dump(dbase_delete_record(fopen('data://text/plain,foo', 'r'), 1));
var_dump(dbase_delete_record($db, -1));
var_dump(dbase_delete_record($db, 1));
var_dump(dbase_delete_record($db, 2147483648));
?>
===DONE===
--EXPECTF--
Warning: dbase_delete_record() expects exactly 2 parameters, 1 given in %s on line %d
NULL

Warning: dbase_delete_record(): supplied resource is not a valid dbase resource in %s on line %d
bool(false)

Warning: dbase_delete_record(): record number has to be in range 1..2147483647, but is -1 in %s on line %d
bool(false)

Warning: dbase_delete_record(): record 1 out of bounds in %s on line %d
bool(false)

Warning: dbase_delete_record() expects parameter 2 to be in%s, float given in %s on line %d
NULL
===DONE===
--CLEAN--
<?php
unlink(__DIR__ . DIRECTORY_SEPARATOR . 'dbase_delete_record_error.dbf');
?>
tests/dbase_get_header_info_basic.phpt000064400000004271151731701510014211 0ustar00--TEST--
dbase_get_header_info(): basic functionality
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
?>
--FILE--
<?php
$filename = __DIR__ . DIRECTORY_SEPARATOR . 'dbase_get_header_info_basic.dbf';
copy(__DIR__ . DIRECTORY_SEPARATOR . 'example.dbf', $filename);

$db = dbase_open($filename, DBASE_RDONLY);
var_dump($db);

var_dump(dbase_get_header_info($db));

var_dump(dbase_close($db));
?>
===DONE===
--EXPECTF--
resource(%d) of type (dbase)
array(7) {
  [0]=>
  array(6) {
    ["name"]=>
    string(2) "ID"
    ["type"]=>
    string(6) "number"
    ["length"]=>
    int(5)
    ["precision"]=>
    int(0)
    ["format"]=>
    string(3) "%5s"
    ["offset"]=>
    int(1)
  }
  [1]=>
  array(6) {
    ["name"]=>
    string(4) "NAME"
    ["type"]=>
    string(9) "character"
    ["length"]=>
    int(25)
    ["precision"]=>
    int(0)
    ["format"]=>
    string(5) "%-25s"
    ["offset"]=>
    int(6)
  }
  [2]=>
  array(6) {
    ["name"]=>
    string(8) "RELEASED"
    ["type"]=>
    string(4) "date"
    ["length"]=>
    int(8)
    ["precision"]=>
    int(0)
    ["format"]=>
    string(3) "%8s"
    ["offset"]=>
    int(31)
  }
  [3]=>
  array(6) {
    ["name"]=>
    string(10) "RELEASED_X"
    ["type"]=>
    string(8) "datetime"
    ["length"]=>
    int(8)
    ["precision"]=>
    int(0)
    ["format"]=>
    string(0) ""
    ["offset"]=>
    int(39)
  }
  [4]=>
  array(6) {
    ["name"]=>
    string(8) "SUPORTED"
    ["type"]=>
    string(7) "boolean"
    ["length"]=>
    int(1)
    ["precision"]=>
    int(0)
    ["format"]=>
    string(3) "%1s"
    ["offset"]=>
    int(47)
  }
  [5]=>
  array(6) {
    ["name"]=>
    string(5) "PRICE"
    ["type"]=>
    string(6) "number"
    ["length"]=>
    int(10)
    ["precision"]=>
    int(2)
    ["format"]=>
    string(4) "%10s"
    ["offset"]=>
    int(48)
  }
  [6]=>
  array(6) {
    ["name"]=>
    string(10) "MARKETSHAR"
    ["type"]=>
    string(5) "float"
    ["length"]=>
    int(6)
    ["precision"]=>
    int(2)
    ["format"]=>
    string(3) "%6s"
    ["offset"]=>
    int(58)
  }
}
bool(true)
===DONE===
--CLEAN--
<?php
$filename = __DIR__ . DIRECTORY_SEPARATOR . 'dbase_get_header_info_basic.dbf';
unlink($filename);
?>
tests/dbase_numfields_error.phpt000064400000001125151731701510013140 0ustar00--TEST--
dbase_numfields(): error conditions
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
if (version_compare(PHP_VERSION, '8', '>')) die('skip for PHP 7 only');
?>
--INI--
allow_url_fopen=1
--FILE--
<?php
var_dump(dbase_numfields());
var_dump(dbase_numfields(fopen('data://text/plain,foo', 'r')));
?>
===DONE===
--EXPECTF--
Warning: dbase_numfields() expects exactly 1 parameter, 0 given in %s on line %d
NULL

Warning: dbase_numfields(): supplied resource is not a valid dbase resource in %s on line %d
bool(false)
===DONE===
tests/dbase_replace_record_variation3.phpt000064400000001630151731701510015052 0ustar00--TEST--
dbase_replace_record(): date of last update is properly updated
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
?>
--INI--
date.timezone=UTC
--FILE--
<?php
$filename = __DIR__ . DIRECTORY_SEPARATOR . 'dbase_replace_record_variation3.dbf';
copy(__DIR__ . DIRECTORY_SEPARATOR . 'example.dbf', $filename);
$db = dbase_open($filename, 2);
dbase_replace_record($db, array(4711, 'foo', '20161028', '20161028123456.789', 'F', 1.23, 99.99), 1);
dbase_close($db);
$date = getdate();
$result = unpack('C4byte', file_get_contents($filename));
var_dump(
    $result['byte2'] + 1900 == $date['year'],
    $result['byte3'] == $date['mon'],
    $result['byte4'] == $date['mday']
);
?>
===DONE===
--EXPECT--
bool(true)
bool(true)
bool(true)
===DONE===
--CLEAN--
<?php
unlink(__DIR__ . DIRECTORY_SEPARATOR . 'dbase_replace_record_variation3.dbf');
?>
tests/dbase_get_record_error_32bit.phpt000064400000002446151731701510014301 0ustar00--TEST--
dbase_get_record(): error conditions
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
if (PHP_INT_SIZE != 4) die('skip for 32bit platforms only');
if (version_compare(PHP_VERSION, '8', '>')) die('skip for PHP 7 only');
?>
--INI--
allow_url_fopen=1
--FILE--
<?php
var_dump(dbase_get_record());
var_dump(dbase_get_record(fopen('data://text/plain,foo', 'r'), 1));

$filename = __DIR__ . DIRECTORY_SEPARATOR . 'dbase_get_record_error.dbf';
$db = dbase_create($filename, [['foo', 'C', 15]]);
var_dump(dbase_get_record($db, -1));
var_dump(dbase_get_record($db, 1));
var_dump(dbase_get_record($db, 2147483648));
?>
===DONE===
--EXPECTF--
Warning: dbase_get_record() expects exactly 2 parameters, 0 given in %s on line %d
NULL

Warning: dbase_get_record(): supplied resource is not a valid dbase resource in %s on line %d
bool(false)

Warning: dbase_get_record(): record number has to be in range 1..2147483647, but is -1 in %s on line %d
bool(false)

Warning: dbase_get_record(): Tried to read bad record 1 in %s on line %d
bool(false)

Warning: dbase_get_record() expects parameter 2 to be in%s, float given in %s on line %d
NULL
===DONE===
--CLEAN--
<?php
unlink(__DIR__ . DIRECTORY_SEPARATOR . 'dbase_get_record_error.dbf');
?>
tests/bug78668_8.phpt000064400000001134151731701520010233 0ustar00--TEST--
Bug #78668 (Out-of-bounds Read in dbase.c)
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
if (version_compare(PHP_VERSION, '8', '<')) die('skip for PHP 8 only');
?>
--FILE--
<?php
$db_path = __DIR__ . "/bug78668.dbf";
$dbh = dbase_open($db_path, 0);
try {
	$column_info = dbase_get_header_info($dbh);
} catch (TypeError $ex) {
    echo $ex->getMessage(), PHP_EOL;
}
?>
===DONE===
--EXPECTF--
Warning: dbase_open(): unable to open database %s on line %d
dbase_get_header_info(): Argument #1 ($database) must be of type resource, bool given
===DONE===
tests/bug73414.dbf000064400000000142151731701520007542 0ustar00t
afooCbarY
tests/dbase_create_variation3.phpt000064400000001411151731701520013342 0ustar00--TEST--
dbase_create() creates a FoxPro DBF
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
?>
--FILE--
<?php
$filename = __DIR__ . DIRECTORY_SEPARATOR . 'dbase_create_variation3.dbf';

$db = dbase_create($filename, [['DATETIME', 'T']], DBASE_TYPE_FOXPRO);
dbase_close($db);

$contents = file_get_contents($filename);
var_dump(
    strlen($contents),
    ord($contents[0]),  // version
    ord($contents[64]), // header record terminator
    ord($contents[65]), // first byte of DBC
    ord($contents[328]) // end of file marker
);
?>
===DONE===
--EXPECT--
int(329)
int(48)
int(13)
int(0)
int(26)
===DONE===
--CLEAN--
<?php
unlink(__DIR__ . DIRECTORY_SEPARATOR . 'dbase_create_variation3.dbf');
?>
tests/dbase_replace_record_error.phpt000064400000002650151731701520014130 0ustar00--TEST--
dbase_replace_record(): test error conditions
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
if (version_compare(PHP_VERSION, '8', '>')) die('skip for PHP 7 only');
?>
--INI--
allow_url_fopen=1
--FILE--
<?php
$filename = __DIR__ . DIRECTORY_SEPARATOR . 'dbase_replace_record_error.dbf';
copy(__DIR__ . DIRECTORY_SEPARATOR . 'example.dbf', $filename);

$db = dbase_open($filename, DBASE_RDWR);

var_dump(dbase_replace_record($db));

var_dump(dbase_replace_record(fopen('data://text/plain,foo', 'r'), [], 1));

try {
    dbase_replace_record($db, 'no array', 1);
} catch (TypeError $ex) {
    echo $ex->getMessage(), PHP_EOL;
}

var_dump(dbase_replace_record($db, [], 1));

var_dump(dbase_replace_record($db, [0, 1, 2, 3, 4, 'foo' => 5, 6], 1));
?>
===DONE===
--EXPECTF--
Warning: dbase_replace_record() expects exactly 3 parameters, 1 given in %s on line %d
NULL

Warning: dbase_replace_record(): supplied resource is not a valid dbase resource in %s on line %d
bool(false)
Argument 2 passed to dbase_replace_record() must be of the type array, string given

Warning: dbase_replace_record(): expected 7 fields, but got 0 in %s on line %d
bool(false)

Warning: dbase_replace_record(): expected plain indexed array in %s on line %d
bool(false)
===DONE===
--CLEAN--
<?php
unlink(__DIR__ . DIRECTORY_SEPARATOR . 'dbase_replace_record_error.dbf');
?>
tests/dbase_close_error_8.phpt000064400000001230151731701530012505 0ustar00--TEST--
dbase_close(): error conditions
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
if (version_compare(PHP_VERSION, '8', '<')) die('skip for PHP 8 only');
?>
--INI--
allow_url_fopen=1
--FILE--
<?php
try {
	var_dump(dbase_close());
} catch (ArgumentCountError $ex) {
    echo $ex->getMessage(), PHP_EOL;
}
try {
	var_dump(dbase_close(fopen('data://text/plain,foo', 'r')));
} catch (TypeError $ex) {
    echo $ex->getMessage(), PHP_EOL;
}
?>
===DONE===
--EXPECTF--
dbase_close() expects exactly 1 argument, 0 given
dbase_close(): supplied resource is not a valid dbase resource
===DONE===
tests/dbase_get_header_info_error.phpt000064400000001214151731701530014255 0ustar00--TEST--
dbase_get_header_info(): error conditions
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
if (version_compare(PHP_VERSION, '8', '>')) die('skip for PHP 7 only');
?>
--INI--
allow_url_fopen=1
--FILE--
<?php
var_dump(dbase_get_header_info('no resource'));
var_dump(dbase_get_header_info(fopen('data://text/plain,foo', 'r')));
?>
===DONE===
--EXPECTF--
Warning: dbase_get_header_info() expects parameter 1 to be resource, string given in %s on line %d
NULL

Warning: dbase_get_header_info(): supplied resource is not a valid dbase resource in %s on line %d
bool(false)
===DONE===
tests/dbase_get_record_with_names_error_32bit.phpt000064400000002665151731701530016524 0ustar00--TEST--
dbase_get_record_with_names(): error conditions
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
if (PHP_INT_SIZE != 4) die('skip for 32bit platforms only');
if (version_compare(PHP_VERSION, '8', '>')) die('skip for PHP 7 only');
?>
--INI--
allow_url_fopen=1
--FILE--
<?php
var_dump(dbase_get_record_with_names());
var_dump(dbase_get_record_with_names(fopen('data://text/plain,foo', 'r'), 1));

$filename = __DIR__ . DIRECTORY_SEPARATOR . 'dbase_get_record_with_names_error.dbf';
$db = dbase_create($filename, [['foo', 'C', 15]]);
var_dump(dbase_get_record_with_names($db, -1));
var_dump(dbase_get_record_with_names($db, 1));
var_dump(dbase_get_record_with_names($db, 2147483648));
?>
===DONE===
--EXPECTF--
Warning: dbase_get_record_with_names() expects exactly 2 parameters, 0 given in %s on line %d
NULL

Warning: dbase_get_record_with_names(): supplied resource is not a valid dbase resource in %s on line %d
bool(false)

Warning: dbase_get_record_with_names(): record number has to be in range 1..2147483647, but is -1 in %s on line %d
bool(false)

Warning: dbase_get_record_with_names(): Tried to read bad record 1 in %s on line %d
bool(false)

Warning: dbase_get_record_with_names() expects parameter 2 to be in%s, float given in %s on line %d
NULL
===DONE===
--CLEAN--
<?php
unlink(__DIR__ . DIRECTORY_SEPARATOR . 'dbase_get_record_with_names_error.dbf');
?>
tests/dbase_add_record_error.phpt000064400000002550151731701530013245 0ustar00--TEST--
dbase_add_record(): test error conditions
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
if (version_compare(PHP_VERSION, '8', '>')) die('skip for PHP 7 only');
?>
--INI--
allow_url_fopen=1
--FILE--
<?php
$filename = __DIR__ . DIRECTORY_SEPARATOR . 'dbase_add_record_error.dbf';
copy(__DIR__ . DIRECTORY_SEPARATOR . 'example.dbf', $filename);

$db = dbase_open($filename, DBASE_RDWR);

var_dump(dbase_add_record($db));

var_dump(dbase_add_record(fopen('data://text/plain,foo', 'r'), []));

try {
    dbase_add_record($db, 'no array');
} catch (TypeError $ex) {
    echo $ex->getMessage(), PHP_EOL;
}

var_dump(dbase_add_record($db, []));

var_dump(dbase_add_record($db, [0, 1, 2, 3, 4, 'foo' => 5, 6]));
?>
===DONE===
--EXPECTF--
Warning: dbase_add_record() expects exactly 2 parameters, 1 given in %s on line %d
NULL

Warning: dbase_add_record(): supplied resource is not a valid dbase resource in %s on line %d
bool(false)
Argument 2 passed to dbase_add_record() must be of the type array, string given

Warning: dbase_add_record(): expected 7 fields, but got 0 in %s on line %d
bool(false)

Warning: dbase_add_record(): expected plain indexed array in %s on line %d
bool(false)
===DONE===
--CLEAN--
<?php
unlink(__DIR__ . DIRECTORY_SEPARATOR . 'dbase_add_record_error.dbf');
?>
tests/example.dbf000064400000000702151731701540010021 0ustar00t@IDNNAMECRELEASEDDRELEASED_XTSUPORTEDLPRICEN
MARKETSHARF
     1dBase III                19840501�Q%T    123.45 34.56     2Clipper                  19850525�S%.�F     56.78 23.45     3Visual FoxPro 7.0        20010627xj%�[&F      0.90 12.34tests/dbase_add_record_variation1.phpt000064400000002514151731701540014172 0ustar00--TEST--
dbase_add_record(): duplicate an existing record from numeric array
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
?>
--FILE--
<?php
$filename = __DIR__ . DIRECTORY_SEPARATOR . 'dbase_add_record_variation1.dbf';
copy(__DIR__ . DIRECTORY_SEPARATOR . 'example.dbf', $filename);

$db = dbase_open($filename, DBASE_RDWR);
var_dump($db);

$record = dbase_get_record($db, 1);
var_dump($record);

unset($record['deleted']);
$record[4] = $record[4] ? 'T' : 'F'; // we have to cater to bool fields ourselves
var_dump(dbase_add_record($db, $record));

var_dump(dbase_get_record($db, 4));

var_dump(dbase_close($db));
?>
===DONE===
--EXPECTF--
resource(%d) of type (dbase)
array(8) {
  [0]=>
  int(1)
  [1]=>
  string(25) "dBase III                "
  [2]=>
  string(8) "19840501"
  [3]=>
  string(18) "19840501000000.000"
  [4]=>
  bool(true)
  [5]=>
  float(123.45)
  [6]=>
  float(34.56)
  ["deleted"]=>
  int(0)
}
bool(true)
array(8) {
  [0]=>
  int(1)
  [1]=>
  string(25) "dBase III                "
  [2]=>
  string(8) "19840501"
  [3]=>
  string(18) "19840501000000.000"
  [4]=>
  bool(true)
  [5]=>
  float(123.45)
  [6]=>
  float(34.56)
  ["deleted"]=>
  int(0)
}
bool(true)
===DONE===
--CLEAN--
<?php
$filename = __DIR__ . DIRECTORY_SEPARATOR . 'dbase_add_record_variation1.dbf';
unlink($filename);
?>
tests/type_numeric_int_32bit.phpt000064400000002732151731701540013173 0ustar00--TEST--
Reading and writing of numeric integer values
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
if (PHP_INT_SIZE != 4) die('skip for 32bit platforms only');
?>
--FILE--
<?php
$db = dbase_create(
    __DIR__ . DIRECTORY_SEPARATOR . 'type_numeric_int_32bit.dbf',
    array(
        array('integer', 'N', 20, 0)
    )
);

$values = array(
    '-9223372036854775809',
    '-9223372036854775808',
    '-2147483649',
    '-2147483648',
    '0',
    '2147483647',
    '2147483648',
    '9223372036854775807',
    '9223372036854775808',
);

foreach ($values as $value) {
    dbase_add_record($db, [$value]);
}

for ($i = 1; $i <= dbase_numrecords($db); $i++) {
    var_dump(
        dbase_get_record($db, $i)[0],
        dbase_get_record_with_names($db, $i)['integer']
    );
}
?>
===DONE===
--EXPECT--
string(20) "-9223372036854775809"
string(20) "-9223372036854775809"
string(20) "-9223372036854775808"
string(20) "-9223372036854775808"
string(20) "         -2147483649"
string(20) "         -2147483649"
int(-2147483648)
int(-2147483648)
int(0)
int(0)
int(2147483647)
int(2147483647)
string(20) "          2147483648"
string(20) "          2147483648"
string(20) " 9223372036854775807"
string(20) " 9223372036854775807"
string(20) " 9223372036854775808"
string(20) " 9223372036854775808"
===DONE===
--CLEAN--
<?php
unlink(__DIR__ . DIRECTORY_SEPARATOR . 'type_numeric_int_32bit.dbf');
?>
tests/bug52112.phpt000064400000002614151731701540007762 0ustar00--TEST--
Bug #52112 (dbase_get_record() returns integer instead of decimal value)
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
$locales = array('de_DE.UTF-8', 'de-DE');
if (array_search(setlocale(LC_NUMERIC, $locales), $locales) === false) {
    die('skip German locale not available');
}
?>
--FILE--
<?php
$filename = __DIR__ . DIRECTORY_SEPARATOR . 'bug52112.dbf';
copy(__DIR__ . DIRECTORY_SEPARATOR . 'example.dbf', $filename);
setlocale(LC_NUMERIC, 'de_DE.UTF-8', 'de-DE');

$db = dbase_open($filename, DBASE_RDONLY);
var_dump($db);

var_dump(dbase_get_record($db, 1));
var_dump(dbase_get_record_with_names($db, 1));

var_dump(dbase_close($db));
?>
===DONE===
--EXPECTF--
resource(%d) of type (dbase)
array(8) {
  [0]=>
  int(1)
  [1]=>
  string(25) "dBase III                "
  [2]=>
  string(8) "19840501"
  [3]=>
  string(18) "19840501000000.000"
  [4]=>
  bool(true)
  [5]=>
  float(123%s45)
  [6]=>
  float(34%s56)
  ["deleted"]=>
  int(0)
}
array(8) {
  ["ID"]=>
  int(1)
  ["NAME"]=>
  string(25) "dBase III                "
  ["RELEASED"]=>
  string(8) "19840501"
  ["RELEASED_X"]=>
  string(18) "19840501000000.000"
  ["SUPORTED"]=>
  bool(true)
  ["PRICE"]=>
  float(123%s45)
  ["MARKETSHAR"]=>
  float(34%s56)
  ["deleted"]=>
  int(0)
}
bool(true)
===DONE===
--CLEAN--
<?php
$filename = __DIR__ . DIRECTORY_SEPARATOR . 'bug52112.dbf';
unlink($filename);
?>
tests/dbase_numfields_basic.phpt000064400000001141151731701550013072 0ustar00--TEST--
dbase_numfields(): basic functionality
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
?>
--FILE--
<?php
$filename = __DIR__ . DIRECTORY_SEPARATOR . 'dbase_numfields_basic.dbf';
copy(__DIR__ . DIRECTORY_SEPARATOR . 'example.dbf', $filename);

$db = dbase_open($filename, DBASE_RDWR);
var_dump($db);

var_dump(dbase_numfields($db));

var_dump(dbase_close($db));
?>
===DONE===
--EXPECTF--
resource(%d) of type (dbase)
int(7)
bool(true)
===DONE===
--CLEAN--
<?php
$filename = __DIR__ . DIRECTORY_SEPARATOR . 'dbase_numfields_basic.dbf';
unlink($filename);
?>
tests/dbase_replace_record_basic.phpt000064400000002016151731701550014057 0ustar00--TEST--
dbase_replace_record(): basic functionality
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
?>
--FILE--
<?php
$filename = __DIR__ . DIRECTORY_SEPARATOR . 'dbase_replace_record_basic.dbf';
copy(__DIR__ . DIRECTORY_SEPARATOR . 'example.dbf', $filename);

$db = dbase_open($filename, DBASE_RDWR);
var_dump($db);

var_dump(dbase_replace_record($db, array(4, 'JPLDIS', '19730101', '19730101123456.789', 'F', 1234567.89, 0.12), 2));

var_dump(dbase_numrecords($db));
var_dump(dbase_get_record($db, 2));

var_dump(dbase_close($db));
?>
===DONE===
--EXPECTF--
resource(%d) of type (dbase)
bool(true)
int(3)
array(8) {
  [0]=>
  int(4)
  [1]=>
  string(25) "JPLDIS                   "
  [2]=>
  string(8) "19730101"
  [3]=>
  string(18) "19730101123456.789"
  [4]=>
  bool(false)
  [5]=>
  float(1234567.89)
  [6]=>
  float(0.12)
  ["deleted"]=>
  int(0)
}
bool(true)
===DONE===
--CLEAN--
<?php
$filename = __DIR__ . DIRECTORY_SEPARATOR . 'dbase_replace_record_basic.dbf';unlink($filename);
?>
tests/dbase_open_error.phpt000064400000000575151731701550012127 0ustar00--TEST--
dbase_open(): error conditions
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
if (version_compare(PHP_VERSION, '8', '>')) die('skip for PHP 7 only');
?>
--FILE--
<?php
var_dump(dbase_open());
?>
===DONE===
--EXPECTF--
Warning: dbase_open() expects exactly 2 parameters, 0 given in %s on line %d
NULL
===DONE===
tests/dbase_create_error_open_basedir.phpt000064400000000625151731701550015137 0ustar00--TEST--
dbase_create(): open_basedir restriction
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
?>
--INI--
open_basedir=.
--FILE--
<?php
var_dump(dbase_create('../bad', array()));
?>
===DONE===
--EXPECTF--
Warning: dbase_create(): open_basedir restriction in effect. File(../bad) is not within the allowed path(s): (.) in %s on line %d
bool(false)
===DONE===
tests/bug73411.phpt000064400000001301151731701560007761 0ustar00--TEST--
Bug #73411 (dbase_pack() returns TRUE on failure)
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
?>
--FILE--
<?php
$filename = __DIR__ . DIRECTORY_SEPARATOR . 'bug73411.dbf';

$db = dbase_create($filename, [['NAME', 'C', 50]]);
dbase_add_record($db, ['foo']);
dbase_add_record($db, ['bar']);
dbase_delete_record($db, 1);
dbase_close($db);

$db = dbase_open($filename, 0); // read-only
var_dump(dbase_pack($db));
dbase_close($db);
?>
===DONE===
--EXPECTF--
Warning: dbase_pack(): unable to write to the file in %s on line %d
bool(false)
===DONE===
--CLEAN--
<?php
unlink(__DIR__ . DIRECTORY_SEPARATOR . 'bug73411.dbf');
?>
tests/bug39305.phpt000064400000002040151731701560007766 0ustar00--TEST--
Bug #39305 (Use of decimal point in different countries)
--SKIPIF--
<?php
$locales = array('de_DE.UTF-8', 'de-DE');

if (!extension_loaded('dbase')) die('skip dbase extension not available');
if (array_search(setlocale(LC_NUMERIC, $locales), $locales) === false) {
    die('skip German locale not available');
}
?>
--FILE--
<?php
$locales = array('de_DE.UTF-8', 'de-DE');
define('FILENAME', __DIR__ . DIRECTORY_SEPARATOR . 'bug39305.dbf');

$db = dbase_create(FILENAME, array(array('num', 'n', 24, 2)));

setlocale(LC_NUMERIC, $locales);
dbase_add_record($db, array(1e20));
$record = dbase_get_record_with_names($db, 1);

setlocale(LC_NUMERIC, 'C');
var_dump($record['num']);

setlocale(LC_NUMERIC, $locales);
dbase_replace_record($db, array(1e20), 1);
$record = dbase_get_record_with_names($db, 1);

setlocale(LC_NUMERIC, 'C');
var_dump($record['num']);

dbase_close($db);
?>
===DONE===
--EXPECTF--
float(1.0E+20)
float(1.0E+20)
===DONE===
--CLEAN--
<?php
define('FILENAME', __DIR__ . DIRECTORY_SEPARATOR . 'bug39305.dbf');

unlink(FILENAME);
?>
tests/dbase_open_error_open_basedir.phpt000064400000000645151731701560014640 0ustar00--TEST--
dbase_open(): open_basedir restriction
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
?>
--INI--
open_basedir=.
--FILE--
<?php
var_dump(dbase_open('../bad', DBASE_RDONLY));
?>
===DONE===
--EXPECTF--
Warning: dbase_open(): open_basedir restriction in effect. File(../bad) is not within the allowed path(s): (.) in %s on line %d
bool(false)
===DONE===
tests/dbase_open_error3.phpt000064400000000754151731701570012213 0ustar00--TEST--
dbase_open() fails if '0' field is not named _NullFlags
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
?>
--FILE--
<?php
$filename = __DIR__ . DIRECTORY_SEPARATOR . 'dbase_open_error3.dbf';
var_dump(dbase_open($filename, DBASE_RDONLY));
?>
===DONE===
--EXPECTF--
Warning: dbase_open(): unexpected field type '0' in %s on line %d

Warning: dbase_open(): unable to open database %s in %s on line %d
bool(false)
===DONE===
tests/dbase_replace_record_variation1.phpt000064400000002554151731701570015064 0ustar00--TEST--
dbase_replace_record(): update existing record from numeric array
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
?>
--FILE--
<?php
$filename = __DIR__ . DIRECTORY_SEPARATOR . 'dbase_replace_record_variation1.dbf';
copy(__DIR__ . DIRECTORY_SEPARATOR . 'example.dbf', $filename);

$db = dbase_open($filename, DBASE_RDWR);
var_dump($db);

$record = dbase_get_record($db, 1);
var_dump($record);

unset($record['deleted']);
$record[4] = $record[4] ? 'T' : 'F'; // we have to cater to bool fields ourselves
$record[5] = 12.34;
var_dump(dbase_replace_record($db, $record, 1));

var_dump(dbase_get_record($db, 1));

var_dump(dbase_close($db));
?>
===DONE===
--EXPECTF--
resource(%d) of type (dbase)
array(8) {
  [0]=>
  int(1)
  [1]=>
  string(25) "dBase III                "
  [2]=>
  string(8) "19840501"
  [3]=>
  string(18) "19840501000000.000"
  [4]=>
  bool(true)
  [5]=>
  float(123.45)
  [6]=>
  float(34.56)
  ["deleted"]=>
  int(0)
}
bool(true)
array(8) {
  [0]=>
  int(1)
  [1]=>
  string(25) "dBase III                "
  [2]=>
  string(8) "19840501"
  [3]=>
  string(18) "19840501000000.000"
  [4]=>
  bool(true)
  [5]=>
  float(12.34)
  [6]=>
  float(34.56)
  ["deleted"]=>
  int(0)
}
bool(true)
===DONE===
--CLEAN--
<?php
$filename = __DIR__ . DIRECTORY_SEPARATOR . 'dbase_replace_record_variation1.dbf';
unlink($filename);
?>
tests/dbase_get_header_info_error_8.phpt000064400000001352151731701570014513 0ustar00--TEST--
dbase_get_header_info(): error conditions
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
if (version_compare(PHP_VERSION, '8', '<')) die('skip for PHP 8 only');
?>
--INI--
allow_url_fopen=1
--FILE--
<?php
try {
	var_dump(dbase_get_header_info('no resource'));
} catch (TypeError $ex) {
    echo $ex->getMessage(), PHP_EOL;
}
try {
	var_dump(dbase_get_header_info(fopen('data://text/plain,foo', 'r')));
} catch (TypeError $ex) {
    echo $ex->getMessage(), PHP_EOL;
}
?>
===DONE===
--EXPECTF--
dbase_get_header_info(): Argument #1 ($database) must be of type resource, string given
dbase_get_header_info(): supplied resource is not a valid dbase resource
===DONE===
tests/type_numeric_int_64bit.phpt000064400000002562151731701570013204 0ustar00--TEST--
Reading and writing of numeric integer values
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
if (PHP_INT_SIZE != 8) die('skip for 64bit platforms only');
?>
--FILE--
<?php
$db = dbase_create(
    __DIR__ . DIRECTORY_SEPARATOR . 'type_numeric_int_64bit.dbf',
    array(
        array('integer', 'N', 20, 0)
    )
);

$values = array(
    '-9223372036854775809',
    '-9223372036854775808',
    '-2147483649',
    '-2147483648',
    '0',
    '2147483647',
    '2147483648',
    '9223372036854775807',
    '9223372036854775808',
);

foreach ($values as $value) {
    dbase_add_record($db, [$value]);
}

for ($i = 1; $i <= dbase_numrecords($db); $i++) {
    var_dump(
        dbase_get_record($db, $i)[0],
        dbase_get_record_with_names($db, $i)['integer']
    );
}
?>
===DONE===
--EXPECT--
string(20) "-9223372036854775809"
string(20) "-9223372036854775809"
int(-9223372036854775808)
int(-9223372036854775808)
int(-2147483649)
int(-2147483649)
int(-2147483648)
int(-2147483648)
int(0)
int(0)
int(2147483647)
int(2147483647)
int(2147483648)
int(2147483648)
int(9223372036854775807)
int(9223372036854775807)
string(20) " 9223372036854775808"
string(20) " 9223372036854775808"
===DONE===
--CLEAN--
<?php
unlink(__DIR__ . DIRECTORY_SEPARATOR . 'type_numeric_int_64bit.dbf');
?>
tests/dbase_get_record_with_names_error_32bit_8.phpt000064400000003200151731701600016733 0ustar00--TEST--
dbase_get_record_with_names(): error conditions
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
if (PHP_INT_SIZE != 4) die('skip for 32bit platforms only');
if (version_compare(PHP_VERSION, '8', '<')) die('skip for PHP 8 only');
?>
--INI--
allow_url_fopen=1
--FILE--
<?php
try {
    var_dump(dbase_get_record_with_names());
} catch (TypeError $ex) {
    echo $ex->getMessage(), PHP_EOL;
} 
try {
    var_dump(dbase_get_record_with_names(fopen('data://text/plain,foo', 'r'), 1));
} catch (TypeError $ex) {
    echo $ex->getMessage(), PHP_EOL;
}

$filename = __DIR__ . DIRECTORY_SEPARATOR . 'dbase_get_record_with_names_error.dbf';
$db = dbase_create($filename, [['foo', 'C', 15]]);
try {
    var_dump(dbase_get_record_with_names($db, -1));
} catch (ValueError $ex) {
    echo $ex->getMessage(), PHP_EOL;
}
var_dump(dbase_get_record_with_names($db, 1));
try {
    var_dump(dbase_get_record_with_names($db, 2147483648));
} catch (TypeError $ex) {
    echo $ex->getMessage(), PHP_EOL;
}
?>
===DONE===
--EXPECTF--
dbase_get_record_with_names() expects exactly 2 arguments, 0 given
dbase_get_record_with_names(): supplied resource is not a valid dbase resource
dbase_get_record_with_names(): Argument #2 ($number) record number has to be in range 1..2147483647, but is -1

Warning: dbase_get_record_with_names(): Tried to read bad record 1 in %s on line %d
bool(false)
dbase_get_record_with_names(): Argument #2 ($number) must be of type int, float given
===DONE===
--CLEAN--
<?php
unlink(__DIR__ . DIRECTORY_SEPARATOR . 'dbase_get_record_with_names_error.dbf');
?>
tests/dbase_get_record_with_names_variation1.phpt000064400000001435151731701600016435 0ustar00--TEST--
dbase_get_record_with_names(): 'deleted' always contains deletion marker
--DESCRIPTION--
Even if the database has a field named 'deleted', dbase_get_record_with_names()
will not return its value, but rather the deletion marker.
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
?>
--FILE--
<?php
$db = dbase_create(
    __DIR__ . DIRECTORY_SEPARATOR . 'dbase_get_record_with_names_variation1.dbf',
    array(
        array('deleted', 'C', 15)
    )
);
dbase_add_record($db, array('foo'));
var_dump(dbase_get_record_with_names($db, 1));
?>
===DONE===
--EXPECT--
array(1) {
  ["deleted"]=>
  int(0)
}
===DONE===
--CLEAN--
<?php
unlink(__DIR__ . DIRECTORY_SEPARATOR . 'dbase_get_record_with_names_variation1.dbf');
?>
tests/dbase_add_record_variation2.phpt000064400000003052151731701600014166 0ustar00--TEST--
dbase_add_record(): duplicate an existing record from associative array
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
?>
--FILE--
<?php
$filename = __DIR__ . DIRECTORY_SEPARATOR . 'dbase_add_record_variation2.dbf';
copy(__DIR__ . DIRECTORY_SEPARATOR . 'example.dbf', $filename);

$db = dbase_open($filename, DBASE_RDWR);
var_dump($db);

$record = dbase_get_record_with_names($db, 1);
var_dump($record);

unset($record['deleted']);
$record['SUPORTED'] = $record['SUPORTED'] ? 'T' : 'F'; // we have to cater to bool fields ourselves
$record = array_values($record); // we can't add an associative array
var_dump(dbase_add_record($db, $record));

var_dump(dbase_get_record_with_names($db, 4));

var_dump(dbase_close($db));
?>
===DONE===
--EXPECTF--
resource(%d) of type (dbase)
array(8) {
  ["ID"]=>
  int(1)
  ["NAME"]=>
  string(25) "dBase III                "
  ["RELEASED"]=>
  string(8) "19840501"
  ["RELEASED_X"]=>
  string(18) "19840501000000.000"
  ["SUPORTED"]=>
  bool(true)
  ["PRICE"]=>
  float(123.45)
  ["MARKETSHAR"]=>
  float(34.56)
  ["deleted"]=>
  int(0)
}
bool(true)
array(8) {
  ["ID"]=>
  int(1)
  ["NAME"]=>
  string(25) "dBase III                "
  ["RELEASED"]=>
  string(8) "19840501"
  ["RELEASED_X"]=>
  string(18) "19840501000000.000"
  ["SUPORTED"]=>
  bool(true)
  ["PRICE"]=>
  float(123.45)
  ["MARKETSHAR"]=>
  float(34.56)
  ["deleted"]=>
  int(0)
}
bool(true)
===DONE===
--CLEAN--
<?php
$filename = __DIR__ . DIRECTORY_SEPARATOR . 'dbase_add_record_variation2.dbf';
unlink($filename);
?>
tests/dbase_delete_record_error_64bit_8.phpt000064400000003063151731701600015214 0ustar00--TEST--
dbase_delete_record(): error conditions
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
if (PHP_INT_SIZE != 8) die('skip for 64bit platforms only');
if (version_compare(PHP_VERSION, '8', '<')) die('skip for PHP 8 only');
?>
--INI--
allow_url_fopen=1
--FILE--
<?php
$filename = __DIR__ . DIRECTORY_SEPARATOR . 'dbase_delete_record_error.dbf';
$db = dbase_create($filename, [['foo', 'C', 15]]);
try {
	var_dump(dbase_delete_record($db));
} catch (ArgumentCountError $ex) {
    echo $ex->getMessage(), PHP_EOL;
}
try {
	var_dump(dbase_delete_record(fopen('data://text/plain,foo', 'r'), 1));
} catch (TypeError $ex) {
    echo $ex->getMessage(), PHP_EOL;
}
try {
	var_dump(dbase_delete_record($db, -1));
} catch (ValueError $ex) {
    echo $ex->getMessage(), PHP_EOL;
}
var_dump(dbase_delete_record($db, 1));
try {
	var_dump(dbase_delete_record($db, 2147483648));
} catch (ValueError $ex) {
    echo $ex->getMessage(), PHP_EOL;
}
?>
===DONE===
--EXPECTF--
dbase_delete_record() expects exactly 2 arguments, 1 given
dbase_delete_record(): supplied resource is not a valid dbase resource
dbase_delete_record(): Argument #2 ($number) record number has to be in range 1..2147483647, but is -1

Warning: dbase_delete_record(): record 1 out of bounds in %s on line %d
bool(false)
dbase_delete_record(): Argument #2 ($number) record number has to be in range 1..2147483647, but is 2147483648
===DONE===
--CLEAN--
<?php
unlink(__DIR__ . DIRECTORY_SEPARATOR . 'dbase_delete_record_error.dbf');
?>
tests/bug78668.phpt000064400000001042151731701610010002 0ustar00--TEST--
Bug #78668 (Out-of-bounds Read in dbase.c)
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
if (version_compare(PHP_VERSION, '8', '>')) die('skip for PHP 7 only');
?>
--FILE--
<?php
$db_path = __DIR__ . "/bug78668.dbf";
$dbh = dbase_open($db_path, 0);
$column_info = dbase_get_header_info($dbh);
?>
===DONE===
--EXPECTF--
Warning: dbase_open(): unable to open database %s on line %d

Warning: dbase_get_header_info() expects parameter 1 to be resource, bool%S given in %s on line %d
===DONE===
tests/dbase_get_record_basic.phpt000064400000001524151731701610013223 0ustar00--TEST--
dbase_get_record(): basic functionality
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
?>
--FILE--
<?php
$filename = __DIR__ . DIRECTORY_SEPARATOR . 'dbase_get_record_basic.dbf';
copy(__DIR__ . DIRECTORY_SEPARATOR . 'example.dbf', $filename);

$db = dbase_open($filename, DBASE_RDWR);
var_dump($db);

var_dump(dbase_get_record($db, 3));

var_dump(dbase_close($db));
?>
===DONE===
--EXPECTF--
resource(%d) of type (dbase)
array(8) {
  [0]=>
  int(3)
  [1]=>
  string(25) "Visual FoxPro 7.0        "
  [2]=>
  string(8) "20010627"
  [3]=>
  string(18) "20010627235959.999"
  [4]=>
  bool(false)
  [5]=>
  float(0.9)
  [6]=>
  float(12.34)
  ["deleted"]=>
  int(0)
}
bool(true)
===DONE===
--CLEAN--
<?php
$filename = __DIR__ . DIRECTORY_SEPARATOR . 'dbase_get_record_basic.dbf';
unlink($filename);
?>
tests/dbase_pack_basic.phpt000064400000001703151731701610012023 0ustar00--TEST--
dbase_pack(): basic functionality
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
?>
--FILE--
<?php
$filename = __DIR__ . DIRECTORY_SEPARATOR . 'dbase_pack_basic.dbf';
copy(__DIR__ . DIRECTORY_SEPARATOR . 'example.dbf', $filename);

$db = dbase_open($filename, DBASE_RDWR);
var_dump($db);

var_dump(dbase_delete_record($db, 2));
var_dump(dbase_pack($db));

var_dump(dbase_numrecords($db));
var_dump(dbase_get_record($db, 2));

var_dump(dbase_close($db));
?>
===DONE===
--EXPECTF--
resource(%d) of type (dbase)
bool(true)
bool(true)
int(2)
array(8) {
  [0]=>
  int(3)
  [1]=>
  string(25) "Visual FoxPro 7.0        "
  [2]=>
  string(8) "20010627"
  [3]=>
  string(18) "20010627235959.999"
  [4]=>
  bool(false)
  [5]=>
  float(0.9)
  [6]=>
  float(12.34)
  ["deleted"]=>
  int(0)
}
bool(true)
===DONE===
--CLEAN--
<?php
$filename = __DIR__ . DIRECTORY_SEPARATOR . 'dbase_pack_basic.dbf';
unlink($filename);
?>
tests/dbase_add_record_variation4.phpt000064400000001126151731701610014171 0ustar00--TEST--
dbase_add_record() writes proper EOF marker
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
?>
--FILE--
<?php
$filename = __DIR__ . DIRECTORY_SEPARATOR . 'dbase_add_record_variation4.dbf';

$db = dbase_create($filename, array(array('foo', 'C', 1)));
dbase_add_record($db, ['x']);
dbase_close($db);

$contents = file_get_contents($filename);
printf("%02X\n", ord(substr($contents, -1)));
?>
===DONE===
--EXPECT--
1A
===DONE===
--CLEAN--
<?php
unlink(__DIR__ . DIRECTORY_SEPARATOR . 'dbase_add_record_variation4.dbf');
?>
tests/dbase_add_record_basic.phpt000064400000001774151731701620013204 0ustar00--TEST--
dbase_add_record(): basic functionality
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
?>
--FILE--
<?php
$filename = __DIR__ . DIRECTORY_SEPARATOR . 'dbase_add_record_basic.dbf';
copy(__DIR__ . DIRECTORY_SEPARATOR . 'example.dbf', $filename);

$db = dbase_open($filename, DBASE_RDWR);
var_dump($db);

var_dump(dbase_add_record($db, array(4, 'JPLDIS', '19730101', '19730101104923.123', 'F', 1234567.89, 1.23)));

var_dump(dbase_numrecords($db));
var_dump(dbase_get_record($db, 4));

var_dump(dbase_close($db));
?>
===DONE===
--EXPECTF--
resource(%d) of type (dbase)
bool(true)
int(4)
array(8) {
  [0]=>
  int(4)
  [1]=>
  string(25) "JPLDIS                   "
  [2]=>
  string(8) "19730101"
  [3]=>
  string(18) "19730101104923.123"
  [4]=>
  bool(false)
  [5]=>
  float(1234567.89)
  [6]=>
  float(1.23)
  ["deleted"]=>
  int(0)
}
bool(true)
===DONE===
--CLEAN--
<?php
$filename = __DIR__ . DIRECTORY_SEPARATOR . 'dbase_add_record_basic.dbf';
unlink($filename);
?>
tests/dbase_open_error1.dbf000064400000000142151731701620011754 0ustar00t
afooXbarY
tests/dbase_replace_record_variation2.phpt000064400000003131151731701620015051 0ustar00--TEST--
dbase_replace_record(): update existing record from associative array
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
?>
--FILE--
<?php
$filename = __DIR__ . DIRECTORY_SEPARATOR . 'dbase_replace_record_variation2.dbf';
copy(__DIR__ . DIRECTORY_SEPARATOR . 'example.dbf', $filename);

$db = dbase_open($filename, DBASE_RDWR);
var_dump($db);

$record = dbase_get_record_with_names($db, 1);
var_dump($record);

unset($record['deleted']);
$record['SUPORTED'] = $record['SUPORTED'] ? 'T' : 'F'; // we have to cater to bool fields ourselves
$record['PRICE'] = 12.34;
$record = array_values($record); // we can't replace with an associative array
var_dump(dbase_replace_record($db, $record, 1));

var_dump(dbase_get_record_with_names($db, 1));

var_dump(dbase_close($db));
?>
===DONE===
--EXPECTF--
resource(%d) of type (dbase)
array(8) {
  ["ID"]=>
  int(1)
  ["NAME"]=>
  string(25) "dBase III                "
  ["RELEASED"]=>
  string(8) "19840501"
  ["RELEASED_X"]=>
  string(18) "19840501000000.000"
  ["SUPORTED"]=>
  bool(true)
  ["PRICE"]=>
  float(123.45)
  ["MARKETSHAR"]=>
  float(34.56)
  ["deleted"]=>
  int(0)
}
bool(true)
array(8) {
  ["ID"]=>
  int(1)
  ["NAME"]=>
  string(25) "dBase III                "
  ["RELEASED"]=>
  string(8) "19840501"
  ["RELEASED_X"]=>
  string(18) "19840501000000.000"
  ["SUPORTED"]=>
  bool(true)
  ["PRICE"]=>
  float(12.34)
  ["MARKETSHAR"]=>
  float(34.56)
  ["deleted"]=>
  int(0)
}
bool(true)
===DONE===
--CLEAN--
<?php
$filename = __DIR__ . DIRECTORY_SEPARATOR . 'dbase_replace_record_variation2.dbf';
unlink($filename);
?>
tests/dbase_replace_record_error_8.phpt000064400000002773151731701630014367 0ustar00--TEST--
dbase_replace_record(): test error conditions
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
if (version_compare(PHP_VERSION, '8', '<')) die('skip for PHP 8 only');
?>
--INI--
allow_url_fopen=1
--FILE--
<?php
$filename = __DIR__ . DIRECTORY_SEPARATOR . 'dbase_replace_record_error.dbf';
copy(__DIR__ . DIRECTORY_SEPARATOR . 'example.dbf', $filename);

$db = dbase_open($filename, DBASE_RDWR);

try {
	var_dump(dbase_replace_record($db));
} catch (ArgumentCountError $ex) {
    echo $ex->getMessage(), PHP_EOL;
}

try {
	var_dump(dbase_replace_record(fopen('data://text/plain,foo', 'r'), [], 1));
} catch (TypeError $ex) {
    echo $ex->getMessage(), PHP_EOL;
}

try {
    dbase_replace_record($db, 'no array', 1);
} catch (TypeError $ex) {
    echo $ex->getMessage(), PHP_EOL;
}

var_dump(dbase_replace_record($db, [], 1));

var_dump(dbase_replace_record($db, [0, 1, 2, 3, 4, 'foo' => 5, 6], 1));
?>
===DONE===
--EXPECTF--
dbase_replace_record() expects exactly 3 arguments, 1 given
dbase_replace_record(): supplied resource is not a valid dbase resource
dbase_replace_record(): Argument #2 ($data) must be of type array, string given

Warning: dbase_replace_record(): expected 7 fields, but got 0 in %s on line %d
bool(false)

Warning: dbase_replace_record(): expected plain indexed array in %s on line %d
bool(false)
===DONE===
--CLEAN--
<?php
unlink(__DIR__ . DIRECTORY_SEPARATOR . 'dbase_replace_record_error.dbf');
?>
tests/dbase_open_error2.dbf000064400000000142151731701630011756 0ustar00tafoo0barC
tests/dbase_numfields_error_8.phpt000064400000001254151731701630013375 0ustar00--TEST--
dbase_numfields(): error conditions
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
if (version_compare(PHP_VERSION, '8', '<')) die('skip for PHP 8 only');
?>
--INI--
allow_url_fopen=1
--FILE--
<?php
try {
	var_dump(dbase_numfields());
} catch (ArgumentCountError $ex) {
    echo $ex->getMessage(), PHP_EOL;
}
try {
	var_dump(dbase_numfields(fopen('data://text/plain,foo', 'r')));
} catch (TypeError $ex) {
    echo $ex->getMessage(), PHP_EOL;
}
?>
===DONE===
--EXPECTF--
dbase_numfields() expects exactly 1 argument, 0 given
dbase_numfields(): supplied resource is not a valid dbase resource
===DONE===
tests/dbase_create_variation1.phpt000064400000001364151731701630013351 0ustar00--TEST--
dbase_create(): date of last update is properly updated
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
?>
--INI--
date.timezone=UTC
--FILE--
<?php
$filename = __DIR__ . DIRECTORY_SEPARATOR . 'dbase_create_variation1.dbf';
$db = dbase_create($filename, array(array('foo', 'C', 1)));
dbase_close($db);
$date = getdate();
$result = unpack('C4byte', file_get_contents($filename));
var_dump(
    $result['byte2'] + 1900 == $date['year'],
    $result['byte3'] == $date['mon'],
    $result['byte4'] == $date['mday']
);
?>
===DONE===
--EXPECT--
bool(true)
bool(true)
bool(true)
===DONE===
--CLEAN--
<?php
unlink(__DIR__ . DIRECTORY_SEPARATOR . 'dbase_create_variation1.dbf');
?>
tests/dbase_pack_error_8.phpt000064400000001223151731701640012322 0ustar00--TEST--
dbase_pack(): error conditions
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
if (version_compare(PHP_VERSION, '8', '<')) die('skip for PHP 8 only');
?>
--INI--
allow_url_fopen=1
--FILE--
<?php
try {
	var_dump(dbase_pack());
} catch (ArgumentCountError $ex) {
    echo $ex->getMessage(), PHP_EOL;
}
try {
	var_dump(dbase_pack(fopen('data://text/plain,foo', 'r')));
} catch (TypeError $ex) {
    echo $ex->getMessage(), PHP_EOL;
}
?>
===DONE===
--EXPECTF--
dbase_pack() expects exactly 1 argument, 0 given
dbase_pack(): supplied resource is not a valid dbase resource
===DONE===
tests/bug80156.phpt000064400000001200151731701640007762 0ustar00--TEST--
Bug #80156 (Incomplete records may be written)
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
if (version_compare(PHP_VERSION, '7.4', '<')) die('skip for PHP 7.4+ only');
?>
--FILE--
<?php
class Foo {
    public function __toString() {
        throw new Exception("not allowed");
    }
}

$def = [["name1", "c", 10], ["name2", "c", 10]];
$dbase = dbase_create(__DIR__ . "/bug80156.dbf", $def);
try {
    dbase_add_record($dbase, ["cmb", new Foo]);
} catch (Exception $ex) {}
var_dump(dbase_numrecords($dbase));
?>
--CLEAN--
<?php
unlink(__DIR__ . "/bug80156.dbf");
?>
--EXPECT--
int(0)
tests/dbase_numrecords_error_8.phpt000064400000001261151731701640013567 0ustar00--TEST--
dbase_numrecords(): error conditions
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
if (version_compare(PHP_VERSION, '8', '<')) die('skip for PHP 8 only');
?>
--INI--
allow_url_fopen=1
--FILE--
<?php
try {
	var_dump(dbase_numrecords());
} catch (ArgumentCountError $ex) {
    echo $ex->getMessage(), PHP_EOL;
}
try {
	var_dump(dbase_numrecords(fopen('data://text/plain,foo', 'r')));
} catch (TypeError $ex) {
    echo $ex->getMessage(), PHP_EOL;
}
?>
===DONE===
--EXPECTF--
dbase_numrecords() expects exactly 1 argument, 0 given
dbase_numrecords(): supplied resource is not a valid dbase resource
===DONE===
tests/dbase_get_record_error_32bit_8.phpt000064400000002771151731701640014535 0ustar00--TEST--
dbase_get_record(): error conditions
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
if (PHP_INT_SIZE != 4) die('skip for 32bit platforms only');
if (version_compare(PHP_VERSION, '8', '<')) die('skip for PHP 8 only');
?>
--INI--
allow_url_fopen=1
--FILE--
<?php
try {
    var_dump(dbase_get_record());
} catch (ArgumentCountError $ex) {
    echo $ex->getMessage(), PHP_EOL;
}
try {
    var_dump(dbase_get_record(fopen('data://text/plain,foo', 'r'), 1));
} catch (TypeError $ex) {
    echo $ex->getMessage(), PHP_EOL;
}

$filename = __DIR__ . DIRECTORY_SEPARATOR . 'dbase_get_record_error.dbf';
$db = dbase_create($filename, [['foo', 'C', 15]]);
try {
    var_dump(dbase_get_record($db, -1));
} catch (ValueError $ex) {
    echo $ex->getMessage(), PHP_EOL;
}
var_dump(dbase_get_record($db, 1));
try {
    var_dump(dbase_get_record($db, 2147483648));
} catch (TypeError $ex) {
    echo $ex->getMessage(), PHP_EOL;
}
?>
===DONE===
--EXPECTF--
dbase_get_record() expects exactly 2 arguments, 0 given
dbase_get_record(): supplied resource is not a valid dbase resource
dbase_get_record(): Argument #2 ($number) record number has to be in range 1..2147483647, but is -1

Warning: dbase_get_record(): Tried to read bad record 1 in %s on line %d
bool(false)
dbase_get_record(): Argument #2 ($number) must be of type int, float given
===DONE===
--CLEAN--
<?php
unlink(__DIR__ . DIRECTORY_SEPARATOR . 'dbase_get_record_error.dbf');
?>
tests/dbase_get_record_with_names_error_64bit.phpt000064400000002723151731701650016527 0ustar00--TEST--
dbase_get_record_with_names(): error conditions
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
if (PHP_INT_SIZE != 8) die('skip for 64bit platforms only');
if (version_compare(PHP_VERSION, '8', '>')) die('skip for PHP 7 only');
?>
--INI--
allow_url_fopen=1
--FILE--
<?php
var_dump(dbase_get_record_with_names());
var_dump(dbase_get_record_with_names(fopen('data://text/plain,foo', 'r'), 1));

$filename = __DIR__ . DIRECTORY_SEPARATOR . 'dbase_get_record_with_names_error.dbf';
$db = dbase_create($filename, [['foo', 'C', 15]]);
var_dump(dbase_get_record_with_names($db, -1));
var_dump(dbase_get_record_with_names($db, 1));
var_dump(dbase_get_record_with_names($db, 2147483648));
?>
===DONE===
--EXPECTF--
Warning: dbase_get_record_with_names() expects exactly 2 parameters, 0 given in %s on line %d
NULL

Warning: dbase_get_record_with_names(): supplied resource is not a valid dbase resource in %s on line %d
bool(false)

Warning: dbase_get_record_with_names(): record number has to be in range 1..2147483647, but is -1 in %s on line %d
bool(false)

Warning: dbase_get_record_with_names(): Tried to read bad record 1 in %s on line %d
bool(false)

Warning: dbase_get_record_with_names(): record number has to be in range 1..2147483647, but is 2147483648 in %s on line %d
bool(false)
===DONE===
--CLEAN--
<?php
unlink(__DIR__ . DIRECTORY_SEPARATOR . 'dbase_get_record_with_names_error.dbf');
?>
tests/dbase_numrecords_error.phpt000064400000001132151731701650013336 0ustar00--TEST--
dbase_numrecords(): error conditions
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
if (version_compare(PHP_VERSION, '8', '>')) die('skip for PHP 7 only');
?>
--INI--
allow_url_fopen=1
--FILE--
<?php
var_dump(dbase_numrecords());
var_dump(dbase_numrecords(fopen('data://text/plain,foo', 'r')));
?>
===DONE===
--EXPECTF--
Warning: dbase_numrecords() expects exactly 1 parameter, 0 given in %s on line %d
NULL

Warning: dbase_numrecords(): supplied resource is not a valid dbase resource in %s on line %d
bool(false)
===DONE===
tests/nullable.phpt000064400000003742151731701650010415 0ustar00--TEST--
Nullable fields
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
?>
--FILE--
<?php
$filename = __DIR__ . DIRECTORY_SEPARATOR . 'nullable.dbf';
$spec = array(
    ['A', 'C', 15],
    ['B', 'C', 15, true],
    ['C', 'C', 15, true],
    ['D', 'N', 15, 0],
    ['E', 'N', 15, 0, true],
    ['F', 'N', 15, 0, true],
    ['G', 'L'],
    ['H', 'L', true],
    ['I', 'L', true],
    ['J', 'D'],
    ['K', 'D', true],
    ['L', 'D', true],
    ['M', 'F', 15, 2],
    ['N', 'F', 15, 2, true],
    ['O', 'F', 15, 2, true],
);

$db = dbase_create($filename, $spec, DBASE_TYPE_FOXPRO);
dbase_add_record($db, [
    null, null, 'foo',
    null, null, 42,
    null, null, 'T',
    null, null, '20161105',
    null, null, 3.14
]);
var_dump(
    dbase_numfields($db),
    count(dbase_get_header_info($db))
);
var_dump(dbase_get_record($db, 1));
dbase_close($db);

$db = dbase_open($filename, DBASE_RDONLY);
var_dump(dbase_get_record_with_names($db, 1));
?>
===DONE===
--EXPECT--
int(15)
int(15)
array(16) {
  [0]=>
  string(15) "               "
  [1]=>
  NULL
  [2]=>
  string(15) "foo            "
  [3]=>
  int(0)
  [4]=>
  NULL
  [5]=>
  int(42)
  [6]=>
  bool(false)
  [7]=>
  NULL
  [8]=>
  bool(true)
  [9]=>
  string(8) "        "
  [10]=>
  NULL
  [11]=>
  string(8) "20161105"
  [12]=>
  float(0)
  [13]=>
  NULL
  [14]=>
  float(3.14)
  ["deleted"]=>
  int(0)
}
array(16) {
  ["A"]=>
  string(15) "               "
  ["B"]=>
  NULL
  ["C"]=>
  string(15) "foo            "
  ["D"]=>
  int(0)
  ["E"]=>
  NULL
  ["F"]=>
  int(42)
  ["G"]=>
  bool(false)
  ["H"]=>
  NULL
  ["I"]=>
  bool(true)
  ["J"]=>
  string(8) "        "
  ["K"]=>
  NULL
  ["L"]=>
  string(8) "20161105"
  ["M"]=>
  float(0)
  ["N"]=>
  NULL
  ["O"]=>
  float(3.14)
  ["deleted"]=>
  int(0)
}
===DONE===
--CLEAN--
<?php
unlink(__DIR__ . DIRECTORY_SEPARATOR . 'nullable.dbf');
?>
tests/dbase_add_record_error-8.phpt000064400000002673151731701650013423 0ustar00--TEST--
dbase_add_record(): test error conditions
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
if (version_compare(PHP_VERSION, '8', '<')) die('skip for PHP 8 only');
?>
--INI--
allow_url_fopen=1
--FILE--
<?php
$filename = __DIR__ . DIRECTORY_SEPARATOR . 'dbase_add_record_error.dbf';
copy(__DIR__ . DIRECTORY_SEPARATOR . 'example.dbf', $filename);

$db = dbase_open($filename, DBASE_RDWR);

try {
	var_dump(dbase_add_record($db));
} catch (ArgumentCountError $ex) {
    echo $ex->getMessage(), PHP_EOL;
}

try {
	var_dump(dbase_add_record(fopen('data://text/plain,foo', 'r'), []));
} catch (TypeError $ex) {
    echo $ex->getMessage(), PHP_EOL;
}

try {
    dbase_add_record($db, 'no array');
} catch (TypeError $ex) {
    echo $ex->getMessage(), PHP_EOL;
}

var_dump(dbase_add_record($db, []));

var_dump(dbase_add_record($db, [0, 1, 2, 3, 4, 'foo' => 5, 6]));
?>
===DONE===
--EXPECTF--
dbase_add_record() expects exactly 2 arguments, 1 given
dbase_add_record(): supplied resource is not a valid dbase resource
dbase_add_record(): Argument #2 ($data) must be of type array, string given

Warning: dbase_add_record(): expected 7 fields, but got 0 in %s on line %d
bool(false)

Warning: dbase_add_record(): expected plain indexed array in %s on line %d
bool(false)
===DONE===
--CLEAN--
<?php
unlink(__DIR__ . DIRECTORY_SEPARATOR . 'dbase_add_record_error.dbf');
?>
tests/dbase_replace_record_error_1_64bit.phpt000064400000002476151731701660015373 0ustar00--TEST--
dbase_replace_record(): error conditions
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
if (PHP_INT_SIZE != 8) die('skip for 64bit platforms only');
if (version_compare(PHP_VERSION, '8', '>')) die('skip for PHP 7 only');
?>
--FILE--
<?php
$filename = __DIR__ . DIRECTORY_SEPARATOR . 'dbase_replace_record_error_1.dbf';
copy(__DIR__ . DIRECTORY_SEPARATOR . 'example.dbf', $filename);

$db = dbase_open($filename, DBASE_RDWR);

try {
    dbase_replace_record($db, 'no array', 1);
} catch (TypeError $ex) {
    echo $ex->getMessage(), PHP_EOL;
}

var_dump(dbase_replace_record($db, [], -1));
var_dump(dbase_replace_record($db, [], 2147483648));

var_dump(dbase_replace_record($db, [], 1));
?>
===DONE===
--EXPECTF--
Argument 2 passed to dbase_replace_record() must be of the type array, string given

Warning: dbase_replace_record(): record number has to be in range 1..2147483647, but is -1 in %s on line %d
bool(false)

Warning: dbase_replace_record(): record number has to be in range 1..2147483647, but is 2147483648 in %s on line %d
bool(false)

Warning: dbase_replace_record(): expected 7 fields, but got 0 in %s on line %d
bool(false)
===DONE===
--CLEAN--
<?php
unlink(__DIR__ . DIRECTORY_SEPARATOR . 'dbase_replace_record_error_1.dbf');
?>
tests/bug73391.phpt000064400000001023151731701660007772 0ustar00--TEST--
Bug #73391 (Writing of floats can cause OOB reads)
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extesion not available');
?>
--FILE--
<?php
$db = dbase_create(
    __DIR__ . DIRECTORY_SEPARATOR . 'bug73391.dbf',
    array(
        array('num', 'N', 10, 2)
    )
);

dbase_add_record($db, array(1.23));
dbase_replace_record($db, array(1.23), 1);

dbase_close($db);
?>
===DONE===
--EXPECT--
===DONE===
--CLEAN--
<?php
unlink(__DIR__ . DIRECTORY_SEPARATOR . 'bug73391.dbf');
?>
tests/dbase_add_record_variation3.phpt000064400000001605151731701660014177 0ustar00--TEST--
dbase_add_record(): date of last update is properly updated
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
?>
--INI--
date.timezone=UTC
--FILE--
<?php
$filename = __DIR__ . DIRECTORY_SEPARATOR . 'dbase_add_record_variation3.dbf';
copy(__DIR__ . DIRECTORY_SEPARATOR . 'example.dbf', $filename);
$db = dbase_open($filename, 2);
dbase_add_record($db, array(4711, 'foo', '20161028', '20161028123456.789', 'F', 1.23, 99.99));
dbase_close($db);
$date = getdate();
$result = unpack('C4byte', file_get_contents($filename));
var_dump(
    $result['byte2'] + 1900 == $date['year'],
    $result['byte3'] == $date['mon'],
    $result['byte4'] == $date['mday']
);
?>
===DONE===
--EXPECT--
bool(true)
bool(true)
bool(true)
===DONE===
--CLEAN--
<?php
unlink(__DIR__ . DIRECTORY_SEPARATOR . 'dbase_add_record_variation3.dbf');
?>
tests/dbase_pack_error.phpt000064400000001074151731701660012101 0ustar00--TEST--
dbase_pack(): error conditions
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
if (version_compare(PHP_VERSION, '8', '>')) die('skip for PHP 7 only');
?>
--INI--
allow_url_fopen=1
--FILE--
<?php
var_dump(dbase_pack());
var_dump(dbase_pack(fopen('data://text/plain,foo', 'r')));
?>
===DONE===
--EXPECTF--
Warning: dbase_pack() expects exactly 1 parameter, 0 given in %s on line %d
NULL

Warning: dbase_pack(): supplied resource is not a valid dbase resource in %s on line %d
bool(false)
===DONE===
tests/dbase_replace_record_error_1_32bit.phpt000064400000002440151731701670015356 0ustar00--TEST--
dbase_replace_record(): error conditions
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
if (PHP_INT_SIZE != 4) die('skip for 32bit platforms only');
if (version_compare(PHP_VERSION, '8', '>')) die('skip for PHP 7 only');
?>
--FILE--
<?php
$filename = __DIR__ . DIRECTORY_SEPARATOR . 'dbase_replace_record_error_1.dbf';
copy(__DIR__ . DIRECTORY_SEPARATOR . 'example.dbf', $filename);

$db = dbase_open($filename, DBASE_RDWR);

try {
    dbase_replace_record($db, 'no array', 1);
} catch (TypeError $ex) {
    echo $ex->getMessage(), PHP_EOL;
}

var_dump(dbase_replace_record($db, [], -1));
var_dump(dbase_replace_record($db, [], 2147483648));

var_dump(dbase_replace_record($db, [], 1));
?>
===DONE===
--EXPECTF--
Argument 2 passed to dbase_replace_record() must be of the type array, string given

Warning: dbase_replace_record(): record number has to be in range 1..2147483647, but is -1 in %s on line %d
bool(false)

Warning: dbase_replace_record() expects parameter 3 to be in%s, float given in %s on line %d
NULL

Warning: dbase_replace_record(): expected 7 fields, but got 0 in %s on line %d
bool(false)
===DONE===
--CLEAN--
<?php
unlink(__DIR__ . DIRECTORY_SEPARATOR . 'dbase_replace_record_error_1.dbf');
?>
tests/dbase_delete_record_error_32bit_8.phpt000064400000003035151731701670015215 0ustar00--TEST--
dbase_delete_record(): error conditions
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
if (PHP_INT_SIZE != 4) die('skip for 32bit platforms only');
if (version_compare(PHP_VERSION, '8', '<')) die('skip for PHP 8 only');
?>
--INI--
allow_url_fopen=1
--FILE--
<?php
$filename = __DIR__ . DIRECTORY_SEPARATOR . 'dbase_delete_record_error.dbf';
$db = dbase_create($filename, [['foo', 'C', 15]]);
try {
    var_dump(dbase_delete_record($db));
} catch (ArgumentCountError $ex) {
    echo $ex->getMessage(), PHP_EOL;
}
try {
    var_dump(dbase_delete_record(fopen('data://text/plain,foo', 'r'), 1));
} catch (TypeError $ex) {
    echo $ex->getMessage(), PHP_EOL;
}
try {
    var_dump(dbase_delete_record($db, -1));
} catch (ValueError $ex) {
    echo $ex->getMessage(), PHP_EOL;
}
var_dump(dbase_delete_record($db, 1));
try {
    var_dump(dbase_delete_record($db, 2147483648));
} catch (TypeError $ex) {
    echo $ex->getMessage(), PHP_EOL;
}
?>
===DONE===
--EXPECTF--
dbase_delete_record() expects exactly 2 arguments, 1 given
dbase_delete_record(): supplied resource is not a valid dbase resource
dbase_delete_record(): Argument #2 ($number) record number has to be in range 1..2147483647, but is -1

Warning: dbase_delete_record(): record 1 out of bounds in %s on line %d
bool(false)
dbase_delete_record(): Argument #2 ($number) must be of type int, float given
===DONE===
--CLEAN--
<?php
unlink(__DIR__ . DIRECTORY_SEPARATOR . 'dbase_delete_record_error.dbf');
?>
tests/bug73395.phpt000064400000000740151731701670010004 0ustar00--TEST--
Bug #73395 (A failing dbase_create() may leak memory)
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
?>
--FILE--
<?php
dbase_create(__DIR__ . DIRECTORY_SEPARATOR . 'bug73395.dbf', array(array('foo')));
?>
===DONE===
--EXPECTF--
Warning: dbase_create(): expected field type as element 1 of list in field 0 in %s on line %d
===DONE===
--CLEAN--
<?php
unlink(__DIR__ . DIRECTORY_SEPARATOR . 'bug73395.dbf');
?>
tests/type_datetime.phpt000064400000003714151731701670011455 0ustar00--TEST--
Reading and writing of datetime values
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
?>
--FILE--
<?php
$db = dbase_create(
    __DIR__ . DIRECTORY_SEPARATOR . 'type_datetime.dbf',
    array(
        array('datetime', 'T')
    ),
    DBASE_TYPE_FOXPRO
);

$values = array(
    // good values
    '00010101000000.000', // minimum
    '15821015120000.000', // gregorian calendar
    '19690324101000.000', // author's birthday
    '19950608090000.000', // PHP's birthday
    '19991231235959.999', // millenium - 1msec
    '20000101000000.000', // millenium
    '20630405111500.000', // Bozeman, Montana
    '45670123123456.789', // all digits
    '99991231235959.999',  // maximum
    
    // bad values - will be silently accepted, but produce garbage
    '00000000000000.000',
    '99999999999999.999',
);

foreach ($values as $value) {
    dbase_add_record($db, array($value));
}

for ($i = 1; $i <= dbase_numrecords($db); $i++) {
    var_dump(
        dbase_get_record($db, $i)[0],
        dbase_get_record_with_names($db, $i)['datetime']
    );
}
?>
===DONE===
--EXPECT--
string(18) "00010101000000.000"
string(18) "00010101000000.000"
string(18) "15821015120000.000"
string(18) "15821015120000.000"
string(18) "19690324101000.000"
string(18) "19690324101000.000"
string(18) "19950608090000.000"
string(18) "19950608090000.000"
string(18) "19991231235959.999"
string(18) "19991231235959.999"
string(18) "20000101000000.000"
string(18) "20000101000000.000"
string(18) "20630405111500.000"
string(18) "20630405111500.000"
string(18) "45670123123456.789"
string(18) "45670123123456.789"
string(18) "99991231235959.999"
string(18) "99991231235959.999"
string(18) "00000000000000.000"
string(18) "00000000000000.000"
string(18) "000000001004039.99"
string(18) "000000001004039.99"
===DONE===
--CLEAN--
<?php
unlink(__DIR__ . DIRECTORY_SEPARATOR . 'type_datetime.dbf');
?>
tests/type_logical.phpt000064400000001576151731701700011271 0ustar00--TEST--
Reading and writing of logical values
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
?>
--FILE--
<?php
$db = dbase_create(
    __DIR__ . DIRECTORY_SEPARATOR . 'type_logical.dbf',
    array(
        array('flag', 'L')
    )
);

foreach (array('T', 'Y', 'F', 'N', ' ', '1', '0', '?') as $flag) {
    dbase_add_record($db, array($flag));
}

for ($i = 1; $i <= dbase_numrecords($db); $i++) {
    var_dump(
        dbase_get_record($db, $i)[0],
        dbase_get_record_with_names($db, $i)['flag']
    );
}
?>
===DONE===
--EXPECT--
bool(true)
bool(true)
bool(true)
bool(true)
bool(false)
bool(false)
bool(false)
bool(false)
bool(false)
bool(false)
bool(false)
bool(false)
bool(false)
bool(false)
NULL
NULL
===DONE===
--CLEAN--
<?php
unlink(__DIR__ . DIRECTORY_SEPARATOR . 'type_logical.dbf');
?>
tests/001.phpt000064400000002230151731701700007102 0ustar00--TEST--
dbase_create() tests
--SKIPIF--
<?php if (!extension_loaded("dbase")) print "skip"; ?>
--FILE--
<?php

function my_error_handler($errno, $errstr, $errfile, $errline) {
	var_dump($errstr);
}

set_error_handler('my_error_handler');

$fields_arr = Array(
    Array(
        array('date','D'),
        ),
    Array(
        array('error', 'E'),
        ),
    Array(
        array('error', -1),
        ),
    Array(
        array(-1, 'N', 3, 0),
        ),
    Array(
        array(),
        ),
    Array(
        ),
);

$file = dirname(__FILE__).'/001.dbf';

foreach ($fields_arr as $fields) {
    var_dump($db = dbase_create($file, $fields));
	if ($db) {
		dbase_close($db);
		unlink($file);
	}
}

echo "Done\n";
?>
--EXPECTF--
resource(%d) of type (dbase)
string(38) "dbase_create(): unknown field type 'E'"
bool(false)
string(38) "dbase_create(): unknown field type '-'"
bool(false)
resource(%d) of type (dbase)
string(67) "dbase_create(): expected field name as element 0 of list in field 0"
bool(false)
string(56) "dbase_create(): Unable to create database without fields"
bool(false)
Done
--CLEAN--
<?php
$file = dirname(__FILE__).'/001.dbf';

unlink($file);
?>
tests/bug31754.phpt000064400000001070151731701700007764 0ustar00--TEST--
Bug #31754 (dbase_open() fails for mode = 1)
--SKIPIF--
<?php
if (!extension_loaded('dbase')) {
	die('skip dbase extension not available');
}
?>
--FILE--
<?php
$filename = __DIR__ . DIRECTORY_SEPARATOR . 'bug31754.dbf';

// creation
$dbh = dbase_create($filename, array(array('foo', 'L')));
dbase_close($dbh);

$dbh = dbase_open($filename, 1);
?>
--EXPECTF--
Warning: dbase_open(): Cannot open %s%ebug31754.dbf in write-only mode in %s%ebug31754.php on line %d
--CLEAN--
<?php
$filename = __DIR__ . DIRECTORY_SEPARATOR . 'bug31754.dbf';
unlink($filename);
?>
tests/bug81563.phpt000064400000001102151731701700007763 0ustar00--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)
}
tests/dbase_open_error3.dbf000064400000000142151731701710011756 0ustar00tafooCbar0
tests/dbase_create_error.phpt000064400000011244151731701710012422 0ustar00--TEST--
dbase_create() - error conditions
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
if (version_compare(PHP_VERSION, '8', '>')) die('skip for PHP 7 only');
?>
--FILE--
<?php
define('FILENAME', __DIR__ . DIRECTORY_SEPARATOR . 'dbase_create_error.dbf');

/* too few arguments */
var_dump(dbase_create(FILENAME));
if (file_exists(FILENAME)) unlink(FILENAME);

/* too many arguments */
var_dump(dbase_create(FILENAME, array(), DBASE_TYPE_DBASE, 'additional argument'));
if (file_exists(FILENAME)) unlink(FILENAME);

/* second argument is no array */
try {
    dbase_create(FILENAME, 'no array');
} catch (TypeError $ex) {
    echo $ex->getMessage(), PHP_EOL;
}
if (file_exists(FILENAME)) unlink(FILENAME);

/* no fields */
var_dump(dbase_create(FILENAME, array()));
if (file_exists(FILENAME)) unlink(FILENAME);

/* associative array */
var_dump(dbase_create(FILENAME, array('foo' => 'bar')));
if (file_exists(FILENAME)) unlink(FILENAME);

/* field without name */
var_dump(dbase_create(FILENAME, array(array())));
if (file_exists(FILENAME)) unlink(FILENAME);

/* field with empty name */
var_dump(dbase_create(FILENAME, array(array(''))));
if (file_exists(FILENAME)) unlink(FILENAME);

/* field name too long */
var_dump(dbase_create(FILENAME, array(array('abcdefghijk'))));
if (file_exists(FILENAME)) unlink(FILENAME);

/* field type missing */
var_dump(dbase_create(FILENAME, array(array('foo'))));
if (file_exists(FILENAME)) unlink(FILENAME);

/* field length missing */
var_dump(dbase_create(FILENAME, array(array('foo', 'C'))));
if (file_exists(FILENAME)) unlink(FILENAME);

/* field length too small */
var_dump(dbase_create(FILENAME, array(array('foo', 'C', -1))));
if (file_exists(FILENAME)) unlink(FILENAME);

/* field length too large */
var_dump(dbase_create(FILENAME, array(array('foo', 'C', 255))));
if (file_exists(FILENAME)) unlink(FILENAME);

/* field precision missing */
var_dump(dbase_create(FILENAME, array(array('foo', 'N', 10))));
if (file_exists(FILENAME)) unlink(FILENAME);

/* field precision too small */
var_dump(dbase_create(FILENAME, array(array('foo', 'N', 10, -1))));
if (file_exists(FILENAME)) unlink(FILENAME);

/* field precision too large */
var_dump(dbase_create(FILENAME, array(array('foo', 'N', 10, 255))));
if (file_exists(FILENAME)) unlink(FILENAME);

/* unknown field type */
var_dump(dbase_create(FILENAME, array(array('foo', '~'))));
if (file_exists(FILENAME)) unlink(FILENAME);

/* unsupported field type*/
var_dump(dbase_create(FILENAME, array(array('foo', 'T'))));
if (file_exists(FILENAME)) unlink(FILENAME);

/* unknown database type */
var_dump(dbase_create(FILENAME, array(array('foo', 'C', 15)), 17));
if (file_exists(FILENAME)) unlink(FILENAME);
?>
===DONE===
--EXPECTF--
Warning: dbase_create() expects at least 2 parameters, 1 given in %s on line %d
NULL

Warning: dbase_create() expects at most 3 parameters, 4 given in %s on line %d
NULL
Argument 2 passed to dbase_create() must be of the type array, string given

Warning: dbase_create(): Unable to create database without fields in %s on line %d
bool(false)

Warning: dbase_create(): expected plain indexed array in %s on line %d
bool(false)

Warning: dbase_create(): expected field name as element 0 of list in field 0 in %s on line %d
bool(false)

Warning: dbase_create(): invalid field name '' (must be non-empty and less than or equal to 10 characters) in %s on line %d
bool(false)

Warning: dbase_create(): invalid field name 'abcdefghijk' (must be non-empty and less than or equal to 10 characters) in %s on line %d
bool(false)

Warning: dbase_create(): expected field type as element 1 of list in field 0 in %s on line %d
bool(false)

Warning: dbase_create(): expected field length as element 2 of list in field 0 in %s on line %d
bool(false)

Warning: dbase_create(): expected length of field 0 to be in range 0..254, but got -1 in %s on line %d
bool(false)

Warning: dbase_create(): expected length of field 0 to be in range 0..254, but got 255 in %s on line %d
bool(false)

Warning: dbase_create(): expected field precision as element 3 of list in field 0 in %s on line %d
bool(false)

Warning: dbase_create(): expected precision of field 0 to be in range 0..254, but got -1 in %s on line %d
bool(false)

Warning: dbase_create(): expected precision of field 0 to be in range 0..254, but got 255 in %s on line %d
bool(false)

Warning: dbase_create(): unknown field type '~' in %s on line %d
bool(false)

Warning: dbase_create(): datetime fields are not supported by dBASE in %s on line %d
bool(false)

Warning: dbase_create(): unknown database type 17 in %s on line %d
bool(false)
===DONE===
--CLEAN--
<?php
define('FILENAME', __DIR__ . DIRECTORY_SEPARATOR . 'dbase_create_error.dbf');

unlink(FILENAME);
?>
tests/bug73447.phpt000064400000001421151731701710007772 0ustar00--TEST--
Bug #73447 (Floats written to character fields are truncated to integer)
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
?>
--FILE--
<?php
$filename = __DIR__ . DIRECTORY_SEPARATOR . 'bug73447.dbf';
$db = dbase_create($filename, [['FLOAT', 'C', 15]]);

dbase_add_record($db, [123.45]);
var_dump(dbase_get_record_with_names($db, 1));
dbase_replace_record($db, [987.65], 1);
var_dump(dbase_get_record_with_names($db, 1));
?>
===DONE===
--EXPECT--
array(2) {
  ["FLOAT"]=>
  string(15) "123.45         "
  ["deleted"]=>
  int(0)
}
array(2) {
  ["FLOAT"]=>
  string(15) "987.65         "
  ["deleted"]=>
  int(0)
}
===DONE===
--CLEAN--
<?php
unlink(__DIR__ . DIRECTORY_SEPARATOR . 'bug73447.dbf');
?>
tests/dbase_delete_record_error_64bit.phpt000064400000002550151731701720014770 0ustar00--TEST--
dbase_delete_record(): error conditions
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
if (PHP_INT_SIZE != 8) die('skip for 64bit platforms only');
if (version_compare(PHP_VERSION, '8', '>')) die('skip for PHP 7 only');
?>
--INI--
allow_url_fopen=1
--FILE--
<?php
$filename = __DIR__ . DIRECTORY_SEPARATOR . 'dbase_delete_record_error.dbf';
$db = dbase_create($filename, [['foo', 'C', 15]]);
var_dump(dbase_delete_record($db));
var_dump(dbase_delete_record(fopen('data://text/plain,foo', 'r'), 1));
var_dump(dbase_delete_record($db, -1));
var_dump(dbase_delete_record($db, 1));
var_dump(dbase_delete_record($db, 2147483648));
?>
===DONE===
--EXPECTF--
Warning: dbase_delete_record() expects exactly 2 parameters, 1 given in %s on line %d
NULL

Warning: dbase_delete_record(): supplied resource is not a valid dbase resource in %s on line %d
bool(false)

Warning: dbase_delete_record(): record number has to be in range 1..2147483647, but is -1 in %s on line %d
bool(false)

Warning: dbase_delete_record(): record 1 out of bounds in %s on line %d
bool(false)

Warning: dbase_delete_record(): record number has to be in range 1..2147483647, but is 2147483648 in %s on line %d
bool(false)
===DONE===
--CLEAN--
<?php
unlink(__DIR__ . DIRECTORY_SEPARATOR . 'dbase_delete_record_error.dbf');
?>
tests/dbase_pack_variation2.phpt000064400000001175151731701720013025 0ustar00--TEST--
dbase_pack() writes proper EOF marker
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
?>
--FILE--
<?php
$filename = __DIR__ . DIRECTORY_SEPARATOR . 'dbase_pack_variation2.dbf';

$db = dbase_create($filename, array(array('NAME', 'C', 15)));
dbase_add_record($db, array('foo'));
dbase_delete_record($db, 1);
dbase_pack($db);
dbase_close($db);

$contents = file_get_contents($filename);
printf("%02X\n", ord(substr($contents, -1)));
?>
===DONE===
--EXPECT--
1A
===DONE===
--CLEAN--
<?php
unlink(__DIR__ . DIRECTORY_SEPARATOR . 'dbase_pack_variation2.dbf');
?>
tests/bug81563.dbf000064400000000237151731701720007555 0ustar00w�SCHLAGNRN
TEILSCHLAGCFLIKC
      12345a DENWLI0546132777tests/bug78668.dbf000064400000000024151731701720007563 0ustar00ffffffffffffffffjrhtests/dbase_get_record_error_64bit.phpt000064400000002504151731701730014305 0ustar00--TEST--
dbase_get_record(): error conditions
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
if (PHP_INT_SIZE != 8) die('skip for 64bit platforms only');
if (version_compare(PHP_VERSION, '8', '>')) die('skip for PHP 7 only');
?>
--INI--
allow_url_fopen=1
--FILE--
<?php
var_dump(dbase_get_record());
var_dump(dbase_get_record(fopen('data://text/plain,foo', 'r'), 1));

$filename = __DIR__ . DIRECTORY_SEPARATOR . 'dbase_get_record_error.dbf';
$db = dbase_create($filename, [['foo', 'C', 15]]);
var_dump(dbase_get_record($db, -1));
var_dump(dbase_get_record($db, 1));
var_dump(dbase_get_record($db, 2147483648));
?>
===DONE===
--EXPECTF--
Warning: dbase_get_record() expects exactly 2 parameters, 0 given in %s on line %d
NULL

Warning: dbase_get_record(): supplied resource is not a valid dbase resource in %s on line %d
bool(false)

Warning: dbase_get_record(): record number has to be in range 1..2147483647, but is -1 in %s on line %d
bool(false)

Warning: dbase_get_record(): Tried to read bad record 1 in %s on line %d
bool(false)

Warning: dbase_get_record(): record number has to be in range 1..2147483647, but is 2147483648 in %s on line %d
bool(false)
===DONE===
--CLEAN--
<?php
unlink(__DIR__ . DIRECTORY_SEPARATOR . 'dbase_get_record_error.dbf');
?>
tests/dbase_numrecords_basic.phpt000064400000001145151731701730013271 0ustar00--TEST--
dbase_numrecords(): basic functionality
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
?>
--FILE--
<?php
$filename = __DIR__ . DIRECTORY_SEPARATOR . 'dbase_numrecords_basic.dbf';
copy(__DIR__ . DIRECTORY_SEPARATOR . 'example.dbf', $filename);

$db = dbase_open($filename, DBASE_RDWR);
var_dump($db);

var_dump(dbase_numrecords($db));

var_dump(dbase_close($db));
?>
===DONE===
--EXPECTF--
resource(%d) of type (dbase)
int(3)
bool(true)
===DONE===
--CLEAN--
<?php
$filename = __DIR__ . DIRECTORY_SEPARATOR . 'dbase_numrecords_basic.dbf';
unlink($filename);
?>
tests/dbase_open_error1.phpt000064400000000722151731701730012202 0ustar00--TEST--
dbase_open() raises warning for unsupported field types
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
?>
--FILE--
<?php
$filename = __DIR__ . DIRECTORY_SEPARATOR . 'dbase_open_error1.dbf';
dbase_open($filename, DBASE_RDONLY);
?>
===DONE===
--EXPECTF--
Warning: dbase_open(): unknown field type 'X' in %s on line %d

Warning: dbase_open(): unable to open database %s in %s on line %d
===DONE===
tests/dbase_create_error_8.phpt000064400000011403151731701730012650 0ustar00--TEST--
dbase_create() - error conditions
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
if (version_compare(PHP_VERSION, '8', '<')) die('skip for PHP 8 only');
?>
--FILE--
<?php
define('FILENAME', __DIR__ . DIRECTORY_SEPARATOR . 'dbase_create_error.dbf');

/* too few arguments */
try {
	var_dump(dbase_create(FILENAME));
} catch (ArgumentCountError $ex) {
    echo $ex->getMessage(), PHP_EOL;
}
if (file_exists(FILENAME)) unlink(FILENAME);

/* too many arguments */
try {
	var_dump(dbase_create(FILENAME, array(), DBASE_TYPE_DBASE, 'additional argument'));
} catch (ArgumentCountError $ex) {
    echo $ex->getMessage(), PHP_EOL;
}
if (file_exists(FILENAME)) unlink(FILENAME);

/* second argument is no array */
try {
    dbase_create(FILENAME, 'no array');
} catch (TypeError $ex) {
    echo $ex->getMessage(), PHP_EOL;
}
if (file_exists(FILENAME)) unlink(FILENAME);

/* no fields */
var_dump(dbase_create(FILENAME, array()));
if (file_exists(FILENAME)) unlink(FILENAME);

/* associative array */
var_dump(dbase_create(FILENAME, array('foo' => 'bar')));
if (file_exists(FILENAME)) unlink(FILENAME);

/* field without name */
var_dump(dbase_create(FILENAME, array(array())));
if (file_exists(FILENAME)) unlink(FILENAME);

/* field with empty name */
var_dump(dbase_create(FILENAME, array(array(''))));
if (file_exists(FILENAME)) unlink(FILENAME);

/* field name too long */
var_dump(dbase_create(FILENAME, array(array('abcdefghijk'))));
if (file_exists(FILENAME)) unlink(FILENAME);

/* field type missing */
var_dump(dbase_create(FILENAME, array(array('foo'))));
if (file_exists(FILENAME)) unlink(FILENAME);

/* field length missing */
var_dump(dbase_create(FILENAME, array(array('foo', 'C'))));
if (file_exists(FILENAME)) unlink(FILENAME);

/* field length too small */
var_dump(dbase_create(FILENAME, array(array('foo', 'C', -1))));
if (file_exists(FILENAME)) unlink(FILENAME);

/* field length too large */
var_dump(dbase_create(FILENAME, array(array('foo', 'C', 255))));
if (file_exists(FILENAME)) unlink(FILENAME);

/* field precision missing */
var_dump(dbase_create(FILENAME, array(array('foo', 'N', 10))));
if (file_exists(FILENAME)) unlink(FILENAME);

/* field precision too small */
var_dump(dbase_create(FILENAME, array(array('foo', 'N', 10, -1))));
if (file_exists(FILENAME)) unlink(FILENAME);

/* field precision too large */
var_dump(dbase_create(FILENAME, array(array('foo', 'N', 10, 255))));
if (file_exists(FILENAME)) unlink(FILENAME);

/* unknown field type */
var_dump(dbase_create(FILENAME, array(array('foo', '~'))));
if (file_exists(FILENAME)) unlink(FILENAME);

/* unsupported field type*/
var_dump(dbase_create(FILENAME, array(array('foo', 'T'))));
if (file_exists(FILENAME)) unlink(FILENAME);

/* unknown database type */
var_dump(dbase_create(FILENAME, array(array('foo', 'C', 15)), 17));
if (file_exists(FILENAME)) unlink(FILENAME);
?>
===DONE===
--EXPECTF--
dbase_create() expects at least 2 arguments, 1 given
dbase_create() expects at most 3 arguments, 4 given
dbase_create(): Argument #2 ($fields) must be of type array, string given

Warning: dbase_create(): Unable to create database without fields in %s on line %d
bool(false)

Warning: dbase_create(): expected plain indexed array in %s on line %d
bool(false)

Warning: dbase_create(): expected field name as element 0 of list in field 0 in %s on line %d
bool(false)

Warning: dbase_create(): invalid field name '' (must be non-empty and less than or equal to 10 characters) in %s on line %d
bool(false)

Warning: dbase_create(): invalid field name 'abcdefghijk' (must be non-empty and less than or equal to 10 characters) in %s on line %d
bool(false)

Warning: dbase_create(): expected field type as element 1 of list in field 0 in %s on line %d
bool(false)

Warning: dbase_create(): expected field length as element 2 of list in field 0 in %s on line %d
bool(false)

Warning: dbase_create(): expected length of field 0 to be in range 0..254, but got -1 in %s on line %d
bool(false)

Warning: dbase_create(): expected length of field 0 to be in range 0..254, but got 255 in %s on line %d
bool(false)

Warning: dbase_create(): expected field precision as element 3 of list in field 0 in %s on line %d
bool(false)

Warning: dbase_create(): expected precision of field 0 to be in range 0..254, but got -1 in %s on line %d
bool(false)

Warning: dbase_create(): expected precision of field 0 to be in range 0..254, but got 255 in %s on line %d
bool(false)

Warning: dbase_create(): unknown field type '~' in %s on line %d
bool(false)

Warning: dbase_create(): datetime fields are not supported by dBASE in %s on line %d
bool(false)

Warning: dbase_create(): unknown database type 17 in %s on line %d
bool(false)
===DONE===
--CLEAN--
<?php
define('FILENAME', __DIR__ . DIRECTORY_SEPARATOR . 'dbase_create_error.dbf');

unlink(FILENAME);
?>
tests/bug73442.phpt000064400000001201151731701740007764 0ustar00--TEST--
Bug #73442 (Float fields always have precision 0)
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
?>
--FILE--
<?php
$filename = __DIR__ . DIRECTORY_SEPARATOR . 'bug73442.dbf';

$db = dbase_create($filename, [['FLOAT', 'F', 15, 5]]);
dbase_close($db);

$stream = fopen($filename, 'r');
fseek($stream, 48);
$bytes = fread($stream, 2);
var_dump(unpack('Clength/Cprecision', $bytes));
?>
===DONE===
--EXPECT--
array(2) {
  ["length"]=>
  int(15)
  ["precision"]=>
  int(5)
}
===DONE===
--CLEAN--
<?php
unlink(__DIR__ . DIRECTORY_SEPARATOR . 'bug73442.dbf');
?>
tests/dbase_open_error_8.phpt000064400000000661151731701740012353 0ustar00--TEST--
dbase_open(): error conditions
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
if (version_compare(PHP_VERSION, '8', '<')) die('skip for PHP 8 only');
?>
--FILE--
<?php
try {
	var_dump(dbase_open());
} catch (ArgumentCountError $ex) {
    echo $ex->getMessage(), PHP_EOL;
}
?>
===DONE===
--EXPECTF--
dbase_open() expects exactly 2 arguments, 0 given
===DONE===
tests/dbase_pack_variation1.phpt000064400000001445151731701740013026 0ustar00--TEST--
dbase_pack(): date of last update is properly updated
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
?>
--INI--
date.timezone=UTC
--FILE--
<?php
$filename = __DIR__ . DIRECTORY_SEPARATOR . 'dbase_pack_variation1.dbf';
copy(__DIR__ . DIRECTORY_SEPARATOR . 'example.dbf', $filename);
$db = dbase_open($filename, 2);
dbase_pack($db);
dbase_close($db);
$date = getdate();
$result = unpack('C4byte', file_get_contents($filename));
var_dump(
    $result['byte2'] + 1900 == $date['year'],
    $result['byte3'] == $date['mon'],
    $result['byte4'] == $date['mday']
);
?>
===DONE===
--EXPECT--
bool(true)
bool(true)
bool(true)
===DONE===
--CLEAN--
<?php
unlink(__DIR__ . DIRECTORY_SEPARATOR . 'dbase_pack_variation1.dbf');
?>
tests/dbase_create_variation2.phpt000064400000001053151731701740013347 0ustar00--TEST--
dbase_create() writes proper EOF marker
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
?>
--FILE--
<?php
$filename = __DIR__ . DIRECTORY_SEPARATOR . 'dbase_create_variation2.dbf';

$db = dbase_create($filename, array(array('foo', 'C', 1)));
dbase_close($db);

$contents = file_get_contents($filename);
printf("%02X\n", ord(substr($contents, -1)));
?>
===DONE===
--EXPECT--
1A
===DONE===
--CLEAN--
<?php
unlink(__DIR__ . DIRECTORY_SEPARATOR . 'dbase_create_variation2.dbf');
?>
tests/dbase_create_basic.phpt000064400000003607151731701750012362 0ustar00--TEST--
dbase_create(): basic functionality
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
?>
--FILE--
<?php
$filename = __DIR__ . DIRECTORY_SEPARATOR . 'dbase_create_basic.dbf';
$definition = array(
    array('ID', 'N', 5, 0),
    array('NAME', 'C', 25),
    array('RELEASED', 'D'),
    array('SUPORTED', 'L'),
    array('PRICE', 'N', 10, 2)
);

$db = dbase_create($filename, $definition);
var_dump($db);
var_dump(dbase_numfields($db));
var_dump(dbase_get_header_info($db));
var_dump(dbase_numrecords($db));
var_dump(dbase_close($db));
?>
===DONE===
--EXPECTF--
resource(%d) of type (dbase)
int(5)
array(5) {
  [0]=>
  array(6) {
    ["name"]=>
    string(2) "ID"
    ["type"]=>
    string(6) "number"
    ["length"]=>
    int(5)
    ["precision"]=>
    int(0)
    ["format"]=>
    string(3) "%5s"
    ["offset"]=>
    int(1)
  }
  [1]=>
  array(6) {
    ["name"]=>
    string(4) "NAME"
    ["type"]=>
    string(9) "character"
    ["length"]=>
    int(25)
    ["precision"]=>
    int(0)
    ["format"]=>
    string(5) "%-25s"
    ["offset"]=>
    int(6)
  }
  [2]=>
  array(6) {
    ["name"]=>
    string(8) "RELEASED"
    ["type"]=>
    string(4) "date"
    ["length"]=>
    int(8)
    ["precision"]=>
    int(0)
    ["format"]=>
    string(3) "%8s"
    ["offset"]=>
    int(31)
  }
  [3]=>
  array(6) {
    ["name"]=>
    string(8) "SUPORTED"
    ["type"]=>
    string(7) "boolean"
    ["length"]=>
    int(1)
    ["precision"]=>
    int(0)
    ["format"]=>
    string(3) "%1s"
    ["offset"]=>
    int(39)
  }
  [4]=>
  array(6) {
    ["name"]=>
    string(5) "PRICE"
    ["type"]=>
    string(6) "number"
    ["length"]=>
    int(10)
    ["precision"]=>
    int(2)
    ["format"]=>
    string(4) "%10s"
    ["offset"]=>
    int(40)
  }
}
int(0)
bool(true)
===DONE===
--CLEAN--
<?php
$filename = __DIR__ . DIRECTORY_SEPARATOR . 'dbase_create_basic.dbf';
unlink($filename);
?>
tests/dbase_close_error.phpt000064400000001101151731701750012257 0ustar00--TEST--
dbase_close(): error conditions
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
if (version_compare(PHP_VERSION, '8', '>')) die('skip for PHP 7 only');
?>
--INI--
allow_url_fopen=1
--FILE--
<?php
var_dump(dbase_close());
var_dump(dbase_close(fopen('data://text/plain,foo', 'r')));
?>
===DONE===
--EXPECTF--
Warning: dbase_close() expects exactly 1 parameter, 0 given in %s on line %d
NULL

Warning: dbase_close(): supplied resource is not a valid dbase resource in %s on line %d
bool(false)
===DONE===
tests/dbase_get_record_with_names_error_64bit_8.phpt000064400000003236151731701750016757 0ustar00--TEST--
dbase_get_record_with_names(): error conditions
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
if (PHP_INT_SIZE != 8) die('skip for 64bit platforms only');
if (version_compare(PHP_VERSION, '8', '<')) die('skip for PHP 8 only');
?>
--INI--
allow_url_fopen=1
--FILE--
<?php
try {
	var_dump(dbase_get_record_with_names());
} catch (ArgumentCountError $ex) {
    echo $ex->getMessage(), PHP_EOL;
}
try {
	var_dump(dbase_get_record_with_names(fopen('data://text/plain,foo', 'r'), 1));
} catch (TypeError $ex) {
    echo $ex->getMessage(), PHP_EOL;
}

$filename = __DIR__ . DIRECTORY_SEPARATOR . 'dbase_get_record_with_names_error.dbf';
$db = dbase_create($filename, [['foo', 'C', 15]]);
try {
	var_dump(dbase_get_record_with_names($db, -1));
} catch (valueError $ex) {
    echo $ex->getMessage(), PHP_EOL;
}
var_dump(dbase_get_record_with_names($db, 1));
try {
	var_dump(dbase_get_record_with_names($db, 2147483648));
} catch (valueError $ex) {
    echo $ex->getMessage(), PHP_EOL;
}
?>
===DONE===
--EXPECTF--
dbase_get_record_with_names() expects exactly 2 arguments, 0 given
dbase_get_record_with_names(): supplied resource is not a valid dbase resource
dbase_get_record_with_names(): Argument #2 ($number) record number has to be in range 1..2147483647, but is -1

Warning: dbase_get_record_with_names(): Tried to read bad record 1 in %s on line %d
bool(false)
dbase_get_record_with_names(): Argument #2 ($number) record number has to be in range 1..2147483647, but is 2147483648
===DONE===
--CLEAN--
<?php
unlink(__DIR__ . DIRECTORY_SEPARATOR . 'dbase_get_record_with_names_error.dbf');
?>
tests/gh-1.phpt000064400000000716151731701760007353 0ustar00--TEST--
GH-1 (dbase_add_record() converts passed floats and leaks memory)
--SKIPIF--
<?php
if (!extension_loaded("dbase")) die("skip dbase extension not available");
?>
--FILE--
<?php
$filename = __DIR__ . "/gh-1.dbf";
$db = dbase_create($filename, array(array('num', 'n', 10, 1)));

$record = array(1234.5);
dbase_add_record($db, $record);
var_dump($record);
?>
--EXPECT--
array(1) {
  [0]=>
  float(1234.5)
}
--CLEAN--
<?php
unlink(__DIR__ . "/gh-1.dbf");
?>
tests/dbase_open_error2.phpt000064400000000746151731701760012214 0ustar00--TEST--
dbase_open() fails if '0' field is not last field
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
?>
--FILE--
<?php
$filename = __DIR__ . DIRECTORY_SEPARATOR . 'dbase_open_error2.dbf';
var_dump(dbase_open($filename, DBASE_RDONLY));
?>
===DONE===
--EXPECTF--
Warning: dbase_open(): unexpected field type '0' in %s on line %d

Warning: dbase_open(): unable to open database %s in %s on line %d
bool(false)
===DONE===
tests/dbase_delete_record_variation1.phpt000064400000001514151731701760014707 0ustar00--TEST--
dbase_delete_record(): date of last update is properly updated
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
?>
--INI--
date.timezone=UTC
--FILE--
<?php
$filename = __DIR__ . DIRECTORY_SEPARATOR . 'dbase_delete_record_variation1.dbf';
copy(__DIR__ . DIRECTORY_SEPARATOR . 'example.dbf', $filename);
$db = dbase_open($filename, 2);
dbase_delete_record($db, 1);
dbase_close($db);
$date = getdate();
$result = unpack('C4byte', file_get_contents($filename));
var_dump(
    $result['byte2'] + 1900 == $date['year'],
    $result['byte3'] == $date['mon'],
    $result['byte4'] == $date['mday']
);
?>
===DONE===
--EXPECT--
bool(true)
bool(true)
bool(true)
===DONE===
--CLEAN--
<?php
unlink(__DIR__ . DIRECTORY_SEPARATOR . 'dbase_delete_record_variation1.dbf');
?>
tests/dbase_get_record_with_names_basic.phpt000064400000001670151731701760015451 0ustar00--TEST--
dbase_get_record_with_names(): basic functionality
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
?>
--FILE--
<?php
$filename = __DIR__ . DIRECTORY_SEPARATOR . 'dbase_get_record_with_names_basic.dbf';
copy(__DIR__ . DIRECTORY_SEPARATOR . 'example.dbf', $filename);

$db = dbase_open($filename, DBASE_RDWR);
var_dump($db);

var_dump(dbase_get_record_with_names($db, 1));

var_dump(dbase_close($db));
?>
===DONE===
--EXPECTF--
resource(%d) of type (dbase)
array(8) {
  ["ID"]=>
  int(1)
  ["NAME"]=>
  string(25) "dBase III                "
  ["RELEASED"]=>
  string(8) "19840501"
  ["RELEASED_X"]=>
  string(18) "19840501000000.000"
  ["SUPORTED"]=>
  bool(true)
  ["PRICE"]=>
  float(123.45)
  ["MARKETSHAR"]=>
  float(34.56)
  ["deleted"]=>
  int(0)
}
bool(true)
===DONE===
--CLEAN--
<?php
$filename = __DIR__ . DIRECTORY_SEPARATOR . 'dbase_get_record_with_names_basic.dbf';
unlink($filename);
?>
tests/dbase_delete_record_basic.phpt000064400000001672151731701770013721 0ustar00--TEST--
dbase_delete_record(): basic functionality
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
?>
--FILE--
<?php
$filename = __DIR__ . DIRECTORY_SEPARATOR . 'dbase_delete_record_basic.dbf';
copy(__DIR__ . DIRECTORY_SEPARATOR . 'example.dbf', $filename);

$db = dbase_open($filename, DBASE_RDWR);
var_dump($db);

var_dump(dbase_delete_record($db, 2));

var_dump(dbase_numrecords($db));
var_dump(dbase_get_record($db, 2));

var_dump(dbase_close($db));
?>
===DONE===
--EXPECTF--
resource(%d) of type (dbase)
bool(true)
int(3)
array(8) {
  [0]=>
  int(2)
  [1]=>
  string(25) "Clipper                  "
  [2]=>
  string(8) "19850525"
  [3]=>
  string(18) "19850525120000.000"
  [4]=>
  bool(false)
  [5]=>
  float(56.78)
  [6]=>
  float(23.45)
  ["deleted"]=>
  int(1)
}
bool(true)
===DONE===
--CLEAN--
<?php
$filename = __DIR__ . DIRECTORY_SEPARATOR . 'dbase_delete_record_basic.dbf';
unlink($filename);
?>
tests/dbase_get_record_error_64bit_8.phpt000064400000003017151731701770014540 0ustar00--TEST--
dbase_get_record(): error conditions
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
if (PHP_INT_SIZE != 8) die('skip for 64bit platforms only');
if (version_compare(PHP_VERSION, '8', '<')) die('skip for PHP 8 only');
?>
--INI--
allow_url_fopen=1
--FILE--
<?php
try {
	var_dump(dbase_get_record());
} catch (ArgumentCountError $ex) {
    echo $ex->getMessage(), PHP_EOL;
}
try {
	var_dump(dbase_get_record(fopen('data://text/plain,foo', 'r'), 1));
} catch (TypeError $ex) {
    echo $ex->getMessage(), PHP_EOL;
}

$filename = __DIR__ . DIRECTORY_SEPARATOR . 'dbase_get_record_error.dbf';
$db = dbase_create($filename, [['foo', 'C', 15]]);
try {
	var_dump(dbase_get_record($db, -1));
} catch (ValueError $ex) {
    echo $ex->getMessage(), PHP_EOL;
}
var_dump(dbase_get_record($db, 1));
try {
	var_dump(dbase_get_record($db, 2147483648));
} catch (ValueError $ex) {
    echo $ex->getMessage(), PHP_EOL;
}
?>
===DONE===
--EXPECTF--
dbase_get_record() expects exactly 2 arguments, 0 given
dbase_get_record(): supplied resource is not a valid dbase resource
dbase_get_record(): Argument #2 ($number) record number has to be in range 1..2147483647, but is -1

Warning: dbase_get_record(): Tried to read bad record 1 in %s on line %d
bool(false)
dbase_get_record(): Argument #2 ($number) record number has to be in range 1..2147483647, but is 2147483648
===DONE===
--CLEAN--
<?php
unlink(__DIR__ . DIRECTORY_SEPARATOR . 'dbase_get_record_error.dbf');
?>
tests/bug73414.phpt000064400000000671151731701770010000 0ustar00--TEST--
Bug #73414 (Unsupported field types may cause dbase_open() to leak memory)
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
?>
--FILE--
<?php
dbase_open(__DIR__ . DIRECTORY_SEPARATOR . 'bug73414.dbf', 0);
?>
===DONE===
--EXPECTF--
Warning: dbase_open(): unknown field type 'Y' in %s on line %d

Warning: dbase_open(): unable to open database %s in %s on line %d
===DONE===
tests/002.phpt000064400000002336151731701770007121 0ustar00--TEST--
dbase_open() tests
--SKIPIF--
<?php if (!extension_loaded("dbase")) print "skip"; ?>
--FILE--
<?php

$file = dirname(__FILE__)."/002.dbf";
@unlink($file);

$fp = fopen($file, "w");
fclose($fp);

var_dump(dbase_open($file, -1));
var_dump(dbase_open($file, 1000));
var_dump(dbase_open($file, DBASE_RDONLY));
var_dump(dbase_open($file."nonex", DBASE_RDONLY));
var_dump(dbase_open("", DBASE_RDONLY));

@unlink($file);

$def = array(
  array("date",    "D"),
  array("name",    "C",  50),
  array("age",      "N",  3, 0),
  array("email",    "C", 128),
  array("ismember", "L")
);

var_dump(dbase_create($file, $def));
var_dump(dbase_open($file, DBASE_RDONLY));

@unlink($file);

echo "Done\n";
?>
--EXPECTF--
Warning: dbase_open(): Invalid access mode -1 in %s on line %d
bool(false)

Warning: dbase_open(): Invalid access mode 1000 in %s on line %d
bool(false)

Warning: dbase_open(): unable to open database %s in %s on line %d
bool(false)

Warning: dbase_open(): unable to open database %s in %s on line %d
bool(false)

Warning: dbase_open(): The filename cannot be empty. in %s on line %d
bool(false)
resource(%d) of type (dbase)
resource(%d) of type (dbase)
Done
--CLEAN--
<?php
$file = dirname(__FILE__)."/002.dbf";

unlink($file);
?>
tests/bug78070.phpt000064400000001672151731702000007770 0ustar00--TEST--
Bug #78070 (dbase functions may modify passed array)
--SKIPIF--
<?php
if (!extension_loaded('dbase')) die('skip dbase extension not available');
?>
--FILE--
<?php

class CharacterType
{
    public function __toString()
    {
        return 'C';
    }
}

$def = array(
    [17, new CharacterType, 10],
    ['foo', 'N', '5', '0', 1]
);
$dbh = dbase_create(__DIR__ . '/bug78070.dbf', $def, DBASE_TYPE_FOXPRO);
var_dump($def);
$record = [4, 42];
dbase_add_record($dbh, $record);
var_dump($record);
dbase_close($dbh);
?>
===DONE===
--EXPECTF--
array(2) {
  [0]=>
  array(3) {
    [0]=>
    int(17)
    [1]=>
    object(CharacterType)#%d (0) {
    }
    [2]=>
    int(10)
  }
  [1]=>
  array(5) {
    [0]=>
    string(3) "foo"
    [1]=>
    string(1) "N"
    [2]=>
    string(1) "5"
    [3]=>
    string(1) "0"
    [4]=>
    int(1)
  }
}
array(2) {
  [0]=>
  int(4)
  [1]=>
  int(42)
}
===DONE===
--CLEAN--
<?php
unlink(__DIR__ . '/bug78070.dbf');
?>