php-src/ext/standard/tests/file/chmod_basic-win32-mb.phpt
Anatol Belski 3d3f11ede4 Fixed the UTF-8 and long path support in the streams on Windows.
Since long the default PHP charset is UTF-8, however the Windows part is
out of step with this important point. The current implementation in PHP
doesn't technically permit to handle UTF-8 filepath and several other
things. Till now, only the ANSI compatible APIs are being used. Here is more
about it

dd317752%28v=vs.85%29.aspx

The patch fixes not only issues with multibyte filenames under
incompatible codepages, but indirectly also issues with some other multibyte
encodings like BIG5, Shift-JIS, etc. by providing a clean way to access
filenames in UTF-8. Below is a small list of issues from the bug tracker,
that are getting fixed:

https://bugs.php.net/63401
https://bugs.php.net/41199
https://bugs.php.net/50203
https://bugs.php.net/71509
https://bugs.php.net/64699
https://bugs.php.net/64506
https://bugs.php.net/30195
https://bugs.php.net/65358
https://bugs.php.net/61315
https://bugs.php.net/70943
https://bugs.php.net/70903
https://bugs.php.net/63593
https://bugs.php.net/54977
https://bugs.php.net/54028
https://bugs.php.net/43148
https://bugs.php.net/30730
https://bugs.php.net/33350
https://bugs.php.net/35300
https://bugs.php.net/46990
https://bugs.php.net/61309
https://bugs.php.net/69333
https://bugs.php.net/45517
https://bugs.php.net/70551
https://bugs.php.net/50197
https://bugs.php.net/72200
https://bugs.php.net/37672

Yet more related tickets can for sure be found - on bugs.php.net, Stackoverflow
and Github. Some of the bugs are pretty recent, some descend to early
2000th, but  the user comments in there last even till today. Just for example,
bug #30195 was opened in 2004, the latest comment in there was made in 2014. It
is certain, that these bugs descend not only to pure PHP use cases, but get also
redirected from the popular PHP based projects. Given the modern systems (and
those supported by PHP) are always based on NTFS, there is no excuse to keep
these issues unresolved.

The internalization approach on Windows is in many ways different from
UNIX and Linux, while it supports and is based on Unicode. It depends on the
current system code page, APIs used and exact kind how the binary was compiled
The locale doesn't affect the way Unicode or ANSI API work. PHP in particular
is being compiled without _UNICODE defined and this is conditioned by the
way we handle strings. Here is more about it

https://msdn.microsoft.com/en-us/library/tsbaswba.aspx

However, with any system code page ANSI functions automatically convert
paths to UTF-16. Paths in some encodings incompatible with the
current system code page, won't work correctly with ANSI APIs. PHP
till now only uses the ANSI Windows APIs.

For example, on a system with the current code page 1252, the paths
in cp1252 are supported and transparently converted to UTF-16 by the
ANSI functions. Once one wants to handle a filepath encoded with cp932 on
that particular system, an ANSI or a POSIX compatible function used in
PHP will produce an erroneous result. When trying to convert that cp932 path
to UTF-8 and passing to the ANSI functions, an ANSI function would
likely interpret the UTF-8 string as some string in the current code page and
create a filepath that represents every single byte of the UTF-8 string.
These behaviors are not only broken but also disregard the documented
INI settings.

This patch solves the issies with the multibyte paths on Windows by
intelligently enforcing the usage of the Unicode aware APIs. For
functions expect Unicode (fe CreateFileW, FindFirstFileW, etc.), arguments
will be converted to UTF-16 wide chars. For functions returning Unicode
aware data (fe GetCurrentDirectoryW, etc.), resulting wide string is
converted back to char's depending on the current PHP charset settings,
either to the current ANSI codepage (this is the behavior prior to this patch)
or to UTF-8 (the default behavior).

In a particular case, users might have to explicitly set
internal_encoding or default_charset, if filenames in ANSI codepage are
necessary. Current tests show no regressions and witness that this will be an
exotic case, the current default UTF-8 encoding is compatible with any
supported system. The dependency libraries are long switching to Unicode APIs,
so some tests were also added for extensions not directly related to streams.
At large, the patch brings over 150 related tests into the core. Those target
and was run on various environments with European, Asian, etc. codepages.
General PHP frameworks was tested and showed no regressions.

