default services conflit ?

This commit is contained in:
armansansd
2022-04-27 11:30:43 +02:00
parent 28190a5749
commit 8bb1064a3b
8132 changed files with 900138 additions and 426 deletions

View File

@@ -0,0 +1,2 @@
github: [mrook]
patreon: michielrook

View File

@@ -0,0 +1,11 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
version: 2
updates:
- package-ecosystem: "composer" # See documentation for possible values
directory: "/" # Location of package manifests
schedule:
interval: "daily"

View File

@@ -0,0 +1,40 @@
on:
push:
branches:
- master
pull_request:
jobs:
test:
runs-on: ${{ matrix.operating-system }}
strategy:
fail-fast: false
matrix:
operating-system: [ ubuntu-latest ]
php: [ '5.4', '5.5', '5.6', '7.0', '7.1', '7.2', '7.3', '7.4', '8.0' ]
dependencies: [ 'locked' ]
name: PHP ${{ matrix.php }} on ${{ matrix.operating-system }} with ${{ matrix.dependencies }} dependencies
steps:
- uses: actions/checkout@v2
name: Checkout repository
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
- uses: ramsey/composer-install@v1
with:
dependency-versions: ${{ matrix.dependencies }}
- name: Install PEAR
run: |
sudo apt-get install php-pear
- name: Run tests
run: |
sudo pear install -f package.xml
pear version
pear run-tests -qr tests/ || { cat run-tests.log; for i in `find tests/ -name '*.out'`; do echo "$i"; cat "$i"; done; exit 1; }

15
old.vendor/pear/archive_tar/.gitignore vendored Normal file
View File

@@ -0,0 +1,15 @@
# composer related
composer.lock
composer.phar
vendor
# IDE
.idea
# eclipse
.buildpath
.project
.settings
# pear
.tarballs
*.tgz
# phpunit
build

View File

