chore(vendor): PHP依赖比较混乱,暂时采用NiuShop官方的依赖相互融合的版本

This commit is contained in:
2025-12-08 16:01:39 +08:00
parent e0aeea15f2
commit 54ef5ccf3d
1542 changed files with 128304 additions and 33334 deletions

View File

@@ -1,27 +1,5 @@
# ChangeLog - Aliyun OSS SDK for PHP # ChangeLog - Aliyun OSS SDK for PHP
## v2.7.2 / 2024-10-28
* Added: presign supports response-* parameters
* Added: forcePathStyle option.
## v2.7.1 / 2024-02-28
* Fixed: fix deprecated
## v2.7.0 / 2024-02-02
* Added: support signature version 4.
* Added: support checkObjectEndcoding option.
* Added: support strictObjectName option.
* Added: support filePathCompatible option.
* Added: support path style.
* Added: support environment variables credentials provider.
* Update: add filed for some api.
* Fixed: fix some bugs.
## v2.6.0 / 2022-08-03
* Added: support credentials provider.
* Fixed: compatible with swoole curl handler.
* Added: support more bucket stat info.
## v2.5.0 / 2022-05-13 ## v2.5.0 / 2022-05-13
* Added: support bucket transfer acceleration. * Added: support bucket transfer acceleration.
* Added: support bucket cname token. * Added: support bucket cname token.

View File

@@ -15,7 +15,7 @@
}, },
"require-dev" : { "require-dev" : {
"phpunit/phpunit": "*", "phpunit/phpunit": "*",
"php-coveralls/php-coveralls": "*" "satooshi/php-coveralls": "*"
}, },
"minimum-stability": "stable", "minimum-stability": "stable",
"autoload": { "autoload": {

View File

@@ -26,39 +26,7 @@ Common::println("bucket $bucket corsConfig created:" . $corsConfig->serializeToX
// Get cors configuration // Get cors configuration
$corsConfig = $ossClient->getBucketCors($bucket); $corsConfig = $ossClient->getBucketCors($bucket);
Common::println("bucket $bucket corsConfig fetched:" . $corsConfig->serializeToXml());
if ($corsConfig->getResponseVary()){
printf("Response Vary : true" .PHP_EOL);
}else{
printf("Response Vary : false" .PHP_EOL);
}
foreach ($corsConfig->getRules() as $key => $rule){
if($rule->getAllowedHeaders()){
foreach($rule->getAllowedHeaders() as $header){
printf("Allowed Headers :" .$header .PHP_EOL);
}
}
if ($rule->getAllowedMethods()){
foreach($rule->getAllowedMethods() as $method){
printf("Allowed Methods :" .$method . PHP_EOL);
}
}
if($rule->getAllowedOrigins()){
foreach($rule->getAllowedOrigins() as $origin){
printf("Allowed Origins :" .$origin , PHP_EOL);
}
}
if($rule->getExposeHeaders()){
foreach($rule->getExposeHeaders() as $exposeHeader){
printf("Expose Headers :" .$exposeHeader . PHP_EOL);
}
}
printf("Max Age Seconds :" .$rule->getMaxAgeSeconds() .PHP_EOL);
}
// Delete cors configuration // Delete cors configuration
$ossClient->deleteBucketCors($bucket); $ossClient->deleteBucketCors($bucket);
@@ -110,44 +78,13 @@ function getBucketCors($ossClient, $bucket)
$corsConfig = null; $corsConfig = null;
try { try {
$corsConfig = $ossClient->getBucketCors($bucket); $corsConfig = $ossClient->getBucketCors($bucket);
if ($corsConfig->getResponseVary()){
printf("Response Vary : true" .PHP_EOL);
}else{
printf("Response Vary : false" .PHP_EOL);
}
foreach ($corsConfig->getRules() as $key => $rule){
if($rule->getAllowedHeaders()){
foreach($rule->getAllowedHeaders() as $header){
printf("Allowed Headers :" .$header .PHP_EOL);
}
}
if ($rule->getAllowedMethods()){
foreach($rule->getAllowedMethods() as $method){
printf("Allowed Methods :" .$method . PHP_EOL);
}
}
if($rule->getAllowedOrigins()){
foreach($rule->getAllowedOrigins() as $origin){
printf("Allowed Origins :" .$origin , PHP_EOL);
}
}
if($rule->getExposeHeaders()){
foreach($rule->getExposeHeaders() as $exposeHeader){
printf("Expose Headers :" .$exposeHeader . PHP_EOL);
}
}
printf("Max Age Seconds :" .$rule->getMaxAgeSeconds() .PHP_EOL);
}
} catch (OssException $e) { } catch (OssException $e) {
printf(__FUNCTION__ . ": FAILED\n"); printf(__FUNCTION__ . ": FAILED\n");
printf($e->getMessage() . "\n"); printf($e->getMessage() . "\n");
return; return;
} }
print(__FUNCTION__ . ": OK" . "\n"); print(__FUNCTION__ . ": OK" . "\n");
print($corsConfig->serializeToXml() . "\n");
} }
/** /**

View File

@@ -227,47 +227,30 @@ function listObjects($ossClient, $bucket)
); );
try { try {
$listObjectInfo = $ossClient->listObjects($bucket, $options); $listObjectInfo = $ossClient->listObjects($bucket, $options);
printf("Bucket Name: %s". "\n",$listObjectInfo->getBucketName());
printf("Prefix: %s". "\n",$listObjectInfo->getPrefix());
printf("Marker: %s". "\n",$listObjectInfo->getMarker());
printf("Next Marker: %s". "\n",$listObjectInfo->getNextMarker());
printf("Max Keys: %s". "\n",$listObjectInfo->getMaxKeys());
printf("Delimiter: %s". "\n",$listObjectInfo->getDelimiter());
printf("Is Truncated: %s". "\n",$listObjectInfo->getIsTruncated());
$objectList = $listObjectInfo->getObjectList(); // object list
$prefixList = $listObjectInfo->getPrefixList(); // directory list
if (!empty($objectList)) {
print("objectList:\n");
foreach ($objectList as $objectInfo) {
printf("Object Name: %s". "\n",$objectInfo->getKey());
printf("Object Size: %s". "\n",$objectInfo->getSize());
printf("Object Type: %s". "\n",$objectInfo->getType());
printf("Object ETag: %s". "\n",$objectInfo->getETag());
printf("Object Last Modified: %s". "\n",$objectInfo->getLastModified());
printf("Object Storage Class: %s". "\n",$objectInfo->getStorageClass());
if ($objectInfo->getRestoreInfo()){
printf("Restore Info: %s". "\n",$objectInfo->getRestoreInfo() );
}
if($objectInfo->getOwner()){
printf("Owner Id:".$objectInfo->getOwner()->getId() . "\n");
printf("Owner Name:".$objectInfo->getOwner()->getDisplayName() . "\n");
}
}
}
if (!empty($prefixList)) {
print("prefixList: \n");
foreach ($prefixList as $prefixInfo) {
printf("Common Prefix:%s\n",$prefixInfo->getPrefix());
}
}
} catch (OssException $e) { } catch (OssException $e) {
printf(__FUNCTION__ . ": FAILED\n"); printf(__FUNCTION__ . ": FAILED\n");
printf($e->getMessage() . "\n"); printf($e->getMessage() . "\n");
return; return;
} }
print(__FUNCTION__ . ": OK" . "\n"); print(__FUNCTION__ . ": OK" . "\n");
$objectList = $listObjectInfo->getObjectList(); // object list
$prefixList = $listObjectInfo->getPrefixList(); // directory list
if (!empty($objectList)) {
print("objectList:\n");
foreach ($objectList as $objectInfo) {
print($objectInfo->getKey() . "\n");
if($objectInfo->getOwner() != null){
printf("owner id:".$objectInfo->getOwner()->getId() . "\n");
printf("owner name:".$objectInfo->getOwner()->getDisplayName() . "\n");
}
}
}
if (!empty($prefixList)) {
print("prefixList: \n");
foreach ($prefixList as $prefixInfo) {
print($prefixInfo->getPrefix() . "\n");
}
}
} }
/** /**
@@ -293,49 +276,30 @@ function listObjectsV2($ossClient, $bucket)
); );
try { try {
$listObjectInfo = $ossClient->listObjectsV2($bucket, $options); $listObjectInfo = $ossClient->listObjectsV2($bucket, $options);
printf("Bucket Name: %s". "\n",$listObjectInfo->getBucketName());
printf("Prefix: %s". "\n",$listObjectInfo->getPrefix());
printf("Next Continuation Token: %s". "\n",$listObjectInfo->getNextContinuationToken());
printf("Continuation Token: %s". "\n",$listObjectInfo->getContinuationToken());
printf("Max Keys: %s". "\n",$listObjectInfo->getMaxKeys());
printf("Key Count: %s". "\n",$listObjectInfo->getKeyCount());
printf("Delimiter: %s". "\n",$listObjectInfo->getDelimiter());
printf("Is Truncated: %s". "\n",$listObjectInfo->getIsTruncated());
printf("Start After: %s". "\n",$listObjectInfo->getStartAfter());
$objectList = $listObjectInfo->getObjectList(); // object list
$prefixList = $listObjectInfo->getPrefixList(); // directory list
if (!empty($objectList)) {
print("objectList:\n");
foreach ($objectList as $objectInfo) {
printf("Object Name: %s". "\n",$objectInfo->getKey());
printf("Object Size: %s". "\n",$objectInfo->getSize());
printf("Object Type: %s". "\n",$objectInfo->getType());
printf("Object ETag: %s". "\n",$objectInfo->getETag());
printf("Object Last Modified: %s". "\n",$objectInfo->getLastModified());
printf("Object Storage Class: %s". "\n",$objectInfo->getStorageClass());
if ($objectInfo->getRestoreInfo()){
printf("Restore Info: %s". "\n",$objectInfo->getRestoreInfo() );
}
if($objectInfo->getOwner()){
printf("Owner Id:".$objectInfo->getOwner()->getId() . "\n");
printf("Owner Name:".$objectInfo->getOwner()->getDisplayName() . "\n");
}
}
}
if (!empty($prefixList)) {
print("prefixList: \n");
foreach ($prefixList as $prefixInfo) {
printf("Common Prefix:%s\n",$prefixInfo->getPrefix());
}
}
} catch (OssException $e) { } catch (OssException $e) {
printf(__FUNCTION__ . ": FAILED\n"); printf(__FUNCTION__ . ": FAILED\n");
printf($e->getMessage() . "\n"); printf($e->getMessage() . "\n");
return; return;
} }
print(__FUNCTION__ . ": OK" . "\n"); print(__FUNCTION__ . ": OK" . "\n");
$objectList = $listObjectInfo->getObjectList(); // object list
$prefixList = $listObjectInfo->getPrefixList(); // directory list
if (!empty($objectList)) {
print("objectList:\n");
foreach ($objectList as $objectInfo) {
print($objectInfo->getKey() . "\n");
if($objectInfo->getOwner() != null){
printf("owner id:".$objectInfo->getOwner()->getId() . "\n");
printf("owner name:".$objectInfo->getOwner()->getDisplayName() . "\n");
}
}
}
if (!empty($prefixList)) {
print("prefixList: \n");
foreach ($prefixList as $prefixInfo) {
print($prefixInfo->getPrefix() . "\n");
}
}
} }
/** /**

View File

@@ -193,6 +193,7 @@ class OssUtil
* *
* @param array $options * @param array $options
* @throws OssException * @throws OssException
* @return boolean
*/ */
public static function validateOptions($options) public static function validateOptions($options)
{ {
@@ -371,8 +372,7 @@ BBB;
* Get the host:port from endpoint. * Get the host:port from endpoint.
* *
* @param string $endpoint the endpoint. * @param string $endpoint the endpoint.
* @return string * @return boolean
* @throws OssException
*/ */
public static function getHostPortFromEndpoint($endpoint) public static function getHostPortFromEndpoint($endpoint)
{ {
@@ -531,13 +531,4 @@ BBB;
throw new OssException("Unrecognized encoding type: " . $encoding); throw new OssException("Unrecognized encoding type: " . $encoding);
} }
} }
public static function unparseUrl($parsed_url) {
$scheme = isset($parsed_url['scheme']) ? $parsed_url['scheme'] . '://' : '';
$host = isset($parsed_url['host']) ? $parsed_url['host'] : '';
$port = isset($parsed_url['port']) ? ':' . $parsed_url['port'] : '';
$path = isset($parsed_url['path']) ? $parsed_url['path'] : '';
$query = isset($parsed_url['query']) ? '?' . $parsed_url['query'] : '';
return "$scheme$host$port$path$query";
}
} }

View File

@@ -170,7 +170,7 @@ class RequestCore
public $registered_streaming_write_callback = null; public $registered_streaming_write_callback = null;
/** /**
* The request timeout time, which is 5,184,000 seconds,that is, 60 days by default * The request timeout time, which is 5,184,000 seconds,that is, 6 days by default
* *
* @var int * @var int
*/ */
@@ -789,7 +789,7 @@ class RequestCore
} }
// As long as this came back as a valid resource or CurlHandle instance... // As long as this came back as a valid resource or CurlHandle instance...
if (is_resource($curl_handle) || (is_object($curl_handle) && in_array(get_class($curl_handle),array('CurlHandle','Swoole\Curl\Handler', 'Swoole\Coroutine\Curl\Handle'),true))) { if (is_resource($curl_handle) || (is_object($curl_handle) && get_class($curl_handle) === 'CurlHandle')) {
// Determine what's what. // Determine what's what.
$header_size = curl_getinfo($curl_handle, CURLINFO_HEADER_SIZE); $header_size = curl_getinfo($curl_handle, CURLINFO_HEADER_SIZE);
$this->response_headers = substr($this->response, 0, $header_size); $this->response_headers = substr($this->response, 0, $header_size);

View File

@@ -41,135 +41,6 @@ class BucketStat
return $this->multipartUploadCount; return $this->multipartUploadCount;
} }
/**
* Get live channel count
*
* @return int
*/
public function getLiveChannelCount()
{
return $this->liveChannelCount;
}
/**
* Get last modified time
*
* @return int
*/
public function getLastModifiedTime()
{
return $this->lastModifiedTime;
}
/**
* Get standard storage
*
* @return int
*/
public function getStandardStorage()
{
return $this->standardStorage;
}
/**
* Get standard object count
*
* @return int
*/
public function getStandardObjectCount()
{
return $this->standardObjectCount;
}
/**
* Get infrequent access storage
*
* @return int
*/
public function getInfrequentAccessStorage()
{
return $this->infrequentAccessStorage;
}
/**
* Get infrequent access real storage
*
* @return int
*/
public function getInfrequentAccessRealStorage()
{
return $this->infrequentAccessRealStorage;
}
/**
* Get infrequent access object count
*
* @return int
*/
public function getInfrequentAccessObjectCount()
{
return $this->infrequentAccessObjectCount;
}
/**
* Get archive storage
*
* @return int
*/
public function getArchiveStorage()
{
return $this->archiveStorage;
}
/**
* Get archive real storage
*
* @return int
*/
public function getArchiveRealStorage()
{
return $this->archiveRealStorage;
}
/**
* Get archive object count
*
* @return int
*/
public function getArchiveObjectCount()
{
return $this->archiveObjectCount;
}
/**
* Get cold archive storage
*
* @return int
*/
public function getColdArchiveStorage()
{
return $this->coldArchiveStorage;
}
/**
* Get cold archive real storage
*
* @return int
*/
public function getColdArchiveRealStorage()
{
return $this->coldArchiveRealStorage;
}
/**
* Get cold archive object count
*
* @return int
*/
public function getColdArchiveObjectCount()
{
return $this->coldArchiveObjectCount;
}
/** /**
* Parse stat from the xml. * Parse stat from the xml.
* *
@@ -189,45 +60,6 @@ class BucketStat
if (isset($xml->MultipartUploadCount) ) { if (isset($xml->MultipartUploadCount) ) {
$this->multipartUploadCount = intval($xml->MultipartUploadCount); $this->multipartUploadCount = intval($xml->MultipartUploadCount);
} }
if (isset($xml->LiveChannelCount) ) {
$this->liveChannelCount = intval($xml->LiveChannelCount);
}
if (isset($xml->LastModifiedTime) ) {
$this->lastModifiedTime = intval($xml->LastModifiedTime);
}
if (isset($xml->StandardStorage) ) {
$this->standardStorage = intval($xml->StandardStorage);
}
if (isset($xml->StandardObjectCount) ) {
$this->standardObjectCount = intval($xml->StandardObjectCount);
}
if (isset($xml->InfrequentAccessStorage) ) {
$this->infrequentAccessStorage = intval($xml->InfrequentAccessStorage);
}
if (isset($xml->InfrequentAccessRealStorage) ) {
$this->infrequentAccessRealStorage = intval($xml->InfrequentAccessRealStorage);
}
if (isset($xml->InfrequentAccessObjectCount) ) {
$this->infrequentAccessObjectCount = intval($xml->InfrequentAccessObjectCount);
}
if (isset($xml->ArchiveStorage) ) {
$this->archiveStorage = intval($xml->ArchiveStorage);
}
if (isset($xml->ArchiveRealStorage) ) {
$this->archiveRealStorage = intval($xml->ArchiveRealStorage);
}
if (isset($xml->ArchiveObjectCount) ) {
$this->archiveObjectCount = intval($xml->ArchiveObjectCount);
}
if (isset($xml->ColdArchiveStorage) ) {
$this->coldArchiveStorage = intval($xml->ColdArchiveStorage);
}
if (isset($xml->ColdArchiveRealStorage) ) {
$this->coldArchiveRealStorage = intval($xml->ColdArchiveRealStorage);
}
if (isset($xml->ColdArchiveObjectCount) ) {
$this->coldArchiveObjectCount = intval($xml->ColdArchiveObjectCount);
}
} }
/** /**
@@ -250,82 +82,4 @@ class BucketStat
*/ */
private $multipartUploadCount; private $multipartUploadCount;
/**
* live channel count
* @var int
*/
private $liveChannelCount;
/**
* last modified time
* @var int
*/
private $lastModifiedTime;
/**
* standard storage
* @var int
*/
private $standardStorage;
/**
* standard object count
* @var int
*/
private $standardObjectCount;
/**
* infrequent access storage
* @var int
*/
private $infrequentAccessStorage;
/**
* infrequent access real storage
* @var int
*/
private $infrequentAccessRealStorage;
/**
* infrequent access object Count
* @var int
*/
private $infrequentAccessObjectCount;
/**
* archive storage
* @var int
*/
private $archiveStorage;
/**
* archive real storage
* @var int
*/
private $archiveRealStorage;
/**
* archive object count
* @var int
*/
private $archiveObjectCount;
/**
* cold archive storage
* @var int
*/
private $coldArchiveStorage;
/**
* cold archive real storage
* @var int
*/
private $coldArchiveRealStorage;
/**
* cold archive object count
* @var int
*/
private $coldArchiveObjectCount;
} }

View File

@@ -45,26 +45,10 @@ class CorsConfig implements XmlConfig
} }
$this->rules[] = $rule; $this->rules[] = $rule;
} }
/**
* @param boolean $value
*/
public function setResponseVary($value)
{
$this->responseVary = $value;
}
/**
* @return boolean
*/
public function getResponseVary(){
if (isset($this->responseVary)) {
return $this->responseVary;
}
return false;
}
/** /**
* Parse CorsConfig from the xml. * Parse CorsConfig from the xml.
*
* @param string $strXml * @param string $strXml
* @throws OssException * @throws OssException
* @return null * @return null
@@ -72,10 +56,6 @@ class CorsConfig implements XmlConfig
public function parseFromXml($strXml) public function parseFromXml($strXml)
{ {
$xml = simplexml_load_string($strXml); $xml = simplexml_load_string($strXml);
if(isset($xml->ResponseVary)){
$this->responseVary =
(strval($xml->ResponseVary) === 'TRUE' || strval($xml->ResponseVary) === 'true') ? true : false;
}
if (!isset($xml->CORSRule)) return; if (!isset($xml->CORSRule)) return;
foreach ($xml->CORSRule as $rule) { foreach ($xml->CORSRule as $rule) {
$corsRule = new CorsRule(); $corsRule = new CorsRule();
@@ -94,6 +74,7 @@ class CorsConfig implements XmlConfig
} }
$this->addRule($corsRule); $this->addRule($corsRule);
} }
return;
} }
/** /**
@@ -108,13 +89,6 @@ class CorsConfig implements XmlConfig
$xmlRule = $xml->addChild('CORSRule'); $xmlRule = $xml->addChild('CORSRule');
$rule->appendToXml($xmlRule); $rule->appendToXml($xmlRule);
} }
if(isset($this->responseVary)){
if ($this->responseVary) {
$xml->addChild('ResponseVary', 'true');
} else {
$xml->addChild('ResponseVary', 'false');
}
}
return $xml->asXML(); return $xml->asXML();
} }
@@ -136,5 +110,4 @@ class CorsConfig implements XmlConfig
* @var CorsRule[] * @var CorsRule[]
*/ */
private $rules = array(); private $rules = array();
private $responseVary;
} }

View File

@@ -24,10 +24,8 @@ class ObjectInfo
* @param string $type * @param string $type
* @param string $size * @param string $size
* @param string $storageClass * @param string $storageClass
* @param Owner|null $owner
* @param null $restoreInfo
*/ */
public function __construct($key, $lastModified, $eTag, $type, $size, $storageClass,$owner=null,$restoreInfo=null) public function __construct($key, $lastModified, $eTag, $type, $size, $storageClass)
{ {
$this->key = $key; $this->key = $key;
$this->lastModified = $lastModified; $this->lastModified = $lastModified;
@@ -35,8 +33,6 @@ class ObjectInfo
$this->type = $type; $this->type = $type;
$this->size = $size; $this->size = $size;
$this->storageClass = $storageClass; $this->storageClass = $storageClass;
$this->owner = $owner;
$this->restoreInfo = $restoreInfo;
} }
/** /**
@@ -98,32 +94,10 @@ class ObjectInfo
return $this->storageClass; return $this->storageClass;
} }
/**
* @return string
*/
public function getRestoreInfo()
{
return $this->restoreInfo;
}
/**
* @return Owner|null
*/
public function getOwner()
{
return $this->owner;
}
private $key = ""; private $key = "";
private $lastModified = ""; private $lastModified = "";
private $eTag = ""; private $eTag = "";
private $type = ""; private $type = "";
private $size = "0"; private $size = "0";
private $storageClass = ""; private $storageClass = "";
/**
* @var Owner
*/
private $owner;
private $restoreInfo;
} }

View File

@@ -22,7 +22,7 @@ class ObjectVersionListInfo
* @param string $nextVersionIdMarker * @param string $nextVersionIdMarker
* @param string $maxKeys * @param string $maxKeys
* @param string $delimiter * @param string $delimiter
* @param null|string $isTruncated * @param null $isTruncated
* @param array $objectversionList * @param array $objectversionList
* @param array $deleteMarkerList * @param array $deleteMarkerList
* @param array $prefixList * @param array $prefixList
@@ -151,7 +151,7 @@ class ObjectVersionListInfo
private $prefix = ""; private $prefix = "";
private $keyMarker = ""; private $keyMarker = "";
private $nextKeyMarker = ""; private $nextKeyMarker = "";
private $versionIdMarker = ""; private $versionIdmarker = "";
private $nextVersionIdMarker = ""; private $nextVersionIdMarker = "";
private $maxKeys = 0; private $maxKeys = 0;
private $delimiter = ""; private $delimiter = "";

File diff suppressed because it is too large Load Diff

View File

