Open Bug 563978 Opened 14 years ago Updated 3 years ago

JavaScript/JSON parser can create DOM elements such as img tags resulting in extraneous GET requests

Categories

(Core :: DOM: HTML Parser, defect, P5)

defect

Tracking

()

UNCONFIRMED

People

(Reporter: themoz, Unassigned)

References

()

Details

(Keywords: testcase)

Attachments

(1 file)

User-Agent:       Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3
Build Identifier: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3

In very specific circumstances, it appears that a JavaScript/JSON object that contains HTML markup within JavaScript strings may be misinterpreted by Firefox, resulting in DOM elements being created and external assets being fetched.

I first observed this with an intranet application and I've produced the following simplified demonstration:

http://www.tsotech.com/mozilla/json-img/

In the demonstration, a JavaScript/JSON array is defined that contains strings that in turn contain HTML markup for img tags.  Since the array is not actually used except to write "Hello world" into a div element, no images should be fetched.  However, using the LiveHttpHeaders Firefox plug-in, you can observe that a GET request is made for the image ("this-image-should-not-be-requested.jpg").  In fact, the request will occur even if the array is not used at all--that is, even if you comment out the line that extracts "Hello world."  In the demonstration, I left that line in merely to confirm that the array was being parsed by JavaScript correctly.

To observe the behavior, it is often necessary to close and restart Firefox as it seems that the response to the extraneous GET request can and will be cached.

The issue appears to be related to the size of the document.  The following demonstration is essentially identical but contains a much smaller JavaScript array, resulting in a smaller overall document.  In this demonstration, the GET request does not occur:

http://www.tsotech.com/mozilla/json-img/smaller-file.html

The larger demonstration that does exhibit the behavior is only slightly larger than 64 kilobytes.  The dependency on file size is just conjecture and the in-memory footprint of the page may be more important.  Replacing some elements of the demonstration such as the script tags in the header with equally-sized paragraphs of Lorem Ipsum removed the behavior.

The precise relationship between the size of the JavaScript array and other elements on the page is unknown to me.  What you see in the demonstration was the result of a trial-and-error process of removing or replacing elements from the original intranet application with simplified approximations until the behavior remained without too much "noise" content in the demonstration.  In the original application where I observed this behavior, the JavaScript array was much smaller but there was a greater deal of plain HTML markup on the page.

Reproducible: Always

Steps to Reproduce:
1. Make sure you have the LiveHttpHeaders plug-in to observe requests.
2. Stop and restart Firefox; open LiveHttpHeaders.
3. Visit the demonstration URL.
4. Observe a request for the image.
Actual Results:  
An image file is fetched via a GET request apparently as a result of an invisible img tag being constructed when no img tag was intended.

Expected Results:  
No image should be fetched; as seen in the smaller demonstration.

The behavior has been observed on Windows 7, Windows XP, and Linux clients.

It appears that a same-origin policy is enforced on the img tag that is constructed invisibly.  I briefly attempted to load an image from a third-party server and in that test scenario, I did not observe any requests.
I was just to report the same issue, which hits our site, nasza-klasa.pl over thousands of times a day.
We have jsoned html passed to a javascript variable, forming a very long single line of script. From stats there seems to be a corellation between the length of the line and the probability of the error, so I assume it has something to do with buffer overrun.

This line is for example causing errors:

