@Override public boolean equals(@Nullable Object other) { // TODO(user): js uses reference equality, this uses content comparison if (other instanceof StringData) { // So that StringData and UnsanitizedString can be used interchangeably. Keep this in sync // with StringData#equals. return ((StringData) other).stringValue().equals(this.getContent()); } return other instanceof UnsanitizedString && this.getContentDirection() == ((SanitizedContent) other).getContentDirection() && this.getContent().equals(((UnsanitizedString) other).getContent()); }
public static SoyValue changeNewlineToBr(SoyValue value) { String result = NEWLINE_PATTERN.matcher(coerceToString(value)).replaceAll("<br>"); // Make sure to transmit the known direction, if any, to any downstream directive that may need // it, e.g. BidiSpanWrapDirective. Since a known direction is carried only by SanitizedContent, // and the transformation we make is only valid in HTML, we only transmit the direction when we // get HTML SanitizedContent. // TODO(user): Consider always returning HTML SanitizedContent. if (value instanceof SanitizedContent) { SanitizedContent sanitizedContent = (SanitizedContent) value; if (sanitizedContent.getContentKind() == ContentKind.HTML) { return UnsafeSanitizedContentOrdainer.ordainAsSafe( result, ContentKind.HTML, sanitizedContent.getContentDirection()); } } return StringData.forValue(result); }
public static SoyString changeNewlineToBr(SoyValue value) { String result = NEWLINE_PATTERN.matcher(coerceToString(value)).replaceAll("<br>"); // Make sure to transmit the known direction, if any, to any downstream directive that may need // it, e.g. BidiSpanWrapDirective. Since a known direction is carried only by SanitizedContent, // and the transformation we make is only valid in HTML, we only transmit the direction when we // get HTML SanitizedContent. // TODO(user): Consider always returning HTML SanitizedContent. if (value instanceof SanitizedContent) { SanitizedContent sanitizedContent = (SanitizedContent) value; if (sanitizedContent.getContentKind() == ContentKind.HTML) { return UnsafeSanitizedContentOrdainer.ordainAsSafe( result, ContentKind.HTML, sanitizedContent.getContentDirection()); } } return StringData.forValue(result); }
public static int bidiTextDir(SoyValue value, boolean isHtml) { Dir valueDir = null; boolean isHtmlForValueDirEstimation = false; if (value instanceof SanitizedContent) { SanitizedContent sanitizedContent = (SanitizedContent) value; valueDir = sanitizedContent.getContentDirection(); if (valueDir == null) { isHtmlForValueDirEstimation = sanitizedContent.getContentKind() == ContentKind.HTML; } } if (valueDir == null) { isHtmlForValueDirEstimation = isHtmlForValueDirEstimation || isHtml; valueDir = BidiUtils.estimateDirection(value.coerceToString(), isHtmlForValueDirEstimation); } return valueDir.ord; }
public static int bidiTextDir(SoyValue value, boolean isHtml) { Dir valueDir = null; boolean isHtmlForValueDirEstimation = false; if (value instanceof SanitizedContent) { SanitizedContent sanitizedContent = (SanitizedContent) value; valueDir = sanitizedContent.getContentDirection(); if (valueDir == null) { isHtmlForValueDirEstimation = sanitizedContent.getContentKind() == ContentKind.HTML; } } if (valueDir == null) { isHtmlForValueDirEstimation = isHtmlForValueDirEstimation || isHtml; valueDir = BidiUtils.estimateDirection(value.coerceToString(), isHtmlForValueDirEstimation); } return valueDir.ord; } }
@Override public void render(LoggingAdvisingAppendable appendable) throws IOException { appendable .setSanitizedContentKind(getContentKind()) .setSanitizedContentDirectionality(getContentDirection()) .append(content); }
@Override public void close() throws IOException { if (!isInHtml()) { StringBuilder buffer = (StringBuilder) activeAppendable; if (buffer.length() > 0) { SanitizedContent content = cleanHtml(buffer.toString(), getSanitizedContentDirectionality(), optionalSafeTags); delegate .setSanitizedContentKind(content.getContentKind()) .setSanitizedContentDirectionality(content.getContentDirection()) .append(content.getContent()); buffer.setLength(0); } } } }
@Override public void close() throws IOException { if (!isInHtml()) { StringBuilder buffer = (StringBuilder) activeAppendable; if (buffer.length() > 0) { SanitizedContent content = cleanHtml(buffer.toString(), getSanitizedContentDirectionality(), optionalSafeTags); delegate .setSanitizedContentKind(content.getContentKind()) .setSanitizedContentDirectionality(content.getContentDirection()) .append(content.getContent()); buffer.setLength(0); } } } }
public static SanitizedContent escapeHtml(SoyValue value) { if (value == null) { // jbcsrc uses null as null. value = NullData.INSTANCE; } Dir valueDir = null; if (value instanceof SanitizedContent) { SanitizedContent sanitizedContent = (SanitizedContent) value; if (sanitizedContent.getContentKind() == SanitizedContent.ContentKind.HTML) { return (SanitizedContent) value; } valueDir = sanitizedContent.getContentDirection(); } return UnsafeSanitizedContentOrdainer.ordainAsSafe( EscapingConventions.EscapeHtml.INSTANCE.escape(value.coerceToString()), SanitizedContent.ContentKind.HTML, valueDir); }
public static String bidiMarkAfter(BidiGlobalDir bidiGlobalDir, SoyValue value, boolean isHtml) { Dir valueDir = null; if (value instanceof SanitizedContent) { SanitizedContent sanitizedContent = (SanitizedContent) value; valueDir = sanitizedContent.getContentDirection(); isHtml = isHtml || sanitizedContent.getContentKind() == ContentKind.HTML; } String markAfterKnownDir = BidiFormatter.getInstance(bidiGlobalDir.toDir()) .markAfter(valueDir, value.coerceToString(), isHtml); return markAfterKnownDir; }
public static String bidiMarkAfter(BidiGlobalDir bidiGlobalDir, SoyValue value, boolean isHtml) { Dir valueDir = null; if (value instanceof SanitizedContent) { SanitizedContent sanitizedContent = (SanitizedContent) value; valueDir = sanitizedContent.getContentDirection(); isHtml = isHtml || sanitizedContent.getContentKind() == ContentKind.HTML; } String markAfterKnownDir = BidiFormatter.getInstance(bidiGlobalDir.toDir()) .markAfter(valueDir, value.coerceToString(), isHtml); return markAfterKnownDir; }
public static SanitizedContent escapeHtml(SoyValue value) { if (value == null) { // jbcsrc uses null as null. value = NullData.INSTANCE; } Dir valueDir = null; if (value instanceof SanitizedContent) { SanitizedContent sanitizedContent = (SanitizedContent) value; if (sanitizedContent.getContentKind() == SanitizedContent.ContentKind.HTML) { return (SanitizedContent) value; } valueDir = sanitizedContent.getContentDirection(); } return UnsafeSanitizedContentOrdainer.ordainAsSafe( EscapingConventions.EscapeHtml.INSTANCE.escape(value.coerceToString()), SanitizedContent.ContentKind.HTML, valueDir); }
/** * Normalizes the input HTML while preserving "safe" tags and the known directionality. * * @param optionalSafeTags to add to the basic whitelist of formatting safe tags * @return the normalized input, in the form of {@link SanitizedContent} of {@link * ContentKind#HTML} */ public static SanitizedContent cleanHtml( SoyValue value, Collection<? extends OptionalSafeTag> optionalSafeTags) { value = normalizeNull(value); Dir valueDir = null; if (value instanceof SanitizedContent) { SanitizedContent sanitizedContent = (SanitizedContent) value; if (sanitizedContent.getContentKind() == SanitizedContent.ContentKind.HTML) { return (SanitizedContent) value; } valueDir = sanitizedContent.getContentDirection(); } return cleanHtml(value.coerceToString(), valueDir, optionalSafeTags); }
public static String bidiSpanWrap(BidiGlobalDir dir, SoyValue value) { Dir valueDir = null; if (value instanceof SanitizedContent) { valueDir = ((SanitizedContent) value).getContentDirection(); } BidiFormatter bidiFormatter = BidiFormatter.getInstance(dir.toDir()); // We always treat the value as HTML, because span-wrapping is only useful when its output will // be treated as HTML (without escaping), and because |bidiSpanWrap is not itself specified to // do HTML escaping in Soy. (Both explicit and automatic HTML escaping, if any, is done before // calling |bidiSpanWrap because BidiSpanWrapDirective implements SanitizedContentOperator, // but this does not mean that the input has to be HTML SanitizedContent. In legacy usage, a // string that is not SanitizedContent is often printed in an autoescape="false" template or by // a print with a |noAutoescape, in which case our input is just SoyData.) If the output will be // treated as HTML, the input had better be safe HTML/HTML-escaped (even if it isn't HTML // SanitizedData), or we have an XSS opportunity and a much bigger problem than bidi garbling. String wrappedValue = bidiFormatter.spanWrap(valueDir, value.coerceToString(), /* isHtml= */ true); // Like other directives implementing SanitizedContentOperator, BidiSpanWrapDirective is called // after the escaping (if any) has already been done, and thus there is no need for it to // produce actual SanitizedContent. return wrappedValue; }
public static String bidiSpanWrap(BidiGlobalDir dir, SoyValue value) { Dir valueDir = null; if (value instanceof SanitizedContent) { valueDir = ((SanitizedContent) value).getContentDirection(); } BidiFormatter bidiFormatter = BidiFormatter.getInstance(dir.toDir()); // We always treat the value as HTML, because span-wrapping is only useful when its output will // be treated as HTML (without escaping), and because |bidiSpanWrap is not itself specified to // do HTML escaping in Soy. (Both explicit and automatic HTML escaping, if any, is done before // calling |bidiSpanWrap because BidiSpanWrapDirective implements SanitizedContentOperator, // but this does not mean that the input has to be HTML SanitizedContent. In legacy usage, a // string that is not SanitizedContent is often printed in an autoescape="false" template or by // a print with a |noAutoescape, in which case our input is just SoyData.) If the output will be // treated as HTML, the input had better be safe HTML/HTML-escaped (even if it isn't HTML // SanitizedData), or we have an XSS opportunity and a much bigger problem than bidi garbling. String wrappedValue = bidiFormatter.spanWrap(valueDir, value.coerceToString(), true /* isHtml */); // Like other directives implementing SanitizedContentOperator, BidiSpanWrapDirective is called // after the escaping (if any) has already been done, and thus there is no need for it to // produce actual SanitizedContent. return wrappedValue; }
/** * Normalizes the input HTML while preserving "safe" tags and the known directionality. * * @param optionalSafeTags to add to the basic whitelist of formatting safe tags * @return the normalized input, in the form of {@link SanitizedContent} of {@link * ContentKind#HTML} */ public static SanitizedContent cleanHtml( SoyValue value, Collection<? extends OptionalSafeTag> optionalSafeTags) { value = normalizeNull(value); Dir valueDir = null; if (value instanceof SanitizedContent) { SanitizedContent sanitizedContent = (SanitizedContent) value; if (sanitizedContent.getContentKind() == SanitizedContent.ContentKind.HTML) { return (SanitizedContent) value; } valueDir = sanitizedContent.getContentDirection(); } return cleanHtml(value.coerceToString(), valueDir, optionalSafeTags); }
public static SoyValue insertWordBreaks(SoyValue value, int maxCharsBetweenWordBreaks) { String result = new InsertWordBreaks(maxCharsBetweenWordBreaks).processString(coerceToString(value)); // Make sure to transmit the known direction, if any, to any downstream directive that may need // it, e.g. BidiSpanWrapDirective. Since a known direction is carried only by SanitizedContent, // and the transformation we make is only valid in HTML, we only transmit the direction when we // get HTML SanitizedContent. // TODO(user): Consider always returning HTML SanitizedContent. if (value instanceof SanitizedContent) { SanitizedContent sanitizedContent = (SanitizedContent) value; if (sanitizedContent.getContentKind() == ContentKind.HTML) { return UnsafeSanitizedContentOrdainer.ordainAsSafe( result, ContentKind.HTML, sanitizedContent.getContentDirection()); } } return StringData.forValue(result); }
public static String bidiDirAttr(BidiGlobalDir dir, SoyValue value, boolean isHtml) { Dir valueDir = null; boolean isHtmlForValueDirEstimation = false; if (value instanceof SanitizedContent) { SanitizedContent sanitizedContent = (SanitizedContent) value; valueDir = sanitizedContent.getContentDirection(); if (valueDir == null) { isHtmlForValueDirEstimation = sanitizedContent.getContentKind() == ContentKind.HTML; } } if (valueDir == null) { isHtmlForValueDirEstimation = isHtmlForValueDirEstimation || isHtml; valueDir = BidiUtils.estimateDirection(value.coerceToString(), isHtmlForValueDirEstimation); } BidiFormatter bidiFormatter = BidiFormatter.getInstance(dir.toDir()); return bidiFormatter.knownDirAttr(valueDir); }
public static SoyString insertWordBreaks(SoyValue value, int maxCharsBetweenWordBreaks) { String result = new InsertWordBreaks(maxCharsBetweenWordBreaks).processString(coerceToString(value)); // Make sure to transmit the known direction, if any, to any downstream directive that may need // it, e.g. BidiSpanWrapDirective. Since a known direction is carried only by SanitizedContent, // and the transformation we make is only valid in HTML, we only transmit the direction when we // get HTML SanitizedContent. // TODO(user): Consider always returning HTML SanitizedContent. if (value instanceof SanitizedContent) { SanitizedContent sanitizedContent = (SanitizedContent) value; if (sanitizedContent.getContentKind() == ContentKind.HTML) { return UnsafeSanitizedContentOrdainer.ordainAsSafe( result, ContentKind.HTML, sanitizedContent.getContentDirection()); } } return StringData.forValue(result); }
public static SanitizedContent bidiDirAttrSanitized( BidiGlobalDir dir, SoyValue value, boolean isHtml) { Dir valueDir = null; boolean isHtmlForValueDirEstimation = false; if (value instanceof SanitizedContent) { SanitizedContent sanitizedContent = (SanitizedContent) value; valueDir = sanitizedContent.getContentDirection(); if (valueDir == null) { isHtmlForValueDirEstimation = sanitizedContent.getContentKind() == ContentKind.HTML; } } if (valueDir == null) { isHtmlForValueDirEstimation = isHtmlForValueDirEstimation || isHtml; valueDir = BidiUtils.estimateDirection(value.coerceToString(), isHtmlForValueDirEstimation); } BidiFormatter bidiFormatter = BidiFormatter.getInstance(dir.toDir()); return bidiFormatter.knownDirAttrSanitized(valueDir); }