@@ -7,7 +7,7 @@ use OSS\Model\CnameTokenInfo;
class CreateBucketCnameTokenResult extends Result class CreateBucketCnameTokenResult extends Result
{ {
/** /**
* @return CnameTokenInfo * @return CnameConfig
*/ */
protected function parseDataFromResponse() protected function parseDataFromResponse()
{ {

View File

@@ -16,7 +16,7 @@ class GetBucketInfoResult extends Result
/** /**
* Parse data from response * Parse data from response
* *
* @return BucketInfo * @return string
* @throws OssException * @throws OssException
*/ */
protected function parseDataFromResponse() protected function parseDataFromResponse()

View File

@@ -7,7 +7,7 @@ use OSS\Model\GetLiveChannelHistory;
class GetLiveChannelHistoryResult extends Result class GetLiveChannelHistoryResult extends Result
{ {
/** /**
* @return GetLiveChannelHistory * @return
*/ */
protected function parseDataFromResponse() protected function parseDataFromResponse()
{ {

View File

@@ -7,7 +7,7 @@ use OSS\Model\GetLiveChannelInfo;
class GetLiveChannelInfoResult extends Result class GetLiveChannelInfoResult extends Result
{ {
/** /**
* @return GetLiveChannelInfo * @return
*/ */
protected function parseDataFromResponse() protected function parseDataFromResponse()
{ {

View File

@@ -2,7 +2,6 @@
namespace OSS\Result; namespace OSS\Result;
use OSS\Core\OssException;
use OSS\Core\OssUtil; use OSS\Core\OssUtil;
use OSS\Model\ObjectVersionInfo; use OSS\Model\ObjectVersionInfo;
use OSS\Model\ObjectVersionListInfo; use OSS\Model\ObjectVersionListInfo;
@@ -18,8 +17,7 @@ class ListObjectVersionsResult extends Result
/** /**
* Parse the xml data returned by the ListObjectVersions interface * Parse the xml data returned by the ListObjectVersions interface
* *
* @return ObjectVersionListInfo * return ObjectVersionListInfo
* @throws OssException
*/ */
protected function parseDataFromResponse() protected function parseDataFromResponse()
{ {

View File

@@ -2,11 +2,9 @@
namespace OSS\Result; namespace OSS\Result;
use OSS\Core\OssException;
use OSS\Core\OssUtil; use OSS\Core\OssUtil;
use OSS\Model\ObjectInfo; use OSS\Model\ObjectInfo;
use OSS\Model\ObjectListInfo; use OSS\Model\ObjectListInfo;
use OSS\Model\Owner;
use OSS\Model\PrefixInfo; use OSS\Model\PrefixInfo;
/** /**
@@ -18,8 +16,7 @@ class ListObjectsResult extends Result
/** /**
* Parse the xml data returned by the ListObjects interface * Parse the xml data returned by the ListObjects interface
* *
* @return ObjectListInfo * return ObjectListInfo
* @throws OssException
*/ */
protected function parseDataFromResponse() protected function parseDataFromResponse()
{ {
@@ -53,13 +50,7 @@ class ListObjectsResult extends Result
$type = isset($content->Type) ? strval($content->Type) : ""; $type = isset($content->Type) ? strval($content->Type) : "";
$size = isset($content->Size) ? strval($content->Size) : "0"; $size = isset($content->Size) ? strval($content->Size) : "0";
$storageClass = isset($content->StorageClass) ? strval($content->StorageClass) : ""; $storageClass = isset($content->StorageClass) ? strval($content->StorageClass) : "";
if(isset($content->Owner)){ $retList[] = new ObjectInfo($key, $lastModified, $eTag, $type, $size, $storageClass);
$owner = new Owner(strval($content->Owner->ID),strval($content->Owner->DisplayName));
}else{
$owner = null;
}
$restoreInfo= isset($content->RestoreInfo) ? strval($content->RestoreInfo) : null;
$retList[] = new ObjectInfo($key, $lastModified, $eTag, $type, $size, $storageClass,$owner,$restoreInfo);
} }
} }
return $retList; return $retList;

View File

@@ -2,11 +2,9 @@
namespace OSS\Result; namespace OSS\Result;
use OSS\Core\OssException;
use OSS\Core\OssUtil; use OSS\Core\OssUtil;
use OSS\Model\ObjectInfo; use OSS\Model\ObjectInfo;
use OSS\Model\ObjectListInfoV2; use OSS\Model\ObjectListInfoV2;
use OSS\Model\Owner;
use OSS\Model\PrefixInfo; use OSS\Model\PrefixInfo;
/** /**
@@ -18,8 +16,7 @@ class ListObjectsV2Result extends Result
/** /**
* Parse the xml data returned by the ListObjectsV2 interface * Parse the xml data returned by the ListObjectsV2 interface
* *
* @return ObjectListInfoV2 * return ObjectListInfoV2
* @throws OssException
*/ */
protected function parseDataFromResponse() protected function parseDataFromResponse()
{ {
@@ -54,13 +51,7 @@ class ListObjectsV2Result extends Result
$type = isset($content->Type) ? strval($content->Type) : ""; $type = isset($content->Type) ? strval($content->Type) : "";
$size = isset($content->Size) ? strval($content->Size) : "0"; $size = isset($content->Size) ? strval($content->Size) : "0";
$storageClass = isset($content->StorageClass) ? strval($content->StorageClass) : ""; $storageClass = isset($content->StorageClass) ? strval($content->StorageClass) : "";
if(isset($content->Owner)){ $retList[] = new ObjectInfo($key, $lastModified, $eTag, $type, $size, $storageClass);
$owner = new Owner(strval($content->Owner->ID),strval($content->Owner->DisplayName));
}else{
$owner = null;
}
$restoreInfo= isset($content->RestoreInfo) ? strval($content->RestoreInfo) : null;
$retList[] = new ObjectInfo($key, $lastModified, $eTag, $type, $size, $storageClass,$owner,$restoreInfo);
} }
} }
return $retList; return $retList;

View File

@@ -109,29 +109,10 @@ abstract class Result
if (empty($body) || false === strpos($body, '<?xml')) { if (empty($body) || false === strpos($body, '<?xml')) {
return ''; return '';
} }
$flag = false;
try {
$xml = simplexml_load_string($body); $xml = simplexml_load_string($body);
if (isset($xml->Message)) { if (isset($xml->Message)) {
return strval($xml->Message); return strval($xml->Message);
} }
$flag = true;
} catch (\Exception $e) {
$flag = true;
}
if ($flag === true) {
$start = strpos($body, '<Message>');
if ($start === false) {
return '';
}
$start += 9;
$end = strpos($body, '</Message>', $start);
if ($end === false) {
return '';
}
return substr($body, $start, $end - $start);
}
return ''; return '';
} }
@@ -146,29 +127,10 @@ abstract class Result
if (empty($body) || false === strpos($body, '<?xml')) { if (empty($body) || false === strpos($body, '<?xml')) {
return ''; return '';
} }
$flag = false;
try {
$xml = simplexml_load_string($body); $xml = simplexml_load_string($body);
if (isset($xml->Code)) { if (isset($xml->Code)) {
return strval($xml->Code); return strval($xml->Code);
} }
$flag = true;
} catch (\Exception $e) {
$flag = true;
}
if ($flag === true) {
$start = strpos($body, '<Code>');
if ($start === false) {
return '';
}
$start += 6;
$end = strpos($body, '</Code>', $start);
if ($end === false) {
return '';
}
return substr($body, $start, $end - $start);
}
return ''; return '';
} }

View File

@@ -4,7 +4,6 @@ namespace OSS\Tests;
require_once __DIR__ . '/Common.php'; require_once __DIR__ . '/Common.php';
use OSS\Core\OssException;
use OSS\Model\CnameConfig; use OSS\Model\CnameConfig;
class BucketCnameTest extends \PHPUnit\Framework\TestCase class BucketCnameTest extends \PHPUnit\Framework\TestCase
@@ -32,34 +31,47 @@ class BucketCnameTest extends \PHPUnit\Framework\TestCase
public function testAddCname() public function testAddCname()
{ {
try {
$this->client->addBucketCname($this->bucketName, 'www.baidu.com'); $this->client->addBucketCname($this->bucketName, 'www.baidu.com');
} catch (OssException $e) { $this->client->addBucketCname($this->bucketName, 'www.qq.com');
print_r($e->getMessage());
$this->assertTrue(true);
}
try {
$ret = $this->client->getBucketCname($this->bucketName); $ret = $this->client->getBucketCname($this->bucketName);
$this->assertEquals(0, count($ret->getCnames())); $this->assertEquals(2, count($ret->getCnames()));
} catch (OssException $e) {
$this->assertTrue(false); // add another 2 cnames
$this->client->addBucketCname($this->bucketName, 'www.sina.com.cn');
$this->client->addBucketCname($this->bucketName, 'www.iqiyi.com');
$ret = $this->client->getBucketCname($this->bucketName);
$cnames = $ret->getCnames();
$cnameList = array();
foreach ($cnames as $c) {
$cnameList[] = $c['Domain'];
} }
$should = array(
'www.baidu.com',
'www.qq.com',
'www.sina.com.cn',
'www.iqiyi.com'
);
$this->assertEquals(4, count($cnames));
$this->assertEquals(sort($should), sort($cnameList));
} }
public function testDeleteCname() public function testDeleteCname()
{ {
try { $this->client->addBucketCname($this->bucketName, 'www.baidu.com');
$this->client->deleteBucketCname($this->bucketName, 'www.not-exist.com'); $this->client->addBucketCname($this->bucketName, 'www.qq.com');
} catch (OssException $e) {
$this->assertTrue(false);
}
try {
$ret = $this->client->getBucketCname($this->bucketName); $ret = $this->client->getBucketCname($this->bucketName);
$this->assertEquals(0, count($ret->getCnames())); $this->assertEquals(2, count($ret->getCnames()));
} catch (OssException $e) {
$this->assertTrue(false); // delete one cname
} $this->client->deleteBucketCname($this->bucketName, 'www.baidu.com');
$ret = $this->client->getBucketCname($this->bucketName);
$this->assertEquals(1, count($ret->getCnames()));
$cnames = $ret->getCnames();
$this->assertEquals('www.qq.com', $cnames[0]['Domain']);
} }
} }

View File

@@ -14,14 +14,10 @@ class BucketLiveChannelTest extends \PHPUnit\Framework\TestCase
protected function setUp(): void protected function setUp(): void
{ {
try {
$this->client = Common::getOssClient(); $this->client = Common::getOssClient();
$this->bucketName = 'php-sdk-test-rtmp-bucket-name-' . strval(rand(0, 10000)); $this->bucketName = 'php-sdk-test-rtmp-bucket-name-' . strval(rand(0, 10000));
$this->client->createBucket($this->bucketName); $this->client->createBucket($this->bucketName);
Common::waitMetaSync(); Common::waitMetaSync();
}catch(\Exception $e) {
}
} }
protected function tearDown(): void protected function tearDown(): void

View File

@@ -64,6 +64,7 @@ class CallbackTest extends TestOssClientBase
try { try {
$result = $this->ossClient->completeMultipartUpload($this->bucket, $object, $upload_id, $upload_parts, $options); $result = $this->ossClient->completeMultipartUpload($this->bucket, $object, $upload_id, $upload_parts, $options);
$this->assertEquals("200", $result['info']['http_code']); $this->assertEquals("200", $result['info']['http_code']);
$this->assertEquals("{\"Status\":\"OK\"}", $result['body']);
} catch (OssException $e) { } catch (OssException $e) {
$this->assertTrue(false); $this->assertTrue(false);
} }
@@ -269,6 +270,7 @@ class CallbackTest extends TestOssClientBase
try { try {
$result = $this->ossClient->putObject($this->bucket, $object, $content, $options); $result = $this->ossClient->putObject($this->bucket, $object, $content, $options);
$this->assertEquals($status, $result['info']['http_code']); $this->assertEquals($status, $result['info']['http_code']);
$this->assertEquals("{\"Status\":\"OK\"}", $result['body']);
} catch (OssException $e) { } catch (OssException $e) {
$this->assertFalse(true); $this->assertFalse(true);
} }
@@ -290,8 +292,5 @@ class CallbackTest extends TestOssClientBase
protected function setUp(): void protected function setUp(): void
{ {
parent::setUp(); parent::setUp();
if (strlen(Common::getCallbackUrl()) == 0) {
throw new OssException("callback url can not be empty!");
}
} }
} }

View File

@@ -3,11 +3,9 @@
namespace OSS\Tests; namespace OSS\Tests;
require_once __DIR__ . '/../../../autoload.php'; require_once __DIR__ . '/../../../autoload.php';
require_once __DIR__ . DIRECTORY_SEPARATOR . 'StsClient.php';
use OSS\OssClient; use OSS\OssClient;
use OSS\Core\OssException; use OSS\Core\OssException;
use OSS\Credentials\StaticCredentialsProvider;
/** /**
* Class Common * Class Common
@@ -21,121 +19,34 @@ class Common
* *
* @return OssClient An OssClient instance * @return OssClient An OssClient instance
*/ */
public static function getOssClient($conf = NULL) public static function getOssClient()
{ {
try { try {
$provider = new StaticCredentialsProvider( $ossClient = new OssClient(
getenv('OSS_ACCESS_KEY_ID'), getenv('OSS_ACCESS_KEY_ID'),
getenv('OSS_ACCESS_KEY_SECRET') getenv('OSS_ACCESS_KEY_SECRET'),
); getenv('OSS_ENDPOINT'), false);
$config = array(
'region' => self::getRegion(),
'endpoint' => self::getEndpoint(),
'provider' => $provider,
'signatureVersion' => self::getSignVersion()
);
if ($conf != null) {
foreach ($conf as $key => $value) {
$config[$key] = $value;
}
}
$ossClient = new OssClient($config);
} catch (OssException $e) {
printf(__FUNCTION__ . "creating OssClient instance: FAILED\n");
printf($e->getMessage() . "\n");
}
return $ossClient;
}
public static function getStsOssClient($conf = NULL)
{
$stsClient = new StsClient();
$assumeRole = new AssumeRole();
$stsClient->AccessSecret = getenv('OSS_ACCESS_KEY_SECRET');
$assumeRole->AccessKeyId = getenv('OSS_ACCESS_KEY_ID');
$assumeRole->RoleArn = getenv('OSS_TEST_RAM_ROLE_ARN');
$params = $assumeRole->getAttributes();
$response = $stsClient->doAction($params);
try {
$provider = new StaticCredentialsProvider(
$response->Credentials->AccessKeyId,
$response->Credentials->AccessKeySecret,
$response->Credentials->SecurityToken
);
$config = array(
'region' => self::getRegion(),
'endpoint' => self::getEndpoint(),
'provider' => $provider,
'signatureVersion' => self::getSignVersion()
);
if ($conf != null) {
foreach ($conf as $key => $value) {
$config[$key] = $value;
}
}
$ossStsClient = new OssClient($config);
} catch (OssException $e) { } catch (OssException $e) {
printf(__FUNCTION__ . "creating OssClient instance: FAILED\n"); printf(__FUNCTION__ . "creating OssClient instance: FAILED\n");
printf($e->getMessage() . "\n"); printf($e->getMessage() . "\n");
return null; return null;
} }
return $ossStsClient; return $ossClient;
} }
public static function getBucketName() public static function getBucketName()
{ {
$name = getenv('OSS_BUCKET'); return getenv('OSS_BUCKET');
if (empty($name)) {
return "skyranch-php-test";
}
return $name;
} }
public static function getRegion() public static function getRegion()
{ {
return getenv('OSS_TEST_REGION'); return getenv('OSS_REGION');
}
public static function getEndpoint()
{
return getenv('OSS_TEST_ENDPOINT');
} }
public static function getCallbackUrl() public static function getCallbackUrl()
{ {
return getenv('OSS_TEST_CALLBACK_URL'); return getenv('OSS_CALLBACK_URL');
}
public static function getPayerUid()
{
return getenv('OSS_TEST_PAYER_UID');
}
public static function getPayerAccessKeyId()
{
return getenv('OSS_TEST_PAYER_ACCESS_KEY_ID');
}
public static function getPayerAccessKeySecret()
{
return getenv('OSS_TEST_PAYER_ACCESS_KEY_SECRET');
}
public static function getSignVersion()
{
return OssClient::OSS_SIGNATURE_VERSION_V1;
}
public static function getPathStyleBucket()
{
return getenv('OSS_TEST_PATHSTYLE_BUCKET');
} }
/** /**

View File

@@ -2,14 +2,19 @@
namespace OSS\Tests; namespace OSS\Tests;
use OSS\Core\OssUtil;
use OSS\OssClient;
require_once __DIR__ . '/Common.php'; require_once __DIR__ . '/Common.php';
require_once __DIR__ . DIRECTORY_SEPARATOR . 'TestOssClientBase.php';
class ContentTypeTest extends TestOssClientBase class ContentTypeTest extends TestOssClientBase
{ {
private function runCmd($cmd)
{
$output = array();
$status = 0;
exec($cmd . ' 2>/dev/null', $output, $status);
$this->assertEquals(0, $status);
}
private function getContentType($bucket, $object) private function getContentType($bucket, $object)
{ {
$client = $this->ossClient; $client = $this->ossClient;
@@ -22,22 +27,22 @@ class ContentTypeTest extends TestOssClientBase
$client = $this->ossClient; $client = $this->ossClient;
$bucket = $this->bucket; $bucket = $this->bucket;
$file = __DIR__ . DIRECTORY_SEPARATOR . 'x.html'; $file = '/tmp/x.html';
$object = 'test/x'; $object = 'test/x';
OssUtil::generateFile($file, 5); $this->runCmd('touch ' . $file);
$client->uploadFile($bucket, $object, $file); $client->uploadFile($bucket, $object, $file);
$type = $this->getContentType($bucket, $object); $type = $this->getContentType($bucket, $object);
$this->assertEquals('text/html', $type);
unlink($file);
$file = __DIR__ . DIRECTORY_SEPARATOR . 'x.json'; $this->assertEquals('text/html', $type);
$file = '/tmp/x.json';
$object = 'test/y'; $object = 'test/y';
OssUtil::generateFile($file, 100 * 1024); $this->runCmd('dd if=/dev/urandom of=' . $file . ' bs=1024 count=100');
$client->multiuploadFile($bucket, $object, $file, array('partSize' => 100)); $client->multiuploadFile($bucket, $object, $file, array('partSize' => 100));
$type = $this->getContentType($bucket, $object); $type = $this->getContentType($bucket, $object);
unlink($file);
$this->assertEquals('application/json', $type); $this->assertEquals('application/json', $type);
} }
@@ -49,37 +54,43 @@ class ContentTypeTest extends TestOssClientBase
$object = "test/x.txt"; $object = "test/x.txt";
$client->putObject($bucket, $object, "hello world"); $client->putObject($bucket, $object, "hello world");
$type = $this->getContentType($bucket, $object); $type = $this->getContentType($bucket, $object);
$this->assertEquals('text/plain', $type); $this->assertEquals('text/plain', $type);
$file = __DIR__ . DIRECTORY_SEPARATOR . 'x.html'; $file = '/tmp/x.html';
$object = 'test/x.txt'; $object = 'test/x.txt';
OssUtil::generateFile($file, 5); $this->runCmd('touch ' . $file);
$client->uploadFile($bucket, $object, $file); $client->uploadFile($bucket, $object, $file);
unlink($file);
$type = $this->getContentType($bucket, $object); $type = $this->getContentType($bucket, $object);
$this->assertEquals('text/html', $type); $this->assertEquals('text/html', $type);
$file = __DIR__ . DIRECTORY_SEPARATOR . 'x.none'; $file = '/tmp/x.none';
$object = 'test/x.txt'; $object = 'test/x.txt';
OssUtil::generateFile($file, 5); $this->runCmd('touch ' . $file);
$client->uploadFile($bucket, $object, $file); $client->uploadFile($bucket, $object, $file);
unlink($file);
$type = $this->getContentType($bucket, $object); $type = $this->getContentType($bucket, $object);
$this->assertEquals('text/plain', $type); $this->assertEquals('text/plain', $type);
$file = __DIR__ . DIRECTORY_SEPARATOR . 'x.mp3'; $file = '/tmp/x.mp3';
OssUtil::generateFile($file, 1024 * 100);
$object = 'test/y.json'; $object = 'test/y.json';
$this->runCmd('dd if=/dev/urandom of=' . $file . ' bs=1024 count=100');
$client->multiuploadFile($bucket, $object, $file, array('partSize' => 100)); $client->multiuploadFile($bucket, $object, $file, array('partSize' => 100));
unlink($file);
$type = $this->getContentType($bucket, $object); $type = $this->getContentType($bucket, $object);
$this->assertEquals('audio/mpeg', $type); $this->assertEquals('audio/mpeg', $type);
$file = __DIR__ . DIRECTORY_SEPARATOR . 'x.none';
OssUtil::generateFile($file, 1024 * 100); $file = '/tmp/x.none';
$object = 'test/y.json'; $object = 'test/y.json';
$this->runCmd('dd if=/dev/urandom of=' . $file . ' bs=1024 count=100');
$client->multiuploadFile($bucket, $object, $file, array('partSize' => 100)); $client->multiuploadFile($bucket, $object, $file, array('partSize' => 100));
unlink($file);
$type = $this->getContentType($bucket, $object); $type = $this->getContentType($bucket, $object);
$this->assertEquals('application/json', $type); $this->assertEquals('application/json', $type);
} }
@@ -96,28 +107,27 @@ class ContentTypeTest extends TestOssClientBase
$this->assertEquals('text/html', $type); $this->assertEquals('text/html', $type);
$file = __DIR__ . DIRECTORY_SEPARATOR . 'x.html'; $file = '/tmp/x.html';
$object = 'test/x'; $object = 'test/x';
OssUtil::generateFile($file, 100); $this->runCmd('touch ' . $file);
$client->uploadFile($bucket, $object, $file, array(OssClient::OSS_HEADERS => array( $client->uploadFile($bucket, $object, $file, array(
'Content-Type' => 'application/json' 'Content-Type' => 'application/json'
))); ));
unlink($file);
$type = $this->getContentType($bucket, $object); $type = $this->getContentType($bucket, $object);
$this->assertEquals('application/json', $type); $this->assertEquals('application/json', $type);
$file = __DIR__ . DIRECTORY_SEPARATOR . 'x.json'; $file = '/tmp/x.json';
$object = 'test/y'; $object = 'test/y';
OssUtil::generateFile($file, 100 * 1024); $this->runCmd('dd if=/dev/urandom of=' . $file . ' bs=1024 count=100');
$client->multiuploadFile($bucket, $object, $file, array( $client->multiuploadFile($bucket, $object, $file, array(
'partSize' => 100, 'partSize' => 100,
'Content-Type' => 'audio/mpeg' 'Content-Type' => 'audio/mpeg'
)); ));
unlink($file);
$type = $this->getContentType($bucket, $object); $type = $this->getContentType($bucket, $object);
$this->assertEquals('audio/mpeg', $type); $this->assertEquals('audio/mpeg', $type);
} }
} }

View File

@@ -3,12 +3,9 @@
namespace OSS\Tests; namespace OSS\Tests;
use OSS\Http\ResponseCore;
use OSS\Model\CorsConfig; use OSS\Model\CorsConfig;
use OSS\Model\CorsRule; use OSS\Model\CorsRule;
use OSS\Core\OssException; use OSS\Core\OssException;
use OSS\Result\GetCorsResult;
use OSS\Result\Result;
class CorsConfigTest extends \PHPUnit\Framework\TestCase class CorsConfigTest extends \PHPUnit\Framework\TestCase
{ {
@@ -38,7 +35,6 @@ class CorsConfigTest extends \PHPUnit\Framework\TestCase
<ExposeHeader>x-oss-test1</ExposeHeader> <ExposeHeader>x-oss-test1</ExposeHeader>
<MaxAgeSeconds>110</MaxAgeSeconds> <MaxAgeSeconds>110</MaxAgeSeconds>
</CORSRule> </CORSRule>
<ResponseVary>false</ResponseVary>
</CORSConfiguration> </CORSConfiguration>
BBBB; BBBB;
@@ -62,23 +58,6 @@ BBBB;
<MaxAgeSeconds>10</MaxAgeSeconds> <MaxAgeSeconds>10</MaxAgeSeconds>
</CORSRule> </CORSRule>
</CORSConfiguration> </CORSConfiguration>
BBBB;
private $validXml3 = <<<BBBB
<?xml version="1.0" encoding="utf-8"?>
<CORSConfiguration>
<CORSRule>
<AllowedOrigin>http://www.b.com</AllowedOrigin>
<AllowedOrigin>http://www.a.com</AllowedOrigin>
<AllowedOrigin>http://www.a.com</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<AllowedMethod>PUT</AllowedMethod>
<AllowedMethod>POST</AllowedMethod>
<AllowedHeader>x-oss-test</AllowedHeader>
<MaxAgeSeconds>10</MaxAgeSeconds>
</CORSRule>
<ResponseVary>true</ResponseVary>
</CORSConfiguration>
BBBB; BBBB;
public function testParseValidXml() public function testParseValidXml()
@@ -102,56 +81,6 @@ BBBB;
$this->assertEquals($this->cleanXml($this->validXml2), $this->cleanXml($corsConfig->serializeToXml())); $this->assertEquals($this->cleanXml($this->validXml2), $this->cleanXml($corsConfig->serializeToXml()));
} }
public function testParseValidXml3()
{
$corsConfig = new CorsConfig();
$corsConfig->parseFromXml($this->validXml3);
$this->assertEquals($this->cleanXml($this->validXml3), $this->cleanXml($corsConfig->serializeToXml()));
$this->assertTrue($corsConfig->getResponseVary());
}
public function testResponseValidXml3()
{
$response = new ResponseCore(array(), $this->validXml, 200);
$result = new GetCorsResult($response);
$this->assertTrue($result->isOK());
$this->assertNotNull($result->getData());
$this->assertNotNull($result->getRawResponse());
$this->assertNotNull($result->getRawResponse()->body);
$corsConfig = $result->getData();
$this->assertEquals($this->cleanXml($this->validXml), $this->cleanXml($corsConfig->serializeToXml()));
$this->assertNotNull($corsConfig->getRules());
$rules = $corsConfig->getRules();
$this->assertNotNull($rules[0]->getAllowedHeaders());
$this->assertNotNull($rules[0]->getAllowedMethods());
$this->assertNotNull($rules[0]->getAllowedOrigins());
$this->assertNotNull($rules[0]->getExposeHeaders());
$this->assertNotNull($rules[0]->getMaxAgeSeconds());
$this->assertFalse($corsConfig->getResponseVary());
}
public function testResponseValidXml4()
{
$response = new ResponseCore(array(), $this->validXml3, 200);
$result = new GetCorsResult($response);
$this->assertTrue($result->isOK());
$this->assertNotNull($result->getData());
$this->assertNotNull($result->getRawResponse());
$this->assertNotNull($result->getRawResponse()->body);
$corsConfig = $result->getData();
$this->assertEquals($this->cleanXml($this->validXml3), $this->cleanXml($corsConfig->serializeToXml()));
$this->assertNotNull($corsConfig->getRules());
$rules = $corsConfig->getRules();
$this->assertNotNull($rules[0]->getAllowedHeaders());
$this->assertNotNull($rules[0]->getAllowedMethods());
$this->assertNotNull($rules[0]->getAllowedOrigins());
$this->assertNotNull($rules[0]->getExposeHeaders());
$this->assertNotNull($rules[0]->getMaxAgeSeconds());
$this->assertTrue($corsConfig->getResponseVary());
}
public function testCreateCorsConfigFromMoreThan10Rules() public function testCreateCorsConfigFromMoreThan10Rules()
{ {
$corsConfig = new CorsConfig(); $corsConfig = new CorsConfig();

View File

@@ -10,24 +10,11 @@ class GetBucketStatResultTest extends \PHPUnit\Framework\TestCase
{ {
private $validXml = <<<BBBB private $validXml = <<<BBBB
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" ?>
<BucketStat> <BucketStat>
<Storage>1600</Storage> <Storage>100</Storage>
<ObjectCount>230</ObjectCount> <ObjectCount>200</ObjectCount>
<MultipartUploadCount>40</MultipartUploadCount> <MultipartUploadCount>10</MultipartUploadCount>
<LiveChannelCount>4</LiveChannelCount>
<LastModifiedTime>1643341269</LastModifiedTime>
<StandardStorage>430</StandardStorage>
<StandardObjectCount>66</StandardObjectCount>
<InfrequentAccessStorage>2359296</InfrequentAccessStorage>
<InfrequentAccessRealStorage>360</InfrequentAccessRealStorage>
<InfrequentAccessObjectCount>54</InfrequentAccessObjectCount>
<ArchiveStorage>2949120</ArchiveStorage>
<ArchiveRealStorage>450</ArchiveRealStorage>
<ArchiveObjectCount>74</ArchiveObjectCount>
<ColdArchiveStorage>2359296</ColdArchiveStorage>
<ColdArchiveRealStorage>360</ColdArchiveRealStorage>
<ColdArchiveObjectCount>36</ColdArchiveObjectCount>
</BucketStat> </BucketStat>
BBBB; BBBB;
@@ -45,22 +32,9 @@ BBBB;
$this->assertNotNull($result->getData()); $this->assertNotNull($result->getData());
$this->assertNotNull($result->getRawResponse()); $this->assertNotNull($result->getRawResponse());
$stat = $result->getData(); $stat = $result->getData();
$this->assertEquals(1600, $stat->getStorage()); $this->assertEquals(100, $stat->getStorage());
$this->assertEquals(230, $stat->getObjectCount()); $this->assertEquals(200, $stat->getObjectCount());
$this->assertEquals(40, $stat->getMultipartUploadCount()); $this->assertEquals(10, $stat->getMultipartUploadCount());
$this->assertEquals(4, $stat->getLiveChannelCount());
$this->assertEquals(1643341269, $stat->getLastModifiedTime());
$this->assertEquals(430, $stat->getStandardStorage());
$this->assertEquals(66, $stat->getStandardObjectCount());
$this->assertEquals(2359296, $stat->getInfrequentAccessStorage());
$this->assertEquals(360, $stat->getInfrequentAccessRealStorage());
$this->assertEquals(54, $stat->getInfrequentAccessObjectCount());
$this->assertEquals(2949120, $stat->getArchiveStorage());
$this->assertEquals(450, $stat->getArchiveRealStorage());
$this->assertEquals(74, $stat->getArchiveObjectCount());
$this->assertEquals(2359296, $stat->getColdArchiveStorage());
$this->assertEquals(360, $stat->getColdArchiveRealStorage());
$this->assertEquals(36, $stat->getColdArchiveObjectCount());
} }
public function testParseNullXml() public function testParseNullXml()

View File

@@ -42,8 +42,35 @@ BBBB;
</ListAllMyBucketsResult> </ListAllMyBucketsResult>
BBBB; BBBB;
public function testParseValidXml()
{
$response = new ResponseCore(array(), $this->validXml, 200);
$result = new ListBucketsResult($response);
$this->assertTrue($result->isOK());
$this->assertNotNull($result->getData());
$this->assertNotNull($result->getRawResponse());
$bucketListInfo = $result->getData();
$this->assertEquals(2, count($bucketListInfo->getBucketList()));
}
private $errorBody = <<< BBBB public function testParseNullXml()
{
$response = new ResponseCore(array(), $this->nullXml, 200);
$result = new ListBucketsResult($response);
$this->assertTrue($result->isOK());
$this->assertNotNull($result->getData());
$this->assertNotNull($result->getRawResponse());
$bucketListInfo = $result->getData();
$this->assertEquals(0, count($bucketListInfo->getBucketList()));
}
public function test403()
{
$errorHeader = array(
'x-oss-request-id' => '1a2b-3c4d'
);
$errorBody = <<< BBBB
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<Error> <Error>
<Code>NoSuchBucket</Code> <Code>NoSuchBucket</Code>
@@ -53,8 +80,24 @@ BBBB;
<BucketName>hello</BucketName> <BucketName>hello</BucketName>
</Error> </Error>
BBBB; BBBB;
$response = new ResponseCore($errorHeader, $errorBody, 403);
try {
new ListBucketsResult($response);
} catch (OssException $e) {
$this->assertEquals(
$e->getMessage(),
'NoSuchBucket: The specified bucket does not exist. RequestId: 1a2b-3c4d');
$this->assertEquals($e->getHTTPStatus(), '403');
$this->assertEquals($e->getRequestId(), '1a2b-3c4d');
$this->assertEquals($e->getErrorCode(), 'NoSuchBucket');
$this->assertEquals($e->getErrorMessage(), 'The specified bucket does not exist.');
$this->assertEquals($e->getDetails(), $errorBody);
}
}
private $xml = <<<BBBB public function testParseXml2()
{
$xml = <<<BBBB
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<ListAllMyBucketsResult> <ListAllMyBucketsResult>
<Owner> <Owner>
@@ -89,51 +132,7 @@ BBBB;
</ListAllMyBucketsResult> </ListAllMyBucketsResult>
BBBB; BBBB;
public function testParseValidXml() $response = new ResponseCore(array(), $xml, 200);
{
$response = new ResponseCore(array(), $this->validXml, 200);
$result = new ListBucketsResult($response);
$this->assertTrue($result->isOK());
$this->assertNotNull($result->getData());
$this->assertNotNull($result->getRawResponse());
$bucketListInfo = $result->getData();
$this->assertEquals(2, count($bucketListInfo->getBucketList()));
}
public function testParseNullXml()
{
$response = new ResponseCore(array(), $this->nullXml, 200);
$result = new ListBucketsResult($response);
$this->assertTrue($result->isOK());
$this->assertNotNull($result->getData());
$this->assertNotNull($result->getRawResponse());
$bucketListInfo = $result->getData();
$this->assertEquals(0, count($bucketListInfo->getBucketList()));
}
public function test403()
{
$errorHeader = array(
'x-oss-request-id' => '1a2b-3c4d'
);
$response = new ResponseCore($errorHeader, $this->errorBody, 403);
try {
new ListBucketsResult($response);
} catch (OssException $e) {
$this->assertEquals(
$e->getMessage(),
'NoSuchBucket: The specified bucket does not exist. RequestId: 1a2b-3c4d');
$this->assertEquals($e->getHTTPStatus(), '403');
$this->assertEquals($e->getRequestId(), '1a2b-3c4d');
$this->assertEquals($e->getErrorCode(), 'NoSuchBucket');
$this->assertEquals($e->getErrorMessage(), 'The specified bucket does not exist.');
$this->assertEquals($e->getDetails(), $this->errorBody);
}
}
public function testParseXml2()
{
$response = new ResponseCore(array(), $this->xml, 200);
$result = new ListBucketsResult($response); $result = new ListBucketsResult($response);
$this->assertTrue($result->isOK()); $this->assertTrue($result->isOK());
$this->assertNotNull($result->getData()); $this->assertNotNull($result->getData());

View File

@@ -75,33 +75,6 @@ BBBB;
</Owner> </Owner>
</Contents> </Contents>
</ListBucketResult> </ListBucketResult>
BBBB;
private $validXmlWithResoreInfo = <<<BBBB
<?xml version="1.0" encoding="UTF-8"?>
<ListBucketResult>
<Name>testbucket-hf</Name>
<EncodingType>url</EncodingType>
<Prefix>php%2Fprefix</Prefix>
<Marker>php%2Fmarker</Marker>
<NextMarker>php%2Fnext-marker</NextMarker>
<MaxKeys>1000</MaxKeys>
<Delimiter>%2F</Delimiter>
<IsTruncated>true</IsTruncated>
<Contents>
<Key>php/a%2Bb</Key>
<LastModified>2015-11-18T03:36:00.000Z</LastModified>
<ETag>"89B9E567E7EB8815F2F7D41851F9A2CD"</ETag>
<Type>Normal</Type>
<Size>13115</Size>
<StorageClass>Standard</StorageClass>
<Owner>
<ID>cname_user</ID>
<DisplayName>cname_user</DisplayName>
</Owner>
<RestoreInfo>ongoing-request="false", expiry-date="Tue, 25 Apr 2023 07:30:00 GMT"</RestoreInfo>
</Contents>
</ListBucketResult>
BBBB; BBBB;
public function testParseValidXml1() public function testParseValidXml1()
@@ -175,34 +148,4 @@ BBBB;
$this->assertEquals(13115, $objects[0]->getSize()); $this->assertEquals(13115, $objects[0]->getSize());
$this->assertEquals('Standard', $objects[0]->getStorageClass()); $this->assertEquals('Standard', $objects[0]->getStorageClass());
} }
public function testParseValidXmlWithRestoreInfo()
{
$response = new ResponseCore(array(), $this->validXmlWithResoreInfo, 200);
$result = new ListObjectsResult($response);
$this->assertTrue($result->isOK());
$this->assertNotNull($result->getData());
$this->assertNotNull($result->getRawResponse());
$objectListInfo = $result->getData();
$this->assertEquals(0, count($objectListInfo->getPrefixList()));
$this->assertEquals(1, count($objectListInfo->getObjectList()));
$this->assertEquals('testbucket-hf', $objectListInfo->getBucketName());
$this->assertEquals('php/prefix', $objectListInfo->getPrefix());
$this->assertEquals('php/marker', $objectListInfo->getMarker());
$this->assertEquals('php/next-marker', $objectListInfo->getNextMarker());
$this->assertEquals(1000, $objectListInfo->getMaxKeys());
$this->assertEquals('/', $objectListInfo->getDelimiter());
$this->assertEquals('true', $objectListInfo->getIsTruncated());
$objects = $objectListInfo->getObjectList();
$this->assertEquals('php/a+b', $objects[0]->getKey());
$this->assertEquals('2015-11-18T03:36:00.000Z', $objects[0]->getLastModified());
$this->assertEquals('"89B9E567E7EB8815F2F7D41851F9A2CD"', $objects[0]->getETag());
$this->assertEquals('Normal', $objects[0]->getType());
$this->assertEquals(13115, $objects[0]->getSize());
$this->assertEquals('Standard', $objects[0]->getStorageClass());
$this->assertEquals('ongoing-request="false", expiry-date="Tue, 25 Apr 2023 07:30:00 GMT"', $objects[0]->getRestoreInfo());
$this->assertEquals('cname_user', $objects[0]->getOwner()->getId());
$this->assertEquals('cname_user', $objects[0]->getOwner()->getDisplayName());
}
} }

View File

@@ -74,35 +74,6 @@ BBBB;
</Contents> </Contents>
<KeyCount>1</KeyCount> <KeyCount>1</KeyCount>
</ListBucketResult> </ListBucketResult>
BBBB;
private $validXmlWithRestoreInfo = <<<BBBB
<?xml version="1.0" encoding="UTF-8"?>
<ListBucketResult>
<Name>testbucket-hf</Name>
<EncodingType>url</EncodingType>
<Prefix>php%2Fprefix</Prefix>
<StartAfter>php%2Fmarker</StartAfter>
<ContinuationToken>1gJiYw--</ContinuationToken>
<NextContinuationToken>CgJiYw--</NextContinuationToken>
<MaxKeys>1000</MaxKeys>
<Delimiter>%2F</Delimiter>
<IsTruncated>true</IsTruncated>
<Contents>
<Key>php/a%2Bb</Key>
<LastModified>2015-11-18T03:36:00.000Z</LastModified>
<ETag>"89B9E567E7EB8815F2F7D41851F9A2CD"</ETag>
<Type>Normal</Type>
<Size>13115</Size>
<StorageClass>Standard</StorageClass>
<Owner>
<ID>cname_user</ID>
<DisplayName>cname_user</DisplayName>
</Owner>
<RestoreInfo>ongoing-request="false", expiry-date="Tue, 25 Apr 2023 07:30:00 GMT"</RestoreInfo>
</Contents>
<KeyCount>1</KeyCount>
</ListBucketResult>
BBBB; BBBB;
public function testParseValidXml1() public function testParseValidXml1()
@@ -180,36 +151,4 @@ BBBB;
$this->assertEquals(13115, $objects[0]->getSize()); $this->assertEquals(13115, $objects[0]->getSize());
$this->assertEquals('Standard', $objects[0]->getStorageClass()); $this->assertEquals('Standard', $objects[0]->getStorageClass());
} }
public function testParseValidXmlWithRestoreInfo()
{
$response = new ResponseCore(array(), $this->validXmlWithRestoreInfo, 200);
$result = new ListObjectsV2Result($response);
$this->assertTrue($result->isOK());
$this->assertNotNull($result->getData());
$this->assertNotNull($result->getRawResponse());
$objectListInfo = $result->getData();
$this->assertEquals(0, count($objectListInfo->getPrefixList()));
$this->assertEquals(1, count($objectListInfo->getObjectList()));
$this->assertEquals('testbucket-hf', $objectListInfo->getBucketName());
$this->assertEquals('php/prefix', $objectListInfo->getPrefix());
$this->assertEquals('php/marker', $objectListInfo->getStartAfter());
$this->assertEquals('CgJiYw--', $objectListInfo->getNextContinuationToken());
$this->assertEquals('1gJiYw--', $objectListInfo->getContinuationToken());
$this->assertEquals(1000, $objectListInfo->getMaxKeys());
$this->assertEquals('/', $objectListInfo->getDelimiter());
$this->assertEquals('true', $objectListInfo->getIsTruncated());
$this->assertEquals(1, $objectListInfo->getKeyCount());
$objects = $objectListInfo->getObjectList();
$this->assertEquals('php/a+b', $objects[0]->getKey());
$this->assertEquals('2015-11-18T03:36:00.000Z', $objects[0]->getLastModified());
$this->assertEquals('"89B9E567E7EB8815F2F7D41851F9A2CD"', $objects[0]->getETag());
$this->assertEquals('Normal', $objects[0]->getType());
$this->assertEquals(13115, $objects[0]->getSize());
$this->assertEquals('Standard', $objects[0]->getStorageClass());
$this->assertEquals('ongoing-request="false", expiry-date="Tue, 25 Apr 2023 07:30:00 GMT"', $objects[0]->getRestoreInfo());
$this->assertEquals('cname_user', $objects[0]->getOwner()->getId());
$this->assertEquals('cname_user', $objects[0]->getOwner()->getDisplayName());
}
} }

View File

@@ -3,7 +3,6 @@
namespace OSS\Tests; namespace OSS\Tests;
require_once __DIR__ . '/Common.php'; require_once __DIR__ . '/Common.php';
require_once __DIR__ . DIRECTORY_SEPARATOR . 'TestOssClientBase.php';
class ObjectAclTest extends TestOssClientBase class ObjectAclTest extends TestOssClientBase
{ {

View File

@@ -7,7 +7,6 @@ use OSS\Model\CorsConfig;
use OSS\Model\CorsRule; use OSS\Model\CorsRule;
use OSS\OssClient; use OSS\OssClient;
require_once __DIR__ . DIRECTORY_SEPARATOR . 'TestOssClientBase.php'; require_once __DIR__ . DIRECTORY_SEPARATOR . 'TestOssClientBase.php';
@@ -39,7 +38,6 @@ class OssClientBucketCorsTest extends TestOssClientBase
$rule->addExposeHeader("x-oss-test1"); $rule->addExposeHeader("x-oss-test1");
$rule->setMaxAgeSeconds(110); $rule->setMaxAgeSeconds(110);
$corsConfig->addRule($rule); $corsConfig->addRule($rule);
$corsConfig->setResponseVary(true);
try { try {
$this->ossClient->putBucketCors($this->bucket, $corsConfig); $this->ossClient->putBucketCors($this->bucket, $corsConfig);
@@ -82,44 +80,5 @@ class OssClientBucketCorsTest extends TestOssClientBase
$this->assertFalse(True); $this->assertFalse(True);
} }
try {
Common::waitMetaSync();
$this->ossClient->deleteBucketCors($this->bucket);
} catch (OssException $e) {
$this->assertFalse(True);
}
$corsConfig = new CorsConfig();
$rule = new CorsRule();
$rule->addAllowedHeader("x-oss-test");
$rule->addAllowedOrigin("http://www.b.com");
$rule->addAllowedMethod("GET");
$rule->addExposeHeader("x-oss-test1");
$rule->setMaxAgeSeconds(10);
$corsConfig->addRule($rule);
$rule = new CorsRule();
$rule->addAllowedHeader("x-oss-test");
$rule->addAllowedMethod("GET");
$rule->addAllowedOrigin("http://www.b.com");
$rule->addExposeHeader("x-oss-test1");
$rule->setMaxAgeSeconds(110);
$corsConfig->addRule($rule);
$corsConfig->setResponseVary(false);
try {
$this->ossClient->putBucketCors($this->bucket, $corsConfig);
} catch (OssException $e) {
$this->assertFalse(True);
}
try {
Common::waitMetaSync();
$corsConfig4 = $this->ossClient->getBucketCors($this->bucket);
$this->assertNotNull($corsConfig4);
$this->assertEquals($corsConfig->serializeToXml(), $corsConfig4->serializeToXml());
} catch (OssException $e) {
$this->assertFalse(True);
}
} }
} }

View File

@@ -1,5 +1,4 @@
<?php <?php
namespace OSS\Tests; namespace OSS\Tests;
use OSS\Core\OssException; use OSS\Core\OssException;
@@ -20,12 +19,8 @@ class OssClientBucketPolicyTest extends TestOssClientBase
"oss:GetObject" "oss:GetObject"
], ],
"Effect":"Deny", "Effect":"Deny",
"Principal": [ "Principal":["1234567890"],
"1234567890" "Resource":["acs:oss:*:1234567890:*/*"]
],
"Resource": [
"acs:oss:*:1234567890:*/*"
]
} }
] ]
} }
@@ -43,9 +38,7 @@ BBBB;
try { try {
$this->ossClient->putBucketPolicy($this->bucket, $policy_str); $this->ossClient->putBucketPolicy($this->bucket, $policy_str);
$policy = $this->ossClient->getBucketPolicy($this->bucket); $policy = $this->ossClient->getBucketPolicy($this->bucket);
$data1 = json_decode($policy_str, true); $this->assertEquals($policy_str, $policy);
$data2 = json_decode($policy, true);
$this->assertEquals($data1, $data2);
$this->ossClient->deleteBucketPolicy($this->bucket); $this->ossClient->deleteBucketPolicy($this->bucket);
} catch (OssException $e) { } catch (OssException $e) {
$this->assertTrue(false); $this->assertTrue(false);

View File

@@ -52,11 +52,11 @@ class OssClientBucketTest extends TestOssClientBase
$this->assertTrue($this->ossClient->doesBucketExist($this->bucket)); $this->assertTrue($this->ossClient->doesBucketExist($this->bucket));
$this->assertFalse($this->ossClient->doesBucketExist($this->bucket . '-notexist')); $this->assertFalse($this->ossClient->doesBucketExist($this->bucket . '-notexist'));
//$this->assertContains(Common::getRegion(), $this->ossClient->getBucketLocation($this->bucket)); $this->assertEquals($this->ossClient->getBucketLocation($this->bucket), Common::getRegion());
$res = $this->ossClient->getBucketMeta($this->bucket); $res = $this->ossClient->getBucketMeta($this->bucket);
$this->assertEquals('200', $res['info']['http_code']); $this->assertEquals('200', $res['info']['http_code']);
//$this->assertContains(Common::getRegion(), $res['x-oss-bucket-region']); $this->assertEquals(Common::getRegion(), $res['x-oss-bucket-region']);
} }
public function testCreateBucketWithStorageType() public function testCreateBucketWithStorageType()

