diff --git a/NEWS b/NEWS
index 713008bfbb4..a69402fa57d 100644
--- a/NEWS
+++ b/NEWS
@@ -45,6 +45,8 @@ PHP NEWS
- Fixed bug #38217 (ReflectionClass::newInstanceArgs() tries to allocate too
much memory). (Tony)
- Fixed bug #38214 (gif interlace output cannot work). (Pierre)
+- Fixed bug #38213, #37611, #37571 (wddx encoding fails to handle certain
+ characters). (Ilia)
- Fixed bug #38212 (Segfault on invalid imagecreatefromgd2part() parameters).
(Pierre)
- Fixed bug #38211 (variable name and cookie name match breaks script
diff --git a/ext/wddx/tests/bug37569.phpt b/ext/wddx/tests/bug37569.phpt
index cc19bb0943f..f7422c9ec22 100755
--- a/ext/wddx/tests/bug37569.phpt
+++ b/ext/wddx/tests/bug37569.phpt
@@ -4,9 +4,775 @@ Bug #37569 (WDDX incorrectly encodes high-ascii characters)
--FILE--
--EXPECT--
-
-
+A
+int(65)
+int(65)
+bool(true)
+B
+int(66)
+int(66)
+bool(true)
+C
+int(67)
+int(67)
+bool(true)
+D
+int(68)
+int(68)
+bool(true)
+E
+int(69)
+int(69)
+bool(true)
+F
+int(70)
+int(70)
+bool(true)
+G
+int(71)
+int(71)
+bool(true)
+H
+int(72)
+int(72)
+bool(true)
+I
+int(73)
+int(73)
+bool(true)
+J
+int(74)
+int(74)
+bool(true)
+K
+int(75)
+int(75)
+bool(true)
+L
+int(76)
+int(76)
+bool(true)
+M
+int(77)
+int(77)
+bool(true)
+N
+int(78)
+int(78)
+bool(true)
+O
+int(79)
+int(79)
+bool(true)
+P
+int(80)
+int(80)
+bool(true)
+Q
+int(81)
+int(81)
+bool(true)
+R
+int(82)
+int(82)
+bool(true)
+S
+int(83)
+int(83)
+bool(true)
+T
+int(84)
+int(84)
+bool(true)
+U
+int(85)
+int(85)
+bool(true)
+V
+int(86)
+int(86)
+bool(true)
+W
+int(87)
+int(87)
+bool(true)
+X
+int(88)
+int(88)
+bool(true)
+Y
+int(89)
+int(89)
+bool(true)
+Z
+int(90)
+int(90)
+bool(true)
+[
+int(91)
+int(91)
+bool(true)
+\
+int(92)
+int(92)
+bool(true)
+]
+int(93)
+int(93)
+bool(true)
+^
+int(94)
+int(94)
+bool(true)
+_
+int(95)
+int(95)
+bool(true)
+`
+int(96)
+int(96)
+bool(true)
+a
+int(97)
+int(97)
+bool(true)
+b
+int(98)
+int(98)
+bool(true)
+c
+int(99)
+int(99)
+bool(true)
+d
+int(100)
+int(100)
+bool(true)
+e
+int(101)
+int(101)
+bool(true)
+f
+int(102)
+int(102)
+bool(true)
+g
+int(103)
+int(103)
+bool(true)
+h
+int(104)
+int(104)
+bool(true)
+i
+int(105)
+int(105)
+bool(true)
+j
+int(106)
+int(106)
+bool(true)
+k
+int(107)
+int(107)
+bool(true)
+l
+int(108)
+int(108)
+bool(true)
+m
+int(109)
+int(109)
+bool(true)
+n
+int(110)
+int(110)
+bool(true)
+o
+int(111)
+int(111)
+bool(true)
+p
+int(112)
+int(112)
+bool(true)
+q
+int(113)
+int(113)
+bool(true)
+r
+int(114)
+int(114)
+bool(true)
+s
+int(115)
+int(115)
+bool(true)
+t
+int(116)
+int(116)
+bool(true)
+u
+int(117)
+int(117)
+bool(true)
+v
+int(118)
+int(118)
+bool(true)
+w
+int(119)
+int(119)
+bool(true)
+x
+int(120)
+int(120)
+bool(true)
+y
+int(121)
+int(121)
+bool(true)
+z
+int(122)
+int(122)
+bool(true)
+{
+int(123)
+int(123)
+bool(true)
+|
+int(124)
+int(124)
+bool(true)
+}
+int(125)
+int(125)
+bool(true)
+~
+int(126)
+int(126)
+bool(true)
+
+int(127)
+int(127)
+bool(true)
+
+int(128)
+int(128)
+bool(true)
+
+int(129)
+int(129)
+bool(true)
+
+int(130)
+int(130)
+bool(true)
+
+int(131)
+int(131)
+bool(true)
+
+int(132)
+int(132)
+bool(true)
+
+int(133)
+int(133)
+bool(true)
+
+int(134)
+int(134)
+bool(true)
+
+int(135)
+int(135)
+bool(true)
+
+int(136)
+int(136)
+bool(true)
+
+int(137)
+int(137)
+bool(true)
+
+int(138)
+int(138)
+bool(true)
+
+int(139)
+int(139)
+bool(true)
+
+int(140)
+int(140)
+bool(true)
+
+int(141)
+int(141)
+bool(true)
+
+int(142)
+int(142)
+bool(true)
+
+int(143)
+int(143)
+bool(true)
+
+int(144)
+int(144)
+bool(true)
+
+int(145)
+int(145)
+bool(true)
+
+int(146)
+int(146)
+bool(true)
+
+int(147)
+int(147)
+bool(true)
+
+int(148)
+int(148)
+bool(true)
+
+int(149)
+int(149)
+bool(true)
+
+int(150)
+int(150)
+bool(true)
+
+int(151)
+int(151)
+bool(true)
+
+int(152)
+int(152)
+bool(true)
+
+int(153)
+int(153)
+bool(true)
+
+int(154)
+int(154)
+bool(true)
+
+int(155)
+int(155)
+bool(true)
+
+int(156)
+int(156)
+bool(true)
+
+int(157)
+int(157)
+bool(true)
+
+int(158)
+int(158)
+bool(true)
+
+int(159)
+int(159)
+bool(true)
+
+int(160)
+int(160)
+bool(true)
+¡
+int(161)
+int(161)
+bool(true)
+¢
+int(162)
+int(162)
+bool(true)
+£
+int(163)
+int(163)
+bool(true)
+¤
+int(164)
+int(164)
+bool(true)
+¥
+int(165)
+int(165)
+bool(true)
+¦
+int(166)
+int(166)
+bool(true)
+§
+int(167)
+int(167)
+bool(true)
+¨
+int(168)
+int(168)
+bool(true)
+©
+int(169)
+int(169)
+bool(true)
+ª
+int(170)
+int(170)
+bool(true)
+«
+int(171)
+int(171)
+bool(true)
+¬
+int(172)
+int(172)
+bool(true)
+
+int(173)
+int(173)
+bool(true)
+®
+int(174)
+int(174)
+bool(true)
+¯
+int(175)
+int(175)
+bool(true)
+°
+int(176)
+int(176)
+bool(true)
+±
+int(177)
+int(177)
+bool(true)
+²
+int(178)
+int(178)
+bool(true)
+³
+int(179)
+int(179)
+bool(true)
+´
+int(180)
+int(180)
+bool(true)
+µ
+int(181)
+int(181)
+bool(true)
+¶
+int(182)
+int(182)
+bool(true)
+·
+int(183)
+int(183)
+bool(true)
+¸
+int(184)
+int(184)
+bool(true)
+¹
+int(185)
+int(185)
+bool(true)
+º
+int(186)
+int(186)
+bool(true)
+»
+int(187)
+int(187)
+bool(true)
+¼
+int(188)
+int(188)
+bool(true)
+½
+int(189)
+int(189)
+bool(true)
+¾
+int(190)
+int(190)
+bool(true)
+¿
+int(191)
+int(191)
+bool(true)
+À
+int(192)
+int(192)
+bool(true)
+Á
+int(193)
+int(193)
+bool(true)
+Â
+int(194)
+int(194)
+bool(true)
+Ã
+int(195)
+int(195)
+bool(true)
+Ä
+int(196)
+int(196)
+bool(true)
+Å
+int(197)
+int(197)
+bool(true)
+Æ
+int(198)
+int(198)
+bool(true)
+Ç
+int(199)
+int(199)
+bool(true)
+È
+int(200)
+int(200)
+bool(true)
+É
+int(201)
+int(201)
+bool(true)
+Ê
+int(202)
+int(202)
+bool(true)
+Ë
+int(203)
+int(203)
+bool(true)
+Ì
+int(204)
+int(204)
+bool(true)
+Í
+int(205)
+int(205)
+bool(true)
+Î
+int(206)
+int(206)
+bool(true)
+Ï
+int(207)
+int(207)
+bool(true)
+Ð
+int(208)
+int(208)
+bool(true)
+Ñ
+int(209)
+int(209)
+bool(true)
+Ò
+int(210)
+int(210)
+bool(true)
+Ó
+int(211)
+int(211)
+bool(true)
+Ô
+int(212)
+int(212)
+bool(true)
+Õ
+int(213)
+int(213)
+bool(true)
+Ö
+int(214)
+int(214)
+bool(true)
+×
+int(215)
+int(215)
+bool(true)
+Ø
+int(216)
+int(216)
+bool(true)
+Ù
+int(217)
+int(217)
+bool(true)
+Ú
+int(218)
+int(218)
+bool(true)
+Û
+int(219)
+int(219)
+bool(true)
+Ü
+int(220)
+int(220)
+bool(true)
+Ý
+int(221)
+int(221)
+bool(true)
+Þ
+int(222)
+int(222)
+bool(true)
+ß
+int(223)
+int(223)
+bool(true)
+à
+int(224)
+int(224)
+bool(true)
+á
+int(225)
+int(225)
+bool(true)
+â
+int(226)
+int(226)
+bool(true)
+ã
+int(227)
+int(227)
+bool(true)
+ä
+int(228)
+int(228)
+bool(true)
+å
+int(229)
+int(229)
+bool(true)
+æ
+int(230)
+int(230)
+bool(true)
+ç
+int(231)
+int(231)
+bool(true)
+è
+int(232)
+int(232)
+bool(true)
+é
+int(233)
+int(233)
+bool(true)
+ê
+int(234)
+int(234)
+bool(true)
+ë
+int(235)
+int(235)
+bool(true)
+ì
+int(236)
+int(236)
+bool(true)
+í
+int(237)
+int(237)
+bool(true)
+î
+int(238)
+int(238)
+bool(true)
+ï
+int(239)
+int(239)
+bool(true)
+ð
+int(240)
+int(240)
+bool(true)
+ñ
+int(241)
+int(241)
+bool(true)
+ò
+int(242)
+int(242)
+bool(true)
+ó
+int(243)
+int(243)
+bool(true)
+ô
+int(244)
+int(244)
+bool(true)
+õ
+int(245)
+int(245)
+bool(true)
+ö
+int(246)
+int(246)
+bool(true)
+÷
+int(247)
+int(247)
+bool(true)
+ø
+int(248)
+int(248)
+bool(true)
+ù
+int(249)
+int(249)
+bool(true)
+ú
+int(250)
+int(250)
+bool(true)
+û
+int(251)
+int(251)
+bool(true)
+ü
+int(252)
+int(252)
+bool(true)
+ý
+int(253)
+int(253)
+bool(true)
+þ
+int(254)
+int(254)
+bool(true)
+ÿ
+int(255)
+int(255)
+bool(true)
\ No newline at end of file
diff --git a/ext/wddx/wddx.c b/ext/wddx/wddx.c
index 37b94d76641..dcbf6a6bf3f 100644
--- a/ext/wddx/wddx.c
+++ b/ext/wddx/wddx.c
@@ -368,51 +368,20 @@ void php_wddx_packet_end(wddx_packet *packet)
*/
static void php_wddx_serialize_string(wddx_packet *packet, zval *var)
{
- char *buf,
- *p,
- *vend,
- control_buf[WDDX_BUF_LEN];
- int l;
-
php_wddx_add_chunk_static(packet, WDDX_STRING_S);
if (Z_STRLEN_P(var) > 0) {
- l = 0;
- vend = Z_STRVAL_P(var) + Z_STRLEN_P(var);
- buf = (char *)emalloc(Z_STRLEN_P(var) + 1);
-
- for(p = Z_STRVAL_P(var); p != vend; p++) {
- switch (*p) {
- case '<':
- FLUSH_BUF();
- php_wddx_add_chunk_static(packet, "<");
- break;
-
- case '&':
- FLUSH_BUF();
- php_wddx_add_chunk_static(packet, "&");
- break;
-
- case '>':
- FLUSH_BUF();
- php_wddx_add_chunk_static(packet, ">");
- break;
-
- default:
- if (iscntrl((int)*(unsigned char *)p) || (int)*(unsigned char *)p >= 127) {
- FLUSH_BUF();
- sprintf(control_buf, WDDX_CHAR, (int)*(unsigned char *)p);
- php_wddx_add_chunk(packet, control_buf);
- } else
- buf[l++] = *p;
- break;
- }
- }
+ char *buf, *enc;
+ int buf_len, enc_len;
+
+ buf = php_escape_html_entities(Z_STRVAL_P(var), Z_STRLEN_P(var), &buf_len, 0, ENT_QUOTES, NULL TSRMLS_CC);
+ enc = xml_utf8_encode(buf, buf_len, &enc_len, "ISO-8859-1");
+
+ php_wddx_add_chunk_ex(packet, enc, enc_len);
- FLUSH_BUF();
efree(buf);
+ efree(enc);
}
-
php_wddx_add_chunk_static(packet, WDDX_STRING_E);
}
/* }}} */