TLK: OpenSSL integration
TLK: Commitments
TLK: About bug #36008
TLK: PHP security - the article
TLK: PHP security - the accusations
TLK: PHP security - the fallout
TLK: PHP security - the Java solution
TLK: PHP security - prepared statements
TLK: PHP security - a secure query builder?
TLK: PHP security - more exploits, please
TLK: PHP security - remote URL includes
NEW: CVS server change
CVS: Lots of 5_2-only and Engine fixes
PAT: Everything applied

TLK: OpenSSL integration

One Thomas Hruska wrote to internals@ at the start of the week. He intended to access around twenty of 'the more obscure OpenSSL functions' from within PHP, and would like to contribute his code to the PHP community. He had already started researching the ext/openssl source code in PHP 5.2.0, but expected to need 'some hand holding' in areas such as CVS, patch creation and building PHP under Windows. Thomas is an experienced C/C++ programmer, but will need guidance when it comes to PHP-specific functions and macros. He added that he'd be happy to document as he went along, possibly not recognizing this as a pledge to write the entire manual.

Marcus Börger pointed him to the README.* files and CODING_STANDARDS in the top-level source directory, and also gave links to the resources available for new extension authors - his own slides and Sara Golemon's articles and useful book. He wrote that, as PHP 5.2.0 is already out there, Thomas should either develop for CVS HEAD or hope for a future PHP 5.3 series. That aside, he welcomed Thomas' efforts.

Wez Furlong wrote to make Thomas aware of his work on 'DH kex and some bignum functions', and to say that Pierre-Alain Joye also has some ext/openssl work pending. To avoid duplication of effort, Wez suggested that he and Pierre should either push their code out into the light of day, or pass it to Thomas directly. He also offered Thomas support over the existing extension code, explaining that he had been responsible for much of it. Pierre clarified his own position; he'd been working on a new API, and had a 'toy example' on his hard drive that implements the BN API as objects. That said, ext/openssl was ported to PECL a few weeks ago precisely to allow development outside the PHP tree, and Pierre saw no reason not to integrate Thomas' work there. He asked about Thomas' plans, with the idea of putting some kind of roadmap together. Thomas was fairly certain there would be no overlap; his areas of interest are BIO, PKCS#7 and EVP.

Short version: We're all expecting good things for OpenSSL in the near future.

TLK: Commitments

Andrei Zmievski wrote to the list in the hope of finding out what had happened about the JIT/input encoding work Pierre had promised a few weeks back, by now holding up the preview release of PHP 6.0. Andrei hoped Pierre would see his message and respond to it in the next day or so, but if not, someone else would need to step in and do the work. A furious Pierre wrote back immediately, saying that the decision had only been settled one day before the Christmas holidays and a PHP 6.0 preview release was not the top priority at present anyhow. He saw Andrei's pushing him so hard as counter-productive, and ended plaintively that it was 2.20am in his timezone, he'd just spent an hour working on a bug in a stable and existing PHP branch, and he needed some rest.

Andrei, who doesn't live anywhere near Europe, doesn't consider December 18th as 'one day before the Christmas holidays', and said so. He added that, far from picking on Pierre in particular, he'd also been bugging Wez and Marcus - two more very busy people - for their promised work in CVS HEAD. The difference was that PDO and SPL are not an integral part of PHP, whereas request decoding most definitely is, and Pierre had made a commitment to deliver it. Andrei wrote at some length about responsibilities and the necessity of deadlines in open source, explaining he was 'bummed' over missing the Christmas preview release deadline. All he really wanted to know was whether Pierre still intended working on the promised functionality? If so, he would like to know when to expect delivery; and if not, he'd simply like to thank Pierre for his contributions to date and find someone else to take it over.

Short version: Stand off.

TLK: About bug #36008

Tom Sommer wrote to internals@ asking for news about bug #36008 (incorrect round() & number_format() result). Had it been fixed? After all, it was pretty nasty for those running financially critical applications...

Rasmus Lerdorf took a look to see whether the bug should be marked critical, and came back explaining that this isn't actually something the PHP development team can do anything about:

Floating point values need to be sanitized before you do any sort of
calculation with them or you will be magnifying any system-level
imprecision. In that example he sanitized it by converting it to a
string which isn't magic, it is just another way to truncate the
imprecision. Any decent accounting/financial application should be
working in integers (as in cents) and should never run into these issues.

There is nothing we can do to fix this.

Short version: User education is paramount. Hopefully, some are reading this.

TLK: PHP security - the article

PHP user Alain Williams brought everyone's attention to an article in The Register addressing PHP security concerns, and we all duly went away to read it.

Rasmus was the first to respond publicly. He wrote that some of the concrete suggestions in the article - such as defaulting to allow only local file inclusions, and forcing input to be filtered and output escaped - had already been addressed in PHP 5.2.0. There is already a global way for a script to ignore variables in a URL, too; simply remove G from the variables_order setting. Rasmus agreed with the author that the development team could and should do more to help PHP users write safe applications. However, balancing that requirement with the ease of use that attracts people to PHP in the first place, while retaining support for the existing code base, poses an interesting challenge.

Rasmus also wrote about remote versus local issues, claiming that most reported security problems with PHP are of the local variety. He saw this as a flaw in the various attempts to separate users in a shared hosting environment - something he's mentioned before now - since it's not possible to achieve 100% security against other users on the same server. Moreover, 'it is very hard to protect the user from himself without completely crippling the language and the various attempts we have made over the years like safe_mode and open_basedir can never be fully secure'. That said, he saw open_basedir as a useful security layer when used alongside something like mod_security and the filter extension in a layered security model, and gave some examples of this in action. He hoped this would explain some of the current thinking about security in PHP. Rasmus concluded that he actually doesn't believe things are as bad as they're perceived to be, 'but it is all about perception, so if they think it is bad, it is bad'. Combatting that perception would be largely a matter of documentation.

Short version: It's not that bad...

TLK: PHP security - the accusations

PHP security expert Stefan Esser wasn't prepared to let Rasmus or the team off so easily as all that. He argued that the use of data:// or php:// input URLs easily bypasses the protection in PHP 5.2.0, and overlong URLs passed to a 'safe' URL wrapper, such as zip://, can still produce a stack overflow there. As for Rasmus' contention that PHP security issues tend to be local, how about the htmlentities() overflow, the bugs in unserialize(), and the fileupload() and memory_limit exploits? What about last year's zend_hash_del_key_or_index() remote vulnerability? What about the HTTP Digest Auth double-free vulnerability he'd fixed in the past? There are more than enough local holes, but it was 'a blatant lie' to suggest there were no remote ones. Looking through Rasmus' suggestions for the way a layered security model should work, Stefan grumbled that ext/filter isn't exactly bug free at this stage and suggested Rasmus should stop the marketing speak and 'face reality'.

Alain wrote that the real problem is that many PHP users don't have a wealth of experience behind them; they need help. Fellow user Mark Krenz used the moment to attack every developer who'd ever said 'safe mode sucks', since it was clearly the only way to get around 'certain situations'. Ilia Alshanetsky promptly repeated it. Alain mentioned his recent obsession with the need for declared variables, as in perl's use strict, but Rasmus was swift to dismiss that particular feature request; he didn't see how catching typos on variable assignment could possibly impact security. Alain, who teaches both PHP and perl, wrote that common newbie errors peculiar to PHP include forgetting to declare variables as global within a function. Christian Schneider pointed out that the need for global declarations should arise once in a blue moon, and 'it should be painful and done with $GLOBALS' anyway. He recommended E_NOTICE as a way to disclose undefined variables. Alain argued that E_NOTICE only tells you a variable is undefined when you access it - not at the point of assignment. It became clear in a later exchange with Ilia that Alain felt the purpose of the entire thread was to find new ways for PHP to help newbies discover problems in their scripts. Derick Rethans mentioned testing and code coverage as interesting concepts that should probably be taught in class. Alain, arguing that newbies don't see the need for either, replied that the point was to help 'the sort of person who would not come near this mail list'. Ilia retorted that this mailing list exists for internals discussions; discussions about PHP tools for PHP code don't have a place on it.

Short version: OK, so it's terrible.