@@ -0,0 +1,29 @@
sudo: false
language: php
matrix:
fast_finish: true
allow_failures:
- php: nightly
include:
- php: 5.2
dist: precise
- php: 5.3
dist: precise
- php: 5.4
dist: trusty
- php: 5.5
dist: trusty
- php: 5.6
- php: 7.0
- php: 7.1
- php: 7.2
- php: 7.3
- php: 7.4
- php: nightly
install:
# - pear upgrade --force --alldeps pear/pear
- pear install -f package.xml
script:
- pear version
- pear run-tests -qr tests/
- for i in `find tests/ -name '*.out'`; do echo "$i"; cat "$i"; done

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,34 @@
Archive_Tar
==========
![.github/workflows/build.yml](https://github.com/pear/Archive_Tar/workflows/.github/workflows/build.yml/badge.svg)
This package provides handling of tar files in PHP.
It supports creating, listing, extracting and adding to tar files.
Gzip support is available if PHP has the zlib extension built-in or
loaded. Bz2 compression is also supported with the bz2 extension loaded.
Also Lzma2 compressed archives are supported with xz extension.
This package is hosted at http://pear.php.net/package/Archive_Tar
Please report all new issues via the PEAR bug tracker.
Pull requests are welcome!
Testing, building
-----------------
To test, run either
$ phpunit tests/
or
$ pear run-tests -r
To build, simply
$ pear package
To install from scratch
$ pear install package.xml
To upgrade
$ pear upgrade -f package.xml

View File

@@ -0,0 +1,54 @@
{
"name": "pear/archive_tar",
"description": "Tar file management class with compression support (gzip, bzip2, lzma2)",
"type": "library",
"keywords": [
"archive",
"tar"
],
"homepage": "https://github.com/pear/Archive_Tar",
"license": "BSD-3-Clause",
"authors": [
{
"name": "Vincent Blavet",
"email": "vincent@phpconcept.net"
},
{
"name": "Greg Beaver",
"email": "greg@chiaraquartet.net"
},
{
"name": "Michiel Rook",
"email": "mrook@php.net"
}
],
"require": {
"php": ">=5.2.0",
"pear/pear-core-minimal": "^1.10.0alpha2"
},
"suggest": {
"ext-zlib": "Gzip compression support.",
"ext-bz2": "Bz2 compression support.",
"ext-xz": "Lzma2 compression support."
},
"autoload": {
"psr-0": {
"Archive_Tar": ""
}
},
"include-path": [
"./"
],
"support": {
"issues": "http://pear.php.net/bugs/search.php?cmd=display&package_name[]=Archive_Tar",
"source": "https://github.com/pear/Archive_Tar"
},
"require-dev": {
"phpunit/phpunit": "*"
},
"extra": {
"branch-alias": {
"dev-master": "1.4.x-dev"
}
}
}

View File

@@ -0,0 +1,475 @@
Documentation for class Archive_Tar
===================================
Last update : 2001-08-15
Overview :
----------
The Archive_Tar class helps in creating and managing GNU TAR format
files compressed by GNU ZIP or not.
The class offers basic functions like creating an archive, adding
files in the archive, extracting files from the archive and listing
the archive content.
It also provide advanced functions that allow the adding and
extraction of files with path manipulation.
Sample :
--------
// ----- Creating the object (uncompressed archive)
$tar_object = new Archive_Tar("tarname.tar");
$tar_object->setErrorHandling(PEAR_ERROR_PRINT);
// ----- Creating the archive
$v_list[0]="file.txt";
$v_list[1]="data/";
$v_list[2]="file.log";
$tar_object->create($v_list);
// ----- Adding files
$v_list[0]="dev/file.txt";
$v_list[1]="dev/data/";
$v_list[2]="log/file.log";
$tar_object->add($v_list);
// ----- Adding more files
$tar_object->add("release/newfile.log release/readme.txt");
// ----- Listing the content
if (($v_list = $tar_object->listContent()) != 0)
for ($i=0; $i<sizeof($v_list); $i++)
{
echo "Filename :'".$v_list[$i][filename]."'<br>";
echo " .size :'".$v_list[$i][size]."'<br>";
echo " .mtime :'".$v_list[$i][mtime]."' (".date("l dS of F Y h:i:s A", $v_list[$i][mtime]).")<br>";
echo " .mode :'".$v_list[$i][mode]."'<br>";
echo " .uid :'".$v_list[$i][uid]."'<br>";
echo " .gid :'".$v_list[$i][gid]."'<br>";
echo " .typeflag :'".$v_list[$i][typeflag]."'<br>";
}
// ----- Extracting the archive in directory "install"
$tar_object->extract("install");
Public arguments :
------------------
None
Public Methods :
----------------
Method : Archive_Tar($p_tarname, $compress = null)
Description :
Archive_Tar Class constructor. This flavour of the constructor only
declare a new Archive_Tar object, identifying it by the name of the
tar file.
If the compress argument is set the tar will be read or created as a
gzip or bz2 compressed TAR file.
Arguments :
$p_tarname : A valid filename for the tar archive file.
$p_compress : can be null, 'gz' or 'bz2'. For
compatibility reason it can also be true. This
parameter indicates if gzip or bz2 compression
is required.
Return value :
The Archive_Tar object.
Sample :
$tar_object = new Archive_Tar("tarname.tar");
$tar_object_compressed = new Archive_Tar("tarname.tgz", true);
How it works :
Initialize the object.
Method : create($p_filelist)
Description :
This method creates the archive file and add the files / directories
that are listed in $p_filelist.
If the file already exists and is writable, it is replaced by the
new tar. It is a create and not an add. If the file exists and is
read-only or is a directory it is not replaced. The method return
false and a PEAR error text.
The $p_filelist parameter can be an array of string, each string
representing a filename or a directory name with their path if
needed. It can also be a single string with names separated by a
single blank.
See also createModify() method for more details.
Arguments :
$p_filelist : An array of filenames and directory names, or a single
string with names separated by a single blank space.
Return value :
true on success, false on error.
Sample 1 :
$tar_object = new Archive_Tar("tarname.tar");
$tar_object->setErrorHandling(PEAR_ERROR_PRINT); // Optional error handling
$v_list[0]="file.txt";
$v_list[1]="data/"; (Optional '/' at the end)
$v_list[2]="file.log";
$tar_object->create($v_list);
Sample 2 :
$tar_object = new Archive_Tar("tarname.tar");
$tar_object->setErrorHandling(PEAR_ERROR_PRINT); // Optional error handling
$tar_object->create("file.txt data/ file.log");
How it works :
Just calling the createModify() method with the right parameters.
Method : createModify($p_filelist, $p_add_dir, $p_remove_dir = "")
Description :
This method creates the archive file and add the files / directories
that are listed in $p_filelist.
If the file already exists and is writable, it is replaced by the
new tar. It is a create and not an add. If the file exists and is
read-only or is a directory it is not replaced. The method return
false and a PEAR error text.
The $p_filelist parameter can be an array of string, each string
representing a filename or a directory name with their path if
needed. It can also be a single string with names separated by a
single blank.
The path indicated in $p_remove_dir will be removed from the
memorized path of each file / directory listed when this path
exists. By default nothing is removed (empty path "")
The path indicated in $p_add_dir will be added at the beginning of
the memorized path of each file / directory listed. However it can
be set to empty "". The adding of a path is done after the removing
of path.
The path add/remove ability enables the user to prepare an archive
for extraction in a different path than the origin files are.
See also addModify() method for file adding properties.
Arguments :
$p_filelist : An array of filenames and directory names, or a single
string with names separated by a single blank space.
$p_add_dir : A string which contains a path to be added to the
memorized path of each element in the list.
$p_remove_dir : A string which contains a path to be removed from
the memorized path of each element in the list, when
relevant.
Return value :
true on success, false on error.
Sample 1 :
$tar_object = new Archive_Tar("tarname.tar");
$tar_object->setErrorHandling(PEAR_ERROR_PRINT); // Optional error handling
$v_list[0]="file.txt";
$v_list[1]="data/"; (Optional '/' at the end)
$v_list[2]="file.log";
$tar_object->createModify($v_list, "install");
// files are stored in the archive as :
// install/file.txt
// install/data
// install/data/file1.txt
// install/data/... all the files and sub-dirs of data/
// install/file.log
Sample 2 :
$tar_object = new Archive_Tar("tarname.tar");
$tar_object->setErrorHandling(PEAR_ERROR_PRINT); // Optional error handling
$v_list[0]="dev/file.txt";
$v_list[1]="dev/data/"; (Optional '/' at the end)
$v_list[2]="log/file.log";
$tar_object->createModify($v_list, "install", "dev");
// files are stored in the archive as :
// install/file.txt
// install/data
// install/data/file1.txt
// install/data/... all the files and sub-dirs of data/
// install/log/file.log
How it works :
Open the file in write mode (erasing the existing one if one),
call the _addList() method for adding the files in an empty archive,
add the tar footer (512 bytes block), close the tar file.
Method : addModify($p_filelist, $p_add_dir, $p_remove_dir="")
Description :
This method add the files / directories listed in $p_filelist at the
end of the existing archive. If the archive does not yet exists it
is created.
The $p_filelist parameter can be an array of string, each string
representing a filename or a directory name with their path if
needed. It can also be a single string with names separated by a
single blank.
The path indicated in $p_remove_dir will be removed from the
memorized path of each file / directory listed when this path
exists. By default nothing is removed (empty path "")
The path indicated in $p_add_dir will be added at the beginning of
the memorized path of each file / directory listed. However it can
be set to empty "". The adding of a path is done after the removing
of path.
The path add/remove ability enables the user to prepare an archive
for extraction in a different path than the origin files are.
If a file/dir is already in the archive it will only be added at the
end of the archive. There is no update of the existing archived
file/dir. However while extracting the archive, the last file will
replace the first one. This results in a none optimization of the
archive size.
If a file/dir does not exist the file/dir is ignored. However an
error text is send to PEAR error.
If a file/dir is not readable the file/dir is ignored. However an
error text is send to PEAR error.
If the resulting filename/dirname (after the add/remove option or
not) string is greater than 99 char, the file/dir is
ignored. However an error text is send to PEAR error.
Arguments :
$p_filelist : An array of filenames and directory names, or a single
string with names separated by a single blank space.
$p_add_dir : A string which contains a path to be added to the
memorized path of each element in the list.
$p_remove_dir : A string which contains a path to be removed from
the memorized path of each element in the list, when
relevant.
Return value :
true on success, false on error.
Sample 1 :
$tar_object = new Archive_Tar("tarname.tar");
[...]
$v_list[0]="dev/file.txt";
$v_list[1]="dev/data/"; (Optional '/' at the end)
$v_list[2]="log/file.log";
$tar_object->addModify($v_list, "install");
// files are stored in the archive as :
// install/file.txt
// install/data
// install/data/file1.txt
// install/data/... all the files and sub-dirs of data/
// install/file.log
Sample 2 :
$tar_object = new Archive_Tar("tarname.tar");
[...]
$v_list[0]="dev/file.txt";
$v_list[1]="dev/data/"; (Optional '/' at the end)
$v_list[2]="log/file.log";
$tar_object->addModify($v_list, "install", "dev");
// files are stored in the archive as :
// install/file.txt
// install/data
// install/data/file1.txt
// install/data/... all the files and sub-dirs of data/
// install/log/file.log
How it works :
If the archive does not exists it create it and add the files.
If the archive does exists and is not compressed, it open it, jump
before the last empty 512 bytes block (tar footer) and add the files
at this point.
If the archive does exists and is compressed, a temporary copy file
is created. This temporary file is then 'gzip' read block by block
until the last empty block. The new files are then added in the
compressed file.
The adding of files is done by going through the file/dir list,
adding files per files, in a recursive way through the
directory. Each time a path need to be added/removed it is done
before writing the file header in the archive.
Method : add($p_filelist)
Description :
This method add the files / directories listed in $p_filelist at the
end of the existing archive. If the archive does not yet exists it
is created.
The $p_filelist parameter can be an array of string, each string
representing a filename or a directory name with their path if
needed. It can also be a single string with names separated by a
single blank.
See addModify() method for details and limitations.
Arguments :
$p_filelist : An array of filenames and directory names, or a single
string with names separated by a single blank space.
Return value :
true on success, false on error.
Sample 1 :
$tar_object = new Archive_Tar("tarname.tar");
[...]
$v_list[0]="dev/file.txt";
$v_list[1]="dev/data/"; (Optional '/' at the end)
$v_list[2]="log/file.log";
$tar_object->add($v_list);
Sample 2 :
$tar_object = new Archive_Tar("tarname.tgz", true);
[...]
$v_list[0]="dev/file.txt";
$v_list[1]="dev/data/"; (Optional '/' at the end)
$v_list[2]="log/file.log";
$tar_object->add($v_list);
How it works :
Simply call the addModify() method with the right parameters.
Method : addString($p_filename, $p_string, $p_datetime, $p_params)
Description :
This method add a single string as a file at the
end of the existing archive. If the archive does not yet exists it
is created.
Arguments :
$p_filename : A string which contains the full filename path
that will be associated with the string.
$p_string : The content of the file added in the archive.
$p_datetime : (Optional) Timestamp of the file (default = now)
$p_params : (Optional) Various file metadata:
stamp - As above, timestamp of the file
mode - UNIX-style permissions (default 0600)
type - Is this a regular file or link (see TAR
format spec for how to create a hard/symlink)
uid - UNIX-style user ID (default 0 = root)
gid - UNIX-style group ID (default 0 = root)
Return value :
true on success, false on error.
Sample 1 :
$v_archive = & new Archive_Tar($p_filename);
$v_archive->setErrorHandling(PEAR_ERROR_PRINT);
$v_result = $v_archive->addString('data/test.txt', 'This is the text of the string');
$v_result = $v_archive->addString(
'data/test.sh',
"#!/bin/sh\necho 'Hello'",
time(),
array( "mode" => 0755, "uid" => 34 )
);
Method : extract($p_path = "")
Description :
This method extract all the content of the archive in the directory
indicated by $p_path.If $p_path is optional, if not set the archive
is extracted in the current directory.
While extracting a file, if the directory path does not exists it is
created.
See extractModify() for details and limitations.
Arguments :
$p_path : Optional path where the files/dir need to by extracted.
Return value :
true on success, false on error.
Sample :
$tar_object = new Archive_Tar("tarname.tar");
$tar_object->extract();
How it works :
Simply call the extractModify() method with appropriate parameters.
Method : extractModify($p_path, $p_remove_path)
Description :
This method extract all the content of the archive in the directory
indicated by $p_path. When relevant the memorized path of the
files/dir can be modified by removing the $p_remove_path path at the
beginning of the file/dir path.
While extracting a file, if the directory path does not exists it is
created.
While extracting a file, if the file already exists it is replaced
without looking for last modification date.
While extracting a file, if the file already exists and is write
protected, the extraction is aborted.
While extracting a file, if a directory with the same name already
exists, the extraction is aborted.
While extracting a directory, if a file with the same name already
exists, the extraction is aborted.
While extracting a file/directory if the destination directory exist
and is write protected, or does not exist but can not be created,
the extraction is aborted.
If after extraction an extracted file does not show the correct
stored file size, the extraction is aborted.
When the extraction is aborted, a PEAR error text is set and false
is returned. However the result can be a partial extraction that may
need to be manually cleaned.
Arguments :
$p_path : The path of the directory where the files/dir need to by
extracted.
$p_remove_path : Part of the memorized path that can be removed if
present at the beginning of the file/dir path.
Return value :
true on success, false on error.
Sample :
// Imagine tarname.tar with files :
// dev/data/file.txt
// dev/data/log.txt
// readme.txt
$tar_object = new Archive_Tar("tarname.tar");
$tar_object->extractModify("install", "dev");
// Files will be extracted there :
// install/data/file.txt
// install/data/log.txt
// install/readme.txt
How it works :
Open the archive and call a more generic function that can extract
only a part of the archive or all the archive.
See extractList() method for more details.
Method : extractInString($p_filename)
Description :
This method extract from the archive one file identified by $p_filename.
The return value is a string with the file content, or NULL on error.
Arguments :
$p_filename : The path of the file to extract in a string.
Return value :
a string with the file content or NULL.
Sample :
// Imagine tarname.tar with files :
// dev/data/file.txt
// dev/data/log.txt
// dev/readme.txt
$v_archive = & new Archive_Tar('tarname.tar');
$v_archive->setErrorHandling(PEAR_ERROR_PRINT);
$v_string = $v_archive->extractInString('dev/readme.txt');
echo $v_string;
Method : listContent()
Description :
This method returns an array of arrays that describe each
file/directory present in the archive.
The array is not sorted, so it show the position of the file in the
archive.
The file informations are :
$file[filename] : Name and path of the file/dir.
$file[mode] : File permissions (result of fileperms())
$file[uid] : user id
$file[gid] : group id
$file[size] : filesize
$file[mtime] : Last modification time (result of filemtime())
$file[typeflag] : "" for file, "5" for directory
Arguments :
Return value :
An array of arrays or 0 on error.
Sample :
$tar_object = new Archive_Tar("tarname.tar");
if (($v_list = $tar_object->listContent()) != 0)
for ($i=0; $i<sizeof($v_list); $i++)
{
echo "Filename :'".$v_list[$i][filename]."'<br>";
echo " .size :'".$v_list[$i][size]."'<br>";
echo " .mtime :'".$v_list[$i][mtime]."' (".
date("l dS of F Y h:i:s A", $v_list[$i][mtime]).")<br>";
echo " .mode :'".$v_list[$i][mode]."'<br>";
echo " .uid :'".$v_list[$i][uid]."'<br>";
echo " .gid :'".$v_list[$i][gid]."'<br>";
echo " .typeflag :'".$v_list[$i][typeflag]."'<br>";
}
How it works :
Call the same function as an extract however with a flag to only go
through the archive without extracting the files.
Method : extractList($p_filelist, $p_path = "", $p_remove_path = "")
Description :
This method extract from the archive only the files indicated in the
$p_filelist. These files are extracted in the current directory or
in the directory indicated by the optional $p_path parameter.
If indicated the $p_remove_path can be used in the same way as it is
used in extractModify() method.
Arguments :
$p_filelist : An array of filenames and directory names, or a single
string with names separated by a single blank space.
$p_path : The path of the directory where the files/dir need to by
extracted.
$p_remove_path : Part of the memorized path that can be removed if
present at the beginning of the file/dir path.
Return value :
true on success, false on error.
Sample :
// Imagine tarname.tar with files :
// dev/data/file.txt
// dev/data/log.txt
// readme.txt
$tar_object = new Archive_Tar("tarname.tar");
$tar_object->extractList("dev/data/file.txt readme.txt", "install",
"dev");
// Files will be extracted there :
// install/data/file.txt
// install/readme.txt
How it works :
Go through the archive and extract only the files present in the
list.

View File

@@ -0,0 +1,712 @@
<?xml version="1.0" encoding="UTF-8"?>
<package packagerversion="1.9.4" version="2.0" xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0 http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.0 http://pear.php.net/dtd/package-2.0.xsd">
<name>Archive_Tar</name>
<channel>pear.php.net</channel>
<summary>Tar file management class</summary>
<description>This class provides handling of tar files in PHP.
It supports creating, listing, extracting and adding to tar files.
Gzip support is available if PHP has the zlib extension built-in or
loaded. Bz2 compression is also supported with the bz2 extension loaded.
Also Lzma2 compressed archives are supported with xz extension.</description>
<lead>
<name>Vincent Blavet</name>
<user>vblavet</user>
<email>vincent@phpconcept.net</email>
<active>no</active>
</lead>
<lead>
<name>Greg Beaver</name>
<user>cellog</user>
<email>greg@chiaraquartet.net</email>
<active>no</active>
</lead>
<lead>
<name>Michiel Rook</name>
<user>mrook</user>
<email>mrook@php.net</email>
<active>yes</active>
</lead>
<helper>
<name>Stig Bakken</name>
<user>ssb</user>
<email>stig@php.net</email>
<active>no</active>
</helper>
<date>2021-07-20</date>
<time>18:00:00</time>
<version>
<release>1.4.14</release>
<api>1.4.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<license uri="http://www.opensource.org/licenses/bsd-license.php">New BSD License</license>
<notes>
* Properly fix symbolic link path traversal (CVE-2021-32610)
</notes>
<contents>
<dir name="/">
<dir name="Archive">
<file baseinstalldir="/" name="Tar.php" role="php" />
</dir> <!-- /Archive -->
<dir name="docs">
<file baseinstalldir="/" name="Archive_Tar.txt" role="doc" />
</dir> <!-- /docs -->
</dir> <!-- / -->
</contents>
<compatible>
<name>PEAR</name>
<channel>pear.php.net</channel>
<min>1.8.0</min>
<max>1.10.10</max>
</compatible>
<dependencies>
<required>
<php>
<min>5.2.0</min>
</php>
<pearinstaller>
<min>1.9.0</min>
</pearinstaller>
</required>
</dependencies>
<phprelease />
<changelog>
<release>
<version>
<release>1.4.13</release>
<api>1.4.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<date>2021-02-16</date>
<license uri="http://www.opensource.org/licenses/bsd-license.php">New BSD License</license>
<notes>
* Fix Bug #27010: Relative symlinks failing (out-of path file extraction) [mrook]
</notes>
</release>
<release>
<version>
<release>1.4.12</release>
<api>1.4.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<date>2021-01-18</date>
<license uri="http://www.opensource.org/licenses/bsd-license.php">New BSD License</license>
<notes>
* Fix Bug #27008: Symlink out-of-path write vulnerability (CVE-2020-36193) [mrook]
</notes>
</release>
<release>
<version>
<release>1.4.11</release>
<api>1.4.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<date>2020-11-19</date>
<license uri="http://www.opensource.org/licenses/bsd-license.php">New BSD License</license>
<notes>
* Fix Bug #27002: Filename manipulation vulnerabilities (CVE-2020-28948 / CVE-2020-28949) [mrook]
</notes>
</release>
<release>
<version>
<release>1.4.10</release>
<api>1.4.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<date>2020-09-15</date>
<license uri="http://www.opensource.org/licenses/bsd-license.php">New BSD License</license>
<notes>
* Fix block padding when the file buffer length is a multiple of 512 and smaller than Archive_Tar buffer length
* Don&apos;t try to copy username/groupname in chroot jail
</notes>
</release>
<release>
<version>
<release>1.4.9</release>
<api>1.4.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<date>2019-12-04</date>
<license uri="http://www.opensource.org/licenses/bsd-license.php">New BSD License</license>
<notes>
* Implement Feature #23861: Add option to disallow symlinks [mrook]
</notes>
</release>
<release>
<version>
<release>1.4.8</release>
<api>1.4.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<date>2019-10-21</date>
<license uri="http://www.opensource.org/licenses/bsd-license.php">New BSD License</license>
<notes>
* Fix Bug #23852: PHP 7.4 - Archive_Tar-&gt;_readHeader throws deprecation [mrook]
</notes>
</release>
<release>
<version>
<release>1.4.7</release>
<api>1.4.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<date>2019-04-08</date>
<license uri="http://www.opensource.org/licenses/bsd-license.php">New BSD License</license>
<notes>
* Improved performance by increasing read buffer size
</notes>
</release>
<release>
<version>
<release>1.4.6</release>
<api>1.4.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<date>2019-02-01</date>
<license uri="http://www.opensource.org/licenses/bsd-license.php">New BSD License</license>
<notes>
* Improve path traversal detection for forward and backward slashes
</notes>
</release>
<release>
<version>
<release>1.4.5</release>
<api>1.4.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<date>2019-01-02</date>
<license uri="http://www.opensource.org/licenses/bsd-license.php">New BSD License</license>
<notes>
* Fix Bug #23788: Relative symlinks are broken [mrook]
</notes>
</release>
<release>
<version>
<release>1.4.4</release>
<api>1.4.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<date>2018-12-20</date>
<license uri="http://www.opensource.org/licenses/bsd-license.php">New BSD License</license>
<notes>
* Fix Bug #21058: Long symlinks are not supported [mrook]
* Fix Bug #23782: Prevent phar:// files from being extracted [mrook]
</notes>
</release>
<release>
<version>
<release>1.4.3</release>
<api>1.4.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<date>2017-06-11</date>
<license uri="http://www.opensource.org/licenses/bsd-license.php">New BSD License</license>
<notes>
* Fix Bug #21218: Cannot use result of built-in function in write context in PHP
7.2.0alpha1 [mrook]
</notes>
</release>
<release>
<version>
<release>1.4.2</release>
<api>1.4.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<date>2016-02-25</date>
<license uri="http://www.opensource.org/licenses/bsd-license.php">New BSD License</license>
<notes>
* Fix reading of archives with files &gt; 8GB
* Performance optimizations
* Do not try to call require_once on PEAR.php if it has already been loaded by the autoloader
</notes>
</release>
<release>
<version>
<release>1.4.1</release>
<api>1.4.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<date>2015-08-05</date>
<license uri="http://www.opensource.org/licenses/bsd-license.php">New BSD License</license>
<notes>
* Update composer.json to use pear-core-minimal 1.10.0alpha2
</notes>
</release>
<release>
<version>
<release>1.4.0</release>
<api>1.4.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<date>2015-07-20</date>
<license uri="http://www.opensource.org/licenses/bsd-license.php">New BSD License</license>
<notes>
* Add support for PHP 7
* Drop support for PHP 4
* Add visibility declarations to methods and properties
</notes>
</release>
<release>
<version>
<release>1.3.16</release>
<api>1.3.1</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<date>2015-04-14</date>
<license uri="http://www.opensource.org/licenses/bsd-license.php">New BSD License</license>
<notes>
* Fix Bug #20514: invalid package.xml; not installable with pyrus [mrook]
</notes>
</release>
<release>
<version>
<release>1.3.15</release>
<api>1.3.1</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<date>2015-03-05</date>
<license uri="http://www.opensource.org/licenses/bsd-license.php">New BSD License</license>
<notes>
* Fixes composer.json parse error
</notes>
</release>
<release>
<version>
<release>1.3.14</release>
<api>1.3.1</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<date>2015-02-26</date>
<license uri="http://www.opensource.org/licenses/bsd-license.php">New BSD License</license>
<notes>
* Fix Bug #18505: Possible incorrect handling of file names in TAR [mrook]
</notes>
</release>
<release>
<version>
<release>1.3.13</release>
<api>1.3.1</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<date>2014-09-02</date>
<license uri="http://www.opensource.org/licenses/bsd-license.php">New BSD
License</license>
<notes>
* Fix Bug #20382: gzopen fix [mrook]
</notes>
</release>
<release>
<version>
<release>1.3.12</release>
<api>1.3.1</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<date>2014-08-04</date>
<license uri="http://www.opensource.org/licenses/bsd-license.php">New BSD
License</license>
<notes>
* Fix Bug #19964: Memory leaking in Archive_Tar [mrook]
* Fix Bug #20246: Broken with php 5.5.9 [mrook]
* Fix Bug #20275: &quot;pax_global_header&quot; looks like a regular file
* [mrook]
* Implement Feature #19827: pass filename to _addFile function - downstream
* patch [mrook]
* Implement Feature #20132: Add custom mode/uid/gid to addString() [mrook]
</notes>
</release>
<release>
<version>
<release>1.3.11</release>
<api>1.3.1</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<date>2013-02-09</date>
<license uri="http://www.opensource.org/licenses/bsd-license.php">New BSD
License</license>
<notes>
* Fix Bug #19746: Broken with PHP 5.5 [mrook]
* Implement Feature #11258: Custom date/time in files added on-the-fly
* [mrook]
</notes>
</release>
<release>
<version>
<release>1.3.10</release>
<api>1.3.1</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<date>2012-04-10</date>
<license uri="http://www.opensource.org/licenses/bsd-license.php">New BSD
License</license>
<notes>
* Fix Bug #13361: Unable to add() some files (ex. mp3) [mrook]
* Fix Bug #19330: Class creates incorrect (non-readable) tar.gz file
* [mrook]
</notes>
</release>
<release>
<version>
<release>1.3.9</release>
<api>1.3.1</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<date>2012-02-27</date>
<license uri="http://www.opensource.org/licenses/bsd-license.php">New BSD License</license>
<notes>
* Fix Bug #16759: No error thrown from missing PHP zlib functions [mrook]
* Fix Bug #18877: Incorrect handling of backslashes in filenames on Linux [mrook]
* Fix Bug #19085: Error while packaging [mrook]
* Fix Bug #19289: Invalid tar file generated [mrook]
</notes>
</release>
<release>
<version>
<release>1.3.8</release>
<api>1.3.1</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<date>2011-10-14</date>
<license uri="http://www.opensource.org/licenses/bsd-license.php">New BSD License</license>
<notes>
* Fix Bug #17853: Test failure: dirtraversal.phpt [mrook]
* Fix Bug #18512: dead links are not saved in tar file [mrook]
* Fix Bug #18702: Unpacks incorrectly on long file names using header prefix [mrook]
* Implement Feature #10145: Patch to return a Pear Error Object on failure [mrook]
* Implement Feature #17491: Option to preserve permissions [mrook]
* Implement Feature #17813: Prevent PHP notice when extracting corrupted archive [mrook]
</notes>
</release>
<release>
<version>
<release>1.3.7</release>
<api>1.3.1</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<date>2010-04-26</date>
<license uri="http://www.opensource.org/licenses/bsd-license.php">New BSD License</license>
<notes>
PEAR compatibility update
</notes>
</release>
<release>
<version>
<release>1.3.6</release>
<api>1.3.1</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<date>2010-03-09</date>
<license uri="http://www.opensource.org/licenses/bsd-license.php">New BSD License</license>
<notes>
* Fix Bug #16963: extractList can&apos;t extract zipped files from big tar [mrook]
* Implement Feature #4013: Ignoring files and directories on creating an archive. [mrook]
</notes>
</release>
<release>
<version>
<release>1.3.5</release>
<api>1.3.1</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<date>2009-12-31</date>
<license uri="http://www.opensource.org/licenses/bsd-license.php">New BSD License</license>
<notes>
* Fix Bug #16958: Update &apos;compatible&apos; tag in package.xml [mrook]
</notes>
</release>
<release>
<version>
<release>1.3.4</release>
<api>1.3.1</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<date>2009-12-30</date>
<license uri="http://www.opensource.org/licenses/bsd-license.php">New BSD License</license>
<notes>
* Fix Bug #11871: wrong result of ::listContent() if filename begins or ends with space [mrook]
* Fix Bug #12462: invalid tar magic [mrook]
* Fix Bug #13918: Long filenames may get up to 511 0x00 bytes appended on read [mrook]
* Fix Bug #16202: Bogus modification times [mrook]
* Implement Feature #16212: Die is not exception [mrook]
</notes>
</release>
<release>
<version>
<release>1.3.3</release>
<api>1.3.1</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<date>2009-03-27</date>
<license uri="http://www.opensource.org/licenses/bsd-license.php">New BSD License</license>
<notes>
Change the license to New BSD license
minor bugfix release
* fix Bug #9921 compression with bzip2 fails [cellog]
* fix Bug #11594 _readLongHeader leaves 0 bytes in filename [jamessas]
* fix Bug #11769 Incorrect symlink handing [fajar99]
</notes>
</release>
<release>
<version>
<release>1.3.2</release>
<api>1.3.1</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<date>2007-01-03</date>
<license uri="http://www.php.net/license">PHP License</license>
<notes>
Correct Bug #4016
Remove duplicate remove error display with &apos;@&apos;
Correct Bug #3909 : Check existence of OS_WINDOWS constant
Correct Bug #5452 fix for &quot;lone zero block&quot; when untarring packages
Change filemode (from pear-core/Archive/Tar.php v.1.21)
Correct Bug #6486 Can not extract symlinks
Correct Bug #6933 Archive_Tar (Tar file management class) Directory traversal
Correct Bug #8114 Files added on-the-fly not storing date
Correct Bug #9352 Bug on _dirCheck function over nfs path
</notes>
</release>
<release>
<version>
<release>1.3.1</release>
<api>1.3.1</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<date>2005-03-17</date>
<license uri="http://www.php.net/license">PHP License</license>
<notes>
Correct Bug #3855
</notes>
</release>
<release>
<version>
<release>1.3.0</release>
<api>1.3.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<date>2005-03-06</date>
<license uri="http://www.php.net/license">PHP License</license>
<notes>
Bugs correction (2475, 2488, 2135, 2176)
</notes>
</release>
<release>
<version>
<release>1.2</release>
<api>1.2</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<date>2004-05-08</date>
<license uri="http://www.php.net/license">PHP License</license>
<notes>
Add support for other separator than the space char and bug
correction
</notes>
</release>
<release>
<version>
<release>1.1</release>
<api>1.1</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<date>2003-05-28</date>
<license uri="http://www.php.net/license">PHP License</license>
<notes>
* Add support for BZ2 compression
* Add support for add and extract without using temporary files : methods addString() and extractInString()
</notes>
</release>
<release>
<version>
<release>1.0</release>
<api>1.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<date>2003-01-24</date>
<license uri="http://www.php.net/license">PHP License</license>
<notes>
Change status to stable
</notes>
</release>
<release>
<version>
<release>0.10-b1</release>
<api>0.10-b1</api>
</version>
<stability>
<release>beta</release>
<api>beta</api>
</stability>
<date>2003-01-08</date>
<license uri="http://www.php.net/license">PHP License</license>
<notes>
Add support for long filenames (greater than 99 characters)
</notes>
</release>
<release>
<version>
<release>0.9</release>
<api>0.9</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<date>2002-05-27</date>
<license uri="http://www.php.net/license">PHP License</license>
<notes>
Auto-detect gzip&apos;ed files
</notes>
</release>
<release>
<version>
<release>0.4</release>
<api>0.4</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<date>2002-05-20</date>
<license uri="http://www.php.net/license">PHP License</license>
<notes>
Windows bugfix: use forward slashes inside archives
</notes>
</release>
<release>
<version>
<release>0.2</release>
<api>0.2</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<date>2002-02-18</date>
<license uri="http://www.php.net/license">PHP License</license>
<notes>
From initial commit to stable
</notes>
</release>
<release>
<version>
<release>0.3</release>
<api>0.3</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<date>2002-04-13</date>
<license uri="http://www.php.net/license">PHP License</license>
<notes>
Windows bugfix: used wrong directory separators
</notes>
</release>
</changelog>
</package>

View File

@@ -0,0 +1,236 @@
#!@prefix@/bin/php -Cq
<?php // -*- PHP -*-
// {{{ setup
define('S_IFDIR', 0040000); // Directory
define('S_IFCHR', 0020000); // Character device
define('S_IFBLK', 0060000); // Block device
define('S_IFREG', 0100000); // Regular file
define('S_IFIFO', 0010000); // FIFO
define('S_IFLNK', 0120000); // Symbolic link
define('S_IFSOCK', 0140000); // Socket
require_once "PEAR.php";
require_once "Archive/Tar.php";
require_once "Console/Getopt.php";
// }}}
// {{{ options
$verbose = false;
$op_create = false;
$op_list = false;
$op_extract = false;
$use_gzip = false;
$file = '';
$progname = basename(array_shift($argv));
$options = Console_Getopt::getopt($argv, "h?ctxvzf:");
if (PEAR::isError($options)) {
usage($options);
}
$opts = $options[0];
foreach ($opts as $opt) {
switch ($opt[0]) {
case 'v': {
$verbose = true;
break;
}
case 'c': {
$op_create = true;
break;
}
case 't': {
$op_list = true;
break;
}
case 'x': {
$op_extract = true;
break;
}
case 'z': {
$use_gzip = true;
break;
}
case 'f': {
$file = $opt[1];
break;
}
case 'h':
case '?': {
usage();
break;
}
}
}
if ($op_create + $op_list + $op_extract > 1) {
usage("Only one of -c, -t and -x can be specified at once!");
}
if ($op_create + $op_list + $op_extract == 0) {
usage("Please specify either -c, -t or -x!");
}
if (empty($file)) {
if ($op_create) {
$file = "php://stdout";
} else {
$file = "php://stdin";
}
}
// }}}
$tar = new Archive_Tar($file, $use_gzip);
$tar->setErrorHandling(PEAR_ERROR_DIE, "$progname error: %s\n");
if ($op_create) {
do_create($tar, $options[1]);
$tar->create($options[1]);
} elseif ($op_list) {
do_list($tar, $verbose);
} elseif ($op_extract) {
do_extract($tar);
}
// {{{ getrwx()
function getrwx($bits) {
$str = '';
$str .= ($bits & 4) ? 'r' : '-';
$str .= ($bits & 2) ? 'w' : '-';
$str .= ($bits & 1) ? 'x' : '-';
return $str;
}
// }}}
// {{{ getfiletype()
function getfiletype($bits) {
static $map = array(
'-' => S_IFREG,
'd' => S_IFDIR,
'l' => S_IFLNK,
'c' => S_IFCHR,
'b' => S_IFBLK,
'p' => S_IFIFO,
's' => S_IFSOCK,
);
foreach ($map as $char => $mask) {
if ($bits & $mask) {
return $char;
}
}
}
// }}}
// {{{ getuser()
function getuser($uid) {
static $cache = array();
if (isset($cache[$uid])) {
return $cache[$uid];
}
if (function_exists("posix_getpwuid")) {
if (is_array($user = @posix_getpwuid($uid))) {
$cache[$uid] = $user['name'];
return $user['name'];
}
}
$cache[$uid] = $uid;
return $uid;
}
// }}}
// {{{ getgroup()
function getgroup($gid) {
static $cache = array();
if (isset($cache[$gid])) {
return $cache[$gid];
}
if (function_exists("posix_getgrgid")) {
if (is_array($group = @posix_getgrgid($gid))) {
$cache[$gid] = $group['name'];
return $group['name'];
}
}
$cache[$gid] = $gid;
return $gid;
}
// }}}
// {{{ do_create()
function do_create(&$tar, &$files)
{
$tar->create($files);
}
// }}}
// {{{ do_list()
function do_list(&$tar, $verbose)
{
static $rwx = array(4 => 'r', 2 => 'w', 1 => 'x');
$files = $tar->listContent();
if (is_array($files) && sizeof($files) > 0) {
foreach ($files as $file) {
if ($verbose) {
$fm = (int)$file['mode'];
$mode = sprintf('%s%s%s%s', getfiletype($fm),
getrwx(($fm >> 6) & 7), getrwx(($fm >> 3) & 7),
getrwx($fm & 7));
$owner = getuser($file['uid']) . '/' . getgroup($file['gid']);
printf("%10s %-11s %7d %s %s\n", $mode, $owner, $file['size'],
date('Y-m-d H:i:s', $file['mtime']), $file['filename']);
} else {
printf("%s\n", $file['filename']);
}
}
}
}
// }}}
// {{{ do_extract()
function do_extract(&$tar, $destdir = ".")
{
$tar->extract($destdir);
}
// }}}
// {{{ usage()
function usage($errormsg = '')
{
global $progname;
$fp = fopen("php://stderr", "w");
if ($errormsg) {
if (PEAR::isError($errormsg)) {
fwrite($fp, $errormsg->getMessage() . "\n");
} else {
fwrite($fp, "$errormsg\n");
}
}
fwrite($fp, "$progname [-h|-?] {-c|-t|-x} [-z] [-v] [-f file] [file(s)...]
Options:
-h, -? Show this screen
-c Create archive
-t List archive
-x Extract archive
-z Run input/output through gzip
-f file Use <file> as input or output (default is stdin/stdout)
");
fclose($fp);
exit;
}
// }}}
?>

View File

@@ -0,0 +1,6 @@
#!/bin/sh
rsync -av Archive/Tar.php ../../php4/pear/Archive/.
rsync -av package.xml ../../php4/pear/package-Archive_Tar.xml
rsync -av docs/Archive_Tar.txt ../../php4/pear/docs/.

View File

@@ -0,0 +1,33 @@
--TEST--
test file size that happens to be 512 * n bytes
--SKIPIF--
--FILE--
<?php
$dirname = dirname(__FILE__);
require_once $dirname . '/setup.php.inc';
$tar = new Archive_Tar($dirname . '/512nbytesfile.tar.gz', null, 2048);
$tar->add($dirname .'/testblock3');
$tar->listContent();
$phpunit->assertNoErrors('after tar archive listing');
$returnval = shell_exec('tar -Ptf ' . $dirname . '/512nbytesfile.tar.gz | sort');
$phpunit->assertNoErrors('after shell tar listing');
$expectedvalue =
<<< EOD
$dirname/testblock3
$dirname/testblock3/1024bytes.txt
$dirname/testblock3/randombytes.txt
EOD;
$phpunit->assertEquals($expectedvalue, $returnval, 'wrong output for shell tar verification');
echo 'test done'
?>
--CLEAN--
<?php
$dirname = dirname(__FILE__);
@unlink($dirname.'/512nbytesfile.tar.gz');
?>
--EXPECT--
test done

View File

@@ -0,0 +1,46 @@
--TEST--
test saving of dead symbolic links
--SKIPIF--
--FILE--
<?php
require_once dirname(__FILE__) . '/setup.php.inc';
function fileName($item){
return rtrim($item['filename'],'/').' => '.$item['link'];
}
//prepare filesystem
@mkdir('test');
@mkdir('test/a');
@touch('test/b');
@symlink('a', 'test/dir_link');
@symlink('b', 'test/file_link');
@symlink('dead', 'test/dead_link');
//prepare reference tar
system('tar -cf test1.tar test');
$tar1=new Archive_Tar('test1.tar');
$tar1List=array_map('fileName',$tar1->listContent());
//create tar
$tar2=new Archive_Tar('test2.tar');
$tar2->create(array('test','nonExisting'));// to make sure we are still report nonExisting
$tar2List=array_map('fileName',$tar2->listContent());
$phpunit->assertErrors(array(
array('package' => 'PEAR_Error', 'message' => "File 'nonExisting' does not exist")), 'after 1');
$phpunit->assertEquals($tar1List, $tar2List, 'bla');
echo 'tests done';
?>
--CLEAN--
<?php
@rmdir('test/a');
@unlink('test/b');
@unlink('test/dir_link');
@unlink('test/file_link');
@unlink('test/dead_link');
@rmdir('test');
@unlink('test1.tar');
@unlink('test2.tar');
?>
--EXPECT--
tests done

View File

@@ -0,0 +1,24 @@
--TEST--
test directory traversal security vulnerability
--SKIPIF--
--FILE--
<?php
require_once dirname(__FILE__) . '/setup.php.inc';
$me = dirname(__FILE__) . '/testit';
$tar = new Archive_Tar(dirname(__FILE__) . '/hamidTARtester2.tar');
$tar->listContent();
$phpunit->assertErrors(array(
array('package' => 'PEAR_Error', 'message' => 'Malicious .tar detected, file "/../../../../../../../../../../../../../../AAAAAAAAAAAAAAAAA/BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB.txt" will not install in desired directory tree')
), 'after 1');
$tar->extract();
$phpunit->assertErrors(array(
array('package' => 'PEAR_Error', 'message' => 'Malicious .tar detected, file "/../../../../../../../../../../../../../../AAAAAAAAAAAAAAAAA/BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB.txt" will not install in desired directory tree')
), 'after 2');
echo 'tests done';
?>
--CLEAN--
<?php
@rmdir('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAa');
?>
--EXPECT--
tests done

Binary file not shown.

View File

@@ -0,0 +1,20 @@
--TEST--
test files that happen to contain the endblock
--SKIPIF--
--FILE--
<?php
require_once dirname(__FILE__) . '/setup.php.inc';
$tar = new Archive_Tar(dirname(__FILE__) . '/testblock.tar.gz');
$tar->add(dirname(__FILE__) . '/testblock1');
$tar->add(dirname(__FILE__) . '/testblock2');
$tar = new Archive_Tar(dirname(__FILE__) . '/testblock.tar.gz');
$tar->listContent();
$phpunit->assertNoErrors('after');
echo 'tests done';
?>
--CLEAN--
<?php
@unlink(dirname(__FILE__) . '/testblock.tar.gz');
?>
--EXPECT--
tests done

View File

@@ -0,0 +1,20 @@
--TEST--
test saving of dead symbolic links
--SKIPIF--
--FILE--
<?php
require_once dirname(__FILE__) . '/setup.php.inc';
$tar1 = new Archive_Tar(dirname(__FILE__) . '/text-0.txt');
$tar1->listContent();
$phpunit->assertErrors(array(
array('package' => 'PEAR_Error', 'message' => "Invalid checksum for file \"4&2Vib~Au.=ZqMTw~=}UoF/~5Gs;JTXF*<FyG\"\n" .
'1Hvu#nol Y 21/{G9i|D=$GTI KREuA\wI<wM@dYOKzS{6&]QE8ud|EPb:f?-Gt' . "\n" .
'I#)E9)@;_.0y9`P,&jY! :\.J8uG/a8,.vT[$Fe;>}hm\"#xO7:46y_tg6c-[A&S]z0fke?(B6?$:W$X{E%PO>~UWl8(' . "\n" .
'.%RWPjN55)cd&?oJPgFFZj#+U<qrF:9yIRe\" : UPJX05Zz extracted')), 'after 1');
echo 'tests done';
?>
--CLEAN--
--EXPECT--
tests done

View File

@@ -0,0 +1,30 @@
--TEST--
test trimming of characters in long filenames
--SKIPIF--
--FILE--
<?php
require_once dirname(__FILE__) . '/setup.php.inc';
$dirname = dirname(__FILE__) . '/longfilenamedir/';
for ($i = 0; $i < 8; $i++) {
$dirname .= str_pad('', 64, 'a') . '/';
}
$longfilename = $dirname . "b ";
mkdir($dirname, 0777, true);
touch($longfilename);
$tar = new Archive_Tar(dirname(__FILE__) . '/testlongfilename.tar');
$tar->addModify(array($longfilename), '', dirname(__FILE__));
$tar = new Archive_Tar(dirname(__FILE__) . '/testlongfilename.tar');
$files = $tar->listContent();
$file = reset($files);
$lastChar = $file['filename'][strlen($file['filename']) - 1];
$phpunit->assertEquals(' ', $lastChar, 'should contain space as last character');
echo 'tests done';
?>
--CLEAN--
<?php
$dirname = dirname(__FILE__);
unlink($dirname . '/testlongfilename.tar');
system("rm -r $dirname/longfilenamedir");
?>
--EXPECT--
tests done

View File

@@ -0,0 +1,29 @@
--TEST--
test trimming of characters in long symbolic link targets
--SKIPIF--
--FILE--
<?php
require_once dirname(__FILE__) . '/setup.php.inc';
$dirname = dirname(__FILE__) . '/longsymlink/';
$longfilename = $dirname . str_repeat("b", 120) . " ";
$symlinkfilename = $dirname . "a";
mkdir($dirname, 0777, true);
touch($longfilename);
symlink($longfilename, $symlinkfilename);
$tar = new Archive_Tar(dirname(__FILE__) . '/testlongsymlink.tar');
$tar->addModify(array($longfilename, $symlinkfilename), '', dirname(__FILE__));
$tar = new Archive_Tar(dirname(__FILE__) . '/testlongsymlink.tar');
$files = $tar->listContent();
$file = end($files);
$lastChar = $file['link'][strlen($file['link']) - 1];
$phpunit->assertEquals(' ', $lastChar, 'should contain space as last character');
echo 'tests done';
?>
--CLEAN--
<?php
$dirname = dirname(__FILE__);
unlink($dirname . '/testlongsymlink.tar');
system("rm -r $dirname/longsymlink");
?>
--EXPECT--
tests done

View File

@@ -0,0 +1,18 @@
--TEST--
tests writes to out-of-path filenames
--SKIPIF--
--FILE--
<?php
require_once dirname(__FILE__) . '/setup.php.inc';
$tar = new Archive_Tar(dirname(__FILE__) . '/out_of_path_symlink.tar');
$tar->extract();
$phpunit->assertErrors(array(array('package' => 'PEAR_Error', 'message' => "Out-of-path file extraction {symlink --> /tmp/}")), 'after 1');
$phpunit->assertFileNotExists('symlink/whatever-filename', 'Out-of-path filename should not have succeeded');
echo 'tests done';
?>
--CLEAN--
<?php
@unlink("symlink");
?>
--EXPECT--
tests done

View File

@@ -0,0 +1,13 @@
--TEST--
tests if pax global / extended headers are ignored
--SKIPIF--
--FILE--
<?php
require_once dirname(__FILE__) . '/setup.php.inc';
$tar = new Archive_Tar(dirname(__FILE__) . '/testpax.tar');
$phpunit->assertEquals(1, count($tar->listContent()), "count should be 1");
echo 'tests done';
?>
--CLEAN--
--EXPECT--
tests done

View File

@@ -0,0 +1,18 @@
--TEST--
test preserving of permissions
--SKIPIF--
--FILE--
<?php
require_once dirname(__FILE__) . '/setup.php.inc';
$tar = new Archive_Tar(dirname(__FILE__) . '/testperms.tar');
$tar->extract('', true);
$phpunit->assertNoErrors('after');
echo 'tests done';
?>
--CLEAN--
<?php
@unlink('a');
@unlink('b');
?>
--EXPECT--
tests done

View File

@@ -0,0 +1,414 @@
<?php
@include_once 'Text/Diff.php';
@include_once 'Text/Diff/Renderer.php';
@include_once 'Text/Diff/Renderer/unified.php';
require_once 'PEAR/ErrorStack.php';
require_once 'PEAR.php';
class PEAR_PHPTest
{
var $_diffonly;
var $_errors;
function __construct($diffonly = false, $noStackCatch = false)
{
$this->_diffonly = $diffonly;
$this->_errors = array();
PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, array($this, 'pearerrorCallback'));
if (!$noStackCatch) {
PEAR_ErrorStack::setDefaultCallback(array($this, 'pearerrorstackCallback'));
}
}
function pearerrorCallback($err)
{
PEAR_ErrorStack::staticPush('PEAR_Error', -1, 'error', array('obj' => $err),
$err->getMessage());
}
function pearerrorstackCallback($err)
{
$this->_errors[] = $err;
}
function assertPEARError($err, $message)
{
if (is_a($err, 'PEAR_Error')) {
return true;
}
$this->_failTest(debug_backtrace(), $message);
echo "Not a PEAR_Error\n";
return false;
}
function assertNoErrors($message, $trace = null)
{
if (count($this->_errors) == 0) {
return true;
}
if ($trace === null) {
$trace = debug_backtrace();
}
$this->_failTest($trace, $message);
foreach ($this->_errors as $err) {
if ($err['package'] == 'PEAR_Error') {
echo "Unexpected PEAR_Error:\n";
echo 'message "' . $err['message'] . "\"\n";
} else {
echo "Unexpected PEAR_ErrorStack error:\n";
echo 'package "' . $err['package'] . "\"\n";
echo 'message "' . $err['message'] . "\"\n";
}
}
$this->_errors = array();
return false;
}
function assertErrors($errors, $message, $trace = null)
{
if (!count($this->_errors)) {
if ($trace === null) {
$trace = debug_backtrace();
}
$this->_failTest($trace, $message);
echo "No errors caught, but errors were expected\n";
return false;
}
if (!isset($errors[0])) {
$errors = array($errors);
}
$failed = false;
foreach ($errors as $err) {
$found = false;
foreach ($this->_errors as $i => $caughterror) {
if ($caughterror['package'] == $err['package']) {
if ($caughterror['message'] == $err['message']) {
$found = true;
break;
}
}
}
if ($found) {
unset($this->_errors[$i]);
continue;
}
if (!$failed) {
if ($trace === null) {
$trace = debug_backtrace();
}
$failed = true;
$this->_failTest($trace, $message);
}
echo "Unthrown error:\n";
if ($err['package'] == 'PEAR_Error') {
echo "PEAR_Error:\n";
} else {
echo "error package: \"$err[package]\"\n";
}
echo "message: \"$err[message]\"\n";
}
if (count($this->_errors)) {
if (!$failed) {
if ($trace === null) {
$trace = debug_backtrace();
}
$failed = true;
$this->_failTest($trace, $message);
}
foreach ($this->_errors as $err) {
echo "Unexpected error:\n";
if ($err['package'] == 'PEAR_Error') {
echo "PEAR_Error:\n";
} else {
echo "error package: \"$err[package]\"\n";
}
echo "message: \"$err[message]\"\n";
}
}
$this->_errors = array();
return !$failed;
}
function assertTrue($test, $message)
{
$this->assertNoErrors($message, debug_backtrace());
if ($test === true) {
return true;
}
$this->_failTest(debug_backtrace(), $message);
echo "Unexpected non-true value: \n";
var_export($test);
echo "\n'$message'\n";
return false;
}
function assertIsa($control, $test, $message)
{
$this->assertNoErrors($message, debug_backtrace());
if (is_a($test, $control)) {
return true;
}
$this->_failTest(debug_backtrace(), $message);
echo "Unexpected non-$control object: \n";
var_export($test);
echo "\n'$message'\n";
return false;
}
function assertNull($test, $message)
{
$this->assertNoErrors($message, debug_backtrace());
if ($test === null) {
return true;
}
$this->_failTest(debug_backtrace(), $message);
echo "Unexpected non-null value: \n";
var_export($test);
echo "\n'$message'\n";
return false;
}
function assertNotNull($test, $message)
{
$this->assertNoErrors($message, debug_backtrace());
if ($test !== null) {
return true;
}
$this->_failTest(debug_backtrace(), $message);
echo "Unexpected null: \n";
var_export($test);
echo "\n'$message'\n";
return false;
}
function assertSame($test, $test1, $message)
{
$this->assertNoErrors($message, debug_backtrace());
if ($test === $test1) {
return true;
}
$this->_failTest(debug_backtrace(), $message);
echo "Unexpectedly two vars are not the same thing: \n";
echo "\n'$message'\n";
return false;
}
function assertNotSame($test, $test1, $message)
{
$this->assertNoErrors($message, debug_backtrace());
if ($test !== $test1) {
return true;
}
$this->_failTest(debug_backtrace(), $message);
echo "Unexpectedly two vars are the same thing: \n";
echo "\n'$message'\n";
return false;
}
function assertFalse($test, $message)
{
$this->assertNoErrors($message, debug_backtrace());
if ($test === false) {
return true;
}
$this->_failTest(debug_backtrace(), $message);
echo "Unexpected non-false value: \n";
var_export($test);
echo "\n'$message'\n";
return false;
}
function assertNotTrue($test, $message)
{
$this->assertNoErrors($message, debug_backtrace());
if (!$test) {
return true;
}
$this->_failTest(debug_backtrace(), $message);
echo "Unexpected loose true value: \n";
var_export($test);
echo "\n'$message'\n";
return false;
}
function assertNotFalse($test, $message)
{
$this->assertNoErrors($message, debug_backtrace());
if ($test) {
return true;
}
$this->_failTest(debug_backtrace(), $message);
echo "Unexpected loose false value: \n";
var_export($test);
echo "\n'$message'\n";
return false;
}
function assertEquals($control, $test, $message)
{
$this->assertNoErrors($message, debug_backtrace());
if (str_replace(array("\r", "\n"), array('', ''),
var_export($control, true)) != str_replace(array("\r", "\n"), array('', ''),
var_export($test, true))) {
$this->_failTest(debug_backtrace(), $message);
if (class_exists('Text_Diff')) {
echo "Diff of expecting/received:\n";
$diff = new Text_Diff(
explode("\n", var_export($control, true)),
explode("\n", var_export($test, true)));
// Output the diff in unified format.
$renderer = new Text_Diff_Renderer_unified();
echo $renderer->render($diff);
if ($this->_diffonly) {
return false;
}
}
echo "Expecting:\n";
var_export($control);
echo "\nReceived:\n";
var_export($test);
echo "\n";
return false;
}
return true;
}
function assertFileExists($fname, $message)
{
$this->assertNoErrors($message, debug_backtrace());
if (!@file_exists($fname)) {
$this->_failTest(debug_backtrace(), $message);
echo "File '$fname' does not exist, and should\n";
return false;
}
return true;
}
function assertFileNotExists($fname, $message)
{
$this->assertNoErrors($message, debug_backtrace());
if (@file_exists($fname)) {
$this->_failTest(debug_backtrace(), $message);
echo "File '$fname' exists, and should not\n";
return false;
}
return true;
}
function assertRegEquals($dump, &$reg, $message)
{
$actualdump = var_export(trim($this->dumpReg($reg)), true);
$testdump = var_export(trim($dump), true);
return $this->assertEquals($testdump, $actualdump, $message);
}
function assertPackageInfoEquals($control, $test, $message)
{
$this->assertNoErrors($message, debug_backtrace());
if (isset($control[0])) {
if (!isset($test[0]) || (count($control) != count($test))) {
echo "Invalid packageInfo\n";
$ret = $this->assertEquals($control, $test, $message);
}
$ret = true;
foreach ($control as $i => $packageinfo) {
$ret = $ret &&
$this->assertPackageInfoEquals($packageinfo, $test[$i], $message . $i);
}
return $ret;
}
if (isset($control['_lastmodified'])) {
if (!isset($test['_lastmodified'])) {
echo "_lastmodified is not set in packageInfo() output\n";
$this->_failTest(debug_backtrace(), $message);
return false;
}
}
$savecontrol = sort($control);
$savetest = sort($test);
unset($control['_lastmodified']);
unset($test['_lastmodified']);
if (var_export($control, true) != var_export($test, true)) {
$this->_failTest(debug_backtrace(), $message);
if (class_exists('Text_Diff')) {
echo "Diff of expecting/received:\n";
$diff = new Text_Diff(
explode("\n", var_export($control, true)),
explode("\n", var_export($test, true)));
// Output the diff in unified format.
$renderer = new Text_Diff_Renderer_unified();
echo $renderer->render($diff);
if ($this->_diffonly) {
return false;
}
}
echo "Expecting:\n";
var_export($savecontrol);
echo "\nReceived:\n";
var_export($savetest);
return false;
}
return true;
}
function _sortRegEntries($a, $b)
{
return strnatcasecmp($a['name'], $b['name']);
}
function dumpReg(&$reg)
{
ob_start();
print "dumping registry...\n";
$infos = $reg->packageInfo(null, null, null);
ksort($infos);
foreach ($infos as $channel => $info) {
echo "channel $channel:\n";
usort($info, array($this, '_sortRegEntries'));
foreach ($info as $pkg) {
print $pkg["name"] . ":";
unset($pkg["name"]);
foreach ($pkg as $k => $v) {
if ($k == '_lastmodified') {
print " _lastmodified is set";
continue;
}
if (is_array($v) && $k == 'filelist') {
print " $k=array(";
$i = 0;
foreach ($v as $k2 => $v2) {
if ($i++ > 0) print ",";
print "{$k2}[";
$j = 0;
foreach ($v2 as $k3 => $v3) {
if ($j++ > 0) print ",";
print "$k3=$v3";
}
print "]";
}
print ")";
} else {
print " $k=\"$v\"";
}
}
print "\n";
}
}
print "dump done\n";
$ret = ob_get_contents();
ob_end_clean();
return $ret;
}
function _failTest($trace, $message)
{
echo 'Test Failure: "' . $message . "\"\n in " . $trace[0]['file'] . ' line ' .
$trace[0]['line'] . "\n";
}
function showAll()
{
$this->_diffonly = false;
}
}
?>

View File

@@ -0,0 +1,26 @@
--TEST--
test symbolic links
--SKIPIF--
--FILE--
<?php
require_once dirname(__FILE__) . '/setup.php.inc';
$me = dirname(__FILE__) . '/testit';
$tar = new Archive_Tar(dirname(__FILE__) . '/relativesymlink.tar');
$tar->extract();
$phpunit->assertNoErrors('after');
$phpunit->assertFileExists('testme', 'dir');
$phpunit->assertFileExists('testme/a/file1.txt', 'file1.txt');
$phpunit->assertFileExists('testme/b/symlink.txt', 'symlink.txt');
$phpunit->assertTrue(is_link('testme/b/symlink.txt'), 'is link');
echo 'tests done';
?>
--CLEAN--
<?php
@unlink('testme/a/file1.txt');
@unlink('testme/b/symlink.txt');
@rmdir('testme/a');
@rmdir('testme/b');
@rmdir('testme');
?>
--EXPECT--
tests done

Binary file not shown.

View File

@@ -0,0 +1,5 @@
<?php
error_reporting(E_ALL);
require_once dirname(__FILE__) . '/phpt_test.php.inc';
$phpunit = new PEAR_PHPTest(true);
require_once dirname(dirname(__FILE__)) . '/Archive/Tar.php';

View File

@@ -0,0 +1,24 @@
--TEST--
test symbolic links
--SKIPIF--
--FILE--
<?php
require_once dirname(__FILE__) . '/setup.php.inc';
$me = dirname(__FILE__) . '/testit';
$tar = new Archive_Tar(dirname(__FILE__) . '/testsymlink.tar');
$tar->extract();
$phpunit->assertNoErrors('after');
$phpunit->assertFileExists('testme', 'dir');
$phpunit->assertFileExists('testme/file1.txt', 'file1.txt');
$phpunit->assertFileExists('testme/symlink.txt', 'symlink.txt');
$phpunit->assertTrue(is_link('testme/symlink.txt'), 'is link');
echo 'tests done';
?>
--CLEAN--
<?php
@unlink('testme/file1.txt');
@unlink('testme/symlink.txt');
@rmdir('testme');
?>
--EXPECT--
tests done

View File

@@ -0,0 +1,28 @@
--TEST--
test symbolic links
--SKIPIF--
--FILE--
<?php
require_once dirname(__FILE__) . '/setup.php.inc';
$me = dirname(__FILE__) . '/testit';
$tar = new Archive_Tar(dirname(__FILE__) . '/testsymlink.tar');
$tar->extract('', false, false);
$phpunit->assertErrors(array(
array(
'package' => 'PEAR_Error',
'message' => 'Symbolic links are not allowed. Unable to extract {testme/symlink.txt}'
),
), 'Warning thrown');
$phpunit->assertFileExists('testme', 'dir');
$phpunit->assertFileNotExists('testme/file1.txt', 'file1.txt');
$phpunit->assertFileNotExists('testme/symlink.txt', 'symlink.txt');
echo 'tests done';
?>
--CLEAN--
<?php
@unlink('testme/file1.txt');
@unlink('testme/symlink.txt');
@rmdir('testme');
?>
--EXPECT--
tests done

View File

@@ -0,0 +1 @@
abc

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View File

@@ -0,0 +1,16 @@
194 210 54 166 74 179 115 216 109 21 220 29 144 242 90 206
240 73 172 14 153 163 43 16 233 20 186 91 95 150 60 61
180 187 233 126 130 154 116 206 213 231 202 148 148 12 125 24
6 139 32 235 117 240 56 96 23 1 182 167 116 64 92 73
250 177 157 119 121 148 112 50 89 24 37 214 81 88 201 75
162 108 60 114 137 227 170 186 231 213 177 33 44 143 243 98
14 28 226 77 152 241 243 62 103 237 187 235 227 73 9 119
162 64 127 74 73 90 112 200 39 6 173 251 12 191 166 18
235 100 74 184 126 153 23 118 27 25 128 222 234 246 165 159
170 127 236 199 91 67 96 185 108 159 172 2 245 202 161 177
147 188 0 151 251 230 251 100 226 67 212 38 72 32 44 117
10 39 163 159 0 197 160 225 25 177 16 0 240 16 137 105
187 132 129 98 24 210 169 33 246 77 217 145 242 118 181 47
160 61 62 129 71 52 253 85 2 215 174 241 55 32 236 27
160 120 145 188 132 37 161 178 45 227 209 57 142 19 88 175
230 238 104 128 26 196 126 118 214 122 201 123

View File

@@ -0,0 +1,2 @@
250 97 98 194 5 149 229 27 58 62 133 73 95 230 219 128
224 98 210 250 162 58 240 80 202 249 173 203 125 186

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,16 @@
a8,.vT[$Fe;>}hm\"#xO7:46y_tg6c-[A&S]z0fke?(B6?$:W$X{E%PO>~UWl8(
.%RWPjN55)cd&?oJPgFFZj#+U<qrF:9yIRe\S0F}Y|[`+4^::byA2Is7UY8QShd
v]F 1O0_[Ip7.12B"!u!UPJX05ZzKXP<JJ(X@4r(M2D})|TA@b#2zFlG(EQqT@M
[RKXlK41}Q= uEq4`p"ons9eil/$Tbp>T~!xcu46(QhbViq%FShbsm5Qt:8}[V1
ov!|iNrfBH)JBa)G?P*v!@=?:Y^2!)v `wxPQ^xT[~W6&q^Un@"c#g3=M++ 0.x
]^Lo4{|}Q]YN?GSaA/*s,Az>04&2Vib~Au.=ZqMTw~=}UoF/~5Gs;JTXF*<FyG"
1Hvu#nol Y 21/{G9i|D=$GTI KREuA\wI<wM@dYOKzS{6&]QE8ud|EPb:f?-Gt
I#)E9)@;_.0y9`P,&jY! :\.J8uGnUd},~`DXkJ-4\\xK24FvGqX434G#0hXLrH
q3YXk^{Rgb` Gg&hUJY)+IrJffZ<O/7)UYj^I}gy.>C#&Vx%>lw9AdZ_eM{s8B#
II*pD'_4H[LivE<WtfQW1IK'(6%|sQG=C,6nfeRVXJ{u:tTB(A"({4>(4!$@Ak^
=|U/{r5n)I{(01wGUM53800-aIdiv1U_HDvgp2q}X,v-{O! 'u$8RJbBO]<PTA
CiqiD_L,=;^W&n?,ai}U&MV9nU[=,t_qDiCkR]SM18ok;dVe@g+G*`FYtl/{cMq
B8R6kfeHNA{bZU?]{[LMLCqokIld;w&NebP<. :8l4d2[~P*\m+MYT}1RK.q4bH
,:XUk'YazKlPN@_WBpb!\em%]H|A+_Fbqki<fjpahg89Xb$fB5ME~ItuXM5H4Ol
*a1SfkUQmv|+xM+Rz2Wq{sXA^uTU(j;Ne.Tcd3uW;>lJSI3L"hj=z .Bfl)waj*
8.G,qEubj;:xJc@Y14nZ`V|%dIk$GAks_MI|y^0R3)rIY9I.DfD,kZ9ap{z Xn

View File

@@ -0,0 +1,6 @@
# composer related
composer.lock
composer.phar
vendor
README.html
dist/

View File

@@ -0,0 +1,9 @@
language: php
php:
- 7
- 5.6
- 5.5
- 5.4
sudo: false
script:
- pear run-tests -r tests/

View File

@@ -0,0 +1,365 @@
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4: */
/**
* PHP Version 5
*
* Copyright (c) 2001-2015, The PEAR developers
*
* This source file is subject to the BSD-2-Clause license,
* that is bundled with this package in the file LICENSE, and is
* available through the world-wide-web at the following url:
* http://opensource.org/licenses/bsd-license.php.
*
* @category Console
* @package Console_Getopt
* @author Andrei Zmievski <andrei@php.net>
* @license http://opensource.org/licenses/bsd-license.php BSD-2-Clause
* @version CVS: $Id$
* @link http://pear.php.net/package/Console_Getopt
*/
require_once 'PEAR.php';
/**
* Command-line options parsing class.
*
* @category Console
* @package Console_Getopt
* @author Andrei Zmievski <andrei@php.net>
* @license http://opensource.org/licenses/bsd-license.php BSD-2-Clause
* @link http://pear.php.net/package/Console_Getopt
*/
class Console_Getopt
{
/**
* Parses the command-line options.
*
* The first parameter to this function should be the list of command-line
* arguments without the leading reference to the running program.
*
* The second parameter is a string of allowed short options. Each of the
* option letters can be followed by a colon ':' to specify that the option
* requires an argument, or a double colon '::' to specify that the option
* takes an optional argument.
*
* The third argument is an optional array of allowed long options. The
* leading '--' should not be included in the option name. Options that
* require an argument should be followed by '=', and options that take an
* option argument should be followed by '=='.
*
* The return value is an array of two elements: the list of parsed
* options and the list of non-option command-line arguments. Each entry in
* the list of parsed options is a pair of elements - the first one
* specifies the option, and the second one specifies the option argument,
* if there was one.
*
* Long and short options can be mixed.
*
* Most of the semantics of this function are based on GNU getopt_long().
*
* @param array $args an array of command-line arguments
* @param string $short_options specifies the list of allowed short options
* @param array $long_options specifies the list of allowed long options
* @param boolean $skip_unknown suppresses Console_Getopt: unrecognized option
*
* @return array two-element array containing the list of parsed options and
* the non-option arguments
*/
public static function getopt2($args, $short_options, $long_options = null, $skip_unknown = false)
{
return Console_Getopt::doGetopt(2, $args, $short_options, $long_options, $skip_unknown);
}
/**
* This function expects $args to start with the script name (POSIX-style).
* Preserved for backwards compatibility.
*
* @param array $args an array of command-line arguments
* @param string $short_options specifies the list of allowed short options
* @param array $long_options specifies the list of allowed long options
*
* @see getopt2()
* @return array two-element array containing the list of parsed options and
* the non-option arguments
*/
public static function getopt($args, $short_options, $long_options = null, $skip_unknown = false)
{
return Console_Getopt::doGetopt(1, $args, $short_options, $long_options, $skip_unknown);
}
/**
* The actual implementation of the argument parsing code.
*
* @param int $version Version to use
* @param array $args an array of command-line arguments
* @param string $short_options specifies the list of allowed short options
* @param array $long_options specifies the list of allowed long options
* @param boolean $skip_unknown suppresses Console_Getopt: unrecognized option
*
* @return array
*/
public static function doGetopt($version, $args, $short_options, $long_options = null, $skip_unknown = false)
{
// in case you pass directly readPHPArgv() as the first arg
if (PEAR::isError($args)) {
return $args;
}
if (empty($args)) {
return array(array(), array());
}
$non_opts = $opts = array();
settype($args, 'array');
if ($long_options) {
sort($long_options);
}
/*
* Preserve backwards compatibility with callers that relied on
* erroneous POSIX fix.
*/
if ($version < 2) {
if (isset($args[0][0]) && $args[0][0] != '-') {
array_shift($args);
}
}
for ($i = 0; $i < count($args); $i++) {
$arg = $args[$i];
/* The special element '--' means explicit end of
options. Treat the rest of the arguments as non-options
and end the loop. */
if ($arg == '--') {
$non_opts = array_merge($non_opts, array_slice($args, $i + 1));
break;
}
if ($arg[0] != '-' || (strlen($arg) > 1 && $arg[1] == '-' && !$long_options)) {
$non_opts = array_merge($non_opts, array_slice($args, $i));
break;
} elseif (strlen($arg) > 1 && $arg[1] == '-') {
$error = Console_Getopt::_parseLongOption(substr($arg, 2),
$long_options,
$opts,
$i,
$args,
$skip_unknown);
if (PEAR::isError($error)) {
return $error;
}
} elseif ($arg == '-') {
// - is stdin
$non_opts = array_merge($non_opts, array_slice($args, $i));
break;
} else {
$error = Console_Getopt::_parseShortOption(substr($arg, 1),
$short_options,
$opts,
$i,
$args,
$skip_unknown);
if (PEAR::isError($error)) {
return $error;
}
}
}
return array($opts, $non_opts);
}
/**
* Parse short option
*
* @param string $arg Argument
* @param string[] $short_options Available short options
* @param string[][] &$opts
* @param int &$argIdx
* @param string[] $args
* @param boolean $skip_unknown suppresses Console_Getopt: unrecognized option
*
* @return void
*/
protected static function _parseShortOption($arg, $short_options, &$opts, &$argIdx, $args, $skip_unknown)
{
for ($i = 0; $i < strlen($arg); $i++) {
$opt = $arg[$i];
$opt_arg = null;
/* Try to find the short option in the specifier string. */
if (($spec = strstr($short_options, $opt)) === false || $arg[$i] == ':') {
if ($skip_unknown === true) {
break;
}
$msg = "Console_Getopt: unrecognized option -- $opt";
return PEAR::raiseError($msg);
}
if (strlen($spec) > 1 && $spec[1] == ':') {
if (strlen($spec) > 2 && $spec[2] == ':') {
if ($i + 1 < strlen($arg)) {
/* Option takes an optional argument. Use the remainder of
the arg string if there is anything left. */
$opts[] = array($opt, substr($arg, $i + 1));
break;
}
} else {
/* Option requires an argument. Use the remainder of the arg
string if there is anything left. */
if ($i + 1 < strlen($arg)) {
$opts[] = array($opt, substr($arg, $i + 1));
break;
} else if (isset($args[++$argIdx])) {
$opt_arg = $args[$argIdx];
/* Else use the next argument. */;
if (Console_Getopt::_isShortOpt($opt_arg)
|| Console_Getopt::_isLongOpt($opt_arg)) {
$msg = "option requires an argument --$opt";
return PEAR::raiseError("Console_Getopt: " . $msg);
}
} else {
$msg = "option requires an argument --$opt";
return PEAR::raiseError("Console_Getopt: " . $msg);
}
}
}
$opts[] = array($opt, $opt_arg);
}
}
/**
* Checks if an argument is a short option
*
* @param string $arg Argument to check
*
* @return bool
*/
protected static function _isShortOpt($arg)
{
return strlen($arg) == 2 && $arg[0] == '-'
&& preg_match('/[a-zA-Z]/', $arg[1]);
}
/**
* Checks if an argument is a long option
*
* @param string $arg Argument to check
*
* @return bool
*/
protected static function _isLongOpt($arg)
{
return strlen($arg) > 2 && $arg[0] == '-' && $arg[1] == '-' &&
preg_match('/[a-zA-Z]+$/', substr($arg, 2));
}
/**
* Parse long option
*
* @param string $arg Argument
* @param string[] $long_options Available long options
* @param string[][] &$opts
* @param int &$argIdx
* @param string[] $args
*
* @return void|PEAR_Error
*/
protected static function _parseLongOption($arg, $long_options, &$opts, &$argIdx, $args, $skip_unknown)
{
@list($opt, $opt_arg) = explode('=', $arg, 2);
$opt_len = strlen($opt);
for ($i = 0; $i < count($long_options); $i++) {
$long_opt = $long_options[$i];
$opt_start = substr($long_opt, 0, $opt_len);
$long_opt_name = str_replace('=', '', $long_opt);
/* Option doesn't match. Go on to the next one. */
if ($long_opt_name != $opt) {
continue;
}
$opt_rest = substr($long_opt, $opt_len);
/* Check that the options uniquely matches one of the allowed
options. */
if ($i + 1 < count($long_options)) {
$next_option_rest = substr($long_options[$i + 1], $opt_len);
} else {
$next_option_rest = '';
}
if ($opt_rest != '' && $opt[0] != '=' &&
$i + 1 < count($long_options) &&
$opt == substr($long_options[$i+1], 0, $opt_len) &&
$next_option_rest != '' &&
$next_option_rest[0] != '=') {
$msg = "Console_Getopt: option --$opt is ambiguous";
return PEAR::raiseError($msg);
}
if (substr($long_opt, -1) == '=') {
if (substr($long_opt, -2) != '==') {
/* Long option requires an argument.
Take the next argument if one wasn't specified. */;
if (!strlen($opt_arg)) {
if (!isset($args[++$argIdx])) {
$msg = "Console_Getopt: option requires an argument --$opt";
return PEAR::raiseError($msg);
}
$opt_arg = $args[$argIdx];
}
if (Console_Getopt::_isShortOpt($opt_arg)
|| Console_Getopt::_isLongOpt($opt_arg)) {
$msg = "Console_Getopt: option requires an argument --$opt";
return PEAR::raiseError($msg);
}
}
} else if ($opt_arg) {
$msg = "Console_Getopt: option --$opt doesn't allow an argument";
return PEAR::raiseError($msg);
}
$opts[] = array('--' . $opt, $opt_arg);
return;
}
if ($skip_unknown === true) {
return;
}
return PEAR::raiseError("Console_Getopt: unrecognized option --$opt");
}
/**
* Safely read the $argv PHP array across different PHP configurations.
* Will take care on register_globals and register_argc_argv ini directives
*
* @return mixed the $argv PHP array or PEAR error if not registered
*/
public static function readPHPArgv()
{
global $argv;
if (!is_array($argv)) {
if (!@is_array($_SERVER['argv'])) {
if (!@is_array($GLOBALS['HTTP_SERVER_VARS']['argv'])) {
$msg = "Could not read cmd args (register_argc_argv=Off?)";
return PEAR::raiseError("Console_Getopt: " . $msg);
}
return $GLOBALS['HTTP_SERVER_VARS']['argv'];
}
return $_SERVER['argv'];
}
return $argv;
}
}

