cvs: php-master-web /scripts ip-to-country
| From: | Gabor Hojtsy | Date: | Fri, 02 May 2003 09:45:52 +0000 |
| Subject: | cvs: php-master-web /scripts ip-to-country | ||
| Groups: | php.mirrors | ||
| Request: | Send a blank email to php-mirrors+get-17207@lists.php.net to get a copy of this message | ||
goba Fri May 2 05:45:52 2003 EDT
Modified files:
/php-master-web/scripts ip-to-country
Log:
Do a deep check on the format of the received
file, and only accept it, if it is in the format defined.
Otherwise reject the new data, and work with the
old one.
This also covers the "no updates" message handling.
Index: php-master-web/scripts/ip-to-country
diff -u php-master-web/scripts/ip-to-country:1.2 php-master-web/scripts/ip-to-country:1.3
--- php-master-web/scripts/ip-to-country:1.2 Thu May 1 15:01:42 2003
+++ php-master-web/scripts/ip-to-country Fri May 2 05:45:52 2003
@@ -7,6 +7,7 @@
{
// Files used / affected
$ipdbt = "ip-to-country.db~";
+ $ipdbc = "ip-to-country.dbr~";
$ipdb = "$root/backend/ip-to-country.db";
$ipidx = "$root/backend/ip-to-country.idx";
@@ -23,12 +24,80 @@
"?site=php.net&dbformat=1&lastupdate=" .
$lastmod, $ipdbt);
- // If the file contains more then a 'no updates' message,
- // then we expect it to be real ip-to-country data, and
- // move the file to the right place
- if (@filesize($ipdbt) > strlen("no updates")) {
- rename($ipdbt, $ipdb);
- } else { unlink($ipdbt); }
+ /*
+ The following code checks the structure of the file
+ received. If this is an updated data file, then it
+ should start with a given line and end with a given line,
+ and all lines inside should be 24 bytes long with a
+ specific format. If the data received is not in this
+ format, then we reject to replace the old file with this.
+ */
+
+ // Open temporary database for reading
+ $ipdbf = fopen($ipdbt, "r");
+ if (!$ipdbf) { die("Unable to open '$ipdbt' for reading"); }
+
+ // Open local rewritten database for writing
+ $ipdbcf = fopen($ipdbc, "w");
+ if (!$ipdbcf) { die("Unable to open '$ipdbc' for writing"); }
+
+ // Initial state is the first line and
+ // the file is expected to be ok
+ $state = 'firstline'; $fileok = TRUE;
+
+ // While we can read a line from the file
+ while (!feof($ipdbf) && ($line = fgets($ipdbf))) {
+
+ // Check the input depending on the state
+ switch ($state) {
+
+ // First line is defined, and after it we
+ // switch to the 'data' state
+ case 'firstline' :
+ if (trim($line) != "#Directi IP-to-Country Db: Start") {
+ $fileok = FALSE;
+ break 2;
+ } else { $state = 'data'; }
+ break;
+
+ // In the data state we either get the last line,
+ // or we get a data line containing 24 bytes, in
+ // which case we write it out to the local rewritten
+ // database
+ case 'data' :
+ if (trim($line) == "#Directi IP-to-Country Db: End") {
+ $state = 'lastline';
+ } elseif (!preg_match("!\\d{20}\\w{3}\n!", $line)) {
+ $fileok = FALSE;
+ break 2;
+ } else {
+ fwrite($ipdbcf, $line);
+ }
+ break;
+
+ // We should not receive any data after the last
+ // line, only whitespace is allowed
+ case 'lastline' :
+ if (strlen(trim($line)) > 0) {
+ $fileok = FALSE;
+ break 2;
+ }
+ break;
+ }
+ }
+ fclose($ipdbf);
+ fclose($ipdbcf);
+
+ // Remove the temp file. If the data is ok, move
+ // it to the destination, or else delete that too
+ unlink($ipdbt);
+ if (file_exists($ipdbc)) {
+ if (!$fileok) {
+ unlink($ipdbc);
+ } else {
+ rename($ipdbc, $ipdb);
+ }
+ }
create_ip_to_country_index($ipdb, $ipidx, $indexby);
}