Don't think %XXX% is for getting sections text (that's demanded to {.section.} command).
This is true only for SOME symbols, others have different meaning.
You will find a good list at
http://www.rejetto.com/wiki/index.php/HFS:_Template_symbolsand you'll see there's no %upload%.
Symbols substitution is at the moment made in an initial step, before macros.
It cannot be done AFTER, because many macros uses %symbols% value to work, like {.if.}
To do it WHILE, i should change the parser deeply.
At the moment there's no way to stop %symbols% like for {:quoting:}.
I may even introduce a special way to do it, but i think that for such special case a javascript encoding should be enough.
Many of these cases, anyway, would be solved by just not having the text "expanded", but managed in a variable.
I'll try to be clearer: when you call {.postvar.} or {.urlvar.} you actually get its value made part of the output (the html), even just for a while.
If you do nothing more, you will get the value in your face, in the browser.
If you instead put such value as parameter of another command, like {.set.} or {.save.}, then it will not be displayed, but instead its used for further elaboration. That's often the case for an application like the one you are developing.
By having this value directly put in a variable, instead of being replaced in the output, we should nicely workaround the problem. And it would be even more efficient.
In the example you made, you would not need to {.set.} and maybe not even {.replace.}
Some commands may just be adapted to be able to work with variables, like i already did in the last year.
i'm sorry for the breadcrumbs, but i had truly no time lately.
this was long, but i hope it was clear enough.
next release.