View File

@@ -4,11 +4,9 @@ namespace OSS\Tests;
require_once __DIR__ . '/Common.php'; require_once __DIR__ . '/Common.php';
require_once __DIR__ . DIRECTORY_SEPARATOR . 'TestOssClientBase.php';
use OSS\OssClient; use OSS\OssClient;
class OssClientImageTest extends TestOssClientBase class OssClinetImageTest extends TestOssClientBase
{ {
private $bucketName; private $bucketName;
private $client; private $client;

View File

@@ -399,6 +399,7 @@ class OssClientMultipartUploadTest extends TestOssClientBase
try { try {
$uploadId = $this->ossClient->initiateMultipartUpload($this->bucket, $object); $uploadId = $this->ossClient->initiateMultipartUpload($this->bucket, $object);
$listMultipartUploadInfo = $this->ossClient->completeMultipartUpload($this->bucket, $object, $uploadId, array()); $listMultipartUploadInfo = $this->ossClient->completeMultipartUpload($this->bucket, $object, $uploadId, array());
var_dump($listMultipartUploadInfo);
$this->assertNotNull($listMultipartUploadInfo); $this->assertNotNull($listMultipartUploadInfo);
} catch (OssException $e) { } catch (OssException $e) {
$this->assertFalse(true); $this->assertFalse(true);
@@ -464,6 +465,7 @@ class OssClientMultipartUploadTest extends TestOssClientBase
try { try {
$result = $this->ossClient->completeMultipartUpload($this->bucket, $object, $upload_id, null,$options); $result = $this->ossClient->completeMultipartUpload($this->bucket, $object, $upload_id, null,$options);
var_dump($result);
$this->assertNotNull($result); $this->assertNotNull($result);
} catch (OssException $e) { } catch (OssException $e) {
$this->assertTrue(false); $this->assertTrue(false);

View File

@@ -451,12 +451,12 @@ class OssClientObjectRequestPaymentTest extends TestOssClientBase
{ {
parent::setUp(); parent::setUp();
$this->payerClient = new OssClient( $this->payerClient = new OssClient(
Common::getPayerAccessKeyId(), getenv('OSS_PAYER_ACCESS_KEY_ID'),
Common::getPayerAccessKeySecret(), getenv('OSS_PAYER_ACCESS_KEY_SECRET'),
Common::getEndpoint(), false); getenv('OSS_ENDPOINT'), false);
$policy = '{"Version":"1","Statement":[{"Action":["oss:*"],"Effect": "Allow",'. $policy = '{"Version":"1","Statement":[{"Action":["oss:*"],"Effect": "Allow",'.
'"Principal":["' . Common::getPayerUid() . '"],'. '"Principal":["' . getenv('OSS_PAYER_UID') . '"],'.
'"Resource": ["acs:oss:*:*:' . $this->bucket . '","acs:oss:*:*:' . $this->bucket . '/*"]}]}'; '"Resource": ["acs:oss:*:*:' . $this->bucket . '","acs:oss:*:*:' . $this->bucket . '/*"]}]}';
$this->ossClient->putBucketPolicy($this->bucket, $policy); $this->ossClient->putBucketPolicy($this->bucket, $policy);

View File

@@ -3,7 +3,6 @@
namespace OSS\Tests; namespace OSS\Tests;
use OSS\Core\OssException; use OSS\Core\OssException;
use OSS\Core\OssUtil;
use OSS\OssClient; use OSS\OssClient;
require_once __DIR__ . DIRECTORY_SEPARATOR . 'TestOssClientBase.php'; require_once __DIR__ . DIRECTORY_SEPARATOR . 'TestOssClientBase.php';
@@ -21,7 +20,8 @@ class OssClientObjectTest extends TestOssClientBase
$this->assertEquals('200', $res['info']['http_code']); $this->assertEquals('200', $res['info']['http_code']);
$this->assertEquals('text/plain', $res['content-type']); $this->assertEquals('text/plain', $res['content-type']);
$this->assertEquals('Accept-Encoding', $res['vary']); $this->assertEquals('Accept-Encoding', $res['vary']);
$this->assertTrue(isset($res['content-encoding'])); $this->assertTrue(isset($res['content-length']));
$this->assertFalse(isset($res['content-encoding']));
} catch (OssException $e) { } catch (OssException $e) {
$this->assertTrue(false); $this->assertTrue(false);
} }
@@ -33,6 +33,7 @@ class OssClientObjectTest extends TestOssClientBase
$this->assertEquals('200', $res['info']['http_code']); $this->assertEquals('200', $res['info']['http_code']);
$this->assertEquals('text/plain', $res['content-type']); $this->assertEquals('text/plain', $res['content-type']);
$this->assertEquals('Accept-Encoding', $res['vary']); $this->assertEquals('Accept-Encoding', $res['vary']);
$this->assertFalse(isset($res['content-length']));
$this->assertEquals('gzip', $res['content-encoding']); $this->assertEquals('gzip', $res['content-encoding']);
} catch (OssException $e) { } catch (OssException $e) {
$this->assertTrue(false); $this->assertTrue(false);
@@ -199,7 +200,8 @@ class OssClientObjectTest extends TestOssClientBase
} catch (OssException $e) { } catch (OssException $e) {
$this->assertTrue(true); $this->assertTrue(true);
$this->assertFalse(file_exists($localfile)); $this->assertFalse(file_exists($localfile));
if (strpos($e, "The specified key does not exist") == false) { if (strpos($e, "The specified key does not exist") == false)
{
$this->assertTrue(true); $this->assertTrue(true);
} }
} }
@@ -212,7 +214,8 @@ class OssClientObjectTest extends TestOssClientBase
$this->assertTrue(false); $this->assertTrue(false);
} catch (OssException $e) { } catch (OssException $e) {
$this->assertTrue(true); $this->assertTrue(true);
if (strpos($e, "The specified key does not exist") == false) { if (strpos($e, "The specified key does not exist") == false)
{
$this->assertTrue(true); $this->assertTrue(true);
} }
} }
@@ -770,166 +773,6 @@ class OssClientObjectTest extends TestOssClientBase
} }
} }
public function testObjectKeyWithNonUTF8Name()
{
$object = "中文测试.txt";
$hexObject = bin2hex($object);
$gbkObject = iconv('UTF-8', 'GBK', $object);
$hexGbkObject = bin2hex($gbkObject);
$content = "hello world";
$this->assertEquals("e4b8ade69687e6b58be8af952e747874", $hexObject);
$this->assertEquals("d6d0cec4b2e2cad42e747874", $hexGbkObject);
try {
$this->ossClient->putObject($this->bucket, $gbkObject, $content);
$this->assertTrue(false);
} catch (OssException $e) {
$this->assertEquals('InvalidArgument', $e->getErrorCode());
$this->assertEquals('The characters encoding must be utf-8.', $e->getErrorMessage());
} catch (\Exception $e) {
$this->assertTrue(false);
}
//enable object encoding check
$config = array(
'checkObjectEncoding' => true,
);
$ossClient = Common::getOssClient($config);
try {
$ossClient->putObject($this->bucket, $gbkObject, $content);
$content1 = $this->ossClient->getObject($this->bucket, $object);
$content2 = $ossClient->getObject($this->bucket, $gbkObject);
$this->assertEquals($content, $content1);
$this->assertEquals($content, $content2);
} catch (\Exception $e) {
$this->assertTrue(false);
}
// ascii
try {
$ossClient->putObject($this->bucket, '1234', 'ascii');
$content1 = $this->ossClient->getObject($this->bucket, '1234');
$content2 = $ossClient->getObject($this->bucket, '1234');
$this->assertEquals('ascii', $content1);
$this->assertEquals('ascii', $content2);
} catch (\Exception $e) {
$this->assertTrue(false);
}
}
public function testEncodeFilePath()
{
if (!OssUtil::isWin()) {
$this->assertTrue(true);
return;
}
$fileFolder = __DIR__ . DIRECTORY_SEPARATOR . "中文目录";
$filePath1 = $fileFolder . DIRECTORY_SEPARATOR . "中文文件名1.txt";
$filePath2 = $fileFolder . DIRECTORY_SEPARATOR . "中文文件名2.txt";
$gbkfileFolder = iconv('UTF-8', 'GBK', $fileFolder);
$gbkfilePath1 = iconv('UTF-8', 'GBK', $filePath1);
$gbkfilePath2 = iconv('UTF-8', 'GBK', $filePath2);
$hexfilePath1 = bin2hex($filePath1);
$hexGbkfilePath2 = bin2hex($gbkfilePath2);
$content1 = '';
$content2 = '';
if (version_compare(phpversion(), '7.0.0', '<')) {
try {
mkdir($gbkfileFolder);
} catch (\Exception $e) {
}
OssUtil::generateFile($gbkfilePath1, 200 * 1024);
OssUtil::generateFile($gbkfilePath2, 202 * 1024);
$content1 = file_get_contents($gbkfilePath1);
$content2 = file_get_contents($gbkfilePath2);
} else {
try {
mkdir($fileFolder);
} catch (\Exception $e) {
}
OssUtil::generateFile($filePath1, 200 * 1024);
OssUtil::generateFile($filePath2, 202 * 1024);
$content1 = file_get_contents($filePath1);
$content2 = file_get_contents($filePath2);
}
try {
// upload file
$this->ossClient->uploadFile($this->bucket, '123', $filePath1);
$this->ossClient->uploadFile($this->bucket, '234', $gbkfilePath2);
$res = $this->ossClient->getObject($this->bucket, '123');
$this->assertEquals($content1, $res);
$res = $this->ossClient->getObject($this->bucket, '234');
$this->assertEquals($content2, $res);
// append file
$position = $this->ossClient->appendFile($this->bucket, 'append-file', $filePath1, 0);
$position = $this->ossClient->appendFile($this->bucket, 'append-file', $gbkfilePath2, $position);
$res = $this->ossClient->getObject($this->bucket, 'append-file');
$this->assertEquals($content1.$content2, $res);
// multi paet
$this->ossClient->multiuploadFile($this->bucket, 'multi-file-123', $filePath1, array(OssClient::OSS_PART_SIZE => 1));
$this->ossClient->multiuploadFile($this->bucket, 'multi-file-234', $gbkfilePath2, array(OssClient::OSS_PART_SIZE => 1));
$res = $this->ossClient->getObject($this->bucket, 'multi-file-123');
$this->assertEquals($content1, $res);
$res = $this->ossClient->getObject($this->bucket, 'multi-file-234');
$this->assertEquals($content2, $res);
// uploadDir
$this->ossClient->uploadDir($this->bucket, "dir", $fileFolder);
$options = array(
'delimiter' => '',
'prefix' => "dir",
);
$listObjectInfo = $this->ossClient->listObjects($this->bucket, $options);
$objectList = $listObjectInfo->getObjectList();
$this->assertEquals(2, count($objectList));
$this->assertEquals('dir/中文文件名1.txt', $objectList[0]->getKey());
$this->assertEquals('dir/中文文件名2.txt', $objectList[1]->getKey());
// uploadDir
if (version_compare(phpversion(), '7.0.0', '<')) {
$this->ossClient->uploadDir($this->bucket, "gbkdir", $gbkfileFolder);
$options = array(
'delimiter' => '',
'prefix' => "gbkdir",
);
$listObjectInfo = $this->ossClient->listObjects($this->bucket, $options);
$objectList = $listObjectInfo->getObjectList();
$this->assertEquals(2, count($objectList));
$this->assertEquals('gbkdir/中文文件名1.txt', $objectList[0]->getKey());
$this->assertEquals('gbkdir/中文文件名2.txt', $objectList[1]->getKey());
}
} catch (OssException $e) {
$this->assertFalse(true);
}
try {
if (phpversion() < "7.0.0") {
unlink($gbkfilePath1);
unlink($gbkfilePath2);
rmdir($gbkfileFolder);
} else {
unlink($filePath1);
unlink($filePath2);
rmdir($fileFolder);
}
} catch (\Exception $e) {
}
}
protected function setUp(): void protected function setUp(): void
{ {
parent::setUp(); parent::setUp();

View File

@@ -2,7 +2,6 @@
namespace OSS\Tests; namespace OSS\Tests;
use http\Client;
use OSS\Core\OssException; use OSS\Core\OssException;
use OSS\Http\RequestCore; use OSS\Http\RequestCore;
use OSS\Http\ResponseCore; use OSS\Http\ResponseCore;
@@ -13,7 +12,7 @@ require_once __DIR__ . DIRECTORY_SEPARATOR . 'TestOssClientBase.php';
class OssClientSignatureTest extends TestOssClientBase class OssClientSignatureTest extends TestOssClientBase
{ {
public function testGetSignedUrlForGettingObject() function testGetSignedUrlForGettingObject()
{ {
$object = "a.file"; $object = "a.file";
$this->ossClient->putObject($this->bucket, $object, file_get_contents(__FILE__)); $this->ossClient->putObject($this->bucket, $object, file_get_contents(__FILE__));
@@ -92,52 +91,6 @@ class OssClientSignatureTest extends TestOssClientBase
$this->assertTrue(false); $this->assertTrue(false);
} }
} }
$object = "?a.file";
$timeout = 3600;
$options = array('Content-Type' => 'txt');
try {
$signedUrl = $this->ossClient->signUrl($this->bucket, $object, $timeout, "PUT", $options);
$this->assertTrue(false);
} catch (OssException $e) {
$this->assertTrue(true);
if (strpos($e, "object name cannot start with `?`") == false)
{
$this->assertTrue(false);
}
}
// Set StrictObjectName false
$object = "?a.file";
$timeout = 3600;
$options = array('Content-Type' => 'txt');
$config = array(
'strictObjectName' => false
);
$ossClient = Common::getOssClient($config);
try {
$signedUrl = $ossClient->signUrl($this->bucket, $object, $timeout, "PUT", $options);
$this->assertTrue(true);
} catch (OssException $e) {
print_r($e->getMessage());
$this->assertFalse(true);
}
// V4
$object = "?a.file";
$timeout = 3600;
$options = array('Content-Type' => 'txt');
$config = array(
'signatureVersion' => OssClient::OSS_SIGNATURE_VERSION_V4
);
$ossClient = Common::getOssClient($config);
try {
$signedUrl = $ossClient->signUrl($this->bucket, $object, $timeout, "PUT", $options);
$this->assertTrue(true);
} catch (OssException $e) {
print_r($e->getMessage());
$this->assertFalse(true);
}
} }
function testGetgenPreSignedUrlForGettingObject() function testGetgenPreSignedUrlForGettingObject()
@@ -178,59 +131,6 @@ class OssClientSignatureTest extends TestOssClientBase
$this->assertTrue(strpos($signedUrl1, 'Expires='.$expiration) !== false); $this->assertTrue(strpos($signedUrl1, 'Expires='.$expiration) !== false);
} }
public function testPutObjectWithQueryCallback()
{
$object = "a.file";
$timeout = 3600;
$url = '{"callbackUrl":"http://aliyun.com", "callbackBody":"bucket=${bucket}&object=${object}"}';
$var =
'{
"x:var1":"value1",
"x:var2":"value2"
}';
try {
$options[OssClient::OSS_QUERY_STRING] = array(
'callback'=>base64_encode($url),
'callback-var'=>base64_encode($var)
);
$signedUrl = $this->ossClient->signUrl($this->bucket, $object, $timeout, "PUT", $options);
$content = file_get_contents(__FILE__);
$request = new RequestCore($signedUrl);
$request->set_method('PUT');
$request->add_header('Content-Type', '');
$request->add_header('Content-Length', strlen($content));
$request->set_body($content);
$request->send_request();
$res = new ResponseCore($request->get_response_header(),
$request->get_response_body(), $request->get_response_code());
$this->assertEquals($res->status, 203);
} catch (OssException $e) {
$this->assertFalse(true);
}
try {
$options = array(OssClient::OSS_CALLBACK => $url,
OssClient::OSS_CALLBACK_VAR => $var
);
$signedUrl = $this->ossClient->signUrl($this->bucket, $object, $timeout, "PUT", $options);
$content = file_get_contents(__FILE__);
$request = new RequestCore($signedUrl);
$request->set_method('PUT');
$request->add_header('Content-Type', '');
$request->add_header(OssClient::OSS_CALLBACK, base64_encode($url));
$request->add_header(OssClient::OSS_CALLBACK_VAR , base64_encode($var));
$request->add_header('Content-Length', strlen($content));
$request->set_body($content);
$request->send_request();
$res = new ResponseCore($request->get_response_header(),
$request->get_response_body(), $request->get_response_code());
$this->assertEquals($res->status, 203);
} catch (OssException $e) {
$this->assertFalse(true);
}
}
protected function tearDown(): void protected function tearDown(): void
{ {
$this->ossClient->deleteObject($this->bucket, "a.file"); $this->ossClient->deleteObject($this->bucket, "a.file");

View File

@@ -3,82 +3,8 @@
namespace OSS\Tests; namespace OSS\Tests;
use OSS\Core\OssException; use OSS\Core\OssException;
use OSS\Credentials\EnvironmentVariableCredentialsProvider;
use OSS\OssClient; use OSS\OssClient;
use OSS\Credentials\Credentials;
use OSS\Credentials\CredentialsProvider;
use OSS\Credentials\StaticCredentialsProvider;
require_once __DIR__ . DIRECTORY_SEPARATOR . 'TestOssClientBase.php';
class TestEmptyIdCredentials extends Credentials
{
public function __construct()
{
}
public function getAccessKeyId()
{
return '';
}
public function getAccessKeySecret()
{
return 'secret';
}
public function getSecurityToken()
{
return null;
}
}
class TestEmptySecretCredentials extends Credentials
{
public function __construct()
{
}
public function getAccessKeyId()
{
return 'id';
}
public function getAccessKeySecret()
{
return '';
}
public function getSecurityToken()
{
return null;
}
}
class TestCredentialsProvider implements CredentialsProvider
{
private $credentials;
public function __construct($flag)
{
if ($flag == 2) {
$this->credentials = new TestEmptyIdCredentials();
} else if ($flag == 1) {
$this->credentials = new TestEmptySecretCredentials();
} else {
$this->credentials = null;
}
}
/**
* @return Credentials
*/
public function getCredentials()
{
return $this->credentials;
}
}
class OssClientTest extends TestOssClientBase class OssClientTest extends TestOssClientBase
{ {
@@ -194,7 +120,7 @@ class OssClientTest extends TestOssClientBase
try { try {
$accessKeyId = ' ' . getenv('OSS_ACCESS_KEY_ID') . ' '; $accessKeyId = ' ' . getenv('OSS_ACCESS_KEY_ID') . ' ';
$accessKeySecret = ' ' . getenv('OSS_ACCESS_KEY_SECRET') . ' '; $accessKeySecret = ' ' . getenv('OSS_ACCESS_KEY_SECRET') . ' ';
$endpoint = ' ' . Common::getEndpoint() . '/ '; $endpoint = ' ' . getenv('OSS_ENDPOINT') . '/ ';
$ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint, false); $ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint, false);
$ossClient->listBuckets(); $ossClient->listBuckets();
$this->assertTrue(true); $this->assertTrue(true);
@@ -238,7 +164,7 @@ class OssClientTest extends TestOssClientBase
try { try {
$accessKeyId = ' ' . getenv('OSS_ACCESS_KEY_ID') . ' '; $accessKeyId = ' ' . getenv('OSS_ACCESS_KEY_ID') . ' ';
$accessKeySecret = ' ' . getenv('OSS_ACCESS_KEY_SECRET') . ' '; $accessKeySecret = ' ' . getenv('OSS_ACCESS_KEY_SECRET') . ' ';
$endpoint = ' ' . Common::getEndpoint() . '/ '; $endpoint = ' ' . getenv('OSS_ENDPOINT') . '/ ';
$bucket = $this->bucket; $bucket = $this->bucket;
$ossClient = new OssClient($accessKeyId, $accessKeySecret , $endpoint, false); $ossClient = new OssClient($accessKeyId, $accessKeySecret , $endpoint, false);
$ossClient->putObject($bucket,'test_emptybody',''); $ossClient->putObject($bucket,'test_emptybody','');
@@ -250,7 +176,7 @@ class OssClientTest extends TestOssClientBase
try { try {
$accessKeyId = ' ' . getenv('OSS_ACCESS_KEY_ID') . ' '; $accessKeyId = ' ' . getenv('OSS_ACCESS_KEY_ID') . ' ';
$accessKeySecret = ' ' . getenv('OSS_ACCESS_KEY_SECRET') . ' '; $accessKeySecret = ' ' . getenv('OSS_ACCESS_KEY_SECRET') . ' ';
$endpoint = ' ' . Common::getEndpoint() . '/ '; $endpoint = ' ' . getenv('OSS_ENDPOINT') . '/ ';
$bucket = $this->bucket; $bucket = $this->bucket;
$ossClient = new OssClient($accessKeyId, $accessKeySecret , $endpoint, false, "invalid-sts-token"); $ossClient = new OssClient($accessKeyId, $accessKeySecret , $endpoint, false, "invalid-sts-token");
$ossClient->putObject($bucket,'test_emptybody',''); $ossClient->putObject($bucket,'test_emptybody','');
@@ -264,7 +190,7 @@ class OssClientTest extends TestOssClientBase
{ {
$accessKeyId = ' ' . getenv('OSS_ACCESS_KEY_ID') . ' '; $accessKeyId = ' ' . getenv('OSS_ACCESS_KEY_ID') . ' ';
$accessKeySecret = ' ' . getenv('OSS_ACCESS_KEY_SECRET') . ' '; $accessKeySecret = ' ' . getenv('OSS_ACCESS_KEY_SECRET') . ' ';
$endpoint = ' ' . Common::getEndpoint() . '/ '; $endpoint = ' ' . getenv('OSS_ENDPOINT') . '/ ';
$bucket = $this->bucket; $bucket = $this->bucket;
$ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint, false); $ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint, false);
@@ -292,8 +218,8 @@ class OssClientTest extends TestOssClientBase
try { try {
$accessKeyId = ' ' . getenv('OSS_ACCESS_KEY_ID') . ' '; $accessKeyId = ' ' . getenv('OSS_ACCESS_KEY_ID') . ' ';
$accessKeySecret = ' ' . getenv('OSS_ACCESS_KEY_SECRET') . ' '; $accessKeySecret = ' ' . getenv('OSS_ACCESS_KEY_SECRET') . ' ';
$endpoint = ' ' . Common::getEndpoint(). '/ '; $endpoint = ' ' . getenv('OSS_ENDPOINT') . '/ ';
$bucket = Common::getBucketName(); $bucket = getenv('OSS_BUCKET');
$ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint, false); $ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint, false);
$ossClient->getBucketCors($bucket); $ossClient->getBucketCors($bucket);
$this->assertTrue(true); $this->assertTrue(true);
@@ -307,7 +233,7 @@ class OssClientTest extends TestOssClientBase
try { try {
$accessKeyId = ' ' . getenv('OSS_ACCESS_KEY_ID') . ' '; $accessKeyId = ' ' . getenv('OSS_ACCESS_KEY_ID') . ' ';
$accessKeySecret = ' ' . getenv('OSS_ACCESS_KEY_SECRET') . ' '; $accessKeySecret = ' ' . getenv('OSS_ACCESS_KEY_SECRET') . ' ';
$endpoint = ' ' . Common::getEndpoint() . '/ '; $endpoint = ' ' . getenv('OSS_ENDPOINT') . '/ ';
$bucket = $this->bucket; $bucket = $this->bucket;
$ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint, false); $ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint, false);
$ossClient->getBucketCname($bucket); $ossClient->getBucketCname($bucket);
@@ -321,8 +247,8 @@ class OssClientTest extends TestOssClientBase
{ {
$accessKeyId = ' ' . getenv('OSS_ACCESS_KEY_ID') . ' '; $accessKeyId = ' ' . getenv('OSS_ACCESS_KEY_ID') . ' ';
$accessKeySecret = ' ' . getenv('OSS_ACCESS_KEY_SECRET') . ' '; $accessKeySecret = ' ' . getenv('OSS_ACCESS_KEY_SECRET') . ' ';
$endpoint = ' ' . Common::getEndpoint() . '/ '; $endpoint = ' ' . getenv('OSS_ENDPOINT') . '/ ';
$bucket = Common::getBucketName() . '-proxy'; $bucket = getenv('OSS_BUCKET') . '-proxy';
$requestProxy = getenv('OSS_PROXY'); $requestProxy = getenv('OSS_PROXY');
$key = 'test-proxy-srv-object'; $key = 'test-proxy-srv-object';
$content = 'test-content'; $content = 'test-content';
@@ -370,13 +296,13 @@ class OssClientTest extends TestOssClientBase
$accessKeyId = 'sk' . getenv('OSS_ACCESS_KEY_ID') . ' '; $accessKeyId = 'sk' . getenv('OSS_ACCESS_KEY_ID') . ' ';
$accessKeySecret = ' ' . getenv('OSS_ACCESS_KEY_SECRET') . ' '; $accessKeySecret = ' ' . getenv('OSS_ACCESS_KEY_SECRET') . ' ';
$endpoint = '192.168.1.1'; $endpoint = '192.168.1.1';
$bucket = Common::getBucketName(); $bucket = getenv('OSS_BUCKET');
$ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint, false); $ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint, false);
$object = "a.file"; $object = "a.file";
$timeout = 3600; $timeout = 3600;
$options = array('Content-Type' => 'txt'); $options = array('Content-Type' => 'txt');
$signedUrl = $ossClient->signUrl($bucket, $object, $timeout, "PUT", $options); $signedUrl = $ossClient->signUrl($bucket, $object, $timeout, "PUT", $options);
$this->assertTrue(strpos($signedUrl, '192.168.1.1/' . $bucket . '/a.file?') != false); $this->assertTrue(strpos($signedUrl, '192.168.1.1/skyranch-php-test/a.file?') != false);
} catch (OssException $e) { } catch (OssException $e) {
$this->assertFalse(true); $this->assertFalse(true);
} }
@@ -388,7 +314,7 @@ class OssClientTest extends TestOssClientBase
$accessKeyId = 'sk' . getenv('OSS_ACCESS_KEY_ID') . ' '; $accessKeyId = 'sk' . getenv('OSS_ACCESS_KEY_ID') . ' ';
$accessKeySecret = ' ' . getenv('OSS_ACCESS_KEY_SECRET') . ' '; $accessKeySecret = ' ' . getenv('OSS_ACCESS_KEY_SECRET') . ' ';
$endpoint = 'cname.endpoint'; $endpoint = 'cname.endpoint';
$bucket = Common::getBucketName(); $bucket = getenv('OSS_BUCKET');
$ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint, true); $ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint, true);
$object = "a.file"; $object = "a.file";
$timeout = 3600; $timeout = 3600;
@@ -405,8 +331,8 @@ class OssClientTest extends TestOssClientBase
try { try {
$accessKeyId = 'sk' . getenv('OSS_ACCESS_KEY_ID') . ' '; $accessKeyId = 'sk' . getenv('OSS_ACCESS_KEY_ID') . ' ';
$accessKeySecret = ' ' . getenv('OSS_ACCESS_KEY_SECRET') . ' '; $accessKeySecret = ' ' . getenv('OSS_ACCESS_KEY_SECRET') . ' ';
$endpoint = ' ' . Common::getEndpoint() . '/ '; $endpoint = ' ' . getenv('OSS_ENDPOINT') . '/ ';
$bucket = Common::getBucketName(); $bucket = getenv('OSS_BUCKET');
$ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint, false, "test-token"); $ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint, false, "test-token");
$object = "a.file"; $object = "a.file";
$timeout = 3600; $timeout = 3600;
@@ -417,105 +343,4 @@ class OssClientTest extends TestOssClientBase
$this->assertFalse(true); $this->assertFalse(true);
} }
} }
public function testEmptyCredentials()
{
// empty case, should throw exception
try {
$id = '';
$secret = 'accessKey_secret';
$provider = new StaticCredentialsProvider($id, $secret);
$config = array(
'provider' => $provider,
'endpoint' => 'http://oss-cn-hangzhou.aliyuncs.com'
);
$ossClient = new OssClient($config);
$this->assertFalse(true);
} catch (OssException $e) {
$this->assertEquals('access key id is empty', $e->getMessage());
}
// empty case, should throw exception
try {
$id = 'id';
$secret = '';
$provider = new StaticCredentialsProvider($id, $secret);
$config = array(
'provider' => $provider,
'endpoint' => 'http://oss-cn-hangzhou.aliyuncs.com'
);
$ossClient = new OssClient($config);
$this->assertFalse(true);
} catch (OssException $e) {
$this->assertEquals('access key secret is empty', $e->getMessage());
}
// empty case, should throw exception
try {
$provider = new TestCredentialsProvider(0);
$config = array(
'provider' => $provider,
'endpoint' => 'http://oss-cn-hangzhou.aliyuncs.com'
);
$ossClient = new OssClient($config);
$ossClient->getBucketAcl("bucket");
$this->assertFalse(true);
} catch (OssException $e) {
$this->assertEquals('credentials is empty.', $e->getMessage());
}
// empty case, should throw exception
try {
$provider = new TestCredentialsProvider(1);
$config = array(
'provider' => $provider,
'endpoint' => 'http://oss-cn-hangzhou.aliyuncs.com'
);
$ossClient = new OssClient($config);
$ossClient->getBucketAcl("bucket");
$this->assertFalse(true);
} catch (OssException $e) {
$this->assertEquals('access key secret is empty', $e->getMessage());
}
// empty case, should throw exception
try {
$provider = new TestCredentialsProvider(2);
$config = array(
'provider' => $provider,
'endpoint' => 'http://oss-cn-hangzhou.aliyuncs.com'
);
$ossClient = new OssClient($config);
$ossClient->getBucketAcl("bucket");
$this->assertFalse(true);
} catch (OssException $e) {
$this->assertEquals('access key id is empty', $e->getMessage());
}
}
public function testEnvironmentVariableCredentialsProvider()
{
try {
$provider = new EnvironmentVariableCredentialsProvider();
$config = array(
'provider' => $provider,
'endpoint' => Common::getEndpoint(),
);
$ossClient = new OssClient($config);
$ossClient->putObject($this->bucket, 'test_emptybody', '');
$this->assertTrue(true);
} catch (OssException $e) {
printf($e->getMessage());
$this->assertFalse(true);
}
try {
$ossClient->getObject($this->bucket, 'test_emptybody');
$this->assertTrue(true);
} catch (OssException $e) {
printf($e->getMessage());
$this->assertFalse(true);
}
}
} }

