Changeset 41697
- Timestamp:
- 10/03/2017 03:43:01 AM (7 years ago)
- Location:
- trunk
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-admin/css/customize-nav-menus.css
r41670 r41697 560 560 #custom-menu-item-name.invalid, 561 561 #custom-menu-item-url.invalid, 562 .edit-menu-item-url.invalid, 562 563 .menu-name-field.invalid, 563 564 .menu-name-field.invalid:focus, -
trunk/src/wp-admin/js/customize-nav-menus.js
r41020 r41697 536 536 var menuItem, 537 537 itemName = $( '#custom-menu-item-name' ), 538 itemUrl = $( '#custom-menu-item-url' ); 538 itemUrl = $( '#custom-menu-item-url' ), 539 urlRegex, 540 urlValue; 539 541 540 542 if ( ! this.currentMenuControl ) { … … 542 544 } 543 545 546 /* 547 * Copyright (c) 2010-2013 Diego Perini, MIT licensed 548 * https://gist.github.com/dperini/729294 549 * see also https://mathiasbynens.be/demo/url-regex 550 * modified to allow protocol-relative URLs 551 */ 552 urlRegex = /^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})).?)(?::\d{2,5})?(?:[/?#]\S*)?$/i; 553 554 urlValue = itemUrl.val(); 544 555 if ( '' === itemName.val() ) { 545 556 itemName.addClass( 'invalid' ); 546 557 return; 547 } else if ( '' === itemUrl.val() || 'http://' === itemUrl.val() ) {558 } else if ( '' === urlValue || 'http://' === urlValue || ! ( '/' === urlValue[0] || urlRegex.test( urlValue ) ) ) { 548 559 itemUrl.addClass( 'invalid' ); 549 560 return; … … 552 563 menuItem = { 553 564 'title': itemName.val(), 554 'url': itemUrl.val(),565 'url': urlValue, 555 566 'type': 'custom', 556 567 'type_label': api.Menus.data.l10n.custom_label, … … 1388 1399 _setupUpdateUI: function() { 1389 1400 var control = this, 1390 settingValue = control.setting(); 1401 settingValue = control.setting(), 1402 updateNotifications; 1391 1403 1392 1404 control.elements = {}; … … 1471 1483 } 1472 1484 }); 1485 1486 // Style the URL field as invalid when there is an invalid_url notification. 1487 updateNotifications = function() { 1488 control.elements.url.element.toggleClass( 'invalid', control.setting.notifications.has( 'invalid_url' ) ); 1489 }; 1490 control.setting.notifications.bind( 'add', updateNotifications ); 1491 control.setting.notifications.bind( 'removed', updateNotifications ); 1473 1492 }, 1474 1493 -
trunk/src/wp-includes/customize/class-wp-customize-nav-menu-item-setting.php
r41162 r41697 642 642 * 643 643 * @param array $menu_item_value The value to sanitize. 644 * @return array|false|null Nullif an input isn't valid. False if it is marked for deletion.645 * Otherwise the sanitized value.644 * @return array|false|null|WP_Error Null or WP_Error if an input isn't valid. False if it is marked for deletion. 645 * Otherwise the sanitized value. 646 646 */ 647 647 public function sanitize( $menu_item_value ) { … … 702 702 $menu_item_value['description'] = wp_unslash( apply_filters( 'content_save_pre', wp_slash( $menu_item_value['description'] ) ) ); 703 703 704 $menu_item_value['url'] = esc_url_raw( $menu_item_value['url'] ); 704 if ( '' !== $menu_item_value['url'] ) { 705 $menu_item_value['url'] = esc_url_raw( $menu_item_value['url'] ); 706 if ( '' === $menu_item_value['url'] ) { 707 return new WP_Error( 'invalid_url', __( 'Invalid URL.' ) ); // Fail sanitization if URL is invalid. 708 } 709 } 705 710 if ( 'publish' !== $menu_item_value['status'] ) { 706 711 $menu_item_value['status'] = 'draft'; -
trunk/tests/phpunit/tests/customize/nav-menu-item-setting.php
r39393 r41697 473 473 $this->assertNull( $setting->sanitize( 123 ) ); 474 474 475 $valid_urls = array( 476 'http://example.com/', 477 'https://foo.example.com/hello.html', 478 'mailto:nobody@example.com?subject=hi', 479 'ftp://example.com/', 480 'ftps://example.com/', 481 'news://news.server.example/example.group.this', 482 'irc://irc.freenode.net/wordpress', 483 'gopher://example.com', 484 'nntp://news.server.example/example.group.this', 485 'feed://example.com/', 486 'telnet://example.com', 487 'mms://example.com', 488 'rtsp://example.com/', 489 'svn://develop.svn.wordpress.org/trunk', 490 'tel:000-000-000', 491 'fax:000-000-000', 492 'xmpp:user@host?message', 493 'webcal://example.com', 494 'urn:org.wordpress', 495 ); 496 foreach ( $valid_urls as $valid_url ) { 497 $url_setting = $setting->sanitize( array( 'url' => $valid_url ) ); 498 $this->assertInternalType( 'array', $url_setting ); 499 $this->assertEquals( $valid_url, $url_setting['url'] ); 500 } 501 502 $invalid_urls = array( 503 'javascript:alert(1)', 504 'unknown://something.out-there', 505 'smtp://user:pass@mailserver.thing', 506 ); 507 foreach ( $invalid_urls as $invalid_url ) { 508 $url_setting = $setting->sanitize( array( 'url' => $invalid_url ) ); 509 $this->assertInstanceOf( 'WP_Error', $url_setting ); 510 $this->assertEquals( 'invalid_url', $url_setting->get_error_code() ); 511 } 512 475 513 $unsanitized = array( 476 514 'object_id' => 'bad', … … 480 518 'type' => 'custom<b>', 481 519 'title' => '\o/ o\'o Hi<script>unfilteredHtml()</script>', 482 'url' => ' javascript:alert(1)',520 'url' => '', // Note the javascript: protocol is checked above and results in a hard validation error, beyond mere sanitization. 483 521 'target' => '" onclick="', 484 522 'attr_title' => '\o/ o\'o <b>bolded</b><script>unfilteredHtml()</script>',
Note: See TracChangeset
for help on using the changeset viewer.