TLK: PHP security - the fallout

Rasmus rolled up his sleeves and went in to tackle Stefan's accusations. The URL wrapper issues have been fixed; Rasmus didn't promise they were now bug-free, but those particular bugs don't exist in PHP 5.2.0. The majority of reported security bugs in PHP are local, and are fixed as soon as they possibly can be; Rasmus added that he fully appreciates Stefan's help in discovering them. And he hadn't been attempting to market anything - just explain what the team are doing to make PHP more secure.

Pierre-Alain Joye was worried by the mention of zip:// earlier. He pointed out that the extension isn't actually enabled by default, but if Stefan knew of a problem in the URL wrapper he'd very much like to know about it please. Stefan argued that ext/zip quite often is enabled by default in PHP distributions, and added that he'd disclosed more than thirty vulnerabilities to security@ over the past three weeks alone. Pierre explained that he doesn't have access to security@; the first time he knows about security issues in his extensions is when someone from the security team quietly commits code there. Besides, he'd asked Stefan several times for a review of ext/zip prior to the stable release... Ilia and Rasmus put Pierre out of his misery; it seems only the 'long path' flaw had existed in the currently active extension in the first place, and this had indeed been fixed promptly. Pierre seized the moment to recommend that package maintainers should distribute the active zip extension - which is available in PECL and is fully back compatible - rather than the old, unmaintained version.

Stas Malyshev was hooked on the accusation over marketing. Did Stefan believe that PHP Group should publish a press release saying, 'PHP is not secure, please do not use it any more'? To his knowledge, there had been just seven remotely exploitable issues in PHP in the last year, and there are none in the current version. What should be improved? And as for facing reality - 'what in your opinion the reality is and what would you have PHP group to do to satisfy you on facing reality account?' Stefan refuted the idea that PHP Group do anything, either to improve security or to prevent license abuse by 'their friends'. When it comes to security patches, he claimed, Ilia alone looks after the PHP code base and Dmitry Stogov takes care of Zend. Stefan asked if Stas needed reminding about a buffer allocation bug in the Zend Memory Manager, or a heap underflow bug in ext/filter. Weren't these remote exploits? Stas retorted that it would be obvious to anyone accessing the commit logs that Stefan's allegations against PHP Group were simply untrue. He added that he obviously does need reminding, if there really is an unfixed bug in the Zend MM, since he believes they've all been addressed; ditto the underflow bug. It would be preferable, though, if Stefan could do any reminding through security@ rather than on a public list.

Short version: It's great when Stas goes Russian on us :-)

TLK: PHP security - the Java solution

Andi Gutmans wondered aloud whether any language provides for secure shared hosting without using a setuid or chroot solution? He believed PHP's problems are made worse by shared hosts failing to deploy PHP securely, and had plans for 'best practices' documentation to allay that side of things. PHP already has ext/filter; the team already use Coverity, and plan to extend automated code checking; register_globals and safe_mode are gone completely in PHP 6; the team have worked on PHP's security issues alongside IBM Research, leading to Wietse Venema's recent taint proposal...

Someone named Paweł Stradomski mentioned in passing that actually Java does provide for secure shared hosting, and cited the ability to declare privileges for the code based on its filesystem location. Stas was fairly certain this couldn't cover JNI modules - the Java equivalent of PHP extensions. Mathieu Carbonneaux explained that most Java applications don't use any JNI modules for precisely that reason. There were none in his own Java shared hosts. In his PHP shared hosts, he uses Stefan's hardening patch, mod_chroot, mod_security as reverse proxy in front and a single Apache instance with uid by application. On the subject of security, though, there were some good ideas floating around - for example, the use of prepared statements to avoid SQL injection vulnerabilities - but none of them would go far without strong documentation. Stas pointed out that PHP applications tend to rely on extensions rather a lot; safe_mode was an attempt to use a similar security model to that in Java, and that was precisely why it failed.

Short version: PHP extensions are just as safe as JNI modules. It's just that we use ours.

TLK: PHP security - prepared statements

