Getting ZgotmplZ by printing spaces inside a simple custom shortcode

Hello,

Long story, but I was trying to use the print fucntion to manually insert spaces in template to align stuff. I was getting the strange ZgotmplZ string. I was able to create a very simple example to re-create the problem.

I’m using hugo:

hugo v0.121.1-00b46fed8e47f7bb0a85d7cfc2d9f1356379b740+extended linux/amd64 BuildDate=2023-12-08T08:47:45Z VendorInfo=gohugoio
GOOS="linux"
GOARCH="amd64"
GOVERSION="go1.21.5"
github.com/sass/libsass="3.6.5"
github.com/webmproject/libwebp="v1.3.2"

The example does not make a lot of sense, but it is just to keep it super simple.

generate_error.html shortcode:

<!-- OK -->
<img src="a.png" {{ print "x" }} >

<!-- Error -->
<img src="a.png" {{ print " " }} >

test_post.md:

## Testing

Before shortcode

{{< generate_error input_parameter >}}

After shortcode

Html output source:

<p>Before shortcode</p>

<img src="a.png" x >


<img src="a.png" ZgotmplZ >


<p>After shortcode</p>

Is this normal? Thanks!
Mathieu

This is unsafe HTML.

You may use safe.HTML provided by Hugo use the following :

<img src="a.png" {{ print " " | safeHTML }} >

To allow unsafe HTML for all, you may set Goldmark config in your configuration file as ( however unsafe HTML is not good ) :

[markup]
  [markup.goldmark]
    [markup.goldmark.renderer]
      unsafe = true

If you have full control over the MD sources, unsafe HTML is ok. Why wouldn’t it be?

Then it may be the case.

I personally only allow HTML specifically so I don’t break something by unsanitized HTML.

To clarify…

1) Your HTML is not unsafe. Your are seeing the effects of Go’s html/template package as it sanitizes the rendered HTML to make it safe against code injection.

2) The markup.goldmark.renderer.unsafe configuration parameter is not relevant to this topic. When set to false (the default), the markdown renderer (Goldmark) replaces HTML within the markdown with:

<!-- raw HTML omitted -->

Clearly that is not a factor—you are not mixing HTML within your markdown.

3) The safeHTML template function is not relevant to this topic. That function declares an HTML element (and its descendants) as safe, and Go’s html/template package will not perform any santization.

4) The fix…

When parsing the template, Go’s html/template package treats your printf insertion as an HTML attribute, so you have to declare the attribute as safe with the safeHTMLAttr template function:

<img src="a.png" {{ print " " | safeHTMLAttr }}>

5) Why doesn’t this happen with <img src="a.png" {{ print "x" }}> ?

That’s a question for the Go maintainers, but I suspect that "x" is seen as a boolean HTML attribute without an attribute value (like the global hidden attribute), and is treated as safe.

All of the examples below are treated as unsafe:

<img src="a.png" {{ print " " }}>
<img src="a.png" {{ print "x " }}>
<img src="a.png" {{ print " x" }}>
<img src="a.png" {{ print " x " }}>
<img src="a.png" {{ print "x y" }}>
2 Likes

Thanks a lot @jmooring for your detailed and complete answer. It solved my spacing issue perfectly.

Do you mind providing guidance on how to properly deal with html output spacing formatting? I already know about the {{- xxx -}}, {{- xxx }} and {{ xxx -}}. Maybe I’m just too OCD about the html output :slight_smile:

Thanks again!

1 Like

Not sure what that means. Can you provide an example of input vs. desired output?

Yeah, probably. In production you will minify, and in development you will typically use the brower’s dev tools (which formats for you) to inspect. The only time I look at the source (Ctrl+U in the browser) is when I suspect that the browser’s dev tools have attempted to correct invalid HTML (which is kind of annoying, though I understand the intent—match what’s rendered in the browser).

Ok, thanks. Yes, I completely forgot about minify. It’s just that during development I wanted to have better control over my indentation. And yes, I use Ctrl + U a lot :slight_smile:

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.