Skip to content

Commit

Permalink
ckruid_to_url works with urls in style attributes
Browse files Browse the repository at this point in the history
<div style="background-image=url(resolveuid/xxxxxx);">

This was broken before.

Refactored the transform in order to test it.
  • Loading branch information
gotcha committed Nov 13, 2023
1 parent a6d6b95 commit 8ec577f
Show file tree
Hide file tree
Showing 6 changed files with 278 additions and 50 deletions.
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
+ open(os.path.join("docs", "FAQ.txt")).read()
)


setup(
name='collective.ckeditor',
version=version,
Expand Down
4 changes: 2 additions & 2 deletions src/collective/ckeditor/pytests/zope_instance.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
import time
import subprocess
try:
import pathlib2 as pathlib
except ImportError:
import pathlib
except ImportError:
import pathlib2 as pathlib
import socket
from contextlib import closing

Expand Down
207 changes: 207 additions & 0 deletions src/collective/ckeditor/tests/test_transform.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
import unittest


class TestReplaceUids(unittest.TestCase):

def testFindTagImg(self):
from collective.ckeditor.transforms import ck_ruid_to_url
# single quotes
text = "<img src='resolveuid/abcdef' />'"
tags, unique = ck_ruid_to_url.find_tags_with_resolveuid(text)
self.assertEquals(len(tags), 1)
self.assertEquals(tags[0], ("<img src='resolveuid/abcdef' />",
'abcdef', 'resolveuid/abcdef'))
self.assertEquals(len(unique), 1)
self.assertEquals(unique, set(["abcdef"]))
# double quotes
text = '<img src="resolveuid/abcdef" />'
tags, unique = ck_ruid_to_url.find_tags_with_resolveuid(text)
self.assertEquals(len(tags), 1)
self.assertEquals(tags[0], ('<img src="resolveuid/abcdef" />',
'abcdef', 'resolveuid/abcdef'))
self.assertEquals(len(unique), 1)
self.assertEquals(unique, set(["abcdef"]))

def testFindTagA(self):
from collective.ckeditor.transforms import ck_ruid_to_url
# single quotes
text = "<a href='resolveuid/abcdef'>Link</a>"
tags, unique = ck_ruid_to_url.find_tags_with_resolveuid(text)
self.assertEquals(len(tags), 1)
self.assertEquals(tags[0], ("<a href='resolveuid/abcdef'>",
'abcdef', 'resolveuid/abcdef'))
self.assertEquals(len(unique), 1)
self.assertEquals(unique, set(["abcdef"]))
# double quotes
text = '<a href="resolveuid/abcdef">Link</a>'
tags, unique = ck_ruid_to_url.find_tags_with_resolveuid(text)
self.assertEquals(len(tags), 1)
self.assertEquals(tags[0], ('<a href="resolveuid/abcdef">',
'abcdef', 'resolveuid/abcdef'))
self.assertEquals(len(unique), 1)
self.assertEquals(unique, set(["abcdef"]))

def testFindTagEmbed(self):
from collective.ckeditor.transforms import ck_ruid_to_url
# single quotes
text = "<embed src='resolveuid/abcdef' />"
tags, unique = ck_ruid_to_url.find_tags_with_resolveuid(text)
self.assertEquals(len(tags), 1)
self.assertEquals(tags[0], ("<embed src='resolveuid/abcdef' />",
'abcdef', 'resolveuid/abcdef'))
self.assertEquals(len(unique), 1)
self.assertEquals(unique, set(["abcdef"]))
# double quotes
text = '<embed src="resolveuid/abcdef" />'
tags, unique = ck_ruid_to_url.find_tags_with_resolveuid(text)
self.assertEquals(len(tags), 1)
self.assertEquals(tags[0], ('<embed src="resolveuid/abcdef" />',
'abcdef', 'resolveuid/abcdef'))
self.assertEquals(len(unique), 1)
self.assertEquals(unique, set(["abcdef"]))

def testFindTagWithStyle(self):
from collective.ckeditor.transforms import ck_ruid_to_url
# single quotes
text = (
"<div style='background-image=url(resolveuid/abcdef);'>"
"content</div>"
)
tags, unique = ck_ruid_to_url.find_tags_with_resolveuid(text)
self.assertEquals(len(tags), 1)
self.assertEquals(
tags[0],
("<div style='background-image=url(resolveuid/abcdef);'>",
'abcdef', 'resolveuid/abcdef')
)
self.assertEquals(len(unique), 1)
self.assertEquals(unique, set(["abcdef"]))
# double quotes
text = (
'<div style="background-image=url(resolveuid/abcdef);">'
"content</div>"
)
tags, unique = ck_ruid_to_url.find_tags_with_resolveuid(text)
self.assertEquals(len(tags), 1)
self.assertEquals(
tags[0],
('<div style="background-image=url(resolveuid/abcdef);">',
'abcdef', 'resolveuid/abcdef')
)
self.assertEquals(len(unique), 1)
self.assertEquals(unique, set(["abcdef"]))

def testFindTagWithMoreStyle(self):
from collective.ckeditor.transforms import ck_ruid_to_url
# single quotes
text = (
"<div style='border-color: red; "
"background-image=url(resolveuid/abcdef);'>"
"content</div>"
)
tags, unique = ck_ruid_to_url.find_tags_with_resolveuid(text)
self.assertEquals(len(tags), 1)
self.assertEquals(
tags[0],
("<div style='border-color: red; "
"background-image=url(resolveuid/abcdef);'>",
'abcdef', 'resolveuid/abcdef')
)
self.assertEquals(len(unique), 1)
self.assertEquals(unique, set(["abcdef"]))
# double quotes
text = (
'<div style="border-color: red; '
'background-image=url(resolveuid/abcdef);">'
"content</div>"
)
tags, unique = ck_ruid_to_url.find_tags_with_resolveuid(text)
self.assertEquals(len(tags), 1)
self.assertEquals(
tags[0],
('<div style="border-color: red; '
'background-image=url(resolveuid/abcdef);">',
'abcdef', 'resolveuid/abcdef')
)
self.assertEquals(len(unique), 1)
self.assertEquals(unique, set(["abcdef"]))

def testFindTagWithEvenMoreStyle(self):
from collective.ckeditor.transforms import ck_ruid_to_url
# single quotes
text = (
"<div style='border-color: red; "
"background-image=url(resolveuid/abcdef); "
"border-style:solid'>"
"content</div>"
)
tags, unique = ck_ruid_to_url.find_tags_with_resolveuid(text)
self.assertEquals(len(tags), 1)
self.assertEquals(
tags[0],
("<div style='border-color: red; "
"background-image=url(resolveuid/abcdef); "
"border-style:solid'>",
'abcdef', 'resolveuid/abcdef')
)
self.assertEquals(len(unique), 1)
self.assertEquals(unique, set(["abcdef"]))
# double quotes
text = (
'<div style="border-color: red; '
'background-image=url(resolveuid/abcdef); '
'border-style:solid">'
"content</div>"
)
tags, unique = ck_ruid_to_url.find_tags_with_resolveuid(text)
self.assertEquals(len(tags), 1)
self.assertEquals(
tags[0],
('<div style="border-color: red; '
'background-image=url(resolveuid/abcdef); '
'border-style:solid">',
'abcdef', 'resolveuid/abcdef')
)
self.assertEquals(len(unique), 1)
self.assertEquals(unique, set(["abcdef"]))

def testMakeUid(self):
from collective.ckeditor.transforms import ck_ruid_to_url
unique = set(['abcdef'])

def mocked(uid):
return '/Plone/ABCDEF'

uid_to_absolute_url = ck_ruid_to_url.make_uid_to_absolute_url(
unique, compute_url=mocked)
self.assertEquals(uid_to_absolute_url, dict(abcdef='/Plone/ABCDEF'))

def testReplaceResolveUid(self):
from collective.ckeditor.transforms import ck_ruid_to_url

def mocked(uid):
return '/Plone/ABCDEF'

original = "<a href='resolveuid/abcdef'>Link</a>"
final = ck_ruid_to_url.replace_resolveuid_urls_with_absolute_urls(
original, compute_url=mocked)
self.assertEquals(final, "<a href='/Plone/ABCDEF'>Link</a>")

original = "<img src='resolveuid/abcdef' />"
final = ck_ruid_to_url.replace_resolveuid_urls_with_absolute_urls(
original, compute_url=mocked)
self.assertEquals(final, "<img src='/Plone/ABCDEF' />")

original = (
"<div style='border-color: red; "
"background-image=url(resolveuid/abcdef); "
"border-style:solid'>"
"content</div>"
)
final = ck_ruid_to_url.replace_resolveuid_urls_with_absolute_urls(
original, compute_url=mocked)
self.assertEquals(
final,
"<div style='border-color: red; "
"background-image=url(/Plone/ABCDEF); "
"border-style:solid'>content</div>")
108 changes: 65 additions & 43 deletions src/collective/ckeditor/transforms/ck_ruid_to_url.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
# Author: Melnychuk Taras
# Contact: [email protected]
# Date: $Date: 2006-08-11
# Copyright: quintagroup.com

from zope.interface import implementer
Expand All @@ -12,10 +10,69 @@

from plone.app.uuid.utils import uuidToURL

RUID_URL_PATTERN = 'resolveuid'
TAG_PATTERN = r'(\<(img|a|embed)[^>]*>)|(\<[^>]*style=[^>]*url\([^>]*>)'
UID_PATTERN = r'(?P<uid_url>[^\"\']*%s/(?P<uid>[^\/\"\'#? ]*))' % \
RUID_URL_PATTERN

def replace_resolveuid_urls_with_absolute_urls(text, compute_url=uuidToURL):
tags_with_resolveuid, unique_uids = find_tags_with_resolveuid(text)
if unique_uids:
uid_to_absolute_url = make_uid_to_absolute_url(unique_uids, compute_url)
for tag, uid, url in tags_with_resolveuid:
if uid in uid_to_absolute_url:
new_url = uid_to_absolute_url[uid]
new_tag = tag.replace(url, new_url)
text = text.replace(tag, new_tag)
return text


TAG_WITH_URL_RE = r'(\<(img|a|embed)[^>]*>)'
TAG_WITH_URL = re.compile(TAG_WITH_URL_RE, re.I | re.S)

TAG_WITH_STYLE_RE = r'(\<[^>]*style=[^>]*url\([^>]*>)'
TAG_WITH_STYLE = re.compile(TAG_WITH_STYLE_RE, re.I | re.S)

RUID_URL = 'resolveuid'

RUID_URL_BETWEEN_QUOTES_RE = (
r'(?P<url_with_uid>[^\"\']*%s/(?P<uid>[^\/\"\'#? ]*))' % RUID_URL
)
RUID_URL_BETWEEN_QUOTES = re.compile(RUID_URL_BETWEEN_QUOTES_RE, re.I | re.S)

RUID_URL_BETWEEN_PARENS_RE = (
r'[^(]*\((?P<url_with_uid>[^\"\')]*%s/(?P<uid>[^\/\"\')#? ]*))' % RUID_URL
)
RUID_URL_BETWEEN_PARENS = re.compile(RUID_URL_BETWEEN_PARENS_RE, re.I | re.S)


def find_tags_with_resolveuid(data):
tags_with_resolveuid = []
unique_uids = set()

for m in TAG_WITH_URL.finditer(data):
ruid = re.search(RUID_URL_BETWEEN_QUOTES, m.group(0)[:3000])
if ruid:
tags_with_resolveuid.append(
(m.group(0), ruid.group('uid'), ruid.group('url_with_uid'))
)

for m in TAG_WITH_STYLE.finditer(data):
ruid = re.search(RUID_URL_BETWEEN_PARENS, m.group(0)[:3000])
if ruid:
tags_with_resolveuid.append(
(m.group(0), ruid.group('uid'), ruid.group('url_with_uid'))
)

for tu in tags_with_resolveuid:
unique_uids.add(tu[1])
return tags_with_resolveuid, unique_uids


def make_uid_to_absolute_url(unique_uids, compute_url=uuidToURL):
uid_to_absolute_url = {}
for uid in unique_uids:
url = compute_url(uid)
if url is not None:
uid_to_absolute_url[uid] = url
return uid_to_absolute_url


@implementer(ITransform)
class ck_ruid_to_url:
Expand All @@ -28,48 +85,13 @@ class ck_ruid_to_url:
def __init__(self, name=None):
if name:
self.__name__ = name
self.tag_regexp = re.compile(TAG_PATTERN, re.I | re.S)
self.ruid_regexp = re.compile(UID_PATTERN, re.I | re.S)

def name(self):
return self.__name__

def find_ruid(self, data):
tags_ruid = []
unique_ruid = []

for m in self.tag_regexp.finditer(data):
ruid = re.search(self.ruid_regexp, m.group(0)[:3000])
if ruid:
tags_ruid.append((m.group(0),
ruid.group('uid'),
ruid.group('uid_url')))

for tu in tags_ruid:
if tu[1] not in unique_ruid:
unique_ruid.append(tu[1])

return tags_ruid, unique_ruid

def mapRUID_URL(self, unique_ruid, portal):
ruid_url = {}
for uid in unique_ruid:
url = uuidToURL(uid)
if url is not None:
ruid_url[uid] = url
return ruid_url

def convert(self, orig, data, **kwargs):
text = orig
tags_ruid, unique_ruid = self.find_ruid(text)
if unique_ruid:
ruid_url = self.mapRUID_URL(unique_ruid, kwargs['context'])
for tag_ruid in tags_ruid:
t, uid, uid_url = tag_ruid
if uid in ruid_url:
text = text.replace(t, t.replace(uid_url, ruid_url[uid]))

data.setData(text)
converted = replace_resolveuid_urls_with_absolute_urls(orig)
data.setData(converted)
return data


Expand Down
6 changes: 3 additions & 3 deletions test-6.0.x.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ eggs =
setuptools =
# lxml = 4.7.1
six = 1.10.0
# selenium = 4.8.0
# Pillow = 9.4.0
# wheel = 0.38.4
selenium = 4.14.0
Pillow = 9.4.0
wheel = 0.38.4

[sources]
collective.plonefinder = git ${remotes:collective}/collective.plonefinder.git pushurl=${remotes:collective_push}/collective.plonefinder.git branch=plone5
Expand Down
2 changes: 0 additions & 2 deletions versions.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,4 @@ six = 1.9.0
collective.recipe.template = 1.11
plone.recipe.codeanalysis = 2.0
zest.releaser = 6.22.1
pytest = 4.6.11
gocept.pytestlayer = 6.3
beautifulsoup4 = 4.9.3

0 comments on commit 8ec577f

Please sign in to comment.