Maybe a more fully worked example is needed. You're making a blog hosting service as a service service. Bloggers have different ideas about what page titles should be. Post Title Blog Name: Post Title Blog Name - Post Title Post Title - Blog Name Blog Name ----embdash---- Post Title ~~~ xXx Post Title xXx ~~~ It's a little overwhelming to put every possibility in a dropdown, so you allow the user to specify a format…
Be Careful with Python's New-Style String Format
151–155 of 155 posts
I feel like this sort of thing should be done with a proper template engine rather than just string formatting.
Re: Be Careful with Python's New-Style String Format
#152No, Rust does not have the ability to access any variable in the program via a format string. Rust has this: format!("{argument}", argument = "test"); // => "test" That's just named arguments to the format. Also, that's a macro; it's expanded at compile time. Python's approach is lame. It should have used something with a limited list of named arguments, or maybe a dict.
FWIW, Rust's syntax is based on Python's, but yeah, you can't access value fields in Rust's syntax.
Re: Be Careful with Python's New-Style String Format
#153Earlier quoted context omitted.
Isn't ingesting user input directly considered a bad idea all around though?
Yes, but it's not obvious how to sanitize input in this case, or that it even needs sanitizing. Formatting a string sounds pretty innocuous.
Would sanitizing for double underscores be enough to capture the most dangerous cases?
import re
def sanitize(user_input):
"""Sanitize user input for str.format
Usage:
sanitize("{post.title} - {post.blog.title}")
sanitize("{post.title}: Another fine post by "{post.author}")
sanitize("~~~ xXx {post.blog.__init__.dbconnection.__keys__.password} xXx ~~~")
"""
return re.sub(r'{[^}]*__[^}]*}', '', user_input)
Even better, we could specify which variables to allow in user input: import re
def sanitize(user_input, *allowed_variables):
"""Sanitize user input for str.format
Usage:
allowed_variables = ["post.blog.title", "post.title", "post.author"]
sanitize("{post.title} - {post.blog.title}", *allowed_variables)
sanitize("{post.title}: Another fine post by "{post.author}", *allowed_variables)
sanitize("~~~ xXx {post.blog.__init__.dbconnection.__keys__.password} xXx ~~~", *allowed_variables)
"""
for match in re.finditer(r'{([^}]*)}', user_input):
if match[1] not in allowed_variables:
user_input = user_input.replace(match[0], '')
return user_inputRe: Be Careful with Python's New-Style String Format
#154Re: Be Careful with Python's New-Style String Format
#155This should be fixed built-in, like how sql injection fixed.