View File

@@ -0,0 +1,25 @@
Copyright (c) 2001-2015, The PEAR developers
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@@ -0,0 +1,26 @@
*******************************************
Console_Getopt - Command-line option parser
*******************************************
This is a PHP implementation of "getopt" supporting both short and long options.
It helps parsing command line options in your PHP script.
Homepage: http://pear.php.net/package/Console_Getopt
.. image:: https://travis-ci.org/pear/Console_Getopt.svg?branch=master
:target: https://travis-ci.org/pear/Console_Getopt
Alternatives
============
* Console_CommandLine__ (recommended)
* Console_GetoptPlus__
__ http://pear.php.net/package/Console_CommandLine
__ http://pear.php.net/package/Console_GetoptPlus
License
=======
BSD-2-Clause

View File

@@ -0,0 +1,35 @@
{
"authors": [
{
"email": "andrei@php.net",
"name": "Andrei Zmievski",
"role": "Lead"
},
{
"email": "stig@php.net",
"name": "Stig Bakken",
"role": "Developer"
},
{
"email": "cellog@php.net",
"name": "Greg Beaver",
"role": "Helper"
}
],
"autoload": {
"psr-0": {
"Console": "./"
}
},
"description": "More info available on: http://pear.php.net/package/Console_Getopt",
"include-path": [
"./"
],
"license": "BSD-2-Clause",
"name": "pear/console_getopt",
"support": {
"issues": "http://pear.php.net/bugs/search.php?cmd=display&package_name[]=Console_Getopt",
"source": "https://github.com/pear/Console_Getopt"
},
"type": "library"
}

