diff --git a/lib/twiml/TwiML.js b/lib/twiml/TwiML.js
index c8349acfa0..21ba893a73 100644
--- a/lib/twiml/TwiML.js
+++ b/lib/twiml/TwiML.js
@@ -12,9 +12,9 @@ function TwiML() {
stringify: {
attValue: function (value) {
if (Array.isArray(value)) {
- return value.join(' ');
+ value = value.join(' ');
}
- return value;
+ return this.attEscape('' + value || '');
}
}
}).dec('1.0', 'UTF-8');
diff --git a/spec/unit/twiml/VoiceResponse.spec.js b/spec/unit/twiml/VoiceResponse.spec.js
index f6a708506d..b0d1317bea 100644
--- a/spec/unit/twiml/VoiceResponse.spec.js
+++ b/spec/unit/twiml/VoiceResponse.spec.js
@@ -167,11 +167,18 @@ describe('create voice response TwiML', function() {
it('should serialize array attributes as space delimited', function() {
var actual = new VoiceResponse();
- actual.dial().number({ statusCallbackEvents: ["initiated", "ringing"] }, '+11234567890')
+ actual.dial().number({ statusCallbackEvents: ['initiated', 'ringing'] }, '+11234567890');
expect(actual.toString()).toEqual('+11234567890');
});
+ it('should escape special characters', function() {
+ var actual = new VoiceResponse();
+ actual.dial().number({ statusCallback: 'https://example.com?action=getTwiml¶m=dial' }, '+11234567890');
+
+ expect(actual.toString()).toEqual('+11234567890');
+ });
+
it('should allow adding arbitrary text to leaf nodes', function() {
var actual = new VoiceResponse();
actual.hangup().addText('extra text');