Comments (12)
Currently, the safehtml/template
API supports parsing templates from TrustedSources
. The fs.FS
is an interface that can be arbitrarily implemented, therefore it cannot be trusted as is.
The way to go could be implementing it using embed.FS
as the parameter instead.
from safehtml.
I actually need to use embed.FS
in a project (golang/go#48410), so I'm willing to make this happen. Here are two designs. The first is minimal:
func ParseFS(fs embed.FS, patterns ...string) (*Template, error)
func (*Template) ParseFS(fs embed.FS, patterns ...string) (*Template, error)
That mimics the standard library changes, except for using embed.FS
instead of fs.FS
.
But I think it would be worth doing something more general, in anticipation of other trusted FSs. This would also let code be agnostic about where the FS came from, much like you can do with file paths now:
type TrustedFS
func TrustedFSFromConstant(stringConstant) TrustedFS
// perhaps TrustedFSFrom{Flag,EnvVar}, etc.
func TrustedFSFromEmbed(embed.FS) TrustedFS
func ParseFS(fs TrustedFS, patterns ...string) (*Template, error)
func (*Template) ParseFS(fs TrustedFS, patterns ...string) (*Template, error)
A third design would allow you to create a TrustedSource from an FS. I haven't thought through whether that can work—does every operation on a TrustedSource make sense with an FS as well as with a file path? For example, what would
func TrustedSourceFromConstantDir(dir stringConstant, src TrustedSource, filename string) (TrustedSource, error)
do if the middle argument was an FS? Although it seems more elegant to have a single concept, it may end up being more confusing.
from safehtml.
I do prefer the second design. In my opinion, it is the most clear and simple.
from safehtml.
I realized that if we add
func ToTrustedFS(TrustedSource) TrustedFS
then we don't need any TrustedFSFromXXX
functions, so that makes it even simpler.
from safehtml.
I see the use case of embed.FS
and having specialized functions to support this.
What is the use case of the other helpers, taking into account that we have ParseGlob
?
from safehtml.
@kele, none right now that couldn't be done in other ways, but I see two reasons to generalize to TrustedFS
now:
- It would allow for easier testing, because the same call to
ParseFS
could take an embed.FS in production code orToTrustedFS(TrustedSourceFromConstant("testdir"))
in test code. - It would open the door to other FS implementations. For example, there's no reason to disallow parsing templates from a zip file under the programmer's control. If you wanted to support that you would just need to add a function to convert a
zip.Reader
(which implementsfs.FS
) to aTrustedFS
.
I think the argument for TrustedFS
is stronger than the one for ToTrustedFS
(that is, converting an existing TrustedSource
to a TrustedFS
).
from safehtml.
- It would allow for easier testing, because the same call to ParseFS could take an embed.FS in production code or ToTrustedFS(TrustedSourceFromConstant("testdir")) in test code.
Shouldn't one swap out the whole Template
instead of the filesystem?
- It would open the door to other FS implementations. For example, there's no reason to disallow parsing templates from a zip file under the programmer's control. If you wanted to support that you would just need to add a function to convert a zip.Reader (which implements fs.FS) to a TrustedFS.
How exactly would that work? Would we (a) keep adding more and more types to convert from to a TrustedFS
, or (b) we'd allow users to somehow implement a TrustedFS
themselves?
For (a): I assume we'd limit who could implement TrustedFS
by e.g. adding a private method? If yes, I'd be okay with that from a security point of view, but I wonder whether we have enough cases to justify adding a layer of abstraction here.
For (b): How could we make sure we won't get unsafe TrustedFS
implementations?
from safehtml.
@kele TrustedFS
cannot be an interface, because that can't be done in a safe way. Even with a private method, clients could still embed the interface in their own structs. It would instead look like TrustedSource
:
type TrustedFS struct {
fsys fs.FS
}
from safehtml.
In this case, we will own all the constructors of TrustedFS
and provide functions like FromEmbed(TrustedFS)
, FromConstantPath(stringConstant)
, FromZip(???)
, correct?
I struggle to see how we could provide any constructors other than from a string constant and an embed.FS
. If these are the only two we can support, then I'm not sure it's worth it to introduce the a TrustedFS
type, because this is one more thing that a developer needs to understand in order to use the API.
from safehtml.
Yes, you would own all the constructors.
I can't think of other constructors either at present. I see TrustedFS
as future-proofing. If you don't think that's worth it, I'm fine with using an embed.FS
directly.
from safehtml.
@kele, I pushed #8 but can't add reviewers. PTAL.
from safehtml.
Closing the issue. Feature implemented in commit d6f0e11.
from safehtml.
Related Issues (8)
- tag with a version HOT 1
- Can safehtml support custom attributes like one that HTMX requires?
- empty safehtml.HTML is true, should be false HOT 3
- Migrate packages that should not be imported to an internal directory HOT 1
- safe identifier characters should include all Unicode alphanumerics
- safe identifier characters should include '.'
- add support for html meta tag
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from safehtml.