- Try to detect recursive skin invocation: When more than 50 skins are rendered

recursively, rendering is interrupted by throwing a RuntimeException.
- If a macro does not produce any output, the default macro attribute is written
out if it is specified.
This commit is contained in:
hns 2002-09-23 15:23:04 +00:00
parent 107dbbea7e
commit f105b8a516

View file

@ -103,6 +103,10 @@ public final class Skin {
if (parts == null) if (parts == null)
reval.res.writeCharArray (source, 0, sourceLength); reval.res.writeCharArray (source, 0, sourceLength);
try {
// check for endless skin recursion
if (++reval.skinDepth > 50)
throw new RuntimeException ("Recursive skin invocation suspected");
int written = 0; int written = 0;
for (int i=0; i<parts.length; i++) { for (int i=0; i<parts.length; i++) {
if (parts[i].start > written) if (parts[i].start > written)
@ -112,6 +116,9 @@ public final class Skin {
} }
if (written < sourceLength) if (written < sourceLength)
reval.res.writeCharArray (source, written, sourceLength-written); reval.res.writeCharArray (source, written, sourceLength-written);
} finally {
reval.skinDepth--;
}
} }
/** /**
@ -328,18 +335,26 @@ public final class Skin {
v = reval.scriptingEngine.get (handlerObject, name); v = reval.scriptingEngine.get (handlerObject, name);
} }
// check if macro wrote out to response buffer // check if macro wrote out to response buffer
int newLength = reval.res.getBufferLength (); if (reval.res.getBufferLength () > oldLength) {
if (newLength > oldLength) {
// insert prefix and append suffix // insert prefix and append suffix
String prefix = (String) parameters.get ("prefix"); String prefix = (String) parameters.get ("prefix");
String suffix = (String) parameters.get ("suffix"); String suffix = (String) parameters.get ("suffix");
if (prefix != null)
reval.res.insert (oldLength, prefix); reval.res.insert (oldLength, prefix);
if (suffix != null)
reval.res.write (suffix); reval.res.write (suffix);
} }
// if macro returned something append it to response // if macro returned something append it to response
if (v != null) { if (v != null) {
writeToResponse (v.toString (), reval.res); writeToResponse (v.toString (), reval.res);
} }
// if the macro hasn't produced any output, write default attribute
// if it is specified.
if (reval.res.getBufferLength () == oldLength) {
String defaultValue = (String) parameters.get ("default");
if (defaultValue != null)
reval.res.write (defaultValue);
}
} else { } else {
String msg = "[HopMacro unhandled: "+getFullName()+"]"; String msg = "[HopMacro unhandled: "+getFullName()+"]";
reval.res.write (" "+msg+" "); reval.res.write (" "+msg+" ");
@ -353,7 +368,7 @@ public final class Skin {
throw timeout; throw timeout;
} catch (Exception x) { } catch (Exception x) {
x.printStackTrace(); x.printStackTrace();
String msg = "[HopMacro error in "+this+": "+x+"]"; String msg = "[HopMacro error in "+getFullName()+": "+x+"]";
reval.res.write (" "+msg+" "); reval.res.write (" "+msg+" ");
app.logEvent (msg); app.logEvent (msg);
} }