View File

@@ -0,0 +1,302 @@
<?xml version="1.0" encoding="UTF-8"?>
<package packagerversion="1.9.2" version="2.0" xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0 http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.0 http://pear.php.net/dtd/package-2.0.xsd">
<name>Console_Getopt</name>
<channel>pear.php.net</channel>
<summary>Command-line option parser</summary>
<description>This is a PHP implementation of &quot;getopt&quot; supporting both
short and long options.</description>
<lead>
<name>Andrei Zmievski</name>
<user>andrei</user>
<email>andrei@php.net</email>
<active>no</active>
</lead>
<developer>
<name>Stig Bakken</name>
<user>ssb</user>
<email>stig@php.net</email>
<active>no</active>
</developer>
<helper>
<name>Greg Beaver</name>
<user>cellog</user>
<email>cellog@php.net</email>
<active>no</active>
</helper>
<date>2019-11-20</date>
<version>
<release>1.4.3</release>
<api>1.4.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<license uri="http://opensource.org/licenses/bsd-license.php">BSD-2-Clause</license>
<notes>
* PR #4: Fix PHP 7.4 deprecation: array/string curly braces access
* PR #5: fix phplint warnings
</notes>
<contents>
<dir name="/">
<dir name="Console">
<file name="Getopt.php" role="php" />
</dir>
<dir name="tests">
<file role="test" name="001-getopt.phpt" />
<file role="test" name="bug10557.phpt" />
<file role="test" name="bug11068.phpt" />
<file role="test" name="bug13140.phpt" />
</dir>
</dir>
</contents>
<compatible>
<name>PEAR</name>
<channel>pear.php.net</channel>
<min>1.4.0</min>
<max>1.999.999</max>
</compatible>
<dependencies>
<required>
<php>
<min>5.4.0</min>
</php>
<pearinstaller>
<min>1.8.0</min>
</pearinstaller>
</required>
</dependencies>
<phprelease />
<changelog>
<release>
<date>2019-11-20</date>
<version>
<release>1.4.3</release>
<api>1.4.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<license uri="http://opensource.org/licenses/bsd-license.php">BSD-2-Clause</license>
<notes>
* PR #4: Fix PHP 7.4 deprecation: array/string curly braces access
* PR #5: fix phplint warnings
</notes>
</release>
<release>
<date>2019-02-06</date>
<version>
<release>1.4.2</release>
<api>1.4.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<license uri="http://opensource.org/licenses/bsd-license.php">BSD-2-Clause</license>
<notes>
* Remove use of each(), which is removed in PHP 8
</notes>
</release>
<release>
<date>2015-07-20</date>
<version>
<release>1.4.1</release>
<api>1.4.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<license uri="http://opensource.org/licenses/bsd-license.php">BSD-2-Clause</license>
<notes>
* Fix unit test on PHP 7 [cweiske]
</notes>
</release>
<release>
<date>2015-02-22</date>
<version>
<release>1.4.0</release>
<api>1.4.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<license uri="http://opensource.org/licenses/bsd-license.php">BSD-2-Clause</license>
<notes>
* Change license to BSD-2-Clause
* Set minimum PHP version to 5.4.0
* Mark static methods with "static" keyword
</notes>
</release>
<release>
<date>2011-03-07</date>
<version>
<release>1.3.1</release>
<api>1.3.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<license uri="http://www.php.net/license">PHP License</license>
<notes>
* Change the minimum PEAR installer dep to be lower
</notes>
</release>
<release>
<date>2010-12-11</date>
<time>20:20:13</time>
<version>
<release>1.3.0</release>
<api>1.3.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<license uri="http://www.php.net/license">PHP License</license>
<notes>
* Implement Request #13140: [PATCH] to skip unknown parameters. [patch by rquadling, improved on by dufuz]
</notes>
</release>
<release>
<date>2007-06-12</date>
<version>
<release>1.2.3</release>
<api>1.2.1</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<license uri="http://www.php.net/license">PHP License</license>
<notes>
* fix Bug #11068: No way to read plain &quot;-&quot; option [cardoe]
</notes>
</release>
<release>
<version>
<release>1.2.2</release>
<api>1.2.1</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<date>2007-02-17</date>
<license uri="http://www.php.net/license">PHP License</license>
<notes>
* fix Bug #4475: An ambiguous error occurred when specifying similar longoption name.
* fix Bug #10055: Not failing properly on short options missing required values
</notes>
</release>
<release>
<version>
<release>1.2.1</release>
<api>1.2.1</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<date>2006-12-08</date>
<license uri="http://www.php.net/license">PHP License</license>
<notes>
Fixed bugs #4448 (Long parameter values truncated with longoption parameter) and #7444 (Trailing spaces after php closing tag)
</notes>
</release>
<release>
<version>
<release>1.2</release>
<api>1.2</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<date>2003-12-11</date>
<license uri="http://www.php.net/license">PHP License</license>
<notes>
Fix to preserve BC with 1.0 and allow correct behaviour for new users
</notes>
</release>
<release>
<version>
<release>1.0</release>
<api>1.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<date>2002-09-13</date>
<license uri="http://www.php.net/license">PHP License</license>
<notes>
Stable release
</notes>
</release>
<release>
<version>
<release>0.11</release>
<api>0.11</api>
</version>
<stability>
<release>beta</release>
<api>beta</api>
</stability>
<date>2002-05-26</date>
<license uri="http://www.php.net/license">PHP License</license>
<notes>
POSIX getopt compatibility fix: treat first element of args
array as command name
</notes>
</release>
<release>
<version>
<release>0.10</release>
<api>0.10</api>
</version>
<stability>
<release>beta</release>
<api>beta</api>
</stability>
<date>2002-05-12</date>
<license uri="http://www.php.net/license">PHP License</license>
<notes>
Packaging fix
</notes>
</release>
<release>
<version>
<release>0.9</release>
<api>0.9</api>
</version>
<stability>
<release>beta</release>
<api>beta</api>
</stability>
<date>2002-05-12</date>
<license uri="http://www.php.net/license">PHP License</license>
<notes>
Initial release
</notes>
</release>
</changelog>
</package>