<script type='text/javascript'>var tip_9849110_5="<div class=\"tip\"><table class=\"table_max\" cellpadding=\"0\" >\n        <tr>\n          <td colspan=\"2\" class=\"header\">Prezent (publiczny) od: <\/td>\n        <\/tr>\n        <tr>\n          <td class=\"icon\" rowspan=\"2\" valign=\"top\"><div class=\"avatar_photo\"><a href=\"\/profile\/1\" title=\"Poka\u017c profil\"><img alt=\"Poka\u017c profil\" src=\"http:\/\/photos.nasza-klasa.pl\/125\/10\/thumb\/6646b702e7.jpeg\"><\/a><\/div><\/td>\n          <td align=\"left\" valign=\"top\"><span class=\"sender\"><a href=\"\/profile\/1\">Pan G\u0105bka<\/a>\n<\/span><div class=\"send\"><a href=\"\/gifts\/send\/1\">(wy\u015blij prezent tej osobie)<\/a>\n<\/div><\/td>\n        <\/tr> \n        <tr>\n          <td valign=\"bottom\"><div class=\"button\"><a href=\"\/poczta\/compose\/1\" title=\"Wy\u015blij wiadomo\u015b\u0107\"><img alt=\"Wy\u015blij wiadomo\u015b\u0107\" src=\"http:\/\/1.s-nk.pl\/img\/school\/default_class\/dziennik_wyslijwiadomosc\"><\/a><\/div><div class=\"button\"><a href=\"\/profile\/1\/photos\" title=\"Poka\u017c galeri\u0119 zdj\u0119\u0107\"><img alt=\"Poka\u017c galeri\u0119 zdj\u0119\u0107\" src=\"http:\/\/0.s-nk.pl\/img\/school\/default_class\/dziennik_galeria\"><\/a><\/div><div class=\"button\"><a href=\"\/friends\/1\" title=\"Poka\u017c znajomych\"><img alt=\"Poka\u017c galeri\u0119 zdj\u0119\u0107\" src=\"http:\/\/1.s-nk.pl\/img\/school\/default_class\/dziennik_znajomi\"><\/a><span class=\"friends_count\">(684003)<\/span><\/div><\/td><\/tr><\/table><\/div>" ; </script><a href="/gifts/view/9849110/5" onmouseover="overlib(tip_9849110_5,STICKY, MOUSEOFF, FULLHTML, HAUTO, VAUTO, OFFSETX, 0, DELAY, 500, BORDER, 0);" onmouseout="nd();"><img alt="Prezent" height="75" src="http://0.s-nk.pl/storage/gifts/img/icon/519" width="75" class="gift_icon" title="Prezent"></a><script type='text/javascript'>var tip_9849110_4="<div class=\"tip\"><table class=\"table_max\" cellpadding=\"0\" >\n        <tr>\n          <td colspan=\"2\" class=\"header\">Prezent (publiczny) od: <\/td>\n        <\/tr>\n        <tr>\n          <td class=\"icon\" rowspan=\"2\" valign=\"top\"><div class=\"avatar_photo\"><a href=\"\/profile\/1\" title=\"Poka\u017c profil\"><img alt=\"Poka\u017c profil\" src=\"http:\/\/photos.nasza-klasa.pl\/125\/10\/thumb\/6646b702e7.jpeg\"><\/a><\/div><\/td>\n          <td align=\"left\" valign=\"top\"><span class=\"sender\"><a href=\"\/profile\/1\">Pan G\u0105bka<\/a>\n<\/span><div class=\"send\"><a href=\"\/gifts\/send\/1\">(wy\u015blij prezent tej osobie)<\/a>\n<\/div><\/td>\n        <\/tr> \n        <tr>\n          <td valign=\"bottom\"><div class=\"button\"><a href=\"\/poczta\/compose\/1\" title=\"Wy\u015blij wiadomo\u015b\u0107\"><img alt=\"Wy\u015blij wiadomo\u015b\u0107\" src=\"http:\/\/1.s-nk.pl\/img\/school\/default_class\/dziennik_wyslijwiadomosc\"><\/a><\/div><div class=\"button\"><a href=\"\/profile\/1\/photos\" title=\"Poka\u017c galeri\u0119 zdj\u0119\u0107\"><img alt=\"Poka\u017c galeri\u0119 zdj\u0119\u0107\" src=\"http:\/\/0.s-nk.pl\/img\/school\/default_class\/dziennik_galeria\"><\/a><\/div><div class=\"button\"><a href=\"\/friends\/1\" title=\"Poka\u017c znajomych\"><img alt=\"Poka\u017c galeri\u0119 zdj\u0119\u0107\" src=\"http:\/\/1.s-nk.pl\/img\/school\/default_class\/dziennik_znajomi\"><\/a><span class=\"friends_count\">(684003)<\/span><\/div><\/td><\/tr><\/table><\/div>" ; </script><a href="/gifts/view/9849110/4" onmouseover="overlib(tip_9849110_4,STICKY, MOUSEOFF, FULLHTML, HAUTO, VAUTO, OFFSETX, 0, DELAY, 500, BORDER, 0);" onmouseout="nd();"><img alt="Prezent" height="75" src="http://0.s-nk.pl/storage/gifts/img/icon/518" width="75" class="gift_icon" title="Prezent"></a><script type='text/javascript'>var tip_9849110_3="<div class=\"tip\"><table class=\"table_max\" cellpadding=\"0\" >\n        <tr>\n          <td colspan=\"2\" class=\"header\">Prezent (publiczny) od: <\/td>\n        <\/tr>\n        <tr>\n          <td class=\"icon\" rowspan=\"2\" valign=\"top\"><div class=\"avatar_photo\"><a href=\"\/profile\/1\" title=\"Poka\u017c profil\"><img alt=\"Poka\u017c profil\" src=\"http:\/\/photos.nasza-klasa.pl\/125\/10\/thumb\/6646b702e7.jpeg\"><\/a><\/div><\/td>\n          <td align=\"left\" valign=\"top\"><span class=\"sender\"><a href=\"\/profile\/1\">Pan G\u0105bka<\/a>\n<\/span><div class=\"send\"><a href=\"\/gifts\/send\/1\">(wy\u015blij prezent tej osobie)<\/a>\n<\/div><\/td>\n        <\/tr> \n        <tr>\n          <td valign=\"bottom\"><div class=\"button\"><a href=\"\/poczta\/compose\/1\" title=\"Wy\u015blij wiadomo\u015b\u0107\"><img alt=\"Wy\u015blij wiadomo\u015b\u0107\" src=\"http:\/\/1.s-nk.pl\/img\/school\/default_class\/dziennik_wyslijwiadomosc\"><\/a><\/div><div class=\"button\"><a href=\"\/profile\/1\/photos\" title=\"Poka\u017c galeri\u0119 zdj\u0119\u0107\"><img alt=\"Poka\u017c galeri\u0119 zdj\u0119\u0107\" src=\"http:\/\/0.s-nk.pl\/img\/school\/default_class\/dziennik_galeria\"><\/a><\/div><div class=\"button\"><a href=\"\/friends\/1\" title=\"Poka\u017c znajomych\"><img alt=\"Poka\u017c galeri\u0119 zdj\u0119\u0107\" src=\"http:\/\/1.s-nk.pl\/img\/school\/default_class\/dziennik_znajomi\"><\/a><span class=\"friends_count\">(684003)<\/span><\/div><\/td><\/tr><\/table><\/div>" ; </script><a href="/gifts/view/9849110/3" onmouseover="overlib(tip_9849110_3,STICKY, MOUSEOFF, FULLHTML, HAUTO, VAUTO, OFFSETX, 0, DELAY, 500, BORDER, 0);" onmouseout="nd();"><img alt="Prezent" height="75" src="http://1.s-nk.pl/storage/gifts/img/icon/520" width="75" class="gift_icon" title="Prezent"></a><script type='text/javascript'>var tip_9849110_2="<div class=\"tip\"><table class=\"table_max\" cellpadding=\"0\" >\n        <tr>\n          <td colspan=\"2\" class=\"header\">Prezent (publiczny) od: <\/td>\n        <\/tr>\n        <tr>\n          <td class=\"icon\" rowspan=\"2\" valign=\"top\"><div class=\"avatar_photo\"><a href=\"\/profile\/1\" title=\"Poka\u017c profil\"><img alt=\"Poka\u017c profil\" src=\"http:\/\/photos.nasza-klasa.pl\/125\/10\/thumb\/6646b702e7.jpeg\"><\/a><\/div><\/td>\n          <td align=\"left\" valign=\"top\"><span class=\"sender\"><a href=\"\/profile\/1\">Pan G\u0105bka<\/a>\n<\/span><div class=\"send\"><a href=\"\/gifts\/send\/1\">(wy\u015blij prezent tej osobie)<\/a>\n<\/div><\/td>\n        <\/tr> \n        <tr>\n          <td valign=\"bottom\"><div class=\"button\"><a href=\"\/poczta\/compose\/1\" title=\"Wy\u015blij wiadomo\u015b\u0107\"><img alt=\"Wy\u015blij wiadomo\u015b\u0107\" src=\"http:\/\/1.s-nk.pl\/img\/school\/default_class\/dziennik_wyslijwiadomosc\"><\/a><\/div><div class=\"button\"><a href=\"\/profile\/1\/photos\" title=\"Poka\u017c galeri\u0119 zdj\u0119\u0107\"><img alt=\"Poka\u017c galeri\u0119 zdj\u0119\u0107\" src=\"http:\/\/0.s-nk.pl\/img\/school\/default_class\/dziennik_galeria\"><\/a><\/div><div class=\"button\"><a href=\"\/friends\/1\" title=\"Poka\u017c znajomych\"><img alt=\"Poka\u017c galeri\u0119 zdj\u0119\u0107\" src=\"http:\/\/1.s-nk.pl\/img\/school\/default_class\/dziennik_znajomi\"><\/a><span class=\"friends_count\">(684003)<\/span><\/div><\/td><\/tr><\/table><\/div>" ; </script><a href="/gifts/view/9849110/2" onmouseover="overlib(tip_9849110_2,STICKY, MOUSEOFF, FULLHTML, HAUTO, VAUTO, OFFSETX, 0, DELAY, 500, BORDER, 0);" onmouseout="nd();"><img alt="Prezent" height="75" src="http://1.s-nk.pl/storage/gifts/img/icon/517" width="75" class="gift_icon" title="Prezent"></a><div class="coolbox_bottom"><div class="coolbox_hint"><a href="/faq#profil">&nbsp;<span>Ostatnio otrzymane prezenty</span></a></div><span class="raquo">&raquo;</span><a href="/gifts/list/9849110"> zobacz wszystkie prezenty</a></div></div>
I'm experiencing this bug as well. 

Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12
Thanks for the testcase!

