Update to 9.0.100 for fix CVE-2024-56337

(cherry picked from commit 0bd2484493fb7a690808601cccfbac489dff8e12)
This commit is contained in:
wk333 2025-02-21 14:49:34 +08:00 committed by openeuler-sync-bot
parent f41515d641
commit 054224ff97
17 changed files with 22 additions and 2507 deletions

View File

@ -1,435 +0,0 @@
From 43b507ebac9d268b1ea3d908e296cc6e46795c00 Mon Sep 17 00:00:00 2001
From: Mark Thomas <markt@apache.org>
Date: Fri, 1 Nov 2024 16:35:17 +0000
Subject: [PATCH] Fix inconsistent resource metadata with current GET and
PUT/DELETE
Origin: https://github.com/apache/tomcat/commit/43b507ebac9d268b1ea3d908e296cc6e46795c00
Concurrent reads and writes (e.g. HTTP GET and PUT / DELETE) for the
same path cause corruption of the FileResource where some of the fields
are set as if the file exists and some as set as if it does not.
---
.../apache/catalina/WebResourceLockSet.java | 73 +++++++
.../catalina/webresources/DirResourceSet.java | 199 +++++++++++++++---
.../catalina/webresources/FileResource.java | 29 ++-
.../webresources/LocalStrings.properties | 1 +
4 files changed, 273 insertions(+), 29 deletions(-)
create mode 100644 java/org/apache/catalina/WebResourceLockSet.java
diff --git a/java/org/apache/catalina/WebResourceLockSet.java b/java/org/apache/catalina/WebResourceLockSet.java
new file mode 100644
index 000000000000..142472c33cd6
--- /dev/null
+++ b/java/org/apache/catalina/WebResourceLockSet.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.catalina;
+
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+/**
+ * Interface implemented by {@link WebResourceSet} implementations that wish to provide locking functionality.
+ */
+public interface WebResourceLockSet {
+
+ /**
+ * Lock the resource at the provided path for reading. The resource is not required to exist. Read locks are not
+ * exclusive.
+ *
+ * @param path The path to the resource to be locked for reading
+ *
+ * @return The {@link ResourceLock} that must be passed to {@link #unlockForRead(ResourceLock)} to release the lock
+ */
+ ResourceLock lockForRead(String path);
+
+ /**
+ * Release a read lock from the resource associated with the given {@link ResourceLock}.
+ *
+ * @param resourceLock The {@link ResourceLock} associated with the resource for which a read lock should be
+ * released
+ */
+ void unlockForRead(ResourceLock resourceLock);
+
+ /**
+ * Lock the resource at the provided path for writing. The resource is not required to exist. Write locks are
+ * exclusive.
+ *
+ * @param path The path to the resource to be locked for writing
+ *
+ * @return The {@link ResourceLock} that must be passed to {@link #unlockForWrite(ResourceLock)} to release the lock
+ */
+ ResourceLock lockForWrite(String path);
+
+ /**
+ * Release the write lock from the resource associated with the given {@link ResourceLock}.
+ *
+ * @param resourceLock The {@link ResourceLock} associated with the resource for which the write lock should be
+ * released
+ */
+ void unlockForWrite(ResourceLock resourceLock);
+
+
+ class ResourceLock {
+ public final AtomicInteger count = new AtomicInteger(0);
+ public final ReentrantReadWriteLock reentrantLock = new ReentrantReadWriteLock();
+ public final String key;
+
+ public ResourceLock(String key) {
+ this.key = key;
+ }
+ }
+}
diff --git a/java/org/apache/catalina/webresources/DirResourceSet.java b/java/org/apache/catalina/webresources/DirResourceSet.java
index a221c3f1c33d..02ddc6ec887c 100644
--- a/java/org/apache/catalina/webresources/DirResourceSet.java
+++ b/java/org/apache/catalina/webresources/DirResourceSet.java
@@ -22,24 +22,35 @@
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
import java.util.Set;
import java.util.jar.Manifest;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.WebResource;
+import org.apache.catalina.WebResourceLockSet;
import org.apache.catalina.WebResourceRoot;
import org.apache.catalina.WebResourceRoot.ResourceSetType;
import org.apache.catalina.util.ResourceSet;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
+import org.apache.tomcat.util.http.RequestUtil;
/**
* Represents a {@link org.apache.catalina.WebResourceSet} based on a directory.
*/
-public class DirResourceSet extends AbstractFileResourceSet {
+public class DirResourceSet extends AbstractFileResourceSet implements WebResourceLockSet {
private static final Log log = LogFactory.getLog(DirResourceSet.class);
+ private boolean caseSensitive = true;
+
+ private Map<String,ResourceLock> resourceLocksByPath = new HashMap<>();
+ private Object resourceLocksByPathLock = new Object();
+
+
/**
* A no argument constructor is required for this to work with the digester.
*/
@@ -91,22 +102,33 @@ public WebResource getResource(String path) {
String webAppMount = getWebAppMount();
WebResourceRoot root = getRoot();
if (path.startsWith(webAppMount)) {
- File f = file(path.substring(webAppMount.length()), false);
- if (f == null) {
- return new EmptyResource(root, path);
- }
- if (!f.exists()) {
- return new EmptyResource(root, path, f);
- }
- if (f.isDirectory() && path.charAt(path.length() - 1) != '/') {
- path = path + '/';
+ /*
+ * Lock the path for reading until the WebResource has been constructed. The lock prevents concurrent reads
+ * and writes (e.g. HTTP GET and PUT / DELETE) for the same path causing corruption of the FileResource
+ * where some of the fields are set as if the file exists and some as set as if it does not.
+ */
+ ResourceLock lock = lockForRead(path);
+ try {
+ File f = file(path.substring(webAppMount.length()), false);
+ if (f == null) {
+ return new EmptyResource(root, path);
+ }
+ if (!f.exists()) {
+ return new EmptyResource(root, path, f);
+ }
+ if (f.isDirectory() && path.charAt(path.length() - 1) != '/') {
+ path = path + '/';
+ }
+ return new FileResource(root, path, f, isReadOnly(), getManifest(), this, lock.key);
+ } finally {
+ unlockForRead(lock);
}
- return new FileResource(root, path, f, isReadOnly(), getManifest());
} else {
return new EmptyResource(root, path);
}
}
+
@Override
public String[] list(String path) {
checkPath(path);
@@ -246,32 +268,42 @@ public boolean write(String path, InputStream is, boolean overwrite) {
return false;
}
- File dest = null;
String webAppMount = getWebAppMount();
- if (path.startsWith(webAppMount)) {
+ if (!path.startsWith(webAppMount)) {
+ return false;
+ }
+
+ File dest = null;
+ /*
+ * Lock the path for writing until the write is complete. The lock prevents concurrent reads and writes (e.g.
+ * HTTP GET and PUT / DELETE) for the same path causing corruption of the FileResource where some of the fields
+ * are set as if the file exists and some as set as if it does not.
+ */
+ ResourceLock lock = lockForWrite(path);
+ try {
dest = file(path.substring(webAppMount.length()), false);
if (dest == null) {
return false;
}
- } else {
- return false;
- }
- if (dest.exists() && !overwrite) {
- return false;
- }
+ if (dest.exists() && !overwrite) {
+ return false;
+ }
- try {
- if (overwrite) {
- Files.copy(is, dest.toPath(), StandardCopyOption.REPLACE_EXISTING);
- } else {
- Files.copy(is, dest.toPath());
+ try {
+ if (overwrite) {
+ Files.copy(is, dest.toPath(), StandardCopyOption.REPLACE_EXISTING);
+ } else {
+ Files.copy(is, dest.toPath());
+ }
+ } catch (IOException ioe) {
+ return false;
}
- } catch (IOException ioe) {
- return false;
- }
- return true;
+ return true;
+ } finally {
+ unlockForWrite(lock);
+ }
}
@Override
@@ -286,6 +318,7 @@ protected void checkType(File file) {
@Override
protected void initInternal() throws LifecycleException {
super.initInternal();
+ caseSensitive = isCaseSensitive();
// Is this an exploded web application?
if (getWebAppMount().equals("")) {
// Look for a manifest
@@ -299,4 +332,114 @@ protected void initInternal() throws LifecycleException {
}
}
}
+
+
+ /*
+ * Determines if this ResourceSet is based on a case sensitive file system or not.
+ */
+ private boolean isCaseSensitive() {
+ try {
+ String canonicalPath = getFileBase().getCanonicalPath();
+ File upper = new File(canonicalPath.toUpperCase(Locale.ENGLISH));
+ if (!canonicalPath.equals(upper.getCanonicalPath())) {
+ return true;
+ }
+ File lower = new File(canonicalPath.toLowerCase(Locale.ENGLISH));
+ if (!canonicalPath.equals(lower.getCanonicalPath())) {
+ return true;
+ }
+ /*
+ * Both upper and lower case versions of the current fileBase have the same canonical path so the file
+ * system must be case insensitive.
+ */
+ } catch (IOException ioe) {
+ log.warn(sm.getString("dirResourceSet.isCaseSensitive.fail", getFileBase().getAbsolutePath()), ioe);
+ }
+
+ return false;
+ }
+
+
+ private String getLockKey(String path) {
+ // Normalize path to ensure that the same key is used for the same path.
+ String normalisedPath = RequestUtil.normalize(path);
+ if (caseSensitive) {
+ return normalisedPath;
+ }
+ return normalisedPath.toLowerCase(Locale.ENGLISH);
+ }
+
+
+ @Override
+ public ResourceLock lockForRead(String path) {
+ String key = getLockKey(path);
+ ResourceLock resourceLock = null;
+ synchronized (resourceLocksByPathLock) {
+ /*
+ * Obtain the ResourceLock and increment the usage count inside the sync to ensure that that map always has
+ * a consistent view of the currently "in-use" ResourceLocks.
+ */
+ resourceLock = resourceLocksByPath.get(key);
+ if (resourceLock == null) {
+ resourceLock = new ResourceLock(key);
+ }
+ resourceLock.count.incrementAndGet();
+ }
+ // Obtain the lock outside the sync as it will block if there is a current write lock.
+ resourceLock.reentrantLock.readLock().lock();
+ return resourceLock;
+ }
+
+
+ @Override
+ public void unlockForRead(ResourceLock resourceLock) {
+ // Unlock outside the sync as there is no need to do it inside.
+ resourceLock.reentrantLock.readLock().unlock();
+ synchronized (resourceLocksByPathLock) {
+ /*
+ * Decrement the usage count and remove ResourceLocks no longer required inside the sync to ensure that that
+ * map always has a consistent view of the currently "in-use" ResourceLocks.
+ */
+ if (resourceLock.count.decrementAndGet() == 0) {
+ resourceLocksByPath.remove(resourceLock.key);
+ }
+ }
+ }
+
+
+ @Override
+ public ResourceLock lockForWrite(String path) {
+ String key = getLockKey(path);
+ ResourceLock resourceLock = null;
+ synchronized (resourceLocksByPathLock) {
+ /*
+ * Obtain the ResourceLock and increment the usage count inside the sync to ensure that that map always has
+ * a consistent view of the currently "in-use" ResourceLocks.
+ */
+ resourceLock = resourceLocksByPath.get(key);
+ if (resourceLock == null) {
+ resourceLock = new ResourceLock(key);
+ }
+ resourceLock.count.incrementAndGet();
+ }
+ // Obtain the lock outside the sync as it will block if there are any other current locks.
+ resourceLock.reentrantLock.writeLock().lock();
+ return resourceLock;
+ }
+
+
+ @Override
+ public void unlockForWrite(ResourceLock resourceLock) {
+ // Unlock outside the sync as there is no need to do it inside.
+ resourceLock.reentrantLock.writeLock().unlock();
+ synchronized (resourceLocksByPathLock) {
+ /*
+ * Decrement the usage count and remove ResourceLocks no longer required inside the sync to ensure that that
+ * map always has a consistent view of the currently "in-use" ResourceLocks.
+ */
+ if (resourceLock.count.decrementAndGet() == 0) {
+ resourceLocksByPath.remove(resourceLock.key);
+ }
+ }
+ }
}
diff --git a/java/org/apache/catalina/webresources/FileResource.java b/java/org/apache/catalina/webresources/FileResource.java
index 32ce5bfa62c3..354022f9096d 100644
--- a/java/org/apache/catalina/webresources/FileResource.java
+++ b/java/org/apache/catalina/webresources/FileResource.java
@@ -31,6 +31,8 @@
import java.security.cert.Certificate;
import java.util.jar.Manifest;
+import org.apache.catalina.WebResourceLockSet;
+import org.apache.catalina.WebResourceLockSet.ResourceLock;
import org.apache.catalina.WebResourceRoot;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
@@ -62,10 +64,20 @@ public class FileResource extends AbstractResource {
private final boolean readOnly;
private final Manifest manifest;
private final boolean needConvert;
+ private final WebResourceLockSet lockSet;
+ private final String lockKey;
public FileResource(WebResourceRoot root, String webAppPath, File resource, boolean readOnly, Manifest manifest) {
+ this(root, webAppPath, resource, readOnly, manifest, null, null);
+ }
+
+
+ public FileResource(WebResourceRoot root, String webAppPath, File resource, boolean readOnly, Manifest manifest,
+ WebResourceLockSet lockSet, String lockKey) {
super(root, webAppPath);
this.resource = resource;
+ this.lockSet = lockSet;
+ this.lockKey = lockKey;
if (webAppPath.charAt(webAppPath.length() - 1) == '/') {
String realName = resource.getName() + '/';
@@ -117,7 +129,22 @@ public boolean delete() {
if (readOnly) {
return false;
}
- return resource.delete();
+ /*
+ * Lock the path for writing until the delete is complete. The lock prevents concurrent reads and writes (e.g.
+ * HTTP GET and PUT / DELETE) for the same path causing corruption of the FileResource where some of the fields
+ * are set as if the file exists and some as set as if it does not.
+ */
+ ResourceLock lock = null;
+ if (lockSet != null) {
+ lock = lockSet.lockForWrite(lockKey);
+ }
+ try {
+ return resource.delete();
+ } finally {
+ if (lockSet != null) {
+ lockSet.unlockForWrite(lock);
+ }
+ }
}
@Override
diff --git a/java/org/apache/catalina/webresources/LocalStrings.properties b/java/org/apache/catalina/webresources/LocalStrings.properties
index 67d76d3b3b32..301c13eb8063 100644
--- a/java/org/apache/catalina/webresources/LocalStrings.properties
+++ b/java/org/apache/catalina/webresources/LocalStrings.properties
@@ -36,6 +36,7 @@ cachedResource.invalidURL=Unable to create an instance of CachedResourceURLStrea
classpathUrlStreamHandler.notFound=Unable to load the resource [{0}] using the thread context class loader or the current class''s class loader
+dirResourceSet.isCaseSensitive.fail=Error trying to determine if file system at [{0}] is case sensitive so assuming it is not case sensitive
dirResourceSet.manifestFail=Failed to read manifest from [{0}]
dirResourceSet.notDirectory=The directory specified by base and internal path [{0}]{1}[{2}] does not exist.
dirResourceSet.writeNpe=The input stream may not be null

View File

@ -1,32 +0,0 @@
From 631500b0c9b2a2a2abb707e3de2e10a5936e5d41 Mon Sep 17 00:00:00 2001
From: Mark Thomas <markt@apache.org>
Date: Fri, 15 Nov 2024 15:55:37 +0000
Subject: [PATCH] Fix for inconsistent metadata was incomplete
Origin: https://github.com/apache/tomcat/commit/631500b0c9b2a2a2abb707e3de2e10a5936e5d41
Need to add key to map once created so it is visible to other threads
---
java/org/apache/catalina/webresources/DirResourceSet.java | 2 ++
webapps/docs/changelog.xml | 4 ++++
2 files changed, 6 insertions(+)
diff --git a/java/org/apache/catalina/webresources/DirResourceSet.java b/java/org/apache/catalina/webresources/DirResourceSet.java
index 02ddc6ec887c..f1d4e86199ee 100644
--- a/java/org/apache/catalina/webresources/DirResourceSet.java
+++ b/java/org/apache/catalina/webresources/DirResourceSet.java
@@ -382,6 +382,7 @@ public ResourceLock lockForRead(String path) {
resourceLock = resourceLocksByPath.get(key);
if (resourceLock == null) {
resourceLock = new ResourceLock(key);
+ resourceLocksByPath.put(key, resourceLock);
}
resourceLock.count.incrementAndGet();
}
@@ -419,6 +420,7 @@ public ResourceLock lockForWrite(String path) {
resourceLock = resourceLocksByPath.get(key);
if (resourceLock == null) {
resourceLock = new ResourceLock(key);
+ resourceLocksByPath.put(key, resourceLock);
}
resourceLock.count.incrementAndGet();
}

View File

@ -1,164 +0,0 @@
From 9813c5dd3259183f659bbb83312a5cf673cc1ebf Mon Sep 17 00:00:00 2001
From: remm <remm@apache.org>
Date: Tue, 15 Oct 2024 21:51:33 +0200
Subject: [PATCH] Fix JSP tag release
Origin: https://github.com/apache/tomcat/commit/9813c5dd3259183f659bbb83312a5cf673cc1ebf
BZ 69399: Fix regression caused by the improvement 69333 which caused
the tag release() to be called when using tag pooling, and to be
skipped when not using it.
Patch submitted by Michal Sobkiewicz.
---
.../org/apache/jasper/compiler/Generator.java | 2 +-
.../apache/jasper/compiler/TestGenerator.java | 51 +++++++++++++++++++
test/webapp/WEB-INF/bugs.tld | 5 ++
test/webapp/jsp/generator/release.jsp | 18 +++++++
webapps/docs/changelog.xml | 10 ++++
5 files changed, 85 insertions(+), 1 deletion(-)
create mode 100644 test/webapp/jsp/generator/release.jsp
diff --git a/java/org/apache/jasper/compiler/Generator.java b/java/org/apache/jasper/compiler/Generator.java
index 814c8bb9fe50..5df52c3d7adc 100644
--- a/java/org/apache/jasper/compiler/Generator.java
+++ b/java/org/apache/jasper/compiler/Generator.java
@@ -2603,7 +2603,7 @@ private void generateCustomEnd(Node.CustomTag n, String tagHandlerVar,
out.print(".reuse(");
out.print(tagHandlerVar);
out.println(");");
-
+ } else {
// Clean-up
out.printin("org.apache.jasper.runtime.JspRuntimeLibrary.releaseTag(");
out.print(tagHandlerVar);
diff --git a/test/org/apache/jasper/compiler/TestGenerator.java b/test/org/apache/jasper/compiler/TestGenerator.java
index f7e3223e331a..087936cd6eb2 100644
--- a/test/org/apache/jasper/compiler/TestGenerator.java
+++ b/test/org/apache/jasper/compiler/TestGenerator.java
@@ -526,6 +526,25 @@ public void setData(String data) {
}
}
+ private static boolean tagTesterTagReleaseReleased = false;
+
+ public static class TesterTagRelease extends TesterTag {
+ private String data;
+
+ public String getData() {
+ return data;
+ }
+
+ public void setData(String data) {
+ this.data = data;
+ }
+
+ @Override
+ public void release() {
+ tagTesterTagReleaseReleased = true;
+ }
+ }
+
public static class DataPropertyEditor extends PropertyEditorSupport {
}
@@ -947,6 +966,38 @@ public void testBug65390() throws Exception {
Assert.assertEquals(body.toString(), HttpServletResponse.SC_OK, rc);
}
+ @Test
+ public void testTagReleaseWithPooling() throws Exception {
+ doTestTagRelease(true);
+ }
+
+ @Test
+ public void testTagReleaseWithoutPooling() throws Exception {
+ doTestTagRelease(false);
+ }
+
+ public void doTestTagRelease(boolean enablePooling) throws Exception {
+ tagTesterTagReleaseReleased = false;
+ Tomcat tomcat = getTomcatInstance();
+
+ File appDir = new File("test/webapp");
+ Context ctxt = tomcat.addContext("", appDir.getAbsolutePath());
+ ctxt.addServletContainerInitializer(new JasperInitializer(), null);
+
+ Tomcat.initWebappDefaults(ctxt);
+ Wrapper w = (Wrapper) ctxt.findChild("jsp");
+ w.addInitParameter("enablePooling", String.valueOf(enablePooling));
+
+ tomcat.start();
+
+ getUrl("http://localhost:" + getPort() + "/jsp/generator/release.jsp");
+ if (enablePooling) {
+ Assert.assertFalse(tagTesterTagReleaseReleased);
+ } else {
+ Assert.assertTrue(tagTesterTagReleaseReleased);
+ }
+ }
+
private void doTestJsp(String jspName) throws Exception {
doTestJsp(jspName, HttpServletResponse.SC_OK);
}
diff --git a/test/webapp/WEB-INF/bugs.tld b/test/webapp/WEB-INF/bugs.tld
index 81d050e284fa..a4e496a83357 100644
--- a/test/webapp/WEB-INF/bugs.tld
+++ b/test/webapp/WEB-INF/bugs.tld
@@ -108,6 +108,11 @@
<tag-class>org.apache.jasper.compiler.TestGenerator$TesterTagA</tag-class>
<body-content>JSP</body-content>
</tag>
+ <tag>
+ <name>TesterTagRelease</name>
+ <tag-class>org.apache.jasper.compiler.TestGenerator$TesterTagRelease</tag-class>
+ <body-content>JSP</body-content>
+ </tag>
<tag>
<name>TesterScriptingTag</name>
<tag-class>org.apache.jasper.compiler.TestGenerator$TesterScriptingTag</tag-class>
diff --git a/test/webapp/jsp/generator/release.jsp b/test/webapp/jsp/generator/release.jsp
new file mode 100644
index 000000000000..ae2d1d19f09a
--- /dev/null
+++ b/test/webapp/jsp/generator/release.jsp
@@ -0,0 +1,18 @@
+<%--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You 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.
+--%>
+<%@ taglib uri="http://tomcat.apache.org/bugs" prefix="bugs" %>
+<bugs:TesterTagRelease/>
\ No newline at end of file
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 72932e81a5c2..4d34ec5008b5 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -173,6 +173,16 @@
</fix>
</changelog>
</subsection>
+ <subsection name="Jasper">
+ <changelog>
+ <fix>
+ <bug>69399</bug>: Fix regression caused by the improvement
+ <bug>69333</bug> which caused the tag <code>release</code> to be called
+ when using tag pooling, and to be skipped when not using it.
+ Patch submitted by Michal Sobkiewicz. (remm)
+ </fix>
+ </changelog>
+ </subsection>
<subsection name="Other">
<changelog>
<update>

View File

@ -1,48 +0,0 @@
From 1d88dd3ffaed76188dd4ee32ce77709ce6e153cd Mon Sep 17 00:00:00 2001
From: Mark Thomas <markt@apache.org>
Date: Mon, 2 Dec 2024 16:36:31 +0000
Subject: [PATCH] Obfuscate session cookie values for JSON output as well as
HTML
Origin: https://github.com/apache/tomcat/commit/1d88dd3ffaed76188dd4ee32ce77709ce6e153cd
---
webapps/docs/changelog.xml | 4 ++++
.../WEB-INF/classes/RequestHeaderExample.java | 18 +++++++++++++++---
2 files changed, 19 insertions(+), 3 deletions(-)
diff --git a/webapps/examples/WEB-INF/classes/RequestHeaderExample.java b/webapps/examples/WEB-INF/classes/RequestHeaderExample.java
index b01c84f33e48..e32f8c233674 100644
--- a/webapps/examples/WEB-INF/classes/RequestHeaderExample.java
+++ b/webapps/examples/WEB-INF/classes/RequestHeaderExample.java
@@ -73,7 +73,7 @@ protected boolean prefersJSON(String acceptHeader) {
// text/html, application/html, etc.
if (accept.contains("html")) {
- return false;
+ return true;
}
}
return false;
@@ -138,8 +138,20 @@ protected void renderJSON(HttpServletRequest request, HttpServletResponse respon
String headerName = e.nextElement();
String headerValue = request.getHeader(headerName);
- out.append("{\"").append(JSONFilter.escape(headerName)).append("\":\"")
- .append(JSONFilter.escape(headerValue)).append("\"}");
+ out.append("{\"").append(JSONFilter.escape(headerName)).append("\":\"");
+
+
+ if (headerName.toLowerCase(Locale.ENGLISH).contains("cookie")) {
+ HttpSession session = request.getSession(false);
+ String sessionId = null;
+ if (session != null) {
+ sessionId = session.getId();
+ }
+ out.append(JSONFilter.escape(CookieFilter.filter(headerValue, sessionId)));
+ } else {
+ out.append(JSONFilter.escape(headerValue));
+ }
+ out.append("\"}");
if (e.hasMoreElements()) {
out.append(',');

View File

@ -1,61 +0,0 @@
From 721544ea28e92549824b106be954a9f411867a1c Mon Sep 17 00:00:00 2001
From: Mark Thomas <markt@apache.org>
Date: Mon, 2 Dec 2024 17:39:05 +0000
Subject: [PATCH] Add the ability to delete session attributes.
Origin: https://github.com/apache/tomcat/commit/721544ea28e92549824b106be954a9f411867a1c
---
webapps/docs/changelog.xml | 4 ++++
.../examples/WEB-INF/classes/SessionExample.java | 14 +++++++++++---
2 files changed, 15 insertions(+), 3 deletions(-)
diff --git a/webapps/examples/WEB-INF/classes/SessionExample.java b/webapps/examples/WEB-INF/classes/SessionExample.java
index 407e2b3c0b0f..b3de2f866956 100644
--- a/webapps/examples/WEB-INF/classes/SessionExample.java
+++ b/webapps/examples/WEB-INF/classes/SessionExample.java
@@ -1,3 +1,4 @@
+
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
@@ -16,6 +17,8 @@
import java.io.IOException;
import java.io.PrintWriter;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.Enumeration;
import java.util.ResourceBundle;
@@ -75,7 +78,7 @@ public void doGet(HttpServletRequest request, HttpServletResponse response) thro
String dataName = request.getParameter("dataname");
String dataValue = request.getParameter("datavalue");
- if (dataName != null && dataValue != null) {
+ if (dataName != null) {
session.setAttribute(dataName, dataValue);
}
@@ -85,7 +88,12 @@ public void doGet(HttpServletRequest request, HttpServletResponse response) thro
while (names.hasMoreElements()) {
String name = names.nextElement();
String value = session.getAttribute(name).toString();
- out.println(HTMLFilter.filter(name) + " = " + HTMLFilter.filter(value) + "<br>");
+ out.println(HTMLFilter.filter(name) + " = " + HTMLFilter.filter(value));
+ out.print("<a href=\"");
+ out.print(HTMLFilter.filter(
+ response.encodeURL("SessionExample?dataname=" + URLEncoder.encode(name, StandardCharsets.UTF_8))));
+ out.println("\" >delete</a>");
+ out.println("<br>");
}
out.println("<P>");
@@ -117,7 +125,7 @@ public void doGet(HttpServletRequest request, HttpServletResponse response) thro
out.println("</form>");
out.print("<p><a href=\"");
- out.print(HTMLFilter.filter(response.encodeURL("SessionExample?dataname=foo&datavalue=bar")));
+ out.print(HTMLFilter.filter(response.encodeURL("SessionExample?dataname=exampleName&datavalue=exampleValue")));
out.println("\" >URL encoded </a>");
out.println("</body>");

View File

@ -1,137 +0,0 @@
From 84065e26ca4555e63a922bb29b13b0a1c86b7654 Mon Sep 17 00:00:00 2001
From: Mark Thomas <markt@apache.org>
Date: Mon, 2 Dec 2024 18:09:44 +0000
Subject: [PATCH] Add a limit of 10 attributes per session to the session
example
Origin: https://github.com/apache/tomcat/commit/84065e26ca4555e63a922bb29b13b0a1c86b7654
---
webapps/docs/changelog.xml | 4 +
.../WEB-INF/classes/SessionExample.java | 94 ++++++++++++-------
2 files changed, 64 insertions(+), 34 deletions(-)
diff --git a/webapps/examples/WEB-INF/classes/SessionExample.java b/webapps/examples/WEB-INF/classes/SessionExample.java
index b3de2f866956..60eaa2e03e4b 100644
--- a/webapps/examples/WEB-INF/classes/SessionExample.java
+++ b/webapps/examples/WEB-INF/classes/SessionExample.java
@@ -41,6 +41,9 @@ public class SessionExample extends HttpServlet {
private static final long serialVersionUID = 1L;
+ private static final int SESSION_ATTRIBUTE_COUNT_LIMIT = 10;
+
+
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
ResourceBundle rb = ResourceBundle.getBundle("LocalStrings", request.getLocale());
@@ -76,15 +79,34 @@ public void doGet(HttpServletRequest request, HttpServletResponse response) thro
out.println(rb.getString("sessions.lastaccessed") + " ");
out.println(new Date(session.getLastAccessedTime()));
+ // Count the existing attributes
+ int sessionAttributeCount = 0;
+ Enumeration<String> names = session.getAttributeNames();
+ while (names.hasMoreElements()) {
+ names.nextElement();
+ sessionAttributeCount++;
+ }
+
String dataName = request.getParameter("dataname");
String dataValue = request.getParameter("datavalue");
if (dataName != null) {
- session.setAttribute(dataName, dataValue);
+ if (dataValue == null) {
+ session.removeAttribute(dataName);
+ sessionAttributeCount--;
+ } else if (sessionAttributeCount < SESSION_ATTRIBUTE_COUNT_LIMIT) {
+ session.setAttribute(dataName, dataValue);
+ sessionAttributeCount++;
+ } else {
+ out.print("<p> Session attribute [");
+ out.print(HTMLFilter.filter(dataName));
+ out.print("] not added as there are already "+ SESSION_ATTRIBUTE_COUNT_LIMIT + " attributes in the ");
+ out.println("session. Delete an attribute before adding another.");
+ }
}
- out.println("<P>");
+ out.println("<p>");
out.println(rb.getString("sessions.data") + "<br>");
- Enumeration<String> names = session.getAttributeNames();
+ names = session.getAttributeNames();
while (names.hasMoreElements()) {
String name = names.nextElement();
String value = session.getAttribute(name).toString();
@@ -96,37 +118,41 @@ public void doGet(HttpServletRequest request, HttpServletResponse response) thro
out.println("<br>");
}
- out.println("<P>");
- out.print("<form action=\"");
- out.print(response.encodeURL("SessionExample"));
- out.print("\" ");
- out.println("method=POST>");
- out.println(rb.getString("sessions.dataname"));
- out.println("<input type=text size=20 name=dataname>");
- out.println("<br>");
- out.println(rb.getString("sessions.datavalue"));
- out.println("<input type=text size=20 name=datavalue>");
- out.println("<br>");
- out.println("<input type=submit>");
- out.println("</form>");
-
- out.println("<P>GET based form:<br>");
- out.print("<form action=\"");
- out.print(response.encodeURL("SessionExample"));
- out.print("\" ");
- out.println("method=GET>");
- out.println(rb.getString("sessions.dataname"));
- out.println("<input type=text size=20 name=dataname>");
- out.println("<br>");
- out.println(rb.getString("sessions.datavalue"));
- out.println("<input type=text size=20 name=datavalue>");
- out.println("<br>");
- out.println("<input type=submit>");
- out.println("</form>");
-
- out.print("<p><a href=\"");
- out.print(HTMLFilter.filter(response.encodeURL("SessionExample?dataname=exampleName&datavalue=exampleValue")));
- out.println("\" >URL encoded </a>");
+ if (sessionAttributeCount < SESSION_ATTRIBUTE_COUNT_LIMIT) {
+ out.println("<p>");
+ out.print("<form action=\"");
+ out.print(response.encodeURL("SessionExample"));
+ out.print("\" ");
+ out.println("method=POST>");
+ out.println(rb.getString("sessions.dataname"));
+ out.println("<input type=text size=20 name=dataname>");
+ out.println("<br>");
+ out.println(rb.getString("sessions.datavalue"));
+ out.println("<input type=text size=20 name=datavalue>");
+ out.println("<br>");
+ out.println("<input type=submit>");
+ out.println("</form>");
+
+ out.println("<p>GET based form:<br>");
+ out.print("<form action=\"");
+ out.print(response.encodeURL("SessionExample"));
+ out.print("\" ");
+ out.println("method=GET>");
+ out.println(rb.getString("sessions.dataname"));
+ out.println("<input type=text size=20 name=dataname>");
+ out.println("<br>");
+ out.println(rb.getString("sessions.datavalue"));
+ out.println("<input type=text size=20 name=datavalue>");
+ out.println("<br>");
+ out.println("<input type=submit>");
+ out.println("</form>");
+
+ out.print("<p><a href=\"");
+ out.print(HTMLFilter.filter(response.encodeURL("SessionExample?dataname=exampleName&datavalue=exampleValue")));
+ out.println("\" >URL encoded </a>");
+ } else {
+ out.print("<p>You may not add more than " + SESSION_ATTRIBUTE_COUNT_LIMIT + " attributes to this session.");
+ }
out.println("</body>");
out.println("</html>");

View File

@ -1,31 +0,0 @@
From 3315a9027a7eaab18f42625b97b569940ff1365d Mon Sep 17 00:00:00 2001
From: Mark Thomas <markt@apache.org>
Date: Mon, 2 Dec 2024 18:13:07 +0000
Subject: [PATCH] Fix backprot
Origin: https://github.com/apache/tomcat/commit/3315a9027a7eaab18f42625b97b569940ff1365d
---
webapps/examples/WEB-INF/classes/SessionExample.java | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/webapps/examples/WEB-INF/classes/SessionExample.java b/webapps/examples/WEB-INF/classes/SessionExample.java
index 60eaa2e03e4b..14e7c9701c84 100644
--- a/webapps/examples/WEB-INF/classes/SessionExample.java
+++ b/webapps/examples/WEB-INF/classes/SessionExample.java
@@ -18,7 +18,6 @@
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URLEncoder;
-import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.Enumeration;
import java.util.ResourceBundle;
@@ -113,7 +112,7 @@ public void doGet(HttpServletRequest request, HttpServletResponse response) thro
out.println(HTMLFilter.filter(name) + " = " + HTMLFilter.filter(value));
out.print("<a href=\"");
out.print(HTMLFilter.filter(
- response.encodeURL("SessionExample?dataname=" + URLEncoder.encode(name, StandardCharsets.UTF_8))));
+ response.encodeURL("SessionExample?dataname=" + URLEncoder.encode(name, "UTF-8"))));
out.println("\" >delete</a>");
out.println("<br>");
}

View File

@ -1,97 +0,0 @@
From c2f7ce21c3fb12caefee87c517a8bb4f80700044 Mon Sep 17 00:00:00 2001
From: Mark Thomas <markt@apache.org>
Date: Tue, 3 Dec 2024 17:45:03 +0000
Subject: [PATCH] Limit to 10 attributes. Add option to delete attribute.
Origin: https://github.com/apache/tomcat/commit/c2f7ce21c3fb12caefee87c517a8bb4f80700044
---
webapps/docs/changelog.xml | 5 ++
.../examples/jsp/security/protected/index.jsp | 49 ++++++++++++++++---
2 files changed, 46 insertions(+), 8 deletions(-)
diff --git a/webapps/examples/jsp/security/protected/index.jsp b/webapps/examples/jsp/security/protected/index.jsp
index 09c23e721910..987a30fd1878 100644
--- a/webapps/examples/jsp/security/protected/index.jsp
+++ b/webapps/examples/jsp/security/protected/index.jsp
@@ -14,8 +14,10 @@
See the License for the specific language governing permissions and
limitations under the License.
--%>
-<%@ page import="java.util.Enumeration" %>
+<%@ page import="java.net.URLEncoder" %>
+<%@ page import="java.nio.charset.StandardCharsets" %>
<%@ page import="java.security.Principal" %>
+<%@ page import="java.util.Enumeration" %>
<%@ page import="org.apache.catalina.TomcatPrincipal" %>
<%
if (request.getParameter("logoff") != null) {
@@ -121,31 +123,62 @@ enter it here:
%>
<br><br>
+<%
+ // Count the existing attributes
+ int sessionAttributeCount = 0;
+ Enumeration<String> names = session.getAttributeNames();
+ while (names.hasMoreElements()) {
+ names.nextElement();
+ sessionAttributeCount++;
+ }
+
+ String dataName = request.getParameter("dataName");
+ String dataValue = request.getParameter("dataValue");
+ if (dataName != null) {
+ if (dataValue == null) {
+ session.removeAttribute(dataName);
+ sessionAttributeCount--;
+ } else if (sessionAttributeCount < 10) {
+ session.setAttribute(dataName, dataValue);
+ sessionAttributeCount++;
+ } else {
+%>
+<p>Session attribute [<%= util.HTMLFilter.filter(dataName) %>] not added as there are already 10 attributes in the
+session. Delete an attribute before adding another.</p>
+<%
+ }
+ }
+
+ if (sessionAttributeCount < 10) {
+%>
To add some data to the authenticated session, enter it here:
<form method="GET" action='<%= response.encodeURL("index.jsp") %>'>
<input type="text" name="dataName">
<input type="text" name="dataValue">
<input type="submit" >
</form>
-<br><br>
-
<%
- String dataName = request.getParameter("dataName");
- if (dataName != null) {
- session.setAttribute(dataName, request.getParameter("dataValue"));
+ } else {
+%>
+<p>You may not add more than 10 attributes to this session.</p>
+<%
}
%>
+<br><br>
+
<p>The authenticated session contains the following attributes:</p>
<table>
<tr><th>Name</th><th>Value</th></tr>
<%
- Enumeration<String> names = session.getAttributeNames();
+ names = session.getAttributeNames();
while (names.hasMoreElements()) {
String name = names.nextElement();
+ String value = session.getAttribute(name).toString();
%>
<tr>
<td><%= util.HTMLFilter.filter(name) %></td>
- <td><%= util.HTMLFilter.filter(String.valueOf(session.getAttribute(name))) %></td>
+ <td><%= util.HTMLFilter.filter(value) %></td>
+ <td><a href='<%= response.encodeURL("index.jsp?dataName=" + URLEncoder.encode(name, StandardCharsets.UTF_8)) %>'>delete</a></td>
</tr>
<%
}

View File

@ -1,23 +0,0 @@
From 75ff7e8622edcc024b268677aa789ee8f0880ecc Mon Sep 17 00:00:00 2001
From: Mark Thomas <markt@apache.org>
Date: Wed, 4 Dec 2024 07:27:40 +0000
Subject: [PATCH] Fix back-port
Origin: https://github.com/apache/tomcat/commit/75ff7e8622edcc024b268677aa789ee8f0880ecc
---
webapps/examples/jsp/security/protected/index.jsp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/webapps/examples/jsp/security/protected/index.jsp b/webapps/examples/jsp/security/protected/index.jsp
index 987a30fd1878..f4c90b8b715c 100644
--- a/webapps/examples/jsp/security/protected/index.jsp
+++ b/webapps/examples/jsp/security/protected/index.jsp
@@ -178,7 +178,7 @@ To add some data to the authenticated session, enter it here:
<tr>
<td><%= util.HTMLFilter.filter(name) %></td>
<td><%= util.HTMLFilter.filter(value) %></td>
- <td><a href='<%= response.encodeURL("index.jsp?dataName=" + URLEncoder.encode(name, StandardCharsets.UTF_8)) %>'>delete</a></td>
+ <td><a href='<%= response.encodeURL("index.jsp?dataName=" + URLEncoder.encode(name, "UTF-8")) %>'>delete</a></td>
</tr>
<%
}

View File

@ -1,270 +0,0 @@
From 4d5cc6538d91386f950373ac8120e98c2c78ed3a Mon Sep 17 00:00:00 2001
From: Mark Thomas <markt@apache.org>
Date: Wed, 4 Dec 2024 15:14:17 +0000
Subject: [PATCH] Limit shopping cart to pre-defined items
Origin: https://github.com/apache/tomcat/commit/4d5cc6538d91386f950373ac8120e98c2c78ed3a
---
webapps/docs/changelog.xml | 4 ++
.../WEB-INF/classes/sessions/DummyCart.java | 42 +++++++++++--------
.../WEB-INF/classes/sessions/Item.java | 37 ++++++++++++++++
webapps/examples/jsp/index.html | 2 +-
webapps/examples/jsp/sessions/carts.jsp | 8 ++--
webapps/examples/jsp/sessions/crt.html | 7 +++-
.../jsp/sessions/{carts.html => shopping.jsp} | 41 +++++++++---------
7 files changed, 95 insertions(+), 46 deletions(-)
create mode 100644 webapps/examples/WEB-INF/classes/sessions/Item.java
rename webapps/examples/jsp/sessions/{carts.html => shopping.jsp} (75%)
diff --git a/webapps/examples/WEB-INF/classes/sessions/DummyCart.java b/webapps/examples/WEB-INF/classes/sessions/DummyCart.java
index 44decc98a9a2..7088557b9595 100644
--- a/webapps/examples/WEB-INF/classes/sessions/DummyCart.java
+++ b/webapps/examples/WEB-INF/classes/sessions/DummyCart.java
@@ -16,42 +16,50 @@
*/
package sessions;
-import java.util.ArrayList;
import java.util.Collections;
-import java.util.List;
+import java.util.HashSet;
+import java.util.Set;
public class DummyCart {
- final List<String> items = Collections.synchronizedList(new ArrayList<>());
+ final Set<Item> items = Collections.synchronizedSet(new HashSet<>());
+ int itemId = -1;
String submit = null;
- String item = null;
- private void addItem(String name) {
- items.add(name);
+ public void setItemId(int itemId) {
+ this.itemId = itemId;
}
- private void removeItem(String name) {
- items.remove(name);
+ public void setSubmit(String s) {
+ submit = s;
}
- public void setItem(String name) {
- item = name;
+ private void addItem(int itemId) {
+ try {
+ items.add(Item.values()[itemId]);
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // Ignore. Can only happen if user edits URL directly.
+ }
}
- public void setSubmit(String s) {
- submit = s;
+ private void removeItem(int itemId) {
+ try {
+ items.remove(Item.values()[itemId]);
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // Ignore. Can only happen if user edits URL directly.
+ }
}
- public String[] getItems() {
- return items.toArray(new String[0]);
+ public Item[] getItems() {
+ return items.toArray(new Item[0]);
}
public void processRequest() {
// null value for submit - user hit enter instead of clicking on
// "add" or "remove"
if (submit == null || submit.equals("add")) {
- addItem(item);
+ addItem(itemId);
} else if (submit.equals("remove")) {
- removeItem(item);
+ removeItem(itemId);
}
// reset at the end of the request
@@ -61,6 +69,6 @@ public void processRequest() {
// reset
private void reset() {
submit = null;
- item = null;
+ itemId = -1;
}
}
diff --git a/webapps/examples/WEB-INF/classes/sessions/Item.java b/webapps/examples/WEB-INF/classes/sessions/Item.java
new file mode 100644
index 000000000000..447d04443744
--- /dev/null
+++ b/webapps/examples/WEB-INF/classes/sessions/Item.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 sessions;
+
+public enum Item {
+
+ VIDEO("Beavis & Butt-head Video collection"),
+ MOVIE("X-files movie"),
+ TAPES("Twin peaks tapes"),
+ CD("NIN CD"),
+ BOOK("JSP Book"),
+ TICKETS("Concert tickets");
+
+ private final String title;
+
+ Item(String title) {
+ this.title = title;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+}
diff --git a/webapps/examples/jsp/index.html b/webapps/examples/jsp/index.html
index b2371207cfe7..dc25005b2710 100644
--- a/webapps/examples/jsp/index.html
+++ b/webapps/examples/jsp/index.html
@@ -228,7 +228,7 @@ <h2>JSP 1.2 Examples</h2>
<tr>
<td>Carts</td>
-<td style="width: 30%;"><a href="sessions/carts.html"><img src="images/execute.gif" alt=""></a><a href="sessions/carts.html">Execute</a></td>
+<td style="width: 30%;"><a href="sessions/shopping.jsp"><img src="images/execute.gif" alt=""></a><a href="sessions/shopping.jsp">Execute</a></td>
<td style="width: 30%;"><a href="sessions/crt.html"><img src="images/code.gif" alt=""></a><a href="sessions/crt.html">Source</a></td>
</tr>
diff --git a/webapps/examples/jsp/sessions/carts.jsp b/webapps/examples/jsp/sessions/carts.jsp
index dc51495c4bec..fa5624dee6bd 100644
--- a/webapps/examples/jsp/sessions/carts.jsp
+++ b/webapps/examples/jsp/sessions/carts.jsp
@@ -27,10 +27,10 @@
<br> You have the following items in your cart:
<ol>
<%
- String[] items = cart.getItems();
- for (String item : items) {
+ Item[] items = cart.getItems();
+ for (Item item : items) {
%>
-<li> <% out.print(util.HTMLFilter.filter(item)); %>
+<li> <% out.print(util.HTMLFilter.filter(item.getTitle())); %>
<%
}
%>
@@ -39,5 +39,5 @@
</FONT>
<hr>
-<%@ include file ="carts.html" %>
+<%@ include file ="shopping.jsp" %>
</html>
diff --git a/webapps/examples/jsp/sessions/crt.html b/webapps/examples/jsp/sessions/crt.html
index 11e6edafe0e9..28ace66012c7 100644
--- a/webapps/examples/jsp/sessions/crt.html
+++ b/webapps/examples/jsp/sessions/crt.html
@@ -22,9 +22,12 @@
</head>
<body bgcolor="#FFFFFF">
-<p><font color="#0000FF"><a href="carts.html"><img src="../images/execute.gif" align="right" border="0"></a><a href="../index.html"><img src="../images/return.gif" width="24" height="24" align="right" border="0"></a></font></p>
+<p><font color="#0000FF"><a href="shopping.jsp"><img src="../images/execute.gif" align="right" border="0"></a><a href="../index.html"><img src="../images/return.gif" width="24" height="24" align="right" border="0"></a></font></p>
-<h3><a href="carts.jsp.html">Source Code for Cart Example<font color="#0000FF"></a>
+<h3><a href="shopping.jsp.html">Source Code for Cart Example Shopping Page<font color="#0000FF"></a>
+ </font> </h3>
+
+<h3><a href="carts.jsp.html">Source Code for Cart Example Cart Page<font color="#0000FF"></a>
</font> </h3>
<h3><a href="DummyCart.html">Property Sheet for DummyCart
diff --git a/webapps/examples/jsp/sessions/carts.html b/webapps/examples/jsp/sessions/shopping.jsp
similarity index 75%
rename from webapps/examples/jsp/sessions/carts.html
rename to webapps/examples/jsp/sessions/shopping.jsp
index 834ee0a594fd..3487b1029547 100644
--- a/webapps/examples/jsp/sessions/carts.html
+++ b/webapps/examples/jsp/sessions/shopping.jsp
@@ -1,5 +1,4 @@
-<html>
-<!--
+<%--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
@@ -14,33 +13,31 @@
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.
--->
-
+--%>
+<%@ page import="sessions.Item" %>
+<html>
<head>
- <title>carts</title>
+<title>Shopping Cart Example</title>
</head>
- <body bgcolor="white">
+<body bgcolor="white">
<font size = 5 color="#CC0000">
<form type=POST action=carts.jsp>
-<BR>
+<br>
Please enter item to add or remove:
<br>
-Add Item:
-
-<SELECT NAME="item">
-<OPTION>Beavis & Butt-head Video collection
-<OPTION>X-files movie
-<OPTION>Twin peaks tapes
-<OPTION>NIN CD
-<OPTION>JSP Book
-<OPTION>Concert tickets
-<OPTION>Love life
-<OPTION>Switch blade
-<OPTION>Rex, Rugs & Rock n' Roll
-</SELECT>
-
+Select Item:
+
+<select name="itemId">
+<%
+ for (Item item : Item.values()) {
+%>
+ <option value="<%= item.ordinal() %>"><%= item.getTitle() %></option>
+<%
+ }
+%>
+</select>
<br> <br>
<INPUT TYPE=submit name="submit" value="add">
@@ -48,6 +45,6 @@
</form>
-</FONT>
+</font>
</body>
</html>

View File

@ -1,717 +0,0 @@
From 84c4af76e7a10fc7f8630ce62e6a46632ea4a90e Mon Sep 17 00:00:00 2001
From: Mark Thomas <markt@apache.org>
Date: Wed, 4 Dec 2024 18:41:34 +0000
Subject: [PATCH] Remove JSP calendar example.
Origin: https://github.com/apache/tomcat/commit/84c4af76e7a10fc7f8630ce62e6a46632ea4a90e
---
build.xml | 9 --
webapps/docs/changelog.xml | 3 +
.../examples/WEB-INF/classes/cal/Entries.java | 63 --------
.../examples/WEB-INF/classes/cal/Entry.java | 52 ------
.../WEB-INF/classes/cal/JspCalendar.java | 152 ------------------
.../WEB-INF/classes/cal/TableBean.java | 106 ------------
webapps/examples/jsp/cal/cal1.jsp | 94 -----------
webapps/examples/jsp/cal/cal2.jsp | 45 ------
webapps/examples/jsp/cal/calendar.html | 43 -----
webapps/examples/jsp/cal/login.html | 47 ------
webapps/examples/jsp/index.html | 8 -
11 files changed, 3 insertions(+), 619 deletions(-)
delete mode 100644 webapps/examples/WEB-INF/classes/cal/Entries.java
delete mode 100644 webapps/examples/WEB-INF/classes/cal/Entry.java
delete mode 100644 webapps/examples/WEB-INF/classes/cal/JspCalendar.java
delete mode 100644 webapps/examples/WEB-INF/classes/cal/TableBean.java
delete mode 100644 webapps/examples/jsp/cal/cal1.jsp
delete mode 100644 webapps/examples/jsp/cal/cal2.jsp
delete mode 100644 webapps/examples/jsp/cal/calendar.html
delete mode 100644 webapps/examples/jsp/cal/login.html
diff --git a/build.xml b/build.xml
index 52f5fa11252f..5b3e1738c283 100644
--- a/build.xml
+++ b/build.xml
@@ -1646,15 +1646,6 @@
</fileset>
</txt2html>
- <txt2html todir="${tomcat.build}/webapps/examples/jsp/cal">
- <fileset dir="webapps/examples/WEB-INF/classes/cal">
- <include name="Entries.java"/>
- <include name="Entry.java"/>
- <include name="JspCalendar.java"/>
- <include name="TableBean.java"/>
- </fileset>
- </txt2html>
-
<txt2html todir="${tomcat.build}/webapps/examples/jsp/jsptoserv">
<fileset dir="webapps/examples/WEB-INF/classes">
<include name="ServletToJsp.java"/>
diff --git a/webapps/examples/WEB-INF/classes/cal/Entries.java b/webapps/examples/WEB-INF/classes/cal/Entries.java
deleted file mode 100644
index cac611a03b1f..000000000000
--- a/webapps/examples/WEB-INF/classes/cal/Entries.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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 cal;
-
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-import javax.servlet.http.HttpServletRequest;
-
-public class Entries {
-
- private final Map<String, Entry> entries;
- private static final String[] time = { "8am", "9am", "10am", "11am",
- "12pm", "1pm", "2pm", "3pm", "4pm", "5pm", "6pm", "7pm", "8pm" };
- public static final int rows = 12;
-
- public Entries() {
- entries = new ConcurrentHashMap<>(rows);
- for (int i = 0; i < rows; i++) {
- entries.put(time[i], new Entry(time[i]));
- }
- }
-
- public int getRows() {
- return rows;
- }
-
- public Entry getEntry(int index) {
- return this.entries.get(time[index]);
- }
-
- public int getIndex(String tm) {
- for (int i = 0; i < rows; i++) {
- if (tm.equals(time[i])) {
- return i;
- }
- }
- return -1;
- }
-
- public void processRequest(HttpServletRequest request, String tm) {
- int index = getIndex(tm);
- if (index >= 0) {
- String descr = request.getParameter("description");
- entries.get(time[index]).setDescription(descr);
- }
- }
-
-}
diff --git a/webapps/examples/WEB-INF/classes/cal/Entry.java b/webapps/examples/WEB-INF/classes/cal/Entry.java
deleted file mode 100644
index ac248bfa3169..000000000000
--- a/webapps/examples/WEB-INF/classes/cal/Entry.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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 cal;
-
-public class Entry {
-
- final String hour;
- String description;
-
- public Entry(String hour) {
- this.hour = hour;
- this.description = "";
-
- }
-
- public String getHour() {
- return this.hour;
- }
-
- public String getColor() {
- if (description.equals("")) {
- return "lightblue";
- }
- return "red";
- }
-
- public String getDescription() {
- if (description.equals("")) {
- return "None";
- }
- return this.description;
- }
-
- public void setDescription(String descr) {
- description = descr;
- }
-
-}
diff --git a/webapps/examples/WEB-INF/classes/cal/JspCalendar.java b/webapps/examples/WEB-INF/classes/cal/JspCalendar.java
deleted file mode 100644
index 29541cccb400..000000000000
--- a/webapps/examples/WEB-INF/classes/cal/JspCalendar.java
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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 cal;
-
-import java.util.Calendar;
-import java.util.Date;
-
-public class JspCalendar {
- final Calendar calendar;
-
- public JspCalendar() {
- calendar = Calendar.getInstance();
- Date trialTime = new Date();
- calendar.setTime(trialTime);
- }
-
-
- public int getYear() {
- return calendar.get(Calendar.YEAR);
- }
-
- public String getMonth() {
- int m = getMonthInt();
- String[] months = new String [] { "January", "February", "March",
- "April", "May", "June",
- "July", "August", "September",
- "October", "November", "December" };
- if (m > 12) {
- return "Unknown to Man";
- }
-
- return months[m - 1];
-
- }
-
- public String getDay() {
- int x = getDayOfWeek();
- String[] days = new String[] {"Sunday", "Monday", "Tuesday", "Wednesday",
- "Thursday", "Friday", "Saturday"};
-
- if (x > 7) {
- return "Unknown to Man";
- }
-
- return days[x - 1];
-
- }
-
- public int getMonthInt() {
- return 1 + calendar.get(Calendar.MONTH);
- }
-
- public String getDate() {
- return getMonthInt() + "/" + getDayOfMonth() + "/" + getYear();
- }
-
- public String getCurrentDate() {
- Date dt = new Date ();
- calendar.setTime (dt);
- return getMonthInt() + "/" + getDayOfMonth() + "/" + getYear();
-
- }
-
- public String getNextDate() {
- calendar.set (Calendar.DAY_OF_MONTH, getDayOfMonth() + 1);
- return getDate ();
- }
-
- public String getPrevDate() {
- calendar.set (Calendar.DAY_OF_MONTH, getDayOfMonth() - 1);
- return getDate ();
- }
-
- public String getTime() {
- return getHour() + ":" + getMinute() + ":" + getSecond();
- }
-
- public int getDayOfMonth() {
- return calendar.get(Calendar.DAY_OF_MONTH);
- }
-
- public int getDayOfYear() {
- return calendar.get(Calendar.DAY_OF_YEAR);
- }
-
- public int getWeekOfYear() {
- return calendar.get(Calendar.WEEK_OF_YEAR);
- }
-
- public int getWeekOfMonth() {
- return calendar.get(Calendar.WEEK_OF_MONTH);
- }
-
- public int getDayOfWeek() {
- return calendar.get(Calendar.DAY_OF_WEEK);
- }
-
- public int getHour() {
- return calendar.get(Calendar.HOUR_OF_DAY);
- }
-
- public int getMinute() {
- return calendar.get(Calendar.MINUTE);
- }
-
-
- public int getSecond() {
- return calendar.get(Calendar.SECOND);
- }
-
-
- public int getEra() {
- return calendar.get(Calendar.ERA);
- }
-
- public String getUSTimeZone() {
- String[] zones = new String[] {"Hawaii", "Alaskan", "Pacific",
- "Mountain", "Central", "Eastern"};
-
- return zones[10 + getZoneOffset()];
- }
-
- public int getZoneOffset() {
- return calendar.get(Calendar.ZONE_OFFSET)/(60*60*1000);
- }
-
-
- public int getDSTOffset() {
- return calendar.get(Calendar.DST_OFFSET)/(60*60*1000);
- }
-
-
- public int getAMPM() {
- return calendar.get(Calendar.AM_PM);
- }
-}
-
-
diff --git a/webapps/examples/WEB-INF/classes/cal/TableBean.java b/webapps/examples/WEB-INF/classes/cal/TableBean.java
deleted file mode 100644
index 9f1cc4a6cf7d..000000000000
--- a/webapps/examples/WEB-INF/classes/cal/TableBean.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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 cal;
-
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-import javax.servlet.http.HttpServletRequest;
-
-public class TableBean {
-
- private final Map<String, Entries> table;
- private final JspCalendar JspCal;
- private Entries entries;
- private String date;
- private String name = null;
- private String email = null;
- private boolean processError = false;
-
- public TableBean() {
- this.table = new ConcurrentHashMap<>(10);
- this.JspCal = new JspCalendar();
- this.date = JspCal.getCurrentDate();
- }
-
- public void setName(String nm) {
- this.name = nm;
- }
-
- public String getName() {
- return this.name;
- }
-
- public void setEmail(String mail) {
- this.email = mail;
- }
-
- public String getEmail() {
- return this.email;
- }
-
- public String getDate() {
- return this.date;
- }
-
- public Entries getEntries() {
- return this.entries;
- }
-
- public void processRequest(HttpServletRequest request) {
-
- // Get the name and e-mail.
- this.processError = false;
- if (name == null || name.equals("")) {
- setName(request.getParameter("name"));
- }
- if (email == null || email.equals("")) {
- setEmail(request.getParameter("email"));
- }
- if (name == null || email == null || name.equals("")
- || email.equals("")) {
- this.processError = true;
- return;
- }
-
- // Get the date.
- String dateR = request.getParameter("date");
- if (dateR == null) {
- date = JspCal.getCurrentDate();
- } else if (dateR.equalsIgnoreCase("next")) {
- date = JspCal.getNextDate();
- } else if (dateR.equalsIgnoreCase("prev")) {
- date = JspCal.getPrevDate();
- }
-
- entries = table.get(date);
- if (entries == null) {
- entries = new Entries();
- table.put(date, entries);
- }
-
- // If time is provided add the event.
- String time = request.getParameter("time");
- if (time != null) {
- entries.processRequest(request, time);
- }
- }
-
- public boolean getProcessError() {
- return this.processError;
- }
-}
diff --git a/webapps/examples/jsp/cal/cal1.jsp b/webapps/examples/jsp/cal/cal1.jsp
deleted file mode 100644
index ce29c13f9608..000000000000
--- a/webapps/examples/jsp/cal/cal1.jsp
+++ /dev/null
@@ -1,94 +0,0 @@
-<%--
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You 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.
---%>
-<%@page contentType="text/html; charset=UTF-8" %>
-<HTML>
-<HEAD><TITLE>
- Calendar: A JSP APPLICATION
-</TITLE></HEAD>
-
-
-<BODY BGCOLOR="white">
-
-<%@ page language="java" import="cal.*" %>
-<jsp:useBean id="table" scope="session" class="cal.TableBean" />
-
-<%
- table.processRequest(request);
- if (table.getProcessError() == false) {
-%>
-
-<!-- HTML table goes here -->
-<CENTER>
-<TABLE WIDTH=60% BGCOLOR=yellow CELLPADDING=15>
-<TR>
-<TD ALIGN=CENTER> <A HREF=cal1.jsp?date=prev> prev </A>
-<TD ALIGN=CENTER> Calendar:<%= table.getDate() %></TD>
-<TD ALIGN=CENTER> <A HREF=cal1.jsp?date=next> next </A>
-</TR>
-</TABLE>
-
-<!-- the main table -->
-<TABLE WIDTH=60% BGCOLOR=lightblue BORDER=1 CELLPADDING=10>
-<TR>
-<TH> Time </TH>
-<TH> Appointment </TH>
-</TR>
-<FORM METHOD=POST ACTION=cal1.jsp>
-<%
- for(int i=0; i<table.getEntries().getRows(); i++) {
- cal.Entry entr = table.getEntries().getEntry(i);
-%>
- <TR>
- <TD>
- <A HREF=cal2.jsp?time=<%= entr.getHour() %>>
- <%= entr.getHour() %> </A>
- </TD>
- <TD BGCOLOR=<%= entr.getColor() %>>
- <% out.print(util.HTMLFilter.filter(entr.getDescription())); %>
- </TD>
- </TR>
-<%
- }
-%>
-</FORM>
-</TABLE>
-<BR>
-
-<!-- footer -->
-<TABLE WIDTH=60% BGCOLOR=yellow CELLPADDING=15>
-<TR>
-<TD ALIGN=CENTER> <% out.print(util.HTMLFilter.filter(table.getName())); %> :
- <% out.print(util.HTMLFilter.filter(table.getEmail())); %> </TD>
-</TR>
-</TABLE>
-</CENTER>
-
-<%
- } else {
-%>
-<font size=5>
- You must enter your name and email address correctly.
-</font>
-<%
- }
-%>
-
-
-</BODY>
-</HTML>
-
-
diff --git a/webapps/examples/jsp/cal/cal2.jsp b/webapps/examples/jsp/cal/cal2.jsp
deleted file mode 100644
index e7e14d8e0468..000000000000
--- a/webapps/examples/jsp/cal/cal2.jsp
+++ /dev/null
@@ -1,45 +0,0 @@
-<%--
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You 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.
---%>
-<%@page contentType="text/html; charset=UTF-8" %>
-<HTML>
-<HEAD><TITLE>
- Calendar: A JSP APPLICATION
-</TITLE></HEAD>
-
-
-<BODY BGCOLOR="white">
-<jsp:useBean id="table" scope="session" class="cal.TableBean" />
-
-<%
- String time = request.getParameter ("time");
-%>
-
-<FONT SIZE=5> Please add the following event:
-<BR> <h3> Date <%= table.getDate() %>
-<BR> Time <%= util.HTMLFilter.filter(time) %> </h3>
-</FONT>
-<FORM METHOD=POST ACTION=cal1.jsp>
-<BR>
-<BR> <INPUT NAME="date" TYPE=HIDDEN VALUE="current">
-<BR> <INPUT NAME="time" TYPE=HIDDEN VALUE="<%= util.HTMLFilter.filter(time) %>">
-<BR> <h2> Description of the event <INPUT NAME="description" TYPE=TEXT SIZE=20> </h2>
-<BR> <INPUT TYPE=SUBMIT VALUE="submit">
-</FORM>
-
-</BODY>
-</HTML>
-
diff --git a/webapps/examples/jsp/cal/calendar.html b/webapps/examples/jsp/cal/calendar.html
deleted file mode 100644
index a0a3ea184134..000000000000
--- a/webapps/examples/jsp/cal/calendar.html
+++ /dev/null
@@ -1,43 +0,0 @@
-<html>
-<!--
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You 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.
--->
-
-<head>
-<title>Untitled Document</title>
-<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-</head>
-
-<body bgcolor="#FFFFFF">
-<p><font color="#0000FF"><a href="login.html"><img src="../images/execute.gif" align="right" border="0"></a><a href="../index.html"><img src="../images/return.gif" width="24" height="24" align="right" border="0"></a></font></p>
-
-<h2> Source Code for Calendar Example. <br>
-<h3><a href="cal1.jsp.html">cal1.jsp<font color="#0000FF"></a>
- </font> </h3>
-<h3><a href="cal2.jsp.html">cal2.jsp<font color="#0000FF"></a>
- </font> </h3>
-
-<br>
-<h2> Beans.
-<h3><a href="TableBean.java.html">TableBean<font color="#0000FF"></a>
- </font> </h3>
-<h3><a href="Entries.java.html">Entries<font color="#0000FF"></a>
- </font> </h3>
-<h3><a href="Entry.java.html">Entry<font color="#0000FF"></a>
- </font> </h3>
-
-</body>
-</html>
diff --git a/webapps/examples/jsp/cal/login.html b/webapps/examples/jsp/cal/login.html
deleted file mode 100644
index 8a62eca07b4d..000000000000
--- a/webapps/examples/jsp/cal/login.html
+++ /dev/null
@@ -1,47 +0,0 @@
-<html>
-<!--
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You 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.
--->
-
-<head>
- <title> Login page for the calendar. </title>
-</head>
-
-<body bgcolor="white">
-<center>
-
- <font size=7 color="red"> Please Enter the following information: </font>
-
-<br>
- <form method=GET action=cal1.jsp>
-
- <font size=5> Name <input type=text name="name" size=20>
- </font>
- <br>
- <font size=5> Email <input type=text name="email" size=20>
- </font>
- <br>
- <input type=submit name=action value="Submit">
-
- </form>
-<hr>
-<font size=3 color="red"> Note: This application does not implement the complete
-functionality of a typical calendar application. It demonstrates a way JSP can
-be used with HTML tables and forms.</font>
-
-</center>
-</body>
-</html>
diff --git a/webapps/examples/jsp/index.html b/webapps/examples/jsp/index.html
index dc25005b2710..ed2da43b9a12 100644
--- a/webapps/examples/jsp/index.html
+++ b/webapps/examples/jsp/index.html
@@ -249,14 +249,6 @@ <h2>JSP 1.2 Examples</h2>
<td style="width: 30%;"><a href="colors/clr.html"><img src="images/code.gif" alt=""></a><a href="colors/clr.html">Source</a></td>
</tr>
-<tr>
-<td>Calendar</td>
-
-<td style="width: 30%;"><a href="cal/login.html"><img src="images/execute.gif" alt=""></a><a href="cal/login.html">Execute</a></td>
-
-<td style="width: 30%;"><a href="cal/calendar.html"><img src="images/code.gif" alt=""></a><a href="cal/calendar.html">Source</a></td>
-</tr>
-
<tr>
<td>Include</td>

View File

@ -1,22 +0,0 @@
From 9ffd23fc27f5d1fc95bf97e5cea175c8968f4533 Mon Sep 17 00:00:00 2001
From: Mark Thomas <markt@apache.org>
Date: Fri, 6 Dec 2024 10:44:05 +0000
Subject: [PATCH] Revert change made for testing
---
webapps/examples/WEB-INF/classes/RequestHeaderExample.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/webapps/examples/WEB-INF/classes/RequestHeaderExample.java b/webapps/examples/WEB-INF/classes/RequestHeaderExample.java
index e32f8c233674..b324e0250d8a 100644
--- a/webapps/examples/WEB-INF/classes/RequestHeaderExample.java
+++ b/webapps/examples/WEB-INF/classes/RequestHeaderExample.java
@@ -73,7 +73,7 @@ protected boolean prefersJSON(String acceptHeader) {
// text/html, application/html, etc.
if (accept.contains("html")) {
- return true;
+ return false;
}
}
return false;

View File

@ -1,440 +0,0 @@
From 5adf342f83eebd5a5e0a83141c56955a25f3a0c3 Mon Sep 17 00:00:00 2001
From: Mark Thomas <markt@apache.org>
Date: Mon, 2 Dec 2024 14:19:14 +0000
Subject: [PATCH] Code clean-up - formatting. No functional change
Origin: https://github.com/apache/tomcat/commit/5adf342f83eebd5a5e0a83141c56955a25f3a0c3
---
.../WEB-INF/classes/CookieExample.java | 32 +++++-------
.../WEB-INF/classes/HelloWorldExample.java | 19 +++----
.../WEB-INF/classes/RequestHeaderExample.java | 49 ++++++-------------
.../WEB-INF/classes/RequestInfoExample.java | 25 ++++------
.../WEB-INF/classes/RequestParamExample.java | 22 +++------
.../WEB-INF/classes/ServletToJsp.java | 19 ++++---
.../WEB-INF/classes/SessionExample.java | 23 +++------
7 files changed, 67 insertions(+), 122 deletions(-)
diff --git a/webapps/examples/WEB-INF/classes/CookieExample.java b/webapps/examples/WEB-INF/classes/CookieExample.java
index cbf375e861bc..32eb1f806ce8 100644
--- a/webapps/examples/WEB-INF/classes/CookieExample.java
+++ b/webapps/examples/WEB-INF/classes/CookieExample.java
@@ -40,11 +40,8 @@ public class CookieExample extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
- public void doGet(HttpServletRequest request,
- HttpServletResponse response)
- throws IOException, ServletException
- {
- ResourceBundle rb = ResourceBundle.getBundle("LocalStrings",request.getLocale());
+ public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
+ ResourceBundle rb = ResourceBundle.getBundle("LocalStrings", request.getLocale());
String cookieName = request.getParameter("cookiename");
String cookieValue = request.getParameter("cookievalue");
@@ -75,11 +72,11 @@ public void doGet(HttpServletRequest request,
// addition of a PathInfo issue
out.println("<a href=\"../cookies.html\">");
- out.println("<img src=\"../images/code.gif\" height=24 " +
- "width=24 align=right border=0 alt=\"view code\"></a>");
+ out.println(
+ "<img src=\"../images/code.gif\" height=24 " + "width=24 align=right border=0 alt=\"view code\"></a>");
out.println("<a href=\"../index.html\">");
- out.println("<img src=\"../images/return.gif\" height=24 " +
- "width=24 align=right border=0 alt=\"return\"></a>");
+ out.println(
+ "<img src=\"../images/return.gif\" height=24 " + "width=24 align=right border=0 alt=\"return\"></a>");
out.println("<h3>" + title + "</h3>");
@@ -95,9 +92,8 @@ public void doGet(HttpServletRequest request,
String cName = cookie.getName();
String cValue = cookie.getValue();
out.print("Cookie Name: " + HTMLFilter.filter(cName) + "<br>");
- out.println(" Cookie Value: "
- + HTMLFilter.filter(CookieFilter.filter(cName, cValue, sessionId))
- + "<br><br>");
+ out.println(" Cookie Value: " + HTMLFilter.filter(CookieFilter.filter(cName, cValue, sessionId)) +
+ "<br><br>");
}
} else {
out.println(rb.getString("cookies.no-cookies"));
@@ -106,10 +102,8 @@ public void doGet(HttpServletRequest request,
if (aCookie != null) {
out.println("<P>");
out.println(rb.getString("cookies.set") + "<br>");
- out.print(rb.getString("cookies.name") + " "
- + HTMLFilter.filter(cookieName) + "<br>");
- out.print(rb.getString("cookies.value") + " "
- + HTMLFilter.filter(cookieValue));
+ out.print(rb.getString("cookies.name") + " " + HTMLFilter.filter(cookieName) + "<br>");
+ out.print(rb.getString("cookies.value") + " " + HTMLFilter.filter(cookieValue));
}
out.println("<P>");
@@ -128,13 +122,9 @@ public void doGet(HttpServletRequest request,
}
@Override
- public void doPost(HttpServletRequest request,
- HttpServletResponse response)
- throws IOException, ServletException
- {
+ public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
doGet(request, response);
}
}
-
diff --git a/webapps/examples/WEB-INF/classes/HelloWorldExample.java b/webapps/examples/WEB-INF/classes/HelloWorldExample.java
index 15911e23af85..346733aba9ab 100644
--- a/webapps/examples/WEB-INF/classes/HelloWorldExample.java
+++ b/webapps/examples/WEB-INF/classes/HelloWorldExample.java
@@ -1,3 +1,4 @@
+
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
@@ -34,12 +35,8 @@ public class HelloWorldExample extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
- public void doGet(HttpServletRequest request,
- HttpServletResponse response)
- throws IOException, ServletException
- {
- ResourceBundle rb =
- ResourceBundle.getBundle("LocalStrings",request.getLocale());
+ public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
+ ResourceBundle rb = ResourceBundle.getBundle("LocalStrings", request.getLocale());
response.setContentType("text/html");
response.setCharacterEncoding("UTF-8");
PrintWriter out = response.getWriter();
@@ -64,16 +61,14 @@ public void doGet(HttpServletRequest request,
// addition of a PathInfo issue
out.println("<a href=\"../helloworld.html\">");
- out.println("<img src=\"../images/code.gif\" height=24 " +
- "width=24 align=right border=0 alt=\"view code\"></a>");
+ out.println(
+ "<img src=\"../images/code.gif\" height=24 " + "width=24 align=right border=0 alt=\"view code\"></a>");
out.println("<a href=\"../index.html\">");
- out.println("<img src=\"../images/return.gif\" height=24 " +
- "width=24 align=right border=0 alt=\"return\"></a>");
+ out.println(
+ "<img src=\"../images/return.gif\" height=24 " + "width=24 align=right border=0 alt=\"return\"></a>");
out.println("<h1>" + title + "</h1>");
out.println("</body>");
out.println("</html>");
}
}
-
-
diff --git a/webapps/examples/WEB-INF/classes/RequestHeaderExample.java b/webapps/examples/WEB-INF/classes/RequestHeaderExample.java
index df2d2d51f78a..98c0e6a9878b 100644
--- a/webapps/examples/WEB-INF/classes/RequestHeaderExample.java
+++ b/webapps/examples/WEB-INF/classes/RequestHeaderExample.java
@@ -42,10 +42,7 @@ public class RequestHeaderExample extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
- public void doGet(HttpServletRequest request,
- HttpServletResponse response)
- throws IOException, ServletException
- {
+ public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
if (prefersJSON(request.getHeader("Accept"))) {
renderJSON(request, response);
} else {
@@ -54,16 +51,12 @@ public void doGet(HttpServletRequest request,
}
/**
- * Returns true if the client appears to prefer a JSON response,
- * false otherwise.
- *
- * Note that this method is not very pedantic and uses only a very lazy
- * algorithm for checking whether JSON is "preferred".
+ * Returns true if the client appears to prefer a JSON response, false otherwise. Note that this method is not very
+ * pedantic and uses only a very lazy algorithm for checking whether JSON is "preferred".
*
* @param acceptHeader The value of the HTTP "Accept" header from the client.
*
- * @return true if the client appears to prefer a JSON response,
- * false otherwise.
+ * @return true if the client appears to prefer a JSON response, false otherwise.
*/
protected boolean prefersJSON(String acceptHeader) {
if (null == acceptHeader) {
@@ -87,11 +80,8 @@ protected boolean prefersJSON(String acceptHeader) {
return false;
}
- protected void renderHTML(HttpServletRequest request,
- HttpServletResponse response)
- throws IOException
- {
- ResourceBundle rb = ResourceBundle.getBundle("LocalStrings",request.getLocale());
+ protected void renderHTML(HttpServletRequest request, HttpServletResponse response) throws IOException {
+ ResourceBundle rb = ResourceBundle.getBundle("LocalStrings", request.getLocale());
response.setContentType("text/html");
response.setCharacterEncoding("UTF-8");
@@ -113,11 +103,11 @@ protected void renderHTML(HttpServletRequest request,
// addition of a PathInfo issue
out.println("<a href=\"../reqheaders.html\">");
- out.println("<img src=\"../images/code.gif\" height=24 " +
- "width=24 align=right border=0 alt=\"view code\"></a>");
+ out.println(
+ "<img src=\"../images/code.gif\" height=24 " + "width=24 align=right border=0 alt=\"view code\"></a>");
out.println("<a href=\"../index.html\">");
- out.println("<img src=\"../images/return.gif\" height=24 " +
- "width=24 align=right border=0 alt=\"return\"></a>");
+ out.println(
+ "<img src=\"../images/return.gif\" height=24 " + "width=24 align=right border=0 alt=\"return\"></a>");
out.println("<h3>" + title + "</h3>");
out.println("<table border=0>");
@@ -143,9 +133,7 @@ protected void renderHTML(HttpServletRequest request,
out.println("</table>");
}
- protected void renderJSON(HttpServletRequest request, HttpServletResponse response)
- throws IOException
- {
+ protected void renderJSON(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.setContentType("application/json");
response.setCharacterEncoding("UTF-8");
@@ -157,14 +145,10 @@ protected void renderJSON(HttpServletRequest request, HttpServletResponse respon
String headerName = e.nextElement();
String headerValue = request.getHeader(headerName);
- out.append("{\"")
- .append(JSONFilter.escape(headerName))
- .append("\":\"")
- .append(JSONFilter.escape(headerValue))
- .append("\"}")
- ;
+ out.append("{\"").append(JSONFilter.escape(headerName)).append("\":\"")
+ .append(JSONFilter.escape(headerValue)).append("\"}");
- if(e.hasMoreElements()) {
+ if (e.hasMoreElements()) {
out.append(',');
}
}
@@ -173,10 +157,7 @@ protected void renderJSON(HttpServletRequest request, HttpServletResponse respon
}
@Override
- public void doPost(HttpServletRequest request,
- HttpServletResponse response)
- throws IOException, ServletException
- {
+ public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
doGet(request, response);
}
diff --git a/webapps/examples/WEB-INF/classes/RequestInfoExample.java b/webapps/examples/WEB-INF/classes/RequestInfoExample.java
index 9ea4668ad42d..57665bb2c51b 100644
--- a/webapps/examples/WEB-INF/classes/RequestInfoExample.java
+++ b/webapps/examples/WEB-INF/classes/RequestInfoExample.java
@@ -37,11 +37,8 @@ public class RequestInfoExample extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
- public void doGet(HttpServletRequest request,
- HttpServletResponse response)
- throws IOException, ServletException
- {
- ResourceBundle rb = ResourceBundle.getBundle("LocalStrings",request.getLocale());
+ public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
+ ResourceBundle rb = ResourceBundle.getBundle("LocalStrings", request.getLocale());
response.setContentType("text/html");
response.setCharacterEncoding("UTF-8");
@@ -64,11 +61,11 @@ public void doGet(HttpServletRequest request,
// addition of a PathInfo issue
out.println("<a href=\"../reqinfo.html\">");
- out.println("<img src=\"../images/code.gif\" height=24 " +
- "width=24 align=right border=0 alt=\"view code\"></a>");
+ out.println(
+ "<img src=\"../images/code.gif\" height=24 " + "width=24 align=right border=0 alt=\"view code\"></a>");
out.println("<a href=\"../index.html\">");
- out.println("<img src=\"../images/return.gif\" height=24 " +
- "width=24 align=right border=0 alt=\"return\"></a>");
+ out.println(
+ "<img src=\"../images/return.gif\" height=24 " + "width=24 align=right border=0 alt=\"return\"></a>");
out.println("<h3>" + title + "</h3>");
out.println("<table border=0><tr><td>");
@@ -93,9 +90,8 @@ public void doGet(HttpServletRequest request,
out.println(HTMLFilter.filter(request.getRemoteAddr()));
out.println("</td></tr>");
- String cipherSuite=
- (String)request.getAttribute("javax.servlet.request.cipher_suite");
- if(cipherSuite!=null){
+ String cipherSuite = (String) request.getAttribute("javax.servlet.request.cipher_suite");
+ if (cipherSuite != null) {
out.println("<tr><td>");
out.println("SSLCipherSuite:");
out.println("</td><td>");
@@ -107,10 +103,7 @@ public void doGet(HttpServletRequest request,
}
@Override
- public void doPost(HttpServletRequest request,
- HttpServletResponse response)
- throws IOException, ServletException
- {
+ public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
doGet(request, response);
}
diff --git a/webapps/examples/WEB-INF/classes/RequestParamExample.java b/webapps/examples/WEB-INF/classes/RequestParamExample.java
index cbcc3712b6d4..69482936c344 100644
--- a/webapps/examples/WEB-INF/classes/RequestParamExample.java
+++ b/webapps/examples/WEB-INF/classes/RequestParamExample.java
@@ -37,11 +37,8 @@ public class RequestParamExample extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
- public void doGet(HttpServletRequest request,
- HttpServletResponse response)
- throws IOException, ServletException
- {
- ResourceBundle rb = ResourceBundle.getBundle("LocalStrings",request.getLocale());
+ public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
+ ResourceBundle rb = ResourceBundle.getBundle("LocalStrings", request.getLocale());
response.setContentType("text/html");
response.setCharacterEncoding("UTF-8");
@@ -58,18 +55,18 @@ public void doGet(HttpServletRequest request,
// img stuff not req'd for source code HTML showing
- // all links relative
+ // all links relative
// XXX
// making these absolute till we work out the
// addition of a PathInfo issue
out.println("<a href=\"../reqparams.html\">");
- out.println("<img src=\"../images/code.gif\" height=24 " +
- "width=24 align=right border=0 alt=\"view code\"></a>");
+ out.println(
+ "<img src=\"../images/code.gif\" height=24 " + "width=24 align=right border=0 alt=\"view code\"></a>");
out.println("<a href=\"../index.html\">");
- out.println("<img src=\"../images/return.gif\" height=24 " +
- "width=24 align=right border=0 alt=\"return\"></a>");
+ out.println(
+ "<img src=\"../images/return.gif\" height=24 " + "width=24 align=right border=0 alt=\"return\"></a>");
out.println("<h3>" + title + "</h3>");
String firstName = request.getParameter("firstname");
@@ -101,10 +98,7 @@ public void doGet(HttpServletRequest request,
}
@Override
- public void doPost(HttpServletRequest request,
- HttpServletResponse response)
- throws IOException, ServletException
- {
+ public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
doGet(request, response);
}
diff --git a/webapps/examples/WEB-INF/classes/ServletToJsp.java b/webapps/examples/WEB-INF/classes/ServletToJsp.java
index a4903a9bba74..e83bbf377620 100644
--- a/webapps/examples/WEB-INF/classes/ServletToJsp.java
+++ b/webapps/examples/WEB-INF/classes/ServletToJsp.java
@@ -24,16 +24,15 @@ public class ServletToJsp extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
- public void doGet (HttpServletRequest request,
- HttpServletResponse response) {
+ public void doGet(HttpServletRequest request, HttpServletResponse response) {
- try {
- // Set the attribute and Forward to hello.jsp
- request.setAttribute ("servletName", "servletToJsp");
- getServletConfig().getServletContext().getRequestDispatcher(
- "/jsp/jsptoserv/hello.jsp").forward(request, response);
- } catch (Exception ex) {
- ex.printStackTrace ();
- }
+ try {
+ // Set the attribute and Forward to hello.jsp
+ request.setAttribute("servletName", "servletToJsp");
+ getServletConfig().getServletContext().getRequestDispatcher("/jsp/jsptoserv/hello.jsp").forward(request,
+ response);
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ }
}
}
diff --git a/webapps/examples/WEB-INF/classes/SessionExample.java b/webapps/examples/WEB-INF/classes/SessionExample.java
index c71ef5f743bb..724b9b437d67 100644
--- a/webapps/examples/WEB-INF/classes/SessionExample.java
+++ b/webapps/examples/WEB-INF/classes/SessionExample.java
@@ -40,11 +40,8 @@ public class SessionExample extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
- public void doGet(HttpServletRequest request,
- HttpServletResponse response)
- throws IOException, ServletException
- {
- ResourceBundle rb = ResourceBundle.getBundle("LocalStrings",request.getLocale());
+ public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
+ ResourceBundle rb = ResourceBundle.getBundle("LocalStrings", request.getLocale());
response.setContentType("text/html");
response.setCharacterEncoding("UTF-8");
@@ -68,11 +65,11 @@ public void doGet(HttpServletRequest request,
// addition of a PathInfo issue
out.println("<a href=\"../sessions.html\">");
- out.println("<img src=\"../images/code.gif\" height=24 " +
- "width=24 align=right border=0 alt=\"view code\"></a>");
+ out.println(
+ "<img src=\"../images/code.gif\" height=24 " + "width=24 align=right border=0 alt=\"view code\"></a>");
out.println("<a href=\"../index.html\">");
- out.println("<img src=\"../images/return.gif\" height=24 " +
- "width=24 align=right border=0 alt=\"return\"></a>");
+ out.println(
+ "<img src=\"../images/return.gif\" height=24 " + "width=24 align=right border=0 alt=\"return\"></a>");
out.println("<h3>" + title + "</h3>");
@@ -96,8 +93,7 @@ public void doGet(HttpServletRequest request,
while (names.hasMoreElements()) {
String name = names.nextElement();
String value = session.getAttribute(name).toString();
- out.println(HTMLFilter.filter(name) + " = "
- + HTMLFilter.filter(value) + "<br>");
+ out.println(HTMLFilter.filter(name) + " = " + HTMLFilter.filter(value) + "<br>");
}
out.println("<P>");
@@ -137,10 +133,7 @@ public void doGet(HttpServletRequest request,
}
@Override
- public void doPost(HttpServletRequest request,
- HttpServletResponse response)
- throws IOException, ServletException
- {
+ public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
doGet(request, response);
}

Binary file not shown.

Binary file not shown.

View File

@ -1,7 +1,7 @@
%global jspspec 2.3
%global major_version 9
%global minor_version 0
%global micro_version 96
%global micro_version 100
%global packdname apache-tomcat-%{version}-src
%global servletspec 4.0
%global elspec 3.0
@ -23,7 +23,7 @@
Name: tomcat
Epoch: 1
Version: %{major_version}.%{minor_version}.%{micro_version}
Release: 4
Release: 1
Summary: Apache Servlet/JSP Engine, RI for Servlet %{servletspec}/JSP %{jspspec} API
License: Apache-2.0
@ -51,19 +51,6 @@ Patch4: rhbz-1857043.patch
# remove bnd dependency which version is too low on rhel8
Patch6: remove-bnd-annotation.patch
Patch7: build-with-jdk-1.8.patch
Patch8: CVE-2024-52318.patch
Patch9: CVE-2024-50379-1.patch
Patch10: CVE-2024-50379-2.patch
Patch11: CVE-2024-54677-pre.patch
Patch12: CVE-2024-54677-1.patch
Patch13: CVE-2024-54677-2.patch
Patch14: CVE-2024-54677-3.patch
Patch15: CVE-2024-54677-4.patch
Patch16: CVE-2024-54677-5.patch
Patch17: CVE-2024-54677-6.patch
Patch18: CVE-2024-54677-7.patch
Patch19: CVE-2024-54677-8.patch
Patch20: CVE-2024-54677-9.patch
BuildArch: noarch
@ -430,6 +417,11 @@ fi
%{appdir}/docs
%changelog
* Fri Feb 21 2025 wangkai <13474090681@163.com> - 1:9.0.100-1
- Update to 9.0.100 for fix CVE-2024-56337
- Add a check to ensure that, if one or more web applications are potentially vulnerable to CVE-2024-56337,
the JVM has been configured to protect against the vulnerability and to configure the JVM correctly if not.
* Wed Dec 18 2024 wangkai <13474090681@163.com> - 1:9.0.96-4
- Fix CVE-2024-50379 CVE-2024-54677