Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.11.x will end 14 Nov 2022 (12 months plus 6 months extension).
  • Bug fixes for security issues in 3.11.x will end 13 Nov 2023 (18 months plus 12 months extension).
  • PHP version: minimum PHP 7.3.0 Note: minimum PHP version has increased since Moodle 3.10. PHP 7.4.x is supported too.

Differences Between: [Versions 310 and 311]

   1  <?php
   2  // This file is part of Moodle - http://moodle.org/
   3  //
   4  // Moodle is free software: you can redistribute it and/or modify
   5  // it under the terms of the GNU General Public License as published by
   6  // the Free Software Foundation, either version 3 of the License, or
   7  // (at your option) any later version.
   8  //
   9  // Moodle is distributed in the hope that it will be useful,
  10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12  // GNU General Public License for more details.
  13  //
  14  // You should have received a copy of the GNU General Public License
  15  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
  16  
  17  /**
  18   * mlang langstring tests.
  19   *
  20   * Based on local_amos mlang_langstring tests.
  21   *
  22   * @package    tool_customlang
  23   * @copyright  2020 Ferran Recio <ferran@moodle.com>
  24   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  25   */
  26  
  27  namespace tool_customlang\local\mlang;
  28  
  29  use advanced_testcase;
  30  use moodle_exception;
  31  
  32  /**
  33   * Langstring tests.
  34   *
  35   * @package    tool_customlang
  36   * @copyright  2020 Ferran Recio <ferran@moodle.com>
  37   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  38   */
  39  class langstring_test extends advanced_testcase {
  40  
  41      /**
  42       * Sanity 1.x string
  43       * - all variables but $a placeholders must be escaped because the string is eval'ed
  44       * - all ' and " must be escaped
  45       * - all single % must be converted into %% for backwards compatibility
  46       *
  47       * @dataProvider fix_syntax_data
  48       * @param string $text the text to test
  49       * @param int $version the lang package version (1 or 2)
  50       * @param int|null $fromversion the version to convert (null for none)
  51       * @param string $expected the expected result
  52       *
  53       */
  54      public function test_fix_syntax(string $text, int $version, ?int $fromversion, string $expected): void {
  55          $this->assertEquals(langstring::fix_syntax($text, $version, $fromversion), $expected);
  56      }
  57  
  58      /**
  59       * Data provider for the test_parse.
  60       *
  61       * @return  array
  62       */
  63      public function fix_syntax_data() : array {
  64          return [
  65              // Syntax sanity v1 strings.
  66              [
  67                  'No change', 1, null,
  68                  'No change'
  69              ],
  70              [
  71                  'Completed 100% of work', 1, null,
  72                  'Completed 100%% of work'
  73              ],
  74              [
  75                  'Completed 100%% of work', 1, null,
  76                  'Completed 100%% of work'
  77              ],
  78              [
  79                  "Windows\r\nsucks", 1, null,
  80                  "Windows\nsucks"
  81              ],
  82              [
  83                  "Linux\nsucks", 1, null,
  84                  "Linux\nsucks"
  85              ],
  86              [
  87                  "Mac\rsucks", 1, null,
  88                  "Mac\nsucks"
  89              ],
  90              [
  91                  "LINE TABULATION\x0Bnewline", 1, null,
  92                  "LINE TABULATION\nnewline"
  93              ],
  94              [
  95                  "FORM FEED\x0Cnewline", 1, null,
  96                  "FORM FEED\nnewline"
  97              ],
  98              [
  99                  "END OF TRANSMISSION BLOCK\x17newline", 1, null,
 100                  "END OF TRANSMISSION BLOCK\nnewline"
 101              ],
 102              [
 103                  "END OF MEDIUM\x19newline", 1, null,
 104                  "END OF MEDIUM\nnewline"
 105              ],
 106              [
 107                  "SUBSTITUTE\x1Anewline", 1, null,
 108                  "SUBSTITUTE\nnewline"
 109              ],
 110              [
 111                  "BREAK PERMITTED HERE\xC2\x82newline", 1, null,
 112                  "BREAK PERMITTED HERE\nnewline"
 113              ],
 114              [
 115                  "NEXT LINE\xC2\x85newline", 1, null,
 116                  "NEXT LINE\nnewline"
 117              ],
 118              [
 119                  "START OF STRING\xC2\x98newline", 1, null,
 120                  "START OF STRING\nnewline"
 121              ],
 122              [
 123                  "STRING TERMINATOR\xC2\x9Cnewline", 1, null,
 124                  "STRING TERMINATOR\nnewline"
 125              ],
 126              [
 127                  "Unicode Zl\xE2\x80\xA8newline", 1, null,
 128                  "Unicode Zl\nnewline"
 129              ],
 130              [
 131                  "Unicode Zp\xE2\x80\xA9newline", 1, null,
 132                  "Unicode Zp\nnewline"
 133              ],
 134              [
 135                  "Empty\n\n\n\n\n\nlines", 1, null,
 136                  "Empty\n\nlines"
 137              ],
 138              [
 139                  "Trailing   \n  whitespace \t \nat \nmultilines  ", 1, null,
 140                  "Trailing\n  whitespace\nat\nmultilines"
 141              ],
 142              [
 143                  'Escape $variable names', 1, null,
 144                  'Escape \$variable names'
 145              ],
 146              [
 147                  'Escape $alike names', 1, null,
 148                  'Escape \$alike names'
 149              ],
 150              [
 151                  'String $a placeholder', 1, null,
 152                  'String $a placeholder'
 153              ],
 154              [
 155                  'Escaped \$a', 1, null,
 156                  'Escaped \$a'
 157              ],
 158              [
 159                  'Wrapped {$a}', 1, null,
 160                  'Wrapped {$a}'
 161              ],
 162              [
 163                  'Trailing $a', 1, null,
 164                  'Trailing $a'
 165              ],
 166              [
 167                  '$a leading', 1, null,
 168                  '$a leading'
 169              ],
 170              [
 171                  'Hit $a-times', 1, null,
 172                  'Hit $a-times'
 173              ], // This is placeholder.
 174              [
 175                  'This is $a_book', 1, null,
 176                  'This is \$a_book'
 177              ], // This is not a place holder.
 178              [
 179                  'Bye $a, ttyl', 1, null,
 180                  'Bye $a, ttyl'
 181              ],
 182              [
 183                  'Object $a->foo placeholder', 1, null,
 184                  'Object $a->foo placeholder'
 185              ],
 186              [
 187                  'Trailing $a->bar', 1, null,
 188                  'Trailing $a->bar'
 189              ],
 190              [
 191                  '<strong>AMOS</strong>', 1, null,
 192                  '<strong>AMOS</strong>'
 193              ],
 194              [
 195                  '<a href="http://localhost">AMOS</a>', 1, null,
 196                  '<a href=\"http://localhost\">AMOS</a>'
 197              ],
 198              [
 199                  '<a href=\"http://localhost\">AMOS</a>', 1, null,
 200                  '<a href=\"http://localhost\">AMOS</a>'
 201              ],
 202              [
 203                  "'Murder!', she wrote", 1, null,
 204                  "'Murder!', she wrote"
 205              ], // Will be escaped by var_export().
 206              [
 207                  "\t  Trim Hunter  \t\t", 1, null,
 208                  'Trim Hunter'
 209              ],
 210              [
 211                  'Delete role "$a->role"?', 1, null,
 212                  'Delete role \"$a->role\"?'
 213              ],
 214              [
 215                  'Delete role \"$a->role\"?', 1, null,
 216                  'Delete role \"$a->role\"?'
 217              ],
 218              [
 219                  "Delete ASCII\0 NULL control character", 1, null,
 220                  'Delete ASCII NULL control character'
 221              ],
 222              [
 223                  "Delete ASCII\x05 ENQUIRY control character", 1, null,
 224                  'Delete ASCII ENQUIRY control character'
 225              ],
 226              [
 227                  "Delete ASCII\x06 ACKNOWLEDGE control character", 1, null,
 228                  'Delete ASCII ACKNOWLEDGE control character'
 229              ],
 230              [
 231                  "Delete ASCII\x07 BELL control character", 1, null,
 232                  'Delete ASCII BELL control character'
 233              ],
 234              [
 235                  "Delete ASCII\x0E SHIFT OUT control character", 1, null,
 236                  'Delete ASCII SHIFT OUT control character'
 237              ],
 238              [
 239                  "Delete ASCII\x0F SHIFT IN control character", 1, null,
 240                  'Delete ASCII SHIFT IN control character'
 241              ],
 242              [
 243                  "Delete ASCII\x10 DATA LINK ESCAPE control character", 1, null,
 244                  'Delete ASCII DATA LINK ESCAPE control character'
 245              ],
 246              [
 247                  "Delete ASCII\x11 DEVICE CONTROL ONE control character", 1, null,
 248                  'Delete ASCII DEVICE CONTROL ONE control character'
 249              ],
 250              [
 251                  "Delete ASCII\x12 DEVICE CONTROL TWO control character", 1, null,
 252                  'Delete ASCII DEVICE CONTROL TWO control character'
 253              ],
 254              [
 255                  "Delete ASCII\x13 DEVICE CONTROL THREE control character", 1, null,
 256                  'Delete ASCII DEVICE CONTROL THREE control character'
 257              ],
 258              [
 259                  "Delete ASCII\x14 DEVICE CONTROL FOUR control character", 1, null,
 260                  'Delete ASCII DEVICE CONTROL FOUR control character'
 261              ],
 262              [
 263                  "Delete ASCII\x15 NEGATIVE ACKNOWLEDGE control character", 1, null,
 264                  'Delete ASCII NEGATIVE ACKNOWLEDGE control character'
 265              ],
 266              [
 267                  "Delete ASCII\x16 SYNCHRONOUS IDLE control character", 1, null,
 268                  'Delete ASCII SYNCHRONOUS IDLE control character'
 269              ],
 270              [
 271                  "Delete ASCII\x1B ESCAPE control character", 1, null,
 272                  'Delete ASCII ESCAPE control character'
 273              ],
 274              [
 275                  "Delete ASCII\x7F DELETE control character", 1, null,
 276                  'Delete ASCII DELETE control character'
 277              ],
 278              [
 279                  "Delete ISO 8859\xC2\x80 PADDING CHARACTER control character", 1, null,
 280                  'Delete ISO 8859 PADDING CHARACTER control character'
 281              ],
 282              [
 283                  "Delete ISO 8859\xC2\x81 HIGH OCTET PRESET control character", 1, null,
 284                  'Delete ISO 8859 HIGH OCTET PRESET control character'
 285              ],
 286              [
 287                  "Delete ISO 8859\xC2\x83 NO BREAK HERE control character", 1, null,
 288                  'Delete ISO 8859 NO BREAK HERE control character'
 289              ],
 290              [
 291                  "Delete ISO 8859\xC2\x84 INDEX control character", 1, null,
 292                  'Delete ISO 8859 INDEX control character'
 293              ],
 294              [
 295                  "Delete ISO 8859\xC2\x86 START OF SELECTED AREA control character", 1, null,
 296                  'Delete ISO 8859 START OF SELECTED AREA control character'
 297              ],
 298              [
 299                  "Delete ISO 8859\xC2\x87 END OF SELECTED AREA control character", 1, null,
 300                  'Delete ISO 8859 END OF SELECTED AREA control character'
 301              ],
 302              [
 303                  "Delete ISO 8859\xC2\x88 CHARACTER TABULATION SET control character", 1, null,
 304                  'Delete ISO 8859 CHARACTER TABULATION SET control character'
 305              ],
 306              [
 307                  "Delete ISO 8859\xC2\x89 CHARACTER TABULATION WITH JUSTIFICATION control character", 1, null,
 308                  'Delete ISO 8859 CHARACTER TABULATION WITH JUSTIFICATION control character'
 309              ],
 310              [
 311                  "Delete ISO 8859\xC2\x8A LINE TABULATION SET control character", 1, null,
 312                  'Delete ISO 8859 LINE TABULATION SET control character'
 313              ],
 314              [
 315                  "Delete ISO 8859\xC2\x8B PARTIAL LINE FORWARD control character", 1, null,
 316                  'Delete ISO 8859 PARTIAL LINE FORWARD control character'
 317              ],
 318              [
 319                  "Delete ISO 8859\xC2\x8C PARTIAL LINE BACKWARD control character", 1, null,
 320                  'Delete ISO 8859 PARTIAL LINE BACKWARD control character'
 321              ],
 322              [
 323                  "Delete ISO 8859\xC2\x8D REVERSE LINE FEED control character", 1, null,
 324                  'Delete ISO 8859 REVERSE LINE FEED control character'
 325              ],
 326              [
 327                  "Delete ISO 8859\xC2\x8E SINGLE SHIFT TWO control character", 1, null,
 328                  'Delete ISO 8859 SINGLE SHIFT TWO control character'
 329              ],
 330              [
 331                  "Delete ISO 8859\xC2\x8F SINGLE SHIFT THREE control character", 1, null,
 332                  'Delete ISO 8859 SINGLE SHIFT THREE control character'
 333              ],
 334              [
 335                  "Delete ISO 8859\xC2\x90 DEVICE CONTROL STRING control character", 1, null,
 336                  'Delete ISO 8859 DEVICE CONTROL STRING control character'
 337              ],
 338              [
 339                  "Delete ISO 8859\xC2\x91 PRIVATE USE ONE control character", 1, null,
 340                  'Delete ISO 8859 PRIVATE USE ONE control character'
 341              ],
 342              [
 343                  "Delete ISO 8859\xC2\x92 PRIVATE USE TWO control character", 1, null,
 344                  'Delete ISO 8859 PRIVATE USE TWO control character'
 345              ],
 346              [
 347                  "Delete ISO 8859\xC2\x93 SET TRANSMIT STATE control character", 1, null,
 348                  'Delete ISO 8859 SET TRANSMIT STATE control character'
 349              ],
 350              [
 351                  "Delete ISO 8859\xC2\x95 MESSAGE WAITING control character", 1, null,
 352                  'Delete ISO 8859 MESSAGE WAITING control character'
 353              ],
 354              [
 355                  "Delete ISO 8859\xC2\x96 START OF GUARDED AREA control character", 1, null,
 356                  'Delete ISO 8859 START OF GUARDED AREA control character'
 357              ],
 358              [
 359                  "Delete ISO 8859\xC2\x97 END OF GUARDED AREA control character", 1, null,
 360                  'Delete ISO 8859 END OF GUARDED AREA control character'
 361              ],
 362              [
 363                  "Delete ISO 8859\xC2\x99 SINGLE GRAPHIC CHARACTER INTRODUCER control character", 1, null,
 364                  'Delete ISO 8859 SINGLE GRAPHIC CHARACTER INTRODUCER control character'
 365              ],
 366              [
 367                  "Delete ISO 8859\xC2\x9A SINGLE CHARACTER INTRODUCER control character", 1, null,
 368                  'Delete ISO 8859 SINGLE CHARACTER INTRODUCER control character'
 369              ],
 370              [
 371                  "Delete ISO 8859\xC2\x9B CONTROL SEQUENCE INTRODUCER control character", 1, null,
 372                  'Delete ISO 8859 CONTROL SEQUENCE INTRODUCER control character'
 373              ],
 374              [
 375                  "Delete ISO 8859\xC2\x9D OPERATING SYSTEM COMMAND control character", 1, null,
 376                  'Delete ISO 8859 OPERATING SYSTEM COMMAND control character'
 377              ],
 378              [
 379                  "Delete ISO 8859\xC2\x9E PRIVACY MESSAGE control character", 1, null,
 380                  'Delete ISO 8859 PRIVACY MESSAGE control character'
 381              ],
 382              [
 383                  "Delete ISO 8859\xC2\x9F APPLICATION PROGRAM COMMAND control character", 1, null,
 384                  'Delete ISO 8859 APPLICATION PROGRAM COMMAND control character'
 385              ],
 386              [
 387                  "Delete Unicode\xE2\x80\x8B ZERO WIDTH SPACE control character", 1, null,
 388                  'Delete Unicode ZERO WIDTH SPACE control character'
 389              ],
 390              [
 391                  "Delete Unicode\xEF\xBB\xBF ZERO WIDTH NO-BREAK SPACE control character", 1, null,
 392                  'Delete Unicode ZERO WIDTH NO-BREAK SPACE control character'
 393              ],
 394              [
 395                  "Delete Unicode\xEF\xBF\xBD REPLACEMENT CHARACTER control character", 1, null,
 396                  'Delete Unicode REPLACEMENT CHARACTER control character'
 397              ],
 398              // Syntax sanity v2 strings.
 399              [
 400                  'No change', 2, null,
 401                  'No change'
 402              ],
 403              [
 404                  'Completed 100% of work', 2, null,
 405                  'Completed 100% of work'
 406              ],
 407              [
 408                  '%%%% HEADER %%%%', 2, null,
 409                  '%%%% HEADER %%%%'
 410              ], // Was not possible before.
 411              [
 412                  "Windows\r\nsucks", 2, null,
 413                  "Windows\nsucks"
 414              ],
 415              [
 416                  "Linux\nsucks", 2, null,
 417                  "Linux\nsucks"
 418              ],
 419              [
 420                  "Mac\rsucks", 2, null,
 421                  "Mac\nsucks"
 422              ],
 423              [
 424                  "LINE TABULATION\x0Bnewline", 2, null,
 425                  "LINE TABULATION\nnewline"
 426              ],
 427              [
 428                  "FORM FEED\x0Cnewline", 2, null,
 429                  "FORM FEED\nnewline"
 430              ],
 431              [
 432                  "END OF TRANSMISSION BLOCK\x17newline", 2, null,
 433                  "END OF TRANSMISSION BLOCK\nnewline"
 434              ],
 435              [
 436                  "END OF MEDIUM\x19newline", 2, null,
 437                  "END OF MEDIUM\nnewline"
 438              ],
 439              [
 440                  "SUBSTITUTE\x1Anewline", 2, null,
 441                  "SUBSTITUTE\nnewline"
 442              ],
 443              [
 444                  "BREAK PERMITTED HERE\xC2\x82newline", 2, null,
 445                  "BREAK PERMITTED HERE\nnewline"
 446              ],
 447              [
 448                  "NEXT LINE\xC2\x85newline", 2, null,
 449                  "NEXT LINE\nnewline"
 450              ],
 451              [
 452                  "START OF STRING\xC2\x98newline", 2, null,
 453                  "START OF STRING\nnewline"
 454              ],
 455              [
 456                  "STRING TERMINATOR\xC2\x9Cnewline", 2, null,
 457                  "STRING TERMINATOR\nnewline"
 458              ],
 459              [
 460                  "Unicode Zl\xE2\x80\xA8newline", 2, null,
 461                  "Unicode Zl\nnewline"
 462              ],
 463              [
 464                  "Unicode Zp\xE2\x80\xA9newline", 2, null,
 465                  "Unicode Zp\nnewline"
 466              ],
 467              [
 468                  "Empty\n\n\n\n\n\nlines", 2, null,
 469                  "Empty\n\n\nlines"
 470              ], // Now allows up to two empty lines.
 471              [
 472                  "Trailing   \n  whitespace\t\nat \nmultilines  ", 2, null,
 473                  "Trailing\n  whitespace\nat\nmultilines"
 474              ],
 475              [
 476                  'Do not escape $variable names', 2, null,
 477                  'Do not escape $variable names'
 478              ],
 479              [
 480                  'Do not escape $alike names', 2, null,
 481                  'Do not escape $alike names'
 482              ],
 483              [
 484                  'Not $a placeholder', 2, null,
 485                  'Not $a placeholder'
 486              ],
 487              [
 488                  'String {$a} placeholder', 2, null,
 489                  'String {$a} placeholder'
 490              ],
 491              [
 492                  'Trailing {$a}', 2, null,
 493                  'Trailing {$a}'
 494              ],
 495              [
 496                  '{$a} leading', 2, null,
 497                  '{$a} leading'
 498              ],
 499              [
 500                  'Trailing $a', 2, null,
 501                  'Trailing $a'
 502              ],
 503              [
 504                  '$a leading', 2, null,
 505                  '$a leading'
 506              ],
 507              [
 508                  'Not $a->foo placeholder', 2, null,
 509                  'Not $a->foo placeholder'
 510              ],
 511              [
 512                  'Object {$a->foo} placeholder', 2, null,
 513                  'Object {$a->foo} placeholder'
 514              ],
 515              [
 516                  'Trailing $a->bar', 2, null,
 517                  'Trailing $a->bar'
 518              ],
 519              [
 520                  'Invalid $a-> placeholder', 2, null,
 521                  'Invalid $a-> placeholder'
 522              ],
 523              [
 524                  '<strong>AMOS</strong>', 2, null,
 525                  '<strong>AMOS</strong>'
 526              ],
 527              [
 528                  "'Murder!', she wrote", 2, null,
 529                  "'Murder!', she wrote"
 530              ], // Will be escaped by var_export().
 531              [
 532                  "\t  Trim Hunter  \t\t", 2, null,
 533                  'Trim Hunter'
 534              ],
 535              [
 536                  'Delete role "$a->role"?', 2, null,
 537                  'Delete role "$a->role"?'
 538              ],
 539              [
 540                  'Delete role \"$a->role\"?', 2, null,
 541                  'Delete role \"$a->role\"?'
 542              ],
 543              [
 544                  "Delete ASCII\0 NULL control character", 2, null,
 545                  'Delete ASCII NULL control character'
 546              ],
 547              [
 548                  "Delete ASCII\x05 ENQUIRY control character", 2, null,
 549                  'Delete ASCII ENQUIRY control character'
 550              ],
 551              [
 552                  "Delete ASCII\x06 ACKNOWLEDGE control character", 2, null,
 553                  'Delete ASCII ACKNOWLEDGE control character'
 554              ],
 555              [
 556                  "Delete ASCII\x07 BELL control character", 2, null,
 557                  'Delete ASCII BELL control character'
 558              ],
 559              [
 560                  "Delete ASCII\x0E SHIFT OUT control character", 2, null,
 561                  'Delete ASCII SHIFT OUT control character'
 562              ],
 563              [
 564                  "Delete ASCII\x0F SHIFT IN control character", 2, null,
 565                  'Delete ASCII SHIFT IN control character'
 566              ],
 567              [
 568                  "Delete ASCII\x10 DATA LINK ESCAPE control character", 2, null,
 569                  'Delete ASCII DATA LINK ESCAPE control character'
 570              ],
 571              [
 572                  "Delete ASCII\x11 DEVICE CONTROL ONE control character", 2, null,
 573                  'Delete ASCII DEVICE CONTROL ONE control character'
 574              ],
 575              [
 576                  "Delete ASCII\x12 DEVICE CONTROL TWO control character", 2, null,
 577                  'Delete ASCII DEVICE CONTROL TWO control character'
 578              ],
 579              [
 580                  "Delete ASCII\x13 DEVICE CONTROL THREE control character", 2, null,
 581                  'Delete ASCII DEVICE CONTROL THREE control character'
 582              ],
 583              [
 584                  "Delete ASCII\x14 DEVICE CONTROL FOUR control character", 2, null,
 585                  'Delete ASCII DEVICE CONTROL FOUR control character'
 586              ],
 587              [
 588                  "Delete ASCII\x15 NEGATIVE ACKNOWLEDGE control character", 2, null,
 589                  'Delete ASCII NEGATIVE ACKNOWLEDGE control character'
 590              ],
 591              [
 592                  "Delete ASCII\x16 SYNCHRONOUS IDLE control character", 2, null,
 593                  'Delete ASCII SYNCHRONOUS IDLE control character'
 594              ],
 595              [
 596                  "Delete ASCII\x1B ESCAPE control character", 2, null,
 597                  'Delete ASCII ESCAPE control character'
 598              ],
 599              [
 600                  "Delete ASCII\x7F DELETE control character", 2, null,
 601                  'Delete ASCII DELETE control character'
 602              ],
 603              [
 604                  "Delete ISO 8859\xC2\x80 PADDING CHARACTER control character", 2, null,
 605                  'Delete ISO 8859 PADDING CHARACTER control character'
 606              ],
 607              [
 608                  "Delete ISO 8859\xC2\x81 HIGH OCTET PRESET control character", 2, null,
 609                  'Delete ISO 8859 HIGH OCTET PRESET control character'
 610              ],
 611              [
 612                  "Delete ISO 8859\xC2\x83 NO BREAK HERE control character", 2, null,
 613                  'Delete ISO 8859 NO BREAK HERE control character'
 614              ],
 615              [
 616                  "Delete ISO 8859\xC2\x84 INDEX control character", 2, null,
 617                  'Delete ISO 8859 INDEX control character'
 618              ],
 619              [
 620                  "Delete ISO 8859\xC2\x86 START OF SELECTED AREA control character", 2, null,
 621                  'Delete ISO 8859 START OF SELECTED AREA control character'
 622              ],
 623              [
 624                  "Delete ISO 8859\xC2\x87 END OF SELECTED AREA control character", 2, null,
 625                  'Delete ISO 8859 END OF SELECTED AREA control character'
 626              ],
 627              [
 628                  "Delete ISO 8859\xC2\x88 CHARACTER TABULATION SET control character", 2, null,
 629                  'Delete ISO 8859 CHARACTER TABULATION SET control character'
 630              ],
 631              [
 632                  "Delete ISO 8859\xC2\x89 CHARACTER TABULATION WITH JUSTIFICATION control character", 2, null,
 633                  'Delete ISO 8859 CHARACTER TABULATION WITH JUSTIFICATION control character'
 634              ],
 635              [
 636                  "Delete ISO 8859\xC2\x8A LINE TABULATION SET control character", 2, null,
 637                  'Delete ISO 8859 LINE TABULATION SET control character'
 638              ],
 639              [
 640                  "Delete ISO 8859\xC2\x8B PARTIAL LINE FORWARD control character", 2, null,
 641                  'Delete ISO 8859 PARTIAL LINE FORWARD control character'
 642              ],
 643              [
 644                  "Delete ISO 8859\xC2\x8C PARTIAL LINE BACKWARD control character", 2, null,
 645                  'Delete ISO 8859 PARTIAL LINE BACKWARD control character'
 646              ],
 647              [
 648                  "Delete ISO 8859\xC2\x8D REVERSE LINE FEED control character", 2, null,
 649                  'Delete ISO 8859 REVERSE LINE FEED control character'
 650              ],
 651              [
 652                  "Delete ISO 8859\xC2\x8E SINGLE SHIFT TWO control character", 2, null,
 653                  'Delete ISO 8859 SINGLE SHIFT TWO control character'
 654              ],
 655              [
 656                  "Delete ISO 8859\xC2\x8F SINGLE SHIFT THREE control character", 2, null,
 657                  'Delete ISO 8859 SINGLE SHIFT THREE control character'
 658              ],
 659              [
 660                  "Delete ISO 8859\xC2\x90 DEVICE CONTROL STRING control character", 2, null,
 661                  'Delete ISO 8859 DEVICE CONTROL STRING control character'
 662              ],
 663              [
 664                  "Delete ISO 8859\xC2\x91 PRIVATE USE ONE control character", 2, null,
 665                  'Delete ISO 8859 PRIVATE USE ONE control character'
 666              ],
 667              [
 668                  "Delete ISO 8859\xC2\x92 PRIVATE USE TWO control character", 2, null,
 669                  'Delete ISO 8859 PRIVATE USE TWO control character'
 670              ],
 671              [
 672                  "Delete ISO 8859\xC2\x93 SET TRANSMIT STATE control character", 2, null,
 673                  'Delete ISO 8859 SET TRANSMIT STATE control character'
 674              ],
 675              [
 676                  "Delete ISO 8859\xC2\x95 MESSAGE WAITING control character", 2, null,
 677                  'Delete ISO 8859 MESSAGE WAITING control character'
 678              ],
 679              [
 680                  "Delete ISO 8859\xC2\x96 START OF GUARDED AREA control character", 2, null,
 681                  'Delete ISO 8859 START OF GUARDED AREA control character'
 682              ],
 683              [
 684                  "Delete ISO 8859\xC2\x97 END OF GUARDED AREA control character", 2, null,
 685                  'Delete ISO 8859 END OF GUARDED AREA control character'
 686              ],
 687              [
 688                  "Delete ISO 8859\xC2\x99 SINGLE GRAPHIC CHARACTER INTRODUCER control character", 2, null,
 689                  'Delete ISO 8859 SINGLE GRAPHIC CHARACTER INTRODUCER control character'
 690              ],
 691              [
 692                  "Delete ISO 8859\xC2\x9A SINGLE CHARACTER INTRODUCER control character", 2, null,
 693                  'Delete ISO 8859 SINGLE CHARACTER INTRODUCER control character'
 694              ],
 695              [
 696                  "Delete ISO 8859\xC2\x9B CONTROL SEQUENCE INTRODUCER control character", 2, null,
 697                  'Delete ISO 8859 CONTROL SEQUENCE INTRODUCER control character'
 698              ],
 699              [
 700                  "Delete ISO 8859\xC2\x9D OPERATING SYSTEM COMMAND control character", 2, null,
 701                  'Delete ISO 8859 OPERATING SYSTEM COMMAND control character'
 702              ],
 703              [
 704                  "Delete ISO 8859\xC2\x9E PRIVACY MESSAGE control character", 2, null,
 705                  'Delete ISO 8859 PRIVACY MESSAGE control character'
 706              ],
 707              [
 708                  "Delete ISO 8859\xC2\x9F APPLICATION PROGRAM COMMAND control character", 2, null,
 709                  'Delete ISO 8859 APPLICATION PROGRAM COMMAND control character'
 710              ],
 711              [
 712                  "Delete Unicode\xE2\x80\x8B ZERO WIDTH SPACE control character", 2, null,
 713                  'Delete Unicode ZERO WIDTH SPACE control character'
 714              ],
 715              [
 716                  "Delete Unicode\xEF\xBB\xBF ZERO WIDTH NO-BREAK SPACE control character", 2, null,
 717                  'Delete Unicode ZERO WIDTH NO-BREAK SPACE control character'
 718              ],
 719              [
 720                  "Delete Unicode\xEF\xBF\xBD REPLACEMENT CHARACTER control character", 2, null,
 721                  'Delete Unicode REPLACEMENT CHARACTER control character'
 722              ],
 723              // Conterting from v1 to v2.
 724              [
 725                  'No change', 2, 1,
 726                  'No change'
 727              ],
 728              [
 729                  'Completed 100% of work', 2, 1,
 730                  'Completed 100% of work'
 731              ],
 732              [
 733                  'Completed 100%% of work', 2, 1,
 734                  'Completed 100% of work'
 735              ],
 736              [
 737                  "Windows\r\nsucks", 2, 1,
 738                  "Windows\nsucks"
 739              ],
 740              [
 741                  "Linux\nsucks", 2, 1,
 742                  "Linux\nsucks"
 743              ],
 744              [
 745                  "Mac\rsucks", 2, 1,
 746                  "Mac\nsucks"
 747              ],
 748              [
 749                  "LINE TABULATION\x0Bnewline", 2, 1,
 750                  "LINE TABULATION\nnewline"
 751              ],
 752              [
 753                  "FORM FEED\x0Cnewline", 2, 1,
 754                  "FORM FEED\nnewline"
 755              ],
 756              [
 757                  "END OF TRANSMISSION BLOCK\x17newline", 2, 1,
 758                  "END OF TRANSMISSION BLOCK\nnewline"
 759              ],
 760              [
 761                  "END OF MEDIUM\x19newline", 2, 1,
 762                  "END OF MEDIUM\nnewline"
 763              ],
 764              [
 765                  "SUBSTITUTE\x1Anewline", 2, 1,
 766                  "SUBSTITUTE\nnewline"
 767              ],
 768              [
 769                  "BREAK PERMITTED HERE\xC2\x82newline", 2, 1,
 770                  "BREAK PERMITTED HERE\nnewline"
 771              ],
 772              [
 773                  "NEXT LINE\xC2\x85newline", 2, 1,
 774                  "NEXT LINE\nnewline"
 775              ],
 776              [
 777                  "START OF STRING\xC2\x98newline", 2, 1,
 778                  "START OF STRING\nnewline"
 779              ],
 780              [
 781                  "STRING TERMINATOR\xC2\x9Cnewline", 2, 1,
 782                  "STRING TERMINATOR\nnewline"
 783              ],
 784              [
 785                  "Unicode Zl\xE2\x80\xA8newline", 2, 1,
 786                  "Unicode Zl\nnewline"
 787              ],
 788              [
 789                  "Unicode Zp\xE2\x80\xA9newline", 2, 1,
 790                  "Unicode Zp\nnewline"
 791              ],
 792              [
 793                  "Empty\n\n\n\n\n\nlines", 2, 1,
 794                  "Empty\n\n\nlines"
 795              ],
 796              [
 797                  "Trailing   \n  whitespace\t\nat \nmultilines  ", 2, 1,
 798                  "Trailing\n  whitespace\nat\nmultilines"
 799              ],
 800              [
 801                  'Do not escape $variable names', 2, 1,
 802                  'Do not escape $variable names'
 803              ],
 804              [
 805                  'Do not escape \$variable names', 2, 1,
 806                  'Do not escape $variable names'
 807              ],
 808              [
 809                  'Do not escape $alike names', 2, 1,
 810                  'Do not escape $alike names'
 811              ],
 812              [
 813                  'Do not escape \$alike names', 2, 1,
 814                  'Do not escape $alike names'
 815              ],
 816              [
 817                  'Do not escape \$a names', 2, 1,
 818                  'Do not escape $a names'
 819              ],
 820              [
 821                  'String $a placeholder', 2, 1,
 822                  'String {$a} placeholder'
 823              ],
 824              [
 825                  'String {$a} placeholder', 2, 1,
 826                  'String {$a} placeholder'
 827              ],
 828              [
 829                  'Trailing $a', 2, 1,
 830                  'Trailing {$a}'
 831              ],
 832              [
 833                  '$a leading', 2, 1,
 834                  '{$a} leading'
 835              ],
 836              [
 837                  '$a', 2, 1,
 838                  '{$a}'
 839              ],
 840              [
 841                  '$a->single', 2, 1,
 842                  '{$a->single}'
 843              ],
 844              [
 845                  'Trailing $a->foobar', 2, 1,
 846                  'Trailing {$a->foobar}'
 847              ],
 848              [
 849                  'Trailing {$a}', 2, 1,
 850                  'Trailing {$a}'
 851              ],
 852              [
 853                  'Hit $a-times', 2, 1,
 854                  'Hit {$a}-times'
 855              ],
 856              [
 857                  'This is $a_book', 2, 1,
 858                  'This is $a_book'
 859              ],
 860              [
 861                  'Object $a->foo placeholder', 2, 1,
 862                  'Object {$a->foo} placeholder'
 863              ],
 864              [
 865                  'Object {$a->foo} placeholder', 2, 1,
 866                  'Object {$a->foo} placeholder'
 867              ],
 868              [
 869                  'Trailing $a->bar', 2, 1,
 870                  'Trailing {$a->bar}'
 871              ],
 872              [
 873                  'Trailing {$a->bar}', 2, 1,
 874                  'Trailing {$a->bar}'
 875              ],
 876              [
 877                  'Invalid $a-> placeholder', 2, 1,
 878                  'Invalid {$a}-> placeholder'
 879                  ], // Weird but BC.
 880              [
 881                  '<strong>AMOS</strong>', 2, 1,
 882                  '<strong>AMOS</strong>'
 883              ],
 884              [
 885                  "'Murder!', she wrote", 2, 1,
 886                  "'Murder!', she wrote"
 887              ], // Will be escaped by var_export().
 888              [
 889                  "\'Murder!\', she wrote", 2, 1,
 890                  "'Murder!', she wrote"
 891              ], // Will be escaped by var_export().
 892              [
 893                  "\t  Trim Hunter  \t\t", 2, 1,
 894                  'Trim Hunter'
 895              ],
 896              [
 897                  'Delete role "$a->role"?', 2, 1,
 898                  'Delete role "{$a->role}"?'
 899              ],
 900              [
 901                  'Delete role \"$a->role\"?', 2, 1,
 902                  'Delete role "{$a->role}"?'
 903              ],
 904              [
 905                  'See &#36;CFG->foo', 2, 1,
 906                  'See $CFG->foo'
 907              ],
 908              [
 909                  "Delete ASCII\0 NULL control character", 2, 1,
 910                  'Delete ASCII NULL control character'
 911              ],
 912              [
 913                  "Delete ASCII\x05 ENQUIRY control character", 2, 1,
 914                  'Delete ASCII ENQUIRY control character'
 915              ],
 916              [
 917                  "Delete ASCII\x06 ACKNOWLEDGE control character", 2, 1,
 918                  'Delete ASCII ACKNOWLEDGE control character'
 919              ],
 920              [
 921                  "Delete ASCII\x07 BELL control character", 2, 1,
 922                  'Delete ASCII BELL control character'
 923              ],
 924              [
 925                  "Delete ASCII\x0E SHIFT OUT control character", 2, 1,
 926                  'Delete ASCII SHIFT OUT control character'
 927              ],
 928              [
 929                  "Delete ASCII\x0F SHIFT IN control character", 2, 1,
 930                  'Delete ASCII SHIFT IN control character'
 931              ],
 932              [
 933                  "Delete ASCII\x10 DATA LINK ESCAPE control character", 2, 1,
 934                  'Delete ASCII DATA LINK ESCAPE control character'
 935              ],
 936              [
 937                  "Delete ASCII\x11 DEVICE CONTROL ONE control character", 2, 1,
 938                  'Delete ASCII DEVICE CONTROL ONE control character'
 939              ],
 940              [
 941                  "Delete ASCII\x12 DEVICE CONTROL TWO control character", 2, 1,
 942                  'Delete ASCII DEVICE CONTROL TWO control character'
 943              ],
 944              [
 945                  "Delete ASCII\x13 DEVICE CONTROL THREE control character", 2, 1,
 946                  'Delete ASCII DEVICE CONTROL THREE control character'
 947              ],
 948              [
 949                  "Delete ASCII\x14 DEVICE CONTROL FOUR control character", 2, 1,
 950                  'Delete ASCII DEVICE CONTROL FOUR control character'
 951              ],
 952              [
 953                  "Delete ASCII\x15 NEGATIVE ACKNOWLEDGE control character", 2, 1,
 954                  'Delete ASCII NEGATIVE ACKNOWLEDGE control character'
 955              ],
 956              [
 957                  "Delete ASCII\x16 SYNCHRONOUS IDLE control character", 2, 1,
 958                  'Delete ASCII SYNCHRONOUS IDLE control character'
 959              ],
 960              [
 961                  "Delete ASCII\x1B ESCAPE control character", 2, 1,
 962                  'Delete ASCII ESCAPE control character'
 963              ],
 964              [
 965                  "Delete ASCII\x7F DELETE control character", 2, 1,
 966                  'Delete ASCII DELETE control character'
 967              ],
 968              [
 969                  "Delete ISO 8859\xC2\x80 PADDING CHARACTER control character", 2, 1,
 970                  'Delete ISO 8859 PADDING CHARACTER control character'
 971              ],
 972              [
 973                  "Delete ISO 8859\xC2\x81 HIGH OCTET PRESET control character", 2, 1,
 974                  'Delete ISO 8859 HIGH OCTET PRESET control character'
 975              ],
 976              [
 977                  "Delete ISO 8859\xC2\x83 NO BREAK HERE control character", 2, 1,
 978                  'Delete ISO 8859 NO BREAK HERE control character'
 979              ],
 980              [
 981                  "Delete ISO 8859\xC2\x84 INDEX control character", 2, 1,
 982                  'Delete ISO 8859 INDEX control character'
 983              ],
 984              [
 985                  "Delete ISO 8859\xC2\x86 START OF SELECTED AREA control character", 2, 1,
 986                  'Delete ISO 8859 START OF SELECTED AREA control character'
 987              ],
 988              [
 989                  "Delete ISO 8859\xC2\x87 END OF SELECTED AREA control character", 2, 1,
 990                  'Delete ISO 8859 END OF SELECTED AREA control character'
 991              ],
 992              [
 993                  "Delete ISO 8859\xC2\x88 CHARACTER TABULATION SET control character", 2, 1,
 994                  'Delete ISO 8859 CHARACTER TABULATION SET control character'
 995              ],
 996              [
 997                  "Delete ISO 8859\xC2\x89 CHARACTER TABULATION WITH JUSTIFICATION control character", 2, 1,
 998                  'Delete ISO 8859 CHARACTER TABULATION WITH JUSTIFICATION control character'
 999              ],
1000              [
1001                  "Delete ISO 8859\xC2\x8A LINE TABULATION SET control character", 2, 1,
1002                  'Delete ISO 8859 LINE TABULATION SET control character'
1003              ],
1004              [
1005                  "Delete ISO 8859\xC2\x8B PARTIAL LINE FORWARD control character", 2, 1,
1006                  'Delete ISO 8859 PARTIAL LINE FORWARD control character'
1007              ],
1008              [
1009                  "Delete ISO 8859\xC2\x8C PARTIAL LINE BACKWARD control character", 2, 1,
1010                  'Delete ISO 8859 PARTIAL LINE BACKWARD control character'
1011              ],
1012              [
1013                  "Delete ISO 8859\xC2\x8D REVERSE LINE FEED control character", 2, 1,
1014                  'Delete ISO 8859 REVERSE LINE FEED control character'
1015              ],
1016              [
1017                  "Delete ISO 8859\xC2\x8E SINGLE SHIFT TWO control character", 2, 1,
1018                  'Delete ISO 8859 SINGLE SHIFT TWO control character'
1019              ],
1020              [
1021                  "Delete ISO 8859\xC2\x8F SINGLE SHIFT THREE control character", 2, 1,
1022                  'Delete ISO 8859 SINGLE SHIFT THREE control character'
1023              ],
1024              [
1025                  "Delete ISO 8859\xC2\x90 DEVICE CONTROL STRING control character", 2, 1,
1026                  'Delete ISO 8859 DEVICE CONTROL STRING control character'
1027              ],
1028              [
1029                  "Delete ISO 8859\xC2\x91 PRIVATE USE ONE control character", 2, 1,
1030                  'Delete ISO 8859 PRIVATE USE ONE control character'
1031              ],
1032              [
1033                  "Delete ISO 8859\xC2\x92 PRIVATE USE TWO control character", 2, 1,
1034                  'Delete ISO 8859 PRIVATE USE TWO control character'
1035              ],
1036              [
1037                  "Delete ISO 8859\xC2\x93 SET TRANSMIT STATE control character", 2, 1,
1038                  'Delete ISO 8859 SET TRANSMIT STATE control character'
1039              ],
1040              [
1041                  "Delete ISO 8859\xC2\x95 MESSAGE WAITING control character", 2, 1,
1042                  'Delete ISO 8859 MESSAGE WAITING control character'
1043              ],
1044              [
1045                  "Delete ISO 8859\xC2\x96 START OF GUARDED AREA control character", 2, 1,
1046                  'Delete ISO 8859 START OF GUARDED AREA control character'
1047              ],
1048              [
1049                  "Delete ISO 8859\xC2\x97 END OF GUARDED AREA control character", 2, 1,
1050                  'Delete ISO 8859 END OF GUARDED AREA control character'
1051              ],
1052              [
1053                  "Delete ISO 8859\xC2\x99 SINGLE GRAPHIC CHARACTER INTRODUCER control character", 2, 1,
1054                  'Delete ISO 8859 SINGLE GRAPHIC CHARACTER INTRODUCER control character'
1055              ],
1056              [
1057                  "Delete ISO 8859\xC2\x9A SINGLE CHARACTER INTRODUCER control character", 2, 1,
1058                  'Delete ISO 8859 SINGLE CHARACTER INTRODUCER control character'
1059              ],
1060              [
1061                  "Delete ISO 8859\xC2\x9B CONTROL SEQUENCE INTRODUCER control character", 2, 1,
1062                  'Delete ISO 8859 CONTROL SEQUENCE INTRODUCER control character'
1063              ],
1064              [
1065                  "Delete ISO 8859\xC2\x9D OPERATING SYSTEM COMMAND control character", 2, 1,
1066                  'Delete ISO 8859 OPERATING SYSTEM COMMAND control character'
1067              ],
1068              [
1069                  "Delete ISO 8859\xC2\x9E PRIVACY MESSAGE control character", 2, 1,
1070                  'Delete ISO 8859 PRIVACY MESSAGE control character'
1071              ],
1072              [
1073                  "Delete ISO 8859\xC2\x9F APPLICATION PROGRAM COMMAND control character", 2, 1,
1074                  'Delete ISO 8859 APPLICATION PROGRAM COMMAND control character'
1075              ],
1076              [
1077                  "Delete Unicode\xE2\x80\x8B ZERO WIDTH SPACE control character", 2, 1,
1078                  'Delete Unicode ZERO WIDTH SPACE control character'
1079              ],
1080              [
1081                  "Delete Unicode\xEF\xBB\xBF ZERO WIDTH NO-BREAK SPACE control character", 2, 1,
1082                  'Delete Unicode ZERO WIDTH NO-BREAK SPACE control character'
1083              ],
1084              [
1085                  "Delete Unicode\xEF\xBF\xBD REPLACEMENT CHARACTER control character", 2, 1,
1086                  'Delete Unicode REPLACEMENT CHARACTER control character'
1087              ],
1088          ];
1089      }
1090  }