🌐 AI搜索 & 代理 主页
Skip to content

Commit 50871a5

Browse files
skrobinsonmgol
authored andcommitted
Ajax: Do not execute scripts for unsuccessful HTTP responses
The script transport used to evaluate fetched script sources which is undesirable for unsuccessful HTTP responses. This is different to other data types where such a convention was fine (e.g. in case of JSON). Fixes gh-4250 Closes gh-4379
1 parent 9df4f1d commit 50871a5

File tree

4 files changed

+145
-0
lines changed

4 files changed

+145
-0
lines changed

src/ajax.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -748,6 +748,11 @@ jQuery.extend( {
748748
response = ajaxHandleResponses( s, jqXHR, responses );
749749
}
750750

751+
// Use a noop converter for missing script
752+
if ( !isSuccess && jQuery.inArray( "script", s.dataTypes ) > -1 ) {
753+
s.converters[ "text script" ] = function() {};
754+
}
755+
751756
// Convert no matter what (that way responseXXX fields are always set)
752757
response = ajaxConvert( s, response, jqXHR, isSuccess );
753758

test/data/mock.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,19 @@ protected function cspClean( $req ) {
216216
unlink( $this->cspFile );
217217
}
218218

219+
protected function errorWithScript( $req ) {
220+
header( 'HTTP/1.0 404 Not Found' );
221+
if ( isset( $req->query['withScriptContentType'] ) ) {
222+
header( 'Content-Type: application/javascript' );
223+
}
224+
if ( isset( $req->query['callback'] ) ) {
225+
$callback = $req->query['callback'];
226+
echo $callback . '( {"status": 404, "msg": "Not Found"} )';
227+
} else {
228+
echo 'QUnit.assert.ok( false, "Mock return erroneously executed" );';
229+
}
230+
}
231+
219232
public function __construct() {
220233
$this->cspFile = __DIR__ . '/support/csp.log';
221234
}

test/middleware-mockserver.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,18 @@ var mocks = {
226226
cspLog = "";
227227
resp.writeHead( 200 );
228228
resp.end();
229+
},
230+
errorWithScript: function( req, resp ) {
231+
if ( req.query.withScriptContentType ) {
232+
resp.writeHead( 404, { "Content-Type": "application/javascript" } );
233+
} else {
234+
resp.writeHead( 404 );
235+
}
236+
if ( req.query.callback ) {
237+
resp.end( req.query.callback + "( {\"status\": 404, \"msg\": \"Not Found\"} )" );
238+
} else {
239+
resp.end( "QUnit.assert.ok( false, \"Mock return erroneously executed\" );" );
240+
}
229241
}
230242
};
231243
var handlers = {

test/unit/ajax.js

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -806,6 +806,121 @@ QUnit.module( "ajax", {
806806
};
807807
} );
808808

809+
ajaxTest( "jQuery.ajax() - do not execute scripts from unsuccessful responses (gh-4250)", 11, function( assert ) {
810+
var globalEval = jQuery.globalEval;
811+
812+
var failConverters = {
813+
"text script": function() {
814+
assert.ok( false, "No converter for unsuccessful response" );
815+
}
816+
};
817+
818+
function request( title, options ) {
819+
var testMsg = title + ": expected file missing status";
820+
return jQuery.extend( {
821+
beforeSend: function() {
822+
jQuery.globalEval = function() {
823+
assert.ok( false, "Should not eval" );
824+
};
825+
},
826+
complete: function() {
827+
jQuery.globalEval = globalEval;
828+
},
829+
// error is the significant assertion
830+
error: function( xhr ) {
831+
assert.strictEqual( xhr.status, 404, testMsg );
832+
},
833+
success: function() {
834+
assert.ok( false, "Unanticipated success" );
835+
}
836+
}, options );
837+
}
838+
839+
return [
840+
request(
841+
"HTML reply",
842+
{
843+
url: url( "404.txt" )
844+
}
845+
),
846+
request(
847+
"HTML reply with dataType",
848+
{
849+
dataType: "script",
850+
url: url( "404.txt" )
851+
}
852+
),
853+
request(
854+
"script reply",
855+
{
856+
url: url( "mock.php?action=errorWithScript&withScriptContentType" )
857+
}
858+
),
859+
request(
860+
"non-script reply",
861+
{
862+
url: url( "mock.php?action=errorWithScript" )
863+
}
864+
),
865+
request(
866+
"script reply with dataType",
867+
{
868+
dataType: "script",
869+
url: url( "mock.php?action=errorWithScript&withScriptContentType" )
870+
}
871+
),
872+
request(
873+
"non-script reply with dataType",
874+
{
875+
dataType: "script",
876+
url: url( "mock.php?action=errorWithScript" )
877+
}
878+
),
879+
request(
880+
"script reply with converter",
881+
{
882+
converters: failConverters,
883+
url: url( "mock.php?action=errorWithScript&withScriptContentType" )
884+
}
885+
),
886+
request(
887+
"non-script reply with converter",
888+
{
889+
converters: failConverters,
890+
url: url( "mock.php?action=errorWithScript" )
891+
}
892+
),
893+
request(
894+
"script reply with converter and dataType",
895+
{
896+
converters: failConverters,
897+
dataType: "script",
898+
url: url( "mock.php?action=errorWithScript&withScriptContentType" )
899+
}
900+
),
901+
request(
902+
"non-script reply with converter and dataType",
903+
{
904+
converters: failConverters,
905+
dataType: "script",
906+
url: url( "mock.php?action=errorWithScript" )
907+
}
908+
),
909+
request(
910+
"JSONP reply with dataType",
911+
{
912+
dataType: "jsonp",
913+
url: url( "mock.php?action=errorWithScript" ),
914+
beforeSend: function() {
915+
jQuery.globalEval = function( response ) {
916+
assert.ok( /"status": 404, "msg": "Not Found"/.test( response ), "Error object returned" );
917+
};
918+
}
919+
}
920+
)
921+
];
922+
} );
923+
809924
ajaxTest( "jQuery.ajax() - synchronous request", 1, function( assert ) {
810925
return {
811926
url: url( "json_obj.js" ),

0 commit comments

Comments
 (0)