Skip to content

Commit

Permalink
XWIKI-21810: Improve suggest URL escaping in StringClass
Browse files Browse the repository at this point in the history
(cherry picked from commit ec18f3a)
  • Loading branch information
manuelleduc authored and michitux committed Jan 24, 2024
1 parent 7e238f5 commit 27eca84
Show file tree
Hide file tree
Showing 2 changed files with 120 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,11 @@
*/
package com.xpn.xwiki.objects.classes;

import java.util.LinkedHashMap;
import java.util.Map;

import org.apache.ecs.xhtml.input;
import org.xwiki.velocity.tools.EscapeTool;
import org.xwiki.xml.XMLUtils;

import com.xpn.xwiki.XWiki;
Expand All @@ -30,6 +34,8 @@
import com.xpn.xwiki.objects.StringProperty;
import com.xpn.xwiki.objects.meta.PropertyMetaClass;

import static org.apache.commons.lang.StringEscapeUtils.escapeJavaScript;

public class StringClass extends PropertyClass
{
private static final long serialVersionUID = 1L;
Expand Down Expand Up @@ -89,7 +95,8 @@ public BaseProperty newProperty()
}

@Override
public void displayEdit(StringBuffer buffer, String name, String prefix, BaseCollection object, XWikiContext context)
public void displayEdit(StringBuffer buffer, String name, String prefix, BaseCollection object,
XWikiContext context)
{
input input = new input();
input.setAttributeFilter(new XMLAttributeValueFilter());
Expand All @@ -105,23 +112,9 @@ public void displayEdit(StringBuffer buffer, String name, String prefix, BaseCol
input.setDisabled(isDisabled());

if (isPicker()) {
input.setClass("suggested");
String path = "";
XWiki xwiki = context.getWiki();
path = xwiki.getURL("Main.WebHome", "view", context);

String classname = this.getObject().getName();
String fieldname = this.getName();
String secondCol = "-", firstCol = "-";

String script =
"\"" + path + "?xpage=suggest&classname=" + classname + "&fieldname=" + fieldname + "&firCol="
+ firstCol + "&secCol=" + secondCol + "&\"";
String varname = "\"input\"";
input.setOnFocus("new ajaxSuggest(this, {script:" + script + ", varname:" + varname + "} )");
displayPickerEdit(input);
}

buffer.append(input.toString());
buffer.append(input);
}

@Override
Expand All @@ -133,4 +126,33 @@ public void displayView(StringBuffer buffer, String name, String prefix, BaseCol
buffer.append(XMLUtils.escapeElementText(property.toText()));
}
}

private void displayPickerEdit(input input)
{
input.setClass("suggested");
XWikiContext xWikiContext = getXWikiContext();
XWiki xwiki = xWikiContext.getWiki();
String path = xwiki.getURL("Main.WebHome", "view", xWikiContext);
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(path);
stringBuilder.append('?');
stringBuilder.append(new EscapeTool().url(getParametersMap()));
stringBuilder.append('&');
input.setOnFocus(String.format("new ajaxSuggest(this, {script:\"%s\", varname:\"input\"} )",
escapeJavaScript(stringBuilder.toString())));
}

private Map<String, String> getParametersMap()
{
String dash = "-";
// Using a linked hash map to keep the order of the keys stable when generating the query parameters, which
// is especially handy for testing, but could be useful in other scenarios.
Map<String, String> parameters = new LinkedHashMap<>();
parameters.put("xpage", "suggest");
parameters.put("classname", getObject().getName());
parameters.put("fieldname", getName());
parameters.put("firCol", dash);
parameters.put("secCol", dash);
return parameters;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*
* See the NOTICE file distributed with this work for additional
* information regarding copyright ownership.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package com.xpn.xwiki.objects.classes;

import org.junit.jupiter.api.Test;
import org.mockito.Mock;
import org.xwiki.model.reference.DocumentReference;

import com.xpn.xwiki.XWikiContext;
import com.xpn.xwiki.test.MockitoOldcore;
import com.xpn.xwiki.test.component.XWikiDocumentFilterUtilsComponentList;
import com.xpn.xwiki.test.junit5.mockito.InjectMockitoOldcore;
import com.xpn.xwiki.test.junit5.mockito.OldcoreTest;
import com.xpn.xwiki.web.XWikiURLFactory;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.when;

/**
* Test of {@link StringClass}.
*
* @version $Id$
*/
@OldcoreTest
@XWikiDocumentFilterUtilsComponentList
class StringClassTest
{
@InjectMockitoOldcore
private MockitoOldcore oldCore;

@Mock
private XWikiURLFactory urlFactory;

@Test
void displayEdit()
{
XWikiContext xWikiContext = this.oldCore.getXWikiContext();
xWikiContext.setURLFactory(this.urlFactory);
when(this.oldCore.getSpyXWiki().getURL("Main.WebHome", "view", xWikiContext)).thenReturn("/a/b");

String fieldName = "test";
String spaceName = "\" + alert(1) + \"";
String pageName = "WebHome";
StringClass stringClass = new StringClass();
stringClass.setPicker(true);
BaseClass baseClass = new BaseClass();
stringClass.setObject(baseClass);
baseClass.setDocumentReference(
new DocumentReference(this.oldCore.getXWikiContext().getWikiId(), spaceName, pageName));
stringClass.setName(fieldName);
StringBuffer stringBuffer = new StringBuffer();
stringClass.displayEdit(stringBuffer, fieldName, spaceName + "." + pageName + "_0_", baseClass,
xWikiContext);
assertEquals("<input "
+ "onfocus='new ajaxSuggest(this, &#123;script:&#34;\\/a\\/b?xpage=suggest&#38;"
+ "classname=%22%20%2B%20alert%281%29%20%2B%20%22.WebHome&#38;fieldname=test&#38;firCol=-&#38;"
+ "secCol=-&#38;&#34;, varname:&#34;input&#34;} )' "
+ "size='30' "
+ "id='&#34; + alert(1) + &#34;.WebHome_0_test' "
+ "class='suggested' "
+ "name='&#34; + alert(1) + &#34;.WebHome_0_test' "
+ "type='text'/>", stringBuffer.toString());
}
}

0 comments on commit 27eca84

Please # to comment.