View File

@@ -0,0 +1,63 @@
--TEST--
Console_Getopt
--FILE--
<?php
require_once 'Console/Getopt.php';
PEAR::setErrorHandling(PEAR_ERROR_PRINT, "%s\n\n");
function test($argstr, $optstr) {
$argv = preg_split('/[[:space:]]+/', $argstr);
if (PEAR::isError($options = Console_Getopt::getopt($argv, $optstr))) {
return;
}
$opts = $options[0];
$non_opts = $options[1];
$i = 0;
print "options: ";
foreach ($opts as $o => $d) {
if ($i++ > 0) {
print ", ";
}
print $d[0] . '=' . $d[1];
}
print "\n";
print "params: " . implode(", ", $non_opts) . "\n";
print "\n";
}
test("-abc", "abc");
test("-abc foo", "abc");
test("-abc foo", "abc:");
test("-abc foo bar gazonk", "abc");
test("-abc foo bar gazonk", "abc:");
test("-a -b -c", "abc");
test("-a -b -c", "abc:");
test("-abc", "ab:c");
test("-abc foo -bar gazonk", "abc");
?>
--EXPECT--
options: a=, b=, c=
params:
options: a=, b=, c=
params: foo
options: a=, b=, c=foo
params:
options: a=, b=, c=
params: foo, bar, gazonk
options: a=, b=, c=foo
params: bar, gazonk
options: a=, b=, c=
params:
Console_Getopt: option requires an argument --c
options: a=, b=c
params:
options: a=, b=, c=
params: foo, -bar, gazonk

View File

@@ -0,0 +1,22 @@
--TEST--
Console_Getopt [bug 10557]
--SKIPIF--
--FILE--
<?php
$_SERVER['argv'] =
$argv = array('hi', '-fjjohnston@mail.com', '--to', '--mailpack', '--debug');
require_once 'Console/Getopt.php';
$ret = Console_Getopt::getopt(Console_Getopt::readPHPArgv(), 'f:t:',
array('from=','to=','mailpack=','direction=','verbose','debug'));
if(PEAR::isError($ret))
{
echo $ret->getMessage()."\n";
echo 'FATAL';
exit;
}
print_r($ret);
?>
--EXPECT--
Console_Getopt: option requires an argument --to
FATAL

View File

@@ -0,0 +1,44 @@
--TEST--
Console_Getopt [bug 11068]
--SKIPIF--
--FILE--
<?php
$_SERVER['argv'] =
$argv = array('hi', '-fjjohnston@mail.com', '--to', 'hi', '-');
require_once 'Console/Getopt.php';
$ret = Console_Getopt::getopt(Console_Getopt::readPHPArgv(), 'f:t:',
array('from=','to=','mailpack=','direction=','verbose','debug'));
if(PEAR::isError($ret))
{
echo $ret->getMessage()."\n";
echo 'FATAL';
exit;
}
print_r($ret);
?>
--EXPECT--
Array
(
[0] => Array
(
[0] => Array
(
[0] => f
[1] => jjohnston@mail.com
)
[1] => Array
(
[0] => --to
[1] => hi
)
)
[1] => Array
(
[0] => -
)
)

View File

@@ -0,0 +1,75 @@
--TEST--
Console_Getopt [bug 13140]
--SKIPIF--
--FILE--
<?php
$_SERVER['argv'] = $argv =
array('--bob', '--foo' , '-bar', '--test', '-rq', 'thisshouldbehere');
require_once 'Console/Getopt.php';
$cg = new Console_GetOpt();
print_r($cg->getopt2($cg->readPHPArgv(), 't', array('test'), true));
print_r($cg->getopt2($cg->readPHPArgv(), 'bar', array('foo'), true));
?>
--EXPECT--
Array
(
[0] => Array
(
[0] => Array
(
[0] => --test
[1] =>
)
)
[1] => Array
(
[0] => thisshouldbehere
)
)
Array
(
[0] => Array
(
[0] => Array
(
[0] => --foo
[1] =>
)
[1] => Array
(
[0] => b
[1] =>
)
[2] => Array
(
[0] => a
[1] =>
)
[3] => Array
(
[0] => r
[1] =>
)
[4] => Array
(
[0] => r
[1] =>
)
)
[1] => Array
(
[0] => thisshouldbehere
)
)

View File

@@ -0,0 +1,26 @@
******************************
Minimal set of PEAR core files
******************************
This repository provides a set of files from ``pear-core``
that are often used in PEAR packages.
It follows the `pear-core`__ repository and gets updated whenever a new
PEAR version is released.
It's meant to be used as dependency for composer packages.
__ https://github.com/pear/pear-core
==============
Included files
==============
- ``OS/Guess.php``
- ``PEAR.php``
- ``PEAR/Error.php``
- ``PEAR/ErrorStack.php``
- ``System.php``
``PEAR/Error.php`` is a dummy file that only includes ``PEAR.php``,
to make autoloaders work without problems.

View File

@@ -0,0 +1,32 @@
{
"name": "pear/pear-core-minimal",
"description": "Minimal set of PEAR core files to be used as composer dependency",
"license": "BSD-3-Clause",
"authors": [
{
"email": "cweiske@php.net",
"name": "Christian Weiske",
"role": "Lead"
}
],
"autoload": {
"psr-0": {
"": "src/"
}
},
"include-path": [
"src/"
],
"support": {
"issues": "http://pear.php.net/bugs/search.php?cmd=display&package_name[]=PEAR",
"source": "https://github.com/pear/pear-core-minimal"
},
"type": "library",
"require": {
"pear/console_getopt": "~1.4",
"pear/pear_exception": "~1.0"
},
"replace": {
"rsky/pear-core-min": "self.version"
}
}

View File

@@ -0,0 +1,395 @@
<?php
/**
* The OS_Guess class
*
* PHP versions 4 and 5
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Gregory Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @link http://pear.php.net/package/PEAR
* @since File available since PEAR 0.1
*/
// {{{ uname examples
// php_uname() without args returns the same as 'uname -a', or a PHP-custom
// string for Windows.
// PHP versions prior to 4.3 return the uname of the host where PHP was built,
// as of 4.3 it returns the uname of the host running the PHP code.
//
// PC RedHat Linux 7.1:
// Linux host.example.com 2.4.2-2 #1 Sun Apr 8 20:41:30 EDT 2001 i686 unknown
//
// PC Debian Potato:
// Linux host 2.4.17 #2 SMP Tue Feb 12 15:10:04 CET 2002 i686 unknown
//
// PC FreeBSD 3.3:
// FreeBSD host.example.com 3.3-STABLE FreeBSD 3.3-STABLE #0: Mon Feb 21 00:42:31 CET 2000 root@example.com:/usr/src/sys/compile/CONFIG i386
//
// PC FreeBSD 4.3:
// FreeBSD host.example.com 4.3-RELEASE FreeBSD 4.3-RELEASE #1: Mon Jun 25 11:19:43 EDT 2001 root@example.com:/usr/src/sys/compile/CONFIG i386
//
// PC FreeBSD 4.5:
// FreeBSD host.example.com 4.5-STABLE FreeBSD 4.5-STABLE #0: Wed Feb 6 23:59:23 CET 2002 root@example.com:/usr/src/sys/compile/CONFIG i386
//
// PC FreeBSD 4.5 w/uname from GNU shellutils:
// FreeBSD host.example.com 4.5-STABLE FreeBSD 4.5-STABLE #0: Wed Feb i386 unknown
//
// HP 9000/712 HP-UX 10:
// HP-UX iq B.10.10 A 9000/712 2008429113 two-user license
//
// HP 9000/712 HP-UX 10 w/uname from GNU shellutils:
// HP-UX host B.10.10 A 9000/712 unknown
//
// IBM RS6000/550 AIX 4.3:
// AIX host 3 4 000003531C00
//
// AIX 4.3 w/uname from GNU shellutils:
// AIX host 3 4 000003531C00 unknown
//
// SGI Onyx IRIX 6.5 w/uname from GNU shellutils:
// IRIX64 host 6.5 01091820 IP19 mips
//
// SGI Onyx IRIX 6.5:
// IRIX64 host 6.5 01091820 IP19
//
// SparcStation 20 Solaris 8 w/uname from GNU shellutils:
// SunOS host.example.com 5.8 Generic_108528-12 sun4m sparc
//
// SparcStation 20 Solaris 8:
// SunOS host.example.com 5.8 Generic_108528-12 sun4m sparc SUNW,SPARCstation-20
//
// Mac OS X (Darwin)
// Darwin home-eden.local 7.5.0 Darwin Kernel Version 7.5.0: Thu Aug 5 19:26:16 PDT 2004; root:xnu/xnu-517.7.21.obj~3/RELEASE_PPC Power Macintosh
//
// Mac OS X early versions
//
// }}}
/* TODO:
* - define endianness, to allow matchSignature("bigend") etc.
*/
/**
* Retrieves information about the current operating system
*
* This class uses php_uname() to grok information about the current OS
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Gregory Beaver <cellog@php.net>
* @copyright 1997-2020 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: @package_version@
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 0.1
*/
class OS_Guess
{
var $sysname;
var $nodename;
var $cpu;
var $release;
var $extra;
function __construct($uname = null)
{
list($this->sysname,
$this->release,
$this->cpu,
$this->extra,
$this->nodename) = $this->parseSignature($uname);
}
function parseSignature($uname = null)
{
static $sysmap = array(
'HP-UX' => 'hpux',
'IRIX64' => 'irix',
);
static $cpumap = array(
'i586' => 'i386',
'i686' => 'i386',
'ppc' => 'powerpc',
);
if ($uname === null) {
$uname = php_uname();
}
$parts = preg_split('/\s+/', trim($uname));
$n = count($parts);
$release = $machine = $cpu = '';
$sysname = $parts[0];
$nodename = $parts[1];
$cpu = $parts[$n-1];
$extra = '';
if ($cpu == 'unknown') {
$cpu = $parts[$n - 2];
}
switch ($sysname) {
case 'AIX' :
$release = "$parts[3].$parts[2]";
break;
case 'Windows' :
$release = $parts[1];
if ($release == '95/98') {
$release = '9x';
}
$cpu = 'i386';
break;
case 'Linux' :
$extra = $this->_detectGlibcVersion();
// use only the first two digits from the kernel version
$release = preg_replace('/^([0-9]+\.[0-9]+).*/', '\1', $parts[2]);
break;
case 'Mac' :
$sysname = 'darwin';
$nodename = $parts[2];
$release = $parts[3];
$cpu = $this->_determineIfPowerpc($cpu, $parts);
break;
case 'Darwin' :
$cpu = $this->_determineIfPowerpc($cpu, $parts);
$release = preg_replace('/^([0-9]+\.[0-9]+).*/', '\1', $parts[2]);
break;
default:
$release = preg_replace('/-.*/', '', $parts[2]);
break;
}
if (isset($sysmap[$sysname])) {
$sysname = $sysmap[$sysname];
} else {
$sysname = strtolower($sysname);
}
if (isset($cpumap[$cpu])) {
$cpu = $cpumap[$cpu];
}
return array($sysname, $release, $cpu, $extra, $nodename);
}
function _determineIfPowerpc($cpu, $parts)
{
$n = count($parts);
if ($cpu == 'Macintosh' && $parts[$n - 2] == 'Power') {
$cpu = 'powerpc';
}
return $cpu;
}
function _detectGlibcVersion()
{
static $glibc = false;
if ($glibc !== false) {
return $glibc; // no need to run this multiple times
}
$major = $minor = 0;
include_once "System.php";
// Let's try reading possible libc.so.6 symlinks
$libcs = array(
'/lib64/libc.so.6',
'/lib/libc.so.6',
'/lib/i386-linux-gnu/libc.so.6'
);
$versions = array();
foreach ($libcs as $file) {
$versions = $this->_readGlibCVersionFromSymlink($file);
if ($versions != []) {
list($major, $minor) = $versions;
break;
}
}
// Use glibc's <features.h> header file to
// get major and minor version number:
if (!($major && $minor)) {
$versions = $this->_readGlibCVersionFromFeaturesHeaderFile();
}
if (is_array($versions) && $versions != []) {
list($major, $minor) = $versions;
}
if (!($major && $minor)) {
return $glibc = '';
}
return $glibc = "glibc{$major}.{$minor}";
}
function _readGlibCVersionFromSymlink($file)
{
$versions = array();
if (@is_link($file)
&& (preg_match('/^libc-(.*)\.so$/', basename(readlink($file)), $matches))
) {
$versions = explode('.', $matches[1]);
}
return $versions;
}
function _readGlibCVersionFromFeaturesHeaderFile()
{
$features_header_file = '/usr/include/features.h';
if (!(@file_exists($features_header_file)
&& @is_readable($features_header_file))
) {
return array();
}
if (!@file_exists('/usr/bin/cpp') || !@is_executable('/usr/bin/cpp')) {
return $this-_parseFeaturesHeaderFile($features_header_file);
} // no cpp
return $this->_fromGlibCTest();
}
function _parseFeaturesHeaderFile($features_header_file)
{
$features_file = fopen($features_header_file, 'rb');
while (!feof($features_file)) {
$line = fgets($features_file, 8192);
if (!$this->_IsADefinition($line)) {
continue;
}
if (strpos($line, '__GLIBC__')) {
// major version number #define __GLIBC__ version
$line = preg_split('/\s+/', $line);
$glibc_major = trim($line[2]);
if (isset($glibc_minor)) {
break;
}
continue;
}
if (strpos($line, '__GLIBC_MINOR__')) {
// got the minor version number
// #define __GLIBC_MINOR__ version
$line = preg_split('/\s+/', $line);
$glibc_minor = trim($line[2]);
if (isset($glibc_major)) {
break;
}
}
}
fclose($features_file);
if (!isset($glibc_major) || !isset($glibc_minor)) {
return array();
}
return array(trim($glibc_major), trim($glibc_minor));
}
function _IsADefinition($line)
{
if ($line === false) {
return false;
}
return strpos(trim($line), '#define') !== false;
}
function _fromGlibCTest()
{
$major = null;
$minor = null;
$tmpfile = System::mktemp("glibctest");
$fp = fopen($tmpfile, "w");
fwrite($fp, "#include <features.h>\n__GLIBC__ __GLIBC_MINOR__\n");
fclose($fp);
$cpp = popen("/usr/bin/cpp $tmpfile", "r");
while ($line = fgets($cpp, 1024)) {
if ($line[0] == '#' || trim($line) == '') {
continue;
}
if (list($major, $minor) = explode(' ', trim($line))) {
break;
}
}
pclose($cpp);
unlink($tmpfile);
if ($major !== null && $minor !== null) {
return [$major, $minor];
}
}
function getSignature()
{
if (empty($this->extra)) {
return "{$this->sysname}-{$this->release}-{$this->cpu}";
}
return "{$this->sysname}-{$this->release}-{$this->cpu}-{$this->extra}";
}
function getSysname()
{
return $this->sysname;
}
function getNodename()
{
return $this->nodename;
}
function getCpu()
{
return $this->cpu;
}
function getRelease()
{
return $this->release;
}
function getExtra()
{
return $this->extra;
}
function matchSignature($match)
{
$fragments = is_array($match) ? $match : explode('-', $match);
$n = count($fragments);
$matches = 0;
if ($n > 0) {
$matches += $this->_matchFragment($fragments[0], $this->sysname);
}
if ($n > 1) {
$matches += $this->_matchFragment($fragments[1], $this->release);
}
if ($n > 2) {
$matches += $this->_matchFragment($fragments[2], $this->cpu);
}
if ($n > 3) {
$matches += $this->_matchFragment($fragments[3], $this->extra);
}
return ($matches == $n);
}
function _matchFragment($fragment, $value)
{
if (strcspn($fragment, '*?') < strlen($fragment)) {
$expression = str_replace(
array('*', '?', '/'),
array('.*', '.', '\\/'),
$fragment
);
$reg = '/^' . $expression . '\\z/';
return preg_match($reg, $value);
}
return ($fragment == '*' || !strcasecmp($fragment, $value));
}
}
/*
* Local Variables:
* indent-tabs-mode: nil
* c-basic-offset: 4
* End:
*/

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,14 @@
<?php
/**
* Dummy file to make autoloaders work
*
* PHP version 5
*
* @category PEAR
* @package PEAR
* @author Christian Weiske <cweiske@php.net>
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @link http://pear.php.net/package/PEAR
*/
require_once __DIR__ . '/../PEAR.php';
?>