Brian Moon took the discussion in a whole new direction by calling prepared statements as a security measure 'a myth': 'Prepared statements protect very little against sql injection. Making people believe otherwise is dangerous'. One Vlad Bosinceanu responded that it's better than having to deal with SQL at a low level and, given that PHP users tend to lack training, that's about as good as it can get. He felt the manual could be used better to push for the adoption of tools to prevent common problems, but saw prepared statements (in PDO) as one of those tools. Mathieu agreed, but wrote that variable binding was more helpful for securing data than prepared statements per se - it's just that they tend to come as a single package, and don't exist at all in many PHP 4 drivers. He repeated his earlier call for good developer education, and suggested a community portal site (with forum) dedicated to good, secure PHP programming. Stefan retorted that, if even the current crop of 'security experts' can make mistakes, anything community based would be doomed to unreliability.

Brian explained that he wasn't disputing the usefulness of variable binding, just the way prepared statements are 'sold' to the community as a security tool. He claimed that neither the PHP nor MySQL manuals mention SQL injection attacks when discussing prepared statements. Wez took issue with him there, although admitting that that page doesn't stress the seriousness of the problem. Stefan argued (much, much later) that it's actually incorrect; it says that the user is not at risk if their application exclusively uses prepared statements, whereas there is a risk of SQL injection in stored procedures too. It was also misleading; it implied that there was no danger in putting user input into a query. Lukas Smith was confused by that allegation; those reading the advice about dynamic query generation in PHP would surely apply the same practices to stored routines? Besides, database administrators tend to be less than fond of dynamic query generation in stored routines. Stefan thought that, in a team, it would be unlikely that those writing PHP applications were also responsible for writing stored procedures. Although pointing out the weakness in Lukas' argument - the assumption that people actually read the manual - he was glad to see the warning about dynamically injected user input there. Lukas wrote that those writing stored procedures really ought to know how to protect against SQL injection anyway; it was hardly a PHP-only issue. That said, both sides should alert one another to potential problems.

Short version: In an ideal world, there'd be no problems at all.

TLK: PHP security - a secure query builder?

Tim Starling shared the secrets of MediaWiki's secure query builder, and demonstrated its usage with a complex SELECT query:

$result = $db->select(
    
# Tables
    
array('user', 'revision'),
    
# Fields
    
array('user_name', 'rev_timestamp'),
    
# Conditions (WHERE)
    
array('user_id=rev_user', 'rev_page' => $page_id),
    
# Query tag, goes into a comment in the SQL
    
__METHOD__,
    
# Options
    
array('LIMIT' => 10, 'ORDER BY' => 'rev_timestamp DESC')
);

He'd like to see something like that query builder in the PHP core. Everyone else agreed that this was 'hideous' code, but Tim pointed out calmly that it's much easier to cope with than the equivalent string mangling. He went on to say that application developers should take some responsibility for the situation; they shouldn't use register_globals or safe_mode in new code, particularly as open_basedir is both simpler and more likely to provide some security. Query building is a sane way to avoid SQL injection, and prepared statements are a useful step in this direction. Shell escaping could be handled in a similar way, and there could be an HTML construction library that makes a clear distinction between HTML and text input. In short, he believed the solution to security vulnerabilities introduced by string manipulation lay in handling each protocol as a protocol, rather than as a string.

Short version: Userland solutions - but he may have a point.

TLK: PHP security - more exploits, please

Zeev Suraski picked up his mail, and simply addressed the technological aspects of Stefan's posts. He began by dismantling the notion that security issues are unique to PHP in any respect; exactly the same problems exist in other languages, and in his opinion this was not something that could be resolved: 'We can't treat hundreds of thousand of lines of code, some of it generated code that we can't even fully validate, as 100% security sensitive'. Zeev regarded the local exploits Stefan sent after leaving the security team as a wakeup call. Not because they existed in the first place, but because it was now clear that the message 'NO LANGUAGE SHOULD BE TRUSTED TO LOCAL USERS WITHOUT OS LEVEL PROTECTION' hadn't reached its target, and needs to be shouted loud. Protection against malicious local hackers is futile, in any language, and safe_mode, open_basedir et al are inherently flawed because they protect at the wrong level. disable_functions should be used as an administrative feature rather than a security feature, and this needed to be made more clear. To clarify: exploits that would normally be 'local' but which are commonly found in code that can be remotely triggered should be classified as remote, in his book, and dealt with quickly. Zeev also made it clear that the core team fully appreciate the work Stefan has put into auditing PHP.

