From 0eb671e7cb4324437780e64a9d23cd66baf6b3ff Mon Sep 17 00:00:00 2001
From: Chris Ridd <chris.ridd@forgerock.com>
Date: Wed, 08 Aug 2012 16:30:08 +0000
Subject: [PATCH] Fix OPENDJ-558 Validation for JPEGSyntax values
---
opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/SchemaBuilder.java | 30 ++++++++++++++-
opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/JPEGSyntaxImpl.java | 44 ++++++++++++++++++++--
opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/Schema.java | 39 ++++++++++++++++++-
3 files changed, 105 insertions(+), 8 deletions(-)
diff --git a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/JPEGSyntaxImpl.java b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/JPEGSyntaxImpl.java
index 72d7c96..2195e84 100644
--- a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/JPEGSyntaxImpl.java
+++ b/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;
}
}
diff --git a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/Schema.java b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/Schema.java
index 2c460c8..ad4db1e 100644
--- a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/Schema.java
+++ b/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.
diff --git a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/SchemaBuilder.java b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/SchemaBuilder.java
index 4308e87..33e9ae8 100644
--- a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/schema/SchemaBuilder.java
+++ b/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;
--
Gitblit v1.10.0