View File

@@ -0,0 +1,979 @@
<?php
/**
* Error Stack Implementation
*
* This is an incredibly simple implementation of a very complex error handling
* facility. It contains the ability
* to track multiple errors from multiple packages simultaneously. In addition,
* it can track errors of many levels, save data along with the error, context
* information such as the exact file, line number, class and function that
* generated the error, and if necessary, it can raise a traditional PEAR_Error.
* It has built-in support for PEAR::Log, to log errors as they occur
*
* Since version 0.2alpha, it is also possible to selectively ignore errors,
* through the use of an error callback, see {@link pushCallback()}
*
* Since version 0.3alpha, it is possible to specify the exception class
* returned from {@link push()}
*
* Since version PEAR1.3.2, ErrorStack no longer instantiates an exception class. This can
* still be done quite handily in an error callback or by manipulating the returned array
* @category Debugging
* @package PEAR_ErrorStack
* @author Greg Beaver <cellog@php.net>
* @copyright 2004-2008 Greg Beaver
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @link http://pear.php.net/package/PEAR_ErrorStack
*/
/**
* Singleton storage
*
* Format:
* <pre>
* array(
* 'package1' => PEAR_ErrorStack object,
* 'package2' => PEAR_ErrorStack object,
* ...
* )
* </pre>
* @access private
* @global array $GLOBALS['_PEAR_ERRORSTACK_SINGLETON']
*/
$GLOBALS['_PEAR_ERRORSTACK_SINGLETON'] = array();
/**
* Global error callback (default)
*
* This is only used if set to non-false. * is the default callback for
* all packages, whereas specific packages may set a default callback
* for all instances, regardless of whether they are a singleton or not.
*
* To exclude non-singletons, only set the local callback for the singleton
* @see PEAR_ErrorStack::setDefaultCallback()
* @access private
* @global array $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK']
*/
$GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'] = array(
'*' => false,
);
/**
* Global Log object (default)
*
* This is only used if set to non-false. Use to set a default log object for
* all stacks, regardless of instantiation order or location
* @see PEAR_ErrorStack::setDefaultLogger()
* @access private
* @global array $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER']
*/
$GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] = false;
/**
* Global Overriding Callback
*
* This callback will override any error callbacks that specific loggers have set.
* Use with EXTREME caution
* @see PEAR_ErrorStack::staticPushCallback()
* @access private
* @global array $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER']
*/
$GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'] = array();
/**#@+
* One of four possible return values from the error Callback
* @see PEAR_ErrorStack::_errorCallback()
*/
/**
* If this is returned, then the error will be both pushed onto the stack
* and logged.
*/
define('PEAR_ERRORSTACK_PUSHANDLOG', 1);
/**
* If this is returned, then the error will only be pushed onto the stack,
* and not logged.
*/
define('PEAR_ERRORSTACK_PUSH', 2);
/**
* If this is returned, then the error will only be logged, but not pushed
* onto the error stack.
*/
define('PEAR_ERRORSTACK_LOG', 3);
/**
* If this is returned, then the error is completely ignored.
*/
define('PEAR_ERRORSTACK_IGNORE', 4);
/**
* If this is returned, then the error is logged and die() is called.
*/
define('PEAR_ERRORSTACK_DIE', 5);
/**#@-*/
/**
* Error code for an attempt to instantiate a non-class as a PEAR_ErrorStack in
* the singleton method.
*/
define('PEAR_ERRORSTACK_ERR_NONCLASS', 1);
/**
* Error code for an attempt to pass an object into {@link PEAR_ErrorStack::getMessage()}
* that has no __toString() method
*/
define('PEAR_ERRORSTACK_ERR_OBJTOSTRING', 2);
/**
* Error Stack Implementation
*
* Usage:
* <code>
* // global error stack
* $global_stack = &PEAR_ErrorStack::singleton('MyPackage');
* // local error stack
* $local_stack = new PEAR_ErrorStack('MyPackage');
* </code>
* @author Greg Beaver <cellog@php.net>
* @version @package_version@
* @package PEAR_ErrorStack
* @category Debugging
* @copyright 2004-2008 Greg Beaver
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @link http://pear.php.net/package/PEAR_ErrorStack
*/
class PEAR_ErrorStack {
/**
* Errors are stored in the order that they are pushed on the stack.
* @since 0.4alpha Errors are no longer organized by error level.
* This renders pop() nearly unusable, and levels could be more easily
* handled in a callback anyway
* @var array
* @access private
*/
var $_errors = array();
/**
* Storage of errors by level.
*
* Allows easy retrieval and deletion of only errors from a particular level
* @since PEAR 1.4.0dev
* @var array
* @access private
*/
var $_errorsByLevel = array();
/**
* Package name this error stack represents
* @var string
* @access protected
*/
var $_package;
/**
* Determines whether a PEAR_Error is thrown upon every error addition
* @var boolean
* @access private
*/
var $_compat = false;
/**
* If set to a valid callback, this will be used to generate the error
* message from the error code, otherwise the message passed in will be
* used
* @var false|string|array
* @access private
*/
var $_msgCallback = false;
/**
* If set to a valid callback, this will be used to generate the error
* context for an error. For PHP-related errors, this will be a file
* and line number as retrieved from debug_backtrace(), but can be
* customized for other purposes. The error might actually be in a separate
* configuration file, or in a database query.
* @var false|string|array
* @access protected
*/
var $_contextCallback = false;
/**
* If set to a valid callback, this will be called every time an error
* is pushed onto the stack. The return value will be used to determine
* whether to allow an error to be pushed or logged.
*
* The return value must be one an PEAR_ERRORSTACK_* constant
* @see PEAR_ERRORSTACK_PUSHANDLOG, PEAR_ERRORSTACK_PUSH, PEAR_ERRORSTACK_LOG
* @var false|string|array
* @access protected
*/
var $_errorCallback = array();
/**
* PEAR::Log object for logging errors
* @var false|Log
* @access protected
*/
var $_logger = false;
/**
* Error messages - designed to be overridden
* @var array
* @abstract
*/
var $_errorMsgs = array();
/**
* Set up a new error stack
*
* @param string $package name of the package this error stack represents
* @param callback $msgCallback callback used for error message generation
* @param callback $contextCallback callback used for context generation,
* defaults to {@link getFileLine()}
* @param boolean $throwPEAR_Error
*/
function __construct($package, $msgCallback = false, $contextCallback = false,
$throwPEAR_Error = false)
{
$this->_package = $package;
$this->setMessageCallback($msgCallback);
$this->setContextCallback($contextCallback);
$this->_compat = $throwPEAR_Error;
}
/**
* Return a single error stack for this package.
*
* Note that all parameters are ignored if the stack for package $package
* has already been instantiated
* @param string $package name of the package this error stack represents
* @param callback $msgCallback callback used for error message generation
* @param callback $contextCallback callback used for context generation,
* defaults to {@link getFileLine()}
* @param boolean $throwPEAR_Error
* @param string $stackClass class to instantiate
*
* @return PEAR_ErrorStack
*/
public static function &singleton(
$package, $msgCallback = false, $contextCallback = false,
$throwPEAR_Error = false, $stackClass = 'PEAR_ErrorStack'
) {
if (isset($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package])) {
return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package];
}
if (!class_exists($stackClass)) {
if (function_exists('debug_backtrace')) {
$trace = debug_backtrace();
}
PEAR_ErrorStack::staticPush('PEAR_ErrorStack', PEAR_ERRORSTACK_ERR_NONCLASS,
'exception', array('stackclass' => $stackClass),
'stack class "%stackclass%" is not a valid class name (should be like PEAR_ErrorStack)',
false, $trace);
}
$GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package] =
new $stackClass($package, $msgCallback, $contextCallback, $throwPEAR_Error);
return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package];
}
/**
* Internal error handler for PEAR_ErrorStack class
*
* Dies if the error is an exception (and would have died anyway)
* @access private
*/
function _handleError($err)
{
if ($err['level'] == 'exception') {
$message = $err['message'];
if (isset($_SERVER['REQUEST_URI'])) {
echo '<br />';
} else {
echo "\n";
}
var_dump($err['context']);
die($message);
}
}
/**
* Set up a PEAR::Log object for all error stacks that don't have one
* @param Log $log
*/
public static function setDefaultLogger(&$log)
{
if (is_object($log) && method_exists($log, 'log') ) {
$GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] = &$log;
} elseif (is_callable($log)) {
$GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] = &$log;
}
}
/**
* Set up a PEAR::Log object for this error stack
* @param Log $log
*/
function setLogger(&$log)
{
if (is_object($log) && method_exists($log, 'log') ) {
$this->_logger = &$log;
} elseif (is_callable($log)) {
$this->_logger = &$log;
}
}
/**
* Set an error code => error message mapping callback
*
* This method sets the callback that can be used to generate error
* messages for any instance
* @param array|string Callback function/method
*/
function setMessageCallback($msgCallback)
{
if (!$msgCallback) {
$this->_msgCallback = array(&$this, 'getErrorMessage');
} else {
if (is_callable($msgCallback)) {
$this->_msgCallback = $msgCallback;
}
}
}
/**
* Get an error code => error message mapping callback
*
* This method returns the current callback that can be used to generate error
* messages
* @return array|string|false Callback function/method or false if none
*/
function getMessageCallback()
{
return $this->_msgCallback;
}
/**
* Sets a default callback to be used by all error stacks
*
* This method sets the callback that can be used to generate error
* messages for a singleton
* @param array|string Callback function/method
* @param string Package name, or false for all packages
*/
public static function setDefaultCallback($callback = false, $package = false)
{
if (!is_callable($callback)) {
$callback = false;
}
$package = $package ? $package : '*';
$GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'][$package] = $callback;
}
/**
* Set a callback that generates context information (location of error) for an error stack
*
* This method sets the callback that can be used to generate context
* information for an error. Passing in NULL will disable context generation
* and remove the expensive call to debug_backtrace()
* @param array|string|null Callback function/method
*/
function setContextCallback($contextCallback)
{
if ($contextCallback === null) {
return $this->_contextCallback = false;
}
if (!$contextCallback) {
$this->_contextCallback = array(&$this, 'getFileLine');
} else {
if (is_callable($contextCallback)) {
$this->_contextCallback = $contextCallback;
}
}
}
/**
* Set an error Callback
* If set to a valid callback, this will be called every time an error
* is pushed onto the stack. The return value will be used to determine
* whether to allow an error to be pushed or logged.
*
* The return value must be one of the ERRORSTACK_* constants.
*
* This functionality can be used to emulate PEAR's pushErrorHandling, and
* the PEAR_ERROR_CALLBACK mode, without affecting the integrity of
* the error stack or logging
* @see PEAR_ERRORSTACK_PUSHANDLOG, PEAR_ERRORSTACK_PUSH, PEAR_ERRORSTACK_LOG
* @see popCallback()
* @param string|array $cb
*/
function pushCallback($cb)
{
array_push($this->_errorCallback, $cb);
}
/**
* Remove a callback from the error callback stack
* @see pushCallback()
* @return array|string|false
*/
function popCallback()
{
if (!count($this->_errorCallback)) {
return false;
}
return array_pop($this->_errorCallback);
}
/**
* Set a temporary overriding error callback for every package error stack
*
* Use this to temporarily disable all existing callbacks (can be used
* to emulate the @ operator, for instance)
* @see PEAR_ERRORSTACK_PUSHANDLOG, PEAR_ERRORSTACK_PUSH, PEAR_ERRORSTACK_LOG
* @see staticPopCallback(), pushCallback()
* @param string|array $cb
*/
public static function staticPushCallback($cb)
{
array_push($GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'], $cb);
}
/**
* Remove a temporary overriding error callback
* @see staticPushCallback()
* @return array|string|false
*/
public static function staticPopCallback()
{
$ret = array_pop($GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK']);
if (!is_array($GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'])) {
$GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'] = array();
}
return $ret;
}
/**
* Add an error to the stack
*
* If the message generator exists, it is called with 2 parameters.
* - the current Error Stack object
* - an array that is in the same format as an error. Available indices
* are 'code', 'package', 'time', 'params', 'level', and 'context'
*
* Next, if the error should contain context information, this is
* handled by the context grabbing method.
* Finally, the error is pushed onto the proper error stack
* @param int $code Package-specific error code
* @param string $level Error level. This is NOT spell-checked
* @param array $params associative array of error parameters
* @param string $msg Error message, or a portion of it if the message
* is to be generated
* @param array $repackage If this error re-packages an error pushed by
* another package, place the array returned from
* {@link pop()} in this parameter
* @param array $backtrace Protected parameter: use this to pass in the
* {@link debug_backtrace()} that should be used
* to find error context
* @return PEAR_Error|array if compatibility mode is on, a PEAR_Error is also
* thrown. If a PEAR_Error is returned, the userinfo
* property is set to the following array:
*
* <code>
* array(
* 'code' => $code,
* 'params' => $params,
* 'package' => $this->_package,
* 'level' => $level,
* 'time' => time(),
* 'context' => $context,
* 'message' => $msg,
* //['repackage' => $err] repackaged error array/Exception class
* );
* </code>
*
* Normally, the previous array is returned.
*/
function push($code, $level = 'error', $params = array(), $msg = false,
$repackage = false, $backtrace = false)
{
$context = false;
// grab error context
if ($this->_contextCallback) {
if (!$backtrace) {
$backtrace = debug_backtrace();
}
$context = call_user_func($this->_contextCallback, $code, $params, $backtrace);
}
// save error
$time = explode(' ', microtime());
$time = $time[1] + $time[0];
$err = array(
'code' => $code,
'params' => $params,
'package' => $this->_package,
'level' => $level,
'time' => $time,
'context' => $context,
'message' => $msg,
);
if ($repackage) {
$err['repackage'] = $repackage;
}
// set up the error message, if necessary
if ($this->_msgCallback) {
$msg = call_user_func_array($this->_msgCallback,
array(&$this, $err));
$err['message'] = $msg;
}
$push = $log = true;
$die = false;
// try the overriding callback first
$callback = $this->staticPopCallback();
if ($callback) {
$this->staticPushCallback($callback);
}
if (!is_callable($callback)) {
// try the local callback next
$callback = $this->popCallback();
if (is_callable($callback)) {
$this->pushCallback($callback);
} else {
// try the default callback
$callback = isset($GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'][$this->_package]) ?
$GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'][$this->_package] :
$GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK']['*'];
}
}
if (is_callable($callback)) {
switch(call_user_func($callback, $err)){
case PEAR_ERRORSTACK_IGNORE:
return $err;
break;
case PEAR_ERRORSTACK_PUSH:
$log = false;
break;
case PEAR_ERRORSTACK_LOG:
$push = false;
break;
case PEAR_ERRORSTACK_DIE:
$die = true;
break;
// anything else returned has the same effect as pushandlog
}
}
if ($push) {
array_unshift($this->_errors, $err);
if (!isset($this->_errorsByLevel[$err['level']])) {
$this->_errorsByLevel[$err['level']] = array();
}
$this->_errorsByLevel[$err['level']][] = &$this->_errors[0];
}
if ($log) {
if ($this->_logger || $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER']) {
$this->_log($err);
}
}
if ($die) {
die();
}
if ($this->_compat && $push) {
return $this->raiseError($msg, $code, null, null, $err);
}
return $err;
}
/**
* Static version of {@link push()}
*
* @param string $package Package name this error belongs to
* @param int $code Package-specific error code
* @param string $level Error level. This is NOT spell-checked
* @param array $params associative array of error parameters
* @param string $msg Error message, or a portion of it if the message
* is to be generated
* @param array $repackage If this error re-packages an error pushed by
* another package, place the array returned from
* {@link pop()} in this parameter
* @param array $backtrace Protected parameter: use this to pass in the
* {@link debug_backtrace()} that should be used
* to find error context
* @return PEAR_Error|array if compatibility mode is on, a PEAR_Error is also
* thrown. see docs for {@link push()}
*/
public static function staticPush(
$package, $code, $level = 'error', $params = array(),
$msg = false, $repackage = false, $backtrace = false
) {
$s = &PEAR_ErrorStack::singleton($package);
if ($s->_contextCallback) {
if (!$backtrace) {
if (function_exists('debug_backtrace')) {
$backtrace = debug_backtrace();
}
}
}
return $s->push($code, $level, $params, $msg, $repackage, $backtrace);
}
/**
* Log an error using PEAR::Log
* @param array $err Error array
* @param array $levels Error level => Log constant map
* @access protected
*/
function _log($err)
{
if ($this->_logger) {
$logger = &$this->_logger;
} else {
$logger = &$GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'];
}
if (is_a($logger, 'Log')) {
$levels = array(
'exception' => PEAR_LOG_CRIT,
'alert' => PEAR_LOG_ALERT,
'critical' => PEAR_LOG_CRIT,
'error' => PEAR_LOG_ERR,
'warning' => PEAR_LOG_WARNING,
'notice' => PEAR_LOG_NOTICE,
'info' => PEAR_LOG_INFO,
'debug' => PEAR_LOG_DEBUG);
if (isset($levels[$err['level']])) {
$level = $levels[$err['level']];
} else {
$level = PEAR_LOG_INFO;
}
$logger->log($err['message'], $level, $err);
} else { // support non-standard logs
call_user_func($logger, $err);
}
}
/**
* Pop an error off of the error stack
*
* @return false|array
* @since 0.4alpha it is no longer possible to specify a specific error
* level to return - the last error pushed will be returned, instead
*/
function pop()
{
$err = @array_shift($this->_errors);
if (!is_null($err)) {
@array_pop($this->_errorsByLevel[$err['level']]);
if (!count($this->_errorsByLevel[$err['level']])) {
unset($this->_errorsByLevel[$err['level']]);
}
}
return $err;
}
/**
* Pop an error off of the error stack, static method
*
* @param string package name
* @return boolean
* @since PEAR1.5.0a1
*/
static function staticPop($package)
{
if ($package) {
if (!isset($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package])) {
return false;
}
return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]->pop();
}
}
/**
* Determine whether there are any errors on the stack
* @param string|array Level name. Use to determine if any errors
* of level (string), or levels (array) have been pushed
* @return boolean
*/
function hasErrors($level = false)
{
if ($level) {
return isset($this->_errorsByLevel[$level]);
}
return count($this->_errors);
}
/**
* Retrieve all errors since last purge
*
* @param boolean set in order to empty the error stack
* @param string level name, to return only errors of a particular severity
* @return array
*/
function getErrors($purge = false, $level = false)
{
if (!$purge) {
if ($level) {
if (!isset($this->_errorsByLevel[$level])) {
return array();
} else {
return $this->_errorsByLevel[$level];
}
} else {
return $this->_errors;
}
}
if ($level) {
$ret = $this->_errorsByLevel[$level];
foreach ($this->_errorsByLevel[$level] as $i => $unused) {
// entries are references to the $_errors array
$this->_errorsByLevel[$level][$i] = false;
}
// array_filter removes all entries === false
$this->_errors = array_filter($this->_errors);
unset($this->_errorsByLevel[$level]);
return $ret;
}
$ret = $this->_errors;
$this->_errors = array();
$this->_errorsByLevel = array();
return $ret;
}
/**
* Determine whether there are any errors on a single error stack, or on any error stack
*
* The optional parameter can be used to test the existence of any errors without the need of
* singleton instantiation
* @param string|false Package name to check for errors
* @param string Level name to check for a particular severity
* @return boolean
*/
public static function staticHasErrors($package = false, $level = false)
{
if ($package) {
if (!isset($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package])) {
return false;
}
return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]->hasErrors($level);
}
foreach ($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'] as $package => $obj) {
if ($obj->hasErrors($level)) {
return true;
}
}
return false;
}
/**
* Get a list of all errors since last purge, organized by package
* @since PEAR 1.4.0dev BC break! $level is now in the place $merge used to be
* @param boolean $purge Set to purge the error stack of existing errors
* @param string $level Set to a level name in order to retrieve only errors of a particular level
* @param boolean $merge Set to return a flat array, not organized by package
* @param array $sortfunc Function used to sort a merged array - default
* sorts by time, and should be good for most cases
*
* @return array
*/
public static function staticGetErrors(
$purge = false, $level = false, $merge = false,
$sortfunc = array('PEAR_ErrorStack', '_sortErrors')
) {
$ret = array();
if (!is_callable($sortfunc)) {
$sortfunc = array('PEAR_ErrorStack', '_sortErrors');
}
foreach ($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'] as $package => $obj) {
$test = $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]->getErrors($purge, $level);
if ($test) {
if ($merge) {
$ret = array_merge($ret, $test);
} else {
$ret[$package] = $test;
}
}
}
if ($merge) {
usort($ret, $sortfunc);
}
return $ret;
}
/**
* Error sorting function, sorts by time
* @access private
*/
public static function _sortErrors($a, $b)
{
if ($a['time'] == $b['time']) {
return 0;
}
if ($a['time'] < $b['time']) {
return 1;
}
return -1;
}
/**
* Standard file/line number/function/class context callback
*
* This function uses a backtrace generated from {@link debug_backtrace()}
* and so will not work at all in PHP < 4.3.0. The frame should
* reference the frame that contains the source of the error.
* @return array|false either array('file' => file, 'line' => line,
* 'function' => function name, 'class' => class name) or
* if this doesn't work, then false
* @param unused
* @param integer backtrace frame.
* @param array Results of debug_backtrace()
*/
public static function getFileLine($code, $params, $backtrace = null)
{
if ($backtrace === null) {
return false;
}
$frame = 0;
$functionframe = 1;
if (!isset($backtrace[1])) {
$functionframe = 0;
} else {
while (isset($backtrace[$functionframe]['function']) &&
$backtrace[$functionframe]['function'] == 'eval' &&
isset($backtrace[$functionframe + 1])) {
$functionframe++;
}
}
if (isset($backtrace[$frame])) {
if (!isset($backtrace[$frame]['file'])) {
$frame++;
}
$funcbacktrace = $backtrace[$functionframe];
$filebacktrace = $backtrace[$frame];
$ret = array('file' => $filebacktrace['file'],
'line' => $filebacktrace['line']);
// rearrange for eval'd code or create function errors
if (strpos($filebacktrace['file'], '(') &&
preg_match(';^(.*?)\((\d+)\) : (.*?)\\z;', $filebacktrace['file'],
$matches)) {
$ret['file'] = $matches[1];
$ret['line'] = $matches[2] + 0;
}
if (isset($funcbacktrace['function']) && isset($backtrace[1])) {
if ($funcbacktrace['function'] != 'eval') {
if ($funcbacktrace['function'] == '__lambda_func') {
$ret['function'] = 'create_function() code';
} else {
$ret['function'] = $funcbacktrace['function'];
}
}
}
if (isset($funcbacktrace['class']) && isset($backtrace[1])) {
$ret['class'] = $funcbacktrace['class'];
}
return $ret;
}
return false;
}
/**
* Standard error message generation callback
*
* This method may also be called by a custom error message generator
* to fill in template values from the params array, simply
* set the third parameter to the error message template string to use
*
* The special variable %__msg% is reserved: use it only to specify
* where a message passed in by the user should be placed in the template,
* like so:
*
* Error message: %msg% - internal error
*
* If the message passed like so:
*
* <code>
* $stack->push(ERROR_CODE, 'error', array(), 'server error 500');
* </code>
*
* The returned error message will be "Error message: server error 500 -
* internal error"
* @param PEAR_ErrorStack
* @param array
* @param string|false Pre-generated error message template
*
* @return string
*/
public static function getErrorMessage(&$stack, $err, $template = false)
{
if ($template) {
$mainmsg = $template;
} else {
$mainmsg = $stack->getErrorMessageTemplate($err['code']);
}
$mainmsg = str_replace('%__msg%', $err['message'], $mainmsg);
if (is_array($err['params']) && count($err['params'])) {
foreach ($err['params'] as $name => $val) {
if (is_array($val)) {
// @ is needed in case $val is a multi-dimensional array
$val = @implode(', ', $val);
}
if (is_object($val)) {
if (method_exists($val, '__toString')) {
$val = $val->__toString();
} else {
PEAR_ErrorStack::staticPush('PEAR_ErrorStack', PEAR_ERRORSTACK_ERR_OBJTOSTRING,
'warning', array('obj' => get_class($val)),
'object %obj% passed into getErrorMessage, but has no __toString() method');
$val = 'Object';
}
}
$mainmsg = str_replace('%' . $name . '%', $val, $mainmsg);
}
}
return $mainmsg;
}
/**
* Standard Error Message Template generator from code
* @return string
*/
function getErrorMessageTemplate($code)
{
if (!isset($this->_errorMsgs[$code])) {
return '%__msg%';
}
return $this->_errorMsgs[$code];
}
/**
* Set the Error Message Template array
*
* The array format must be:
* <pre>
* array(error code => 'message template',...)
* </pre>
*
* Error message parameters passed into {@link push()} will be used as input
* for the error message. If the template is 'message %foo% was %bar%', and the
* parameters are array('foo' => 'one', 'bar' => 'six'), the error message returned will
* be 'message one was six'
* @return string
*/
function setErrorMessageTemplate($template)
{
$this->_errorMsgs = $template;
}
/**
* emulate PEAR::raiseError()
*
* @return PEAR_Error
*/
function raiseError()
{
require_once 'PEAR.php';
$args = func_get_args();
return call_user_func_array(array('PEAR', 'raiseError'), $args);
}
}
$stack = &PEAR_ErrorStack::singleton('PEAR_ErrorStack');
$stack->pushCallback(array('PEAR_ErrorStack', '_handleError'));
?>

