diff --git a/src/main/java/org/olat/admin/user/bulkChange/UserBulkChangeStep02.java b/src/main/java/org/olat/admin/user/bulkChange/UserBulkChangeStep02.java index a93b7918f53a05e9c5f86d82f80becbe0abaf914..8692f6d50fe44ababf2734ce16f174deab99895a 100644 --- a/src/main/java/org/olat/admin/user/bulkChange/UserBulkChangeStep02.java +++ b/src/main/java/org/olat/admin/user/bulkChange/UserBulkChangeStep02.java @@ -61,7 +61,7 @@ import org.olat.core.id.Roles; import org.olat.core.util.Util; import org.olat.group.BusinessGroup; import org.olat.group.BusinessGroupService; -import org.olat.group.ui.BusinessGroupTableModel; +import org.olat.group.ui.BusinessGroupFormController; import org.olat.user.UserManager; import org.olat.user.propertyhandlers.UserPropertyHandler; @@ -133,7 +133,7 @@ class UserBulkChangeStep02 extends BasicStep { // use custom translator with fallback to user properties translator UserManager um = UserManager.getInstance(); Translator pt1 = um.getPropertyHandlerTranslator(getTranslator()); - Translator pt2 = Util.createPackageTranslator(BusinessGroupTableModel.class, ureq.getLocale(), pt1); + Translator pt2 = Util.createPackageTranslator(BusinessGroupFormController.class, ureq.getLocale(), pt1); Translator pt3 = Util.createPackageTranslator(GroupSearchController.class, ureq.getLocale(), pt2); setTranslator(pt3); flc.setTranslator(pt3); diff --git a/src/main/java/org/olat/admin/user/groups/GroupOverviewController.java b/src/main/java/org/olat/admin/user/groups/GroupOverviewController.java index 5d97dfdeba7ae74466f4a1e9a095a95b1ce89255..137d617bb96feae60296b54579567b56ade5ee54 100644 --- a/src/main/java/org/olat/admin/user/groups/GroupOverviewController.java +++ b/src/main/java/org/olat/admin/user/groups/GroupOverviewController.java @@ -36,6 +36,7 @@ import org.olat.core.gui.components.link.LinkFactory; import org.olat.core.gui.components.table.BooleanColumnDescriptor; import org.olat.core.gui.components.table.ColumnDescriptor; import org.olat.core.gui.components.table.CustomCellRenderer; +import org.olat.core.gui.components.table.CustomCssCellRenderer; import org.olat.core.gui.components.table.CustomRenderColumnDescriptor; import org.olat.core.gui.components.table.DefaultColumnDescriptor; import org.olat.core.gui.components.table.Table; @@ -63,6 +64,7 @@ import org.olat.group.model.BusinessGroupMembershipChange; import org.olat.group.model.SearchBusinessGroupParams; import org.olat.group.ui.main.BGRoleCellRenderer; import org.olat.group.ui.main.BGTableItem; +import org.olat.group.ui.main.BusinessGroupNameCellRenderer; import org.olat.group.ui.main.BusinessGroupTableModelWithType; import org.olat.group.ui.main.BusinessGroupTableModelWithType.Cols; @@ -108,12 +110,14 @@ public class GroupOverviewController extends BasicController { groupListCtr = new TableController(null, ureq, control, getTranslator()); listenTo(groupListCtr); - groupListCtr.addColumnDescriptor(new DefaultColumnDescriptor(Cols.name.i18n(), Cols.name.ordinal(), canStartGroups ? TABLE_ACTION_LAUNCH : null, ureq.getLocale())); + CustomCssCellRenderer nameRenderer = new BusinessGroupNameCellRenderer(); + groupListCtr.addColumnDescriptor(new CustomRenderColumnDescriptor(Cols.name.i18n(), Cols.name.ordinal(), canStartGroups ? TABLE_ACTION_LAUNCH : null, + getLocale(), ColumnDescriptor.ALIGNMENT_LEFT, nameRenderer)); groupListCtr.addColumnDescriptor(false, new DefaultColumnDescriptor(Cols.key.i18n(), Cols.key.ordinal(), null, getLocale())); groupListCtr.addColumnDescriptor(new DefaultColumnDescriptor(Cols.firstTime.i18n(), Cols.firstTime.ordinal(), null, getLocale())); groupListCtr.addColumnDescriptor(new DefaultColumnDescriptor(Cols.lastTime.i18n(), Cols.lastTime.ordinal(), null, getLocale())); CustomCellRenderer roleRenderer = new BGRoleCellRenderer(getLocale()); - groupListCtr.addColumnDescriptor(new CustomRenderColumnDescriptor(Cols.role.i18n(), Cols.role.ordinal(), null, getLocale(), ColumnDescriptor.ALIGNMENT_LEFT, roleRenderer)); + groupListCtr.addColumnDescriptor(new CustomRenderColumnDescriptor(Cols.role.i18n(), Cols.role.ordinal(), null, getLocale(), ColumnDescriptor.ALIGNMENT_LEFT, roleRenderer)); groupListCtr.addColumnDescriptor(new BooleanColumnDescriptor(Cols.allowLeave.i18n(), Cols.allowLeave.ordinal(), TABLE_ACTION_UNSUBSCRIBE, translate("table.header.leave"), null)); groupListCtr.setMultiSelect(true); diff --git a/src/main/java/org/olat/admin/user/groups/GroupSearchController.java b/src/main/java/org/olat/admin/user/groups/GroupSearchController.java index 9e7796b9112cd5948bbd112288036ee2112fe57b..7ee21e5e2d3ff35ce06b6a1d01915439b12a6be6 100644 --- a/src/main/java/org/olat/admin/user/groups/GroupSearchController.java +++ b/src/main/java/org/olat/admin/user/groups/GroupSearchController.java @@ -58,7 +58,7 @@ import org.olat.group.BusinessGroupService; import org.olat.group.model.AddToGroupsEvent; import org.olat.group.model.BGRepositoryEntryRelation; import org.olat.group.model.SearchBusinessGroupParams; -import org.olat.group.ui.BusinessGroupTableModel; +import org.olat.group.ui.BusinessGroupFormController; /** * Description:<br> @@ -89,7 +89,7 @@ public class GroupSearchController extends StepFormBasicController { public GroupSearchController(UserRequest ureq, WindowControl wControl) { super(ureq, wControl, LAYOUT_VERTICAL); businessGroupService = CoreSpringFactory.getImpl(BusinessGroupService.class); - Translator pT = Util.createPackageTranslator(BusinessGroupTableModel.class, ureq.getLocale(), getTranslator()); + Translator pT = Util.createPackageTranslator(BusinessGroupFormController.class, ureq.getLocale(), getTranslator()); flc.setTranslator(pT); initForm(ureq); } @@ -98,7 +98,7 @@ public class GroupSearchController extends StepFormBasicController { public GroupSearchController(UserRequest ureq, WindowControl wControl, Form form, StepsRunContext stepsRunContext, int layoutVertical, String pageName) { super(ureq, wControl, form, stepsRunContext, LAYOUT_VERTICAL, "resulttable"); businessGroupService = CoreSpringFactory.getImpl(BusinessGroupService.class); - Translator pT = Util.createPackageTranslator(BusinessGroupTableModel.class, ureq.getLocale(), getTranslator()); + Translator pT = Util.createPackageTranslator(BusinessGroupFormController.class, ureq.getLocale(), getTranslator()); flc.setTranslator(pT); initForm(ureq); } diff --git a/src/main/java/org/olat/catalog/ui/_content/catalog.html b/src/main/java/org/olat/catalog/ui/_content/catalog.html index 8f0e4e517c8078c61a155037420e5fa5afa8d015..40ba75651e65980fe43f25ccd6322d6f62e7e58a 100644 --- a/src/main/java/org/olat/catalog/ui/_content/catalog.html +++ b/src/main/java/org/olat/catalog/ui/_content/catalog.html @@ -5,9 +5,9 @@ <div class="o_catalog_nav"> #foreach($child in $history) #if($ri < $lastIndex) - <a href="$r.commandURIbg("history$ri")" onclick="return o2cl()" onkeypress="return o2cl()" $r.bgTarget()>$child.getName()</a> > + <a href="$r.commandURIbg("history$ri")" onclick="return o2cl()" onkeypress="return o2cl()" $r.bgTarget()>$r.escapeHtml($child.getName())</a> > #else - <strong>$child.getName()</strong> + <strong>$r.escapeHtml($child.getName())</strong> #end #set ($ri = $ri +1) #end @@ -15,10 +15,10 @@ ## render category description <div class="o_catalog_title b_with_small_icon_left o_catalog_cat_icon"> - $r.translate("category") <strong>$currentCatalogEntry.getName()</strong> + $r.translate("category") <strong>$r.escapeHtml($currentCatalogEntry.getName())</strong> </div> #if ($currentCatalogEntry.getDescription()) - <div class="o_catalog_desc">$currentCatalogEntry.getDescription()</div> + <div class="o_catalog_desc">$r.escapeHtml($currentCatalogEntry.getDescription())</div> #end ## calculate some temporary variables @@ -40,7 +40,7 @@ #foreach($child in $children) #if ($child.getType()==$node) <li><a href="$r.commandURIbg("child$ri")" onclick="return o2cl()" onkeypress="return o2cl()" $r.bgTarget()> - <span class="b_with_small_icon_left o_catalog_sub_icon">$child.getName()</span> + <span class="b_with_small_icon_left o_catalog_sub_icon">$r.escapeHtml($child.getName())</span> </a></li> #end #set ($ri = $ri +1) @@ -90,7 +90,7 @@ #end #end <a href="$r.commandURIbg("leaf$ri")" onclick="return o2cl()" onkeypress="return o2cl()" $r.bgTarget() class="b_with_small_icon_left ${iconRenderer.getIconCssClass($child.getRepositoryEntry())}"> - <span id="leaf$ri">$child.getRepositoryEntry().getDisplayname()</span> + <span id="leaf$ri">$r.escapeHtml($child.getRepositoryEntry().getDisplayname())</span> </a> <div id="o_tooltip_$ri" style="display:none;"> #if($r.available("image$ri")) diff --git a/src/main/java/org/olat/commons/calendar/ui/_content/event_details.html b/src/main/java/org/olat/commons/calendar/ui/_content/event_details.html index 5180a5ba07ff8cdde77ae8618a1c7fddf850c4ba..923df07dfee1569828b34248ad0319183052a422 100644 --- a/src/main/java/org/olat/commons/calendar/ui/_content/event_details.html +++ b/src/main/java/org/olat/commons/calendar/ui/_content/event_details.html @@ -1,15 +1,15 @@ <div class="o_cal_time">$date</div> <div class="o_cal_wv_event_tooltip_content"> - $subject + $r.escapeHtml($subject) <div class="o_cal_location"> - <b>$r.translate("cal.form.location"):</b> $location + <b>$r.translate("cal.form.location"):</b> $r.escapeHtml($location) </div> <div class="o_cal_links"> #foreach($link in $links) #if($link.intern) - <a href="javascript:top.o_openUriInMainWindow('$link.uri')" title="$link.title" class="$link.cssClass" onclick="return o2cl();">$link.displayName</a> + <a href="javascript:top.o_openUriInMainWindow('$link.uri')" title="$link.title" class="$link.cssClass" onclick="return o2cl();">$r.escapeHtml($link.displayName)</a> #else - <a href="$link.uri" title="$link.title" class="$link.cssClass" target="_blank">$link.displayName</a> + <a href="$link.uri" title="$link.title" class="$link.cssClass" target="_blank">$r.escapeHtml($link.displayName)</a> #end #end </div> diff --git a/src/main/java/org/olat/commons/info/portlet/InfoMessagePortletRunController.java b/src/main/java/org/olat/commons/info/portlet/InfoMessagePortletRunController.java index 3028212735652a3bd2001fcb6c5efea2e2fc4469..317595ea8278e53921bf48c447dfe39f724b183e 100644 --- a/src/main/java/org/olat/commons/info/portlet/InfoMessagePortletRunController.java +++ b/src/main/java/org/olat/commons/info/portlet/InfoMessagePortletRunController.java @@ -253,7 +253,8 @@ public class InfoMessagePortletRunController extends AbstractPortletRunControlle } sb.append(Formatter.truncate(title, 30)).append("</span> "); //link - String infoTitle = Formatter.truncate(item.getDescription(), 30); + String itemDesc = StringHelper.escapeHtml(item.getDescription()); + String infoTitle = Formatter.truncate(itemDesc, 30); sb.append("<a id='o_sel_info_msg_link_").append(key).append("' href=\"").append(item.getLink()).append("\" class=\"o_portlet_infomessage_link\""); sb.append(">") diff --git a/src/main/java/org/olat/commons/info/ui/_content/display.html b/src/main/java/org/olat/commons/info/ui/_content/display.html index 48a59149058eb01c79f8ba3c4b356653ff4b40c6..c3cd0fa6be5ff52aa6cb017e14d4fcd4d836855c 100644 --- a/src/main/java/org/olat/commons/info/ui/_content/display.html +++ b/src/main/java/org/olat/commons/info/ui/_content/display.html @@ -21,7 +21,7 @@ </div> #end $r.render("info.date.${info.getKey()}") - <h5>${info.getTitle()}</h5> + <h5>$r.escapeHtml(${info.getTitle()})</h5> <p class="o_item_info">$info.getInfos()#if($info.isModified()), <span class="o_item_info_mod">$info.getModifier()</span>#end</p> <p></p> #if($info.getMessage()) diff --git a/src/main/java/org/olat/core/commons/fullWebApp/BaseFullWebappController.java b/src/main/java/org/olat/core/commons/fullWebApp/BaseFullWebappController.java index 8b880c5811967145ee26e8fd8ebe7743e32807fb..5031dd8ec73d225bbbb37703e9b068910c842c39 100644 --- a/src/main/java/org/olat/core/commons/fullWebApp/BaseFullWebappController.java +++ b/src/main/java/org/olat/core/commons/fullWebApp/BaseFullWebappController.java @@ -855,7 +855,7 @@ public class BaseFullWebappController extends BasicController implements Generic getWindowControl().setError(translate("warn.tabsfull")); return null; } - DTabImpl dt = new DTabImpl(ores, repoOres, title, getWindowControl()); + DTabImpl dt = new DTabImpl(ores, repoOres, StringHelper.escapeHtml(title), getWindowControl()); return dt; } diff --git a/src/main/java/org/olat/core/commons/services/mark/ui/BookmarksController.java b/src/main/java/org/olat/core/commons/services/mark/ui/BookmarksController.java index 7720396731ef17973def0e64c947014bbb57b049..57806faf1e1097606419801db785ac3bf9a62774 100644 --- a/src/main/java/org/olat/core/commons/services/mark/ui/BookmarksController.java +++ b/src/main/java/org/olat/core/commons/services/mark/ui/BookmarksController.java @@ -94,7 +94,9 @@ public class BookmarksController extends BasicController { tableCtr = new TableController(tableConfig, ureq, getWindowControl(), getTranslator()); tableCtr.addColumnDescriptor(new DefaultColumnDescriptor("table.bm.title", 0, "choose", getLocale())); tableCtr.addColumnDescriptor(new DefaultColumnDescriptor("table.bm.resource", 1, null, getLocale())); - tableCtr.addColumnDescriptor(new DefaultColumnDescriptor("table.bm.description", 2, null, getLocale())); + DefaultColumnDescriptor descCol = new DefaultColumnDescriptor("table.bm.description", 2, null, getLocale()); + descCol.setEscapeHtml(false); + tableCtr.addColumnDescriptor(descCol); tableCtr.addColumnDescriptor(new StaticColumnDescriptor("delete", "table.header.delete", translate("action.delete"))); listenTo(tableCtr); diff --git a/src/main/java/org/olat/core/commons/services/mark/ui/BookmarksPortletRunController.java b/src/main/java/org/olat/core/commons/services/mark/ui/BookmarksPortletRunController.java index 1d12fd848dcb035d9967384130b9aac09f162bd0..6df1d46d64d6c0ae845d930f33cb0497116e49e1 100644 --- a/src/main/java/org/olat/core/commons/services/mark/ui/BookmarksPortletRunController.java +++ b/src/main/java/org/olat/core/commons/services/mark/ui/BookmarksPortletRunController.java @@ -319,7 +319,6 @@ public class BookmarksPortletRunController extends AbstractPortletRunController< switch (col) { case 0: String name = getBookmarkTitle(bookmark); - name = StringEscapeUtils.escapeHtml(name).toString(); return name; case 1: String resType = bookmark.getDisplayrestype(); diff --git a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/CheckboxElementComponent.java b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/CheckboxElementComponent.java index cac66faaa50051ac2eeb35e58418964581cb5d8d..6b22f5a5689fcf674dd8d128a0c9b6d558b6ce7d 100644 --- a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/CheckboxElementComponent.java +++ b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/CheckboxElementComponent.java @@ -43,9 +43,10 @@ class CheckboxElementComponent extends FormBaseComponentImpl { private final SelectionElement selectionWrapper; private final int which; + private boolean escapeHtml = true; private final String cssClass; private static final ComponentRenderer RENDERER = new CheckboxRenderer(); - public static final String RENDERARG_ESCAPEHTML = "ESC_HTML"; + //public static final String RENDERARG_ESCAPEHTML = "ESC_HTML"; /** * Constructor for a check box component. Set to private, use the @@ -86,6 +87,14 @@ class CheckboxElementComponent extends FormBaseComponentImpl { return which; } + public boolean isEscapeHtml() { + return escapeHtml; + } + + public void setEscapeHtml(boolean escapeHtml) { + this.escapeHtml = escapeHtml; + } + String getKey() { return selectionWrapper.getKey(which); } diff --git a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/CheckboxRenderer.java b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/CheckboxRenderer.java index 25736b46704a7511fec7ba57c4993e7725845be7..bf4c6b86cf62ab04d59dff0f4c8e986d98fc85f2 100644 --- a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/CheckboxRenderer.java +++ b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/CheckboxRenderer.java @@ -54,17 +54,10 @@ class CheckboxRenderer implements ComponentRenderer { RenderResult renderResult, String[] args) { //default should allow <b> </b> coming from localstring properties (see also http://bugs.olat.org/jira/browse/OLAT-4208) - boolean escapeHTML = false; - if(args != null && args.length>0){ - for (int i = 0; i < args.length; i++) { - if(CheckboxElementComponent.RENDERARG_ESCAPEHTML.equals(args[i])){ - escapeHTML = true;//so far used from SelectionTreeComponent, e.q. make the publish render tree safe against special chars in node titles - } - } - } - - CheckboxElementComponent cec = (CheckboxElementComponent)source; + CheckboxElementComponent cec = (CheckboxElementComponent)source; + boolean escapeHTML = cec.isEscapeHtml(); + String subStrName = "name=\"" + cec.getGroupingName() + "\""; String key = cec.getKey(); diff --git a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/SelectionTreeComponentRenderer.java b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/SelectionTreeComponentRenderer.java index 08f7f44051f985c361877998bbc95f3afdae5872..5c527d8e7d318e2abecc75933c2a62fd63bf5985 100644 --- a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/SelectionTreeComponentRenderer.java +++ b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/SelectionTreeComponentRenderer.java @@ -57,10 +57,6 @@ class SelectionTreeComponentRenderer implements ComponentRenderer { public void render(Renderer renderer, StringOutput sb, Component source, URLBuilder ubu, Translator translator, RenderResult renderResult, String[] args) { - - String[] clonedArgs = args != null ? args.clone() : new String[1]; - int cnt = clonedArgs.length; - clonedArgs[cnt-1] = CheckboxElementComponent.RENDERARG_ESCAPEHTML;// SelectionTreeComponent stc = (SelectionTreeComponent)source; Map<String,Component> checkboxes = stc.getSubComponents(); diff --git a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/table/TextFlexiCellRenderer.java b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/table/TextFlexiCellRenderer.java index c01756fe3a2fe11fa252d9ada1e549e42a9f9287..86b5b2a1fa72c6817e47b53a7065fb413201fdd1 100644 --- a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/table/TextFlexiCellRenderer.java +++ b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/table/TextFlexiCellRenderer.java @@ -32,6 +32,7 @@ import org.olat.core.gui.render.StringOutput; import org.olat.core.gui.render.URLBuilder; import org.olat.core.gui.translator.Translator; import org.olat.core.util.Formatter; +import org.olat.core.util.StringHelper; /** * Render value with toString. Render Date value with Formatter depending on locale. @@ -51,10 +52,11 @@ public class TextFlexiCellRenderer implements FlexiCellRenderer { if (cellValue instanceof Date) { Formatter formatter = Formatter.getInstance(translator.getLocale()); target.append( formatter.formatDateAndTime((Date)cellValue) ); - } else { - if (cellValue != null) { - target.append( cellValue.toString() ); - } + } else if(cellValue instanceof String) { + String str = (String)cellValue; + StringHelper.escapeHtml(target, str); + } else if (cellValue != null) { + target.append( cellValue.toString() ); } } } diff --git a/src/main/java/org/olat/core/gui/components/stack/StackedControllerImpl.java b/src/main/java/org/olat/core/gui/components/stack/StackedControllerImpl.java index 4bbda8ae29d0a078301c64f5ea2de5f80eb3ece8..0c77535e4da4076f6fdf7fc5dd7ddb771a37aa86 100644 --- a/src/main/java/org/olat/core/gui/components/stack/StackedControllerImpl.java +++ b/src/main/java/org/olat/core/gui/components/stack/StackedControllerImpl.java @@ -122,7 +122,7 @@ public class StackedControllerImpl extends DefaultController implements StackedC @Override public void pushController(String displayName, Controller controller) { Link link = LinkFactory.createLink("crumb_" + stack.size(), mainVC, this); - link.setCustomDisplayText(displayName); + link.setCustomDisplayText(StringHelper.escapeHtml(displayName)); link.setUserObject(controller); stack.add(link); setContent(controller); diff --git a/src/main/java/org/olat/core/gui/components/table/DefaultColumnDescriptor.java b/src/main/java/org/olat/core/gui/components/table/DefaultColumnDescriptor.java index 69067ca9500751645bc1bea640205b809d4d25d0..500f6594b2999b6316aca33531ffcac5128c8141 100644 --- a/src/main/java/org/olat/core/gui/components/table/DefaultColumnDescriptor.java +++ b/src/main/java/org/olat/core/gui/components/table/DefaultColumnDescriptor.java @@ -34,6 +34,7 @@ import java.util.Locale; import org.olat.core.gui.render.Renderer; import org.olat.core.gui.render.StringOutput; import org.olat.core.util.Formatter; +import org.olat.core.util.StringHelper; /** @@ -56,6 +57,7 @@ public class DefaultColumnDescriptor implements ColumnDescriptor { protected Collator collator; protected Table table; protected int dataColumn; + private boolean escapeHtml = true; private boolean translateHeaderKey = true; /** @@ -103,6 +105,10 @@ public class DefaultColumnDescriptor implements ColumnDescriptor { public void setTranslateHeaderKey(final boolean translateHeaderKey) { this.translateHeaderKey = translateHeaderKey; } + + public void setEscapeHtml(boolean escape) { + this.escapeHtml = escape; + } /** * @@ -118,17 +124,22 @@ public class DefaultColumnDescriptor implements ColumnDescriptor { */ public void renderValue(final StringOutput sb, final int row, final Renderer renderer) { Object val = getModelData(row); - String res; - if (val == null){ + if (val == null) { return; } if (val instanceof Date) { - res = formatter.formatDateAndTime((Date)val); - } - else { - res = val.toString(); + String res = formatter.formatDateAndTime((Date)val); + sb.append(res); + } else if(val instanceof String) { + if(escapeHtml) { + StringHelper.escapeHtml(sb, (String)val); + } else { + sb.append((String)val); + } + } else { + String res = val.toString(); + sb.append(res); } - sb.append(res); } /** diff --git a/src/main/java/org/olat/core/gui/components/tree/MenuTreeRenderer.java b/src/main/java/org/olat/core/gui/components/tree/MenuTreeRenderer.java index 3e3f5ae83a514f8b325955e12e8076c65408799c..a7ebdfc2b30d5fbcabed475f33104aa8aebc4bcc 100644 --- a/src/main/java/org/olat/core/gui/components/tree/MenuTreeRenderer.java +++ b/src/main/java/org/olat/core/gui/components/tree/MenuTreeRenderer.java @@ -47,6 +47,7 @@ import org.olat.core.gui.render.RenderingState; import org.olat.core.gui.render.StringOutput; import org.olat.core.gui.render.URLBuilder; import org.olat.core.gui.translator.Translator; +import org.olat.core.util.StringHelper; import org.olat.core.util.nodes.INode; import org.olat.core.util.tree.TreeHelper; @@ -160,9 +161,6 @@ public class MenuTreeRenderer implements ComponentRenderer { if(tree.isDragEnabled() || tree.isDropEnabled()) { appendDragAndDropObj(curRoot, tree, target, ubu, flags); } - - // render link - String title = curRoot.getTitle(); // expand icon // add ajax support and real open/close function @@ -273,8 +271,15 @@ public class MenuTreeRenderer implements ComponentRenderer { target.append(" id='da").append(ident).append("'"); } target.append(">"); - if(title != null && title.equals("")) title = " "; - target.append(title).append("</span></a>"); + + // render link + String title = curRoot.getTitle(); + if(title != null && title.equals("")) { + target.append(" "); + } else { + StringHelper.escapeHtml(target, title); + } + target.append("</span></a>"); // mark active item as strong for accessablity reasons target.append(selected ? "</strong>" : ""); target.append("</div>"); diff --git a/src/main/java/org/olat/core/gui/components/tree/SelectionTreeRenderer.java b/src/main/java/org/olat/core/gui/components/tree/SelectionTreeRenderer.java index 18f4b54dd51e3381becfbfa534d50711689b1977..e87967768104ef275ac1f8cc16ab01d640834637 100644 --- a/src/main/java/org/olat/core/gui/components/tree/SelectionTreeRenderer.java +++ b/src/main/java/org/olat/core/gui/components/tree/SelectionTreeRenderer.java @@ -179,7 +179,7 @@ public class SelectionTreeRenderer implements ComponentRenderer { // text using css if available String cssClass = root.getCssClass(); if (cssClass != null) target.append("<span class=\"").append(cssClass).append("\">"); - target.append(root.getTitle()); + target.append(StringHelper.escapeHtml(root.getTitle())); if (cssClass != null) target.append("</span>"); target.append("</div></div>"); } diff --git a/src/main/java/org/olat/core/gui/control/generic/closablewrapper/CloseableModalController.java b/src/main/java/org/olat/core/gui/control/generic/closablewrapper/CloseableModalController.java index ab7e8976c7f62d2f5103e243572fd239e3f5e603..bb0387c84614f1764655d7b0f7cb8342f96bb993 100644 --- a/src/main/java/org/olat/core/gui/control/generic/closablewrapper/CloseableModalController.java +++ b/src/main/java/org/olat/core/gui/control/generic/closablewrapper/CloseableModalController.java @@ -40,6 +40,7 @@ import org.olat.core.gui.control.WindowBackOffice; import org.olat.core.gui.control.WindowControl; import org.olat.core.gui.control.util.ZIndexWrapper; import org.olat.core.gui.render.ValidationResult; +import org.olat.core.util.StringHelper; import org.olat.core.util.Util; /** @@ -115,7 +116,9 @@ public class CloseableModalController extends DefaultController { backIcon.setVisible(false); } - if (title != null) myContent.contextPut("title", title); + if (title != null) { + myContent.contextPut("title", StringHelper.escapeHtml(title)); + } myContent.put("modalContent", modalContent); // use our own name this.displayAsOverlay = displayAsOverlay; diff --git a/src/main/java/org/olat/core/gui/control/generic/title/TitledWrapperController.java b/src/main/java/org/olat/core/gui/control/generic/title/TitledWrapperController.java index 2d1e5d0c25eb03271dad20d3435d50bf17d77497..9b0a04cdbe60358d0a3480772b037d5073bbfa68 100644 --- a/src/main/java/org/olat/core/gui/control/generic/title/TitledWrapperController.java +++ b/src/main/java/org/olat/core/gui/control/generic/title/TitledWrapperController.java @@ -103,7 +103,7 @@ public class TitledWrapperController extends BasicController implements Cloneabl this.titleInfo = titleInfo; // set title info variables - theVelocityContainer.contextPut(TITLE_VAR, titleInfo.getTitle()); + theVelocityContainer.contextPut(TITLE_VAR, StringHelper.escapeHtml(titleInfo.getTitle())); theVelocityContainer.contextPut(CONTEXT_TITLE_VAR, titleInfo.getContextTitle()); theVelocityContainer.contextPut(TITLE_SIZE, titleInfo.getTitleSize()); theVelocityContainer.contextPut(USE_SEPARATOR, Boolean.valueOf(titleInfo.isSeparatorEnabled())); diff --git a/src/main/java/org/olat/core/gui/render/StringOutput.java b/src/main/java/org/olat/core/gui/render/StringOutput.java index b21b201897c2743a7c63401154be913078654784..afb0f9468aa41e47fa645d3dc2ca00a592a27b86 100644 --- a/src/main/java/org/olat/core/gui/render/StringOutput.java +++ b/src/main/java/org/olat/core/gui/render/StringOutput.java @@ -30,10 +30,17 @@ import java.io.IOException; import java.io.Reader; import java.io.Writer; +import org.apache.commons.lang.StringEscapeUtils; +import org.olat.core.logging.OLog; +import org.olat.core.logging.Tracing; +import org.olat.core.util.filter.impl.OWASPAntiSamyXSSFilter; + /** * @author Felix Jost */ public class StringOutput extends Writer { + + private static final OLog log = Tracing.createLoggerFor(StringOutput.class); private StringBuilder sb; @@ -110,6 +117,28 @@ public class StringOutput extends Writer { return this; } + /** + * @param buffer + * @return + */ + public StringOutput appendScanned(String str) { + sb.append(new OWASPAntiSamyXSSFilter().filter(str)); + return this; + } + + /** + * @param buffer + * @return + */ + public StringOutput appendHtmlEscaped(String str) { + try { + StringEscapeUtils.escapeHtml(this, str); + } catch (IOException e) { + log.error("Error escaping HTML", e); + } + return this; + } + public void ensureCapacity(int minimumCapacity) { sb.ensureCapacity(minimumCapacity); } diff --git a/src/main/java/org/olat/core/gui/render/velocity/VelocityRenderDecorator.java b/src/main/java/org/olat/core/gui/render/velocity/VelocityRenderDecorator.java index 4b4256221b16bf6c33d33c1106a007adf0368d29..8ddb6204b65d785f8fe2b06081a3e82249a83f06 100644 --- a/src/main/java/org/olat/core/gui/render/velocity/VelocityRenderDecorator.java +++ b/src/main/java/org/olat/core/gui/render/velocity/VelocityRenderDecorator.java @@ -26,6 +26,7 @@ package org.olat.core.gui.render.velocity; +import java.io.IOException; import java.util.Date; import java.util.List; import java.util.Locale; @@ -43,6 +44,7 @@ import org.olat.core.helpers.Settings; import org.olat.core.util.Formatter; import org.olat.core.util.filter.Filter; import org.olat.core.util.filter.FilterFactory; +import org.olat.core.util.filter.impl.OWASPAntiSamyXSSFilter; import org.olat.core.util.i18n.I18nManager; /** @@ -294,7 +296,9 @@ public class VelocityRenderDecorator { StringOutput sb = new StringOutput(100); if (ContextHelpModule.isContextHelpEnabled()) { String hooverText = renderer.getTranslator().translate(hoverTextKey); - if (hooverText != null) hooverText = StringEscapeUtils.escapeHtml(hooverText).toString(); + if (hooverText != null) { + hooverText = StringEscapeUtils.escapeHtml(hooverText); + } String langCode = renderer.getTranslator().getLocale().toString(); sb.append("<a href=\"javascript:contextHelpWindow('"); Renderer.renderNormalURI(sb, "help/"); @@ -487,10 +491,15 @@ public class VelocityRenderDecorator { * @param str * @return */ - public String escapeHtml(String str) { + public String escapeHtml(String str) throws IOException { return StringEscapeUtils.escapeHtml(str); } + public String xssScan(String str) { + OWASPAntiSamyXSSFilter filter = new OWASPAntiSamyXSSFilter(); + return filter.filter(str); + } + /** * @param key * @return @@ -510,7 +519,7 @@ public class VelocityRenderDecorator { * @return */ public String translateInAttribute(String key) { - return escapeHtml(translate(key)); + return StringEscapeUtils.escapeHtml(translate(key)); } /** diff --git a/src/main/java/org/olat/core/util/StringHelper.java b/src/main/java/org/olat/core/util/StringHelper.java index f0ad631069c69760320d8c79c35828197a0e69d0..a175824cdd56d9d037efed4119f82658ca7ca402 100644 --- a/src/main/java/org/olat/core/util/StringHelper.java +++ b/src/main/java/org/olat/core/util/StringHelper.java @@ -26,7 +26,9 @@ package org.olat.core.util; +import java.io.IOException; import java.io.UnsupportedEncodingException; +import java.io.Writer; import java.net.URLEncoder; import java.text.DateFormat; import java.text.DecimalFormat; @@ -44,9 +46,13 @@ import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.apache.commons.lang.StringEscapeUtils; import org.olat.core.id.Identity; import org.olat.core.id.UserConstants; import org.olat.core.logging.AssertException; +import org.olat.core.logging.OLog; +import org.olat.core.logging.Tracing; +import org.olat.core.util.filter.impl.OWASPAntiSamyXSSFilter; /** * enclosing_type Description: <br> @@ -55,6 +61,8 @@ import org.olat.core.logging.AssertException; * @author Felix Jost */ public class StringHelper { + + private static final OLog log = Tracing.createLoggerFor(StringHelper.class); private static final NumberFormat numFormatter; private static final String WHITESPACE_REGEXP = "^\\s*$"; @@ -327,6 +335,22 @@ public class StringHelper { } return tmpDET.toString(); } + + public static final String escapeHtml(String str) { + return StringEscapeUtils.escapeHtml(str); + } + + public static final void escapeHtml(Writer writer, String str) { + try { + StringEscapeUtils.escapeHtml(writer, str); + } catch (IOException e) { + log.error("Error escaping HTML", e); + } + } + + public static final String xssScan(String str) { + return new OWASPAntiSamyXSSFilter().filter(str); + } /** * @param cellValue diff --git a/src/main/java/org/olat/core/util/filter/impl/OWASPAntiSamyXSSFilter.java b/src/main/java/org/olat/core/util/filter/impl/OWASPAntiSamyXSSFilter.java index be549129e6a6b0806afc55056478985b8537767b..b93860573dabd37ecc9ab0d75105417d9de38c53 100644 --- a/src/main/java/org/olat/core/util/filter/impl/OWASPAntiSamyXSSFilter.java +++ b/src/main/java/org/olat/core/util/filter/impl/OWASPAntiSamyXSSFilter.java @@ -24,9 +24,9 @@ import java.io.PrintWriter; import java.io.StringWriter; import java.io.Writer; -import org.olat.core.logging.AssertException; -import org.olat.core.logging.LogDelegator; import org.olat.core.logging.OLATRuntimeException; +import org.olat.core.logging.OLog; +import org.olat.core.logging.Tracing; import org.olat.core.util.filter.Filter; import org.olat.core.util.vfs.VFSManager; import org.owasp.validator.html.AntiSamy; @@ -50,7 +50,9 @@ import org.owasp.validator.html.ScanException; * Initial Date: 30.07.2009 <br> * @author Roman Haag, roman.haag@frentix.com */ -public class OWASPAntiSamyXSSFilter extends LogDelegator implements Filter { +public class OWASPAntiSamyXSSFilter implements Filter { + + private static final OLog log = Tracing.createLoggerFor(OWASPAntiSamyXSSFilter.class); //to be found in /_resources private static final String POLICY_FILE = "antisamy-tinymce.xml"; @@ -58,6 +60,26 @@ public class OWASPAntiSamyXSSFilter extends LogDelegator implements Filter { private CleanResults cr; private final int maxLength; private final boolean entityEncodeIntlChars; + + private static Policy tinyMcePolicy; + private static Policy internalionalTinyMcePolicy; + + static { + try { + String fPath = VFSManager.sanitizePath(OWASPAntiSamyXSSFilter.class.getPackage().getName()); + fPath = fPath.replace('.', '/'); + fPath = fPath + "/_resources/" + POLICY_FILE; + InputStream inStream = OWASPAntiSamyXSSFilter.class.getResourceAsStream(fPath); + tinyMcePolicy = Policy.getInstance(inStream); + internalionalTinyMcePolicy = tinyMcePolicy.cloneWithDirective("entityEncodeIntlChars", "false"); + } catch (Exception e) { + log.error("", e); + } + } + + public OWASPAntiSamyXSSFilter(){ + this(-1, true, false); + } /** * @param maxLength @@ -80,7 +102,7 @@ public class OWASPAntiSamyXSSFilter extends LogDelegator implements Filter { if (jUnitDebug) System.out.println("************************************************"); if (jUnitDebug) System.out.println(" Input: " + original); if (original == null) { - if (isLogDebugEnabled()) logDebug(" Filter-Input was null, is this intended?", null); + if (log.isDebug()) log.debug(" Filter-Input was null, is this intended?", null); return null; } String output = getCleanHTML(original); @@ -89,11 +111,11 @@ public class OWASPAntiSamyXSSFilter extends LogDelegator implements Filter { } else { String errMsg = getOrPrintErrorMessages(); if (!errMsg.equals("")) { - logWarn(" Filter applied! => message from filter, check if this should not be allowed: " + errMsg, null); - logInfo(" Original Input: \n" + original, null); - logInfo(" Filter Result: \n" + output, null); + log.warn(" Filter applied! => message from filter, check if this should not be allowed: " + errMsg, null); + log.info(" Original Input: \n" + original, null); + log.info(" Filter Result: \n" + output, null); } else { - logDebug(" Filter result doesn't match input! / no message from filter! maybe only some formatting differences.", null); + log.debug(" Filter result doesn't match input! / no message from filter! maybe only some formatting differences.", null); } } return output; @@ -108,33 +130,25 @@ public class OWASPAntiSamyXSSFilter extends LogDelegator implements Filter { } private String getCleanHTML(String original) { - Policy policy = null; - try { - String fPath = VFSManager.sanitizePath(this.getClass().getPackage().getName()); - fPath = fPath.replace('.', '/'); - fPath = fPath + "/_resources/" + POLICY_FILE; - InputStream inStream = this.getClass().getResourceAsStream(fPath); - policy = Policy.getInstance(inStream); - if(maxLength > 0) { - policy = policy.cloneWithDirective("maxInputSize", Integer.toString(maxLength)); - } - if(!entityEncodeIntlChars) { - policy = policy.cloneWithDirective("entityEncodeIntlChars", "false"); - } - } catch (PolicyException e) { - if (jUnitDebug) System.err.println("Policy file not found/readable/valid!"); - printOriginStackTrace(); - throw new AssertException("Owasp AntiSamy XSS Filter missing a correct policy file."); - } + Policy policy; + if(entityEncodeIntlChars) { + policy = tinyMcePolicy; + } else { + policy = internalionalTinyMcePolicy; + } + if(maxLength > 0) { + policy = policy.cloneWithDirective("maxInputSize", Integer.toString(maxLength)); + } + AntiSamy as = new AntiSamy(); cr = null; try { cr = as.scan(original, policy); } catch (ScanException e) { - logError("XSS Filter scan error", e); + log.error("XSS Filter scan error", e); printOriginStackTrace(); } catch (PolicyException e) { - logError("XSS Filter policy error", e); + log.error("XSS Filter policy error", e); printOriginStackTrace(); } String output = null; @@ -142,7 +156,7 @@ public class OWASPAntiSamyXSSFilter extends LogDelegator implements Filter { output = cr.getCleanHTML(); } catch (Error e){ output = ""; - logError("Error getting cleaned HTML from string::" + original, e); + log.error("Error getting cleaned HTML from string::" + original, e); } if (jUnitDebug) System.out.println("OWASP-AntiSamy-Outp: " + output); getOrPrintErrorMessages(); diff --git a/src/main/java/org/olat/course/area/BGAreaTableModel.java b/src/main/java/org/olat/course/area/BGAreaTableModel.java index fd20057685226d6c5f8d3384cef4de5a00219a90..4c000c36e272a0e10338e9c5d6bc89631cbca98b 100644 --- a/src/main/java/org/olat/course/area/BGAreaTableModel.java +++ b/src/main/java/org/olat/course/area/BGAreaTableModel.java @@ -28,7 +28,6 @@ package org.olat.course.area; import java.util.ArrayList; import java.util.List; -import org.apache.commons.lang.StringEscapeUtils; import org.olat.core.gui.components.table.DefaultTableDataModel; import org.olat.core.util.Formatter; import org.olat.core.util.filter.FilterFactory; @@ -65,7 +64,7 @@ public class BGAreaTableModel extends DefaultTableDataModel<BGArea> { BGArea area = getObject(row); switch (col) { case 0: - return StringEscapeUtils.escapeHtml(area.getName()).toString(); + return area.getName(); case 1: String description = area.getDescription(); description = FilterFactory.getHtmlTagsFilter().filter(description); diff --git a/src/main/java/org/olat/course/assessment/EfficiencyStatementsListModel.java b/src/main/java/org/olat/course/assessment/EfficiencyStatementsListModel.java index 326c2ec1d2ace20fbb2c2c5b4b59ea02d3d86375..08286ca36265eeb1d9953c4e833c5ca943a90d2a 100644 --- a/src/main/java/org/olat/course/assessment/EfficiencyStatementsListModel.java +++ b/src/main/java/org/olat/course/assessment/EfficiencyStatementsListModel.java @@ -27,7 +27,6 @@ package org.olat.course.assessment; import java.util.List; -import org.apache.commons.lang.StringEscapeUtils; import org.olat.core.gui.components.table.DefaultTableDataModel; import org.olat.course.assessment.model.UserEfficiencyStatementLight; @@ -39,7 +38,7 @@ import org.olat.course.assessment.model.UserEfficiencyStatementLight; * * @author gnaegi */ -public class EfficiencyStatementsListModel extends DefaultTableDataModel { +public class EfficiencyStatementsListModel extends DefaultTableDataModel<UserEfficiencyStatementLight> { /** * @param list of efficiencyStatements @@ -62,7 +61,7 @@ public class EfficiencyStatementsListModel extends DefaultTableDataModel { UserEfficiencyStatementLight efficiencyStatement = getEfficiencyStatementAt(row); switch (col) { case 0: - return StringEscapeUtils.escapeHtml(efficiencyStatement.getShortTitle()); + return efficiencyStatement.getShortTitle(); case 1: Float score = efficiencyStatement.getScore(); return AssessmentHelper.getRoundedScore(score); @@ -78,6 +77,6 @@ public class EfficiencyStatementsListModel extends DefaultTableDataModel { * @return the efficiencyStatement at the given row */ public UserEfficiencyStatementLight getEfficiencyStatementAt(int row) { - return (UserEfficiencyStatementLight) objects.get(row); + return objects.get(row); } } diff --git a/src/main/java/org/olat/course/assessment/EfficiencyStatementsPortletRunController.java b/src/main/java/org/olat/course/assessment/EfficiencyStatementsPortletRunController.java index 064efcec935ad102679e610ebd6a4185c2f104df..0a1e200e4ca03f04542abf6854a196f48eac3552 100644 --- a/src/main/java/org/olat/course/assessment/EfficiencyStatementsPortletRunController.java +++ b/src/main/java/org/olat/course/assessment/EfficiencyStatementsPortletRunController.java @@ -29,7 +29,6 @@ import java.util.ArrayList; import java.util.Comparator; import java.util.List; -import org.apache.commons.lang.StringEscapeUtils; import org.olat.NewControllerFactory; import org.olat.core.commons.fullWebApp.LayoutMain3ColsController; import org.olat.core.commons.fullWebApp.popup.BaseFullWebappPopupLayoutFactory; @@ -318,7 +317,7 @@ public class EfficiencyStatementsPortletRunController extends AbstractPortletRun UserEfficiencyStatementLight efficiencyStatement = getEfficiencyStatementAt(row); switch (col) { case 0: - return StringEscapeUtils.escapeHtml(efficiencyStatement.getShortTitle()); + return efficiencyStatement.getShortTitle(); case 1: Float score = efficiencyStatement.getScore(); return AssessmentHelper.getRoundedScore(score); diff --git a/src/main/java/org/olat/course/assessment/GroupAndContextTableModel.java b/src/main/java/org/olat/course/assessment/GroupAndContextTableModel.java index 6b75cf423b4ccfea672aab7842c3af1d41d90166..2c3bc85a0e33444bc1041c6948e0374404041290 100644 --- a/src/main/java/org/olat/course/assessment/GroupAndContextTableModel.java +++ b/src/main/java/org/olat/course/assessment/GroupAndContextTableModel.java @@ -31,6 +31,7 @@ import java.util.List; import org.apache.commons.lang.StringEscapeUtils; import org.olat.core.gui.components.table.DefaultTableDataModel; import org.olat.core.util.Formatter; +import org.olat.core.util.StringHelper; import org.olat.core.util.filter.FilterFactory; import org.olat.group.BusinessGroup; @@ -70,8 +71,10 @@ public class GroupAndContextTableModel extends DefaultTableDataModel<BusinessGro switch (col) { case 0 : String groupName = businessGroup.getName(); - if(groupName == null) return "???"; - return StringEscapeUtils.escapeHtml(businessGroup.getName()); + if(StringHelper.containsNonWhitespace(groupName)){ + return StringEscapeUtils.escapeHtml(businessGroup.getName()); + } + return "???"; case 1 : String tmp = businessGroup.getDescription(); tmp = FilterFactory.getHtmlTagsFilter().filter(tmp); diff --git a/src/main/java/org/olat/course/assessment/IndentedNodeRenderer.java b/src/main/java/org/olat/course/assessment/IndentedNodeRenderer.java index 765a905c58fc83245fc037f72d1684c114176468..9be00d20747e3f686eef4eb17307dc33acbae269 100644 --- a/src/main/java/org/olat/course/assessment/IndentedNodeRenderer.java +++ b/src/main/java/org/olat/course/assessment/IndentedNodeRenderer.java @@ -28,10 +28,10 @@ package org.olat.course.assessment; import java.util.Locale; import java.util.Map; -import org.apache.commons.lang.StringEscapeUtils; import org.olat.core.gui.components.table.CustomCellRenderer; import org.olat.core.gui.render.Renderer; import org.olat.core.gui.render.StringOutput; +import org.olat.core.util.StringHelper; import org.olat.course.nodes.CourseNodeFactory; /** @@ -85,10 +85,10 @@ public class IndentedNodeRenderer implements CustomCellRenderer { sb.append("<span class=\"b_with_small_icon_left ").append(cssClass); if (altText != null) { - sb.append("\" title= \"").append(StringEscapeUtils.escapeHtml(altText)); + sb.append("\" title= \"").append(StringHelper.escapeHtml(altText)); } sb.append("\">"); - sb.append(title); + sb.append(StringHelper.escapeHtml(title)); sb.append("</span>"); } diff --git a/src/main/java/org/olat/course/assessment/_content/detailview.html b/src/main/java/org/olat/course/assessment/_content/detailview.html index f5f39af20375a9a94100786ee83147e23dce868e..9efb61094b78b61c40946699570f0d17b414fac8 100644 --- a/src/main/java/org/olat/course/assessment/_content/detailview.html +++ b/src/main/java/org/olat/course/assessment/_content/detailview.html @@ -1,7 +1,7 @@ #if ($courseNode) - <div class="b_with_small_icon_left $courseNodeCss">$courseNode.getShortTitle() + <div class="b_with_small_icon_left $courseNodeCss">$r.escapeHtml($courseNode.getShortTitle()) #if ($courseNode.getLongTitle() && $courseNode.getLongTitle() != "") - ($courseNode.getLongTitle()) + ($r.escapeHtml($courseNode.getLongTitle())) #end </div> <hr /> @@ -34,7 +34,7 @@ $r.render("backLink") </td> <td> #foreach($group in $participantGroups) - $group.getName() + $r.escapeHtml($group.getName()) #if ($velocityCount < $participantGroups.size()) , #end diff --git a/src/main/java/org/olat/course/assessment/_content/wrapper.html b/src/main/java/org/olat/course/assessment/_content/wrapper.html index ac4ba5f0696417794a6042523beb5a6ee22e364d..e31a175683216388e39b4dacb4b4dfe67ea12740 100644 --- a/src/main/java/org/olat/course/assessment/_content/wrapper.html +++ b/src/main/java/org/olat/course/assessment/_content/wrapper.html @@ -1,7 +1,7 @@ #if ($courseNode) - <span class="b_with_small_icon_left $courseNodeCss"><strong>$courseNode.getShortTitle()</strong></span> + <span class="b_with_small_icon_left $courseNodeCss"><strong>$r.escapeHtml($courseNode.getShortTitle())</strong></span> #if ($courseNode.getLongTitle() && $courseNode.getLongTitle() != "") - ($courseNode.getLongTitle()) + ($r.escapeHtml($courseNode.getLongTitle())) #end <br /> <hr /> diff --git a/src/main/java/org/olat/course/editor/_content/index.html b/src/main/java/org/olat/course/editor/_content/index.html index d9c19ec76ff944ffa6899eb3030a7c86fc95b2ce..5bb882a1415cc855b874b4ef07911633a6ac74e6 100644 --- a/src/main/java/org/olat/course/editor/_content/index.html +++ b/src/main/java/org/olat/course/editor/_content/index.html @@ -22,12 +22,12 @@ <li> #set ($counter = $velocityCount - 1) #if($errorHelpWizardLink.get($counter)!="NONE") - <strong><a href="$r.commandURI($errorHelpWizardLink.get($counter))" title="${fixit}">${elem}</a></strong> + <strong><a href="$r.commandURI($errorHelpWizardLink.get($counter))" title="${fixit}">$r.escapeHtml(${elem})</a></strong> #else - <strong>${elem}</strong> + <strong>$r.escapeHtml(${elem})</strong> #end <br /> - ${errorMessage.get(${counter})} + $r.escapeHtml(${errorMessage.get(${counter})}) </li> #end <ul> @@ -55,12 +55,12 @@ <li> #set ($counter = $velocityCount - 1) #if($warningHelpWizardLink.get($counter)!="NONE") - <strong><a href="$r.commandURI($warningHelpWizardLink.get($counter))" title="${fixit}">${elem}</a></strong> + <strong><a href="$r.commandURI($warningHelpWizardLink.get($counter))" title="${fixit}">$r.escapeHtml(${elem})</a></strong> #else - <strong>${elem}</strong> + <strong>$r.escapeHtml(${elem})</strong> #end <br /> - ${warningMessage.get(${counter})} + $r.escapeHtml(${warningMessage.get(${counter})}) </li> #end <ul> diff --git a/src/main/java/org/olat/course/nodes/fo/FOPeekviewController.java b/src/main/java/org/olat/course/nodes/fo/FOPeekviewController.java index 2dbc26c92216194b4b6b9bb866f8c28530f04ba8..902afaefc23a8cde19fc7f777e6872aafeb7911a 100644 --- a/src/main/java/org/olat/course/nodes/fo/FOPeekviewController.java +++ b/src/main/java/org/olat/course/nodes/fo/FOPeekviewController.java @@ -32,6 +32,7 @@ import org.olat.core.gui.control.Event; import org.olat.core.gui.control.WindowControl; import org.olat.core.gui.control.controller.BasicController; import org.olat.core.util.Formatter; +import org.olat.core.util.StringHelper; import org.olat.core.util.Util; import org.olat.modules.fo.Forum; import org.olat.modules.fo.ForumManager; @@ -76,7 +77,7 @@ public class FOPeekviewController extends BasicController implements Controller // add link to item // Add link to jump to course node Link nodeLink = LinkFactory.createLink("nodeLink_" + message.getKey(), peekviewVC, this); - nodeLink.setCustomDisplayText(message.getTitle()); + nodeLink.setCustomDisplayText(StringHelper.escapeHtml(message.getTitle())); nodeLink.setCustomEnabledLinkCSS("b_with_small_icon_left o_forum_message_icon o_gotoNode"); nodeLink.setUserObject(Long.toString(message.getKey())); } diff --git a/src/main/java/org/olat/course/nodes/info/InfoPeekViewController.java b/src/main/java/org/olat/course/nodes/info/InfoPeekViewController.java index 865ecf485ff90c0cc600dd8bd7c77afe64832762..8ebc2e1850ad8b37efccd35c78d6855f5499bbd1 100644 --- a/src/main/java/org/olat/course/nodes/info/InfoPeekViewController.java +++ b/src/main/java/org/olat/course/nodes/info/InfoPeekViewController.java @@ -181,7 +181,8 @@ public class InfoPeekViewController extends BasicController { } else { sb.append("<span>"); } - String title = Formatter.truncate(item.getTitle(), 64); + String title = StringHelper.escapeHtml(item.getTitle()); + title = Formatter.truncate(title, 64); sb.append(title).append("</span> "); //link if(StringHelper.containsNonWhitespace(item.getBusinessPath())) { diff --git a/src/main/java/org/olat/course/nodes/st/PeekViewWrapperController.java b/src/main/java/org/olat/course/nodes/st/PeekViewWrapperController.java index 0cf382e420ec31170421af7778af7d5f3a026c40..e07364cbde0d4e7254b9ab86afa827a9390a3090 100644 --- a/src/main/java/org/olat/course/nodes/st/PeekViewWrapperController.java +++ b/src/main/java/org/olat/course/nodes/st/PeekViewWrapperController.java @@ -29,6 +29,7 @@ import org.olat.core.gui.control.Controller; import org.olat.core.gui.control.Event; import org.olat.core.gui.control.WindowControl; import org.olat.core.gui.control.controller.BasicController; +import org.olat.core.util.StringHelper; import org.olat.course.nodes.CourseNode; import org.olat.course.nodes.CourseNodeFactory; @@ -69,7 +70,7 @@ public class PeekViewWrapperController extends BasicController { peekViewWrapperVC.contextPut("coursenode", courseNode); // Add link to jump to course node nodeLink = LinkFactory.createLink("nodeLink", peekViewWrapperVC, this); - nodeLink.setCustomDisplayText(courseNode.getShortTitle()); + nodeLink.setCustomDisplayText(StringHelper.escapeHtml(courseNode.getShortTitle())); // Add css class for course node type String iconCSSClass = CourseNodeFactory.getInstance().getCourseNodeConfigurationEvenForDisabledBB(courseNode.getType()).getIconCSSClass(); nodeLink.setCustomEnabledLinkCSS("b_with_small_icon_left o_gotoNode " + iconCSSClass); diff --git a/src/main/java/org/olat/course/nodes/st/_content/peekViewWrapper.html b/src/main/java/org/olat/course/nodes/st/_content/peekViewWrapper.html index c4b62245333b4a1fe26c65b1642cf5563be1e4e8..6adca7bb12b8a47ee864503746a210afe71773e3 100644 --- a/src/main/java/org/olat/course/nodes/st/_content/peekViewWrapper.html +++ b/src/main/java/org/olat/course/nodes/st/_content/peekViewWrapper.html @@ -5,7 +5,7 @@ </h5> </div> #if ($coursenode.getLongTitle() && $coursenode.getLongTitle() != "") - <div class="o_course_run_displaytitle">$coursenode.getLongTitle()</div> + <div class="o_course_run_displaytitle">$r.escapeHtml($coursenode.getLongTitle())</div> #end #if ($coursenode.getLearningObjectives() && $coursenode.getLearningObjectives() != "") <div class="o_course_run_objectives"> diff --git a/src/main/java/org/olat/course/run/RunMainController.java b/src/main/java/org/olat/course/run/RunMainController.java index a852fa4bef414002fd414dce81742c7e03415074..0a1197c4b157f925be943f7e5b75dff477b0d3a0 100644 --- a/src/main/java/org/olat/course/run/RunMainController.java +++ b/src/main/java/org/olat/course/run/RunMainController.java @@ -75,6 +75,7 @@ import org.olat.core.logging.AssertException; import org.olat.core.logging.OLATSecurityException; import org.olat.core.logging.activity.CourseLoggingAction; import org.olat.core.logging.activity.ThreadLocalUserActivityLogger; +import org.olat.core.util.StringHelper; import org.olat.core.util.coordinate.CoordinatorManager; import org.olat.core.util.coordinate.SyncerExecutor; import org.olat.core.util.event.GenericEventListener; @@ -1053,7 +1054,7 @@ public class RunMainController extends MainLayoutBasicController implements Gene if (uce.getCoachedGroups().size() > 0) { myTool.addHeader(translate("header.tools.ownerGroups")); for (BusinessGroup group:uce.getCoachedGroups()) { - myTool.addLink(CMD_START_GROUP_PREFIX + group.getKey().toString(), group.getName()); + myTool.addLink(CMD_START_GROUP_PREFIX + group.getKey().toString(), StringHelper.escapeHtml(group.getName())); } } diff --git a/src/main/java/org/olat/group/ui/BusinessGroupTableModel.java b/src/main/java/org/olat/group/ui/BusinessGroupTableModel.java deleted file mode 100644 index 054bb578b950cbec8eaf2ee130d9cbe3ee989134..0000000000000000000000000000000000000000 --- a/src/main/java/org/olat/group/ui/BusinessGroupTableModel.java +++ /dev/null @@ -1,97 +0,0 @@ -/** -* OLAT - Online Learning and Training<br> -* http://www.olat.org -* <p> -* Licensed under the Apache License, Version 2.0 (the "License"); <br> -* you may not use this file except in compliance with the License.<br> -* You may obtain a copy of the License at -* <p> -* http://www.apache.org/licenses/LICENSE-2.0 -* <p> -* Unless required by applicable law or agreed to in writing,<br> -* software distributed under the License is distributed on an "AS IS" BASIS, <br> -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> -* See the License for the specific language governing permissions and <br> -* limitations under the License. -* <p> -* Copyright (c) since 2004 at Multimedia- & E-Learning Services (MELS),<br> -* University of Zurich, Switzerland. -* <hr> -* <a href="http://www.openolat.org"> -* OpenOLAT - Online Learning and Training</a><br> -* This file has been modified by the OpenOLAT community. Changes are licensed -* under the Apache 2.0 license as the original file. -*/ - -package org.olat.group.ui; - -import java.util.ArrayList; -import java.util.List; - -import org.apache.commons.lang.StringEscapeUtils; -import org.olat.core.gui.components.table.DefaultTableDataModel; -import org.olat.core.util.Formatter; -import org.olat.core.util.filter.FilterFactory; -import org.olat.group.BusinessGroup; - -/** - * Description: <BR> - * Initial Date: Aug 5, 2004 - * - * @author patrick - */ - -public class BusinessGroupTableModel extends DefaultTableDataModel<BusinessGroup> { - private static final int COLUMN_COUNT = 3; - - /** - * @param owned list of business groups - */ - public BusinessGroupTableModel(List<BusinessGroup> groups) { - super(groups); - } - - /** - * @see org.olat.core.gui.components.table.TableDataModel#getColumnCount() - */ - public int getColumnCount() { - return COLUMN_COUNT; - } - - /** - * @see org.olat.core.gui.components.table.TableDataModel#getValueAt(int, int) - */ - public Object getValueAt(int row, int col) { - BusinessGroup businessGroup = objects.get(row); - switch (col) { - case 0: - String name = businessGroup.getName(); - name = StringEscapeUtils.escapeHtml(name).toString(); - return name; - case 1: - String tmp = businessGroup.getDescription(); - tmp = FilterFactory.getHtmlTagsFilter().filter(tmp); - tmp = Formatter.truncate(tmp, 256); - return tmp; - default: - return "ERROR"; - } - } - - @Override - public BusinessGroupTableModel createCopyWithEmptyList() { - return new BusinessGroupTableModel(new ArrayList<BusinessGroup>()); - } - - /** - * @param row - * @return the business group at the given row - */ - public BusinessGroup getBusinessGroupAt(int row) { - return objects.get(row); - } - - public void removeBusinessGroup(BusinessGroup businessGroup) { - objects.remove(businessGroup); - } -} \ No newline at end of file diff --git a/src/main/java/org/olat/group/ui/main/BGResourcesCellRenderer.java b/src/main/java/org/olat/group/ui/main/BGResourcesCellRenderer.java index b855dcdf54bcddda5960c3b5f512fb7b60ef3923..5a03a8407ec2ec011fd1f1ed41898a215e900b91 100644 --- a/src/main/java/org/olat/group/ui/main/BGResourcesCellRenderer.java +++ b/src/main/java/org/olat/group/ui/main/BGResourcesCellRenderer.java @@ -33,6 +33,7 @@ import org.olat.core.gui.render.Renderer; import org.olat.core.gui.render.StringOutput; import org.olat.core.gui.render.URLBuilder; import org.olat.core.gui.translator.Translator; +import org.olat.core.util.StringHelper; import org.olat.repository.RepositoryEntryShort; /** @@ -68,7 +69,7 @@ public class BGResourcesCellRenderer implements CustomCellRenderer { if(sb.length() > 0) { sb.append(", "); } - sb.append(relation.getDisplayname()); + sb.append(StringHelper.escapeHtml(relation.getDisplayname())); } else if(count >= 2) { Link link = LinkFactory.createLink("repo_entry_" + UUID.randomUUID().toString(), container, listeningController); link.setCustomDisplayText("..."); @@ -81,7 +82,7 @@ public class BGResourcesCellRenderer implements CustomCellRenderer { } else { Link link = LinkFactory.createLink("repo_entry_" + UUID.randomUUID().toString(), container, listeningController); link.setCustomEnabledLinkCSS("b_small_table_icon o_CourseModule_icon"); - link.setCustomDisplayText(relation.getDisplayname()); + link.setCustomDisplayText(StringHelper.escapeHtml(relation.getDisplayname())); link.setUserObject(relation); URLBuilder ubu = renderer.getUrlBuilder().createCopyFor(link); diff --git a/src/main/java/org/olat/group/ui/main/BusinessGroupNameCellRenderer.java b/src/main/java/org/olat/group/ui/main/BusinessGroupNameCellRenderer.java index e1a61cc11522e51a7d5029041420f3fe8252fe48..f60cab6a3acacf0defd0bce7c37856cb088d3a24 100644 --- a/src/main/java/org/olat/group/ui/main/BusinessGroupNameCellRenderer.java +++ b/src/main/java/org/olat/group/ui/main/BusinessGroupNameCellRenderer.java @@ -19,8 +19,8 @@ */ package org.olat.group.ui.main; -import org.apache.commons.lang.StringEscapeUtils; import org.olat.core.gui.components.table.CustomCssCellRenderer; +import org.olat.core.util.StringHelper; import org.olat.group.BusinessGroupShort; /** @@ -51,7 +51,7 @@ public class BusinessGroupNameCellRenderer extends CustomCssCellRenderer { protected String getCellValue(Object val) { if(val instanceof BusinessGroupShort) { BusinessGroupShort group = (BusinessGroupShort)val; - return group.getName() == null ? "" : StringEscapeUtils.escapeHtml(group.getName()); + return group.getName() == null ? "" : StringHelper.escapeHtml(group.getName()); } return val == null ? "" : val.toString(); } diff --git a/src/main/java/org/olat/modules/fo/ForumMessagesTableDataModel.java b/src/main/java/org/olat/modules/fo/ForumMessagesTableDataModel.java index 4f3c8350417a6376ac8375cce70194565eb3a382..fddce2cda89402b9c8a5863bee6bcbea92043fc7 100644 --- a/src/main/java/org/olat/modules/fo/ForumMessagesTableDataModel.java +++ b/src/main/java/org/olat/modules/fo/ForumMessagesTableDataModel.java @@ -29,22 +29,21 @@ import java.util.Date; import java.util.List; import java.util.Set; -import org.apache.commons.lang.StringEscapeUtils; import org.olat.core.gui.components.table.DefaultTableDataModel; import org.olat.core.id.UserConstants; /** * @author Felix Jost */ -public class ForumMessagesTableDataModel extends DefaultTableDataModel { +public class ForumMessagesTableDataModel extends DefaultTableDataModel<Message> { - private Set readMsgs; + private Set<Long> readMsgs; public ForumMessagesTableDataModel() { super(null); } - public ForumMessagesTableDataModel(List objects, Set readMsgs) { + public ForumMessagesTableDataModel(List<Message> objects, Set<Long> readMsgs) { super(objects); this.readMsgs = readMsgs; } @@ -61,10 +60,10 @@ public class ForumMessagesTableDataModel extends DefaultTableDataModel { * fourth if it is new or not */ public final Object getValueAt(int row, int col) { - Message m= (Message) getObject(row); + Message m= getObject(row); switch (col) { case 0 : - String title = StringEscapeUtils.escapeHtml(m.getTitle()).toString(); + String title = m.getTitle(); return title; case 1 : String last= m.getCreator().getUser().getProperty(UserConstants.LASTNAME, getLocale()); diff --git a/src/main/java/org/olat/note/NoteController.java b/src/main/java/org/olat/note/NoteController.java index 98916c2363aca4692d6ba2d25f95a790c0c73918..e7d94169f44a56acdc21ce22997acac0b19a3d04 100644 --- a/src/main/java/org/olat/note/NoteController.java +++ b/src/main/java/org/olat/note/NoteController.java @@ -40,6 +40,7 @@ import org.olat.core.gui.control.Event; import org.olat.core.gui.control.WindowControl; import org.olat.core.id.Identity; import org.olat.core.id.OLATResourceable; +import org.olat.core.util.StringHelper; import org.olat.core.util.event.EventBus; import org.olat.core.util.event.GenericEventListener; import org.olat.core.util.resource.OLATResourceableJustBeforeDeletedEvent; @@ -114,7 +115,7 @@ public class NoteController extends FormBasicController implements GenericEventL // At beginning, the forms shows the note as a disabled field and an edit button. When the user // clicks the edit button, the rich text field turns to the enabled state and the edit button // is set to visible false and the submit button to visible true. - setFormTitle("note", new String[] { n.getNoteTitle() }); + setFormTitle("note", new String[] { StringHelper.escapeHtml(n.getNoteTitle()) }); // set custom css style to override default read-only view of rich text element setFormStyle("o_notes"); diff --git a/src/main/java/org/olat/note/NoteListTableDataModel.java b/src/main/java/org/olat/note/NoteListTableDataModel.java index ace82c82ff501429d79d89fc7bde49e27bfd3f64..0a0aa52173e5bd647dc1a2cfb6495344929f4240 100644 --- a/src/main/java/org/olat/note/NoteListTableDataModel.java +++ b/src/main/java/org/olat/note/NoteListTableDataModel.java @@ -28,7 +28,6 @@ package org.olat.note; import java.util.List; import java.util.Locale; -import org.apache.commons.lang.StringEscapeUtils; import org.olat.ControllerFactory; import org.olat.core.gui.components.table.DefaultTableDataModel; @@ -38,7 +37,7 @@ import org.olat.core.gui.components.table.DefaultTableDataModel; * @author Alexander Schneider */ -class NoteListTableDataModel extends DefaultTableDataModel { +class NoteListTableDataModel extends DefaultTableDataModel<Note> { private Locale locale; @@ -55,11 +54,10 @@ class NoteListTableDataModel extends DefaultTableDataModel { * @see org.olat.core.gui.components.table.TableDataModel#getValueAt(int, int) */ public final Object getValueAt(int row, int col) { - Note n = (Note) getObject(row); + Note n = getObject(row); switch (col) { case 0 : - String title = StringEscapeUtils.escapeHtml(n.getNoteTitle()).toString(); - return title; + return n.getNoteTitle(); case 1 : String resType = n.getResourceTypeName(); return (resType == null ? "n/a" : ControllerFactory.translateResourceableTypeName(resType, locale)); diff --git a/src/main/java/org/olat/note/NotesPortletRunController.java b/src/main/java/org/olat/note/NotesPortletRunController.java index ffb7fe115f78411120daf18e1bf80bfb8af815bd..fa5bfd4b5d6e41adca6e4b0ea3b929be1592bdab 100644 --- a/src/main/java/org/olat/note/NotesPortletRunController.java +++ b/src/main/java/org/olat/note/NotesPortletRunController.java @@ -322,10 +322,10 @@ public class NotesPortletRunController extends AbstractPortletRunController<Note * @see org.olat.core.gui.components.table.TableDataModel#getValueAt(int, int) */ public final Object getValueAt(int row, int col) { - Note note = (Note) getObject(row).getValue(); + Note note = getObject(row).getValue(); switch (col) { case 0: - return StringEscapeUtils.escapeHtml(note.getNoteTitle()).toString(); + return note.getNoteTitle(); case 1: String resType = note.getResourceTypeName(); return (resType == null ? "n/a" : ControllerFactory.translateResourceableTypeName(resType, locale)); @@ -359,7 +359,7 @@ public class NotesPortletRunController extends AbstractPortletRunController<Note Note note = getObject(row).getValue(); switch (col) { case 0: - return StringEscapeUtils.escapeHtml(note.getNoteTitle()).toString(); + return note.getNoteTitle(); case 1: Date lastUpdate = note.getLastModified(); return lastUpdate; diff --git a/src/main/java/org/olat/portfolio/ui/artefacts/view/EPArtefactViewController.java b/src/main/java/org/olat/portfolio/ui/artefacts/view/EPArtefactViewController.java index de8993b214eb3ec6b1dd325613716696ba0eba39..c824afcc13c29ba643826236c5f203dc0c51e5d8 100644 --- a/src/main/java/org/olat/portfolio/ui/artefacts/view/EPArtefactViewController.java +++ b/src/main/java/org/olat/portfolio/ui/artefacts/view/EPArtefactViewController.java @@ -176,7 +176,8 @@ public class EPArtefactViewController extends FormBasicController { if(detailsLinkEnabled && !artefactChooseMode) { detailsLink = uifactory.addFormLink("details.link", formLayout, Link.LINK); detailsLink.setElementCssClass("o_sel_artefact_details"); - } + } + title = uifactory.addInlineTextElement("title", artefact.getTitle(), formLayout, this); flc.contextPut("cssClosed", artefactInClosedMap ? "b_artefact_closed" : ""); diff --git a/src/main/java/org/olat/portfolio/ui/artefacts/view/EPMultipleArtefactsAsTableController.java b/src/main/java/org/olat/portfolio/ui/artefacts/view/EPMultipleArtefactsAsTableController.java index 6a96b3fa180451f464f3dd9be7bbb38860f97f86..bdbc4ea38058d1ecc43f6786e89bea0d2f5ece40 100644 --- a/src/main/java/org/olat/portfolio/ui/artefacts/view/EPMultipleArtefactsAsTableController.java +++ b/src/main/java/org/olat/portfolio/ui/artefacts/view/EPMultipleArtefactsAsTableController.java @@ -127,6 +127,7 @@ public class EPMultipleArtefactsAsTableController extends BasicController implem artefactListTblCtrl.addColumnDescriptor(descr); descr = new DefaultColumnDescriptor("artefact.description", 1, null, getLocale()); + descr.setEscapeHtml(false); artefactListTblCtrl.addColumnDescriptor(true, descr); descr = new DefaultColumnDescriptor("artefact.date", 2, null, getLocale()); diff --git a/src/main/java/org/olat/portfolio/ui/artefacts/view/_content/singleArtefact.html b/src/main/java/org/olat/portfolio/ui/artefacts/view/_content/singleArtefact.html index 70ba1f5d8a9b8f034b3cf91b266170e0c6db8938..3529f592a300866fb35181be6d593a185142b79a 100644 --- a/src/main/java/org/olat/portfolio/ui/artefacts/view/_content/singleArtefact.html +++ b/src/main/java/org/olat/portfolio/ui/artefacts/view/_content/singleArtefact.html @@ -2,7 +2,7 @@ #if ($cssClosed != "") <div class="$!cssClosed"> </div> #end - <h4 class="b_with_small_icon_left $artefact.getIcon()">$!artefact.getTitle()</h4> + <h4 class="b_with_small_icon_left $artefact.getIcon()">$r.escapeHtml($!artefact.getTitle())</h4> #if ($artAttribConfig.get("artefact.title")) <div class="b_form_element_wrapper b_clearfix"> <div class="b_form_element_label">$r.translate("artefact.title")</div> diff --git a/src/main/java/org/olat/portfolio/ui/structel/EPMultiplePageController.java b/src/main/java/org/olat/portfolio/ui/structel/EPMultiplePageController.java index 816ed79af0a6a9736c2b13ea3b5fbf412d94c83c..2a8b1948172d5cdd3418f539cc9ef393aa444296 100644 --- a/src/main/java/org/olat/portfolio/ui/structel/EPMultiplePageController.java +++ b/src/main/java/org/olat/portfolio/ui/structel/EPMultiplePageController.java @@ -37,6 +37,7 @@ import org.olat.core.id.OLATResourceable; import org.olat.core.id.context.ContextEntry; import org.olat.core.id.context.StateEntry; import org.olat.core.util.Formatter; +import org.olat.core.util.StringHelper; import org.olat.core.util.resource.OresHelper; import org.olat.portfolio.EPSecurityCallback; import org.olat.portfolio.manager.EPFrontendManager; @@ -113,7 +114,7 @@ public class EPMultiplePageController extends BasicController implements Activat ArrayList<Link> pageLinkList = new ArrayList<Link>(); for (PortfolioStructure page : pageList) { pageListByKeys.add(page.getKey()); - String pageTitle = ((EPPage) page).getTitle(); + String pageTitle =StringHelper.escapeHtml(((EPPage) page).getTitle()); String shortPageTitle = Formatter.truncate(pageTitle, 20); Link pageLink = LinkFactory .createCustomLink("pageLink" + i, "pageLink" + i, shortPageTitle, Link.LINK + Link.NONTRANSLATED, vC, this); diff --git a/src/main/java/org/olat/portfolio/ui/structel/view/EPTOCReadOnlyController.java b/src/main/java/org/olat/portfolio/ui/structel/view/EPTOCReadOnlyController.java index 04223d36f52e66c89daf44a25bdd9deb8c772371..2b44193d4c3ebcaf135c327e7009c950143f115f 100644 --- a/src/main/java/org/olat/portfolio/ui/structel/view/EPTOCReadOnlyController.java +++ b/src/main/java/org/olat/portfolio/ui/structel/view/EPTOCReadOnlyController.java @@ -34,6 +34,7 @@ import org.olat.core.gui.components.velocity.VelocityContainer; import org.olat.core.gui.control.Event; import org.olat.core.gui.control.WindowControl; import org.olat.core.gui.control.controller.BasicController; +import org.olat.core.util.StringHelper; import org.olat.portfolio.EPSecurityCallback; import org.olat.portfolio.manager.EPFrontendManager; import org.olat.portfolio.model.artefacts.AbstractArtefact; @@ -127,7 +128,7 @@ public class EPTOCReadOnlyController extends BasicController { if (artList != null && artList.size() != 0) { for (AbstractArtefact artefact : artList) { String key = String.valueOf(artefact.getKey()); - String title = artefact.getTitle(); + String title = StringHelper.escapeHtml(artefact.getTitle()); Link iconLink = LinkFactory.createCustomLink("arte_" + key, LINK_CMD_OPEN_ARTEFACT, "", Link.NONTRANSLATED, vC, this); iconLink.setCustomEnabledLinkCSS("b_small_icon b_open_icon"); @@ -154,7 +155,7 @@ public class EPTOCReadOnlyController extends BasicController { } String key = String.valueOf(portfolioStructure.getKey()); - String title = portfolioStructure.getTitle(); + String title = StringHelper.escapeHtml(portfolioStructure.getTitle()); Link iconLink = LinkFactory.createCustomLink("portstruct" + key, LINK_CMD_OPEN_STRUCT, "", Link.NONTRANSLATED, vC, this); iconLink.setCustomEnabledLinkCSS("b_small_icon b_open_icon"); diff --git a/src/main/java/org/olat/repository/RepositoryTableModel.java b/src/main/java/org/olat/repository/RepositoryTableModel.java index 54a79624d752388150e53dc96cb5137c985e495b..3d0b43e7e6d83902fa4a269da2633fbba0bb8603 100644 --- a/src/main/java/org/olat/repository/RepositoryTableModel.java +++ b/src/main/java/org/olat/repository/RepositoryTableModel.java @@ -47,6 +47,7 @@ import org.olat.core.gui.translator.Translator; import org.olat.core.util.StringHelper; import org.olat.login.LoginModule; import org.olat.repository.manager.RepositoryEntryLifecycleDAO; +import org.olat.repository.ui.RepositoryEntryAccessColumnDescriptor; import org.olat.resource.accesscontrol.ACService; import org.olat.resource.accesscontrol.AccessControlModule; import org.olat.resource.accesscontrol.model.OLATResourceAccess; @@ -118,20 +119,15 @@ public class RepositoryTableModel extends DefaultTableDataModel<RepositoryEntry> tableCtr.addColumnDescriptor(new RepositoryEntryTypeColumnDescriptor("table.header.typeimg", RepoCols.repoEntry.ordinal(), null, translator.getLocale(), ColumnDescriptor.ALIGNMENT_LEFT)); - int indexDisplaynameCol = 1;//col 0,1 visible see above if(repositoryModule.isManagedRepositoryEntries()) { tableCtr.addColumnDescriptor(false, new DefaultColumnDescriptor("table.header.externalid", RepoCols.externalId.ordinal(), null, translator.getLocale())); tableCtr.addColumnDescriptor(new DefaultColumnDescriptor("table.header.externalref", RepoCols.externalRef.ordinal(), null, translator.getLocale())); - indexDisplaynameCol++; + } boolean lfVisible = lifecycleDao.countPublicLifecycle() > 0; - if(lfVisible) { - indexDisplaynameCol++; - } tableCtr.addColumnDescriptor(lfVisible, new DefaultColumnDescriptor("table.header.lifecycle.label", RepoCols.lifecycleLabel.ordinal(), null, translator.getLocale())); tableCtr.addColumnDescriptor(false, new DefaultColumnDescriptor("table.header.lifecycle.softkey", RepoCols.lifecycleSoftKey.ordinal(), null, translator.getLocale())); - indexDisplaynameCol++;//see above ColumnDescriptor nameColDesc = new DefaultColumnDescriptor("table.header.displayname", RepoCols.displayname.ordinal(), enableDirectLaunch ? TABLE_ACTION_SELECT_ENTRY : null, translator.getLocale()) { @Override public int compareTo(int rowa, int rowb) { @@ -162,9 +158,11 @@ public class RepositoryTableModel extends DefaultTableDataModel<RepositoryEntry> tableCtr.addColumnDescriptor(false, new DefaultColumnDescriptor("table.header.lifecycle.start", RepoCols.lifecycleStart.ordinal(), null, translator.getLocale())); tableCtr.addColumnDescriptor(false, new DefaultColumnDescriptor("table.header.lifecycle.end", RepoCols.lifecycleEnd.ordinal(), null, translator.getLocale())); tableCtr.addColumnDescriptor(new DefaultColumnDescriptor("table.header.author", RepoCols.author.ordinal(), null, translator.getLocale())); - tableCtr.addColumnDescriptor(new DefaultColumnDescriptor("table.header.access", RepoCols.access.ordinal(), null, translator.getLocale())); - - + + CustomCellRenderer accessRenderer = new RepositoryEntryAccessColumnDescriptor(translator); + tableCtr.addColumnDescriptor(new CustomRenderColumnDescriptor("table.header.access", RepoCols.repoEntry.ordinal(), null, + translator.getLocale(), ColumnDescriptor.ALIGNMENT_LEFT, accessRenderer)); + tableCtr.addColumnDescriptor(false, new DefaultColumnDescriptor("table.header.date", RepoCols.creationDate.ordinal(), null, translator.getLocale())); tableCtr.addColumnDescriptor(false, new DefaultColumnDescriptor("table.header.lastusage", RepoCols.lastUsage.ordinal(), null, translator.getLocale())); if (selectButtonLabel != null) { diff --git a/src/main/java/org/olat/repository/_content/details.html b/src/main/java/org/olat/repository/_content/details.html index a1158f9cdb9e6968f02b59f1f3eb9179036fffee..872085ea5944cb1c0a2b4423e35672e74b9d35f8 100644 --- a/src/main/java/org/olat/repository/_content/details.html +++ b/src/main/java/org/olat/repository/_content/details.html @@ -1,5 +1,5 @@ $r.render("backLink") -<h4>$title - $r.translate("details.header")</h4> +<h4>$r.escapeHtml($title) - $r.translate("details.header")</h4> #if($launchableTyp) <p> $r.render("details.launch") diff --git a/src/main/java/org/olat/repository/ui/RepositoryEntryAccessColumnDescriptor.java b/src/main/java/org/olat/repository/ui/RepositoryEntryAccessColumnDescriptor.java new file mode 100644 index 0000000000000000000000000000000000000000..f86ea8094f856fb35f1cab9cb86392cfdba5f7f7 --- /dev/null +++ b/src/main/java/org/olat/repository/ui/RepositoryEntryAccessColumnDescriptor.java @@ -0,0 +1,81 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.repository.ui; + +import java.util.Locale; + +import org.olat.core.gui.components.table.CustomCellRenderer; +import org.olat.core.gui.render.Renderer; +import org.olat.core.gui.render.StringOutput; +import org.olat.core.gui.translator.Translator; +import org.olat.login.LoginModule; +import org.olat.repository.RepositoryEntry; + +/** + * Render the access rule translated + * + * Initial date: 26.07.2013<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public class RepositoryEntryAccessColumnDescriptor implements CustomCellRenderer { + + private final Translator translator; + private final boolean guestLoginEnabled; + + public RepositoryEntryAccessColumnDescriptor(Translator translator) { + this.translator = translator; + guestLoginEnabled = LoginModule.isGuestLoginLinksEnabled(); + } + + @Override + public void render(StringOutput sb, Renderer renderer, Object val, Locale locale, int alignment, String action) { + if(val instanceof RepositoryEntry) { + RepositoryEntry re = (RepositoryEntry)val; + //fxdiff VCRP-1,2: access control of resources + if(re.isMembersOnly()) { + sb.append(translator.translate("table.header.access.membersonly")); + } + switch (re.getAccess()) { + case RepositoryEntry.ACC_OWNERS: + sb.append(translator.translate("table.header.access.owner")); + break; + case RepositoryEntry.ACC_OWNERS_AUTHORS: + sb.append(translator.translate("table.header.access.author")); + break; + case RepositoryEntry.ACC_USERS: + sb.append(translator.translate("table.header.access.user")); + break; + case RepositoryEntry.ACC_USERS_GUESTS: { + if(!guestLoginEnabled) { + sb.append(translator.translate("table.header.access.user")); + } else { + sb.append(translator.translate("table.header.access.guest")); + } + break; + } + default: + // OLAT-6272 in case of broken repo entries with no access code + // return error instead of nothing + sb.append("ERROR"); + } + } + } +} diff --git a/src/main/java/org/olat/user/AbstractUserPropertyHandler.java b/src/main/java/org/olat/user/AbstractUserPropertyHandler.java index f5de71af0a649360aa3bbe51f93c73a1cfc8d310..12eb99a143d03170accc1ed51f565f1403865cc4 100644 --- a/src/main/java/org/olat/user/AbstractUserPropertyHandler.java +++ b/src/main/java/org/olat/user/AbstractUserPropertyHandler.java @@ -31,6 +31,7 @@ import org.olat.core.commons.persistence.DBFactory; import org.olat.core.gui.components.table.ColumnDescriptor; import org.olat.core.gui.components.table.DefaultColumnDescriptor; import org.olat.core.id.User; +import org.olat.core.util.StringHelper; import org.olat.user.propertyhandlers.UserPropertyHandler; /** @@ -57,7 +58,7 @@ public abstract class AbstractUserPropertyHandler implements UserPropertyHandler * @see org.olat.core.id.UserField#getUserFieldValueAsHTML(org.olat.core.id.User, java.util.Locale) */ public String getUserPropertyAsHTML(User user, Locale locale) { - return getUserProperty(user, locale); + return StringHelper.escapeHtml(getUserProperty(user, locale)); } /** diff --git a/src/main/java/org/olat/user/propertyhandlers/EmailProperty.java b/src/main/java/org/olat/user/propertyhandlers/EmailProperty.java index 7fcd09bfe6fe8972ce1cf9d583ceeb5a805c851e..fa6969057ca5a2ac01fe2da4d6df1c664c6103cc 100644 --- a/src/main/java/org/olat/user/propertyhandlers/EmailProperty.java +++ b/src/main/java/org/olat/user/propertyhandlers/EmailProperty.java @@ -74,13 +74,14 @@ public class EmailProperty extends Generic127CharTextPropertyHandler { public String getUserPropertyAsHTML(User user, Locale locale) { String mail = getUserProperty(user, locale); if (StringHelper.containsNonWhitespace(mail)) { - StringBuffer sb = new StringBuffer(); + mail = StringHelper.escapeHtml(mail); + StringBuilder sb = new StringBuilder(); sb.append("<a href=\"mailto:"); sb.append(mail); sb.append("\" class=\"b_link_mailto\">"); - sb.append(getUserProperty(user, locale)); + sb.append(mail); sb.append("</a>"); - return sb.toString(); + return StringHelper.xssScan(sb.toString()); } return null; } diff --git a/src/main/java/org/olat/user/propertyhandlers/ICQPropertyHandler.java b/src/main/java/org/olat/user/propertyhandlers/ICQPropertyHandler.java index bb9ebd701fa8eebeac951e0d4e49b8c33bd820e7..cefea8897315c016d20ef6570f3b6981ce12b9f4 100644 --- a/src/main/java/org/olat/user/propertyhandlers/ICQPropertyHandler.java +++ b/src/main/java/org/olat/user/propertyhandlers/ICQPropertyHandler.java @@ -55,11 +55,13 @@ public class ICQPropertyHandler extends Generic127CharTextPropertyHandler { // return super.getUserPropertyAsHTML(user, locale); String icqname = getUserProperty(user, locale); if (StringHelper.containsNonWhitespace(icqname)) { - StringBuffer stringBuffer = new StringBuffer(); - stringBuffer.append("<a href=\"" + ICQ_NAME_VALIDATION_URL + "" + icqname + "\" target=\"_blank\">" + icqname + "</a>"); - stringBuffer.append("<img src=\"" + ICQ_INDICATOR_URL + "?icq=" + icqname - + "&img=5\" style=\"width:10px; height:10px; margin-left:2px;\">"); - return stringBuffer.toString(); + icqname = StringHelper.escapeHtml(icqname); + StringBuilder sb = new StringBuilder(); + sb.append("<a href=\"").append(ICQ_NAME_VALIDATION_URL).append(icqname).append("\" target=\"_blank\">") + .append(icqname).append("</a>") + .append("<img src=\"").append(ICQ_INDICATOR_URL).append("?icq=").append(icqname) + .append("&img=5\" style=\"width:10px; height:10px; margin-left:2px;\">"); + return sb.toString(); } else { return null; } diff --git a/src/main/java/org/olat/user/propertyhandlers/MSNPropertyHandler.java b/src/main/java/org/olat/user/propertyhandlers/MSNPropertyHandler.java index 12d0b0c5cd2deba590bfd01d29a73a73c1a22354..d69f08861288e62f76ac24de3346881c91341cf7 100644 --- a/src/main/java/org/olat/user/propertyhandlers/MSNPropertyHandler.java +++ b/src/main/java/org/olat/user/propertyhandlers/MSNPropertyHandler.java @@ -65,9 +65,12 @@ public class MSNPropertyHandler extends Generic127CharTextPropertyHandler { public String getUserPropertyAsHTML(User user, Locale locale) { String msnname = getUserProperty(user, locale); if (StringHelper.containsNonWhitespace(msnname)) { - StringBuffer stringBuffer = new StringBuffer(); - stringBuffer.append("<a href=\"" + MSN_NAME_VALIDATION_URL + "?" + MSN_NAME_URL_PARAMETER + "=" + msnname + "\" target=\"_blank\">" + msnname + "</a>"); - return stringBuffer.toString(); + msnname = StringHelper.escapeHtml(msnname); + StringBuilder sb = new StringBuilder(); + sb.append("<a href=\"").append(MSN_NAME_VALIDATION_URL).append("?") + .append(MSN_NAME_URL_PARAMETER).append("=").append(msnname) + .append("\" target=\"_blank\">").append(msnname).append("</a>"); + return sb.toString(); } else { return null; } diff --git a/src/main/java/org/olat/user/propertyhandlers/PhonePropertyHandler.java b/src/main/java/org/olat/user/propertyhandlers/PhonePropertyHandler.java index 9cd2f67706a750f2329439f78dd7bdba6b02e430..2c848c86cef0beb5e64e5fc4b58e327a1eca1d52 100644 --- a/src/main/java/org/olat/user/propertyhandlers/PhonePropertyHandler.java +++ b/src/main/java/org/olat/user/propertyhandlers/PhonePropertyHandler.java @@ -60,12 +60,11 @@ public class PhonePropertyHandler extends Generic127CharTextPropertyHandler { public String getUserPropertyAsHTML(User user, Locale locale) { String phonenr = getUserProperty(user, locale); if (StringHelper.containsNonWhitespace(phonenr)) { + phonenr = StringHelper.escapeHtml(phonenr); StringBuffer sb = new StringBuffer(); - sb.append("<a href=\"callto:"); - sb.append(phonenr); - sb.append("\" class=\"b_link_call\">"); - sb.append(phonenr); - sb.append("</a>"); + sb.append("<a href=\"callto:") + .append(phonenr).append("\" class=\"b_link_call\">") + .append(phonenr).append("</a>"); return sb.toString(); } return null; diff --git a/src/main/java/org/olat/user/propertyhandlers/SkypePropertyHandler.java b/src/main/java/org/olat/user/propertyhandlers/SkypePropertyHandler.java index a014904dafa406ac9449c0bc3c65e0f128c4152a..acfdcb067e8647f434326672aa4e502c2ff12703 100644 --- a/src/main/java/org/olat/user/propertyhandlers/SkypePropertyHandler.java +++ b/src/main/java/org/olat/user/propertyhandlers/SkypePropertyHandler.java @@ -45,17 +45,19 @@ public class SkypePropertyHandler extends Generic127CharTextPropertyHandler { public String getUserPropertyAsHTML(User user, Locale locale) { String skypeid = getUserProperty(user, locale); if (StringHelper.containsNonWhitespace(skypeid)) { + skypeid = StringHelper.escapeHtml(skypeid); StringBuffer sb = new StringBuffer(); sb.append("<script type=\"text/javascript\" src=\"http://download.skype.com/share/skypebuttons/js/skypeCheck.js\"></script>"); sb.append("<img src=\"http://mystatus.skype.com/smallicon/"); - sb.append(getUserProperty(user, locale)); + sb.append(skypeid); sb.append("\" style=\"border: none; position:relative; top:1px; margin-right:2px;\" width=\"10\" height=\"10\" alt=\"My status\" />"); sb.append("<a href=\"skype:"); sb.append(skypeid); sb.append("?call\">"); sb.append(skypeid); sb.append("</a>"); - return sb.toString(); + String htmlFragment = sb.toString(); + return htmlFragment; } return null; } diff --git a/src/main/java/org/olat/user/propertyhandlers/URLPropertyHandler.java b/src/main/java/org/olat/user/propertyhandlers/URLPropertyHandler.java index a5833e9ec09ce034dde5658f0d678de120e849e8..df0b0b8a6f0c151decb1c5607af9e38f66d0dad2 100644 --- a/src/main/java/org/olat/user/propertyhandlers/URLPropertyHandler.java +++ b/src/main/java/org/olat/user/propertyhandlers/URLPropertyHandler.java @@ -49,13 +49,15 @@ public class URLPropertyHandler extends Generic127CharTextPropertyHandler { public String getUserPropertyAsHTML(User user, Locale locale) { String href = getUserProperty(user, locale); if (StringHelper.containsNonWhitespace(href)) { + href = StringHelper.escapeHtml(href); StringBuffer sb = new StringBuffer(); sb.append("<a href=\""); sb.append(href); sb.append("\" class=\"b_link_extern\" target=\"_blank\">"); - sb.append(getUserProperty(user, locale)); + sb.append(href); sb.append("</a>"); - return sb.toString(); + String htmlFragment = sb.toString(); + return StringHelper.xssScan(htmlFragment); } return null; }