Live data from Hacker News

Be Careful with Python's New-Style String Format

lucumr.pocoo.org

151–155 of 155 posts

Re: Be Careful with Python's New-Style String Format

#151

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…

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

#152
post #9

No, 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

#153
post #65

Earlier 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_input

Re: Be Careful with Python's New-Style String Format

#154

Discussion when this pep when it was accepted and people handwaving and down voting arguments against it. https://www.reddit.com/r/Python/comments/3k6qi8/pep_498_appr...

And again, not the feature under discussion.

Not sure what you mean...
Post reply on HN