-
Notifications
You must be signed in to change notification settings - Fork 322
#3227 Update DWR library to version 3.0 #3230
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: release/2.8.1
Are you sure you want to change the base?
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,167 @@ | ||
| package com.serotonin.web.taglib; | ||
|
|
||
| import javax.servlet.jsp.JspException; | ||
| import javax.servlet.jsp.JspWriter; | ||
| import javax.servlet.jsp.tagext.TagSupport; | ||
| import javax.servlet.http.HttpServletRequest; | ||
| import java.io.IOException; | ||
| import java.lang.reflect.Array; | ||
| import java.util.Collection; | ||
| import java.util.Iterator; | ||
| import java.util.Map; | ||
| import java.util.ResourceBundle; | ||
|
|
||
| import org.apache.logging.log4j.core.util.JsonUtils; | ||
| import com.serotonin.web.i18n.I18NUtils; | ||
| import com.serotonin.web.i18n.LocalizableMessage; | ||
|
||
|
|
||
| public class DwrConvertTag extends TagSupport { | ||
|
|
||
| private Object obj; | ||
|
|
||
| public DwrConvertTag() { | ||
| // no-op | ||
| } | ||
|
|
||
| public void setObj(Object obj) { | ||
| this.obj = obj; | ||
| } | ||
|
|
||
| @Override | ||
| public int doStartTag() throws JspException { | ||
| try { | ||
| JspWriter out = pageContext.getOut(); | ||
| String json = toJson(obj); | ||
| out.write(json); | ||
| return SKIP_BODY; | ||
| } catch (IOException e) { | ||
| throw new JspException("Error writing DwrConvertTag JSON content", e); | ||
| } | ||
| } | ||
|
|
||
| @Override | ||
| public void release() { | ||
| super.release(); | ||
| this.obj = null; | ||
| } | ||
|
|
||
|
Comment on lines
21
to
52
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Find tag registration and usage
rg -n --fixed-strings "DwrConvertTag" -C2
rg -n --glob='**/*.tld' -C2 "com.serotonin.web.taglib.DwrConvertTag"
rg -n --glob='**/*.jsp' -C2 "dwrConvert" "DwrConvertTag"Repository: SCADA-LTS/Scada-LTS Length of output: 1917 🏁 Script executed: #!/bin/bash
# View the full TLD descriptor entry for the convert tag
cat -n WebContent/WEB-INF/tld/escape.tld | sed -n '550,570p'
# Search for actual usage in JSP files
fd --type f -e jsp -e jspx | head -20 | xargs -I {} rg -l "convert" {} 2>/dev/nullRepository: SCADA-LTS/Scada-LTS Length of output: 839 🏁 Script executed: #!/bin/bash
# Find JSP files and search for the convert tag usage
# The tag would typically be used with a namespace prefix like <escape:convert ...>
find . -name "*.jsp" -o -name "*.jspx" | xargs rg -l "convert" 2>/dev/null | head -10
# Also search explicitly for the tag pattern
rg -n "escape:convert|<convert" --type jsp 2>/dev/null | head -20Repository: SCADA-LTS/Scada-LTS Length of output: 420 🏁 Script executed: #!/bin/bash
# Search for escape:convert tag usage in JSP files
rg -n "escape:convert" --type jsp 2>/dev/null
# Also check for the tag declaration in JSP files
rg -n "<%@ taglib.*escape" --type jsp 2>/dev/null | head -5Repository: SCADA-LTS/Scada-LTS Length of output: 45 🏁 Script executed: #!/bin/bash
# Check if any JSP files actually import the escape taglib
rg -n "taglib.*escape" --type jsp 2>/dev/null | head -10
# Search for any test files or usage
find . -name "*Test*.java" -o -name "*test*.java" | xargs rg -l "DwrConvertTag\|escape:convert" 2>/dev/null
# Check for documentation or examples
find . -name "*.md" -o -name "*.txt" -o -name "*.rst" | xargs rg -l "DwrConvertTag\|dwrConvert" 2>/dev/nullRepository: SCADA-LTS/Scada-LTS Length of output: 47 🏁 Script executed: #!/bin/bash
# Simpler search for taglib imports
rg "taglib" --type jsp 2>/dev/null | grep -i escape | head -10
# Check for any JSP importing the escape TLD
rg -n "escape.tld\|uri=\".*escape" --type jsp 2>/dev/null | head -10
# Count occurrences of "convert" in JSP files to understand context
rg -n "convert" --type jsp 2>/dev/null | head -20Repository: SCADA-LTS/Scada-LTS Length of output: 45 🏁 Script executed: #!/bin/bash
# Check web.xml for TLD references
rg -n "escape.tld" --type xml 2>/dev/null
# Check if there's a web.xml file
find . -name "web.xml" -type f | head -3
# Look for taglib-uri declarations
rg -n "taglib-uri" --type xml 2>/dev/null | head -20
# Check escape.tld header to see URI
head -20 WebContent/WEB-INF/tld/escape.tldRepository: SCADA-LTS/Scada-LTS Length of output: 963 🏁 Script executed: #!/bin/bash
# List all TLD files
ls -la WebContent/WEB-INF/tld/
# Verify which file contains the convert tag
rg -l "convert" WebContent/WEB-INF/tld/Repository: SCADA-LTS/Scada-LTS Length of output: 335 🏁 Script executed: #!/bin/bash
# Check if escape.tld is referenced in web.xml
cat WebContent/WEB-INF/web.xml | grep -i "escape\|serotonin" | head -20
# Check the URI declared in escape.tld
head -15 WebContent/WEB-INF/tld/escape.tld | grep -i uri
# Search for JSP imports with the URI pattern
rg -n "http://www.serotoninsoftware.com" --type jsp 2>/dev/nullRepository: SCADA-LTS/Scada-LTS Length of output: 1757 🏁 Script executed: #!/bin/bash
# Check escape.tld for its declared URI
grep -n "uri" WebContent/WEB-INF/tld/escape.tld | head -3
# Search JSP files for taglib imports with escape or serotonin URIs
rg -n "<%@ taglib" --type jsp 2>/dev/null | head -30Repository: SCADA-LTS/Scada-LTS Length of output: 118 🏁 Script executed: #!/bin/bash
# Search for taglib directives in JSP using different pattern
rg "<%@.*taglib" --type jsp 2>/dev/null | head -20
# Also search for URI mappings in web.xml
grep -n "taglib-uri\|taglib-location" WebContent/WEB-INF/web.xml 2>/dev/nullRepository: SCADA-LTS/Scada-LTS Length of output: 45 🏁 Script executed: #!/bin/bash
# Final check: search for any reference to "dwrConvert" or "dwr" that might indicate usage
rg -i "dwr" --type jsp --type java 2>/dev/null | head -20
# Also check comments in the TLD
grep -A 2 -B 2 "convert" WebContent/WEB-INF/tld/escape.tldRepository: SCADA-LTS/Scada-LTS Length of output: 215 The tag IS properly registered in the TLD but appears unused in JSP pages. 🤖 Prompt for AI Agents |
||
| private String toJson(Object value) { | ||
| if (value == null) { | ||
| return "null"; | ||
| } | ||
|
|
||
| if (value instanceof Boolean) { | ||
| return ((Boolean) value) ? "true" : "false"; | ||
| } | ||
|
|
||
| if (value instanceof Number) { | ||
| return value.toString(); | ||
| } | ||
|
|
||
| if (value instanceof CharSequence) { | ||
| return quoteString(value.toString()); | ||
| } | ||
|
|
||
| if (value instanceof LocalizableMessage) { | ||
| String localized = resolveLocalizableMessage((LocalizableMessage) value); | ||
| return quoteString(localized); | ||
| } | ||
|
|
||
| if (value instanceof Map<?, ?>) { | ||
| return mapToJson((Map<?, ?>) value); | ||
| } | ||
|
|
||
| if (value instanceof Collection<?>) { | ||
| return collectionToJson((Collection<?>) value); | ||
| } | ||
|
|
||
| if (value.getClass().isArray()) { | ||
| return arrayToJson(value); | ||
| } | ||
|
|
||
| return quoteString(String.valueOf(value)); | ||
| } | ||
|
|
||
| private String resolveLocalizableMessage(LocalizableMessage lm) { | ||
| try { | ||
| if (pageContext == null) { | ||
| return lm.getLocalizedMessage(null); | ||
| } | ||
|
|
||
| Object req = pageContext.getRequest(); | ||
| if (req instanceof HttpServletRequest) { | ||
| HttpServletRequest httpReq = (HttpServletRequest) req; | ||
| ResourceBundle bundle = I18NUtils.getBundle(httpReq); | ||
| return lm.getLocalizedMessage(bundle); | ||
| } | ||
|
|
||
| return lm.getLocalizedMessage(null); | ||
| } catch (Exception e) { | ||
| String key = lm.getKey(); | ||
| return key != null ? key : lm.serialize(); | ||
| } | ||
| } | ||
|
|
||
| private String mapToJson(Map<?, ?> map) { | ||
| StringBuilder sb = new StringBuilder(); | ||
| sb.append('{'); | ||
| Iterator<? extends Map.Entry<?, ?>> it = map.entrySet().iterator(); | ||
| boolean first = true; | ||
| while (it.hasNext()) { | ||
| Map.Entry<?, ?> entry = it.next(); | ||
| if (!first) { | ||
| sb.append(','); | ||
| } | ||
| first = false; | ||
|
|
||
| String key = String.valueOf(entry.getKey()); | ||
| Object val = entry.getValue(); | ||
|
|
||
| sb.append(quoteString(key)); | ||
| sb.append(':'); | ||
| sb.append(toJson(val)); | ||
| } | ||
| sb.append('}'); | ||
| return sb.toString(); | ||
| } | ||
|
|
||
| private String collectionToJson(Collection<?> collection) { | ||
| StringBuilder sb = new StringBuilder(); | ||
| sb.append('['); | ||
| Iterator<?> it = collection.iterator(); | ||
| boolean first = true; | ||
| while (it.hasNext()) { | ||
| if (!first) { | ||
| sb.append(','); | ||
| } | ||
| first = false; | ||
| Object val = it.next(); | ||
| sb.append(toJson(val)); | ||
| } | ||
| sb.append(']'); | ||
| return sb.toString(); | ||
| } | ||
|
|
||
| private String arrayToJson(Object array) { | ||
| StringBuilder sb = new StringBuilder(); | ||
| sb.append('['); | ||
| int length = Array.getLength(array); | ||
| for (int i = 0; i < length; i++) { | ||
| if (i > 0) { | ||
| sb.append(','); | ||
| } | ||
| Object val = Array.get(array, i); | ||
| sb.append(toJson(val)); | ||
| } | ||
| sb.append(']'); | ||
| return sb.toString(); | ||
| } | ||
|
|
||
| private String quoteString(String s) { | ||
| StringBuilder sb = new StringBuilder(s.length() + 16); | ||
| sb.append('\"'); | ||
| JsonUtils.quoteAsString(s, sb); | ||
| sb.append('\"'); | ||
| return sb.toString(); | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🌐 Web query:
DWR 3.0 Direct Web Remoting dwr.xml DOCTYPE DTD reference specification💡 Result:
Use this DOCTYPE in dwr.xml for DWR 3.0:
(Older examples also reference "http://getahead.org/dwr/dwr30.dtd" with the same public id.) [1][2]
🌐 Web query:
getahead.org dwr30.dtd external DTD remote fetch best practices💡 Result:
Short answer: avoid letting XML parsers fetch external DTDs (like getahead.org/dwr30.dtd) from the network. Either disable external DTD/ENTITY loading or resolve DTDs locally and tightly control when/what the parser may fetch. Key practices:
Sources: OWASP XML-External-Entity cheat sheet; Oracle Java XML guidance; Semgrep/secure-coding guidance; SecureCodingPractices article; general DTD pitfalls. [1][2][3][4][5]
References
[1] OWASP XML External Entity Prevention Cheat Sheet.
[2] Oracle — Java Technology and XML (reduce external entity/DTD cost and controls).
[3] Semgrep / XML Security guidance (disable DTDs / external entities).
[4] SecureCodingPractices — Avoid XXE in Java parsers (features/attributes examples).
[5] Article on DTD pitfalls and availability/performance/security trade-offs.
Disable external DTD loading or use local DTD resolution.
While the PUBLIC identifier is correct for DWR 3.0, fetching the DTD from an external URL (
http://getahead.org/dwr/dwr30.dtd) introduces security risks (XXE/SSRF vulnerabilities) and operational fragility (network failures, offline/restricted environments). Configure your XML parser to disable external DTD/entity loading, or replace with a local, versioned copy of the DTD.🤖 Prompt for AI Agents