summaryrefslogtreecommitdiff
path: root/ext/dbase
diff options
context:
space:
mode:
Diffstat (limited to 'ext/dbase')
-rw-r--r--ext/dbase/dbase.c113
-rw-r--r--ext/dbase/dbf_head.c31
-rw-r--r--ext/dbase/tests/001.phpt61
-rw-r--r--ext/dbase/tests/002.phpt54
4 files changed, 230 insertions, 29 deletions
diff --git a/ext/dbase/dbase.c b/ext/dbase/dbase.c
index f6c6f81c8..b905d89bd 100644
--- a/ext/dbase/dbase.c
+++ b/ext/dbase/dbase.c
@@ -16,7 +16,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: dbase.c,v 1.74.2.2 2006/01/01 12:50:05 sniper Exp $ */
+/* $Id: dbase.c,v 1.74.2.2.2.5 2006/10/10 23:01:23 tony2001 Exp $ */
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -132,6 +132,9 @@ PHP_FUNCTION(dbase_open)
if (Z_LVAL_PP(options) == 1) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot open %s in write-only mode", Z_STRVAL_PP(dbf_name));
RETURN_FALSE;
+ } else if (Z_LVAL_PP(options) < 0) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid access mode %ld", Z_LVAL_PP(options));
+ RETURN_FALSE;
}
if (PG(safe_mode) && (!php_checkuid(Z_STRVAL_PP(dbf_name), NULL, CHECKUID_CHECK_FILE_AND_DIR))) {
@@ -503,6 +506,13 @@ static void php_dbase_get_record(INTERNAL_FUNCTION_PARAMETERS, int assoc)
}
}
break;
+ case 'F':
+ if (!assoc) {
+ add_next_index_double(return_value, atof(str_value));
+ } else {
+ add_assoc_double(return_value, cur_f->db_fname, atof(str_value));
+ }
+ break;
case 'L': /* we used to FALL THROUGH, but now we check for T/Y and F/N
and insert 1 or 0, respectively. db_fdc is the number of
decimals, which we don't care about. 3/14/2001 LEW */
@@ -690,6 +700,9 @@ PHP_FUNCTION(dbase_create)
case 'D':
cur_f->db_flen = 8;
break;
+ case 'F':
+ cur_f->db_flen = 20;
+ break;
case 'N':
case 'C':
/* field length */
@@ -713,6 +726,8 @@ PHP_FUNCTION(dbase_create)
break;
default:
php_error_docref(NULL TSRMLS_CC, E_WARNING, "unknown field type '%c'", cur_f->db_type);
+ free_dbf_head(dbh);
+ RETURN_FALSE;
}
cur_f->db_foffset = rlen;
rlen += cur_f->db_flen;
@@ -728,21 +743,92 @@ PHP_FUNCTION(dbase_create)
}
/* }}} */
+/* {{{ arginfo */
+static
+ZEND_BEGIN_ARG_INFO(arginfo_dbase_open, 0)
+ ZEND_ARG_INFO(0, name)
+ ZEND_ARG_INFO(0, mode)
+ZEND_END_ARG_INFO()
+
+static
+ZEND_BEGIN_ARG_INFO(arginfo_dbase_close, 0)
+ ZEND_ARG_INFO(0, identifier)
+ZEND_END_ARG_INFO()
+
+static
+ZEND_BEGIN_ARG_INFO(arginfo_dbase_numrecords, 0)
+ ZEND_ARG_INFO(0, identifier)
+ZEND_END_ARG_INFO()
+
+static
+ZEND_BEGIN_ARG_INFO(arginfo_dbase_numfields, 0)
+ ZEND_ARG_INFO(0, identifier)
+ZEND_END_ARG_INFO()
+
+static
+ZEND_BEGIN_ARG_INFO(arginfo_dbase_pack, 0)
+ ZEND_ARG_INFO(0, identifier)
+ZEND_END_ARG_INFO()
+
+static
+ZEND_BEGIN_ARG_INFO(arginfo_dbase_add_record, 0)
+ ZEND_ARG_INFO(0, identifier)
+ ZEND_ARG_INFO(0, data) /* ARRAY_INFO(0, data, 0) */
+ZEND_END_ARG_INFO()
+
+static
+ZEND_BEGIN_ARG_INFO(arginfo_dbase_replace_record, 0)
+ ZEND_ARG_INFO(0, identifier)
+ ZEND_ARG_INFO(0, data) /* ARRAY_INFO(0, data, 0) */
+ ZEND_ARG_INFO(0, recnum)
+ZEND_END_ARG_INFO()
+
+static
+ZEND_BEGIN_ARG_INFO(arginfo_dbase_delete_record, 0)
+ ZEND_ARG_INFO(0, identifier)
+ ZEND_ARG_INFO(0, record)
+ZEND_END_ARG_INFO()
+
+static
+ZEND_BEGIN_ARG_INFO(arginfo_dbase_get_record, 0)
+ ZEND_ARG_INFO(0, identifier)
+ ZEND_ARG_INFO(0, record)
+ZEND_END_ARG_INFO()
+
+static
+ZEND_BEGIN_ARG_INFO(arginfo_dbase_get_record_with_names, 0)
+ ZEND_ARG_INFO(0, identifier)
+ ZEND_ARG_INFO(0, record)
+ZEND_END_ARG_INFO()
+
+static
+ZEND_BEGIN_ARG_INFO(arginfo_dbase_create, 0)
+ ZEND_ARG_INFO(0, filename)
+ ZEND_ARG_INFO(0, fields) /* ARRAY_INFO(0, fields, 0) */
+ZEND_END_ARG_INFO()
+
+static
+ZEND_BEGIN_ARG_INFO(arginfo_dbase_get_header_info, 0)
+ ZEND_ARG_INFO(0, database_handle)
+ZEND_END_ARG_INFO()
+
+/* }}} */
+
/* {{{ dbase_functions[]
*/
zend_function_entry dbase_functions[] = {
- PHP_FE(dbase_open, NULL)
- PHP_FE(dbase_create, NULL)
- PHP_FE(dbase_close, NULL)
- PHP_FE(dbase_numrecords, NULL)
- PHP_FE(dbase_numfields, NULL)
- PHP_FE(dbase_add_record, NULL)
- PHP_FE(dbase_replace_record, NULL)
- PHP_FE(dbase_get_record, NULL)
- PHP_FE(dbase_get_record_with_names, NULL)
- PHP_FE(dbase_delete_record, NULL)
- PHP_FE(dbase_pack, NULL)
- PHP_FE(dbase_get_header_info, NULL)
+ PHP_FE(dbase_open, arginfo_dbase_open)
+ PHP_FE(dbase_create, arginfo_dbase_create)
+ PHP_FE(dbase_close, arginfo_dbase_close)
+ PHP_FE(dbase_numrecords, arginfo_dbase_numrecords)
+ PHP_FE(dbase_numfields, arginfo_dbase_numfields)
+ PHP_FE(dbase_add_record, arginfo_dbase_add_record)
+ PHP_FE(dbase_replace_record, arginfo_dbase_replace_record)
+ PHP_FE(dbase_get_record, arginfo_dbase_get_record)
+ PHP_FE(dbase_get_record_with_names, arginfo_dbase_get_record_with_names)
+ PHP_FE(dbase_delete_record, arginfo_dbase_delete_record)
+ PHP_FE(dbase_pack, arginfo_dbase_pack)
+ PHP_FE(dbase_get_header_info, arginfo_dbase_get_header_info)
{NULL, NULL, NULL}
};
/* }}} */
@@ -789,6 +875,7 @@ PHP_FUNCTION(dbase_get_header_info)
case 'N': add_assoc_string(row, "type", "number", 1); break;
case 'L': add_assoc_string(row, "type", "boolean", 1); break;
case 'M': add_assoc_string(row, "type", "memo", 1); break;
+ case 'F': add_assoc_string(row, "type", "float", 1); break;
default: add_assoc_string(row, "type", "unknown", 1); break;
}
diff --git a/ext/dbase/dbf_head.c b/ext/dbase/dbf_head.c
index f45a99cfd..42935c2ea 100644
--- a/ext/dbase/dbf_head.c
+++ b/ext/dbase/dbf_head.c
@@ -26,10 +26,14 @@ dbhead_t *get_dbf_head(int fd)
if ((dbh = (dbhead_t *)calloc(1, sizeof(dbhead_t))) == NULL)
return NULL;
- if (lseek(fd, 0, 0) < 0)
+ if (lseek(fd, 0, 0) < 0) {
+ free(dbh);
return NULL;
- if ((ret = read(fd, &dbhead, sizeof(dbhead))) < 0)
+ }
+ if ((ret = read(fd, &dbhead, sizeof(dbhead))) <= 0) {
+ free(dbh);
return NULL;
+ }
/* build in core info */
dbh->db_fd = fd;
@@ -54,6 +58,7 @@ dbhead_t *get_dbf_head(int fd)
if (gf_retval < 0) {
free_dbf_head(dbh);
+ free(tdbf);
return NULL;
}
if (gf_retval != 2 ) {
@@ -89,7 +94,7 @@ void free_dbf_head(dbhead_t *dbh)
free(cur_f->db_format);
}
}
-
+
free(dbf);
free(dbh);
}
@@ -119,7 +124,7 @@ int put_dbf_head(dbhead_t *dbh)
if (lseek(fd, 0, 0) < 0)
return -1;
- if ((ret = write(fd, &dbhead, sizeof(dbhead))) < 0)
+ if ((ret = write(fd, &dbhead, sizeof(dbhead))) <= 0)
return -1;
return ret;
}
@@ -132,7 +137,7 @@ int get_dbf_field(dbhead_t *dbh, dbfield_t *dbf)
struct dbf_dfield dbfield;
int ret;
- if ((ret = read(dbh->db_fd, &dbfield, sizeof(dbfield))) < 0) {
+ if ((ret = read(dbh->db_fd, &dbfield, sizeof(dbfield))) <= 0) {
return ret;
}
@@ -148,6 +153,7 @@ int get_dbf_field(dbhead_t *dbh, dbfield_t *dbf)
dbf->db_type = dbfield.dbf_type;
switch (dbf->db_type) {
case 'N':
+ case 'F':
dbf->db_flen = dbfield.dbf_flen[0];
dbf->db_fdc = dbfield.dbf_flen[1];
break;
@@ -191,7 +197,7 @@ int put_dbf_field(dbhead_t *dbh, dbfield_t *dbf)
}
/* now write it out to disk */
- if ((ret = write(dbh->db_fd, &dbfield, sizeof(dbfield))) < 0) {
+ if ((ret = write(dbh->db_fd, &dbfield, sizeof(dbfield))) <= 0) {
return ret;
}
return 1;
@@ -231,6 +237,7 @@ char *get_dbf_f_fmt(dbfield_t *dbf)
case 'N':
case 'L':
case 'D':
+ case 'F':
sprintf(format, "%%%ds", dbf->db_flen);
break;
case 'M':
@@ -250,22 +257,14 @@ dbhead_t *dbf_open(char *dp, int o_flags TSRMLS_DC)
cp = dp;
if ((fd = VCWD_OPEN(cp, o_flags|O_BINARY)) < 0) {
- cp = (char *)malloc(MAXPATHLEN); /* So where does this get free()'d? -RL */
- strncpy(cp, dp, MAXPATHLEN-5); strcat(cp, ".dbf");
- if ((fd = VCWD_OPEN(cp, o_flags)) < 0) {
- free(cp);
- perror("open");
- return NULL;
- }
+ return NULL;
}
if ((dbh = get_dbf_head(fd)) == NULL) {
- fprintf(stderr, "Unable to get header\n");
return NULL;
}
- dbh->db_name = cp;
+
dbh->db_cur_rec = 0;
-
return dbh;
}
diff --git a/ext/dbase/tests/001.phpt b/ext/dbase/tests/001.phpt
new file mode 100644
index 000000000..51a448870
--- /dev/null
+++ b/ext/dbase/tests/001.phpt
@@ -0,0 +1,61 @@
+--TEST--
+dbase_create() tests
+--SKIPIF--
+<?php if (!extension_loaded("dbase")) print "skip"; ?>
+--FILE--
+<?php
+
+$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(dbase_create($file, $fields));
+ @unlink($file);
+}
+
+var_dump(dbase_create($file, -1));
+@unlink($file);
+
+var_dump(dbase_create("", ""));
+
+echo "Done\n";
+?>
+--EXPECTF--
+int(%d)
+
+Warning: dbase_create(): unknown field type 'E' in %s on line %d
+bool(false)
+
+Warning: dbase_create(): unknown field type '-' in %s on line %d
+bool(false)
+int(%d)
+
+Warning: dbase_create(): expected field name as first element of list in field 0 in %s on line %d
+bool(false)
+int(%d)
+
+Warning: dbase_create(): Expected array as second parameter in %s on line %d
+bool(false)
+
+Warning: dbase_create(): Expected array as second parameter in %s on line %d
+bool(false)
+Done
diff --git a/ext/dbase/tests/002.phpt b/ext/dbase/tests/002.phpt
new file mode 100644
index 000000000..5c866443f
--- /dev/null
+++ b/ext/dbase/tests/002.phpt
@@ -0,0 +1,54 @@
+--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, 0));
+var_dump(dbase_open($file."nonex", 0));
+var_dump(dbase_open("", 0));
+
+@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, 0));
+
+@unlink($file);
+
+echo "Done\n";
+?>
+--EXPECTF--
+Warning: dbase_open(): Invalid access mode -1 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(): unable to open database %s in %s on line %d
+bool(false)
+
+Warning: dbase_open(): unable to open database in %s on line %d
+bool(false)
+int(%d)
+int(%d)
+Done