Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit 49e809c

Browse files
committed
fix($http): only parse as JSON when opening/closing brackets match
Previously, due to weak JSON-detecting RegExp, string like `[...}` and `{...]` would be considered JSON (even if they obviously aren't) and an expection would be thrown while trying to parse them. This commit makes sure the opening and closing brackets match. This doesn't completely eliminate false positives (e.g. `[]{}[]`), but does help reduce them. Closes #10349
1 parent facfec9 commit 49e809c

File tree

2 files changed

+25
-3
lines changed

2 files changed

+25
-3
lines changed

src/ng/http.js

+11-3
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,11 @@
22

33
var APPLICATION_JSON = 'application/json';
44
var CONTENT_TYPE_APPLICATION_JSON = {'Content-Type': APPLICATION_JSON + ';charset=utf-8'};
5-
var JSON_START = /^\s*(\[|\{[^\{])/;
6-
var JSON_END = /[\}\]]\s*$/;
5+
var JSON_START = /^\s*(\[|\{(?!\{))/;
6+
var JSON_ENDS = {
7+
'[': /\]\s*$/,
8+
'{': /\}\s*$/
9+
};
710
var JSON_PROTECTION_PREFIX = /^\)\]\}',?\n/;
811

912
function defaultHttpResponseTransform(data, headers) {
@@ -12,13 +15,18 @@ function defaultHttpResponseTransform(data, headers) {
1215
data = data.replace(JSON_PROTECTION_PREFIX, '');
1316
var contentType = headers('Content-Type');
1417
if ((contentType && contentType.indexOf(APPLICATION_JSON) === 0 && data.trim()) ||
15-
(JSON_START.test(data) && JSON_END.test(data))) {
18+
isJsonLike(data)) {
1619
data = fromJson(data);
1720
}
1821
}
1922
return data;
2023
}
2124

25+
function isJsonLike(str) {
26+
var jsonStart = str.match(JSON_START);
27+
return jsonStart && JSON_ENDS[jsonStart[1]].test(str);
28+
}
29+
2230
/**
2331
* Parse headers into key value object
2432
*

test/ng/httpSpec.js

+14
Original file line numberDiff line numberDiff line change
@@ -1173,6 +1173,20 @@ describe('$http', function() {
11731173
expect(callback).toHaveBeenCalledOnce();
11741174
expect(callback.mostRecentCall.args[0]).toEqual('{{some}}');
11751175
});
1176+
1177+
it('should not deserialize json when the opening and closing brackets do not match',
1178+
function() {
1179+
$httpBackend.expect('GET', '/url1').respond('[Code](url): function() {}');
1180+
$httpBackend.expect('GET', '/url2').respond('{"is": "not"} ["json"]');
1181+
$http.get('/url1').success(callback);
1182+
$http.get('/url2').success(callback);
1183+
$httpBackend.flush();
1184+
1185+
expect(callback.calls.length).toBe(2);
1186+
expect(callback.calls[0].args[0]).toEqual('[Code](url): function() {}');
1187+
expect(callback.calls[1].args[0]).toEqual('{"is": "not"} ["json"]');
1188+
}
1189+
);
11761190
});
11771191

11781192

0 commit comments

Comments
 (0)