Skip to content

Compose Box-Dot-heavy invalid URL candidate becomes a link after adding a character #102487

Closed

Description

@applause-bot

If you haven’t already, check out our contributing guidelines for onboarding. To join our Slack channel, fill out this form.


Version Number: v9.4.95-0
Reproducible in staging?: Yes
Reproducible in production?: No
If this was caught during regression testing, add the test name, ID and link from BrowserStack: #100421
Email or phone of affected tester (no customers): agexptest+pr280926@gmail.com
Issue reported by: Applause Internal Team
Bug source: Pull Request QA execution
Device used: Windows 11/ Chrome, Samsung S23FE/ Android 16, iPhone 13 Mini/ iOS 26.5
App Component: Chat Report View

Action Performed:

  1. Navigate to https://staging.new.expensify.com/
  2. Go to any 1:1 chat
  3. Open Chrome DevTools and select the Console tab
  4. Run: copy('a.'.repeat(4499) + 'a')
  5. Paste the string in the composer
  6. Type a single character at the end

Expected Result:

The complete text remains plain text after typing a single character at the end.

Actual Result:

The string becomes a link when a single character is appended.

Workaround:

Unknown

Platforms:

  • Android: App
  • Android: mWeb Chrome
  • iOS: App
  • iOS: mWeb Safari
  • iOS: mWeb Chrome
  • Windows: Chrome
  • MacOS: Chrome Safari

Screenshots/Videos

Bug7272042_1790637859317.dot-heavy_invalid_URL_candidate.mp4

View all open jobs on GitHub

Applause Internal Information
Exported by: Julia Ponikarchuk
Bug ID: 7272042

