use of com.zimbra.cs.html.BrowserDefang in project zm-mailbox by Zimbra.
the class Signature method getContents.
public Set<SignatureContent> getContents() {
Set<SignatureContent> contents = new HashSet<SignatureContent>();
BrowserDefang defanger = DefangFactory.getDefanger(MimeConstants.CT_TEXT_HTML);
for (Iterator it = SignatureUtil.ATTR_TYPE_MAP.entrySet().iterator(); it.hasNext(); ) {
Map.Entry entry = (Map.Entry) it.next();
String content = getAttr((String) entry.getKey());
if (content != null) {
if (entry.getKey().equals(ZAttrProvisioning.A_zimbraPrefMailSignatureHTML)) {
StringReader reader = new StringReader(content);
try {
content = defanger.defang(reader, false);
} catch (IOException e) {
ZimbraLog.misc.info("Error sanitizing html signature: %s", content);
}
}
contents.add(new SignatureContent((String) entry.getValue(), content));
}
}
return contents;
}
use of com.zimbra.cs.html.BrowserDefang in project zm-mailbox by Zimbra.
the class ToXML method encodeInviteComponent.
public static Element encodeInviteComponent(Element parent, ItemIdFormatter ifmt, OperationContext octxt, CalendarItem calItem, /* may be null */
ItemId calId, /* may be null */
Invite invite, int fields, boolean neuter) throws ServiceException {
boolean allFields = true;
if (fields != NOTIFY_FIELDS) {
allFields = false;
if (!needToOutput(fields, Change.INVITE)) {
return parent;
}
}
Element e = parent.addNonUniqueElement(MailConstants.E_INVITE_COMPONENT);
e.addAttribute(MailConstants.A_CAL_METHOD, invite.getMethod());
e.addAttribute(MailConstants.A_CAL_COMPONENT_NUM, invite.getComponentNum());
if (invite.hasRsvp()) {
e.addAttribute(MailConstants.A_CAL_RSVP, invite.getRsvp());
}
boolean allowPrivateAccess = calItem != null ? allowPrivateAccess(octxt, calItem) : true;
if (allFields) {
if (invite.isPublic() || allowPrivateAccess) {
String priority = invite.getPriority();
if (priority != null) {
e.addAttribute(MailConstants.A_CAL_PRIORITY, priority);
}
e.addAttribute(MailConstants.A_NAME, invite.getName());
e.addAttribute(MailConstants.A_CAL_LOCATION, invite.getLocation());
List<String> categories = invite.getCategories();
if (categories != null) {
for (String cat : categories) {
e.addNonUniqueElement(MailConstants.E_CAL_CATEGORY).setText(cat);
}
}
List<String> comments = invite.getComments();
if (comments != null) {
for (String cmt : comments) {
e.addNonUniqueElement(MailConstants.E_CAL_COMMENT).setText(cmt);
}
}
List<String> contacts = invite.getContacts();
if (contacts != null) {
for (String contact : contacts) {
e.addNonUniqueElement(MailConstants.E_CAL_CONTACT).setText(contact);
}
}
Geo geo = invite.getGeo();
if (geo != null) {
geo.toXml(e);
}
// Percent Complete (VTODO)
if (invite.isTodo()) {
String pct = invite.getPercentComplete();
if (pct != null)
e.addAttribute(MailConstants.A_TASK_PERCENT_COMPLETE, pct);
long completed = invite.getCompleted();
if (completed != 0) {
ParsedDateTime c = ParsedDateTime.fromUTCTime(completed);
e.addAttribute(MailConstants.A_TASK_COMPLETED, c.getDateTimePartString());
}
}
// Attendee(s)
List<ZAttendee> attendees = invite.getAttendees();
for (ZAttendee at : attendees) {
at.toXml(e);
}
// Alarms
Iterator<Alarm> alarmsIter = invite.alarmsIterator();
while (alarmsIter.hasNext()) {
Alarm alarm = alarmsIter.next();
alarm.toXml(e);
}
// x-prop
encodeXProps(e, invite.xpropsIterator());
// fragment
String fragment = invite.getFragment();
if (!Strings.isNullOrEmpty(fragment)) {
e.addAttribute(MailConstants.E_FRAG, fragment, Element.Disposition.CONTENT);
}
if (!invite.hasBlobPart()) {
e.addAttribute(MailConstants.A_CAL_NO_BLOB, true);
}
// Description (plain and html)
String desc = invite.getDescription();
if (desc != null) {
Element descElem = e.addNonUniqueElement(MailConstants.E_CAL_DESCRIPTION);
descElem.setText(desc);
}
String descHtml = invite.getDescriptionHtml();
BrowserDefang defanger = DefangFactory.getDefanger(MimeConstants.CT_TEXT_HTML);
if (descHtml != null) {
try {
descHtml = StringUtil.stripControlCharacters(descHtml);
descHtml = defanger.defang(descHtml, neuter);
Element descHtmlElem = e.addNonUniqueElement(MailConstants.E_CAL_DESC_HTML);
descHtmlElem.setText(descHtml);
} catch (IOException ex) {
ZimbraLog.calendar.warn("Unable to defang HTML for SetAppointmentRequest", ex);
}
}
if (invite.isEvent()) {
if (calItem != null && calItem instanceof Appointment) {
Instance inst = Instance.fromInvite(calItem.getId(), invite);
Appointment appt = (Appointment) calItem;
e.addAttribute(MailConstants.A_APPT_FREEBUSY_ACTUAL, appt.getEffectiveFreeBusyActual(invite, inst));
}
e.addAttribute(MailConstants.A_APPT_FREEBUSY, invite.getFreeBusy());
e.addAttribute(MailConstants.A_APPT_TRANSPARENCY, invite.getTransparency());
}
// Organizer
if (invite.hasOrganizer()) {
ZOrganizer org = invite.getOrganizer();
org.toXml(e);
}
e.addAttribute(MailConstants.A_CAL_URL, invite.getUrl());
}
if (invite.isOrganizer()) {
e.addAttribute(MailConstants.A_CAL_ISORG, true);
}
boolean isRecurring = false;
e.addAttribute("x_uid", invite.getUid());
e.addAttribute(MailConstants.A_UID, invite.getUid());
e.addAttribute(MailConstants.A_CAL_SEQUENCE, invite.getSeqNo());
// zdsync
e.addAttribute(MailConstants.A_CAL_DATETIME, invite.getDTStamp());
String itemId = null;
if (calId != null) {
itemId = calId.toString(ifmt);
} else if (calItem != null) {
itemId = ifmt.formatItemId(calItem);
}
if ((itemId != null) && !("0".equals(itemId))) {
e.addAttribute(MailConstants.A_CAL_ID, /* calItemId */
itemId);
if (invite.isEvent()) {
// for backward compat
e.addAttribute(MailConstants.A_APPT_ID_DEPRECATE_ME, /* apptId */
itemId);
}
if (calItem != null) {
ItemId ciFolderId = new ItemId(calItem.getMailbox(), calItem.getFolderId());
e.addAttribute(MailConstants.A_CAL_ITEM_FOLDER, /* ciFolder */
ifmt.formatItemId(ciFolderId));
}
}
Recurrence.IRecurrence recur = invite.getRecurrence();
if (recur != null) {
isRecurring = true;
Element recurElt = e.addNonUniqueElement(MailConstants.E_CAL_RECUR);
recur.toXml(recurElt);
}
e.addAttribute(MailConstants.A_CAL_STATUS, invite.getStatus());
e.addAttribute(MailConstants.A_CAL_CLASS, invite.getClassProp());
boolean allDay = invite.isAllDayEvent();
boolean isException = invite.hasRecurId();
if (isException) {
e.addAttribute(MailConstants.A_CAL_IS_EXCEPTION, true);
RecurId rid = invite.getRecurId();
e.addAttribute(MailConstants.A_CAL_RECURRENCE_ID_Z, rid.getDtZ());
encodeRecurId(e, rid, allDay);
}
boolean forceUTC = DebugConfig.calendarForceUTC && !isRecurring && !isException && !allDay;
ParsedDateTime dtStart = invite.getStartTime();
if (dtStart != null) {
encodeDtStart(e, dtStart, allDay, forceUTC);
}
ParsedDateTime dtEnd = invite.getEndTime();
if (dtEnd != null) {
encodeDtEnd(e, dtEnd, allDay, invite.isTodo(), forceUTC);
}
ParsedDuration dur = invite.getDuration();
if (dur != null) {
dur.toXml(e);
}
if (allDay) {
e.addAttribute(MailConstants.A_CAL_ALLDAY, true);
}
if (invite.isDraft()) {
e.addAttribute(MailConstants.A_CAL_DRAFT, true);
}
if (invite.isNeverSent()) {
e.addAttribute(MailConstants.A_CAL_NEVER_SENT, true);
}
}
return e;
}
use of com.zimbra.cs.html.BrowserDefang in project zm-mailbox by Zimbra.
the class NativeFormatter method sendbackOriginalDoc.
private static void sendbackOriginalDoc(InputStream is, String contentType, String defaultCharset, String filename, String desc, long size, HttpServletRequest req, HttpServletResponse resp) throws IOException {
String disp = req.getParameter(UserServlet.QP_DISP);
disp = (disp == null || disp.toLowerCase().startsWith("i")) ? Part.INLINE : Part.ATTACHMENT;
if (desc != null && desc.length() <= 2048) {
// do not return ridiculously long header.
if (desc.contains(" ") && !(desc.startsWith("\"") && desc.endsWith("\""))) {
desc = "\"" + desc.trim() + "\"";
}
resp.addHeader("Content-Description", desc);
}
// defang when the html and svg attachment was requested with disposition inline
if (disp.equals(Part.INLINE) && isScriptableContent(contentType)) {
BrowserDefang defanger = DefangFactory.getDefanger(contentType);
String content = defanger.defang(Mime.getTextReader(is, contentType, defaultCharset), true);
resp.setContentType(contentType);
String charset = Mime.getCharset(contentType);
resp.setCharacterEncoding(Strings.isNullOrEmpty(charset) ? Charsets.UTF_8.name() : charset);
if (!content.isEmpty()) {
resp.setContentLength(content.getBytes().length);
}
resp.getWriter().write(content);
} else {
// flash attachment may contain a malicious script hence..
if (contentType.startsWith(MimeConstants.CT_APPLICATION_SHOCKWAVE_FLASH)) {
disp = Part.ATTACHMENT;
}
resp.setContentType(contentType);
sendbackBinaryData(req, resp, is, contentType, disp, filename, size);
}
}
use of com.zimbra.cs.html.BrowserDefang in project zm-mailbox by Zimbra.
the class ToXML method addContent.
/**
* Adds the decoded text content of a message part to the {@link Element}.
* The content is added as the value of a new <tt><content></tt>
* sub-element. <i>Note: This method will only extract the content of a
* <b>text/*</b> or <b>xml/*</b> message part.</i>
*
* @param elt The element to add the <tt><content></tt> to.
* @param mpi The message part to extract the content from.
* @param maxSize The maximum number of characters to inline (<=0 is unlimited).
* @param neuter Whether to "neuter" image <tt>src</tt> attributes.
* @parame defaultCharset The user's default charset preference.
* @throws MessagingException when message parsing or CTE-decoding fails
* @throws IOException on error during parsing or defanging
* @see HtmlDefang#defang(String, boolean)
*/
private static void addContent(Element elt, MPartInfo mpi, int maxSize, boolean neuter, String defaultCharset, MsgContent wantContent) throws IOException, MessagingException {
// TODO: support other parts
String ctype = mpi.getContentType();
if (!ctype.matches(MimeConstants.CT_TEXT_WILD) && !ctype.matches(MimeConstants.CT_XML_WILD)) {
return;
}
MimePart mp = mpi.getMimePart();
Mime.repairTransferEncoding(mp);
String data = null;
String originalContent = null;
wantContent = wantContent == null ? MsgContent.full : wantContent;
try {
if (maxSize <= 0) {
maxSize = (int) Provisioning.getInstance().getLocalServer().getMailContentMaxSize();
} else {
maxSize = Math.min(maxSize, (int) Provisioning.getInstance().getLocalServer().getMailContentMaxSize());
}
} catch (ServiceException e) {
ZimbraLog.soap.warn("Unable to determine max content size", e);
}
boolean wasTruncated = false;
if (ctype.equals(MimeConstants.CT_TEXT_HTML)) {
String charset = mpi.getContentTypeParameter(MimeConstants.P_CHARSET);
InputStream stream = null;
StringWriter sw = new StringWriter();
TruncatingWriter tw = null;
Writer out = sw;
if (maxSize > 0) {
tw = new TruncatingWriter(sw, maxSize + 1);
out = tw;
}
Reader reader = null;
try {
stream = mp.getInputStream();
if (charset != null && !charset.trim().isEmpty()) {
// make sure to feed getTextReader() a full Content-Type header, not just the primary/subtype portion
reader = Mime.getTextReader(stream, mp.getContentType(), defaultCharset);
BrowserDefang defanger = DefangFactory.getDefanger(mp.getContentType());
defanger.defang(reader, neuter, out);
data = sw.toString();
} else {
String cte = mp.getEncoding();
if (cte != null && !cte.trim().toLowerCase().equals(MimeConstants.ET_7BIT)) {
try {
DefangFactory.getDefanger(ctype).defang(stream, neuter, out);
data = sw.toString();
} catch (IOException e) {
}
}
if (data == null) {
reader = Mime.getTextReader(stream, mp.getContentType(), defaultCharset);
DefangFactory.getDefanger(ctype).defang(reader, neuter, out);
data = sw.toString();
}
}
if (wantContent.equals(MsgContent.original) || wantContent.equals(MsgContent.both)) {
originalContent = removeQuotedText(data, true);
}
} finally {
if (tw != null) {
wasTruncated = tw.wasTruncated();
}
ByteUtil.closeStream(stream);
Closeables.closeQuietly(reader);
}
} else if (ctype.equals(MimeConstants.CT_TEXT_ENRICHED)) {
// Enriched text handling is a little funky because TextEnrichedHandler
// doesn't use Reader and Writer. As a result, we truncate
// the source before converting to HTML.
InputStream stream = mp.getInputStream();
Reader reader = null;
try {
reader = Mime.getTextReader(stream, mp.getContentType(), defaultCharset);
int maxChars = (maxSize > 0 ? maxSize + 1 : -1);
String enriched = ByteUtil.getContent(reader, maxChars, false);
if (enriched.length() == maxChars) {
// The normal check for truncated data won't work because
// the length of the converted text is different than the length
// of the source, so set the attr here.
wasTruncated = true;
}
if (wantContent.equals(MsgContent.original) || wantContent.equals(MsgContent.both)) {
originalContent = TextEnrichedHandler.convertToHTML(removeQuotedText(enriched, false));
}
data = TextEnrichedHandler.convertToHTML(enriched);
} finally {
ByteUtil.closeStream(stream);
Closeables.closeQuietly(reader);
}
} else {
InputStream stream = mp.getInputStream();
Reader reader = null;
try {
reader = Mime.getTextReader(stream, mp.getContentType(), defaultCharset);
int maxChars = (maxSize > 0 ? maxSize + 1 : -1);
data = ByteUtil.getContent(reader, maxChars, false);
if (wantContent.equals(MsgContent.original) || wantContent.equals(MsgContent.both)) {
originalContent = removeQuotedText(data, false);
}
if (data.length() == maxChars) {
wasTruncated = true;
}
} finally {
ByteUtil.closeStream(stream);
Closeables.closeQuietly(reader);
}
}
if (data != null && !wantContent.equals(MsgContent.original)) {
data = StringUtil.stripControlCharacters(data);
if (wasTruncated) {
elt.addAttribute(MailConstants.A_TRUNCATED_CONTENT, true);
if (data.length() > maxSize) {
data = data.substring(0, maxSize);
}
}
elt.addAttribute(MailConstants.E_CONTENT, data, Element.Disposition.CONTENT);
}
if (originalContent != null && (wantContent.equals(MsgContent.original) || wantContent.equals(MsgContent.both))) {
originalContent = StringUtil.stripControlCharacters(originalContent);
elt.addUniqueElement(MailConstants.E_ORIG_CONTENT).setText(originalContent);
}
// TODO: CDATA worth the effort?
}
Aggregations