@Override public int hashCode() { return getContent().hashCode() + 31 * contentKind.hashCode(); }
private void enforceContentKind() { if (expectedContentKind == SanitizedContent.ContentKind.TEXT) { // Allow any template to be called as text. This is consistent with the fact that // kind="text" templates can call any other template. return; } if (!contentKind.isPresent()) { throw new IllegalStateException( "Cannot render a non strict template '" + templateName + "' as '" + Ascii.toLowerCase(expectedContentKind.name()) + "'"); } if (expectedContentKind != contentKind.get()) { throw new IllegalStateException( "Expected template '" + templateName + "' to be kind=\"" + Ascii.toLowerCase(expectedContentKind.name()) + "\" but was kind=\"" + Ascii.toLowerCase(contentKind.get().name()) + "\""); } } }
/** * Loads assumed-safe content from a Java resource. * * <p>This performs ZERO VALIDATION of the data, and takes you on your word that the input is * valid. We assume that resources should be safe because they are part of the binary, and * therefore not attacker controlled, unless the source code is compromised (in which there's * nothing we can do). * * @param contextClass Class relative to which to load the resource. * @param resourceName The name of the resource, relative to the context class. * @param charset The character set to use, usually Charsets.UTF_8. * @param kind The content kind of the resource. */ public static SanitizedContent fromResource( Class<?> contextClass, String resourceName, Charset charset, ContentKind kind) throws IOException { pretendValidateResource(resourceName, kind); return SanitizedContent.create( Resources.toString(Resources.getResource(contextClass, resourceName), charset), kind, // Text resources are usually localized, so one might think that the locale direction should // be assumed for them. We do not do that because: // - We do not know the locale direction here. // - Some messages do not get translated. // - This method currently can't be used for text resources (see pretendValidateResource()). kind.getDefaultDir()); }
(callee.getContentKind() != null) ? UnsafeSanitizedContentOrdainer.ordainAsSafe( calleeBuilder.toString(), ContentKind.valueOf(callee.getContentKind().name())) : StringData.forValue(calleeBuilder.toString()); for (SoyPrintDirective directive : node.getEscapingDirectives()) {
contentKind.isEmpty() ? Optional.<ContentKind>absent() : Optional.of(ContentKind.valueOf(contentKind)); this.callees = ImmutableSet.copyOf(annotation.callees()); this.delCallees = ImmutableSet.copyOf(annotation.delCallees());
contentKind.isEmpty() ? Optional.<ContentKind>absent() : Optional.of(ContentKind.valueOf(contentKind)); this.callees = ImmutableSet.copyOf(annotation.callees()); this.delCallees = ImmutableSet.copyOf(annotation.delCallees());
printDirective instanceof SanitizedContentOperator ? SanitizedContentKind.valueOf( ((SanitizedContentOperator) printDirective).getContentKind().name()) : null; if (contentKind == null || contentKind != escapingMode.contentKind) {
printDirective instanceof SanitizedContentOperator ? SanitizedContentKind.valueOf( ((SanitizedContentOperator) printDirective).getContentKind().name()) : null; if (contentKind == null || contentKind != escapingMode.contentKind) {
private void enforceContentKind(TemplateNode template) { if (expectedContentKind == SanitizedContent.ContentKind.TEXT) { // Allow any template to be called as text. This is consistent with the fact that // kind="text" templates can call any other template. return; } if (template.getContentKind() == null) { throw new SoyTofuException( "Expected template to be autoescape=\"strict\" " + "but was autoescape=\"" + template.getAutoescapeMode().getAttributeValue() + "\": " + template.getTemplateName()); } SanitizedContentKind expectedAsSanitizedContentKind = SanitizedContentKind.valueOf(expectedContentKind.name()); if (expectedAsSanitizedContentKind != template.getContentKind()) { throw new SoyTofuException( "Expected template to be kind=\"" + expectedAsSanitizedContentKind.asAttributeValue() + "\" but was kind=\"" + template.getContentKind().asAttributeValue() + "\": " + template.getTemplateName()); } } }
private void enforceContentKind(TemplateNode template) { if (expectedContentKind == SanitizedContent.ContentKind.TEXT) { // Allow any template to be called as text. This is consistent with the fact that // kind="text" templates can call any other template. return; } if (template.getContentKind() == null) { throw new SoyTofuException( "Cannot render a non strict template '" + templateName + "' as '" + Ascii.toLowerCase(expectedContentKind.name()) + "'"); } SanitizedContentKind expectedAsSanitizedContentKind = SanitizedContentKind.valueOf(expectedContentKind.name()); if (expectedAsSanitizedContentKind != template.getContentKind()) { throw new SoyTofuException( "Expected template '" + template.getTemplateName() + "' to be kind=\"" + expectedAsSanitizedContentKind.asAttributeValue() + "\" but was kind=\"" + template.getContentKind().asAttributeValue() + "\""); } } }
@Override public SanitizedContent.ContentKind render(Appendable out) { TemplateNode template = baseTofu.renderMain( out, templateName, data, ijData, activeDelPackageNames, msgBundle, idRenamingMap, cssRenamingMap, debugSoyTemplateInfo); if (contentKindExplicitlySet || template.getContentKind() != null) { // Enforce the content kind if: // - The caller explicitly set a content kind to validate. // - The template is strict. This avoids accidentally using a text strict template in a // place where HTML was implicitly expected. enforceContentKind(template); } return template.getContentKind() != null ? SanitizedContent.ContentKind.valueOf(template.getContentKind().name()) : null; }
/** * Loads assumed-safe content from a Java resource. * * <p>This performs ZERO VALIDATION of the data, and takes you on your word that the input is * valid. We assume that resources should be safe because they are part of the binary, and * therefore not attacker controlled, unless the source code is compromised (in which there's * nothing we can do). * * @param resourceName The name of the resource to be found using {@linkplain * Thread#getContextClassLoader() context class loader}. * @param charset The character set to use, usually Charsets.UTF_8. * @param kind The content kind of the resource. */ public static SanitizedContent fromResource( String resourceName, Charset charset, ContentKind kind) throws IOException { pretendValidateResource(resourceName, kind); return SanitizedContent.create( Resources.toString(Resources.getResource(resourceName), charset), kind, // Text resources are usually localized, so one might think that the locale direction should // be assumed for them. We do not do that because: // - We do not know the locale direction here. // - Some messages do not get translated. // - This method currently can't be used for text resources (see pretendValidateResource()). kind.getDefaultDir()); }
/** * Loads assumed-safe content from a Java resource. * * <p>This performs ZERO VALIDATION of the data, and takes you on your word that the input is * valid. We assume that resources should be safe because they are part of the binary, and * therefore not attacker controlled, unless the source code is compromised (in which there's * nothing we can do). * * @param contextClass Class relative to which to load the resource. * @param resourceName The name of the resource, relative to the context class. * @param charset The character set to use, usually Charsets.UTF_8. * @param kind The content kind of the resource. */ public static SanitizedContent fromResource( Class<?> contextClass, String resourceName, Charset charset, ContentKind kind) throws IOException { pretendValidateResource(resourceName, kind); return SanitizedContent.create( Resources.toString(Resources.getResource(contextClass, resourceName), charset), kind, // Text resources are usually localized, so one might think that the locale direction should // be assumed for them. We do not do that because: // - We do not know the locale direction here. // - Some messages do not get translated. // - This method currently can't be used for text resources (see pretendValidateResource()). kind.getDefaultDir()); }
/** * Generates code to box the expression assuming that it is non-nullable and on the top of the * stack. */ private static void doBox(CodeBuilder adapter, SoyRuntimeType type) { if (type.isKnownSanitizedContent()) { FieldRef.enumReference( ContentKind.valueOf(((SanitizedType) type.soyType()).getContentKind().name())) .accessStaticUnchecked(adapter); MethodRef.ORDAIN_AS_SAFE.invokeUnchecked(adapter); } else if (type.isKnownString()) { MethodRef.STRING_DATA_FOR_VALUE.invokeUnchecked(adapter); } else if (type.isKnownList()) { MethodRef.LIST_IMPL_FOR_PROVIDER_LIST.invokeUnchecked(adapter); } else if (type.isKnownLegacyObjectMap()) { FieldRef.enumReference(RuntimeType.LEGACY_OBJECT_MAP_OR_RECORD).putUnchecked(adapter); MethodRef.DICT_IMPL_FOR_PROVIDER_MAP.invokeUnchecked(adapter); } else if (type.isKnownMap()) { MethodRef.MAP_IMPL_FOR_PROVIDER_MAP.invokeUnchecked(adapter); } else if (type.isKnownProto()) { MethodRef.SOY_PROTO_VALUE_IMPL_CREATE.invokeUnchecked(adapter); } else { throw new IllegalStateException("Can't box soy expression of type " + type); } }
/** * Generates code to box the expression assuming that it is non-nullable and on the top of the * stack. */ private static void doBox(CodeBuilder adapter, SoyRuntimeType type) { if (type.isKnownSanitizedContent()) { FieldRef.enumReference( ContentKind.valueOf(((SanitizedType) type.soyType()).getContentKind().name())) .accessStaticUnchecked(adapter); MethodRef.ORDAIN_AS_SAFE.invokeUnchecked(adapter); } else if (type.isKnownString()) { MethodRef.STRING_DATA_FOR_VALUE.invokeUnchecked(adapter); } else if (type.isKnownListOrUnionOfLists()) { MethodRef.LIST_IMPL_FOR_PROVIDER_LIST.invokeUnchecked(adapter); } else if (type.isKnownLegacyObjectMapOrUnionOfMaps()) { FieldRef.enumReference(RuntimeMapTypeTracker.Type.LEGACY_OBJECT_MAP_OR_RECORD) .putUnchecked(adapter); MethodRef.DICT_IMPL_FOR_PROVIDER_MAP.invokeUnchecked(adapter); } else if (type.isKnownMapOrUnionOfMaps()) { MethodRef.MAP_IMPL_FOR_PROVIDER_MAP.invokeUnchecked(adapter); } else if (type.isKnownProtoOrUnionOfProtos()) { MethodRef.SOY_PROTO_VALUE_CREATE.invokeUnchecked(adapter); } else { throw new IllegalStateException("Can't box soy expression of type " + type); } }
private void enforceContentKind() { if (expectedContentKind == SanitizedContent.ContentKind.TEXT) { // Allow any template to be called as text. This is consistent with the fact that // kind="text" templates can call any other template. return; } if (!contentKind.isPresent()) { throw new IllegalStateException( "Cannot render a non strict template as '" + Ascii.toLowerCase(expectedContentKind.name()) + "'"); } if (expectedContentKind != contentKind.get()) { throw new IllegalStateException( "Expected template to be kind=\"" + Ascii.toLowerCase(expectedContentKind.name()) + "\" but was kind=\"" + Ascii.toLowerCase(contentKind.get().name()) + "\": " + templateName); } } }
@Override public SanitizedContent.ContentKind render(Appendable out) { TemplateNode template = baseTofu.renderMain( out, templateName, data, ijData, activeDelPackageNames, msgBundle, idRenamingMap, cssRenamingMap, debugSoyTemplateInfo, pluginInstances); if (contentKindExplicitlySet || template.getContentKind() != null) { // Enforce the content kind if: // - The caller explicitly set a content kind to validate. // - The template is strict. This avoids accidentally using a text strict template in a // place where HTML was implicitly expected. enforceContentKind(template); } return template.getContentKind() != null ? SanitizedContent.ContentKind.valueOf(template.getContentKind().name()) : null; }
/** * Loads assumed-safe content from a Java resource. * * <p>This performs ZERO VALIDATION of the data, and takes you on your word that the input is * valid. We assume that resources should be safe because they are part of the binary, and * therefore not attacker controlled, unless the source code is compromised (in which there's * nothing we can do). * * @param resourceName The name of the resource to be found using {@linkplain * Thread#getContextClassLoader() context class loader}. * @param charset The character set to use, usually Charsets.UTF_8. * @param kind The content kind of the resource. */ public static SanitizedContent fromResource( String resourceName, Charset charset, ContentKind kind) throws IOException { pretendValidateResource(resourceName, kind); return SanitizedContent.create( Resources.toString(Resources.getResource(resourceName), charset), kind, // Text resources are usually localized, so one might think that the locale direction should // be assumed for them. We do not do that because: // - We do not know the locale direction here. // - Some messages do not get translated. // - This method currently can't be used for text resources (see pretendValidateResource()). kind.getDefaultDir()); }
/** * Wraps an expression with the proper SanitizedContent constructor. * * <p>NOTE: The pyExpr provided must be properly escaped for the given ContentKind. Please talk to * ISE (ise@) for any questions or concerns. * * @param contentKind The kind of sanitized content. * @param pyExpr The expression to wrap. * @deprecated this method is not safe to use without a security review. Do not use it. */ @Deprecated public static PyExpr wrapAsSanitizedContent(ContentKind contentKind, PyExpr pyExpr) { String sanitizer = NodeContentKinds.toPySanitizedContentOrdainer( SanitizedContentKind.valueOf(contentKind.name())); String approval = "sanitize.IActuallyUnderstandSoyTypeSafetyAndHaveSecurityApproval(" + "'Internally created Sanitization.')"; return new PyExpr( sanitizer + "(" + pyExpr.getText() + ", approval=" + approval + ")", Integer.MAX_VALUE); }
/** * Wraps with the proper SanitizedContent constructor if contentKind is non-null. * * @param contentKind The kind of sanitized content. * @param jsExpr The expression to wrap. * @deprecated This method is not safe to use without a security review, please migrate away from * it. */ @Deprecated public static JsExpr maybeWrapAsSanitizedContent( @Nullable ContentKind contentKind, JsExpr jsExpr) { if (contentKind == null) { return jsExpr; } else { return wrapWithFunction( NodeContentKinds.toJsSanitizedContentOrdainer( SanitizedContentKind.valueOf(contentKind.name())), jsExpr); } } }