Skip to content

Commit

Permalink
Merge branch 'master' into B100-ZK-5522
Browse files Browse the repository at this point in the history
  • Loading branch information
jumperchen authored Dec 11, 2023
2 parents 0a07030 + 1a12aa3 commit b84e999
Show file tree
Hide file tree
Showing 10 changed files with 137 additions and 3 deletions.
4 changes: 4 additions & 0 deletions zk/src/main/java/org/zkoss/zk/ui/http/DHtmlLayoutServlet.java
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,10 @@ protected void doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected boolean process(Session sess, HttpServletRequest request, HttpServletResponse response, String path,
boolean bRichlet) throws ServletException, IOException {

// Fix Server-Side Request Forgery (SSRF)
if (!Https.isValidPath(path)) return false;

final WebApp wapp = sess.getWebApp();
final WebAppCtrl wappc = (WebAppCtrl) wapp;
final Configuration config = wapp.getConfiguration();
Expand Down
4 changes: 4 additions & 0 deletions zk/src/main/java/org/zkoss/zk/ui/http/RichletFilter.java
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,10 @@ public void doFilter(ServletRequest request, ServletResponse response, FilterCha

protected boolean process(Session sess, HttpServletRequest request, HttpServletResponse response, String path,
boolean bRichlet) throws ServletException, IOException {

// Fix Server-Side Request Forgery (SSRF)
if (!Https.isValidPath(path)) return false;

final WebApp wapp = sess.getWebApp();
final WebAppCtrl wappc = (WebAppCtrl) wapp;
final Configuration config = wapp.getConfiguration();
Expand Down
1 change: 1 addition & 0 deletions zkdoc/release-note
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ ZK 10.0.0
ZK-5037: invisible first column hides checkmarks in a listbox
ZK-5535: TrackerImplEx#removeAllReference accesses map value by iteration instead of key, lowers performance
ZK-5522: CommonFns.formatNumber() doesn't handle null as javadoc mentions
ZK-5569: Radiogroup onCheck event type mismatch

* Upgrade Notes
+ Upgrade commons-fileupload to commons-fileupload2-javax 2.0.0-M1 and commons-io to 2.13.0 to support jakarta-friendly uploads
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package org.zkoss.zktest.test2;

import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.event.CheckEvent;
import org.zkoss.zk.ui.select.SelectorComposer;
import org.zkoss.zk.ui.select.annotation.Listen;
import org.zkoss.zk.ui.util.Clients;
import org.zkoss.zul.Radio;

public class B100_ZK_5569Composer extends SelectorComposer<Component> {
private static final long serialVersionUID = 1L;

@Listen("onCheck = #categorySelector")
public void selectCategory(CheckEvent event) {
Clients.log(event.getName() + ": " + ((Radio) event.getTarget()).getLabel());
}
}
13 changes: 13 additions & 0 deletions zktest/src/main/webapp/test2/B100-ZK-5569.zul
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<zk>
<window apply="org.zkoss.zktest.test2.B100_ZK_5569Composer">
<label>click any radio, should see correct label in zk log and no exception</label>
<radiogroup id="categorySelector">
<hlayout width="100%">
<radio label="All Food" checked="true" width="90px" />
<radio label="Vegetables" width="90px" />
<radio label="Seafood" width="90px" />
<radio label="Fruits" width="90px" />
</hlayout>
</radiogroup>
</window>
</zk>
1 change: 1 addition & 0 deletions zktest/src/main/webapp/test2/config.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3165,6 +3165,7 @@ B90-ZK-4431.zul=A,E,Multislider
##zats##B100-ZK-5393.zul=A,E,FileUpload,JakartaEE
##zats##B100-ZK-5535.zul=A,E,performance,tree,mvvm,trackerNode,treeModel
##zats##B100-ZK-5522.zul=A,E,CommonFns,formatNumber
##zats##B100-ZK-5569.zul=A,E,Radiogroup,onCheck

##
# Features - 3.0.x version
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package org.zkoss.zktest.zats.test2;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;

import org.junit.jupiter.api.Test;

import org.zkoss.test.webdriver.WebDriverTestCase;
import org.zkoss.test.webdriver.ztl.JQuery;
import org.zkoss.test.webdriver.ztl.Widget;

public class B100_ZK_5569Test extends WebDriverTestCase {
@Test
public void test() {
connect();
JQuery jqRadio = jq("@radio");
check(jqRadio.eq(1));
waitResponse();
assertEquals("onCheck: Vegetables", getZKLog());
assertNoAnyError();
closeZKLog();
check(jqRadio.eq(2));
waitResponse();
assertEquals("onCheck: Seafood", getZKLog());
assertNoAnyError();
closeZKLog();
check(jqRadio.eq(3));
waitResponse();
assertEquals("onCheck: Fruits", getZKLog());
assertNoAnyError();
closeZKLog();
check(jqRadio.eq(0));
waitResponse();
assertEquals("onCheck: All Food", getZKLog());
assertNoAnyError();
closeZKLog();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Dimension;

import org.zkoss.test.webdriver.WebDriverTestCase;

Expand All @@ -26,7 +25,6 @@ public void test() {
connect();
waitResponse();

final Dimension size = driver.manage().window().getSize();
Assertions.assertEquals(size.width >> 1, jq("$div1").width(), 3);
Assertions.assertEquals(jq("body").innerWidth() >> 1, jq("$div1").width(), 3);
}
}
14 changes: 14 additions & 0 deletions zul/src/main/java/org/zkoss/zul/Radiogroup.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import org.zkoss.zk.ui.Page;
import org.zkoss.zk.ui.UiException;
import org.zkoss.zk.ui.WrongValueException;
import org.zkoss.zk.ui.event.CheckEvent;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.ext.Disable;
Expand Down Expand Up @@ -755,6 +756,19 @@ private void readObject(java.io.ObjectInputStream s) throws java.io.IOException,
initDataListener();
}
}
//-- ComponentCtrl --//
/** Processes an AU request.
* @since 10.0.0
*/
public void service(org.zkoss.zk.au.AuRequest request, boolean everError) {
final String cmd = request.getCommand();
if (cmd.equals(Events.ON_CHECK)) {
// for compatibility (before 10.0.0), the target of check event in radio group should be the checked radio
CheckEvent evt = new CheckEvent(request.getCommand(), getSelectedItem(), (Boolean) request.getData().get(""));
Events.postEvent(this, evt);
} else
super.service(request, everError);
}

public void onPageAttached(Page newpage, Page oldpage) {
super.onPageAttached(newpage, oldpage);
Expand Down
43 changes: 43 additions & 0 deletions zweb/src/main/java/org/zkoss/web/servlet/http/Https.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,13 @@
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.file.Paths;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.Map;
import java.util.regex.Pattern;
import java.util.zip.GZIPOutputStream;

import javax.servlet.ServletContext;
Expand Down Expand Up @@ -376,6 +378,47 @@ public static final Date toDate(String sdate) throws ParseException {
throw ex;
}

private static final String PATH_REGEX = "^(/[-\\w:@&?=+,.!/~*'%$_;\\(\\)]*)?$";
private static final Pattern PATH_PATTERN = Pattern.compile(PATH_REGEX);

/**
* Returns whether the specified path is valid.
* It is valid if it is null, or starts with "/" and doesn't contain "..".
*
* @since 10.0.0
*/
public static final boolean isValidPath(String path) {
if (path == null)
return false;
path = Paths.get(path).normalize().toString();

if (!PATH_PATTERN.matcher(path).matches()) {
return false;
}
if (path.startsWith("/../") || path.equals("/..")) {
return false;
}
final int slash2Count = countToken("//", path);
if (slash2Count > 0) {
return false;
}

return true;
}

private static int countToken(final String token, final String target) {
int tokenIndex = 0;
int count = 0;
while (tokenIndex != -1) {
tokenIndex = target.indexOf(token, tokenIndex);
if (tokenIndex > -1) {
tokenIndex++;
count++;
}
}
return count;
}

/**
* Converts a data to a string complaint to HTTP protocol.
*/
Expand Down

0 comments on commit b84e999

Please sign in to comment.