Skip to content

Commit

Permalink
Fix: Update Lit bundle parser regex.
Browse files Browse the repository at this point in the history
Now the pattern will not fail with a StackOverflowException
as we will search from the start character accepting
any characters until we reach the caught start character with ;
  • Loading branch information
caalador authored and pleku committed Dec 1, 2020
1 parent 60b4fd8 commit 30ee60c
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -74,14 +74,14 @@ public final class BundleLitParser {
* <p>
* <code>render\(\)[\s]*\{</code> finds the template getter method
* <p>
* <code>[\s]*return[\s]*html[\s]*`</code> finds the return statement
* <code>[\s]*return[\s]*html[\s]*(\`)</code> finds the return statement
* <p>
* </p>
* <code>(([^`]|\\\\.)*)</code> captures all text until we encounter the end
* character with <code>;}</code> e.g. <code>';}</code>
* <code>([\s\S]*)</code> captures all text until we encounter the end
* character with <code>\1;}</code> e.g. <code>';}</code>
*/
private static final Pattern LIT_TEMPLATE_PATTERN = Pattern.compile(
"render\\(\\)[\\s]*\\{[\\s]*return[\\s]*html[\\s]*`(([^`]|\\\\.)*)`;[\\s]*\\}");
"render\\(\\)[\\s]*\\{[\\s]*return[\\s]*html[\\s]*(\\`)([\\s\\S]*?)\\1;[\\s]*\\}");

private static final Pattern HASH_PATTERN = Pattern
.compile("\"hash\"\\s*:\\s*\"([^\"]+)\"\\s*,");
Expand Down Expand Up @@ -144,11 +144,10 @@ public static Element parseLitTemplateElement(String fileName,
String content = StringUtil.removeComments(source);
Matcher templateMatcher = LIT_TEMPLATE_PATTERN.matcher(content);

// GroupCount should be 2 as the first group contains `|'|" depending
// on what was in template return html' and the second is the
// template contents.
// GroupCount should be 2 as the first group contains ` and the second
// is the template contents.
if (templateMatcher.find() && templateMatcher.groupCount() == 2) {
String group = templateMatcher.group(1);
String group = templateMatcher.group(2);
LOGGER.trace("Found regular Lit template content was {}", group);

templateDocument = Jsoup.parse(group);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Copyright 2000-2020 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/

package com.vaadin.flow.component.littemplate;

import java.io.IOException;

import org.jsoup.nodes.Element;
import org.junit.Assert;
import org.junit.Test;

public class BundleLitParserTest {
private String content = "\n var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\n if (typeof Reflect === 'object' && typeof Reflect.decorate === 'function') r = Reflect.decorate(decorators, target, key, desc);\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\n return c > 3 && r && Object.defineProperty(target, key, r), r;\n };\n import { customElement, html, LitElement } from 'lit-element';\n let AboutView = class AboutView extends LitElement {\n render() {\n return html `<vaadin-split-layout style='width: 100%; height: 100%;'>\n <div style='width:400px;display:flex;flex-direction:column;'>\n <div style='padding:var(--lumo-space-l);flex-grow:1;'>\n <vaadin-form-layout>\n <vaadin-text-field\n label='First name'\n id='firstName'\n ></vaadin-text-field\n ><vaadin-text-field\n label='Last name'\n id='lastName'\n ></vaadin-text-field\n ><vaadin-date-picker\n label='Date of birth'\n id='dateOfBirth'\n ></vaadin-date-picker\n ><vaadin-text-field\n label='Occupation'\n id='occupation'\n ></vaadin-text-field\n ><vaadin-checkbox\n id='important'\n style='padding-top: var(--lumo-space-m);'\n >Important</vaadin-checkbox\n >\n </vaadin-form-layout>\n </div>\n <vaadin-horizontal-layout\n style='flex-wrap:wrap;width:100%;background-color:var(--lumo-contrast-5pct);padding:var(--lumo-space-s) var(--lumo-space-l);'\n theme='spacing'\n >\n <vaadin-button theme='primary' id='save'>Save</vaadin-button>\n <vaadin-button theme='tertiary' slot='' id='cancel'\n >Cancel</vaadin-button\n >\n </vaadin-horizontal-layout>\n </div>\n </vaadin-split-layout>`;\n }\n };\n AboutView = __decorate([\n customElement('about-view')\n ], AboutView);\n export { AboutView };\n";

@Test
public void parseTemplate() throws IOException {
final Element element = BundleLitParser
.parseLitTemplateElement("in.ts", content);

Assert.assertEquals("The html should contain 12 elements making it 13 with the expected addition of a template element", 13,
element.getAllElements().size());
Assert.assertEquals("", "vaadin-split-layout", element.getElementsByTag("template").get(0).child(0).tagName());
}
}

0 comments on commit 30ee60c

Please sign in to comment.