Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ PHP NEWS
correctly, and external writes raise "Cannot modify private(set)
property" instead of the previous readonly modification error.
(David Carlier)
. Fixed Dom\Notation nodes missing tree connection, so that
ownerDocument, parentNode, isConnected and baseURI now return correct
values, and textContent returns NULL per the DOM specification.
(jordikroon)

- Fileinfo:
. Fixed bug GH-20679 (finfo_file() doesn't work on remote resources).
Expand Down Expand Up @@ -88,6 +92,7 @@ PHP NEWS
preloading). (Arnaud, welcomycozyhom)

- OpenSSL:
. Added AES-SIV support. (jordikroon)
. Implemented GH-20310 (No critical extension indication in
openssl_x509_parse() output). (StephenWall)

Expand Down
15 changes: 14 additions & 1 deletion ext/dom/dom_iterators.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,18 +54,31 @@ static dom_nnodemap_object *php_dom_iterator_get_nnmap(const php_dom_iterator *i
return nnmap->ptr;
}

xmlNodePtr create_notation(const xmlChar *name, const xmlChar *ExternalID, const xmlChar *SystemID) /* {{{ */
xmlNodePtr create_notation(xmlDtdPtr parent_dtd, const xmlChar *name, const xmlChar *ExternalID, const xmlChar *SystemID) /* {{{ */
{
xmlEntityPtr ret = xmlMalloc(sizeof(xmlEntity));
memset(ret, 0, sizeof(xmlEntity));
ret->type = XML_NOTATION_NODE;
ret->name = xmlStrdup(name);
ret->ExternalID = xmlStrdup(ExternalID);
ret->SystemID = xmlStrdup(SystemID);
if (parent_dtd != NULL) {
ret->parent = parent_dtd;
ret->doc = parent_dtd->doc;
}
return (xmlNodePtr) ret;
}
/* }}} */

void dom_free_notation(xmlEntityPtr entity) /* {{{ */
{
xmlFree((xmlChar *) entity->name);
xmlFree((xmlChar *) entity->ExternalID);
xmlFree((xmlChar *) entity->SystemID);
xmlFree(entity);
}
/* }}} */