View File

@@ -0,0 +1,630 @@
<?php
/**
* File/Directory manipulation
*
* PHP versions 4 and 5
*
* @category pear
* @package System
* @author Tomas V.V.Cox <cox@idecnet.com>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @link http://pear.php.net/package/PEAR
* @since File available since Release 0.1
*/
/**
* base class
*/
require_once 'PEAR.php';
require_once 'Console/Getopt.php';
$GLOBALS['_System_temp_files'] = array();
/**
* System offers cross platform compatible system functions
*
* Static functions for different operations. Should work under
* Unix and Windows. The names and usage has been taken from its respectively
* GNU commands. The functions will return (bool) false on error and will
* trigger the error with the PHP trigger_error() function (you can silence
* the error by prefixing a '@' sign after the function call, but this
* is not recommended practice. Instead use an error handler with
* {@link set_error_handler()}).
*
* Documentation on this class you can find in:
* http://pear.php.net/manual/
*
* Example usage:
* if (!@System::rm('-r file1 dir1')) {
* print "could not delete file1 or dir1";
* }
*
* In case you need to to pass file names with spaces,
* pass the params as an array:
*
* System::rm(array('-r', $file1, $dir1));
*
* @category pear
* @package System
* @author Tomas V.V. Cox <cox@idecnet.com>
* @copyright 1997-2006 The PHP Group
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: @package_version@
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 0.1
* @static
*/
class System
{
/**
* returns the commandline arguments of a function
*
* @param string $argv the commandline
* @param string $short_options the allowed option short-tags
* @param string $long_options the allowed option long-tags
* @return array the given options and there values
*/
public static function _parseArgs($argv, $short_options, $long_options = null)
{
if (!is_array($argv) && $argv !== null) {
/*
// Quote all items that are a short option
$av = preg_split('/(\A| )--?[a-z0-9]+[ =]?((?<!\\\\)((,\s*)|((?<!,)\s+))?)/i', $argv, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_OFFSET_CAPTURE);
$offset = 0;
foreach ($av as $a) {
$b = trim($a[0]);
if ($b[0] == '"' || $b[0] == "'") {
continue;
}
$escape = escapeshellarg($b);
$pos = $a[1] + $offset;
$argv = substr_replace($argv, $escape, $pos, strlen($b));
$offset += 2;
}
*/
// Find all items, quoted or otherwise
preg_match_all("/(?:[\"'])(.*?)(?:['\"])|([^\s]+)/", $argv, $av);
$argv = $av[1];
foreach ($av[2] as $k => $a) {
if (empty($a)) {
continue;
}
$argv[$k] = trim($a) ;
}
}
return Console_Getopt::getopt2($argv, $short_options, $long_options);
}
/**
* Output errors with PHP trigger_error(). You can silence the errors
* with prefixing a "@" sign to the function call: @System::mkdir(..);
*
* @param mixed $error a PEAR error or a string with the error message
* @return bool false
*/
protected static function raiseError($error)
{
if (PEAR::isError($error)) {
$error = $error->getMessage();
}
trigger_error($error, E_USER_WARNING);
return false;
}
/**
* Creates a nested array representing the structure of a directory
*
* System::_dirToStruct('dir1', 0) =>
* Array
* (
* [dirs] => Array
* (
* [0] => dir1
* )
*
* [files] => Array
* (
* [0] => dir1/file2
* [1] => dir1/file3
* )
* )
* @param string $sPath Name of the directory
* @param integer $maxinst max. deep of the lookup
* @param integer $aktinst starting deep of the lookup
* @param bool $silent if true, do not emit errors.
* @return array the structure of the dir
*/
protected static function _dirToStruct($sPath, $maxinst, $aktinst = 0, $silent = false)
{
$struct = array('dirs' => array(), 'files' => array());
if (($dir = @opendir($sPath)) === false) {
if (!$silent) {
System::raiseError("Could not open dir $sPath");
}
return $struct; // XXX could not open error
}
$struct['dirs'][] = $sPath = realpath($sPath); // XXX don't add if '.' or '..' ?
$list = array();
while (false !== ($file = readdir($dir))) {
if ($file != '.' && $file != '..') {
$list[] = $file;
}
}
closedir($dir);
natsort($list);
if ($aktinst < $maxinst || $maxinst == 0) {
foreach ($list as $val) {
$path = $sPath . DIRECTORY_SEPARATOR . $val;
if (is_dir($path) && !is_link($path)) {
$tmp = System::_dirToStruct($path, $maxinst, $aktinst+1, $silent);
$struct = array_merge_recursive($struct, $tmp);
} else {
$struct['files'][] = $path;
}
}
}
return $struct;
}
/**
* Creates a nested array representing the structure of a directory and files
*
* @param array $files Array listing files and dirs
* @return array
* @static
* @see System::_dirToStruct()
*/
protected static function _multipleToStruct($files)
{
$struct = array('dirs' => array(), 'files' => array());
settype($files, 'array');
foreach ($files as $file) {
if (is_dir($file) && !is_link($file)) {
$tmp = System::_dirToStruct($file, 0);
$struct = array_merge_recursive($tmp, $struct);
} else {
if (!in_array($file, $struct['files'])) {
$struct['files'][] = $file;
}
}
}
return $struct;
}
/**
* The rm command for removing files.
* Supports multiple files and dirs and also recursive deletes
*
* @param string $args the arguments for rm
* @return mixed PEAR_Error or true for success
* @static
* @access public
*/
public static function rm($args)
{
$opts = System::_parseArgs($args, 'rf'); // "f" does nothing but I like it :-)
if (PEAR::isError($opts)) {
return System::raiseError($opts);
}
foreach ($opts[0] as $opt) {
if ($opt[0] == 'r') {
$do_recursive = true;
}
}
$ret = true;
if (isset($do_recursive)) {
$struct = System::_multipleToStruct($opts[1]);
foreach ($struct['files'] as $file) {
if (!@unlink($file)) {
$ret = false;
}
}
rsort($struct['dirs']);
foreach ($struct['dirs'] as $dir) {
if (!@rmdir($dir)) {
$ret = false;
}
}
} else {
foreach ($opts[1] as $file) {
$delete = (is_dir($file)) ? 'rmdir' : 'unlink';
if (!@$delete($file)) {
$ret = false;
}
}
}
return $ret;
}
/**
* Make directories.
*
* The -p option will create parent directories
* @param string $args the name of the director(y|ies) to create
* @return bool True for success
*/
public static function mkDir($args)
{
$opts = System::_parseArgs($args, 'pm:');
if (PEAR::isError($opts)) {
return System::raiseError($opts);
}
$mode = 0777; // default mode
foreach ($opts[0] as $opt) {
if ($opt[0] == 'p') {
$create_parents = true;
} elseif ($opt[0] == 'm') {
// if the mode is clearly an octal number (starts with 0)
// convert it to decimal
if (strlen($opt[1]) && $opt[1][0] == '0') {
$opt[1] = octdec($opt[1]);
} else {
// convert to int
$opt[1] += 0;
}
$mode = $opt[1];
}
}
$ret = true;
if (isset($create_parents)) {
foreach ($opts[1] as $dir) {
$dirstack = array();
while ((!file_exists($dir) || !is_dir($dir)) &&
$dir != DIRECTORY_SEPARATOR) {
array_unshift($dirstack, $dir);
$dir = dirname($dir);
}
while ($newdir = array_shift($dirstack)) {
if (!is_writeable(dirname($newdir))) {
$ret = false;
break;
}
if (!mkdir($newdir, $mode)) {
$ret = false;
}
}
}
} else {
foreach($opts[1] as $dir) {
if ((@file_exists($dir) || !is_dir($dir)) && !mkdir($dir, $mode)) {
$ret = false;
}
}
}
return $ret;
}
/**
* Concatenate files
*
* Usage:
* 1) $var = System::cat('sample.txt test.txt');
* 2) System::cat('sample.txt test.txt > final.txt');
* 3) System::cat('sample.txt test.txt >> final.txt');
*
* Note: as the class use fopen, urls should work also
*
* @param string $args the arguments
* @return boolean true on success
*/
public static function &cat($args)
{
$ret = null;
$files = array();
if (!is_array($args)) {
$args = preg_split('/\s+/', $args, -1, PREG_SPLIT_NO_EMPTY);
}
$count_args = count($args);
for ($i = 0; $i < $count_args; $i++) {
if ($args[$i] == '>') {
$mode = 'wb';
$outputfile = $args[$i+1];
break;
} elseif ($args[$i] == '>>') {
$mode = 'ab+';
$outputfile = $args[$i+1];
break;
} else {
$files[] = $args[$i];
}
}
$outputfd = false;
if (isset($mode)) {
if (!$outputfd = fopen($outputfile, $mode)) {
$err = System::raiseError("Could not open $outputfile");
return $err;
}
$ret = true;
}
foreach ($files as $file) {
if (!$fd = fopen($file, 'r')) {
System::raiseError("Could not open $file");
continue;
}
while ($cont = fread($fd, 2048)) {
if (is_resource($outputfd)) {
fwrite($outputfd, $cont);
} else {
$ret .= $cont;
}
}
fclose($fd);
}
if (is_resource($outputfd)) {
fclose($outputfd);
}
return $ret;
}
/**
* Creates temporary files or directories. This function will remove
* the created files when the scripts finish its execution.
*
* Usage:
* 1) $tempfile = System::mktemp("prefix");
* 2) $tempdir = System::mktemp("-d prefix");
* 3) $tempfile = System::mktemp();
* 4) $tempfile = System::mktemp("-t /var/tmp prefix");
*
* prefix -> The string that will be prepended to the temp name
* (defaults to "tmp").
* -d -> A temporary dir will be created instead of a file.
* -t -> The target dir where the temporary (file|dir) will be created. If
* this param is missing by default the env vars TMP on Windows or
* TMPDIR in Unix will be used. If these vars are also missing
* c:\windows\temp or /tmp will be used.
*
* @param string $args The arguments
* @return mixed the full path of the created (file|dir) or false
* @see System::tmpdir()
*/
public static function mktemp($args = null)
{
static $first_time = true;
$opts = System::_parseArgs($args, 't:d');
if (PEAR::isError($opts)) {
return System::raiseError($opts);
}
foreach ($opts[0] as $opt) {
if ($opt[0] == 'd') {
$tmp_is_dir = true;
} elseif ($opt[0] == 't') {
$tmpdir = $opt[1];
}
}
$prefix = (isset($opts[1][0])) ? $opts[1][0] : 'tmp';
if (!isset($tmpdir)) {
$tmpdir = System::tmpdir();
}
if (!System::mkDir(array('-p', $tmpdir))) {
return false;
}
$tmp = tempnam($tmpdir, $prefix);
if (isset($tmp_is_dir)) {
unlink($tmp); // be careful possible race condition here
if (!mkdir($tmp, 0700)) {
return System::raiseError("Unable to create temporary directory $tmpdir");
}
}
$GLOBALS['_System_temp_files'][] = $tmp;
if (isset($tmp_is_dir)) {
//$GLOBALS['_System_temp_files'][] = dirname($tmp);
}
if ($first_time) {
PEAR::registerShutdownFunc(array('System', '_removeTmpFiles'));
$first_time = false;
}
return $tmp;
}
/**
* Remove temporary files created my mkTemp. This function is executed
* at script shutdown time
*/
public static function _removeTmpFiles()
{
if (count($GLOBALS['_System_temp_files'])) {
$delete = $GLOBALS['_System_temp_files'];
array_unshift($delete, '-r');
System::rm($delete);
$GLOBALS['_System_temp_files'] = array();
}
}
/**
* Get the path of the temporal directory set in the system
* by looking in its environments variables.
* Note: php.ini-recommended removes the "E" from the variables_order setting,
* making unavaible the $_ENV array, that s why we do tests with _ENV
*
* @return string The temporary directory on the system
*/
public static function tmpdir()
{
if (OS_WINDOWS) {
if ($var = isset($_ENV['TMP']) ? $_ENV['TMP'] : getenv('TMP')) {
return $var;
}
if ($var = isset($_ENV['TEMP']) ? $_ENV['TEMP'] : getenv('TEMP')) {
return $var;
}
if ($var = isset($_ENV['USERPROFILE']) ? $_ENV['USERPROFILE'] : getenv('USERPROFILE')) {
return $var;
}
if ($var = isset($_ENV['windir']) ? $_ENV['windir'] : getenv('windir')) {
return $var;
}
return getenv('SystemRoot') . '\temp';
}
if ($var = isset($_ENV['TMPDIR']) ? $_ENV['TMPDIR'] : getenv('TMPDIR')) {
return $var;
}
return realpath(function_exists('sys_get_temp_dir') ? sys_get_temp_dir() : '/tmp');
}
/**
* The "which" command (show the full path of a command)
*
* @param string $program The command to search for
* @param mixed $fallback Value to return if $program is not found
*
* @return mixed A string with the full path or false if not found
* @author Stig Bakken <ssb@php.net>
*/
public static function which($program, $fallback = false)
{
// enforce API
if (!is_string($program) || '' == $program) {
return $fallback;
}
// full path given
if (basename($program) != $program) {
$path_elements[] = dirname($program);
$program = basename($program);
} else {
$path = getenv('PATH');
if (!$path) {
$path = getenv('Path'); // some OSes are just stupid enough to do this
}
$path_elements = explode(PATH_SEPARATOR, $path);
}
if (OS_WINDOWS) {
$exe_suffixes = getenv('PATHEXT')
? explode(PATH_SEPARATOR, getenv('PATHEXT'))
: array('.exe','.bat','.cmd','.com');
// allow passing a command.exe param
if (strpos($program, '.') !== false) {
array_unshift($exe_suffixes, '');
}
} else {
$exe_suffixes = array('');
}
foreach ($exe_suffixes as $suff) {
foreach ($path_elements as $dir) {
$file = $dir . DIRECTORY_SEPARATOR . $program . $suff;
// It's possible to run a .bat on Windows that is_executable
// would return false for. The is_executable check is meaningless...
if (OS_WINDOWS) {
if (file_exists($file)) {
return $file;
}
} else {
if (is_executable($file)) {
return $file;
}
}
}
}
return $fallback;
}
/**
* The "find" command
*
* Usage:
*
* System::find($dir);
* System::find("$dir -type d");
* System::find("$dir -type f");
* System::find("$dir -name *.php");
* System::find("$dir -name *.php -name *.htm*");
* System::find("$dir -maxdepth 1");
*
* Params implemented:
* $dir -> Start the search at this directory
* -type d -> return only directories
* -type f -> return only files
* -maxdepth <n> -> max depth of recursion
* -name <pattern> -> search pattern (bash style). Multiple -name param allowed
*
* @param mixed Either array or string with the command line
* @return array Array of found files
*/
public static function find($args)
{
if (!is_array($args)) {
$args = preg_split('/\s+/', $args, -1, PREG_SPLIT_NO_EMPTY);
}
$dir = realpath(array_shift($args));
if (!$dir) {
return array();
}
$patterns = array();
$depth = 0;
$do_files = $do_dirs = true;
$args_count = count($args);
for ($i = 0; $i < $args_count; $i++) {
switch ($args[$i]) {
case '-type':
if (in_array($args[$i+1], array('d', 'f'))) {
if ($args[$i+1] == 'd') {
$do_files = false;
} else {
$do_dirs = false;
}
}
$i++;
break;
case '-name':
$name = preg_quote($args[$i+1], '#');
// our magic characters ? and * have just been escaped,
// so now we change the escaped versions to PCRE operators
$name = strtr($name, array('\?' => '.', '\*' => '.*'));
$patterns[] = '('.$name.')';
$i++;
break;
case '-maxdepth':
$depth = $args[$i+1];
break;
}
}
$path = System::_dirToStruct($dir, $depth, 0, true);
if ($do_files && $do_dirs) {
$files = array_merge($path['files'], $path['dirs']);
} elseif ($do_dirs) {
$files = $path['dirs'];
} else {
$files = $path['files'];
}
if (count($patterns)) {
$dsq = preg_quote(DIRECTORY_SEPARATOR, '#');
$pattern = '#(^|'.$dsq.')'.implode('|', $patterns).'($|'.$dsq.')#';
$ret = array();
$files_count = count($files);
for ($i = 0; $i < $files_count; $i++) {
// only search in the part of the file below the current directory
$filepart = basename($files[$i]);
if (preg_match($pattern, $filepart)) {
$ret[] = $files[$i];
}
}
return $ret;
}
return $files;
}
}