Referring (presumably) to the concurrent ongoing battle in security@, Stefan wondered why Zeev thought he'd been reporting crash bugs. All his proof-of-concept scripts demonstrated bugs that could be exploited to execute arbitrary code or access areas of read/write memory; he was prepared to publish full exploits, if pushed. The holes been found during 'a very quick audit' and should have been obvious to any security-aware C programmer. If Zeev wanted to see more remote exploits, he'd have to wait until enough new lines of code had been committed to make new buffer overflows likely. To Zeev, it was simply a matter of terminology - a crash bug that can be exploited to trigger unexpected behaviour could equally well be called a locally exploitable bug, and he didn't particularly care which name it went under. He declared bluntly that Stefan was wrong to dismiss them as 'obvious'; he'd expect there to be many more bugs reported even after Stefan's audit, 'because contrary to what you say, it's not easy finding them at all'. However, Zeev found it 'reassuring' that Stefan couldn't produce an armful of remote exploits until a bunch of new code goes into CVS. He went on to say that PHP's track record regarding remote exploits is actually very good considering its popularity; the fact that Stefan couldn't find any additional ones off-the-cuff meant the language is in pretty good shape after all. He wound up with an invitation to Stefan to keep on looking for and reporting remote bugs in a professional manner, as of yore.

Short version: Was that loud enough, Zeev?

TLK: PHP security - remote URL includes

Somewhere along the line, Stefan had ripped into the whole notion of remote URL includes, which - he claimed - are responsible for the majority of server attacks. 'In PHP 5.2.1 there will be a configuration option that activates an (incomplete) blacklist. Everyone should know by now that blacklists are BAD.'

Rasmus responded to this one. He didn't feel the term 'blacklist' was appropriate for a flag marking the stream handlers capable of making a network connection, given that there is a finite set of stream handlers in PHP. Assuming the correct ones had been marked, the only way to circumvent it would be to bounce through some kind of filesystem network mechanism - but at that level, it was surely the responsibility of the local systems administrator to protect the system. Stefan argued that the base assumption, that of a finite set of stream handlers, is wrong. There are user streams, which could be registered and then abused via an included file. There are PECL extensions that register streams outside the PHP core; Stefan chose pecl/ssh2 as an example. Although SSH is a network protocol, and although the manual states that SSH streams are forbidden in allow_url_fopen, the code says otherwise; is_url is set to 0. Anyone installing pecl/ssh2 would still be vulnerable to remote file includes - and this was exactly the problem with the blacklist approach that Stefan was trying to describe.

Marcus surprised everyone by agreeing with Stefan that the is_url flag isn't very helpful. In his opinion, there should be an INI setting enabling the administrator to specify which stream handlers are allowed - and user streams shouldn't be part of it. Ilia thought this sounded like a recipe for disaster, since those deciding which streams are local and which remote might not have certain remote streams in their sights. He saw no reason internal flags couldn't be used effectively, with the onus on the extension author to get it right. The only real problem was that the is_url flag is new; older extensions providing a remote wrapper can't be guaranteed to have the appropriate setting in place, because the maintainer may simply have been resolving a compile failure by adding it. Rasmus wondered what had happened to the decision to mark user streams insecure by default? Marcus explained to Ilia that his aim was to provide precision at INI_SYSTEM level, not at PHP user level. Stefan suggested that it would be better simply to forbid the use of URLs inside include/require, introduce include_url() to replace the feature, and rename allow_url_include to allow_dangerous_urls. Greg Beaver quite liked that idea - particularly the bit about using the word 'dangerous' in the INI setting - but would rather find a way to easily whitelist 'harmless' URL wrappers such as phar and PHP_Archive, which only access local files. He thought introducing the include_url() family of functions would be too confusing, given the levels of confusion already existing over include(), require() and *_once(). Greg went on to suggest an internal flag in the Zend Engine, set during calls to include/require, that would automatically disable all network access functions during a stream wrapper's open() and read() calls. The down side of this was that it would require a new Zend API function to be inserted into extensions utilizing stream wrappers, but 'fortunately the list is finite'...

