511 * covers all common link protocols, except for 'javascript' which should not |
516 * covers all common link protocols, except for 'javascript' which should not |
512 * be allowed for untrusted users. |
517 * be allowed for untrusted users. |
513 * |
518 * |
514 * @since 1.0.0 |
519 * @since 1.0.0 |
515 * |
520 * |
516 * @param string $string Content to filter through kses |
521 * @param string $string Content to filter through kses |
517 * @param array $allowed_html List of allowed HTML elements |
522 * @param array $allowed_html List of allowed HTML elements |
518 * @param array $allowed_protocols Optional. Allowed protocol in links. |
523 * @param array $allowed_protocols Optional. Allowed protocol in links. |
519 * @return string Filtered content with only allowed HTML elements |
524 * @return string Filtered content with only allowed HTML elements |
520 */ |
525 */ |
521 function wp_kses( $string, $allowed_html, $allowed_protocols = array() ) { |
526 function wp_kses( $string, $allowed_html, $allowed_protocols = array() ) { |
522 if ( empty( $allowed_protocols ) ) |
527 if ( empty( $allowed_protocols ) ) |
523 $allowed_protocols = wp_allowed_protocols(); |
528 $allowed_protocols = wp_allowed_protocols(); |
524 $string = wp_kses_no_null($string); |
529 $string = wp_kses_no_null( $string, array( 'slash_zero' => 'keep' ) ); |
525 $string = wp_kses_js_entities($string); |
|
526 $string = wp_kses_normalize_entities($string); |
530 $string = wp_kses_normalize_entities($string); |
527 $string = wp_kses_hook($string, $allowed_html, $allowed_protocols); // WP changed the order of these funcs and added args to wp_kses_hook |
531 $string = wp_kses_hook($string, $allowed_html, $allowed_protocols); // WP changed the order of these funcs and added args to wp_kses_hook |
528 return wp_kses_split($string, $allowed_html, $allowed_protocols); |
532 return wp_kses_split($string, $allowed_html, $allowed_protocols); |
529 } |
533 } |
530 |
534 |
531 /** |
535 /** |
|
536 * Filters one attribute only and ensures its value is allowed. |
|
537 * |
|
538 * This function has the advantage of being more secure than esc_attr() and can |
|
539 * escape data in some situations where wp_kses() must strip the whole attribute. |
|
540 * |
|
541 * @since 4.2.3 |
|
542 * |
|
543 * @param string $string The 'whole' attribute, including name and value. |
|
544 * @param string $element The element name to which the attribute belongs. |
|
545 * @return string Filtered attribute. |
|
546 */ |
|
547 function wp_kses_one_attr( $string, $element ) { |
|
548 $uris = array('xmlns', 'profile', 'href', 'src', 'cite', 'classid', 'codebase', 'data', 'usemap', 'longdesc', 'action'); |
|
549 $allowed_html = wp_kses_allowed_html( 'post' ); |
|
550 $allowed_protocols = wp_allowed_protocols(); |
|
551 $string = wp_kses_no_null( $string, array( 'slash_zero' => 'keep' ) ); |
|
552 |
|
553 // Preserve leading and trailing whitespace. |
|
554 $matches = array(); |
|
555 preg_match('/^\s*/', $string, $matches); |
|
556 $lead = $matches[0]; |
|
557 preg_match('/\s*$/', $string, $matches); |
|
558 $trail = $matches[0]; |
|
559 if ( empty( $trail ) ) { |
|
560 $string = substr( $string, strlen( $lead ) ); |
|
561 } else { |
|
562 $string = substr( $string, strlen( $lead ), -strlen( $trail ) ); |
|
563 } |
|
564 |
|
565 // Parse attribute name and value from input. |
|
566 $split = preg_split( '/\s*=\s*/', $string, 2 ); |
|
567 $name = $split[0]; |
|
568 if ( count( $split ) == 2 ) { |
|
569 $value = $split[1]; |
|
570 |
|
571 // Remove quotes surrounding $value. |
|
572 // Also guarantee correct quoting in $string for this one attribute. |
|
573 if ( '' == $value ) { |
|
574 $quote = ''; |
|
575 } else { |
|
576 $quote = $value[0]; |
|
577 } |
|
578 if ( '"' == $quote || "'" == $quote ) { |
|
579 if ( substr( $value, -1 ) != $quote ) { |
|
580 return ''; |
|
581 } |
|
582 $value = substr( $value, 1, -1 ); |
|
583 } else { |
|
584 $quote = '"'; |
|
585 } |
|
586 |
|
587 // Sanitize quotes, angle braces, and entities. |
|
588 $value = esc_attr( $value ); |
|
589 |
|
590 // Sanitize URI values. |
|
591 if ( in_array( strtolower( $name ), $uris ) ) { |
|
592 $value = wp_kses_bad_protocol( $value, $allowed_protocols ); |
|
593 } |
|
594 |
|
595 $string = "$name=$quote$value$quote"; |
|
596 $vless = 'n'; |
|
597 } else { |
|
598 $value = ''; |
|
599 $vless = 'y'; |
|
600 } |
|
601 |
|
602 // Sanitize attribute by name. |
|
603 wp_kses_attr_check( $name, $value, $string, $vless, $element, $allowed_html ); |
|
604 |
|
605 // Restore whitespace. |
|
606 return $lead . $string . $trail; |
|
607 } |
|
608 |
|
609 /** |
532 * Return a list of allowed tags and attributes for a given context. |
610 * Return a list of allowed tags and attributes for a given context. |
533 * |
611 * |
534 * @since 3.5.0 |
612 * @since 3.5.0 |
535 * |
613 * |
536 * @param string $context The context for which to retrieve tags. Allowed values are |
614 * @global array $allowedposttags |
537 * post | strip | data | entities or the name of a field filter such as pre_user_description. |
615 * @global array $allowedtags |
|
616 * @global array $allowedentitynames |
|
617 * |
|
618 * @param string|array $context The context for which to retrieve tags. |
|
619 * Allowed values are post, strip, data, entities, or |
|
620 * the name of a field filter such as pre_user_description. |
538 * @return array List of allowed tags and their allowed attributes. |
621 * @return array List of allowed tags and their allowed attributes. |
539 */ |
622 */ |
540 function wp_kses_allowed_html( $context = '' ) { |
623 function wp_kses_allowed_html( $context = '' ) { |
541 global $allowedposttags, $allowedtags, $allowedentitynames; |
624 global $allowedposttags, $allowedtags, $allowedentitynames; |
542 |
625 |
543 if ( is_array( $context ) ) { |
626 if ( is_array( $context ) ) { |
544 /** |
627 /** |
545 * Filter HTML elements allowed for a given context. |
628 * Filters HTML elements allowed for a given context. |
546 * |
629 * |
547 * @since 3.5.0 |
630 * @since 3.5.0 |
548 * |
631 * |
549 * @param string $tags Allowed tags, attributes, and/or entities. |
632 * @param array $context Context to judge allowed tags by. |
550 * @param string $context Context to judge allowed tags by. Allowed values are 'post', |
633 * @param string $context_type Context type (explicit). |
551 * 'data', 'strip', 'entities', 'explicit', or the name of a filter. |
|
552 */ |
634 */ |
553 return apply_filters( 'wp_kses_allowed_html', $context, 'explicit' ); |
635 return apply_filters( 'wp_kses_allowed_html', $context, 'explicit' ); |
554 } |
636 } |
555 |
637 |
556 switch ( $context ) { |
638 switch ( $context ) { |
581 } |
663 } |
582 |
664 |
583 /** |
665 /** |
584 * You add any kses hooks here. |
666 * You add any kses hooks here. |
585 * |
667 * |
586 * There is currently only one kses WordPress hook and it is called here. All |
668 * There is currently only one kses WordPress hook, {@see 'pre_kses'}, and it is called here. |
587 * parameters are passed to the hooks and expected to receive a string. |
669 * All parameters are passed to the hooks and expected to receive a string. |
588 * |
670 * |
589 * @since 1.0.0 |
671 * @since 1.0.0 |
590 * |
672 * |
591 * @param string $string Content to filter through kses |
673 * @param string $string Content to filter through kses |
592 * @param array $allowed_html List of allowed HTML elements |
674 * @param array $allowed_html List of allowed HTML elements |
593 * @param array $allowed_protocols Allowed protocol in links |
675 * @param array $allowed_protocols Allowed protocol in links |
594 * @return string Filtered content through 'pre_kses' hook |
676 * @return string Filtered content through {@see 'pre_kses'} hook. |
595 */ |
677 */ |
596 function wp_kses_hook( $string, $allowed_html, $allowed_protocols ) { |
678 function wp_kses_hook( $string, $allowed_html, $allowed_protocols ) { |
597 /** |
679 /** |
598 * Filter content to be run through kses. |
680 * Filters content to be run through kses. |
599 * |
681 * |
600 * @since 2.3.0 |
682 * @since 2.3.0 |
601 * |
683 * |
602 * @param string $string Content to run through kses. |
684 * @param string $string Content to run through kses. |
603 * @param array $allowed_html Allowed HTML elements. |
685 * @param array $allowed_html Allowed HTML elements. |
604 * @param array $allowed_protocols Allowed protocol in links. |
686 * @param array $allowed_protocols Allowed protocol in links. |
605 */ |
687 */ |
606 $string = apply_filters( 'pre_kses', $string, $allowed_html, $allowed_protocols ); |
688 return apply_filters( 'pre_kses', $string, $allowed_html, $allowed_protocols ); |
607 return $string; |
|
608 } |
689 } |
609 |
690 |
610 /** |
691 /** |
611 * This function returns kses' version number. |
692 * This function returns kses' version number. |
612 * |
693 * |
720 * is to check if the tag has a closing XHTML slash, and if it does, it puts one |
809 * is to check if the tag has a closing XHTML slash, and if it does, it puts one |
721 * in the returned code as well. |
810 * in the returned code as well. |
722 * |
811 * |
723 * @since 1.0.0 |
812 * @since 1.0.0 |
724 * |
813 * |
725 * @param string $element HTML element/tag |
814 * @param string $element HTML element/tag |
726 * @param string $attr HTML attributes from HTML element to closing HTML element tag |
815 * @param string $attr HTML attributes from HTML element to closing HTML element tag |
727 * @param array $allowed_html Allowed HTML elements |
816 * @param array $allowed_html Allowed HTML elements |
728 * @param array $allowed_protocols Allowed protocols to keep |
817 * @param array $allowed_protocols Allowed protocols to keep |
729 * @return string Sanitized HTML element |
818 * @return string Sanitized HTML element |
730 */ |
819 */ |
731 function wp_kses_attr($element, $attr, $allowed_html, $allowed_protocols) { |
820 function wp_kses_attr($element, $attr, $allowed_html, $allowed_protocols) { |
732 // Is there a closing XHTML slash at the end of the attributes? |
|
733 |
|
734 if ( ! is_array( $allowed_html ) ) |
821 if ( ! is_array( $allowed_html ) ) |
735 $allowed_html = wp_kses_allowed_html( $allowed_html ); |
822 $allowed_html = wp_kses_allowed_html( $allowed_html ); |
736 |
823 |
|
824 // Is there a closing XHTML slash at the end of the attributes? |
737 $xhtml_slash = ''; |
825 $xhtml_slash = ''; |
738 if (preg_match('%\s*/\s*$%', $attr)) |
826 if (preg_match('%\s*/\s*$%', $attr)) |
739 $xhtml_slash = ' /'; |
827 $xhtml_slash = ' /'; |
740 |
828 |
741 // Are any attributes allowed at all for this element? |
829 // Are any attributes allowed at all for this element? |
742 if ( ! isset($allowed_html[strtolower($element)]) || count($allowed_html[strtolower($element)]) == 0 ) |
830 $element_low = strtolower( $element ); |
|
831 if ( empty( $allowed_html[ $element_low ] ) || true === $allowed_html[ $element_low ] ) { |
743 return "<$element$xhtml_slash>"; |
832 return "<$element$xhtml_slash>"; |
|
833 } |
744 |
834 |
745 // Split it |
835 // Split it |
746 $attrarr = wp_kses_hair($attr, $allowed_protocols); |
836 $attrarr = wp_kses_hair($attr, $allowed_protocols); |
747 |
837 |
748 // Go through $attrarr, and save the allowed attributes for this element |
838 // Go through $attrarr, and save the allowed attributes for this element |
749 // in $attr2 |
839 // in $attr2 |
750 $attr2 = ''; |
840 $attr2 = ''; |
751 |
841 foreach ( $attrarr as $arreach ) { |
752 $allowed_attr = $allowed_html[strtolower($element)]; |
842 if ( wp_kses_attr_check( $arreach['name'], $arreach['value'], $arreach['whole'], $arreach['vless'], $element, $allowed_html ) ) { |
753 foreach ($attrarr as $arreach) { |
843 $attr2 .= ' '.$arreach['whole']; |
754 if ( ! isset( $allowed_attr[strtolower($arreach['name'])] ) ) |
|
755 continue; // the attribute is not allowed |
|
756 |
|
757 $current = $allowed_attr[strtolower($arreach['name'])]; |
|
758 if ( $current == '' ) |
|
759 continue; // the attribute is not allowed |
|
760 |
|
761 if ( strtolower( $arreach['name'] ) == 'style' ) { |
|
762 $orig_value = $arreach['value']; |
|
763 $value = safecss_filter_attr( $orig_value ); |
|
764 |
|
765 if ( empty( $value ) ) |
|
766 continue; |
|
767 |
|
768 $arreach['value'] = $value; |
|
769 $arreach['whole'] = str_replace( $orig_value, $value, $arreach['whole'] ); |
|
770 } |
844 } |
771 |
845 } |
772 if ( ! is_array($current) ) { |
|
773 $attr2 .= ' '.$arreach['whole']; |
|
774 // there are no checks |
|
775 |
|
776 } else { |
|
777 // there are some checks |
|
778 $ok = true; |
|
779 foreach ($current as $currkey => $currval) { |
|
780 if ( ! wp_kses_check_attr_val($arreach['value'], $arreach['vless'], $currkey, $currval) ) { |
|
781 $ok = false; |
|
782 break; |
|
783 } |
|
784 } |
|
785 |
|
786 if ( $ok ) |
|
787 $attr2 .= ' '.$arreach['whole']; // it passed them |
|
788 } // if !is_array($current) |
|
789 } // foreach |
|
790 |
846 |
791 // Remove any "<" or ">" characters |
847 // Remove any "<" or ">" characters |
792 $attr2 = preg_replace('/[<>]/', '', $attr2); |
848 $attr2 = preg_replace('/[<>]/', '', $attr2); |
793 |
849 |
794 return "<$element$attr2$xhtml_slash>"; |
850 return "<$element$attr2$xhtml_slash>"; |
|
851 } |
|
852 |
|
853 /** |
|
854 * Determine whether an attribute is allowed. |
|
855 * |
|
856 * @since 4.2.3 |
|
857 * |
|
858 * @param string $name The attribute name. Returns empty string when not allowed. |
|
859 * @param string $value The attribute value. Returns a filtered value. |
|
860 * @param string $whole The name=value input. Returns filtered input. |
|
861 * @param string $vless 'y' when attribute like "enabled", otherwise 'n'. |
|
862 * @param string $element The name of the element to which this attribute belongs. |
|
863 * @param array $allowed_html The full list of allowed elements and attributes. |
|
864 * @return bool Is the attribute allowed? |
|
865 */ |
|
866 function wp_kses_attr_check( &$name, &$value, &$whole, $vless, $element, $allowed_html ) { |
|
867 $allowed_attr = $allowed_html[strtolower( $element )]; |
|
868 |
|
869 $name_low = strtolower( $name ); |
|
870 if ( ! isset( $allowed_attr[$name_low] ) || '' == $allowed_attr[$name_low] ) { |
|
871 $name = $value = $whole = ''; |
|
872 return false; |
|
873 } |
|
874 |
|
875 if ( 'style' == $name_low ) { |
|
876 $new_value = safecss_filter_attr( $value ); |
|
877 |
|
878 if ( empty( $new_value ) ) { |
|
879 $name = $value = $whole = ''; |
|
880 return false; |
|
881 } |
|
882 |
|
883 $whole = str_replace( $value, $new_value, $whole ); |
|
884 $value = $new_value; |
|
885 } |
|
886 |
|
887 if ( is_array( $allowed_attr[$name_low] ) ) { |
|
888 // there are some checks |
|
889 foreach ( $allowed_attr[$name_low] as $currkey => $currval ) { |
|
890 if ( ! wp_kses_check_attr_val( $value, $vless, $currkey, $currval ) ) { |
|
891 $name = $value = $whole = ''; |
|
892 return false; |
|
893 } |
|
894 } |
|
895 } |
|
896 |
|
897 return true; |
795 } |
898 } |
796 |
899 |
797 /** |
900 /** |
798 * Builds an attribute list from string containing attributes. |
901 * Builds an attribute list from string containing attributes. |
799 * |
902 * |
922 |
1025 |
923 return $attrarr; |
1026 return $attrarr; |
924 } |
1027 } |
925 |
1028 |
926 /** |
1029 /** |
|
1030 * Finds all attributes of an HTML element. |
|
1031 * |
|
1032 * Does not modify input. May return "evil" output. |
|
1033 * |
|
1034 * Based on wp_kses_split2() and wp_kses_attr() |
|
1035 * |
|
1036 * @since 4.2.3 |
|
1037 * |
|
1038 * @param string $element HTML element/tag |
|
1039 * @return array|bool List of attributes found in $element. Returns false on failure. |
|
1040 */ |
|
1041 function wp_kses_attr_parse( $element ) { |
|
1042 $valid = preg_match('%^(<\s*)(/\s*)?([a-zA-Z0-9]+\s*)([^>]*)(>?)$%', $element, $matches); |
|
1043 if ( 1 !== $valid ) { |
|
1044 return false; |
|
1045 } |
|
1046 |
|
1047 $begin = $matches[1]; |
|
1048 $slash = $matches[2]; |
|
1049 $elname = $matches[3]; |
|
1050 $attr = $matches[4]; |
|
1051 $end = $matches[5]; |
|
1052 |
|
1053 if ( '' !== $slash ) { |
|
1054 // Closing elements do not get parsed. |
|
1055 return false; |
|
1056 } |
|
1057 |
|
1058 // Is there a closing XHTML slash at the end of the attributes? |
|
1059 if ( 1 === preg_match( '%\s*/\s*$%', $attr, $matches ) ) { |
|
1060 $xhtml_slash = $matches[0]; |
|
1061 $attr = substr( $attr, 0, -strlen( $xhtml_slash ) ); |
|
1062 } else { |
|
1063 $xhtml_slash = ''; |
|
1064 } |
|
1065 |
|
1066 // Split it |
|
1067 $attrarr = wp_kses_hair_parse( $attr ); |
|
1068 if ( false === $attrarr ) { |
|
1069 return false; |
|
1070 } |
|
1071 |
|
1072 // Make sure all input is returned by adding front and back matter. |
|
1073 array_unshift( $attrarr, $begin . $slash . $elname ); |
|
1074 array_push( $attrarr, $xhtml_slash . $end ); |
|
1075 |
|
1076 return $attrarr; |
|
1077 } |
|
1078 |
|
1079 /** |
|
1080 * Builds an attribute list from string containing attributes. |
|
1081 * |
|
1082 * Does not modify input. May return "evil" output. |
|
1083 * In case of unexpected input, returns false instead of stripping things. |
|
1084 * |
|
1085 * Based on wp_kses_hair() but does not return a multi-dimensional array. |
|
1086 * |
|
1087 * @since 4.2.3 |
|
1088 * |
|
1089 * @param string $attr Attribute list from HTML element to closing HTML element tag |
|
1090 * @return array|bool List of attributes found in $attr. Returns false on failure. |
|
1091 */ |
|
1092 function wp_kses_hair_parse( $attr ) { |
|
1093 if ( '' === $attr ) { |
|
1094 return array(); |
|
1095 } |
|
1096 |
|
1097 $regex = |
|
1098 '(?:' |
|
1099 . '[-a-zA-Z:]+' // Attribute name. |
|
1100 . '|' |
|
1101 . '\[\[?[^\[\]]+\]\]?' // Shortcode in the name position implies unfiltered_html. |
|
1102 . ')' |
|
1103 . '(?:' // Attribute value. |
|
1104 . '\s*=\s*' // All values begin with '=' |
|
1105 . '(?:' |
|
1106 . '"[^"]*"' // Double-quoted |
|
1107 . '|' |
|
1108 . "'[^']*'" // Single-quoted |
|
1109 . '|' |
|
1110 . '[^\s"\']+' // Non-quoted |
|
1111 . '(?:\s|$)' // Must have a space |
|
1112 . ')' |
|
1113 . '|' |
|
1114 . '(?:\s|$)' // If attribute has no value, space is required. |
|
1115 . ')' |
|
1116 . '\s*'; // Trailing space is optional except as mentioned above. |
|
1117 |
|
1118 // Although it is possible to reduce this procedure to a single regexp, |
|
1119 // we must run that regexp twice to get exactly the expected result. |
|
1120 |
|
1121 $validation = "%^($regex)+$%"; |
|
1122 $extraction = "%$regex%"; |
|
1123 |
|
1124 if ( 1 === preg_match( $validation, $attr ) ) { |
|
1125 preg_match_all( $extraction, $attr, $attrarr ); |
|
1126 return $attrarr[0]; |
|
1127 } else { |
|
1128 return false; |
|
1129 } |
|
1130 } |
|
1131 |
|
1132 /** |
927 * Performs different checks for attribute values. |
1133 * Performs different checks for attribute values. |
928 * |
1134 * |
929 * The currently implemented checks are "maxlen", "minlen", "maxval", "minval" |
1135 * The currently implemented checks are "maxlen", "minlen", "maxval", "minval" |
930 * and "valueless". |
1136 * and "valueless". |
931 * |
1137 * |
932 * @since 1.0.0 |
1138 * @since 1.0.0 |
933 * |
1139 * |
934 * @param string $value Attribute value |
1140 * @param string $value Attribute value |
935 * @param string $vless Whether the value is valueless. Use 'y' or 'n' |
1141 * @param string $vless Whether the value is valueless. Use 'y' or 'n' |
936 * @param string $checkname What $checkvalue is checking for. |
1142 * @param string $checkname What $checkvalue is checking for. |
937 * @param mixed $checkvalue What constraint the value should pass |
1143 * @param mixed $checkvalue What constraint the value should pass |
938 * @return bool Whether check passes |
1144 * @return bool Whether check passes |
939 */ |
1145 */ |
940 function wp_kses_check_attr_val($value, $vless, $checkname, $checkvalue) { |
1146 function wp_kses_check_attr_val($value, $vless, $checkname, $checkvalue) { |
941 $ok = true; |
1147 $ok = true; |
942 |
1148 |
1181 * @param string $string Content to normalize entities |
1382 * @param string $string Content to normalize entities |
1182 * @return string Content with normalized entities |
1383 * @return string Content with normalized entities |
1183 */ |
1384 */ |
1184 function wp_kses_normalize_entities($string) { |
1385 function wp_kses_normalize_entities($string) { |
1185 // Disarm all entities by converting & to & |
1386 // Disarm all entities by converting & to & |
1186 |
|
1187 $string = str_replace('&', '&', $string); |
1387 $string = str_replace('&', '&', $string); |
1188 |
1388 |
1189 // Change back the allowed entities in our entity whitelist |
1389 // Change back the allowed entities in our entity whitelist |
1190 |
|
1191 $string = preg_replace_callback('/&([A-Za-z]{2,8}[0-9]{0,2});/', 'wp_kses_named_entities', $string); |
1390 $string = preg_replace_callback('/&([A-Za-z]{2,8}[0-9]{0,2});/', 'wp_kses_named_entities', $string); |
1192 $string = preg_replace_callback('/&#(0*[0-9]{1,7});/', 'wp_kses_normalize_entities2', $string); |
1391 $string = preg_replace_callback('/&#(0*[0-9]{1,7});/', 'wp_kses_normalize_entities2', $string); |
1193 $string = preg_replace_callback('/&#[Xx](0*[0-9A-Fa-f]{1,6});/', 'wp_kses_normalize_entities3', $string); |
1392 $string = preg_replace_callback('/&#[Xx](0*[0-9A-Fa-f]{1,6});/', 'wp_kses_normalize_entities3', $string); |
1194 |
1393 |
1195 return $string; |
1394 return $string; |
1201 * This function only accepts valid named entity references, which are finite, |
1400 * This function only accepts valid named entity references, which are finite, |
1202 * case-sensitive, and highly scrutinized by HTML and XML validators. |
1401 * case-sensitive, and highly scrutinized by HTML and XML validators. |
1203 * |
1402 * |
1204 * @since 3.0.0 |
1403 * @since 3.0.0 |
1205 * |
1404 * |
|
1405 * @global array $allowedentitynames |
|
1406 * |
1206 * @param array $matches preg_replace_callback() matches array |
1407 * @param array $matches preg_replace_callback() matches array |
1207 * @return string Correctly encoded entity |
1408 * @return string Correctly encoded entity |
1208 */ |
1409 */ |
1209 function wp_kses_named_entities($matches) { |
1410 function wp_kses_named_entities($matches) { |
1210 global $allowedentitynames; |
1411 global $allowedentitynames; |
1211 |
1412 |
1212 if ( empty($matches[1]) ) |
1413 if ( empty($matches[1]) ) |
1213 return ''; |
1414 return ''; |
1214 |
1415 |
1215 $i = $matches[1]; |
1416 $i = $matches[1]; |
1216 return ( ( ! in_array($i, $allowedentitynames) ) ? "&$i;" : "&$i;" ); |
1417 return ( ! in_array( $i, $allowedentitynames ) ) ? "&$i;" : "&$i;"; |
1217 } |
1418 } |
1218 |
1419 |
1219 /** |
1420 /** |
1220 * Callback for wp_kses_normalize_entities() regular expression. |
1421 * Callback for wp_kses_normalize_entities() regular expression. |
1221 * |
1422 * |
1222 * This function helps {@see wp_kses_normalize_entities()} to only accept 16-bit |
1423 * This function helps wp_kses_normalize_entities() to only accept 16-bit |
1223 * values and nothing more for `&#number;` entities. |
1424 * values and nothing more for `&#number;` entities. |
1224 * |
1425 * |
1225 * @access private |
1426 * @access private |
1226 * @since 1.0.0 |
1427 * @since 1.0.0 |
1227 * |
1428 * |
1247 * Callback for wp_kses_normalize_entities() for regular expression. |
1448 * Callback for wp_kses_normalize_entities() for regular expression. |
1248 * |
1449 * |
1249 * This function helps wp_kses_normalize_entities() to only accept valid Unicode |
1450 * This function helps wp_kses_normalize_entities() to only accept valid Unicode |
1250 * numeric entities in hex form. |
1451 * numeric entities in hex form. |
1251 * |
1452 * |
|
1453 * @since 2.7.0 |
1252 * @access private |
1454 * @access private |
1253 * |
1455 * |
1254 * @param array $matches preg_replace_callback() matches array |
1456 * @param array $matches preg_replace_callback() matches array |
1255 * @return string Correctly encoded entity |
1457 * @return string Correctly encoded entity |
1256 */ |
1458 */ |
1257 function wp_kses_normalize_entities3($matches) { |
1459 function wp_kses_normalize_entities3($matches) { |
1258 if ( empty($matches[1]) ) |
1460 if ( empty($matches[1]) ) |
1259 return ''; |
1461 return ''; |
1260 |
1462 |
1261 $hexchars = $matches[1]; |
1463 $hexchars = $matches[1]; |
1262 return ( ( ! valid_unicode(hexdec($hexchars)) ) ? "&#x$hexchars;" : '&#x'.ltrim($hexchars,'0').';' ); |
1464 return ( ! valid_unicode( hexdec( $hexchars ) ) ) ? "&#x$hexchars;" : '&#x'.ltrim($hexchars,'0').';'; |
1263 } |
1465 } |
1264 |
1466 |
1265 /** |
1467 /** |
1266 * Helper function to determine if a Unicode value is valid. |
1468 * Helper function to determine if a Unicode value is valid. |
|
1469 * |
|
1470 * @since 2.7.0 |
1267 * |
1471 * |
1268 * @param int $i Unicode value |
1472 * @param int $i Unicode value |
1269 * @return bool True if the value was a valid Unicode number |
1473 * @return bool True if the value was a valid Unicode number |
1270 */ |
1474 */ |
1271 function valid_unicode($i) { |
1475 function valid_unicode($i) { |
1469 return ''; |
1697 return ''; |
1470 |
1698 |
1471 $css_array = explode( ';', trim( $css ) ); |
1699 $css_array = explode( ';', trim( $css ) ); |
1472 |
1700 |
1473 /** |
1701 /** |
1474 * Filter list of allowed CSS attributes. |
1702 * Filters list of allowed CSS attributes. |
1475 * |
1703 * |
1476 * @since 2.8.1 |
1704 * @since 2.8.1 |
|
1705 * @since 4.4.0 Added support for `min-height`, `max-height`, `min-width`, and `max-width`. |
|
1706 * @since 4.6.0 Added support for `list-style-type`. |
1477 * |
1707 * |
1478 * @param array $attr List of allowed CSS attributes. |
1708 * @param array $attr List of allowed CSS attributes. |
1479 */ |
1709 */ |
1480 $allowed_attr = apply_filters( 'safe_style_css', array( 'text-align', 'margin', 'color', 'float', |
1710 $allowed_attr = apply_filters( 'safe_style_css', array( |
1481 'border', 'background', 'background-color', 'border-bottom', 'border-bottom-color', |
1711 'background', |
1482 'border-bottom-style', 'border-bottom-width', 'border-collapse', 'border-color', 'border-left', |
1712 'background-color', |
1483 'border-left-color', 'border-left-style', 'border-left-width', 'border-right', 'border-right-color', |
1713 |
1484 'border-right-style', 'border-right-width', 'border-spacing', 'border-style', 'border-top', |
1714 'border', |
1485 'border-top-color', 'border-top-style', 'border-top-width', 'border-width', 'caption-side', |
1715 'border-width', |
1486 'clear', 'cursor', 'direction', 'font', 'font-family', 'font-size', 'font-style', |
1716 'border-color', |
1487 'font-variant', 'font-weight', 'height', 'letter-spacing', 'line-height', 'margin-bottom', |
1717 'border-style', |
1488 'margin-left', 'margin-right', 'margin-top', 'overflow', 'padding', 'padding-bottom', |
1718 'border-right', |
1489 'padding-left', 'padding-right', 'padding-top', 'text-decoration', 'text-indent', 'vertical-align', |
1719 'border-right-color', |
1490 'width' ) ); |
1720 'border-right-style', |
|
1721 'border-right-width', |
|
1722 'border-bottom', |
|
1723 'border-bottom-color', |
|
1724 'border-bottom-style', |
|
1725 'border-bottom-width', |
|
1726 'border-left', |
|
1727 'border-left-color', |
|
1728 'border-left-style', |
|
1729 'border-left-width', |
|
1730 'border-top', |
|
1731 'border-top-color', |
|
1732 'border-top-style', |
|
1733 'border-top-width', |
|
1734 |
|
1735 'border-spacing', |
|
1736 'border-collapse', |
|
1737 'caption-side', |
|
1738 |
|
1739 'color', |
|
1740 'font', |
|
1741 'font-family', |
|
1742 'font-size', |
|
1743 'font-style', |
|
1744 'font-variant', |
|
1745 'font-weight', |
|
1746 'letter-spacing', |
|
1747 'line-height', |
|
1748 'text-decoration', |
|
1749 'text-indent', |
|
1750 'text-align', |
|
1751 |
|
1752 'height', |
|
1753 'min-height', |
|
1754 'max-height', |
|
1755 |
|
1756 'width', |
|
1757 'min-width', |
|
1758 'max-width', |
|
1759 |
|
1760 'margin', |
|
1761 'margin-right', |
|
1762 'margin-bottom', |
|
1763 'margin-left', |
|
1764 'margin-top', |
|
1765 |
|
1766 'padding', |
|
1767 'padding-right', |
|
1768 'padding-bottom', |
|
1769 'padding-left', |
|
1770 'padding-top', |
|
1771 |
|
1772 'clear', |
|
1773 'cursor', |
|
1774 'direction', |
|
1775 'float', |
|
1776 'overflow', |
|
1777 'vertical-align', |
|
1778 'list-style-type', |
|
1779 ) ); |
1491 |
1780 |
1492 if ( empty($allowed_attr) ) |
1781 if ( empty($allowed_attr) ) |
1493 return $css; |
1782 return $css; |
1494 |
1783 |
1495 $css = ''; |
1784 $css = ''; |