The impact on the current C code base is low, the most places affected
are the Windows only places in the three files tsrm_win32.c, zend_virtual_cwd.c
and plain_wrapper.c. The actual implementation of the most of the wide
char supporting functionality is in win32/ioutil.* and win32/codepage.*,
several  low level functionsare extended in place to avoid reimplementation for
now. No performance impact was sighted. As previously mentioned, the ANSI APIs
used prior the patch perform Unicode conversions internally. Using the
Unicode  APIs directly while doing custom conversions just retains the status
quo. The ways to optimize it are open (fe. by implementing caching for the
strings converted to wide variants).

The long path implementation is user transparent. If a path exceeds the
length of _MAX_PATH, it'll be automatically prefixed with \\?\. The MAXPATHLEN
is set to 2048 bytes.

Appreciation to Pierre Joye, Matt Ficken, @algo13 and others for tips, ideas
and testing.

Thanks.
2016-06-20 12:45:39 +02:00

545 lines
17 KiB
PHP

--TEST--
chmod() basic functionality
--SKIPIF--
<?php
if (substr(PHP_OS, 0, 3) != 'WIN') {
die('skip Windows only chmod test');
}
?>
--FILE--
<?php
define("PERMISSIONS_MASK", 0777);
$filename = __FILE__ . "私はガラスを食べられます.tmp";
$fd = fopen($filename, "w+");
fclose($fd);
for ($perms_to_set = 0777; $perms_to_set >= 0; $perms_to_set--) {
chmod($filename, $perms_to_set);
$set_perms = (fileperms($filename) & PERMISSIONS_MASK);
clearstatcache();
printf("Setting mode %o gives mode %o\n", $perms_to_set, $set_perms);
}
var_dump(chmod($filename, 0777));
unlink($filename);
echo "done";
?>
--EXPECT--
Setting mode 777 gives mode 666
Setting mode 776 gives mode 666
Setting mode 775 gives mode 666
Setting mode 774 gives mode 666
Setting mode 773 gives mode 666
Setting mode 772 gives mode 666
Setting mode 771 gives mode 666
Setting mode 770 gives mode 666
Setting mode 767 gives mode 666
Setting mode 766 gives mode 666
Setting mode 765 gives mode 666
Setting mode 764 gives mode 666
Setting mode 763 gives mode 666
Setting mode 762 gives mode 666
Setting mode 761 gives mode 666
Setting mode 760 gives mode 666
Setting mode 757 gives mode 666
Setting mode 756 gives mode 666
Setting mode 755 gives mode 666
Setting mode 754 gives mode 666
Setting mode 753 gives mode 666
Setting mode 752 gives mode 666
Setting mode 751 gives mode 666
Setting mode 750 gives mode 666
Setting mode 747 gives mode 666
Setting mode 746 gives mode 666
Setting mode 745 gives mode 666
Setting mode 744 gives mode 666
Setting mode 743 gives mode 666
Setting mode 742 gives mode 666
Setting mode 741 gives mode 666
Setting mode 740 gives mode 666
Setting mode 737 gives mode 666
Setting mode 736 gives mode 666
Setting mode 735 gives mode 666
Setting mode 734 gives mode 666
Setting mode 733 gives mode 666
Setting mode 732 gives mode 666
Setting mode 731 gives mode 666
Setting mode 730 gives mode 666
Setting mode 727 gives mode 666
Setting mode 726 gives mode 666
Setting mode 725 gives mode 666
Setting mode 724 gives mode 666
Setting mode 723 gives mode 666
Setting mode 722 gives mode 666
Setting mode 721 gives mode 666
Setting mode 720 gives mode 666
Setting mode 717 gives mode 666
Setting mode 716 gives mode 666
Setting mode 715 gives mode 666
Setting mode 714 gives mode 666
Setting mode 713 gives mode 666
Setting mode 712 gives mode 666
Setting mode 711 gives mode 666
Setting mode 710 gives mode 666
Setting mode 707 gives mode 666
Setting mode 706 gives mode 666
Setting mode 705 gives mode 666
Setting mode 704 gives mode 666
Setting mode 703 gives mode 666
Setting mode 702 gives mode 666
Setting mode 701 gives mode 666
Setting mode 700 gives mode 666
Setting mode 677 gives mode 666
Setting mode 676 gives mode 666
Setting mode 675 gives mode 666
Setting mode 674 gives mode 666
Setting mode 673 gives mode 666
Setting mode 672 gives mode 666
Setting mode 671 gives mode 666
Setting mode 670 gives mode 666
Setting mode 667 gives mode 666
Setting mode 666 gives mode 666
Setting mode 665 gives mode 666
Setting mode 664 gives mode 666
Setting mode 663 gives mode 666
Setting mode 662 gives mode 666
Setting mode 661 gives mode 666
Setting mode 660 gives mode 666
Setting mode 657 gives mode 666
Setting mode 656 gives mode 666
Setting mode 655 gives mode 666
Setting mode 654 gives mode 666
Setting mode 653 gives mode 666
Setting mode 652 gives mode 666
Setting mode 651 gives mode 666
Setting mode 650 gives mode 666
Setting mode 647 gives mode 666
Setting mode 646 gives mode 666
Setting mode 645 gives mode 666
Setting mode 644 gives mode 666
Setting mode 643 gives mode 666
Setting mode 642 gives mode 666
Setting mode 641 gives mode 666
Setting mode 640 gives mode 666
Setting mode 637 gives mode 666
Setting mode 636 gives mode 666
Setting mode 635 gives mode 666
Setting mode 634 gives mode 666
Setting mode 633 gives mode 666
Setting mode 632 gives mode 666
Setting mode 631 gives mode 666
Setting mode 630 gives mode 666
Setting mode 627 gives mode 666
Setting mode 626 gives mode 666
Setting mode 625 gives mode 666
Setting mode 624 gives mode 666
Setting mode 623 gives mode 666
Setting mode 622 gives mode 666
Setting mode 621 gives mode 666
Setting mode 620 gives mode 666
Setting mode 617 gives mode 666
Setting mode 616 gives mode 666
Setting mode 615 gives mode 666
Setting mode 614 gives mode 666
Setting mode 613 gives mode 666
Setting mode 612 gives mode 666
Setting mode 611 gives mode 666
Setting mode 610 gives mode 666
Setting mode 607 gives mode 666
Setting mode 606 gives mode 666
Setting mode 605 gives mode 666
Setting mode 604 gives mode 666
Setting mode 603 gives mode 666
Setting mode 602 gives mode 666
Setting mode 601 gives mode 666
Setting mode 600 gives mode 666
Setting mode 577 gives mode 444
Setting mode 576 gives mode 444
Setting mode 575 gives mode 444
Setting mode 574 gives mode 444
Setting mode 573 gives mode 444
Setting mode 572 gives mode 444
Setting mode 571 gives mode 444
Setting mode 570 gives mode 444
Setting mode 567 gives mode 444
Setting mode 566 gives mode 444
Setting mode 565 gives mode 444
Setting mode 564 gives mode 444
Setting mode 563 gives mode 444
Setting mode 562 gives mode 444
Setting mode 561 gives mode 444
Setting mode 560 gives mode 444
Setting mode 557 gives mode 444
Setting mode 556 gives mode 444
Setting mode 555 gives mode 444
Setting mode 554 gives mode 444
Setting mode 553 gives mode 444
Setting mode 552 gives mode 444
Setting mode 551 gives mode 444
Setting mode 550 gives mode 444
Setting mode 547 gives mode 444
Setting mode 546 gives mode 444
Setting mode 545 gives mode 444
Setting mode 544 gives mode 444
Setting mode 543 gives mode 444
Setting mode 542 gives mode 444
Setting mode 541 gives mode 444
Setting mode 540 gives mode 444
Setting mode 537 gives mode 444
Setting mode 536 gives mode 444
Setting mode 535 gives mode 444
Setting mode 534 gives mode 444
Setting mode 533 gives mode 444
Setting mode 532 gives mode 444
Setting mode 531 gives mode 444
Setting mode 530 gives mode 444
Setting mode 527 gives mode 444
Setting mode 526 gives mode 444
Setting mode 525 gives mode 444
Setting mode 524 gives mode 444
Setting mode 523 gives mode 444
Setting mode 522 gives mode 444
Setting mode 521 gives mode 444
Setting mode 520 gives mode 444
Setting mode 517 gives mode 444
Setting mode 516 gives mode 444
Setting mode 515 gives mode 444
Setting mode 514 gives mode 444
Setting mode 513 gives mode 444
Setting mode 512 gives mode 444
Setting mode 511 gives mode 444
Setting mode 510 gives mode 444
Setting mode 507 gives mode 444
Setting mode 506 gives mode 444
Setting mode 505 gives mode 444
Setting mode 504 gives mode 444
Setting mode 503 gives mode 444
Setting mode 502 gives mode 444
Setting mode 501 gives mode 444
Setting mode 500 gives mode 444
Setting mode 477 gives mode 444
Setting mode 476 gives mode 444
Setting mode 475 gives mode 444
Setting mode 474 gives mode 444
Setting mode 473 gives mode 444
Setting mode 472 gives mode 444
Setting mode 471 gives mode 444
Setting mode 470 gives mode 444
Setting mode 467 gives mode 444
Setting mode 466 gives mode 444
Setting mode 465 gives mode 444
Setting mode 464 gives mode 444
Setting mode 463 gives mode 444
Setting mode 462 gives mode 444
Setting mode 461 gives mode 444
Setting mode 460 gives mode 444
Setting mode 457 gives mode 444
Setting mode 456 gives mode 444
Setting mode 455 gives mode 444
Setting mode 454 gives mode 444
Setting mode 453 gives mode 444
Setting mode 452 gives mode 444
Setting mode 451 gives mode 444
Setting mode 450 gives mode 444
Setting mode 447 gives mode 444
Setting mode 446 gives mode 444
Setting mode 445 gives mode 444
Setting mode 444 gives mode 444
Setting mode 443 gives mode 444
Setting mode 442 gives mode 444
Setting mode 441 gives mode 444
Setting mode 440 gives mode 444
Setting mode 437 gives mode 444
Setting mode 436 gives mode 444
Setting mode 435 gives mode 444
Setting mode 434 gives mode 444
Setting mode 433 gives mode 444
Setting mode 432 gives mode 444
Setting mode 431 gives mode 444
Setting mode 430 gives mode 444
Setting mode 427 gives mode 444
Setting mode 426 gives mode 444
Setting mode 425 gives mode 444
Setting mode 424 gives mode 444
Setting mode 423 gives mode 444
Setting mode 422 gives mode 444
Setting mode 421 gives mode 444
Setting mode 420 gives mode 444
Setting mode 417 gives mode 444
Setting mode 416 gives mode 444
Setting mode 415 gives mode 444
Setting mode 414 gives mode 444
Setting mode 413 gives mode 444
Setting mode 412 gives mode 444
Setting mode 411 gives mode 444
Setting mode 410 gives mode 444
Setting mode 407 gives mode 444
Setting mode 406 gives mode 444
Setting mode 405 gives mode 444
Setting mode 404 gives mode 444
Setting mode 403 gives mode 444
Setting mode 402 gives mode 444
Setting mode 401 gives mode 444
Setting mode 400 gives mode 444
Setting mode 377 gives mode 666
Setting mode 376 gives mode 666
Setting mode 375 gives mode 666
Setting mode 374 gives mode 666
Setting mode 373 gives mode 666
Setting mode 372 gives mode 666
Setting mode 371 gives mode 666
Setting mode 370 gives mode 666
Setting mode 367 gives mode 666
Setting mode 366 gives mode 666
Setting mode 365 gives mode 666
Setting mode 364 gives mode 666
Setting mode 363 gives mode 666
Setting mode 362 gives mode 666
Setting mode 361 gives mode 666
Setting mode 360 gives mode 666
Setting mode 357 gives mode 666
Setting mode 356 gives mode 666
Setting mode 355 gives mode 666
Setting mode 354 gives mode 666
Setting mode 353 gives mode 666
Setting mode 352 gives mode 666
Setting mode 351 gives mode 666
Setting mode 350 gives mode 666
Setting mode 347 gives mode 666
Setting mode 346 gives mode 666
Setting mode 345 gives mode 666
Setting mode 344 gives mode 666
Setting mode 343 gives mode 666
Setting mode 342 gives mode 666
Setting mode 341 gives mode 666
Setting mode 340 gives mode 666
Setting mode 337 gives mode 666
Setting mode 336 gives mode 666
Setting mode 335 gives mode 666
Setting mode 334 gives mode 666
Setting mode 333 gives mode 666
Setting mode 332 gives mode 666
Setting mode 331 gives mode 666
Setting mode 330 gives mode 666
Setting mode 327 gives mode 666
Setting mode 326 gives mode 666
Setting mode 325 gives mode 666
Setting mode 324 gives mode 666
Setting mode 323 gives mode 666
Setting mode 322 gives mode 666
Setting mode 321 gives mode 666
Setting mode 320 gives mode 666
Setting mode 317 gives mode 666
Setting mode 316 gives mode 666
Setting mode 315 gives mode 666
Setting mode 314 gives mode 666
Setting mode 313 gives mode 666
Setting mode 312 gives mode 666
Setting mode 311 gives mode 666
Setting mode 310 gives mode 666
Setting mode 307 gives mode 666
Setting mode 306 gives mode 666
Setting mode 305 gives mode 666
Setting mode 304 gives mode 666
Setting mode 303 gives mode 666
Setting mode 302 gives mode 666
Setting mode 301 gives mode 666
Setting mode 300 gives mode 666
Setting mode 277 gives mode 666
Setting mode 276 gives mode 666
Setting mode 275 gives mode 666
Setting mode 274 gives mode 666
Setting mode 273 gives mode 666
Setting mode 272 gives mode 666
Setting mode 271 gives mode 666
Setting mode 270 gives mode 666
Setting mode 267 gives mode 666
Setting mode 266 gives mode 666
Setting mode 265 gives mode 666
Setting mode 264 gives mode 666
Setting mode 263 gives mode 666
Setting mode 262 gives mode 666
Setting mode 261 gives mode 666
Setting mode 260 gives mode 666
Setting mode 257 gives mode 666
Setting mode 256 gives mode 666
Setting mode 255 gives mode 666
Setting mode 254 gives mode 666
Setting mode 253 gives mode 666
Setting mode 252 gives mode 666
Setting mode 251 gives mode 666
Setting mode 250 gives mode 666
Setting mode 247 gives mode 666
Setting mode 246 gives mode 666
Setting mode 245 gives mode 666
Setting mode 244 gives mode 666
Setting mode 243 gives mode 666
Setting mode 242 gives mode 666
Setting mode 241 gives mode 666
Setting mode 240 gives mode 666
Setting mode 237 gives mode 666
Setting mode 236 gives mode 666
Setting mode 235 gives mode 666
Setting mode 234 gives mode 666
Setting mode 233 gives mode 666
Setting mode 232 gives mode 666
Setting mode 231 gives mode 666
Setting mode 230 gives mode 666
Setting mode 227 gives mode 666
Setting mode 226 gives mode 666
Setting mode 225 gives mode 666
Setting mode 224 gives mode 666
Setting mode 223 gives mode 666
Setting mode 222 gives mode 666
Setting mode 221 gives mode 666
Setting mode 220 gives mode 666
Setting mode 217 gives mode 666
Setting mode 216 gives mode 666
Setting mode 215 gives mode 666
Setting mode 214 gives mode 666
Setting mode 213 gives mode 666
Setting mode 212 gives mode 666
Setting mode 211 gives mode 666
Setting mode 210 gives mode 666
Setting mode 207 gives mode 666
Setting mode 206 gives mode 666
Setting mode 205 gives mode 666
Setting mode 204 gives mode 666
Setting mode 203 gives mode 666
Setting mode 202 gives mode 666
Setting mode 201 gives mode 666
Setting mode 200 gives mode 666
Setting mode 177 gives mode 444
Setting mode 176 gives mode 444
Setting mode 175 gives mode 444
Setting mode 174 gives mode 444
Setting mode 173 gives mode 444
Setting mode 172 gives mode 444
Setting mode 171 gives mode 444
Setting mode 170 gives mode 444
Setting mode 167 gives mode 444
Setting mode 166 gives mode 444
Setting mode 165 gives mode 444
Setting mode 164 gives mode 444
Setting mode 163 gives mode 444
Setting mode 162 gives mode 444
Setting mode 161 gives mode 444
Setting mode 160 gives mode 444
Setting mode 157 gives mode 444
Setting mode 156 gives mode 444
Setting mode 155 gives mode 444
Setting mode 154 gives mode 444
Setting mode 153 gives mode 444
Setting mode 152 gives mode 444
Setting mode 151 gives mode 444
Setting mode 150 gives mode 444
Setting mode 147 gives mode 444
Setting mode 146 gives mode 444
Setting mode 145 gives mode 444
Setting mode 144 gives mode 444
Setting mode 143 gives mode 444
Setting mode 142 gives mode 444
Setting mode 141 gives mode 444
Setting mode 140 gives mode 444
Setting mode 137 gives mode 444
Setting mode 136 gives mode 444
Setting mode 135 gives mode 444
Setting mode 134 gives mode 444
Setting mode 133 gives mode 444
Setting mode 132 gives mode 444
Setting mode 131 gives mode 444
Setting mode 130 gives mode 444
Setting mode 127 gives mode 444
Setting mode 126 gives mode 444
Setting mode 125 gives mode 444
Setting mode 124 gives mode 444
Setting mode 123 gives mode 444
Setting mode 122 gives mode 444
Setting mode 121 gives mode 444
Setting mode 120 gives mode 444
Setting mode 117 gives mode 444
Setting mode 116 gives mode 444
Setting mode 115 gives mode 444
Setting mode 114 gives mode 444
Setting mode 113 gives mode 444
Setting mode 112 gives mode 444
Setting mode 111 gives mode 444
Setting mode 110 gives mode 444
Setting mode 107 gives mode 444
Setting mode 106 gives mode 444
Setting mode 105 gives mode 444
Setting mode 104 gives mode 444
Setting mode 103 gives mode 444
Setting mode 102 gives mode 444
Setting mode 101 gives mode 444
Setting mode 100 gives mode 444
Setting mode 77 gives mode 444
Setting mode 76 gives mode 444
Setting mode 75 gives mode 444
Setting mode 74 gives mode 444
Setting mode 73 gives mode 444
Setting mode 72 gives mode 444
Setting mode 71 gives mode 444
Setting mode 70 gives mode 444
Setting mode 67 gives mode 444
Setting mode 66 gives mode 444
Setting mode 65 gives mode 444
Setting mode 64 gives mode 444
Setting mode 63 gives mode 444
Setting mode 62 gives mode 444
Setting mode 61 gives mode 444
Setting mode 60 gives mode 444
Setting mode 57 gives mode 444
Setting mode 56 gives mode 444
Setting mode 55 gives mode 444
Setting mode 54 gives mode 444
Setting mode 53 gives mode 444
Setting mode 52 gives mode 444
Setting mode 51 gives mode 444
Setting mode 50 gives mode 444
Setting mode 47 gives mode 444
Setting mode 46 gives mode 444
Setting mode 45 gives mode 444
Setting mode 44 gives mode 444
Setting mode 43 gives mode 444
Setting mode 42 gives mode 444
Setting mode 41 gives mode 444
Setting mode 40 gives mode 444
Setting mode 37 gives mode 444
Setting mode 36 gives mode 444
Setting mode 35 gives mode 444
Setting mode 34 gives mode 444
Setting mode 33 gives mode 444
Setting mode 32 gives mode 444
Setting mode 31 gives mode 444
Setting mode 30 gives mode 444
Setting mode 27 gives mode 444
Setting mode 26 gives mode 444
Setting mode 25 gives mode 444
Setting mode 24 gives mode 444
Setting mode 23 gives mode 444
Setting mode 22 gives mode 444
Setting mode 21 gives mode 444
Setting mode 20 gives mode 444
Setting mode 17 gives mode 444
Setting mode 16 gives mode 444
Setting mode 15 gives mode 444
Setting mode 14 gives mode 444
Setting mode 13 gives mode 444
Setting mode 12 gives mode 444
Setting mode 11 gives mode 444
Setting mode 10 gives mode 444
Setting mode 7 gives mode 444
Setting mode 6 gives mode 444
Setting mode 5 gives mode 444
Setting mode 4 gives mode 444
Setting mode 3 gives mode 444
Setting mode 2 gives mode 444
Setting mode 1 gives mode 444
Setting mode 0 gives mode 444
bool(true)
done