PSL 6.4.0
This release fixes 12 security vulnerabilities, adds Vec\intersect(), supports PHP 8.6, and fixes more than 240 bugs across the library. Upgrading is strongly recommended.
Security
DNSSEC:SecureResolverandTrustChainResolvervalidate every answer, alias, delegation and denial-proof RRset against the keys of its own zone, so forged or unsigned DNS data no longer passes as validated. (GHSA-pqp4-hj5q-h473)MIME\SMIME\Verifier: Verifies the signer certificate against explicit trust anchors, checking its chain, validity, purpose and CA constraints, so a signature made with an unknown self-signed certificate no longer verifies. An empty trust list now fails verification. (GHSA-7h2c-65cx-p93w)TCPandTLS: Connections accepted on one listener no longer share TLS context state, which could report another client's certificate or apply the client certificate trust settings of an earlier configuration. With ext-sockets, whichtcpnow suggests, each accepted connection gets its own context. (GHSA-3vrh-x3c6-5h36)TLS\Listener: Runs handshakes concurrently, each with its own deadline (10 seconds by default,$handshakeTimeout), up to$maxPendingHandshakes(256 by default) at a time, so a client that connects and sends nothing can no longer block the listener. (GHSA-7fr9-xww6-mfp3)HTTP\Client: Keys pooled connections by their TLS, SNI, proxy, SOCKS, Unix socket and protocol settings as well as the origin, so a request no longer reuses a connection opened with different TLS or proxy settings. (GHSA-6q49-9m5c-9xgg)HTTP\ClientSSRF preset:DeniedDestinationsMiddleware::forPrivateNetworkRanges()now covers the special-purpose ranges it missed, such as100.64.0.0/10, and matches IPv4-mapped IPv6 peers. (GHSA-xpwf-27h9-7jjj)MessageandMIMEheader injection: Constructed header fields, mailboxes, message ids and MIME parameters reject CR, LF and NUL, andMultiPart\Formpercent-encodes them in field names. (GHSA-j84h-7gw3-w75x)MessageBcc disclosure:serialize()no longer writes theBccandResent-Bccfields, which exposed blind recipients to every recipient. (GHSA-rj6q-j8xp-7532)H2denial of service: Checks every frame againstSETTINGS_MAX_FRAME_SIZEbefore reading its payload, bounds received header blocks and decoded field sections by default (64 KiB), and gives every connection its own rate limiter state. (GHSA-37xv-5qfq-7qxc)MIMEmultipart denial of service: Skips the preamble in constant memory and bounds each part header section ($maxHeaderSize, 16 KiB by default). (GHSA-h47r-xw6c-xwwm)Filesystem\create_temporary_file(): Creates files exclusively and with0600permissions, so other local users can no longer read or plant them. (GHSA-q8cp-xq93-r9jr)SMTP: Refuses to send withrequireTlsunless the connection uses TLS and the server advertisesREQUIRETLS, instead of silently sending without it. (GHSA-gmcv-xvgq-xjqg)
Further hardening without an advisory:
DNS: Rejects a response whose question does not match the query, and checks the UDP transaction ID before parsing any record.HTTP\Client: Validates requests before writing them, hardens and bounds HTTP/1 response parsing, and enforcesmaxResponseBodySizeon HTTP/2 responses.H2: Rejects received field names and values with invalid characters.TCP\SocketPool: Tracks checked-out connections by object instead of by reusable object ID, so a connection can no longer be pooled under another peer's host and port.
Features
Vec\intersect(): Returns the values of the first iterable that are present in every other iterable, as a list. Values are compared by their string representation, likeDict\intersect(). (by @shadowhand in #812)
use Psl\Vec;
Vec\intersect([1, 2, 3, 4], [2, 4, 6], [4, 2]); // [2, 4]Fixes
This release contains more than 240 bug fixes. The highlights are below; CHANGELOG.md lists every one.
H2andHPACK: A stream error resets only the affected stream instead of closing the connection. Flow control counts DATA padding, outbound DATA respects the peer's maximum frame size, SETTINGS apply in wire order, and local settings changes take effect once acknowledged. HPACK tables stay within the negotiated limits.HTTP\Client: HTTP/2 requests are retried only when that is safe. Redirects rewind or resend bodies correctly and resolveLocationwith RFC 3986 rules. HTTP/2 concurrency respects the server's stream limit, cancellation is honoured at every wait, the100 Continuewait is bounded ($expectContinueTimeout), and theRetryClientbackoff is clamped.IO: Large writes run in linear time. Stream handles make one native read per call and report a connection reset as an error instead of a clean end of data.Readerkeeps its buffered bytes at the end of the data and when a read is interrupted or cancelled, and unreferenced stream handles are closed.DateTime:FormatPattern::UnixTimestamp,JulianDay,HttpandCookieproduce correct values, and parsing keeps milliseconds. Date fields use the Gregorian calendar whatever the default locale, day, week and month arithmetic is safe across DST changes, and timezone aliases resolve instead of falling back to UTC.Async:SemaphoreandKeyedSemaphorenever run more operations than their limit, and admit them first in, first out.all(),any()andfirst()accept generators, and cancellation tokens call every subscribed callback even when one throws.TLS,TCP,Network,UDPandUnix: A short TLS write no longer corrupts the byte stream, and peer fingerprints are checked after the handshake. A failed asynchronous connect throws, IPv6 hosts are stored without brackets, every networking wait settles exactly once, and unreferenced listeners and streams are closed.DNSandDNSSEC:CachedResolverhonours record lifetimes and caches failures briefly, as RFC 9520 requires.UDPResolversupports IPv6 nameservers,FallbackResolverstops at NXDOMAIN, and both IANA root keys, KSK-2017 and KSK-2024, are trusted (by @loganaden in #809).MIMEandMessage: Signatures made byDKIM\Signernow verify. Multipart boundaries are only recognized at the start of a line, andmaxPartsis enforced as soon as another part starts.SMTP: Checks SMTPUTF8 support before sending non-ASCII addresses or headers, encodes non-ASCII domains as A-labels, throwsConnectionExceptioninstead of leaking IO exceptions, and passes the cancellation token to STARTTLS.Encoding: The streaming Base64, Hex and QuotedPrintable handles produce exactly what their one-shot functions do, and RFC 2047 encoded words are split and decoded correctly.Type\class_string(): Accepts interface names when no class is given. (by @shadowhand in #813)Vec\unique_scalar()andDict\unique_scalar(): Compare values by strict identity, so1,'1',1.0andtrueare distinct.- Also fixed:
Ansi,Cache,Channel,CIDR,Collection,Compression,Crypto,Dict,Env,File,Filesystem,Graph,HTML,IP,Iter,Math,Password,Process,Range,SOCKS,Str,TerminalandURI.
Deprecations
Str\metaphone(): Deprecated, because the underlying PHP function is deprecated as of PHP 8.6. Use a userland phonetic matching library instead. (by @simPod in #811)
Other
- Dependencies: Every PSL package now requires
^6.4of the PSL packages it depends on that changed in this release, so updating any package also brings in the bug and security fixes of its PSL dependencies.
Known issue
HTTP\Client: The first requests to some HTTP/2 servers, such asapi.github.com, can fail with "HTTP/2 connection is closed." A fix will follow in 6.4.1.
Install: composer require php-standard-library/php-standard-library:^6.4
New Contributors
- @loganaden made their first contribution in #809
- @shadowhand made their first contribution in #812
Full Changelog: 6.3.0...6.4.0