Skip to content

Conversation

@aNsHuL5217
Copy link
Contributor

Description

Fixes #6614.

This PR updates the RichText#linkify_users method to support user mentions containing spaces by allowing quoted syntax (e.g., @"Open Mapper").

Key changes:

  • Updated Regex: Now detects mentions enclosed in quotes.
  • Quote Handling: Supports straight quotes ("), smart quotes (“”), and escaped entities ("), ensuring compatibility with the Markdown renderer.
  • Email Protection: Added a negative lookbehind (?<!\w) to ensure that email addresses (e.g., [email protected]) are not accidentally parsed as mentions.
  • Prevented Double-Linking: The visible @ symbol is replaced with the HTML entity &#64; to prevent subsequent parsers (like expand_link_shorthands) from detecting the mention a second time.

How has this been tested?

  • New Test Case: Added test_linkify_username_with_space to test/lib/rich_text_test.rb to verify that quoted mentions are correctly parsed into relative links with safe HTML output.
  • Regression Testing: Ran the full RichTextTest suite (bundle exec rails test test/lib/rich_text_test.rb) to confirm that standard mentions (@user) and email addresses still function correctly.
  • Linting: Verified code style compliance using rubocop.

@hlfan
Copy link
Collaborator

hlfan commented Dec 16, 2025

And how am I supposed to tag this user named "Yo"?

@aNsHuL5217 aNsHuL5217 force-pushed the fix-issue-6614-username-spaces branch from b4e6bad to 03656fa Compare December 16, 2025 11:17
@aNsHuL5217
Copy link
Contributor Author

Thanks for pointing that out @hlfan ! I realized the original regex didn't account for names containing quotes like "Yo".

I've updated the logic to support single quotes as wrappers, so you can now tag that user simply as @'Yo'.

This update also handles cases where Markdown converts standard quotes into "smart" curly quotes, preventing broken links. I've added a test case to cover this scenario as well.

@aNsHuL5217 aNsHuL5217 force-pushed the fix-issue-6614-username-spaces branch from 03656fa to 816d260 Compare December 16, 2025 14:08
Copy link
Collaborator

@hlfan hlfan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@aNsHuL5217
Copy link
Contributor Author

Sorry for that @hlfan !
To fix the @'tis false positive, would you prefer I restrict the regex (e.g. max 50 chars, no newlines) or implement database validation?

@hlfan
Copy link
Collaborator

hlfan commented Dec 16, 2025

Well, that's the crux of the issue. We couldn't even deny newlines, as there's already one user with \r\n in the name: https://www.openstreetmap.org/user/Mohamedkaizen%0D%0AMohamedkaizen

I think the way to reduce this risk as much as possible is to use a different delimitation character that is more commonly related to URLs than casual text. Right now, the longest name of a contributor is bwdlqwbdjlbqlwdjbqlwjdbqljwbdlqwjbdlqwjdblqjwbdlqjwdbqlwjdblqwdblqjbdlqjwbdljqbwdljqwbdlqbwdbqwdblqwdlqwbdlbdlqbwldbqlwbdlqbwdlqbdlqbdljwbdlqwbdwlbqlwdblqwbdjlqwbdjlqwbdljqwbdljqbwdljqbdlqwbdlqbdljqbdljqbwdljbqldbqlwdbljqwbdljqwdbqlwdbqlwjdbqlwdbqlw at 249 chars, so none of these suggestions would be inclusive.

And database validation is probably too much of a slowdown for how often this library is called.

@HolgerJeromin
Copy link
Collaborator

HolgerJeromin commented Dec 17, 2025

Do we really have to fix the issue for all?
Or it is OK to break the three funny users which have ", linebreaks and other stuff in it?
I would keep it simple and ignore them.

we could keep them in (negative) unit test (with explaining comments) to declare the explicit simplicity.

@hlfan
Copy link
Collaborator

hlfan commented Dec 17, 2025

But where do you draw the line? Do you want users to need to escape whitespace or not?

private

def linkify_users(text)
regex = /(?<!\w)@(?:“([^”]+?)”|”([^”]+?)”|‘([^’]+?)’|’([^’]+?)’|"([^"]+?)"|'([^']+?)'|(\w+))/
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there some way to match that doesn't involve an unreadable regular expression?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's also a lot of logic in this regular expression that is not tested. It looks like it matches

  • “”
  • ””
  • ‘’
  • ’’
  • ""
  • ''

Should we have a test that shows that it doesn't linkify something like @"foo'? What happens if there are multiple potential matches? e.g. @“foo@”bar”

@HolgerJeromin
Copy link
Collaborator

But where do you draw the line? Do you want users to need to escape whitespace or not?

IMO spaces could be supported. But we should ignore other white space or " (which will produce wrong links, yes)

@pablobm
Copy link
Contributor

pablobm commented Dec 19, 2025

I think we should go in a different direction. This solution would require users to learn a new syntax that is not obvious, particularly as it's not a common convention that they may have learned at other apps. And that's before going into the side-effects that are being discussed above.

I have created an issue at #6635, describing what I think we should do instead.

@aNsHuL5217
Copy link
Contributor Author

@pnorman I gave the @"foo' edge case a shot, but getting it to work safely (without breaking URLs or HTML) made the regex extremely complex and unreadable.

I'm thinking of sticking with the simpler implementation. In my opinion, the trade-off of having hard-to-maintain code isn't worth it for such a rare edge case. The current version handles all standard and smart quotes correctly.

I've reverted to the cleaner version—let me know if you're okay with this approach!

@aNsHuL5217
Copy link
Contributor Author

@pablobm Thanks for linking that issue! I just read through the discussion in #6635.

Honestly, while a proper dropdown/User-ID system would be the ideal solution eventually, it looks like it's facing some pretty massive blockers right now. As 1ec5 and TomHughes pointed out, we don't have a User Search API, and moving away from plain-text comments to support hidden IDs would likely require a full Rich Text Editor overhaul.

I think this PR is the best path forward for now because it solves the bug immediately without needing a massive architectural rewrite. We can always upgrade to the "perfect" system later if those technical hurdles get cleared, but I don't think we should block this fix while waiting for that to happen.

@hlfan hlfan marked this pull request as draft December 20, 2025 23:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

@ syntax with space in user name fails on changeset comment

5 participants