View File

@@ -143,7 +143,7 @@ BBBB;
public function testReadDir() public function testReadDir()
{ {
$list = OssUtil::readDir(__DIR__, ".|..|.svn|.git", true); $list = OssUtil::readDir("./src", ".|..|.svn|.git", true);
$this->assertNotNull($list); $this->assertNotNull($list);
} }

View File

@@ -6,7 +6,7 @@ use OSS\Core\OssException;
use OSS\Http\ResponseCore; use OSS\Http\ResponseCore;
use OSS\Result\PutSetDeleteResult; use OSS\Result\PutSetDeleteResult;
class PutSetDeleteResultTest extends \PHPUnit\Framework\TestCase class ResultTest extends \PHPUnit\Framework\TestCase
{ {
public function testNullResponse() public function testNullResponse()

View File

@@ -11,10 +11,10 @@ return array(
'think\\trace\\' => array($vendorDir . '/topthink/think-trace/src'), 'think\\trace\\' => array($vendorDir . '/topthink/think-trace/src'),
'think\\captcha\\' => array($vendorDir . '/topthink/think-captcha/src'), 'think\\captcha\\' => array($vendorDir . '/topthink/think-captcha/src'),
'think\\app\\' => array($vendorDir . '/topthink/think-multi-app/src'), 'think\\app\\' => array($vendorDir . '/topthink/think-multi-app/src'),
'think\\' => array($vendorDir . '/topthink/framework/src/think', $vendorDir . '/topthink/think-helper/src', $vendorDir . '/topthink/think-orm/src', $vendorDir . '/topthink/think-queue/src', $vendorDir . '/topthink/think-template/src'), 'think\\' => array($vendorDir . '/topthink/think-template/src', $vendorDir . '/topthink/think-helper/src', $vendorDir . '/topthink/think-orm/src', $vendorDir . '/topthink/framework/src/think', $vendorDir . '/topthink/think-queue/src'),
'thans\\filesystem\\' => array($vendorDir . '/thans/thinkphp-filesystem-cloud/src'), 'thans\\filesystem\\' => array($vendorDir . '/thans/thinkphp-filesystem-cloud/src'),
'phpseclib3\\' => array($vendorDir . '/phpseclib/phpseclib/phpseclib'), 'phpseclib3\\' => array($vendorDir . '/phpseclib/phpseclib/phpseclib'),
'phpDocumentor\\Reflection\\' => array($vendorDir . '/phpdocumentor/reflection-common/src', $vendorDir . '/phpdocumentor/reflection-docblock/src', $vendorDir . '/phpdocumentor/type-resolver/src'), 'phpDocumentor\\Reflection\\' => array($vendorDir . '/phpdocumentor/reflection-common/src', $vendorDir . '/phpdocumentor/type-resolver/src', $vendorDir . '/phpdocumentor/reflection-docblock/src'),
'liliuwei\\think\\' => array($vendorDir . '/liliuwei/thinkphp-jump/src'), 'liliuwei\\think\\' => array($vendorDir . '/liliuwei/thinkphp-jump/src'),
'extend\\' => array($baseDir . '/extend'), 'extend\\' => array($baseDir . '/extend'),
'app\\' => array($baseDir . '/app'), 'app\\' => array($baseDir . '/app'),
@@ -42,7 +42,7 @@ return array(
'Qcloud\\Cos\\' => array($vendorDir . '/qcloud/cos-sdk-v5/src'), 'Qcloud\\Cos\\' => array($vendorDir . '/qcloud/cos-sdk-v5/src'),
'Psr\\SimpleCache\\' => array($vendorDir . '/psr/simple-cache/src'), 'Psr\\SimpleCache\\' => array($vendorDir . '/psr/simple-cache/src'),
'Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'), 'Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'),
'Psr\\Http\\Message\\' => array($vendorDir . '/psr/http-factory/src', $vendorDir . '/psr/http-message/src'), 'Psr\\Http\\Message\\' => array($vendorDir . '/psr/http-message/src', $vendorDir . '/psr/http-factory/src'),
'Psr\\Http\\Client\\' => array($vendorDir . '/psr/http-client/src'), 'Psr\\Http\\Client\\' => array($vendorDir . '/psr/http-client/src'),
'Psr\\EventDispatcher\\' => array($vendorDir . '/psr/event-dispatcher/src'), 'Psr\\EventDispatcher\\' => array($vendorDir . '/psr/event-dispatcher/src'),
'Psr\\Container\\' => array($vendorDir . '/psr/container/src'), 'Psr\\Container\\' => array($vendorDir . '/psr/container/src'),

View File

@@ -191,11 +191,11 @@ class ComposerStaticInit516d2ac39a060b91610bddcc729d2cf4
), ),
'think\\' => 'think\\' =>
array ( array (
0 => __DIR__ . '/..' . '/topthink/framework/src/think', 0 => __DIR__ . '/..' . '/topthink/think-template/src',
1 => __DIR__ . '/..' . '/topthink/think-helper/src', 1 => __DIR__ . '/..' . '/topthink/think-helper/src',
2 => __DIR__ . '/..' . '/topthink/think-orm/src', 2 => __DIR__ . '/..' . '/topthink/think-orm/src',
3 => __DIR__ . '/..' . '/topthink/think-queue/src', 3 => __DIR__ . '/..' . '/topthink/framework/src/think',
4 => __DIR__ . '/..' . '/topthink/think-template/src', 4 => __DIR__ . '/..' . '/topthink/think-queue/src',
), ),
'thans\\filesystem\\' => 'thans\\filesystem\\' =>
array ( array (
@@ -208,8 +208,8 @@ class ComposerStaticInit516d2ac39a060b91610bddcc729d2cf4
'phpDocumentor\\Reflection\\' => 'phpDocumentor\\Reflection\\' =>
array ( array (
0 => __DIR__ . '/..' . '/phpdocumentor/reflection-common/src', 0 => __DIR__ . '/..' . '/phpdocumentor/reflection-common/src',
1 => __DIR__ . '/..' . '/phpdocumentor/reflection-docblock/src', 1 => __DIR__ . '/..' . '/phpdocumentor/type-resolver/src',
2 => __DIR__ . '/..' . '/phpdocumentor/type-resolver/src', 2 => __DIR__ . '/..' . '/phpdocumentor/reflection-docblock/src',
), ),
'liliuwei\\think\\' => 'liliuwei\\think\\' =>
array ( array (
@@ -321,8 +321,8 @@ class ComposerStaticInit516d2ac39a060b91610bddcc729d2cf4
), ),
'Psr\\Http\\Message\\' => 'Psr\\Http\\Message\\' =>
array ( array (
0 => __DIR__ . '/..' . '/psr/http-factory/src', 0 => __DIR__ . '/..' . '/psr/http-message/src',
1 => __DIR__ . '/..' . '/psr/http-message/src', 1 => __DIR__ . '/..' . '/psr/http-factory/src',
), ),
'Psr\\Http\\Client\\' => 'Psr\\Http\\Client\\' =>
array ( array (

View File

@@ -6272,20 +6272,6 @@
"support": { "support": {
"source": "https://github.com/symfony/var-dumper/tree/v4.4.41" "source": "https://github.com/symfony/var-dumper/tree/v4.4.41"
}, },
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"install-path": "../symfony/var-dumper" "install-path": "../symfony/var-dumper"
}, },
{ {
@@ -6876,7 +6862,13 @@
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/top-think/think-trace/zipball/9a9fa8f767b6c66c5a133ad21ca1bc96ad329444", "url": "https://api.github.com/repos/top-think/think-trace/zipball/9a9fa8f767b6c66c5a133ad21ca1bc96ad329444",
"reference": "9a9fa8f767b6c66c5a133ad21ca1bc96ad329444", "reference": "9a9fa8f767b6c66c5a133ad21ca1bc96ad329444",
"shasum": "" "shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
}, },
"require": { "require": {
"php": ">=7.1.0", "php": ">=7.1.0",
@@ -6886,12 +6878,12 @@
"type": "library", "type": "library",
"extra": { "extra": {
"think": { "think": {
"config": {
"trace": "src/config.php"
},
"services": [ "services": [
"think\\trace\\Service" "think\\trace\\Service"
] ],
"config": {
"trace": "src/config.php"
}
} }
}, },
"installation-source": "dist", "installation-source": "dist",
@@ -6911,10 +6903,6 @@
} }
], ],
"description": "thinkphp debug trace", "description": "thinkphp debug trace",
"support": {
"issues": "https://github.com/top-think/think-trace/issues",
"source": "https://github.com/top-think/think-trace/tree/v1.4"
},
"install-path": "../topthink/think-trace" "install-path": "../topthink/think-trace"
}, },
{ {

View File

@@ -1,9 +1,9 @@
<?php return array( <?php return array(
'root' => array( 'root' => array(
'name' => 'topthink/think', 'name' => 'topthink/think',
'pretty_version' => '1.0.0+no-version-set', 'pretty_version' => 'dev-main',
'version' => '1.0.0.0', 'version' => 'dev-main',
'reference' => NULL, 'reference' => 'e0aeea15f212c8fd39c805cda2d8616e4f4a6a29',
'type' => 'project', 'type' => 'project',
'install_path' => __DIR__ . '/../../', 'install_path' => __DIR__ . '/../../',
'aliases' => array(), 'aliases' => array(),
@@ -908,9 +908,9 @@
'dev_requirement' => false, 'dev_requirement' => false,
), ),
'topthink/think' => array( 'topthink/think' => array(
'pretty_version' => '1.0.0+no-version-set', 'pretty_version' => 'dev-main',
'version' => '1.0.0.0', 'version' => 'dev-main',
'reference' => NULL, 'reference' => 'e0aeea15f212c8fd39c805cda2d8616e4f4a6a29',
'type' => 'project', 'type' => 'project',
'install_path' => __DIR__ . '/../../', 'install_path' => __DIR__ . '/../../',
'aliases' => array(), 'aliases' => array(),

View File

@@ -1,7 +1,7 @@
PHP Cron Expression Parser PHP Cron Expression Parser
========================== ==========================
[![Latest Stable Version](https://poser.pugx.org/dragonmantank/cron-expression/v/stable.png)](https://packagist.org/packages/dragonmantank/cron-expression) [![Total Downloads](https://poser.pugx.org/dragonmantank/cron-expression/downloads.png)](https://packagist.org/packages/dragonmantank/cron-expression) [![Tests](https://github.com/dragonmantank/cron-expression/actions/workflows/tests.yml/badge.svg)](https://github.com/dragonmantank/cron-expression/actions/workflows/tests.yml) [![StyleCI](https://github.styleci.io/repos/103715337/shield?branch=master)](https://github.styleci.io/repos/103715337) [![Latest Stable Version](https://poser.pugx.org/dragonmantank/cron-expression/v/stable.png)](https://packagist.org/packages/dragonmantank/cron-expression) [![Total Downloads](https://poser.pugx.org/dragonmantank/cron-expression/downloads.png)](https://packagist.org/packages/dragonmantank/cron-expression) [![Build Status](https://secure.travis-ci.org/dragonmantank/cron-expression.png)](http://travis-ci.org/dragonmantank/cron-expression) [![StyleCI](https://github.styleci.io/repos/103715337/shield?branch=master)](https://github.styleci.io/repos/103715337)
The PHP cron expression parser can parse a CRON expression, determine if it is The PHP cron expression parser can parse a CRON expression, determine if it is
due to run, calculate the next run date of the expression, and calculate the previous due to run, calculate the next run date of the expression, and calculate the previous
@@ -55,65 +55,23 @@ CRON Expressions
A CRON expression is a string representing the schedule for a particular command to execute. The parts of a CRON schedule are as follows: A CRON expression is a string representing the schedule for a particular command to execute. The parts of a CRON schedule are as follows:
```
* * * * * * * * * *
- - - - - - - - - -
| | | | | | | | | |
| | | | | | | | | |
| | | | +----- day of week (0-7) (Sunday = 0 or 7) (or SUN-SAT) | | | | +----- day of week (0 - 7) (Sunday=0 or 7)
| | | +--------- month (1-12) (or JAN-DEC) | | | +---------- month (1 - 12)
| | +------------- day of month (1-31) | | +--------------- day of month (1 - 31)
| +----------------- hour (0-23) | +-------------------- hour (0 - 23)
+--------------------- minute (0-59) +------------------------- min (0 - 59)
```
Each part of expression can also use wildcard, lists, ranges and steps: This library also supports a few macros:
- wildcard - match always * `@yearly`, `@annually` - Run once a year, midnight, Jan. 1 - `0 0 1 1 *`
- `* * * * *` - At every minute. * `@monthly` - Run once a month, midnight, first of month - `0 0 1 * *`
- day of week and day of month also support `?`, an alias to `*` * `@weekly` - Run once a week, midnight on Sun - `0 0 * * 0`
- lists - match list of values, ranges and steps * `@daily`, `@midnight` - Run once a day, midnight - `0 0 * * *`
- e.g. `15,30 * * * *` - At minute 15 and 30. * `@hourly` - Run once an hour, first minute - `0 * * * *`
- ranges - match values in range
- e.g. `1-9 * * * *` - At every minute from 1 through 9.
- steps - match every nth value in range
- e.g. `*/5 * * * *` - At every 5th minute.
- e.g. `0-30/5 * * * *` - At every 5th minute from 0 through 30.
- combinations
- e.g. `0-14,30-44 * * * *` - At every minute from 0 through 14 and every minute from 30 through 44.
You can also use macro instead of an expression:
- `@yearly`, `@annually` - At 00:00 on 1st of January. (same as `0 0 1 1 *`)
- `@monthly` - At 00:00 on day-of-month 1. (same as `0 0 1 * *`)
- `@weekly` - At 00:00 on Sunday. (same as `0 0 * * 0`)
- `@daily`, `@midnight` - At 00:00. (same as `0 0 * * *`)
- `@hourly` - At minute 0. (same as `0 * * * *`)
Day of month extra features:
- nearest weekday - weekday (Monday-Friday) nearest to the given day
- e.g. `* * 15W * *` - At every minute on a weekday nearest to the 15th.
- If you were to specify `15W` as the value, the meaning is: "the nearest weekday to the 15th of the month"
So if the 15th is a Saturday, the trigger will fire on Friday the 14th.
If the 15th is a Sunday, the trigger will fire on Monday the 16th.
If the 15th is a Tuesday, then it will fire on Tuesday the 15th.
- However, if you specify `1W` as the value for day-of-month,
and the 1st is a Saturday, the trigger will fire on Monday the 3rd,
as it will not 'jump' over the boundary of a month's days.
- last day of the month
- e.g. `* * L * *` - At every minute on a last day-of-month.
- last weekday of the month
- e.g. `* * LW * *` - At every minute on a last weekday.
Day of week extra features:
- nth day
- e.g. `* * * * 7#4` - At every minute on 4th Sunday.
- 1-5
- Every day of week repeats 4-5 times a month. To target the last one, use "last day" feature instead.
- last day
- e.g. `* * * * 7L` - At every minute on the last Sunday.
Requirements Requirements
============ ============
@@ -127,5 +85,3 @@ Projects that Use cron-expression
* Part of the [Laravel Framework](https://github.com/laravel/framework/) * Part of the [Laravel Framework](https://github.com/laravel/framework/)
* Available as a [Symfony Bundle - setono/cron-expression-bundle](https://github.com/Setono/CronExpressionBundle) * Available as a [Symfony Bundle - setono/cron-expression-bundle](https://github.com/Setono/CronExpressionBundle)
* Framework agnostic, PHP-based job scheduler - [Crunz](https://github.com/crunzphp/crunz) * Framework agnostic, PHP-based job scheduler - [Crunz](https://github.com/crunzphp/crunz)
* Framework agnostic job scheduler - with locks, parallelism, per-second scheduling and more - [orisai/scheduler](https://github.com/orisai/scheduler)
* Explain expression in English (and other languages) with [orisai/cron-expression-explainer](https://github.com/orisai/cron-expression-explainer)

View File

@@ -18,6 +18,7 @@
"require-dev": { "require-dev": {
"phpstan/phpstan": "^1.0", "phpstan/phpstan": "^1.0",
"phpunit/phpunit": "^7.0|^8.0|^9.0", "phpunit/phpunit": "^7.0|^8.0|^9.0",
"phpstan/phpstan-webmozart-assert": "^1.0",
"phpstan/extension-installer": "^1.0" "phpstan/extension-installer": "^1.0"
}, },
"autoload": { "autoload": {
@@ -37,11 +38,6 @@
"phpstan": "./vendor/bin/phpstan analyze", "phpstan": "./vendor/bin/phpstan analyze",
"test": "phpunit" "test": "phpunit"
}, },
"extra": {
"branch-alias": {
"dev-master": "3.x-dev"
}
},
"config": { "config": {
"allow-plugins": { "allow-plugins": {
"ocramius/package-versions": true, "ocramius/package-versions": true,

View File

@@ -12,6 +12,7 @@ use Exception;
use InvalidArgumentException; use InvalidArgumentException;
use LogicException; use LogicException;
use RuntimeException; use RuntimeException;
use Webmozart\Assert\Assert;
/** /**
* CRON expression parser that can determine whether or not a CRON expression is * CRON expression parser that can determine whether or not a CRON expression is
@@ -147,7 +148,7 @@ class CronExpression
/** /**
* @deprecated since version 3.0.2, use __construct instead. * @deprecated since version 3.0.2, use __construct instead.
*/ */
public static function factory(string $expression, ?FieldFactoryInterface $fieldFactory = null): CronExpression public static function factory(string $expression, FieldFactoryInterface $fieldFactory = null): CronExpression
{ {
/** @phpstan-ignore-next-line */ /** @phpstan-ignore-next-line */
return new static($expression, $fieldFactory); return new static($expression, $fieldFactory);
@@ -178,7 +179,7 @@ class CronExpression
* @param null|FieldFactoryInterface $fieldFactory Factory to create cron fields * @param null|FieldFactoryInterface $fieldFactory Factory to create cron fields
* @throws InvalidArgumentException * @throws InvalidArgumentException
*/ */
public function __construct(string $expression, ?FieldFactoryInterface $fieldFactory = null) public function __construct(string $expression, FieldFactoryInterface $fieldFactory = null)
{ {
$shortcut = strtolower($expression); $shortcut = strtolower($expression);
$expression = self::$registeredAliases[$shortcut] ?? $expression; $expression = self::$registeredAliases[$shortcut] ?? $expression;
@@ -199,12 +200,7 @@ class CronExpression
public function setExpression(string $value): CronExpression public function setExpression(string $value): CronExpression
{ {
$split = preg_split('/\s/', $value, -1, PREG_SPLIT_NO_EMPTY); $split = preg_split('/\s/', $value, -1, PREG_SPLIT_NO_EMPTY);
Assert::isArray($split);
if (!\is_array($split)) {
throw new InvalidArgumentException(
$value . ' is not a valid CRON expression'
);
}
$notEnoughParts = \count($split) < 5; $notEnoughParts = \count($split) < 5;
@@ -338,10 +334,7 @@ class CronExpression
$currentTime = new DateTime($currentTime); $currentTime = new DateTime($currentTime);
} }
if (!$currentTime instanceof DateTime) { Assert::isInstanceOf($currentTime, DateTime::class);
throw new InvalidArgumentException('invalid current time');
}
$currentTime->setTimezone(new DateTimeZone($timeZone)); $currentTime->setTimezone(new DateTimeZone($timeZone));
$matches = []; $matches = [];
@@ -427,10 +420,7 @@ class CronExpression
$currentTime = new DateTime($currentTime); $currentTime = new DateTime($currentTime);
} }
if (!$currentTime instanceof DateTime) { Assert::isInstanceOf($currentTime, DateTime::class);
throw new InvalidArgumentException('invalid current time');
}
$currentTime->setTimezone(new DateTimeZone($timeZone)); $currentTime->setTimezone(new DateTimeZone($timeZone));
// drop the seconds to 0 // drop the seconds to 0
@@ -472,10 +462,7 @@ class CronExpression
$currentDate = new DateTime('now'); $currentDate = new DateTime('now');
} }
if (!$currentDate instanceof DateTime) { Assert::isInstanceOf($currentDate, DateTime::class);
throw new InvalidArgumentException('invalid current date');
}
$currentDate->setTimezone(new DateTimeZone($timeZone)); $currentDate->setTimezone(new DateTimeZone($timeZone));
// Workaround for setTime causing an offset change: https://bugs.php.net/bug.php?id=81074 // Workaround for setTime causing an offset change: https://bugs.php.net/bug.php?id=81074
$currentDate = DateTime::createFromFormat("!Y-m-d H:iO", $currentDate->format("Y-m-d H:iP"), $currentDate->getTimezone()); $currentDate = DateTime::createFromFormat("!Y-m-d H:iO", $currentDate->format("Y-m-d H:iP"), $currentDate->getTimezone());

View File

@@ -0,0 +1,6 @@
# [4.16.0](https://github.com/ezyang/htmlpurifier/compare/v4.15.0...v4.16.0) (2022-09-18)
### Features
* add semantic release ([#307](https://github.com/ezyang/htmlpurifier/issues/307)) ([db31243](https://github.com/ezyang/htmlpurifier/commit/db312435cb9d8d73395f75f9642a43ba6de5e903)), closes [#322](https://github.com/ezyang/htmlpurifier/issues/322) [#323](https://github.com/ezyang/htmlpurifier/issues/323) [#326](https://github.com/ezyang/htmlpurifier/issues/326) [#327](https://github.com/ezyang/htmlpurifier/issues/327) [#328](https://github.com/ezyang/htmlpurifier/issues/328) [#329](https://github.com/ezyang/htmlpurifier/issues/329) [#330](https://github.com/ezyang/htmlpurifier/issues/330) [#331](https://github.com/ezyang/htmlpurifier/issues/331) [#332](https://github.com/ezyang/htmlpurifier/issues/332) [#333](https://github.com/ezyang/htmlpurifier/issues/333) [#337](https://github.com/ezyang/htmlpurifier/issues/337) [#335](https://github.com/ezyang/htmlpurifier/issues/335) [ezyang/htmlpurifier#334](https://github.com/ezyang/htmlpurifier/issues/334) [#336](https://github.com/ezyang/htmlpurifier/issues/336) [#338](https://github.com/ezyang/htmlpurifier/issues/338)

View File

@@ -1 +1 @@
4.19.0 4.15.0

View File

@@ -13,7 +13,7 @@
} }
], ],
"require": { "require": {
"php": "~5.6.0 || ~7.0.0 || ~7.1.0 || ~7.2.0 || ~7.3.0 || ~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0" "php": "~5.6.0 || ~7.0.0 || ~7.1.0 || ~7.2.0 || ~7.3.0 || ~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0"
}, },
"require-dev": { "require-dev": {
"cerdic/css-tidy": "^1.7 || ^2.0", "cerdic/css-tidy": "^1.7 || ^2.0",
@@ -38,8 +38,7 @@
"repositories": [ "repositories": [
{ {
"type": "vcs", "type": "vcs",
"url": "https://github.com/ezyang/simpletest.git", "url": "https://github.com/ezyang/simpletest.git"
"no-api": true
} }
] ]
} }

View File

@@ -7,7 +7,7 @@
* primary concern and you are using an opcode cache. PLEASE DO NOT EDIT THIS * primary concern and you are using an opcode cache. PLEASE DO NOT EDIT THIS
* FILE, changes will be overwritten the next time the script is run. * FILE, changes will be overwritten the next time the script is run.
* *
* @version 4.19.0 * @version 4.15.0
* *
* @warning * @warning
* You must *not* include any other HTML Purifier files before this file, * You must *not* include any other HTML Purifier files before this file,
@@ -101,7 +101,6 @@ require 'HTMLPurifier/AttrDef/CSS/Length.php';
require 'HTMLPurifier/AttrDef/CSS/ListStyle.php'; require 'HTMLPurifier/AttrDef/CSS/ListStyle.php';
require 'HTMLPurifier/AttrDef/CSS/Multiple.php'; require 'HTMLPurifier/AttrDef/CSS/Multiple.php';
require 'HTMLPurifier/AttrDef/CSS/Percentage.php'; require 'HTMLPurifier/AttrDef/CSS/Percentage.php';
require 'HTMLPurifier/AttrDef/CSS/Ratio.php';
require 'HTMLPurifier/AttrDef/CSS/TextDecoration.php'; require 'HTMLPurifier/AttrDef/CSS/TextDecoration.php';
require 'HTMLPurifier/AttrDef/CSS/URI.php'; require 'HTMLPurifier/AttrDef/CSS/URI.php';
require 'HTMLPurifier/AttrDef/HTML/Bool.php'; require 'HTMLPurifier/AttrDef/HTML/Bool.php';

View File

@@ -19,7 +19,7 @@
*/ */
/* /*
HTML Purifier 4.19.0 - Standards Compliant HTML Filtering HTML Purifier 4.15.0 - Standards Compliant HTML Filtering
Copyright (C) 2006-2008 Edward Z. Yang Copyright (C) 2006-2008 Edward Z. Yang
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
@@ -58,12 +58,12 @@ class HTMLPurifier
* Version of HTML Purifier. * Version of HTML Purifier.
* @type string * @type string
*/ */
public $version = '4.19.0'; public $version = '4.15.0';
/** /**
* Constant with version of HTML Purifier. * Constant with version of HTML Purifier.
*/ */
const VERSION = '4.19.0'; const VERSION = '4.15.0';
/** /**
* Global configuration object. * Global configuration object.

View File

@@ -95,7 +95,6 @@ require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Length.php';
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/ListStyle.php'; require_once $__dir . '/HTMLPurifier/AttrDef/CSS/ListStyle.php';
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Multiple.php'; require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Multiple.php';
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Percentage.php'; require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Percentage.php';
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Ratio.php';
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/TextDecoration.php'; require_once $__dir . '/HTMLPurifier/AttrDef/CSS/TextDecoration.php';
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/URI.php'; require_once $__dir . '/HTMLPurifier/AttrDef/CSS/URI.php';
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/Bool.php'; require_once $__dir . '/HTMLPurifier/AttrDef/HTML/Bool.php';

View File

@@ -27,13 +27,6 @@ class HTMLPurifier_AttrDef_CSS extends HTMLPurifier_AttrDef
$definition = $config->getCSSDefinition(); $definition = $config->getCSSDefinition();
$allow_duplicates = $config->get("CSS.AllowDuplicates"); $allow_duplicates = $config->get("CSS.AllowDuplicates");
$universal_attrdef = new HTMLPurifier_AttrDef_Enum(
array(
'initial',
'inherit',
'unset',
)
);
// According to the CSS2.1 spec, the places where a // According to the CSS2.1 spec, the places where a
// non-delimiting semicolon can appear are in strings // non-delimiting semicolon can appear are in strings
@@ -103,13 +96,16 @@ class HTMLPurifier_AttrDef_CSS extends HTMLPurifier_AttrDef
if (!$ok) { if (!$ok) {
continue; continue;
} }
$result = $universal_attrdef->validate($value, $config, $context); // inefficient call, since the validator will do this again
if ($result === false) { if (strtolower(trim($value)) !== 'inherit') {
// inherit works for everything (but only on the base property)
$result = $definition->info[$property]->validate( $result = $definition->info[$property]->validate(
$value, $value,
$config, $config,
$context $context
); );
} else {
$result = 'inherit';
} }
if ($result === false) { if ($result === false) {
continue; continue;

View File

@@ -10,21 +10,23 @@ class HTMLPurifier_AttrDef_CSS_FontFamily extends HTMLPurifier_AttrDef
public function __construct() public function __construct()
{ {
// Lowercase letters $this->mask = '_- ';
$l = range('a', 'z'); for ($c = 'a'; $c <= 'z'; $c++) {
// Uppercase letters $this->mask .= $c;
$u = range('A', 'Z'); }
// Digits for ($c = 'A'; $c <= 'Z'; $c++) {
$d = range('0', '9'); $this->mask .= $c;
// Special bytes used by UTF-8 }
$b = array_map('chr', range(0x80, 0xFF)); for ($c = '0'; $c <= '9'; $c++) {
// All valid characters for the mask $this->mask .= $c;
$c = array_merge($l, $u, $d, $b); } // cast-y, but should be fine
// Concatenate all valid characters into a string // special bytes used by UTF-8
// Use '_- ' as an initial value for ($i = 0x80; $i <= 0xFF; $i++) {
$this->mask = array_reduce($c, function ($carry, $value) { // We don't bother excluding invalid bytes in this range,
return $carry . $value; // because the our restriction of well-formed UTF-8 will
}, '_- '); // prevent these from ever occurring.
$this->mask .= chr($i);
}
/* /*
PHP's internal strcspn implementation is PHP's internal strcspn implementation is
@@ -195,7 +197,7 @@ class HTMLPurifier_AttrDef_CSS_FontFamily extends HTMLPurifier_AttrDef
// transforms don't pose a security risk (as \\ and \" // transforms don't pose a security risk (as \\ and \"
// might--these escapes are not supported by most browsers). // might--these escapes are not supported by most browsers).
// We could try to be clever and use single-quote wrapping // We could try to be clever and use single-quote wrapping
// when there is a double quote present, but I have chosen // when there is a double quote present, but I have choosen
// not to implement that. (NOTE: you can reduce the amount // not to implement that. (NOTE: you can reduce the amount
// of escapes by one depending on what quoting style you use) // of escapes by one depending on what quoting style you use)
// $font = str_replace('\\', '\\5C ', $font); // $font = str_replace('\\', '\\5C ', $font);

View File

@@ -25,7 +25,12 @@ class HTMLPurifier_AttrDef_HTML_LinkTypes extends HTMLPurifier_AttrDef
'rev' => 'AllowedRev' 'rev' => 'AllowedRev'
); );
if (!isset($configLookup[$name])) { if (!isset($configLookup[$name])) {
throw new Exception('Unrecognized attribute name for link relationship.'); trigger_error(
'Unrecognized attribute name for link ' .
'relationship.',
E_USER_ERROR
);
return;
} }
$this->name = $configLookup[$name]; $this->name = $configLookup[$name];
} }

View File

@@ -63,18 +63,24 @@ class HTMLPurifier_AttrDef_URI_Host extends HTMLPurifier_AttrDef
// This doesn't match I18N domain names, but we don't have proper IRI support, // This doesn't match I18N domain names, but we don't have proper IRI support,
// so force users to insert Punycode. // so force users to insert Punycode.
// Underscores defined as Unreserved Characters in RFC 3986 are // There is not a good sense in which underscores should be
// allowed in a URI. There are cases where we want to consider a // allowed, since it's technically not! (And if you go as
// URI containing "_" such as "_dmarc.example.com". // far to allow everything as specified by the DNS spec...
// Underscores are not allowed in the default. If you want to // well, that's literally everything, modulo some space limits
// allow it, set Core.AllowHostnameUnderscore to true. // for the components and the overall name (which, by the way,
// we are NOT checking!). So we (arbitrarily) decide this:
// let's allow underscores wherever we would have allowed
// hyphens, if they are enabled. This is a pretty good match
// for browser behavior, for example, a large number of browsers
// cannot handle foo_.example.com, but foo_bar.example.com is
// fairly well supported.
$underscore = $config->get('Core.AllowHostnameUnderscore') ? '_' : ''; $underscore = $config->get('Core.AllowHostnameUnderscore') ? '_' : '';
// Based off of RFC 1738, but amended so that // Based off of RFC 1738, but amended so that
// as per RFC 3696, the top label need only not be all numeric. // as per RFC 3696, the top label need only not be all numeric.
// The productions describing this are: // The productions describing this are:
$a = '[a-z]'; // alpha $a = '[a-z]'; // alpha
$an = "[a-z0-9$underscore]"; // alphanum $an = '[a-z0-9]'; // alphanum
$and = "[a-z0-9-$underscore]"; // alphanum | "-" $and = "[a-z0-9-$underscore]"; // alphanum | "-"
// domainlabel = alphanum | alphanum *( alphanum | "-" ) alphanum // domainlabel = alphanum | alphanum *( alphanum | "-" ) alphanum
$domainlabel = "$an(?:$and*$an)?"; $domainlabel = "$an(?:$and*$an)?";
@@ -100,7 +106,7 @@ class HTMLPurifier_AttrDef_URI_Host extends HTMLPurifier_AttrDef
// If we have Net_IDNA2 support, we can support IRIs by // If we have Net_IDNA2 support, we can support IRIs by
// punycoding them. (This is the most portable thing to do, // punycoding them. (This is the most portable thing to do,
// since otherwise we have to assume browsers support // since otherwise we have to assume browsers support
} elseif ($config->get('Core.EnableIDNA') && class_exists('Net_IDNA2')) { } elseif ($config->get('Core.EnableIDNA')) {
$idna = new Net_IDNA2(array('encoding' => 'utf8', 'overlong' => false, 'strict' => true)); $idna = new Net_IDNA2(array('encoding' => 'utf8', 'overlong' => false, 'strict' => true));
// we need to encode each period separately // we need to encode each period separately
$parts = explode('.', $string); $parts = explode('.', $string);

View File

@@ -37,7 +37,7 @@ class HTMLPurifier_AttrDef_URI_IPv6 extends HTMLPurifier_AttrDef_URI_IPv4
} }
} }
// IPv4-compatibility check // IPv4-compatiblity check
if (preg_match('#(?<=:' . ')' . $this->ip4 . '$#s', $aIP, $find)) { if (preg_match('#(?<=:' . ')' . $this->ip4 . '$#s', $aIP, $find)) {
$aIP = substr($aIP, 0, 0 - strlen($find[0])); $aIP = substr($aIP, 0, 0 - strlen($find[0]));
$ip = explode('.', $find[0]); $ip = explode('.', $find[0]);

View File

@@ -3,7 +3,7 @@
// this MUST be placed in post, as it assumes that any value in dir is valid // this MUST be placed in post, as it assumes that any value in dir is valid
/** /**
* Post-transform that ensures that bdo tags have the dir attribute set. * Post-trasnform that ensures that bdo tags have the dir attribute set.
*/ */
class HTMLPurifier_AttrTransform_BdoDir extends HTMLPurifier_AttrTransform class HTMLPurifier_AttrTransform_BdoDir extends HTMLPurifier_AttrTransform
{ {

View File

@@ -33,11 +33,7 @@ class HTMLPurifier_AttrTransform_TargetBlank extends HTMLPurifier_AttrTransform
// XXX Kind of inefficient // XXX Kind of inefficient
$url = $this->parser->parse($attr['href']); $url = $this->parser->parse($attr['href']);
$scheme = $url->getSchemeObj($config, $context);
// Ignore invalid schemes (e.g. `javascript:`)
if (!($scheme = $url->getSchemeObj($config, $context))) {
return $attr;
}
if ($scheme->browsable && !$url->isBenign($config, $context)) { if ($scheme->browsable && !$url->isBenign($config, $context)) {
$attr['target'] = '_blank'; $attr['target'] = '_blank';

View File

@@ -77,7 +77,7 @@ class HTMLPurifier_AttrTypes
} }
if (!isset($this->info[$type])) { if (!isset($this->info[$type])) {
throw new Exception('Cannot retrieve undefined attribute type ' . $type); trigger_error('Cannot retrieve undefined attribute type ' . $type, E_USER_ERROR);
return; return;
} }
return $this->info[$type]->make($string); return $this->info[$type]->make($string);

View File

@@ -135,7 +135,7 @@ class HTMLPurifier_AttrValidator
// we'd also want slightly more complicated substitution // we'd also want slightly more complicated substitution
// involving an array as the return value, // involving an array as the return value,
// although we're not sure how colliding attributes would // although we're not sure how colliding attributes would
// resolve (certain ones would be completely overridden, // resolve (certain ones would be completely overriden,
// others would prepend themselves). // others would prepend themselves).
} }

View File

@@ -5,7 +5,7 @@ if (!defined('HTMLPURIFIER_PREFIX')) {
define('HTMLPURIFIER_PREFIX', realpath(dirname(__FILE__) . '/..')); define('HTMLPURIFIER_PREFIX', realpath(dirname(__FILE__) . '/..'));
} }
// accommodations for versions earlier than 5.0.2 // accomodations for versions earlier than 5.0.2
// borrowed from PHP_Compat, LGPL licensed, by Aidan Lister <aidan@php.net> // borrowed from PHP_Compat, LGPL licensed, by Aidan Lister <aidan@php.net>
if (!defined('PHP_EOL')) { if (!defined('PHP_EOL')) {
switch (strtoupper(substr(PHP_OS, 0, 3))) { switch (strtoupper(substr(PHP_OS, 0, 3))) {
@@ -79,11 +79,44 @@ class HTMLPurifier_Bootstrap
public static function registerAutoload() public static function registerAutoload()
{ {
$autoload = array('HTMLPurifier_Bootstrap', 'autoload'); $autoload = array('HTMLPurifier_Bootstrap', 'autoload');
if (spl_autoload_functions() === false) { if (($funcs = spl_autoload_functions()) === false) {
spl_autoload_register($autoload); spl_autoload_register($autoload);
} else { } elseif (function_exists('spl_autoload_unregister')) {
if (version_compare(PHP_VERSION, '5.3.0', '>=')) {
// prepend flag exists, no need for shenanigans // prepend flag exists, no need for shenanigans
spl_autoload_register($autoload, true, true); spl_autoload_register($autoload, true, true);
} else {
$buggy = version_compare(PHP_VERSION, '5.2.11', '<');
$compat = version_compare(PHP_VERSION, '5.1.2', '<=') &&
version_compare(PHP_VERSION, '5.1.0', '>=');
foreach ($funcs as $func) {
if ($buggy && is_array($func)) {
// :TRICKY: There are some compatibility issues and some
// places where we need to error out
$reflector = new ReflectionMethod($func[0], $func[1]);
if (!$reflector->isStatic()) {
throw new Exception(
'HTML Purifier autoloader registrar is not compatible
with non-static object methods due to PHP Bug #44144;
Please do not use HTMLPurifier.autoload.php (or any
file that includes this file); instead, place the code:
spl_autoload_register(array(\'HTMLPurifier_Bootstrap\', \'autoload\'))
after your own autoloaders.'
);
}
// Suprisingly, spl_autoload_register supports the
// Class::staticMethod callback format, although call_user_func doesn't
if ($compat) {
$func = implode('::', $func);
}
}
spl_autoload_unregister($func);
}
spl_autoload_register($autoload);
foreach ($funcs as $func) {
spl_autoload_register($func);
}
}
} }
} }
} }

View File

@@ -13,7 +13,7 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
* Assoc array of attribute name to definition object. * Assoc array of attribute name to definition object.
* @type HTMLPurifier_AttrDef[] * @type HTMLPurifier_AttrDef[]
*/ */
public $info = []; public $info = array();
/** /**
* Constructs the info array. The meat of this class. * Constructs the info array. The meat of this class.
@@ -22,12 +22,7 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
protected function doSetup($config) protected function doSetup($config)
{ {
$this->info['text-align'] = new HTMLPurifier_AttrDef_Enum( $this->info['text-align'] = new HTMLPurifier_AttrDef_Enum(
['left', 'right', 'center', 'justify'], array('left', 'right', 'center', 'justify'),
false
);
$this->info['direction'] = new HTMLPurifier_AttrDef_Enum(
['ltr', 'rtl'],
false false
); );
@@ -36,7 +31,7 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
$this->info['border-right-style'] = $this->info['border-right-style'] =
$this->info['border-left-style'] = $this->info['border-left-style'] =
$this->info['border-top-style'] = new HTMLPurifier_AttrDef_Enum( $this->info['border-top-style'] = new HTMLPurifier_AttrDef_Enum(
[ array(
'none', 'none',
'hidden', 'hidden',
'dotted', 'dotted',
@@ -47,42 +42,42 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
'ridge', 'ridge',
'inset', 'inset',
'outset' 'outset'
], ),
false false
); );
$this->info['border-style'] = new HTMLPurifier_AttrDef_CSS_Multiple($border_style); $this->info['border-style'] = new HTMLPurifier_AttrDef_CSS_Multiple($border_style);
$this->info['clear'] = new HTMLPurifier_AttrDef_Enum( $this->info['clear'] = new HTMLPurifier_AttrDef_Enum(
['none', 'left', 'right', 'both'], array('none', 'left', 'right', 'both'),
false false
); );
$this->info['float'] = new HTMLPurifier_AttrDef_Enum( $this->info['float'] = new HTMLPurifier_AttrDef_Enum(
['none', 'left', 'right'], array('none', 'left', 'right'),
false false
); );
$this->info['font-style'] = new HTMLPurifier_AttrDef_Enum( $this->info['font-style'] = new HTMLPurifier_AttrDef_Enum(
['normal', 'italic', 'oblique'], array('normal', 'italic', 'oblique'),
false false
); );
$this->info['font-variant'] = new HTMLPurifier_AttrDef_Enum( $this->info['font-variant'] = new HTMLPurifier_AttrDef_Enum(
['normal', 'small-caps'], array('normal', 'small-caps'),
false false
); );
$uri_or_none = new HTMLPurifier_AttrDef_CSS_Composite( $uri_or_none = new HTMLPurifier_AttrDef_CSS_Composite(
[ array(
new HTMLPurifier_AttrDef_Enum(['none']), new HTMLPurifier_AttrDef_Enum(array('none')),
new HTMLPurifier_AttrDef_CSS_URI() new HTMLPurifier_AttrDef_CSS_URI()
] )
); );
$this->info['list-style-position'] = new HTMLPurifier_AttrDef_Enum( $this->info['list-style-position'] = new HTMLPurifier_AttrDef_Enum(
['inside', 'outside'], array('inside', 'outside'),
false false
); );
$this->info['list-style-type'] = new HTMLPurifier_AttrDef_Enum( $this->info['list-style-type'] = new HTMLPurifier_AttrDef_Enum(
[ array(
'disc', 'disc',
'circle', 'circle',
'square', 'square',
@@ -92,7 +87,7 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
'lower-alpha', 'lower-alpha',
'upper-alpha', 'upper-alpha',
'none' 'none'
], ),
false false
); );
$this->info['list-style-image'] = $uri_or_none; $this->info['list-style-image'] = $uri_or_none;
@@ -100,32 +95,34 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
$this->info['list-style'] = new HTMLPurifier_AttrDef_CSS_ListStyle($config); $this->info['list-style'] = new HTMLPurifier_AttrDef_CSS_ListStyle($config);
$this->info['text-transform'] = new HTMLPurifier_AttrDef_Enum( $this->info['text-transform'] = new HTMLPurifier_AttrDef_Enum(
['capitalize', 'uppercase', 'lowercase', 'none'], array('capitalize', 'uppercase', 'lowercase', 'none'),
false false
); );
$this->info['color'] = new HTMLPurifier_AttrDef_CSS_Color(); $this->info['color'] = new HTMLPurifier_AttrDef_CSS_Color();
$this->info['background-image'] = $uri_or_none; $this->info['background-image'] = $uri_or_none;
$this->info['background-repeat'] = new HTMLPurifier_AttrDef_Enum( $this->info['background-repeat'] = new HTMLPurifier_AttrDef_Enum(
['repeat', 'repeat-x', 'repeat-y', 'no-repeat'] array('repeat', 'repeat-x', 'repeat-y', 'no-repeat')
); );
$this->info['background-attachment'] = new HTMLPurifier_AttrDef_Enum( $this->info['background-attachment'] = new HTMLPurifier_AttrDef_Enum(
['scroll', 'fixed'] array('scroll', 'fixed')
); );
$this->info['background-position'] = new HTMLPurifier_AttrDef_CSS_BackgroundPosition(); $this->info['background-position'] = new HTMLPurifier_AttrDef_CSS_BackgroundPosition();
$this->info['background-size'] = new HTMLPurifier_AttrDef_CSS_Composite( $this->info['background-size'] = new HTMLPurifier_AttrDef_CSS_Composite(
[ array(
new HTMLPurifier_AttrDef_Enum( new HTMLPurifier_AttrDef_Enum(
[ array(
'auto', 'auto',
'cover', 'cover',
'contain', 'contain',
] 'initial',
'inherit',
)
), ),
new HTMLPurifier_AttrDef_CSS_Percentage(), new HTMLPurifier_AttrDef_CSS_Percentage(),
new HTMLPurifier_AttrDef_CSS_Length() new HTMLPurifier_AttrDef_CSS_Length()
] )
); );
$border_color = $border_color =
@@ -134,10 +131,10 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
$this->info['border-left-color'] = $this->info['border-left-color'] =
$this->info['border-right-color'] = $this->info['border-right-color'] =
$this->info['background-color'] = new HTMLPurifier_AttrDef_CSS_Composite( $this->info['background-color'] = new HTMLPurifier_AttrDef_CSS_Composite(
[ array(
new HTMLPurifier_AttrDef_Enum(['transparent']), new HTMLPurifier_AttrDef_Enum(array('transparent')),
new HTMLPurifier_AttrDef_CSS_Color() new HTMLPurifier_AttrDef_CSS_Color()
] )
); );
$this->info['background'] = new HTMLPurifier_AttrDef_CSS_Background($config); $this->info['background'] = new HTMLPurifier_AttrDef_CSS_Background($config);
@@ -149,32 +146,32 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
$this->info['border-bottom-width'] = $this->info['border-bottom-width'] =
$this->info['border-left-width'] = $this->info['border-left-width'] =
$this->info['border-right-width'] = new HTMLPurifier_AttrDef_CSS_Composite( $this->info['border-right-width'] = new HTMLPurifier_AttrDef_CSS_Composite(
[ array(
new HTMLPurifier_AttrDef_Enum(['thin', 'medium', 'thick']), new HTMLPurifier_AttrDef_Enum(array('thin', 'medium', 'thick')),
new HTMLPurifier_AttrDef_CSS_Length('0') //disallow negative new HTMLPurifier_AttrDef_CSS_Length('0') //disallow negative
] )
); );
$this->info['border-width'] = new HTMLPurifier_AttrDef_CSS_Multiple($border_width); $this->info['border-width'] = new HTMLPurifier_AttrDef_CSS_Multiple($border_width);
$this->info['letter-spacing'] = new HTMLPurifier_AttrDef_CSS_Composite( $this->info['letter-spacing'] = new HTMLPurifier_AttrDef_CSS_Composite(
[ array(
new HTMLPurifier_AttrDef_Enum(['normal']), new HTMLPurifier_AttrDef_Enum(array('normal')),
new HTMLPurifier_AttrDef_CSS_Length() new HTMLPurifier_AttrDef_CSS_Length()
] )
); );
$this->info['word-spacing'] = new HTMLPurifier_AttrDef_CSS_Composite( $this->info['word-spacing'] = new HTMLPurifier_AttrDef_CSS_Composite(
[ array(
new HTMLPurifier_AttrDef_Enum(['normal']), new HTMLPurifier_AttrDef_Enum(array('normal')),
new HTMLPurifier_AttrDef_CSS_Length() new HTMLPurifier_AttrDef_CSS_Length()
] )
); );
$this->info['font-size'] = new HTMLPurifier_AttrDef_CSS_Composite( $this->info['font-size'] = new HTMLPurifier_AttrDef_CSS_Composite(
[ array(
new HTMLPurifier_AttrDef_Enum( new HTMLPurifier_AttrDef_Enum(
[ array(
'xx-small', 'xx-small',
'x-small', 'x-small',
'small', 'small',
@@ -184,20 +181,20 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
'xx-large', 'xx-large',
'larger', 'larger',
'smaller' 'smaller'
] )
), ),
new HTMLPurifier_AttrDef_CSS_Percentage(), new HTMLPurifier_AttrDef_CSS_Percentage(),
new HTMLPurifier_AttrDef_CSS_Length() new HTMLPurifier_AttrDef_CSS_Length()
] )
); );
$this->info['line-height'] = new HTMLPurifier_AttrDef_CSS_Composite( $this->info['line-height'] = new HTMLPurifier_AttrDef_CSS_Composite(
[ array(
new HTMLPurifier_AttrDef_Enum(['normal']), new HTMLPurifier_AttrDef_Enum(array('normal')),
new HTMLPurifier_AttrDef_CSS_Number(true), // no negatives new HTMLPurifier_AttrDef_CSS_Number(true), // no negatives
new HTMLPurifier_AttrDef_CSS_Length('0'), new HTMLPurifier_AttrDef_CSS_Length('0'),
new HTMLPurifier_AttrDef_CSS_Percentage(true) new HTMLPurifier_AttrDef_CSS_Percentage(true)
] )
); );
$margin = $margin =
@@ -205,11 +202,11 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
$this->info['margin-bottom'] = $this->info['margin-bottom'] =
$this->info['margin-left'] = $this->info['margin-left'] =
$this->info['margin-right'] = new HTMLPurifier_AttrDef_CSS_Composite( $this->info['margin-right'] = new HTMLPurifier_AttrDef_CSS_Composite(
[ array(
new HTMLPurifier_AttrDef_CSS_Length(), new HTMLPurifier_AttrDef_CSS_Length(),
new HTMLPurifier_AttrDef_CSS_Percentage(), new HTMLPurifier_AttrDef_CSS_Percentage(),
new HTMLPurifier_AttrDef_Enum(['auto']) new HTMLPurifier_AttrDef_Enum(array('auto'))
] )
); );
$this->info['margin'] = new HTMLPurifier_AttrDef_CSS_Multiple($margin); $this->info['margin'] = new HTMLPurifier_AttrDef_CSS_Multiple($margin);
@@ -220,40 +217,41 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
$this->info['padding-bottom'] = $this->info['padding-bottom'] =
$this->info['padding-left'] = $this->info['padding-left'] =
$this->info['padding-right'] = new HTMLPurifier_AttrDef_CSS_Composite( $this->info['padding-right'] = new HTMLPurifier_AttrDef_CSS_Composite(
[ array(
new HTMLPurifier_AttrDef_CSS_Length('0'), new HTMLPurifier_AttrDef_CSS_Length('0'),
new HTMLPurifier_AttrDef_CSS_Percentage(true) new HTMLPurifier_AttrDef_CSS_Percentage(true)
] )
); );
$this->info['padding'] = new HTMLPurifier_AttrDef_CSS_Multiple($padding); $this->info['padding'] = new HTMLPurifier_AttrDef_CSS_Multiple($padding);
$this->info['text-indent'] = new HTMLPurifier_AttrDef_CSS_Composite( $this->info['text-indent'] = new HTMLPurifier_AttrDef_CSS_Composite(
[ array(
new HTMLPurifier_AttrDef_CSS_Length(), new HTMLPurifier_AttrDef_CSS_Length(),
new HTMLPurifier_AttrDef_CSS_Percentage() new HTMLPurifier_AttrDef_CSS_Percentage()
] )
); );
$trusted_wh = new HTMLPurifier_AttrDef_CSS_Composite( $trusted_wh = new HTMLPurifier_AttrDef_CSS_Composite(
[ array(
new HTMLPurifier_AttrDef_CSS_Length('0'), new HTMLPurifier_AttrDef_CSS_Length('0'),
new HTMLPurifier_AttrDef_CSS_Percentage(true), new HTMLPurifier_AttrDef_CSS_Percentage(true),
new HTMLPurifier_AttrDef_Enum(['auto']) new HTMLPurifier_AttrDef_Enum(array('auto', 'initial', 'inherit'))
] )
); );
$trusted_min_wh = new HTMLPurifier_AttrDef_CSS_Composite( $trusted_min_wh = new HTMLPurifier_AttrDef_CSS_Composite(
[ array(
new HTMLPurifier_AttrDef_CSS_Length('0'), new HTMLPurifier_AttrDef_CSS_Length('0'),
new HTMLPurifier_AttrDef_CSS_Percentage(true), new HTMLPurifier_AttrDef_CSS_Percentage(true),
] new HTMLPurifier_AttrDef_Enum(array('initial', 'inherit'))
)
); );
$trusted_max_wh = new HTMLPurifier_AttrDef_CSS_Composite( $trusted_max_wh = new HTMLPurifier_AttrDef_CSS_Composite(
[ array(
new HTMLPurifier_AttrDef_CSS_Length('0'), new HTMLPurifier_AttrDef_CSS_Length('0'),
new HTMLPurifier_AttrDef_CSS_Percentage(true), new HTMLPurifier_AttrDef_CSS_Percentage(true),
new HTMLPurifier_AttrDef_Enum(['none']) new HTMLPurifier_AttrDef_Enum(array('none', 'initial', 'inherit'))
] )
); );
$max = $config->get('CSS.MaxImgLength'); $max = $config->get('CSS.MaxImgLength');
@@ -265,10 +263,10 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
'img', 'img',
// For img tags: // For img tags:
new HTMLPurifier_AttrDef_CSS_Composite( new HTMLPurifier_AttrDef_CSS_Composite(
[ array(
new HTMLPurifier_AttrDef_CSS_Length('0', $max), new HTMLPurifier_AttrDef_CSS_Length('0', $max),
new HTMLPurifier_AttrDef_Enum(['auto']) new HTMLPurifier_AttrDef_Enum(array('auto'))
] )
), ),
// For everyone else: // For everyone else:
$trusted_wh $trusted_wh
@@ -280,7 +278,12 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
new HTMLPurifier_AttrDef_Switch( new HTMLPurifier_AttrDef_Switch(
'img', 'img',
// For img tags: // For img tags:
new HTMLPurifier_AttrDef_CSS_Composite(
array(
new HTMLPurifier_AttrDef_CSS_Length('0', $max), new HTMLPurifier_AttrDef_CSS_Length('0', $max),
new HTMLPurifier_AttrDef_Enum(array('initial', 'inherit'))
)
),
// For everyone else: // For everyone else:
$trusted_min_wh $trusted_min_wh
); );
@@ -292,46 +295,22 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
'img', 'img',
// For img tags: // For img tags:
new HTMLPurifier_AttrDef_CSS_Composite( new HTMLPurifier_AttrDef_CSS_Composite(
[ array(
new HTMLPurifier_AttrDef_CSS_Length('0', $max), new HTMLPurifier_AttrDef_CSS_Length('0', $max),
new HTMLPurifier_AttrDef_Enum(['none']) new HTMLPurifier_AttrDef_Enum(array('none', 'initial', 'inherit'))
] )
), ),
// For everyone else: // For everyone else:
$trusted_max_wh $trusted_max_wh
); );
$this->info['aspect-ratio'] = new HTMLPurifier_AttrDef_CSS_Multiple(
new HTMLPurifier_AttrDef_CSS_Composite([
new HTMLPurifier_AttrDef_CSS_Ratio(),
new HTMLPurifier_AttrDef_Enum(['auto']),
])
);
// text-decoration and related shorthands
$this->info['text-decoration'] = new HTMLPurifier_AttrDef_CSS_TextDecoration(); $this->info['text-decoration'] = new HTMLPurifier_AttrDef_CSS_TextDecoration();
$this->info['text-decoration-line'] = new HTMLPurifier_AttrDef_Enum(
['none', 'underline', 'overline', 'line-through']
);
$this->info['text-decoration-style'] = new HTMLPurifier_AttrDef_Enum(
['solid', 'double', 'dotted', 'dashed', 'wavy']
);
$this->info['text-decoration-color'] = new HTMLPurifier_AttrDef_CSS_Color();
$this->info['text-decoration-thickness'] = new HTMLPurifier_AttrDef_CSS_Composite([
new HTMLPurifier_AttrDef_CSS_Length(),
new HTMLPurifier_AttrDef_CSS_Percentage(),
new HTMLPurifier_AttrDef_Enum(['auto', 'from-font'])
]);
$this->info['font-family'] = new HTMLPurifier_AttrDef_CSS_FontFamily(); $this->info['font-family'] = new HTMLPurifier_AttrDef_CSS_FontFamily();
// this could use specialized code // this could use specialized code
$this->info['font-weight'] = new HTMLPurifier_AttrDef_Enum( $this->info['font-weight'] = new HTMLPurifier_AttrDef_Enum(
[ array(
'normal', 'normal',
'bold', 'bold',
'bolder', 'bolder',
@@ -345,7 +324,7 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
'700', '700',
'800', '800',
'900' '900'
], ),
false false
); );
@@ -361,21 +340,21 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
$this->info['border-right'] = new HTMLPurifier_AttrDef_CSS_Border($config); $this->info['border-right'] = new HTMLPurifier_AttrDef_CSS_Border($config);
$this->info['border-collapse'] = new HTMLPurifier_AttrDef_Enum( $this->info['border-collapse'] = new HTMLPurifier_AttrDef_Enum(
['collapse', 'separate'] array('collapse', 'separate')
); );
$this->info['caption-side'] = new HTMLPurifier_AttrDef_Enum( $this->info['caption-side'] = new HTMLPurifier_AttrDef_Enum(
['top', 'bottom'] array('top', 'bottom')
); );
$this->info['table-layout'] = new HTMLPurifier_AttrDef_Enum( $this->info['table-layout'] = new HTMLPurifier_AttrDef_Enum(
['auto', 'fixed'] array('auto', 'fixed')
); );
$this->info['vertical-align'] = new HTMLPurifier_AttrDef_CSS_Composite( $this->info['vertical-align'] = new HTMLPurifier_AttrDef_CSS_Composite(
[ array(
new HTMLPurifier_AttrDef_Enum( new HTMLPurifier_AttrDef_Enum(
[ array(
'baseline', 'baseline',
'sub', 'sub',
'super', 'super',
@@ -384,11 +363,11 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
'middle', 'middle',
'bottom', 'bottom',
'text-bottom' 'text-bottom'
] )
), ),
new HTMLPurifier_AttrDef_CSS_Length(), new HTMLPurifier_AttrDef_CSS_Length(),
new HTMLPurifier_AttrDef_CSS_Percentage() new HTMLPurifier_AttrDef_CSS_Percentage()
] )
); );
$this->info['border-spacing'] = new HTMLPurifier_AttrDef_CSS_Multiple(new HTMLPurifier_AttrDef_CSS_Length(), 2); $this->info['border-spacing'] = new HTMLPurifier_AttrDef_CSS_Multiple(new HTMLPurifier_AttrDef_CSS_Length(), 2);
@@ -396,7 +375,7 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
// These CSS properties don't work on many browsers, but we live // These CSS properties don't work on many browsers, but we live
// in THE FUTURE! // in THE FUTURE!
$this->info['white-space'] = new HTMLPurifier_AttrDef_Enum( $this->info['white-space'] = new HTMLPurifier_AttrDef_Enum(
['nowrap', 'normal', 'pre', 'pre-wrap', 'pre-line'] array('nowrap', 'normal', 'pre', 'pre-wrap', 'pre-line')
); );
if ($config->get('CSS.Proprietary')) { if ($config->get('CSS.Proprietary')) {
@@ -443,21 +422,21 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
// more CSS3 // more CSS3
$this->info['page-break-after'] = $this->info['page-break-after'] =
$this->info['page-break-before'] = new HTMLPurifier_AttrDef_Enum( $this->info['page-break-before'] = new HTMLPurifier_AttrDef_Enum(
[ array(
'auto', 'auto',
'always', 'always',
'avoid', 'avoid',
'left', 'left',
'right' 'right'
] )
); );
$this->info['page-break-inside'] = new HTMLPurifier_AttrDef_Enum(['auto', 'avoid']); $this->info['page-break-inside'] = new HTMLPurifier_AttrDef_Enum(array('auto', 'avoid'));
$border_radius = new HTMLPurifier_AttrDef_CSS_Composite( $border_radius = new HTMLPurifier_AttrDef_CSS_Composite(
[ array(
new HTMLPurifier_AttrDef_CSS_Percentage(true), // disallow negative new HTMLPurifier_AttrDef_CSS_Percentage(true), // disallow negative
new HTMLPurifier_AttrDef_CSS_Length('0') // disallow negative new HTMLPurifier_AttrDef_CSS_Length('0') // disallow negative
]); ));
$this->info['border-top-left-radius'] = $this->info['border-top-left-radius'] =
$this->info['border-top-right-radius'] = $this->info['border-top-right-radius'] =
@@ -474,7 +453,7 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
protected function doSetupTricky($config) protected function doSetupTricky($config)
{ {
$this->info['display'] = new HTMLPurifier_AttrDef_Enum( $this->info['display'] = new HTMLPurifier_AttrDef_Enum(
[ array(
'inline', 'inline',
'block', 'block',
'list-item', 'list-item',
@@ -493,12 +472,12 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
'table-cell', 'table-cell',
'table-caption', 'table-caption',
'none' 'none'
] )
); );
$this->info['visibility'] = new HTMLPurifier_AttrDef_Enum( $this->info['visibility'] = new HTMLPurifier_AttrDef_Enum(
['visible', 'hidden', 'collapse'] array('visible', 'hidden', 'collapse')
); );
$this->info['overflow'] = new HTMLPurifier_AttrDef_Enum(['visible', 'hidden', 'auto', 'scroll']); $this->info['overflow'] = new HTMLPurifier_AttrDef_Enum(array('visible', 'hidden', 'auto', 'scroll'));
$this->info['opacity'] = new HTMLPurifier_AttrDef_CSS_AlphaValue(); $this->info['opacity'] = new HTMLPurifier_AttrDef_CSS_AlphaValue();
} }
@@ -508,23 +487,23 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
protected function doSetupTrusted($config) protected function doSetupTrusted($config)
{ {
$this->info['position'] = new HTMLPurifier_AttrDef_Enum( $this->info['position'] = new HTMLPurifier_AttrDef_Enum(
['static', 'relative', 'absolute', 'fixed'] array('static', 'relative', 'absolute', 'fixed')
); );
$this->info['top'] = $this->info['top'] =
$this->info['left'] = $this->info['left'] =
$this->info['right'] = $this->info['right'] =
$this->info['bottom'] = new HTMLPurifier_AttrDef_CSS_Composite( $this->info['bottom'] = new HTMLPurifier_AttrDef_CSS_Composite(
[ array(
new HTMLPurifier_AttrDef_CSS_Length(), new HTMLPurifier_AttrDef_CSS_Length(),
new HTMLPurifier_AttrDef_CSS_Percentage(), new HTMLPurifier_AttrDef_CSS_Percentage(),
new HTMLPurifier_AttrDef_Enum(['auto']), new HTMLPurifier_AttrDef_Enum(array('auto')),
] )
); );
$this->info['z-index'] = new HTMLPurifier_AttrDef_CSS_Composite( $this->info['z-index'] = new HTMLPurifier_AttrDef_CSS_Composite(
[ array(
new HTMLPurifier_AttrDef_Integer(), new HTMLPurifier_AttrDef_Integer(),
new HTMLPurifier_AttrDef_Enum(['auto']), new HTMLPurifier_AttrDef_Enum(array('auto')),
] )
); );
} }

View File

@@ -190,9 +190,6 @@ class HTMLPurifier_ChildDef_Table extends HTMLPurifier_ChildDef
$current_tr_tbody = null; $current_tr_tbody = null;
foreach($content as $node) { foreach($content as $node) {
if (!isset($node->name)) {
continue;
}
switch ($node->name) { switch ($node->name) {
case 'tbody': case 'tbody':
$current_tr_tbody = null; $current_tr_tbody = null;

View File

@@ -21,7 +21,7 @@ class HTMLPurifier_Config
* HTML Purifier's version * HTML Purifier's version
* @type string * @type string
*/ */
public $version = '4.19.0'; public $version = '4.15.0';
/** /**
* Whether or not to automatically finalize * Whether or not to automatically finalize
@@ -898,12 +898,8 @@ class HTMLPurifier_Config
break; break;
} }
} }
if ($no == E_USER_ERROR) {
throw new Exception($msg . $extra);
} else {
trigger_error($msg . $extra, $no); trigger_error($msg . $extra, $no);
} }
}
/** /**
* Returns a serialized form of the configuration object that can * Returns a serialized form of the configuration object that can

View File

@@ -72,7 +72,7 @@ class HTMLPurifier_ConfigSchema
$r = unserialize($contents); $r = unserialize($contents);
if (!$r) { if (!$r) {
$hash = sha1($contents); $hash = sha1($contents);
throw new Exception("Unserialization of configuration schema failed, sha1 of file was $hash"); trigger_error("Unserialization of configuration schema failed, sha1 of file was $hash", E_USER_ERROR);
} }
return $r; return $r;
} }

View File

@@ -66,7 +66,7 @@ class HTMLPurifier_ConfigSchema_Interchange_Directive
public $version; public $version;
/** /**
* ID of directive that supersedes this old directive. * ID of directive that supercedes this old directive.
* Null if not deprecated. * Null if not deprecated.
* @type HTMLPurifier_ConfigSchema_Interchange_Id * @type HTMLPurifier_ConfigSchema_Interchange_Id
*/ */

File diff suppressed because one or more lines are too long

View File

@@ -142,11 +142,12 @@ class HTMLPurifier_ContentSets
if ($return !== false) { if ($return !== false) {
return $return; return $return;
} }
// error-out
throw new Exception( trigger_error(
'Could not determine which ChildDef class to instantiate', 'Could not determine which ChildDef class to instantiate',
E_USER_ERROR E_USER_ERROR
); );
return false;
} }
/** /**

View File

@@ -24,7 +24,11 @@ class HTMLPurifier_Context
public function register($name, &$ref) public function register($name, &$ref)
{ {
if (array_key_exists($name, $this->_storage)) { if (array_key_exists($name, $this->_storage)) {
throw new Exception("Name $name produces collision, cannot re-register"); trigger_error(
"Name $name produces collision, cannot re-register",
E_USER_ERROR
);
return;
} }
$this->_storage[$name] =& $ref; $this->_storage[$name] =& $ref;
} }
@@ -39,7 +43,10 @@ class HTMLPurifier_Context
{ {
if (!array_key_exists($name, $this->_storage)) { if (!array_key_exists($name, $this->_storage)) {
if (!$ignore_error) { if (!$ignore_error) {
throw new Exception("Attempted to retrieve non-existent variable $name"); trigger_error(
"Attempted to retrieve non-existent variable $name",
E_USER_ERROR
);
} }
$var = null; // so we can return by reference $var = null; // so we can return by reference
return $var; return $var;
@@ -54,7 +61,11 @@ class HTMLPurifier_Context
public function destroy($name) public function destroy($name)
{ {
if (!array_key_exists($name, $this->_storage)) { if (!array_key_exists($name, $this->_storage)) {
throw new Exception("Attempted to destroy non-existent variable $name"); trigger_error(
"Attempted to destroy non-existent variable $name",
E_USER_ERROR
);
return;
} }
unset($this->_storage[$name]); unset($this->_storage[$name]);
} }

View File

@@ -139,9 +139,8 @@ class HTMLPurifier_DefinitionCache_Serializer extends HTMLPurifier_DefinitionCac
continue; continue;
} }
$key = substr($filename, 0, strlen($filename) - 4); $key = substr($filename, 0, strlen($filename) - 4);
$file = $dir . '/' . $filename; if ($this->isOld($key, $config)) {
if ($this->isOld($key, $config) && file_exists($file)) { unlink($dir . '/' . $filename);
unlink($file);
} }
} }
closedir($dh); closedir($dh);
@@ -288,14 +287,13 @@ class HTMLPurifier_DefinitionCache_Serializer extends HTMLPurifier_DefinitionCac
} elseif (filegroup($dir) === posix_getgid()) { } elseif (filegroup($dir) === posix_getgid()) {
$chmod = $chmod | 0070; $chmod = $chmod | 0070;
} else { } else {
// PHP's probably running as nobody, it is // PHP's probably running as nobody, so we'll
// not obvious how to fix this (777 is probably // need to give global permissions
// bad if you are multi-user), let the user figure it out $chmod = $chmod | 0777;
$chmod = null;
} }
trigger_error( trigger_error(
'Directory ' . $dir . ' not writable. ' . 'Directory ' . $dir . ' not writable, ' .
($chmod === null ? '' : 'Please chmod to ' . decoct($chmod)), 'please chmod to ' . decoct($chmod),
E_USER_WARNING E_USER_WARNING
); );
} else { } else {

View File

@@ -71,7 +71,7 @@ class HTMLPurifier_DefinitionCacheFactory
return $this->caches[$method][$type]; return $this->caches[$method][$type];
} }
if (isset($this->implementations[$method]) && if (isset($this->implementations[$method]) &&
class_exists($class = $this->implementations[$method])) { class_exists($class = $this->implementations[$method], false)) {
$cache = new $class($type); $cache = new $class($type);
} else { } else {
if ($method != 'Serializer') { if ($method != 'Serializer') {

View File

@@ -86,7 +86,7 @@ class HTMLPurifier_DoctypeRegistry
$doctype = $this->aliases[$doctype]; $doctype = $this->aliases[$doctype];
} }
if (!isset($this->doctypes[$doctype])) { if (!isset($this->doctypes[$doctype])) {
throw new Exception('Doctype ' . htmlspecialchars($doctype) . ' does not exist'); trigger_error('Doctype ' . htmlspecialchars($doctype) . ' does not exist', E_USER_ERROR);
$anon = new HTMLPurifier_Doctype($doctype); $anon = new HTMLPurifier_Doctype($doctype);
return $anon; return $anon;
} }

View File

@@ -12,7 +12,7 @@ class HTMLPurifier_Encoder
*/ */
private function __construct() private function __construct()
{ {
throw new Exception('Cannot instantiate encoder, call methods statically'); trigger_error('Cannot instantiate encoder, call methods statically', E_USER_ERROR);
} }
/** /**
@@ -390,7 +390,7 @@ class HTMLPurifier_Encoder
$str = self::unsafeIconv($encoding, 'utf-8//IGNORE', $str); $str = self::unsafeIconv($encoding, 'utf-8//IGNORE', $str);
if ($str === false) { if ($str === false) {
// $encoding is not a valid encoding // $encoding is not a valid encoding
throw new Exception('Invalid encoding ' . $encoding); trigger_error('Invalid encoding ' . $encoding, E_USER_ERROR);
return ''; return '';
} }
// If the string is bjorked by Shift_JIS or a similar encoding // If the string is bjorked by Shift_JIS or a similar encoding
@@ -404,11 +404,12 @@ class HTMLPurifier_Encoder
} }
$bug = HTMLPurifier_Encoder::testIconvTruncateBug(); $bug = HTMLPurifier_Encoder::testIconvTruncateBug();
if ($bug == self::ICONV_OK) { if ($bug == self::ICONV_OK) {
throw new Exception('Encoding not supported, please install iconv'); trigger_error('Encoding not supported, please install iconv', E_USER_ERROR);
} else { } else {
throw new Exception( trigger_error(
'You have a buggy version of iconv, see https://bugs.php.net/bug.php?id=48147 ' . 'You have a buggy version of iconv, see https://bugs.php.net/bug.php?id=48147 ' .
'and http://sourceware.org/bugzilla/show_bug.cgi?id=13541' 'and http://sourceware.org/bugzilla/show_bug.cgi?id=13541',
E_USER_ERROR
); );
} }
} }
@@ -453,7 +454,7 @@ class HTMLPurifier_Encoder
$str = mb_convert_encoding($str, 'ISO-8859-1', 'UTF-8'); $str = mb_convert_encoding($str, 'ISO-8859-1', 'UTF-8');
return $str; return $str;
} }
throw new Exception('Encoding not supported'); trigger_error('Encoding not supported', E_USER_ERROR);
// You might be tempted to assume that the ASCII representation // You might be tempted to assume that the ASCII representation
// might be OK, however, this is *not* universally true over all // might be OK, however, this is *not* universally true over all
// encodings. So we take the conservative route here, rather // encodings. So we take the conservative route here, rather
@@ -544,9 +545,10 @@ class HTMLPurifier_Encoder
} elseif (($c = strlen($r)) < 9000) { } elseif (($c = strlen($r)) < 9000) {
$code = self::ICONV_TRUNCATES; $code = self::ICONV_TRUNCATES;
} elseif ($c > 9000) { } elseif ($c > 9000) {
throw new Exception( trigger_error(
'Your copy of iconv is extremely buggy. Please notify HTML Purifier maintainers: ' . 'Your copy of iconv is extremely buggy. Please notify HTML Purifier maintainers: ' .
'include your iconv version as per phpversion()' 'include your iconv version as per phpversion()',
E_USER_ERROR
); );
} else { } else {
$code = self::ICONV_OK; $code = self::ICONV_OK;

View File

@@ -5,7 +5,7 @@
// $config or $context to the callback functions. // $config or $context to the callback functions.
/** /**
* Handles referencing and dereferencing character entities * Handles referencing and derefencing character entities
*/ */
class HTMLPurifier_EntityParser class HTMLPurifier_EntityParser
{ {
@@ -116,8 +116,8 @@ class HTMLPurifier_EntityParser
protected function entityCallback($matches) protected function entityCallback($matches)
{ {
$entity = $matches[0]; $entity = $matches[0];
$hex_part = isset($matches[1]) ? $matches[1] : null; $hex_part = @$matches[1];
$dec_part = isset($matches[2]) ? $matches[2] : null; $dec_part = @$matches[2];
$named_part = empty($matches[3]) ? (empty($matches[4]) ? "" : $matches[4]) : $matches[3]; $named_part = empty($matches[3]) ? (empty($matches[4]) ? "" : $matches[4]) : $matches[3];
if ($hex_part !== NULL && $hex_part !== "") { if ($hex_part !== NULL && $hex_part !== "") {
return HTMLPurifier_Encoder::unichr(hexdec($hex_part)); return HTMLPurifier_Encoder::unichr(hexdec($hex_part));

View File

@@ -4,7 +4,7 @@
* Represents a pre or post processing filter on HTML Purifier's output * Represents a pre or post processing filter on HTML Purifier's output
* *
* Sometimes, a little ad-hoc fixing of HTML has to be done before * Sometimes, a little ad-hoc fixing of HTML has to be done before
* it gets sent through HTML Purifier: you can use filters to achieve * it gets sent through HTML Purifier: you can use filters to acheive
* this effect. For instance, YouTube videos can be preserved using * this effect. For instance, YouTube videos can be preserved using
* this manner. You could have used a decorator for this task, but * this manner. You could have used a decorator for this task, but
* PHP's support for them is not terribly robust, so we're going * PHP's support for them is not terribly robust, so we're going

View File

@@ -54,11 +54,6 @@ class HTMLPurifier_Filter_ExtractStyleBlocks extends HTMLPurifier_Filter
*/ */
private $_enum_attrdef; private $_enum_attrdef;
/**
* @type HTMLPurifier_AttrDef_Enum
*/
private $_universal_attrdef;
public function __construct() public function __construct()
{ {
$this->_tidy = new csstidy(); $this->_tidy = new csstidy();
@@ -75,13 +70,6 @@ class HTMLPurifier_Filter_ExtractStyleBlocks extends HTMLPurifier_Filter
'focus' 'focus'
) )
); );
$this->_universal_attrdef = new HTMLPurifier_AttrDef_Enum(
array(
'initial',
'inherit',
'unset',
)
);
} }
/** /**
@@ -158,7 +146,6 @@ class HTMLPurifier_Filter_ExtractStyleBlocks extends HTMLPurifier_Filter
foreach ($this->_tidy->css as $k => $decls) { foreach ($this->_tidy->css as $k => $decls) {
// $decls are all CSS declarations inside an @ selector // $decls are all CSS declarations inside an @ selector
$new_decls = array(); $new_decls = array();
if (is_array($decls)) {
foreach ($decls as $selector => $style) { foreach ($decls as $selector => $style) {
$selector = trim($selector); $selector = trim($selector);
if ($selector === '') { if ($selector === '') {
@@ -319,11 +306,6 @@ class HTMLPurifier_Filter_ExtractStyleBlocks extends HTMLPurifier_Filter
unset($style[$name]); unset($style[$name]);
continue; continue;
} }
$uni_ret = $this->_universal_attrdef->validate($value, $config, $context);
if ($uni_ret !== false) {
$style[$name] = $uni_ret;
continue;
}
$def = $css_definition->info[$name]; $def = $css_definition->info[$name];
$ret = $def->validate($value, $config, $context); $ret = $def->validate($value, $config, $context);
if ($ret === false) { if ($ret === false) {
@@ -334,9 +316,6 @@ class HTMLPurifier_Filter_ExtractStyleBlocks extends HTMLPurifier_Filter
} }
$new_decls[$selector] = $style; $new_decls[$selector] = $style;
} }
} else {
continue;
}
$new_css[$k] = $new_decls; $new_css[$k] = $new_decls;
} }
// remove stuff that shouldn't be used, could be reenabled // remove stuff that shouldn't be used, could be reenabled

View File

@@ -19,7 +19,7 @@ class HTMLPurifier_Filter_YouTube extends HTMLPurifier_Filter
$pre_regex = '#<object[^>]+>.+?' . $pre_regex = '#<object[^>]+>.+?' .
'(?:http:)?//www.youtube.com/((?:v|cp)/[A-Za-z0-9\-_=]+).+?</object>#s'; '(?:http:)?//www.youtube.com/((?:v|cp)/[A-Za-z0-9\-_=]+).+?</object>#s';
$pre_replace = '<span class="youtube-embed">\1</span>'; $pre_replace = '<span class="youtube-embed">\1</span>';
return preg_replace($pre_regex, $pre_replace, (string)$html); return preg_replace($pre_regex, $pre_replace, $html);
} }
/** /**
@@ -31,7 +31,7 @@ class HTMLPurifier_Filter_YouTube extends HTMLPurifier_Filter
public function postFilter($html, $config, $context) public function postFilter($html, $config, $context)
{ {
$post_regex = '#<span class="youtube-embed">((?:v|cp)/[A-Za-z0-9\-_=]+)</span>#'; $post_regex = '#<span class="youtube-embed">((?:v|cp)/[A-Za-z0-9\-_=]+)</span>#';
return preg_replace_callback($post_regex, array($this, 'postFilterCallback'), (string)$html); return preg_replace_callback($post_regex, array($this, 'postFilterCallback'), $html);
} }
/** /**

View File

@@ -244,7 +244,7 @@ class HTMLPurifier_Generator
// whitespace (in fact, most don't, at least for attributes // whitespace (in fact, most don't, at least for attributes
// like alt, but an extra space at the end is barely // like alt, but an extra space at the end is barely
// noticeable). Still, we have a configuration knob for // noticeable). Still, we have a configuration knob for
// this, since this transformation is not necessary if you // this, since this transformation is not necesary if you
// don't process user input with innerHTML or you don't plan // don't process user input with innerHTML or you don't plan
// on supporting Internet Explorer. // on supporting Internet Explorer.
if ($this->_innerHTMLFix) { if ($this->_innerHTMLFix) {

View File

@@ -264,8 +264,9 @@ class HTMLPurifier_HTMLDefinition extends HTMLPurifier_Definition
if (isset($this->info_content_sets['Block'][$block_wrapper])) { if (isset($this->info_content_sets['Block'][$block_wrapper])) {
$this->info_block_wrapper = $block_wrapper; $this->info_block_wrapper = $block_wrapper;
} else { } else {
throw new Exception( trigger_error(
'Cannot use non-block element as block wrapper' 'Cannot use non-block element as block wrapper',
E_USER_ERROR
); );
} }
@@ -275,7 +276,11 @@ class HTMLPurifier_HTMLDefinition extends HTMLPurifier_Definition
$this->info_parent = $parent; $this->info_parent = $parent;
$this->info_parent_def = $def; $this->info_parent_def = $def;
} else { } else {
throw new Exception('Cannot use unrecognized element as parent'); trigger_error(
'Cannot use unrecognized element as parent',
E_USER_ERROR
);
$this->info_parent_def = $this->manager->getElement($this->info_parent, true);
} }
// support template text // support template text

View File

@@ -28,7 +28,7 @@ class HTMLPurifier_HTMLModule_Edit extends HTMLPurifier_HTMLModule
// HTML 4.01 specifies that ins/del must not contain block // HTML 4.01 specifies that ins/del must not contain block
// elements when used in an inline context, chameleon is // elements when used in an inline context, chameleon is
// a complicated workaround to achieve this effect // a complicated workaround to acheive this effect
// Inline context ! Block context (exclamation mark is // Inline context ! Block context (exclamation mark is
// separator, see getChildDef for parsing) // separator, see getChildDef for parsing)

View File

@@ -28,7 +28,12 @@ class HTMLPurifier_HTMLModule_Iframe extends HTMLPurifier_HTMLModule
if ($config->get('HTML.SafeIframe')) { if ($config->get('HTML.SafeIframe')) {
$this->safe = true; $this->safe = true;
} }
$attrs = array( $this->addElement(
'iframe',
'Inline',
'Flow',
'Common',
array(
'src' => 'URI#embedded', 'src' => 'URI#embedded',
'width' => 'Length', 'width' => 'Length',
'height' => 'Length', 'height' => 'Length',
@@ -38,18 +43,7 @@ class HTMLPurifier_HTMLModule_Iframe extends HTMLPurifier_HTMLModule
'longdesc' => 'URI', 'longdesc' => 'URI',
'marginheight' => 'Pixels', 'marginheight' => 'Pixels',
'marginwidth' => 'Pixels', 'marginwidth' => 'Pixels',
); )
if ($config->get('HTML.Trusted')) {
$attrs['allowfullscreen'] = 'Bool#allowfullscreen';
}
$this->addElement(
'iframe',
'Inline',
'Flow',
'Common',
$attrs
); );
} }
} }

View File

@@ -2,7 +2,7 @@
/** /**
* XHTML 1.1 Ruby Annotation Module, defines elements that indicate * XHTML 1.1 Ruby Annotation Module, defines elements that indicate
* short runs of text alongside base text for annotation or pronunciation. * short runs of text alongside base text for annotation or pronounciation.
*/ */
class HTMLPurifier_HTMLModule_Ruby extends HTMLPurifier_HTMLModule class HTMLPurifier_HTMLModule_Ruby extends HTMLPurifier_HTMLModule
{ {

View File

@@ -112,8 +112,9 @@ class HTMLPurifier_HTMLModule_Tidy extends HTMLPurifier_HTMLModule
return; return;
} }
if (!isset($this->fixesForLevel[$this->defaultLevel])) { if (!isset($this->fixesForLevel[$this->defaultLevel])) {
throw new Exception( trigger_error(
'Default level ' . $this->defaultLevel . ' does not exist' 'Default level ' . $this->defaultLevel . ' does not exist',
E_USER_ERROR
); );
return; return;
} }
@@ -161,7 +162,8 @@ class HTMLPurifier_HTMLModule_Tidy extends HTMLPurifier_HTMLModule
$e->$type = $fix; $e->$type = $fix;
break; break;
default: default:
throw new Exception("Fix type $type not supported"); trigger_error("Fix type $type not supported", E_USER_ERROR);
break;
} }
} }
} }
@@ -219,7 +221,6 @@ class HTMLPurifier_HTMLModule_Tidy extends HTMLPurifier_HTMLModule
*/ */
public function makeFixes() public function makeFixes()
{ {
return array();
} }
} }

View File

@@ -1,7 +1,7 @@
<?php <?php
/** /**
* Name is deprecated, but allowed in strict doctypes, so only * Name is deprecated, but allowed in strict doctypes, so onl
*/ */
class HTMLPurifier_HTMLModule_Tidy_Name extends HTMLPurifier_HTMLModule_Tidy class HTMLPurifier_HTMLModule_Tidy_Name extends HTMLPurifier_HTMLModule_Tidy
{ {

View File

@@ -183,7 +183,11 @@ class HTMLPurifier_HTMLModuleManager
if (!$ok) { if (!$ok) {
$module = $original_module; $module = $original_module;
if (!class_exists($module)) { if (!class_exists($module)) {
throw new Exception($original_module . ' module does not exist'); trigger_error(
$original_module . ' module does not exist',
E_USER_ERROR
);
return;
} }
} }
$module = new $module(); $module = new $module();

View File

@@ -109,7 +109,7 @@ class HTMLPurifier_LanguageFactory
} else { } else {
$class = 'HTMLPurifier_Language_' . $pcode; $class = 'HTMLPurifier_Language_' . $pcode;
$file = $this->dir . '/Language/classes/' . $code . '.php'; $file = $this->dir . '/Language/classes/' . $code . '.php';
if (file_exists($file) || class_exists($class)) { if (file_exists($file) || class_exists($class, false)) {
$lang = new $class($config, $context); $lang = new $class($config, $context);
} else { } else {
// Go fallback // Go fallback
@@ -173,8 +173,14 @@ class HTMLPurifier_LanguageFactory
// infinite recursion guard // infinite recursion guard
if (isset($languages_seen[$code])) { if (isset($languages_seen[$code])) {
throw new Exception('Circular fallback reference in language ' . $code); trigger_error(
'Circular fallback reference in language ' .
$code,
E_USER_ERROR
);
$fallback = 'en';
} }
$language_seen[$code] = true;
// load the fallback recursively // load the fallback recursively
$this->loadLanguage($fallback); $this->loadLanguage($fallback);

View File

@@ -101,7 +101,7 @@ class HTMLPurifier_Lexer
break; break;
} }
if (class_exists('DOMDocument') && if (class_exists('DOMDocument', false) &&
method_exists('DOMDocument', 'loadHTML') && method_exists('DOMDocument', 'loadHTML') &&
!extension_loaded('domxml') !extension_loaded('domxml')
) { ) {
@@ -238,7 +238,7 @@ class HTMLPurifier_Lexer
*/ */
public function tokenizeHTML($string, $config, $context) public function tokenizeHTML($string, $config, $context)
{ {
throw new Exception('Call to abstract class'); trigger_error('Call to abstract class', E_USER_ERROR);
} }
/** /**
@@ -269,6 +269,20 @@ class HTMLPurifier_Lexer
); );
} }
/**
* Special Internet Explorer conditional comments should be removed.
* @param string $string HTML string to process.
* @return string HTML with conditional comments removed.
*/
protected static function removeIEConditional($string)
{
return preg_replace(
'#<!--\[if [^>]+\]>.*?<!\[endif\]-->#si', // probably should generalize for all strings
'',
$string
);
}
/** /**
* Callback function for escapeCDATA() that does the work. * Callback function for escapeCDATA() that does the work.
* *
@@ -309,6 +323,8 @@ class HTMLPurifier_Lexer
// escape CDATA // escape CDATA
$html = $this->escapeCDATA($html); $html = $this->escapeCDATA($html);
$html = $this->removeIEConditional($html);
// extract body from document if applicable // extract body from document if applicable
if ($config->get('Core.ConvertDocumentToFragment')) { if ($config->get('Core.ConvertDocumentToFragment')) {
$e = false; $e = false;

View File

@@ -52,7 +52,14 @@ class HTMLPurifier_Lexer_DOMLex extends HTMLPurifier_Lexer
// attempt to armor stray angled brackets that cannot possibly // attempt to armor stray angled brackets that cannot possibly
// form tags and thus are probably being used as emoticons // form tags and thus are probably being used as emoticons
if ($config->get('Core.AggressivelyFixLt')) { if ($config->get('Core.AggressivelyFixLt')) {
$html = $this->aggressivelyFixLt($html); $char = '[^a-z!\/]';
$comment = "/<!--(.*?)(-->|\z)/is";
$html = preg_replace_callback($comment, array($this, 'callbackArmorCommentEntities'), $html);
do {
$old = $html;
$html = preg_replace("/<($char)/i", '&lt;\\1', $html);
} while ($html !== $old);
$html = preg_replace_callback($comment, array($this, 'callbackUndoCommentSubst'), $html); // fix comments
} }
// preprocess html, essential for UTF-8 // preprocess html, essential for UTF-8
@@ -65,9 +72,6 @@ class HTMLPurifier_Lexer_DOMLex extends HTMLPurifier_Lexer
if ($config->get('Core.AllowParseManyTags') && defined('LIBXML_PARSEHUGE')) { if ($config->get('Core.AllowParseManyTags') && defined('LIBXML_PARSEHUGE')) {
$options |= LIBXML_PARSEHUGE; $options |= LIBXML_PARSEHUGE;
} }
if ($config->get('Core.RemoveBlanks') && defined('LIBXML_NOBLANKS')) {
$options |= LIBXML_NOBLANKS;
}
set_error_handler(array($this, 'muteErrorHandler')); set_error_handler(array($this, 'muteErrorHandler'));
// loadHTML() fails on PHP 5.3 when second parameter is given // loadHTML() fails on PHP 5.3 when second parameter is given
@@ -100,6 +104,7 @@ class HTMLPurifier_Lexer_DOMLex extends HTMLPurifier_Lexer
* To iterate is human, to recurse divine - L. Peter Deutsch * To iterate is human, to recurse divine - L. Peter Deutsch
* @param DOMNode $node DOMNode to be tokenized. * @param DOMNode $node DOMNode to be tokenized.
* @param HTMLPurifier_Token[] $tokens Array-list of already tokenized tokens. * @param HTMLPurifier_Token[] $tokens Array-list of already tokenized tokens.
* @return HTMLPurifier_Token of node appended to previously passed tokens.
*/ */
protected function tokenizeDOM($node, &$tokens, $config) protected function tokenizeDOM($node, &$tokens, $config)
{ {
@@ -281,7 +286,7 @@ class HTMLPurifier_Lexer_DOMLex extends HTMLPurifier_Lexer
*/ */
public function callbackUndoCommentSubst($matches) public function callbackUndoCommentSubst($matches)
{ {
return '<!--' . $this->undoCommentSubstr($matches[1]) . $matches[2]; return '<!--' . strtr($matches[1], array('&amp;' => '&', '&lt;' => '<')) . $matches[2];
} }
/** /**
@@ -292,25 +297,7 @@ class HTMLPurifier_Lexer_DOMLex extends HTMLPurifier_Lexer
*/ */
public function callbackArmorCommentEntities($matches) public function callbackArmorCommentEntities($matches)
{ {
return '<!--' . $this->armorEntities($matches[1]) . $matches[2]; return '<!--' . str_replace('&', '&amp;', $matches[1]) . $matches[2];
}
/**
* @param string $string
* @return string
*/
protected function armorEntities($string)
{
return str_replace('&', '&amp;', $string);
}
/**
* @param string $string
* @return string
*/
protected function undoCommentSubstr($string)
{
return strtr($string, array('&amp;' => '&', '&lt;' => '<'));
} }
/** /**
@@ -346,66 +333,6 @@ class HTMLPurifier_Lexer_DOMLex extends HTMLPurifier_Lexer
$ret .= '</body></html>'; $ret .= '</body></html>';
return $ret; return $ret;
} }
/**
* @param string $html
* @return string
*/
protected function aggressivelyFixLt($html)
{
$char = '[^a-z!\/]';
$html = $this->manipulateHtmlComments($html, array($this, 'armorEntities'));
do {
$old = $html;
$html = preg_replace("/<($char)/i", '&lt;\\1', $html);
} while ($html !== $old);
return $this->manipulateHtmlComments($html, array($this, 'undoCommentSubstr'));
}
/**
* Modify HTML comments in the given HTML content using a callback.
*
* @param string $html
* @param callable $callback
* @return string
*/
protected function manipulateHtmlComments($html, callable $callback)
{
$offset = 0;
$startTag = '<!--';
$endTag = '-->';
while (($startPos = strpos($html, $startTag, $offset)) !== false) {
$startPos += strlen($startTag); // Move past `<!--`
$endPos = strpos($html, $endTag, $startPos);
if ($endPos === false) {
// No matching ending comment tag found
break;
}
// Extract the original comment content
$commentContent = substr($html, $startPos, $endPos - $startPos);
// Apply the callback to the comment content
$newCommentContent = $callback($commentContent);
// Reconstruct the entire comment with the new content
$newComment = $startTag . $newCommentContent . $endTag;
// Replace the old comment in the HTML content with the new one
$html = substr($html, 0, $startPos - strlen($startTag)) .
$newComment .
substr($html, $endPos + strlen($endTag));
// Move offset to the end of the new comment for the next iteration
$offset = strpos($html, $newComment, $offset) + strlen($newComment);
}
return $html;
}
} }
// vim: et sw=4 sts=4 // vim: et sw=4 sts=4

View File

@@ -111,7 +111,7 @@ class HTMLPurifier_Lexer_DirectLex extends HTMLPurifier_Lexer
if ($synchronize_interval && // synchronization is on if ($synchronize_interval && // synchronization is on
$cursor > 0 && // cursor is further than zero $cursor > 0 && // cursor is further than zero
$loops % $synchronize_interval === 0) { // time to synchronize! $loops % $synchronize_interval === 0) { // time to synchronize!
$current_line = 1 + substr_count($html, $nl, 0, $cursor); $current_line = 1 + $this->substrCount($html, $nl, 0, $cursor);
} }
} }
@@ -139,7 +139,7 @@ class HTMLPurifier_Lexer_DirectLex extends HTMLPurifier_Lexer
); );
if ($maintain_line_numbers) { if ($maintain_line_numbers) {
$token->rawPosition($current_line, $current_col); $token->rawPosition($current_line, $current_col);
$current_line += substr_count($html, $nl, $cursor, $position_next_lt - $cursor); $current_line += $this->substrCount($html, $nl, $cursor, $position_next_lt - $cursor);
} }
$array[] = $token; $array[] = $token;
$cursor = $position_next_lt + 1; $cursor = $position_next_lt + 1;
@@ -214,7 +214,7 @@ class HTMLPurifier_Lexer_DirectLex extends HTMLPurifier_Lexer
); );
if ($maintain_line_numbers) { if ($maintain_line_numbers) {
$token->rawPosition($current_line, $current_col); $token->rawPosition($current_line, $current_col);
$current_line += substr_count($html, $nl, $cursor, $strlen_segment); $current_line += $this->substrCount($html, $nl, $cursor, $strlen_segment);
} }
$array[] = $token; $array[] = $token;
$cursor = $end ? $position_comment_end : $position_comment_end + 3; $cursor = $end ? $position_comment_end : $position_comment_end + 3;
@@ -229,7 +229,7 @@ class HTMLPurifier_Lexer_DirectLex extends HTMLPurifier_Lexer
$token = new HTMLPurifier_Token_End($type); $token = new HTMLPurifier_Token_End($type);
if ($maintain_line_numbers) { if ($maintain_line_numbers) {
$token->rawPosition($current_line, $current_col); $token->rawPosition($current_line, $current_col);
$current_line += substr_count($html, $nl, $cursor, $position_next_gt - $cursor); $current_line += $this->substrCount($html, $nl, $cursor, $position_next_gt - $cursor);
} }
$array[] = $token; $array[] = $token;
$inside_tag = false; $inside_tag = false;
@@ -248,7 +248,7 @@ class HTMLPurifier_Lexer_DirectLex extends HTMLPurifier_Lexer
$token = new HTMLPurifier_Token_Text('<'); $token = new HTMLPurifier_Token_Text('<');
if ($maintain_line_numbers) { if ($maintain_line_numbers) {
$token->rawPosition($current_line, $current_col); $token->rawPosition($current_line, $current_col);
$current_line += substr_count($html, $nl, $cursor, $position_next_gt - $cursor); $current_line += $this->substrCount($html, $nl, $cursor, $position_next_gt - $cursor);
} }
$array[] = $token; $array[] = $token;
$inside_tag = false; $inside_tag = false;
@@ -276,7 +276,7 @@ class HTMLPurifier_Lexer_DirectLex extends HTMLPurifier_Lexer
} }
if ($maintain_line_numbers) { if ($maintain_line_numbers) {
$token->rawPosition($current_line, $current_col); $token->rawPosition($current_line, $current_col);
$current_line += substr_count($html, $nl, $cursor, $position_next_gt - $cursor); $current_line += $this->substrCount($html, $nl, $cursor, $position_next_gt - $cursor);
} }
$array[] = $token; $array[] = $token;
$inside_tag = false; $inside_tag = false;
@@ -310,7 +310,7 @@ class HTMLPurifier_Lexer_DirectLex extends HTMLPurifier_Lexer
} }
if ($maintain_line_numbers) { if ($maintain_line_numbers) {
$token->rawPosition($current_line, $current_col); $token->rawPosition($current_line, $current_col);
$current_line += substr_count($html, $nl, $cursor, $position_next_gt - $cursor); $current_line += $this->substrCount($html, $nl, $cursor, $position_next_gt - $cursor);
} }
$array[] = $token; $array[] = $token;
$cursor = $position_next_gt + 1; $cursor = $position_next_gt + 1;
@@ -343,6 +343,28 @@ class HTMLPurifier_Lexer_DirectLex extends HTMLPurifier_Lexer
return $array; return $array;
} }
/**
* PHP 5.0.x compatible substr_count that implements offset and length
* @param string $haystack
* @param string $needle
* @param int $offset
* @param int $length
* @return int
*/
protected function substrCount($haystack, $needle, $offset, $length)
{
static $oldVersion;
if ($oldVersion === null) {
$oldVersion = version_compare(PHP_VERSION, '5.1', '<');
}
if ($oldVersion) {
$haystack = substr($haystack, $offset, $length);
return substr_count($haystack, $needle);
} else {
return substr_count($haystack, $needle, $offset, $length);
}
}
/** /**
* Takes the inside of an HTML tag and makes an assoc array of attributes. * Takes the inside of an HTML tag and makes an assoc array of attributes.
* *

View File

@@ -1223,14 +1223,14 @@ class HTML5
'type' => self::COMMENT 'type' => self::COMMENT
); );
/* Otherwise if the next seven characters are a case-insensitive match /* Otherwise if the next seven chacacters are a case-insensitive match
for the word "DOCTYPE", then consume those characters and switch to the for the word "DOCTYPE", then consume those characters and switch to the
DOCTYPE state. */ DOCTYPE state. */
} elseif (strtolower($this->character($this->char + 1, 7)) === 'doctype') { } elseif (strtolower($this->character($this->char + 1, 7)) === 'doctype') {
$this->char += 7; $this->char += 7;
$this->state = 'doctype'; $this->state = 'doctype';
/* Otherwise, it is a parse error. Switch to the bogus comment state. /* Otherwise, is is a parse error. Switch to the bogus comment state.
The next character that is consumed, if any, is the first character The next character that is consumed, if any, is the first character
that will be in the comment. */ that will be in the comment. */
} else { } else {

View File

@@ -32,11 +32,6 @@ class HTMLPurifier_Printer_ConfigForm extends HTMLPurifier_Printer
*/ */
protected $compress = false; protected $compress = false;
/**
* @var HTMLPurifier_Config
*/
protected $genConfig;
/** /**
* @param string $name Form element name for directives to be stuffed into * @param string $name Form element name for directives to be stuffed into
* @param string $doc_url String documentation URL, will have fragment tagged on * @param string $doc_url String documentation URL, will have fragment tagged on

View File

@@ -20,7 +20,7 @@
* The second objective is to ensure that explicitly excluded elements of * The second objective is to ensure that explicitly excluded elements of
* an element do not appear in its children. Code that accomplishes this * an element do not appear in its children. Code that accomplishes this
* task is pervasive through the strategy, though the two are distinct tasks * task is pervasive through the strategy, though the two are distinct tasks
* and could, theoretically, be separated (although it's not recommended). * and could, theoretically, be seperated (although it's not recommended).
* *
* @note Whether or not unrecognized children are silently dropped or * @note Whether or not unrecognized children are silently dropped or
* translated into text depends on the child definitions. * translated into text depends on the child definitions.

View File

@@ -641,7 +641,7 @@ class HTMLPurifier_Strategy_MakeWellFormed extends HTMLPurifier_Strategy
// Needless to say, we need to UN-skip the token so it gets // Needless to say, we need to UN-skip the token so it gets
// reprocessed. // reprocessed.
// //
// - Suppose that you successfully process a token, replace it with // - Suppose that you successfuly process a token, replace it with
// one with your skip mark, but now another injector wants to // one with your skip mark, but now another injector wants to
// process the skipped token with another token. Should you continue // process the skipped token with another token. Should you continue
// to skip that new token, or reprocess it? If you reprocess, // to skip that new token, or reprocess it? If you reprocess,

View File

@@ -44,7 +44,7 @@ abstract class HTMLPurifier_Token_Tag extends HTMLPurifier_Token
$this->name = ctype_lower($name) ? $name : strtolower($name); $this->name = ctype_lower($name) ? $name : strtolower($name);
foreach ($attr as $key => $value) { foreach ($attr as $key => $value) {
// normalization only necessary when key is not lowercase // normalization only necessary when key is not lowercase
if (!ctype_lower((string)$key)) { if (!ctype_lower($key)) {
$new_key = strtolower($key); $new_key = strtolower($key);
if (!isset($attr[$new_key])) { if (!isset($attr[$new_key])) {
$attr[$new_key] = $attr[$key]; $attr[$new_key] = $attr[$key];

Some files were not shown because too many files have changed in this diff Show More