Skip to content

Commit

Permalink
Improved handling of repeating characters
Browse files Browse the repository at this point in the history
  • Loading branch information
psmyrek committed Mar 15, 2021
1 parent 23d7707 commit e36175e
Show file tree
Hide file tree
Showing 13 changed files with 66 additions and 13 deletions.
4 changes: 2 additions & 2 deletions packages/ckeditor5-engine/src/view/styles/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ export function isLineStyle( string ) {
return lineStyleValues.includes( string );
}

const lengthRegExp = /^([+-]?[0-9]*[.]?[0-9]+(px|cm|mm|in|pc|pt|ch|em|ex|rem|vh|vw|vmin|vmax)|0)$/;
const lengthRegExp = /^([+-]?[0-9]*([.][0-9]+)?(px|cm|mm|in|pc|pt|ch|em|ex|rem|vh|vw|vmin|vmax)|0)$/;

/**
* Checks if string contains [length](https://developer.mozilla.org/en-US/docs/Web/CSS/length) CSS value.
Expand All @@ -98,7 +98,7 @@ export function isLength( string ) {
return lengthRegExp.test( string );
}

const PERCENTAGE_VALUE_REGEXP = /^[+-]?[0-9]*[.]?[0-9]+%$/;
const PERCENTAGE_VALUE_REGEXP = /^[+-]?[0-9]*([.][0-9]+)?%$/;

/**
* Checks if string contains [percentage](https://developer.mozilla.org/en-US/docs/Web/CSS/percentage) CSS value.
Expand Down
10 changes: 10 additions & 0 deletions packages/ckeditor5-engine/tests/view/styles/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,11 @@ describe( 'Styles utils', () => {
isLength
);
} );

// s/ckeditor5/3
it( 'should handle invalid values with repeated characters', () => {
expect( isLength( '9'.repeat( 1000000 ) ) ).to.be.false;
} );
} );

describe( 'isPercentage()', () => {
Expand All @@ -191,6 +196,11 @@ describe( 'Styles utils', () => {
it( 'returns false for not a percentage values', () => {
testValues( [ '0', '1px', '1000px', '1.1px', '345.457px', '.457px' ], value => !isPercentage( value ) );
} );

// s/ckeditor5/3
it( 'should handle invalid values with repeated characters', () => {
expect( isPercentage( '9'.repeat( 1000000 ) ) ).to.be.false;
} );
} );

describe( 'getBoxSidesShorthandValue()', () => {
Expand Down
2 changes: 1 addition & 1 deletion packages/ckeditor5-font/src/fontsize/fontsizeediting.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ export default class FontSizeEditing extends Plugin {
const editor = this.editor;

// If `fontSize.supportAllValues=true`, we do not allow to use named presets in the plugin's configuration.
const presets = definition.model.values.filter( value => !String( value ).match( /[\d.]+[\w%]+/ ) );
const presets = definition.model.values.filter( value => !String( value ).match( /^[\d.]+[a-zA-Z%]+$/ ) );

if ( presets.length ) {
/**
Expand Down
4 changes: 2 additions & 2 deletions packages/ckeditor5-image/src/autoimage.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ import { global } from 'ckeditor5/src/utils';
import { insertImage } from './image/utils';

// Implements the pattern: http(s)://(www.)example.com/path/to/resource.ext?query=params&maybe=too.
const IMAGE_URL_REGEXP = new RegExp( String( /^(http(s)?:\/\/)?[\w-]+(\.[\w-]+)+[\w._~:/?#[\]@!$&'()*+,;=%-]+/.source +
/\.(jpg|jpeg|png|gif|ico|webp|JPG|JPEG|PNG|GIF|ICO|WEBP)\??[\w._~:/#[\]@!$&'()*+,;=%-]*$/.source ) );
const IMAGE_URL_REGEXP = new RegExp( String( /^(http(s)?:\/\/)?[\w-]+\.[\w._~:/?#[\]@!$&'()*+,;=%-]+/.source +
/\.(jpg|jpeg|png|gif|ico|webp|JPG|JPEG|PNG|GIF|ICO|WEBP)(\?[\w._~:/#[\]@!$&'()*+,;=%-]*)?$/.source ) );

/**
* The auto-image plugin. It recognizes image links in the pasted content and embeds
Expand Down
14 changes: 14 additions & 0 deletions packages/ckeditor5-image/tests/autoimage.js
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,20 @@ describe( 'AutoImage - integration', () => {
);
} );
}

// s/ckeditor5/3
it( 'should handle invalid URL with repeated characters', () => {
const invalidURL = 'a.' + 'a'.repeat( 1000000 );

setData( editor.model, '<paragraph>[]</paragraph>' );
pasteHtml( editor, invalidURL );

clock.tick( 100 );

expect( getData( editor.model ) ).to.equal(
`<paragraph>${ invalidURL }[]</paragraph>`
);
} );
} );

it( 'works for URL that was pasted as a link', () => {
Expand Down
4 changes: 2 additions & 2 deletions packages/ckeditor5-list/src/converters.js
Original file line number Diff line number Diff line change
Expand Up @@ -445,12 +445,12 @@ export function cleanListItem( evt, data, conversionApi ) {
if ( child.is( '$text' ) ) {
// If this is the first node and it's a text node, left-trim it.
if ( firstNode ) {
child._data = child.data.replace( /^\s+/, '' );
child._data = child.data.trimStart();
}

// If this is the last text node before <ul> or <ol>, right-trim it.
if ( !child.nextSibling || isList( child.nextSibling ) ) {
child._data = child.data.replace( /\s+$/, '' );
child._data = child.data.trimEnd();
}
} else if ( isList( child ) ) {
// If this is a <ul> or <ol>, do not process it, just mark that we already visited list element.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ const regex = new RegExp(
/\b(?:(?:https?|ftp):\/\/|www\.)/.source +

// Domain name.
/(?![-_])(?:[-\w\u00a1-\uffff]{0,63}[^-_]\.)+(?:[a-z\u00a1-\uffff]{2,})/.source +
/(?![-_])(?:[-_a-z0-9\u00a1-\uffff]{1,63}[a-z0-9\u00a1-\uffff]\.)+(?:[a-z\u00a1-\uffff]{2,})/.source +

// The rest.
/(?:[^\s<>]*)/.source,
Expand Down
2 changes: 1 addition & 1 deletion packages/ckeditor5-media-embed/src/automediaembed.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { global } from 'ckeditor5/src/utils';
import MediaEmbedEditing from './mediaembedediting';
import { insertMedia } from './utils';

const URL_REGEXP = /^(?:http(s)?:\/\/)?[\w.-]+(?:\.[\w.-]+)+[\w\-._~:/?#[\]@!$&'()*+,;=%]+$/;
const URL_REGEXP = /^(?:http(s)?:\/\/)?[\w.-][\w\-._~:/?#[\]@!$&'()*+,;=%]+$/;

/**
* The auto-media embed plugin. It recognizes media links in the pasted content and embeds
Expand Down
14 changes: 14 additions & 0 deletions packages/ckeditor5-media-embed/tests/automediaembed.js
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,20 @@ describe( 'AutoMediaEmbed - integration', () => {
);
} );

// s/ckeditor5/3
it( 'should handle invalid URL with repeated characters', () => {
const invalidURL = 'a.' + 'a'.repeat( 1000000 ) + '^';

setData( editor.model, '<paragraph>[]</paragraph>' );
pasteHtml( editor, invalidURL );

clock.tick( 100 );

expect( getData( editor.model ) ).to.equal(
`<paragraph>${ invalidURL }[]</paragraph>`
);
} );

// #47
it( 'does not transform a valid URL into a media if the element cannot be placed in the current position', () => {
setData( editor.model, '<image src="/assets/sample.png"><caption>Foo.[]</caption></image>' );
Expand Down
2 changes: 1 addition & 1 deletion packages/ckeditor5-paste-from-office/src/filters/list.js
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ function findAllItemLikeElements( documentFragment, writer ) {
// If it cannot be adjusted, the `null` value is returned.
function detectListStyle( listLikeItem, stylesString ) {
const listStyleRegexp = new RegExp( `@list l${ listLikeItem.id }:level${ listLikeItem.indent }\\s*({[^}]*)`, 'gi' );
const listStyleTypeRegex = /mso-level-number-format:([^;]*);/gi;
const listStyleTypeRegex = /mso-level-number-format:((?!mso-level-number-format:)[^;]*);/gi;

const listStyleMatch = listStyleRegexp.exec( stylesString );

Expand Down
4 changes: 2 additions & 2 deletions packages/ckeditor5-paste-from-office/src/filters/space.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@ export function normalizeSpacing( htmlString ) {
// Run normalizeSafariSpaceSpans() two times to cover nested spans.
return normalizeSafariSpaceSpans( normalizeSafariSpaceSpans( htmlString ) )
// Remove all \r\n from "spacerun spans" so the last replace line doesn't strip all whitespaces.
.replace( /(<span\s+style=['"]mso-spacerun:yes['"]>[\s]*?)[\r\n]+(\s*<\/span>)/g, '$1$2' )
.replace( /(<span\s+style=['"]mso-spacerun:yes['"]>[^\S\r\n]*?)[\r\n]+([^\S\r\n]*<\/span>)/g, '$1$2' )
.replace( /<span\s+style=['"]mso-spacerun:yes['"]><\/span>/g, '' )
.replace( / <\//g, '\u00A0</' )
.replace( / <o:p><\/o:p>/g, '\u00A0<o:p></o:p>' )
// Remove <o:p> block filler from empty paragraph. Safari uses \u00A0 instead of &nbsp;.
.replace( /<o:p>(&nbsp;|\u00A0)<\/o:p>/g, '' )
// Remove all whitespaces when they contain any \r or \n.
.replace( />(\s*[\r\n]\s*)</g, '><' );
.replace( />([^\S\r\n]*[\r\n]\s*)</g, '><' );
}

/**
Expand Down
15 changes: 15 additions & 0 deletions packages/ckeditor5-paste-from-office/tests/filters/list.js
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,21 @@ describe( 'PasteFromOffice - filters', () => {
);
} );

// s/ckeditor5/3
it( 'should handle invalid style with repeated characters', () => {
const styles = '@list l0:level1\n' +
'{' + 'mso-level-number-format:'.repeat( 100000 ) + '}';

const html = `<p ${ level1 }>Foo</p>`;
const view = htmlDataProcessor.toView( html );

transformListItemLikeElementsIntoLists( view, styles );

expect( stringify( view ) ).to.equal(
`<ol><li ${ level1 }>Foo</li></ol>`
);
} );

it( 'converts "arabic-leading-zero" style to proper CSS attribute', () => {
const styles = '@list l0:level1\n' +
'{mso-level-number-format:arabic-leading-zero;}';
Expand Down
2 changes: 1 addition & 1 deletion packages/ckeditor5-widget/src/widgetresize/resizerstate.js
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ export default class ResizeState {

const widthStyle = domResizeHost.style.width;

if ( widthStyle && widthStyle.match( /^\d+\.?\d*%$/ ) ) {
if ( widthStyle && widthStyle.match( /^\d+(\.\d*)?%$/ ) ) {
this.originalWidthPercents = parseFloat( widthStyle );
} else {
this.originalWidthPercents = calculateHostPercentageWidth( domResizeHost, clientRect );
Expand Down

0 comments on commit e36175e

Please sign in to comment.