I can reproduce with Firefox 3.6 and Firebug 1.6, but not on Firefox 4 nightlies with Firebug 1.7X.0a7). I can reproduce in Firefox 4 with HTML5 parser turned off, so this could be fixed by the HTML5 parser (didn't find similar bugs though). Can you confirm it's fixed with a build from http://nightly.mozilla.org/ ?
Depends on: html5-parsing
Keywords: testcase
OS: Windows 7 → All
Product: Firefox → Core
QA Contact: general → general
Hardware: x86 → All
The HTML parser (both old and new) has a heuristic prescan that will attempt to prefetch resources.  I wouldn't be too surprised if the old parser's heuristics triggered on the <img> here...

Blake, do you happen to recall whether the old prescan kept track of whether it was inside a <script>?  Henri, does the new one do so?  It sorta sounds like it does.

Note: for the link in the url field is the useful testcase to look at.  The attached testcase has so much stuff going on that it's hard to say anything about it.
Component: General → HTML: Parser
QA Contact: general → parser
Also note that no DOM elements are generated by the prescan; it just makes requests to prime caches.
(In reply to comment #5)
>  Henri, does the new one do so?  It sorta sounds like it
> does.

The new one keeps track of whether it is inside a script, yes. It runs the full tree building algorithm.

Bulk-downgrade of unassigned, >=5 years untouched DOM/Storage bugs' priority.

If you have reason to believe this is wrong (especially for the severity), please write a comment and ni :jstutte.

Severity: normal → S4
Priority: -- → P5
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: