Ionaru / easy-markdown-editor

EasyMDE: A simple, beautiful, and embeddable JavaScript Markdown editor. Delightful editing for beginners and experts alike. Features built-in autosaving and spell checking.
https://stackblitz.com/edit/easymde
MIT License
2.45k stars 319 forks source link

problems in urls with special characters #373

Closed Sonia-pl closed 2 years ago

Sonia-pl commented 2 years ago

When the user writtes in the editor some urls with parameters like this: ?$filter=parentmasteragent=%JCL% this url is not saved. We cannot control if the url writted by the user is correct. Can you correct this point?

Besides, when the user writes in the editor urls with '(' , ')' characters, we get a 404 , but if we access from navigator the url works correctly.

Thanks

Zignature commented 2 years ago

I just tried some test links and they all work fine for me:

  1. Test link with special characters -> http://example.com/?$filter=parentmasteragent=%JCL%
  2. Test link with parentheses -> http://example.com/?caniuse=(parentheses)
  3. Test link with parentheses & special characters -> http://example.com/?$filter=(parentmasteragent)=%JCL%

My best guess is that your CMS is sanitizing user input and removing or replacing characters in the links.

Sonia-pl commented 2 years ago

1) Yes, I agree with you if we remove satinaze option point number one works. 2) The problem with http://example.com/?caniuse=(parentheses) is that the last ) is removed, and this url works without ), and our url does not work without it.

Zignature commented 2 years ago

2) The problem with http://example.com/?caniuse=(parentheses) is that the last ) is removed, and this url works without ), and our url does not work without it.

The last ) isn't removed in my test, so there must still be some sanitizing, filtering or replacing going on on your side of it is removed.

Zignature commented 2 years ago

I think you have "unbalanced" parentheses in your links, meaning no opening or closing parenthesis. This messes up the rendered link:

Zignature commented 2 years ago

Links with unbalanced parentheses will work if you enter them between < and > characters:

or:

You'll run into the same problem if you have unbalanced pointy brackets in your URLs though...

The same thing can happen when you use unbalanced square brackets - [ and ] in the link text:

Unbalanced square brackets in the link text need to be escaped with a \.:

It's an issue with the Markdown spec, not EasyMDE. See: https://gfm.docschina.org/Inlines/Links.html Actually not an issue, just the way the spec is.

Zignature commented 2 years ago

The parentheses and pointy/angle brackets can also be escaped with a backslash.

escaped urlca>\<ped(>) -> [escaped url](<https://example.com?es\)ca\>\<ped\(>)

Zignature commented 2 years ago

Links could be escaped if entered with the JS prompt (option promptURLs needs to be set to true). The same applies to image links.

/**
 * Action for drawing a link.
 */
function drawLink(editor) {
    var cm = editor.codemirror;
    var stat = getState(cm);
    var options = editor.options;
    var url = 'https://';
    if (options.promptURLs) {
        url = prompt(options.promptTexts.link, 'https://');
        if (!url) {
            return false;
        }

        if (/[()<>]/.test(url)) url = escapeUrl(url);
    }
    _replaceSelection(cm, stat.link, options.insertTexts.link, url);
}

/**
 * Escape URLs to prevent breaking up rendered Markdown links
 * @param url {string} The url of the link or image
 */
function escapeUrl(url) {

    url = url.replace(/\(/g,'\\(')
             .replace(/\)/g,'\\)')
             .replace(/</g,'\\<')
             .replace(/>/g,'\\>');

    return url;
}

Good idea @Ionaru ? By the way, I tried looping over an object but that didn't work out, hence the consecutive replaces.

Ofcourse people cannot be stopped entering URLs manually and forgetting to escape them, and the problem with unbalanced square brackets in the link text remains...

Zignature commented 2 years ago

The first of the above two commits can be skipped/omitted.

Ionaru commented 2 years ago

I'm not sure if escaping is the right call here, sorry for the late reply. Maybe we should encode URLs instead? https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURI

Zignature commented 2 years ago

Been thinking about that too but the question is whether encoded parentheses (%28 and %29) and angle brackets (%3C and %3E) are accepted/recognized by the CMS it's send to.

Only parentheses and angle brackets mess up link rendering., but it's just as simple a fix as escaping :) Simpler yet because no extra function is needed.

if (/[()<>]/.test(url)) url = encodeURI(url);

Zignature commented 2 years ago

Or create a new option where people can choose:

transformURLs: "encode|escape"

Zignature commented 2 years ago

Encoded URLs are indeed "translated" but parentheses aren't encoded... so the problem remains when encoding URLs.

So escaping it is. Could make it optional though... escapeURLs: "true|false"

Zignature commented 2 years ago

Or do both. First encoding and then escaping if parentheses are present:

url = encodeURI(url);
if (/[()]/.test(url)) url = escapeURI(url);

...

function escapeURI(url) {

    url = url.replace(/\(/g,'\\(').replace(/\)/g,'\\)');

    return url;
}
Ionaru commented 2 years ago

The last suggestion sounds good.

Zignature commented 2 years ago

optional or automatic?

Ionaru commented 2 years ago

Automatic, I think an option is overkill.

Zignature commented 2 years ago

Just did a PR #393