opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/JPEGSyntaxImpl.java
@@ -22,6 +22,7 @@ * * * Copyright 2009 Sun Microsystems, Inc. * Portions Copyright 2012 ForgeRock AS */ package org.forgerock.opendj.ldap.schema; @@ -34,9 +35,10 @@ import org.forgerock.opendj.ldap.ByteSequence; /** * This class implements the JPEG attribute syntax. This should be restricted to * holding only JPEG image contents, but we will accept any set of bytes. It * will be treated much like the octet string attribute syntax. * This class implements the JPEG attribute syntax. This is actually * two specifications - JPEG and JFIF. As an extension we allow JPEG * and Exif, which is what most digital cameras use. We only check for * valid JFIF and Exif headers. */ final class JPEGSyntaxImpl extends AbstractSyntaxImpl { @Override @@ -73,7 +75,41 @@ */ public boolean valueIsAcceptable(final Schema schema, final ByteSequence value, final LocalizableMessageBuilder invalidReason) { // All values will be acceptable for the fax syntax. if (!schema.allowMalformedJPEGPhotos()) { /* JFIF files start: * 0xff 0xd8 0xff 0xe0 LH LL 0x4a 0x46 0x49 0x46 ... * SOI APP0 len "JFIF" * * Exif files (from most digital cameras) start: * 0xff 0xd8 0xff 0xe1 LH LL 0x45 0x78 0x69 0x66 ... * SOI APP1 len "Exif" * * So all legal values must be at least 10 bytes long */ if (value.length() < 10) { return false; } if (value.byteAt(0) != (byte) 0xff && value.byteAt(1) != (byte) 0xd8) { return false; } if (value.byteAt(2) == (byte) 0xff && value.byteAt(3) == (byte) 0xe0 && value.byteAt(6) == 'J' && value.byteAt(7) == 'F' && value.byteAt(8) == 'I' && value.byteAt(9) == 'F') { return true; } if (value.byteAt(2) == (byte) 0xff && value.byteAt(3) == (byte) 0xe1 && value.byteAt(6) == 'E' && value.byteAt(7) == 'x' && value.byteAt(8) == 'i' && value.byteAt(9) == 'f') { return true; } // No JFIF or Exif header found return false; } return true; } } opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/Schema.java
@@ -85,6 +85,10 @@ return true; } public boolean allowMalformedJPEGPhotos() { return true; } public boolean allowZeroLengthDirectoryStrings() { return false; } @@ -301,6 +305,8 @@ private static interface Impl { boolean allowMalformedNamesAndOptions(); boolean allowMalformedJPEGPhotos(); boolean allowNonStandardTelephoneNumbers(); boolean allowZeroLengthDirectoryStrings(); @@ -393,6 +399,10 @@ return strictImpl.allowMalformedNamesAndOptions(); } public boolean allowMalformedJPEGPhotos() { return strictImpl.allowMalformedJPEGPhotos(); } public boolean allowNonStandardTelephoneNumbers() { return strictImpl.allowNonStandardTelephoneNumbers(); } @@ -651,6 +661,8 @@ private final String schemaName; private final boolean allowMalformedJPEGPhotos; private final boolean allowNonStandardTelephoneNumbers; private final boolean allowZeroLengthDirectoryStrings; @@ -658,6 +670,7 @@ private final boolean allowMalformedNamesAndOptions; StrictImpl(final String schemaName, final boolean allowMalformedNamesAndOptions, final boolean allowMalformedJPEGPhotos, final boolean allowNonStandardTelephoneNumbers, final boolean allowZeroLengthDirectoryStrings, final Map<String, Syntax> numericOID2Syntaxes, @@ -680,6 +693,7 @@ final List<LocalizableMessage> warnings) { this.schemaName = schemaName; this.allowMalformedNamesAndOptions = allowMalformedNamesAndOptions; this.allowMalformedJPEGPhotos = allowMalformedJPEGPhotos; this.allowNonStandardTelephoneNumbers = allowNonStandardTelephoneNumbers; this.allowZeroLengthDirectoryStrings = allowZeroLengthDirectoryStrings; this.numericOID2Syntaxes = Collections.unmodifiableMap(numericOID2Syntaxes); @@ -707,6 +721,10 @@ return allowMalformedNamesAndOptions; } public boolean allowMalformedJPEGPhotos() { return allowMalformedJPEGPhotos; } public boolean allowNonStandardTelephoneNumbers() { return allowNonStandardTelephoneNumbers; } @@ -1323,6 +1341,7 @@ private final Impl impl; Schema(final String schemaName, final boolean allowMalformedNamesAndOptions, final boolean allowMalformedJPEGPhotos, final boolean allowNonStandardTelephoneNumbers, final boolean allowZeroLengthDirectoryStrings, final Map<String, Syntax> numericOID2Syntaxes, @@ -1345,8 +1364,9 @@ final List<LocalizableMessage> warnings) { impl = new StrictImpl(schemaName, allowMalformedNamesAndOptions, allowNonStandardTelephoneNumbers, allowZeroLengthDirectoryStrings, numericOID2Syntaxes, numericOID2MatchingRules, numericOID2MatchingRuleUses, allowMalformedJPEGPhotos, allowNonStandardTelephoneNumbers, allowZeroLengthDirectoryStrings, numericOID2Syntaxes, numericOID2MatchingRules, numericOID2MatchingRuleUses, numericOID2AttributeTypes, numericOID2ObjectClasses, numericOID2NameForms, numericOID2ContentRules, id2StructureRules, name2MatchingRules, name2MatchingRuleUses, name2AttributeTypes, name2ObjectClasses, @@ -1382,6 +1402,21 @@ } /** * Returns {@code true} if the JPEG Photo syntax defined for this * schema allows values which do not conform to the JFIF or Exif * specifications. * <p> * By default this compatibility option is set to {@code true}. * * @return {@code true} if the JPEG Photo syntax defined for this * schema allows values which do not conform to the JFIF * of Exit specifications. */ public boolean allowMalformedJPEGPhotos() { return impl.allowMalformedJPEGPhotos(); } /** * Returns {@code true} if the Telephone Number syntax defined for this * schema allows values which do not conform to the E.123 international * telephone number format. opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/SchemaBuilder.java
@@ -172,6 +172,8 @@ private boolean allowMalformedNamesAndOptions; private boolean allowMalformedJPEGPhotos; // A schema which should be copied into this builder on any mutation. private Schema copyOnWriteSchema = null; @@ -2247,6 +2249,26 @@ } /** * Specifies whether or not the JPEG Photo syntax should allow values * which do not conform to the JFIF or Exif specifications. * <p> * By default this compatibility option is set to {@code true}. * * @param allowMalformedJPEGPhotos * {@code true} if the JPEG Photo syntax should allow * values which do not conform to the JFIF or Exif * specifications. * @return A reference to this {@code SchemaBuilder}. */ public SchemaBuilder allowMalformedJPEGPhotos( final boolean allowMalformedJPEGPhotos) { lazyInitBuilder(); this.allowMalformedJPEGPhotos = allowMalformedJPEGPhotos; return this; } /** * Specifies whether or not the Telephone Number syntax should allow values * which do not conform to the E.123 international telephone number format. * <p> @@ -2508,8 +2530,9 @@ final Schema schema = new Schema(localSchemaName, allowMalformedNamesAndOptions, allowNonStandardTelephoneNumbers, allowZeroLengthDirectoryStrings, numericOID2Syntaxes, numericOID2MatchingRules, numericOID2MatchingRuleUses, allowMalformedJPEGPhotos, allowNonStandardTelephoneNumbers, allowZeroLengthDirectoryStrings, numericOID2Syntaxes, numericOID2MatchingRules, numericOID2MatchingRuleUses, numericOID2AttributeTypes, numericOID2ObjectClasses, numericOID2NameForms, numericOID2ContentRules, id2StructureRules, name2MatchingRules, name2MatchingRuleUses, name2AttributeTypes, name2ObjectClasses, @@ -2784,6 +2807,7 @@ // Lazy initialization. if (numericOID2Syntaxes == null) { allowMalformedNamesAndOptions = true; allowMalformedJPEGPhotos = true; allowNonStandardTelephoneNumbers = true; allowZeroLengthDirectoryStrings = false; @@ -2814,6 +2838,7 @@ addSchema0(copyOnWriteSchema, true); allowMalformedNamesAndOptions = copyOnWriteSchema.allowMalformedNamesAndOptions(); allowMalformedJPEGPhotos = copyOnWriteSchema.allowMalformedJPEGPhotos(); allowNonStandardTelephoneNumbers = copyOnWriteSchema.allowNonStandardTelephoneNumbers(); allowZeroLengthDirectoryStrings = copyOnWriteSchema.allowZeroLengthDirectoryStrings(); @@ -2826,6 +2851,7 @@ this.copyOnWriteSchema = copyOnWriteSchema; this.allowMalformedNamesAndOptions = true; this.allowMalformedJPEGPhotos = true; this.allowNonStandardTelephoneNumbers = true; this.allowZeroLengthDirectoryStrings = false;