doc-en icon indicating copy to clipboard operation
doc-en copied to clipboard

stream_copy_to_stream() treats $offset of 0 as "current position"

Open ProgerXP opened this issue 3 years ago • 1 comments

Documentation does not mention that $offset of 0 keeps $from's position rather than copying from 0th offset.

<?php
$a = fopen('php://memory', 'r+');
$b = fopen('php://memory', 'r+');
fwrite($a, '0123456789');
fseek($a, 3);
stream_copy_to_stream($a, $b, 2, 0);
rewind($b);
echo stream_get_contents($b);

This code outputs 34 and not 01 as suggested by the documentation.

To me, this looks more like an implementation issue because $offset may depend on external factors such as user's input, and code most often doesn't expect the function's seeking behaviour to change if the input is zero or non-zero.

Related code (note the pos > 0 condition):

https://github.com/php/php-src/blob/11b612af6dbe9fdd60edb58d37e441c97bff79e0/ext/standard/streamsfuncs.c#L481-L509

PHP_FUNCTION(stream_copy_to_stream)
{
	// ...
	if (pos > 0 && php_stream_seek(src, pos, SEEK_SET) < 0) {

ProgerXP avatar Dec 08 '22 11:12 ProgerXP

To me, this looks more like an implementation issue because $offset may depend on external factors such as user's input, and code most often doesn't expect the function's seeking behaviour to change if the input is zero or non-zero.

I think it is "just" an unfortunate API design. The default value of $offset would have better been -1, and the respective condition pos >= 0. Given that it is implemented that way since the optional parameter has been introduced (PHP 5.1.0), I don't think we can change that now. So we're left with fixing the docs.

cmb69 avatar Dec 08 '22 12:12 cmb69