xmlNodePtr php_dom_libxml_hash_iter(xmlHashTable *ht, int index)
{
int htsize;
Expand Down
6 changes: 4 additions & 2 deletions ext/dom/obj_map.c
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,8 @@ static void dom_map_get_notation_item(dom_nnodemap_object *map, zend_long index,
xmlNodePtr node = map->ht ? php_dom_libxml_hash_iter(map->ht, index) : NULL;
if (node) {
xmlNotation *notation = (xmlNotation *) node;
node = create_notation(notation->name, notation->PublicID, notation->SystemID);
xmlDtdPtr dtd = (xmlDtdPtr) dom_object_get_node(map->baseobj);
node = create_notation(dtd, notation->name, notation->PublicID, notation->SystemID);
}
dom_ret_node_to_zobj(map, node, return_value);
}
Expand Down Expand Up @@ -504,7 +505,8 @@ static xmlNodePtr dom_map_get_ns_named_item_notation(dom_nnodemap_object *map, c
{
xmlNotationPtr notation = xmlHashLookup(map->ht, BAD_CAST ZSTR_VAL(named));
if (notation) {
return create_notation(notation->name, notation->PublicID, notation->SystemID);
xmlDtdPtr dtd = (xmlDtdPtr) dom_object_get_node(map->baseobj);
return create_notation(dtd, notation->name, notation->PublicID, notation->SystemID);
}
return NULL;
}
Expand Down
8 changes: 7 additions & 1 deletion ext/dom/php_dom.c
Original file line number Diff line number Diff line change
Expand Up @@ -1486,7 +1486,13 @@ void dom_objects_free_storage(zend_object *object)
if (ptr != NULL && ptr->node != NULL) {
xmlNodePtr node = ptr->node;

if (node->type != XML_DOCUMENT_NODE && node->type != XML_HTML_DOCUMENT_NODE) {
if (node->type == XML_NOTATION_NODE) {
unsigned int refcount = php_libxml_decrement_node_ptr((php_libxml_node_object *) intern);
php_libxml_decrement_doc_ref((php_libxml_node_object *) intern);
if (refcount == 0) {
dom_free_notation((xmlEntityPtr) node);
}
} else if (node->type != XML_DOCUMENT_NODE && node->type != XML_HTML_DOCUMENT_NODE) {
php_libxml_node_decrement_resource((php_libxml_node_object *) intern);
} else {
php_libxml_decrement_node_ptr((php_libxml_node_object *) intern);
Expand Down
3 changes: 2 additions & 1 deletion ext/dom/php_dom.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,8 @@ int dom_hierarchy(xmlNodePtr parent, xmlNodePtr child);
bool dom_has_feature(zend_string *feature, zend_string *version);
bool dom_node_is_read_only(const xmlNode *node);
bool dom_node_children_valid(const xmlNode *node);
xmlNodePtr create_notation(const xmlChar *name, const xmlChar *ExternalID, const xmlChar *SystemID);
xmlNodePtr create_notation(xmlDtdPtr parent_dtd, const xmlChar *name, const xmlChar *ExternalID, const xmlChar *SystemID);
void dom_free_notation(xmlEntityPtr entity);
xmlNode *php_dom_libxml_hash_iter(xmlHashTable *ht, int index);
zend_object_iterator *php_dom_get_iterator(zend_class_entry *ce, zval *object, int by_ref);
void dom_set_doc_classmap(php_libxml_ref_obj *document, zend_class_entry *basece, zend_class_entry *ce);
Expand Down
13 changes: 7 additions & 6 deletions ext/dom/tests/modern/xml/DTDNamedNodeMap.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ var_dump($doctype);

var_dump($doctype->entities["test"]);
var_dump($doctype->entities["myimage"]);
// TODO: isConnected returning false is a bug
var_dump($doctype->notations["GIF"]);

?>
Expand Down Expand Up @@ -142,17 +141,19 @@ object(Dom\Entity)#3 (17) {
["textContent"]=>
NULL
}
object(Dom\Notation)#4 (13) {
object(Dom\Notation)#4 (14) {
["nodeType"]=>
int(12)
["nodeName"]=>
string(3) "GIF"
["baseURI"]=>
string(11) "about:blank"
string(%d) "%s"
["isConnected"]=>
bool(false)
bool(true)
["ownerDocument"]=>
string(22) "(object value omitted)"
["parentNode"]=>
NULL
string(22) "(object value omitted)"
["parentElement"]=>
NULL
["childNodes"]=>
Expand All @@ -168,5 +169,5 @@ object(Dom\Notation)#4 (13) {
["nodeValue"]=>
NULL
["textContent"]=>
string(0) ""
NULL
}
101 changes: 101 additions & 0 deletions ext/dom/tests/modern/xml/XMLDocument_node_notation_wiring.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
--TEST--
Dom\XMLDocument: Dom\Notation nodes are connected to their document and doctype
--EXTENSIONS--
dom
--FILE--
<?php
$cases = [
'GIF' => '<!NOTATION GIF SYSTEM "image/gif">',
'JPEG' => '<!NOTATION JPEG PUBLIC "-//W3C//NOTATION JPEG//EN" "image/jpeg">',
'HTML' => '<!NOTATION HTML PUBLIC "-//W3C//NOTATION HTML//EN">',
];

foreach ($cases as $name => $declaration) {
$xml = <<<XML
<!DOCTYPE root [
$declaration
]>
<root/>
XML;

$dom = Dom\XMLDocument::createFromString($xml);
$doctype = $dom->doctype;
$notations = $doctype->notations;

echo "=== $name ===\n";

$namedNotation = $notations->getNamedItem($name);
foreach ($notations as $iteratedNotation) {
// getNamedItem
var_dump($namedNotation->nodeName);
var_dump($namedNotation->textContent);
var_dump($namedNotation->nodeValue);
var_dump($namedNotation->isConnected);
var_dump($namedNotation->ownerDocument === $dom);
var_dump($namedNotation->parentNode === $doctype);
var_dump($namedNotation->parentElement);

// iteration
var_dump($iteratedNotation->nodeName);
var_dump($iteratedNotation->textContent);
var_dump($iteratedNotation->nodeValue);
var_dump($iteratedNotation->isConnected);
var_dump($iteratedNotation->ownerDocument === $dom);
var_dump($iteratedNotation->parentNode === $doctype);
var_dump($iteratedNotation->parentElement);

// wiring
// getNamedItem and iteration each allocate a fresh Notation instance
var_dump($namedNotation !== $iteratedNotation);
}
}
?>
--EXPECT--
=== GIF ===
string(3) "GIF"
NULL
NULL
bool(true)
bool(true)
bool(true)
NULL
string(3) "GIF"
NULL
NULL
bool(true)
bool(true)
bool(true)
NULL
bool(true)
=== JPEG ===
string(4) "JPEG"
NULL
NULL
bool(true)
bool(true)
bool(true)
NULL
string(4) "JPEG"
NULL
NULL
bool(true)
bool(true)
bool(true)
NULL
bool(true)
=== HTML ===
string(4) "HTML"
NULL
NULL
bool(true)
bool(true)
bool(true)
NULL
string(4) "HTML"
NULL
NULL
bool(true)
bool(true)
bool(true)
NULL
bool(true)
4 changes: 2 additions & 2 deletions ext/openssl/openssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -4571,7 +4571,7 @@ PHP_FUNCTION(openssl_encrypt)
zend_string *ret;
zval *tag = NULL;

if (zend_parse_parameters(ZEND_NUM_ARGS(), "sss|lszsl", &data, &data_len, &method, &method_len,
if (zend_parse_parameters(ZEND_NUM_ARGS(), "sss|lszs!l", &data, &data_len, &method, &method_len,
&password, &password_len, &options, &iv, &iv_len, &tag, &aad, &aad_len, &tag_len) == FAILURE) {
RETURN_THROWS();
}
Expand All @@ -4593,7 +4593,7 @@ PHP_FUNCTION(openssl_decrypt)
size_t data_len, method_len, password_len, iv_len = 0, tag_len = 0, aad_len = 0;
zend_string *ret;

if (zend_parse_parameters(ZEND_NUM_ARGS(), "sss|lss!s", &data, &data_len, &method, &method_len,
if (zend_parse_parameters(ZEND_NUM_ARGS(), "sss|lss!s!", &data, &data_len, &method, &method_len,
&password, &password_len, &options, &iv, &iv_len, &tag, &tag_len, &aad, &aad_len) == FAILURE) {
RETURN_THROWS();
}
Expand Down
4 changes: 2 additions & 2 deletions ext/openssl/openssl.stub.php
Original file line number Diff line number Diff line change
Expand Up @@ -662,9 +662,9 @@ function openssl_digest(string $data, string $digest_algo, bool $binary = false)
/**
* @param string $tag
*/
function openssl_encrypt(#[\SensitiveParameter] string $data, string $cipher_algo, #[\SensitiveParameter] string $passphrase, int $options = 0, string $iv = "", &$tag = null, string $aad = "", int $tag_length = 16): string|false {}
function openssl_encrypt(#[\SensitiveParameter] string $data, string $cipher_algo, #[\SensitiveParameter] string $passphrase, int $options = 0, string $iv = "", &$tag = null, ?string $aad = "", int $tag_length = 16): string|false {}

function openssl_decrypt(string $data, string $cipher_algo, #[\SensitiveParameter] string $passphrase, int $options = 0, string $iv = "", ?string $tag = null, string $aad = ""): string|false {}
function openssl_decrypt(string $data, string $cipher_algo, #[\SensitiveParameter] string $passphrase, int $options = 0, string $iv = "", ?string $tag = null, ?string $aad = ""): string|false {}

function openssl_cipher_iv_length(string $cipher_algo): int|false {}

Expand Down
6 changes: 3 additions & 3 deletions ext/openssl/openssl_arginfo.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 15 additions & 2 deletions ext/openssl/openssl_backend_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -1650,10 +1650,14 @@ void php_openssl_load_cipher_mode(struct php_openssl_cipher_mode *mode, const EV
{
int cipher_mode = EVP_CIPHER_mode(cipher_type);
memset(mode, 0, sizeof(struct php_openssl_cipher_mode));

switch (cipher_mode) {
case EVP_CIPH_GCM_MODE:
case EVP_CIPH_CCM_MODE:
/* We check for EVP_CIPH_OCB_MODE, because LibreSSL does not support it. */
/* We check for EVP_CIPH_SIV_MODE and EVP_CIPH_SIV_MODE, because LibreSSL does not support it. */
#ifdef EVP_CIPH_SIV_MODE
case EVP_CIPH_SIV_MODE:
#endif
#ifdef EVP_CIPH_OCB_MODE
case EVP_CIPH_OCB_MODE:
/* For OCB mode, explicitly set the tag length even when decrypting,
Expand All @@ -1663,6 +1667,7 @@ void php_openssl_load_cipher_mode(struct php_openssl_cipher_mode *mode, const EV
php_openssl_set_aead_flags(mode);
mode->set_tag_length_when_encrypting = cipher_mode == EVP_CIPH_CCM_MODE;
mode->is_single_run_aead = cipher_mode == EVP_CIPH_CCM_MODE;
mode->aad_supports_vector = cipher_mode == EVP_CIPH_SIV_MODE;
break;
#ifdef NID_chacha20_poly1305
default:
Expand Down Expand Up @@ -1804,13 +1809,21 @@ zend_result php_openssl_cipher_update(const EVP_CIPHER *cipher_type,
{
int i = 0;

/* For AEAD modes that do not support vector AAD, treat NULL AAD as zero-length AAD */
if (!mode->aad_supports_vector && aad == NULL) {
aad_len = 0;
aad = "";
}

if (mode->is_single_run_aead && !EVP_CipherUpdate(cipher_ctx, NULL, &i, NULL, (int)data_len)) {
php_openssl_store_errors();
php_error_docref(NULL, E_WARNING, "Setting of data length failed");
return FAILURE;
}

if (mode->is_aead && !EVP_CipherUpdate(cipher_ctx, NULL, &i, (const unsigned char *) aad, (int) aad_len)) {
/* Only pass AAD to OpenSSL if caller provided it.
This makes NULL mean zero AAD items, while "" with len 0 means one empty AAD item. */
if (mode->is_aead && aad != NULL && !EVP_CipherUpdate(cipher_ctx, NULL, &i, (const unsigned char *)aad, (int)aad_len)) {
php_openssl_store_errors();
php_error_docref(NULL, E_WARNING, "Setting of additional application data failed");
return FAILURE;
Expand Down
1 change: 1 addition & 0 deletions ext/openssl/php_openssl_backend.h
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,7 @@ struct php_openssl_cipher_mode {
bool is_single_run_aead;
bool set_tag_length_always;
bool set_tag_length_when_encrypting;
bool aad_supports_vector;
int aead_get_tag_flag;
int aead_set_tag_flag;
int aead_ivlen_flag;
Expand Down
Loading
Loading