View File

@@ -0,0 +1,27 @@
Copyright (c) 1997-2009,
Stig Bakken <ssb@php.net>,
Gregory Beaver <cellog@php.net>,
Helgi Þormar Þorbjörnsson <helgi@php.net>,
Tomas V.V.Cox <cox@idecnet.com>,
Martin Jansen <mj@php.net>.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@@ -0,0 +1,456 @@
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 foldmethod=marker: */
/**
* PEAR_Exception
*
* PHP version 5
*
* @category PEAR
* @package PEAR_Exception
* @author Tomas V. V. Cox <cox@idecnet.com>
* @author Hans Lellelid <hans@velum.net>
* @author Bertrand Mansion <bmansion@mamasam.com>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @link http://pear.php.net/package/PEAR_Exception
* @since File available since Release 1.0.0
*/
/**
* Base PEAR_Exception Class
*
* 1) Features:
*
* - Nestable exceptions (throw new PEAR_Exception($msg, $prev_exception))
* - Definable triggers, shot when exceptions occur
* - Pretty and informative error messages
* - Added more context info available (like class, method or cause)
* - cause can be a PEAR_Exception or an array of mixed
* PEAR_Exceptions/PEAR_ErrorStack warnings
* - callbacks for specific exception classes and their children
*
* 2) Ideas:
*
* - Maybe a way to define a 'template' for the output
*
* 3) Inherited properties from PHP Exception Class:
*
* protected $message
* protected $code
* protected $line
* protected $file
* private $trace
*
* 4) Inherited methods from PHP Exception Class:
*
* __clone
* __construct
* getMessage
* getCode
* getFile
* getLine
* getTraceSafe
* getTraceSafeAsString
* __toString
*
* 5) Usage example
*
* <code>
* require_once 'PEAR/Exception.php';
*
* class Test {
* function foo() {
* throw new PEAR_Exception('Error Message', ERROR_CODE);
* }
* }
*
* function myLogger($pear_exception) {
* echo $pear_exception->getMessage();
* }
* // each time a exception is thrown the 'myLogger' will be called
* // (its use is completely optional)
* PEAR_Exception::addObserver('myLogger');
* $test = new Test;
* try {
* $test->foo();
* } catch (PEAR_Exception $e) {
* print $e;
* }
* </code>
*
* @category PEAR
* @package PEAR_Exception
* @author Tomas V.V.Cox <cox@idecnet.com>
* @author Hans Lellelid <hans@velum.net>
* @author Bertrand Mansion <bmansion@mamasam.com>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: @package_version@
* @link http://pear.php.net/package/PEAR_Exception
* @since Class available since Release 1.0.0
*/
class PEAR_Exception extends Exception
{
const OBSERVER_PRINT = -2;
const OBSERVER_TRIGGER = -4;
const OBSERVER_DIE = -8;
protected $cause;
private static $_observers = array();
private static $_uniqueid = 0;
private $_trace;
/**
* Supported signatures:
* - PEAR_Exception(string $message);
* - PEAR_Exception(string $message, int $code);
* - PEAR_Exception(string $message, Exception $cause);
* - PEAR_Exception(string $message, Exception $cause, int $code);
* - PEAR_Exception(string $message, PEAR_Error $cause);
* - PEAR_Exception(string $message, PEAR_Error $cause, int $code);
* - PEAR_Exception(string $message, array $causes);
* - PEAR_Exception(string $message, array $causes, int $code);
*
* @param string $message exception message
* @param int|Exception|PEAR_Error|array|null $p2 exception cause
* @param int|null $p3 exception code or null
*/
public function __construct($message, $p2 = null, $p3 = null)
{
if (is_int($p2)) {
$code = $p2;
$this->cause = null;
} elseif (is_object($p2) || is_array($p2)) {
// using is_object allows both Exception and PEAR_Error
if (is_object($p2) && !($p2 instanceof Exception)) {
if (!class_exists('PEAR_Error') || !($p2 instanceof PEAR_Error)) {
throw new PEAR_Exception(
'exception cause must be Exception, ' .
'array, or PEAR_Error'
);
}
}
$code = $p3;
if (is_array($p2) && isset($p2['message'])) {
// fix potential problem of passing in a single warning
$p2 = array($p2);
}
$this->cause = $p2;
} else {
$code = null;
$this->cause = null;
}
parent::__construct($message, (int) $code);
$this->signal();
}
/**
* Add an exception observer
*
* @param mixed $callback - A valid php callback, see php func is_callable()
* - A PEAR_Exception::OBSERVER_* constant
* - An array(const PEAR_Exception::OBSERVER_*,
* mixed $options)
* @param string $label The name of the observer. Use this if you want
* to remove it later with removeObserver()
*
* @return void
*/
public static function addObserver($callback, $label = 'default')
{
self::$_observers[$label] = $callback;
}
/**
* Remove an exception observer
*
* @param string $label Name of the observer
*
* @return void
*/
public static function removeObserver($label = 'default')
{
unset(self::$_observers[$label]);
}
/**
* Generate a unique ID for an observer
*
* @return int unique identifier for an observer
*/
public static function getUniqueId()
{
return self::$_uniqueid++;
}
/**
* Send a signal to all observers
*
* @return void
*/
protected function signal()
{
foreach (self::$_observers as $func) {
if (is_callable($func)) {
call_user_func($func, $this);
continue;
}
settype($func, 'array');
switch ($func[0]) {
case self::OBSERVER_PRINT :
$f = (isset($func[1])) ? $func[1] : '%s';
printf($f, $this->getMessage());
break;
case self::OBSERVER_TRIGGER :
$f = (isset($func[1])) ? $func[1] : E_USER_NOTICE;
trigger_error($this->getMessage(), $f);
break;
case self::OBSERVER_DIE :
$f = (isset($func[1])) ? $func[1] : '%s';
die(printf($f, $this->getMessage()));
break;
default:
trigger_error('invalid observer type', E_USER_WARNING);
}
}
}
/**
* Return specific error information that can be used for more detailed
* error messages or translation.
*
* This method may be overridden in child exception classes in order
* to add functionality not present in PEAR_Exception and is a placeholder
* to define API
*
* The returned array must be an associative array of parameter => value like so:
* <pre>
* array('name' => $name, 'context' => array(...))
* </pre>
*
* @return array
*/
public function getErrorData()
{
return array();
}
/**
* Returns the exception that caused this exception to be thrown
*
* @return Exception|array The context of the exception
*/
public function getCause()
{
return $this->cause;
}
/**
* Function must be public to call on caused exceptions
*
* @param array $causes Array that gets filled.
*
* @return void
*/
public function getCauseMessage(&$causes)
{
$trace = $this->getTraceSafe();
$cause = array('class' => get_class($this),
'message' => $this->message,
'file' => 'unknown',
'line' => 'unknown');
if (isset($trace[0])) {
if (isset($trace[0]['file'])) {
$cause['file'] = $trace[0]['file'];
$cause['line'] = $trace[0]['line'];
}
}
$causes[] = $cause;
if ($this->cause instanceof PEAR_Exception) {
$this->cause->getCauseMessage($causes);
} elseif ($this->cause instanceof Exception) {
$causes[] = array('class' => get_class($this->cause),
'message' => $this->cause->getMessage(),
'file' => $this->cause->getFile(),
'line' => $this->cause->getLine());
} elseif (class_exists('PEAR_Error') && $this->cause instanceof PEAR_Error) {
$causes[] = array('class' => get_class($this->cause),
'message' => $this->cause->getMessage(),
'file' => 'unknown',
'line' => 'unknown');
} elseif (is_array($this->cause)) {
foreach ($this->cause as $cause) {
if ($cause instanceof PEAR_Exception) {
$cause->getCauseMessage($causes);
} elseif ($cause instanceof Exception) {
$causes[] = array('class' => get_class($cause),
'message' => $cause->getMessage(),
'file' => $cause->getFile(),
'line' => $cause->getLine());
} elseif (class_exists('PEAR_Error')
&& $cause instanceof PEAR_Error
) {
$causes[] = array('class' => get_class($cause),
'message' => $cause->getMessage(),
'file' => 'unknown',
'line' => 'unknown');
} elseif (is_array($cause) && isset($cause['message'])) {
// PEAR_ErrorStack warning
$causes[] = array(
'class' => $cause['package'],
'message' => $cause['message'],
'file' => isset($cause['context']['file']) ?
$cause['context']['file'] :
'unknown',
'line' => isset($cause['context']['line']) ?
$cause['context']['line'] :
'unknown',
);
}
}
}
}
/**
* Build a backtrace and return it
*
* @return array Backtrace
*/
public function getTraceSafe()
{
if (!isset($this->_trace)) {
$this->_trace = $this->getTrace();
if (empty($this->_trace)) {
$backtrace = debug_backtrace();
$this->_trace = array($backtrace[count($backtrace)-1]);
}
}
return $this->_trace;
}
/**
* Gets the first class of the backtrace
*
* @return string Class name
*/
public function getErrorClass()
{
$trace = $this->getTraceSafe();
return $trace[0]['class'];
}
/**
* Gets the first method of the backtrace
*
* @return string Method/function name
*/
public function getErrorMethod()
{
$trace = $this->getTraceSafe();
return $trace[0]['function'];
}
/**
* Converts the exception to a string (HTML or plain text)
*
* @return string String representation
*
* @see toHtml()
* @see toText()
*/
public function __toString()
{
if (isset($_SERVER['REQUEST_URI'])) {
return $this->toHtml();
}
return $this->toText();
}
/**
* Generates a HTML representation of the exception
*
* @return string HTML code
*/
public function toHtml()
{
$trace = $this->getTraceSafe();
$causes = array();
$this->getCauseMessage($causes);
$html = '<table style="border: 1px" cellspacing="0">' . "\n";
foreach ($causes as $i => $cause) {
$html .= '<tr><td colspan="3" style="background: #ff9999">'
. str_repeat('-', $i) . ' <b>' . $cause['class'] . '</b>: '
. htmlspecialchars($cause['message'])
. ' in <b>' . $cause['file'] . '</b> '
. 'on line <b>' . $cause['line'] . '</b>'
. "</td></tr>\n";
}
$html .= '<tr><td colspan="3" style="background-color: #aaaaaa; text-align: center; font-weight: bold;">Exception trace</td></tr>' . "\n"
. '<tr><td style="text-align: center; background: #cccccc; width:20px; font-weight: bold;">#</td>'
. '<td style="text-align: center; background: #cccccc; font-weight: bold;">Function</td>'
. '<td style="text-align: center; background: #cccccc; font-weight: bold;">Location</td></tr>' . "\n";
foreach ($trace as $k => $v) {
$html .= '<tr><td style="text-align: center;">' . $k . '</td>'
. '<td>';
if (!empty($v['class'])) {
$html .= $v['class'] . $v['type'];
}
$html .= $v['function'];
$args = array();
if (!empty($v['args'])) {
foreach ($v['args'] as $arg) {
if (is_null($arg)) {
$args[] = 'null';
} else if (is_array($arg)) {
$args[] = 'Array';
} else if (is_object($arg)) {
$args[] = 'Object('.get_class($arg).')';
} else if (is_bool($arg)) {
$args[] = $arg ? 'true' : 'false';
} else if (is_int($arg) || is_double($arg)) {
$args[] = $arg;
} else {
$arg = (string)$arg;
$str = htmlspecialchars(substr($arg, 0, 16));
if (strlen($arg) > 16) {
$str .= '&hellip;';
}
$args[] = "'" . $str . "'";
}
}
}
$html .= '(' . implode(', ', $args) . ')'
. '</td>'
. '<td>' . (isset($v['file']) ? $v['file'] : 'unknown')
. ':' . (isset($v['line']) ? $v['line'] : 'unknown')
. '</td></tr>' . "\n";
}
$html .= '<tr><td style="text-align: center;">' . ($k+1) . '</td>'
. '<td>{main}</td>'
. '<td>&nbsp;</td></tr>' . "\n"
. '</table>';
return $html;
}
/**
* Generates text representation of the exception and stack trace
*
* @return string
*/
public function toText()
{
$causes = array();
$this->getCauseMessage($causes);
$causeMsg = '';
foreach ($causes as $i => $cause) {
$causeMsg .= str_repeat(' ', $i) . $cause['class'] . ': '
. $cause['message'] . ' in ' . $cause['file']
. ' on line ' . $cause['line'] . "\n";
}
return $causeMsg . $this->getTraceAsString();
}
}
?>

View File

@@ -0,0 +1,41 @@
{
"name": "pear/pear_exception",
"description": "The PEAR Exception base class.",
"type": "class",
"keywords": [
"exception"
],
"homepage": "https://github.com/pear/PEAR_Exception",
"license": "BSD-2-Clause",
"authors": [
{
"name": "Helgi Thormar",
"email": "dufuz@php.net"
},
{
"name": "Greg Beaver",
"email": "cellog@php.net"
}
],
"require": {
"php": ">=5.2.0"
},
"autoload": {
"classmap": ["PEAR/"]
},
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"include-path": [
"."
],
"support": {
"issues": "http://pear.php.net/bugs/search.php?cmd=display&package_name[]=PEAR_Exception",
"source": "https://github.com/pear/PEAR_Exception"
},
"require-dev": {
"phpunit/phpunit": "<9"
}
}