Prevent Diazo from escaping ampersands within an attribute - plone

I am using a template with the following TAL:
<iframe tal:attributes="src view/src" />
where view.src returns a URL including a query string with ampersands.
The template renders this fine, but after going through Diazo the ampersands are escaped as &
How can I prevent Diazo from doing this?

The template is returning invalid HTML - outside of the CDATA script and style tags, ampersands should be encoded as entities (http://htmlhelp.com/tools/validator/problems.html#amp). The HTMLParser can guess what you mean, but the serializer encodes the data correctly on the way out and there is not way to avoid that.
Note that this is just the HTML encoding of data, to take an example:
<iframe src="http://example.com?foo=1&baz=2" />
The value of the iframe's src attribute is http://example.com?foo=1&baz=2.

Related

Should I use both HtmlEncode and JavaScriptStringEncode if inside HTML <script> tag?

I want to render in .NET a string destined for Javascript, say:
<html>
...
<script>
alert('<%= this.MyStringHere %>');
</script>
</html>
How should I encode MyStringHere? Do I need HttpUtility.HtmlEncode(HttpUtility.JavaScriptStringEncode(unencodedString)) or is just HttpUtility.JavaScriptStringEncode(unencodedString) sufficient? Or are both wrong?
Feel free to mention alternative server tag <% solutions in your answer too, but I'm looking for the code-based solution, the example is a little contrived.
You only need to encode the script for JS use, no need to double encode using HTML encoding. Just HTML encoding will not work either because it will not encode \n etc.
<script>
alert(<%=HttpUtility.JavaScriptStringEncode(this.MyStringHere, true)%>);
alert("<%=HttpUtility.JavaScriptStringEncode(this.MyStringHere, false)%>");
</script>
Note that JavaScriptStringEncode will not add the double quotes by default - see official docs.
If you have server-side JSON package installed, you could also use that - and it will also work for arrays, dictionaries etc.. Note that it will also add quotes for strings so you do not add them yourself.
You also have to remember that you cannot use <%: text %> syntax since that does the HTML encoding. In MVC Razor views you even have to explicitly disable HTML encoding by using #Html.Raw(Json.Encode(...)).

Is it safe to rely on an ASPX file being valid XML?

If an aspx file compiles, is it safe to assume that it is valid XML?
Does ASP.NET work by parsing the server controls as XML?
No - only the asp controls need to be valid XML. It is completely "legal" to write non-XHTML code in an ASPX file.
I don't think you can assume that it's valid Xml for the simple reason that it can contain markup that's not valid xml or xhtml.
One quick example: You can write <br> for the "break" tag, and this will display fine in all browsers. The valid Xhmtl version is <br />, but this is not required.
XML != XHTML != ASPX
You can test this by making a DIV and putting "Hello's to all of you" which would be valid ASP and XHTML but not valid XML: "Hello's to all of you"

How to preserve ampersand in URL's querystring when using RegisterClientScriptInclude?

I have the need to add a javascript include to my ASP.NET page. The url of the javascript file has two key/value pairs in the query string. But the ampersand is being escaped and I don't want that.
Page.ClientScript.RegisterClientScriptInclude("myKey",
"https://dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6.2&s=1")
This results in the following HTML:
<script
src="https://dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6.2&s=1"
type="text/javascript"></script>
But what I really want is:
<script
src="https://dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6.2&s=1"
type="text/javascript"></script>
Help?
Actually the encoded ampersand is valid HTML markup. Your goal is an attempt to generate invalid markup. Unencoded ampersands are not valid.
I have run into this in the past and never found a way around it. I needed to create the URL server side and I don't like putting inline code in my aspx pages so I ended up using a Literal control and building the script tag and assigning it.
For your example:
<form id="form1" runat="server">
<asp:Literal ID="ltScriptInclude" runat="server"></asp:Literal>
Then in the Page_Load:
string url = "https://dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6.2&s=1";
ltScriptInclude.Text = string.Format(
"<script src=\"{0}\" type=\"text/javascript\"></script>",
url);
A complete recreation would be to also do a check for the registered key by wrapping the assignment in an if like:
if (IsStartupScriptRegistered("myKey"))
{
// assign
// set the key
}
But that is probably not needed since it is not being assigned anywhere else with the change of a PostBack double assigning it.
It's not the cleanest solution and it would have been nice if the RegisterClientScriptInclude had some type of param to tell it to not encode. Unfortunately I don't think there is any way around it and the above isn't too bad. Most includes for script files usually don't have the & so the vast majority would never run into this problem.

Can I place a comment inside a tag in ASP.NET?

I am looking to display this in my .aspx page, without using special character XML tags, can this be achieved?
<asp:ServerTag Property1="a"
Property2="b"
Property3="c" <%-- Comment why this particular property is necessary --%>
Property4="d" />
However, I am greeted with the error message Server tags cannot contain <% ... %> constructs. If I use an HTML <!-- --> tag, I'm told the server tag is not well formed.
Is there any other syntax to make this possible?
Put server-side comment above your server-side control.
<!-- client-side comment (html) - appears in html source but not rendered on page
<%-- server-side comment - stripped out on server, never sees light of day, browser never knows about it
like this
<%-- Usage:
Property2 is xyz...
Property3 will .. abc. Ignore Property 1 when this is set. etc
--%>
<asp:ServerTag Property1="a"
Property2="b"
Property3="c"
Property4="d" />
It's just like putting source code comments above your functions.
Think "server to server". It will make the difference between your HTML source looking like
cluttered with "pass through" html comment <!--:
<!-- Property usage: abc, def, ...xyz -->
Rendered server control contents.
vs. the cleaner stripped out " <%-- source:
Rendered server control contents.
Less bandwidth with latter too. No extraneous (and confusing to user) comments in HTML source.
It's not possible, no. The server tags need to be well-formed XML and you can't have tags like that in XML. You can put a comment at the top, of course, like so:
<!-- Property2 needed because... -->
<asp:ServerTag Property1="a" Property2="b" Property3="c" />
Not necessarily like that but you may want to consider decorating the property in c# to let the user know its relevance. After that something like resharper (or maybe vs) will give you this information when you try to set it.

Possible to add line breaks in a textarea field while keeping it XHTML 1.0 valid?

EDIT: After re-reading my post I think I am being a little bit unclear about what the problem is. Let me try to re-phrase it:
Users can leave comments on my site using a textarea field in a form. It should be possible to add line breaks in the comment using <br />. The comment is then stored as a string in a mysql-database (escaped to make it safe) and later on retrieved from the database and displayed on the site. Regular line breaks are not recognized when the comment is displayed.
Users can edit their comments, and in that case the original comment is displayed in a textarea field to be modified (see image below). The problem is that if there are any <br /> present, the code is not valid as XHTML 1.0 (see error message below).
Can I make the code valid using any other type of line break? As stated in the comments, regular line breaks in combination with xml:space="preserve" does not work (line breaks are displayed in the textarea field, but not when the comment is displayed as normal text on the site).
Original question:
I have a web-form which includes a textarea field to leave comments, and I want it to be able to add line breaks using <br />. Below is a simple example:
(source: shipit.se)
It works as intended, however it does not validate as XHTML 1.0 transitional when using the W3C validation service. This is the error I get:
Error Line 90, Column 1587: document type does not allow element "br" here
…ription" rows="0" cols="0">Test<br />line break</textarea></dd><dt class="cha
The element named above was found in a context where it is not allowed. This could mean that you have incorrectly nested elements -- such as a "style" element in the "body" section instead of inside "head" -- or two elements that overlap (which is not allowed).
One common cause for this error is the use of XHTML syntax in HTML documents. Due to HTML's rules of implicitly closed elements, this error can create cascading effects. For instance, using XHTML's "self-closing" tags for "meta" and "link" in the "head" section of a HTML document may cause the parser to infer the end of the "head" section and the beginning of the "body" section (where "link" and "meta" are not allowed; hence the reported error).
Is there a way to make the line breaks valid code, or do I need to find a workaround (like e.g. using specific tags for line breaks in the textarea field and then replacing them with <br /> later on when displaying the comment)?
Have you tried adding a xml:space="preserve" attribute and use just plain normal line breaks?
Why not use regular linebreaks? Those work just fine.
If you want <br /> to appear, you need to encode those entities:
<br />
From the DTD:
<!ELEMENT TEXTAREA - - (#PCDATA) -- multi-line text field -->
In the XHTML code of your page, a <textarea> can only contain text (#PCDATA), and you cannot nest any XHTML elements within the <textarea>.
Your questions seems to show two different things. The image shows "<br />" written into a <textarea>, while the message from the W3C Validator is referring to a <br /> element written into the XHTML of your page within the <textarea> element.
In the first case, having "Test<br />line break" appear to the user in the text area is done by using the appropriate entities, just as altCognito wrote:
<textarea>Test<br />line break</textarea>
Anything that's being entered by the user that is then redisplayed within a <textarea> on a new page should be encoded (i.e., use entities for &, ", ', <, and >).
If want to display a user's entry:
Test<br />line break
...as...
Test
line break
...within another text area, then you will need to parse what has been entered into the original <textarea> and replace the user-entered <br />s with normal line breaks. See Lucero's answer.
i just did this and works.
<textarea name="contenidoMensaje" id="contenidoMensaje" cols="80" rows="10">
-----Mensaje Original-----
{blank space}
<?php echo str_replace("<br />", "\n", $contenidoMensaje); ?>
</textarea>

Resources