- 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,15 +103,22 @@ public final class Skin {
if (parts == null) if (parts == null)
reval.res.writeCharArray (source, 0, sourceLength); reval.res.writeCharArray (source, 0, sourceLength);
int written = 0; try {
for (int i=0; i<parts.length; i++) { // check for endless skin recursion
if (parts[i].start > written) if (++reval.skinDepth > 50)
reval.res.writeCharArray (source, written, parts[i].start-written); throw new RuntimeException ("Recursive skin invocation suspected");
parts[i].render (reval, thisObject, paramObject); int written = 0;
written = parts[i].end; for (int i=0; i<parts.length; i++) {
if (parts[i].start > written)
reval.res.writeCharArray (source, written, parts[i].start-written);
parts[i].render (reval, thisObject, paramObject);
written = parts[i].end;
}
if (written < sourceLength)
reval.res.writeCharArray (source, written, sourceLength-written);
} finally {
reval.skinDepth--;
} }
if (written < sourceLength)
reval.res.writeCharArray (source, written, sourceLength-written);
} }
/** /**
@ -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");
reval.res.insert (oldLength, prefix); if (prefix != null)
reval.res.write (suffix); reval.res.insert (oldLength, prefix);
if (suffix != null)
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);
} }