This was, it has to be said, a very long thread.

Stefan explained patiently that he'd only been talking about a single function, not an entire family. He saw including anything through an URL wrapper as broken, but felt it could be worked around by having allow_url_include affect all URLs, turned off by default and settable from the script. 'Insane applications' could turn it on and off for every remote URL they needed; and there should be an INI setting providing the admin with a means of completely disallowing is_url wrapper includes.

Tim Starling went back to Stefan's original argument against blacklists, writing that 'arbitrary local includes are almost as dangerous' because upload features are so prevalent in PHP applications. To Tim, PHP's particular vulnerability lies in Web executable include scripts and register_globals. Apparently reasonable code could constitute a serious security hole thanks to those two elements, and many developers would miss the threat because it's under-documented. Tim would like to see a prominent warning on all include-related manual pages stating that variables should never be used as a base path for included scripts, and clearly demonstrating 'extremely dangerous' code such as:

<?php

require_once("$InstallPath/BaseClass.php");
class
DerivedClass extends BaseClass {}

Agreeing with Stefan's earlier point about the limitations of documentation, Tim noted that this would of course offer protection only to those who read the manual.

Stas, meanwhile, had read Marcus' thoughts on the limitations of the is_url flag, and wanted to know what user streams had to do with anything. Marcus muttered something sarcastic. Stefan explained nicely; this wasn't about including URL stream wrappers you had provided yourself, but about URL include vulnerabilities in your application that would allow remote attacks against the application's user streams. He wouldn't be at all surprised to see a user stream wrapper that allows specifying a remote URL - and unlike php://filter, a user stream wouldn't pass along any warning that its data came from an included file. Stas, getting the picture clearly now, thought that in most cases prohibiting anything but a plain file wrapper for included files should be OK, but there are a number of legitimate wrappers - like those Greg had mentioned - that would be broken by this. He suggested there could be a flag passed to stream_open() saying that the wrapper is used for include files. Greg replied that there's one like that passed to wrapper_open in PECL streams already; the problem is that the onus is on the wrapper implementation to do the right thing.

Short version: Things started to turn circular.

NEW: CVS server change

Rasmus made a short announcement to the internals list at the end of the week:

There will be a short downtime of the cvs server this afternoon. I need
to move it to another data center. The IP address will be changing as
well. I lowered the TTL of the dns zone file yesterday, so it should be
pretty quick to catch up once the machine is hooked back up. I expect
about 20-30 minutes of downtime and then some dns delays lasting no more
than an hour. The new ip will be 69.147.83.196 so if you can't wait and
you see it up, you can point cvs.php.net to that. y2 is moving as well
and the new ip for that will be 69.147.83.197.

Short version: Nice, whizzy new CVS.

CVS: Lots of 5_2-only and Engine fixes

Changes in CVS that you should probably be aware of include:

  • The core gained a new PHPAPI function, php_stream_open_for_zend_ex(), providing a means for opening a file for Zend with error suppression (PHP_5_2 branch only) [Ilia]
  • In ext/spl, bugs #38325 (spl_autoload_register() gaves wrong line for "class not found") and #40091 (spl_autoload_register with 2 instances of the same class) were fixed - again in 5_2 only [Ilia]
  • Exif bug #40073 (exif_read_data dies on certain images) was fixed [Marcus, Tony Dovgal]
  • Zend Engine bugs #40002 (Try/Catch performs poorly), #40076 (zend_alloc.c: Value of enumeration constant must be in range of signed integer), #35106 (nested foreach fails when array variable has a reference), #36214 (__get method works properly only when conditional operator is used), #39449 (Overloaded array properties do not work correctly), #39990 (Cannot "foreach" over overloaded properties) and #39969 (ini setting short_open_tag has no effect when using --enable-maintainer-zts) were fixed [Dmitry]
  • Across all current PHP branches, ext/session was patched to prevent SESSION/GLOBALS overload through session decoding [Ilia]
  • ext/curl gained a new constant, CURLOPT_TCP_NODELAY [Sara]
  • Also in ext/curl, bug #36248 (CURLOPT_HEADERFUNCTION, couldn't set the function in the class) was fixed in PHP_4_4 branch only [Ilia]
  • In the milter SAPI, bug #40083 (smfi_getsymval always returns blank strings) was fixed [Tony]
  • In ext/oci8, bug #40078 (ORA-01405 when fetching NULL values using oci_bind_array_by_name()) was fixed [Tony]
  • Core bug #40098 (php_fopen_primary_script() not thread safe) was fixed [Ilia]
  • PDO bug #40121 (PDO_DBLIB driver wont free statements) was fixed in 5_2 only [Ilia]
  • Also in PHP_5_2 only, the apache2handler SAPI now compiles on Netware, fixing bug #40127 [Ilia]