Activity

  1. added
    DeployBlockerCashThis issue or pull request should block deployment
    BugSomething is broken. Auto assigns a BugZero manager.
    on Sep 29, 2026
  2. applause-bot commented on Sep 29, 2026

    @applause-bot
    Author

    While Applause doesn't embed attachments for this bug, here are the links for quick view:
    https://platform.applause.com/services/links/v1/external/0053566184c8b90f59c957cb9d9bccc744e8b12f92540105d13c8c03e4304f3c

  3. melvin-bot commented on Sep 29, 2026

    @melvin-bot

    You have been assigned to this deploy blocker because you recently merged this PR: #100421

  4. melvin-bot commented on Sep 29, 2026

    @melvin-bot

    @JS00001 @linhvovan29546 you have been assigned to this deploy blocker because you reviewed the offending PR: #100421

  5. melvin-bot commented on Sep 29, 2026

    @melvin-bot

    💬 A slack conversation has been started in #expensify-open-source

  6. github-actions commented on Sep 29, 2026

    @github-actions
    Contributor

    👋 Friendly reminder that deploy blockers are time-sensitive ⏱ issues! Check out the open `StagingDeployCash` deploy checklist to see the list of PRs included in this release, then work quickly to do one of the following:

    1. Identify the pull request that introduced this issue and revert it.
    2. Find someone who can quickly fix the issue.
    3. Fix the issue yourself.
  7. MelvinBot commented on Sep 29, 2026

    @MelvinBot
    Contributor

    🔍 Investigation Summary

    Classification: Frontend, expected behavior newly visible in the composer
    Causing PR: fix: preserve Markdown formatting in long messages by Uzaifm127. That PR made the behavior visible. It did not add a new autolink bug.
    Related issue: [$250] Chat - Live markdown in composer is removed if the text exceeds 4000 characters

    Recommendation: DEMOTE (do not revert)

    The link is correct under the existing autolink rule. 'a.'.repeat(4499) + 'a' stays plain because no TLD is one letter long. Typing a letter such as d or e changes the last label to ad or ae. Those are real country-code TLDs, so the string is now a valid hostname.

    Production already links this exact message once you send it. It also already highlights shorter versions in the composer. The only change is that the composer now parses text longer than 4,000 characters. That was the goal of the PR. A revert would bring back the related issue above to fix a synthetic 9,000-character input.

    📋 Detailed analysis

    Why it reproduces only on staging

    The PR raised the composer's live-markdown parse limit from 4,000 to CONST.MAX_MARKUP_LENGTH (10,000).

    Which characters trigger a link

    • Letters that turn the string into a link, because a plus the letter is a ccTLD: c d e f g i l m o q r s t u w x z
    • Letters and digits that leave it plain: b h j k n p v y, and any digit

    The URL rule has not changed

    Production already links the sent message

    When you send a message, src/libs/ReportUtils.ts:6933-6935 skips Markdown only above MAX_MARKUP_LENGTH (src/CONST/index.ts:5868, 10,000). So this 9,001-character message is already linked after sending on production. The staging composer now shows the same result as the sent message.

    No other PR in the checklist is involved

    Between production and staging, the parsing-related files (package.json, src/libs/ParsingUtils.ts, src/libs/EmojiUtils.tsx) changed only through the PR above.

    Optional follow-up (not a blocker)

    To stop absurd hostnames like this from linking, apply DNS limits in expensify-common's URL regex and candidate scanner: 253 characters total and 63 characters per label. This would also change how production renders sent messages. The PR's QA Test 3 should also be updated. It expects no link after you "type several characters", which is wrong for any character that completes a TLD.

    Note: this comes from reading the code in expensify-common 2.0.207 and react-native-live-markdown 0.1.342. I did not run the parser locally.


    cc JS00001 linhvovan29546 Uzaifm127, please confirm demotion.


    view run

  8. linhvovan29546 commented on Sep 29, 2026

    @linhvovan29546
    Contributor

    I think we can demote this based on the Investigation Summary above. I’ve tested it in production as well. cc @JS00001 @Uzaifm127

  9. Uzaifm127 commented on Sep 29, 2026

    @Uzaifm127
    Contributor

    Yes, we can demote as it is also there in prod. I also agree with Melvin analysis

    Screen.Recording.2026-09-29.at.10.20.27.AM.mov
  10. 1 remaining item

  11. added and removed
    DeployBlockerCashThis issue or pull request should block deployment
    on Sep 29, 2026
  12. JS00001 commented on Oct 2, 2026

    @JS00001
    Contributor

    @Uzaifm127 are we able to fix this one?

  13. Uzaifm127 commented on Oct 2, 2026

    @Uzaifm127
    Contributor

    @JS00001 Yes, this will be handled by this PR. It applies the 253 character hostname limit, so the long heavy dotted URL in this issue will no longer become an autolink.

    A dotted URL with a hostname below 253 characters will still become an autolink when its labels are valid and it ends with a valid TLD. I think this is expected because it is still a valid hostname format, and I do not think users are likely to paste a URL like a.a.a.a.a.a... in the composer. The long dotted input from this issue is the case we need to handle, and it will no longer become an autolink after this PR.

    To prevent those URLs further from becoming autolinks too, ExpensiMark would need to check whether each domain actually exists through a DNS lookup, which is not something the parser does or should do.

    @linhvovan29546 What do you think?

  14. JS00001 commented on Oct 5, 2026

    @JS00001
    Contributor

    Looking at this again. I don't know if this is worth the time to handle. This doesnt seem like a realistic case that we'd ever run into

  15. linhvovan29546 commented on Oct 5, 2026

    @linhvovan29546
    Contributor

    Agree with @JS00001 not worth the time. Even with the 253-char hostname limit from #951, any substring under that limit with valid labels ending in a real TLD is still a technically valid hostname, so it'd still autolink. The fix only patches the pathological >253 char case, which isn't a realistic input anyway. I'd vote to close this as won't-fix.

  16. Uzaifm127 commented on Oct 5, 2026

    @Uzaifm127
    Contributor

    Yep, my vote is also up to close this issue.

  17. JS00001 commented on Oct 5, 2026

    @JS00001
    Contributor

    Lets close this one then and go back to the original issue. Is anything left there?

  18. Uzaifm127 commented on Oct 5, 2026

    @Uzaifm127
    Contributor

    @JS00001 For this issue, the PR is in draft and actively being worked on.

    For this issue, all the PRs have been merged, each and everything has been covered, 7 days regression period is going on there. The follow up work needs to be done, which I'm investigating as I mentioned that in this comment

    Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

BugSomething is broken. Auto assigns a BugZero manager.DailyKSv2Engineering

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions