in jspwiki-main/src/main/java/org/apache/wiki/parser/JSPWikiMarkupParser.java [1441:1530]
private Element handleDiv( ) throws IOException {
int ch = nextToken();
Element el = null;
if( ch == '%' ) {
String style = null;
String clazz = null;
ch = nextToken();
// Style or class?
if( ch == '(' ) {
style = readBraceContent('(',')');
} else if( Character.isLetter( (char) ch ) ) {
pushBack( ch );
clazz = readUntil( "( \t\n\r" );
//Note: ref.https://www.w3.org/TR/CSS21/syndata.html#characters
//CSS Classnames can contain only the characters [a-zA-Z0-9] and
//ISO 10646 characters U+00A0 and higher, plus the "-" and the "_".
//They cannot start with a digit, two hyphens, or a hyphen followed by a digit.
//(1) replace '.' by spaces, allowing multiple classnames on a div or span
//(2) remove any invalid character
if( clazz != null ) {
clazz = clazz.replace( '.', ' ' )
.replaceAll( "[^\\s-_\\w\\x200-\\x377]+", "" );
}
ch = nextToken();
// check for %%class1.class2( style information )
if( ch == '(' ) {
style = readBraceContent( '(', ')' );
// Pop out only spaces, so that the upcoming EOL check does not check the next line.
} else if( ch == '\n' || ch == '\r' ) {
pushBack( ch );
}
} else {
// Anything else stops.
pushBack( ch );
try {
final Boolean isSpan = m_styleStack.pop();
if( isSpan == null ) {
// Fail quietly
} else if( isSpan ) {
el = popElement( "span" );
} else {
el = popElement( "div" );
}
} catch( final EmptyStackException e ) {
LOG.debug( "Page '" + m_context.getName() + "' closes a %%-block that has not been opened." );
return m_currentElement;
}
return el;
}
// Check if there is an attempt to do something nasty
try {
style = StringEscapeUtils.unescapeHtml4(style);
if( style != null && style.contains( "javascript:" ) ) {
LOG.debug( "Attempt to output javascript within CSS: {}", style );
final ResourceBundle rb = Preferences.getBundle( m_context, InternationalizationManager.CORE_BUNDLE );
return addElement( makeError( rb.getString( "markupparser.error.javascriptattempt" ) ) );
}
} catch( final NumberFormatException e ) {
// If there are unknown entities, we don't want the parser to stop.
final ResourceBundle rb = Preferences.getBundle( m_context, InternationalizationManager.CORE_BUNDLE );
final String msg = MessageFormat.format( rb.getString( "markupparser.error.parserfailure"), e.getMessage() );
return addElement( makeError( msg ) );
}
// Decide if we should open a div or a span?
final String eol = peekAheadLine();
if( !eol.trim().isEmpty() ) {
// There is stuff after the class
el = new Element("span");
m_styleStack.push( Boolean.TRUE );
} else {
startBlockLevel();
el = new Element("div");
m_styleStack.push( Boolean.FALSE );
}
if( style != null ) el.setAttribute("style", style);
if( clazz != null ) el.setAttribute("class", clazz);
return pushElement( el );
}
pushBack( ch );
return el;
}