In other CVS news, Dmitry backported a fix for #39819 (Using $this not in object context can cause segfaults) to the PHP_4_4 branch, following a request from PHP user Matteo Beccati.

Navigating the slippery slopes of CVS HEAD, Sara began her week by doing something mysterious 'to allow libxml DomNodes to remain persistent when requested by other extensions'. She went on to add a convenience function for opening files with Unicode names, _php_stream_u_open_wrapper(), to the PHPAPI. Finally, she went to sort out a sysconf() issue seen on platforms that have getpwnam_r() but no _SC_GETPW_R_SIZE_MAX define. Weirdly, two members of the dev team reported that their platforms had the constant defined but no value set for it, rendering Sara's fix impotent. Tony posted a patch to get around the problem.

Andrei realized that every file in the build system and SAPIs with 'php5' in its name needs renaming in CVS HEAD, and posted a patch to cover 'the top-level stuff plus sapi/apache'. He left the Windows build systems (old and new) out of the equation entirely, and also left the rest of the SAPIs and modules to their own maintainers. Nobody objected, so Andrei went ahead and committed his semi-update. He ended his week by creating a new configure macro, PHP_SETUP_ICU, that can be used to set up the entire ICU configuration in self-contained extensions.

Marcus contented himself with adding a new helper macro, zstrlen(), to the Zend Engine, and doing some odd bits and pieces of tidying.

Nuno Lopes was doing similar work, until both Derick and Pierre jointly confronted him over 'clogging the source code with ifdefs'. Pierre's main issue was that that kind of change shouldn't go into CVS at all during the RC phase, and he asked Nuno to operate a 'hands-off' policy on the 5_2 branch until PHP 5.2.1 has been released. Unfortunately Nuno removed some dead code and optimized part of ext/gd later in the week, which wasn't really what Pierre had in mind. He asked Nuno if this change could be termed 'critical'? Nuno felt it could, given large enough images, but added that he'd held back on the largest part of his optimization work because of the timing. Pierre asked to see the code prior to commit, to which Nuno readily agreed.

Short version: There's a time and a place for everything. (OK, most things.)

PAT: Everything applied

Dmitry applied a patch this week that's been sitting around since August: bug #35634 (Erroneous "Class declarations may not be nested" error raised) has now been fixed, thanks to Carl P. Corliss. Dmitry was also responsible for applying a proc_open() fix from Amit (no surname given), which will now close any open files on failure.

Patch king Matt Wilmas offered up patches for the new b prefix in syntax highlighting and ext/tokenizer, which were promptly applied by Andrei in the PHP_5_2 branch and CVS HEAD. Andrey Hristov killed off a few Zend Engine compiler warnings in CVS HEAD - also applied by Andrei - and someone known only as Evan G. assisted Andrei in rewriting large chunks of README.UNICODE.

Andy Wharmby - a contender for Matt's position just lately - provided a safe_mode fix for bug #40079 (php_get_current_user() not thread safe), which Ilia applied in the PHP_5_2 branch. He also produced a build fix, which Hannes Magnusson promptly added into CVS.

And finally, Christopher Jones - another contender - sent Tony a fix for bug #39988 (type argument of oci_define_by_name() is ignored) and several new tests for ext/oci8. Tony duly added them into PHP_5_2 branch and CVS HEAD.

Short version: Thanks guys!