summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaisuke Miyakawa <dmiyakawa@google.com>2011-01-10 13:36:16 -0800
committerDaisuke Miyakawa <dmiyakawa@google.com>2011-01-10 14:10:38 -0800
commitc955c8b0da0c9fcbad0ddcae76641358c27e72cd (patch)
tree19e56c1af5c1b274ac14a5cde2c7679c964bf304
parent00b4b98ea94df7fa3f88ee9a623d60db0d4fc451 (diff)
downloadandroid_frameworks_opt_vcard-c955c8b0da0c9fcbad0ddcae76641358c27e72cd.tar.gz
android_frameworks_opt_vcard-c955c8b0da0c9fcbad0ddcae76641358c27e72cd.tar.bz2
android_frameworks_opt_vcard-c955c8b0da0c9fcbad0ddcae76641358c27e72cd.zip
Handle a case BASE64 doesn't contain two CRLFs
Although BASE64 must contain two CRLFs at its end, sometimes we encounter the case where it doesn't. This change handles it if possible. Bug: 3330767 Change-Id: Ibe2be216a25fe1047034be1fdb17bb5d35ed1b5f
-rw-r--r--java/com/android/vcard/VCardParser.java2
-rw-r--r--java/com/android/vcard/VCardParserImpl_V21.java22
-rw-r--r--java/com/android/vcard/VCardParser_V21.java4
-rw-r--r--java/com/android/vcard/VCardParser_V30.java4
-rw-r--r--tests/res/raw/v21_base64_no_2_crlf.vcf78
-rw-r--r--tests/src/com/android/vcard/tests/VCardImporterTests.java10
6 files changed, 115 insertions, 5 deletions
diff --git a/java/com/android/vcard/VCardParser.java b/java/com/android/vcard/VCardParser.java
index b7b8291..931ce96 100644
--- a/java/com/android/vcard/VCardParser.java
+++ b/java/com/android/vcard/VCardParser.java
@@ -51,5 +51,5 @@ public interface VCardParser {
* Actual cancel is done after parsing the current vcard.
* </p>
*/
- public abstract void cancel();
+ public void cancel();
}
diff --git a/java/com/android/vcard/VCardParserImpl_V21.java b/java/com/android/vcard/VCardParserImpl_V21.java
index a72c643..8c058bf 100644
--- a/java/com/android/vcard/VCardParserImpl_V21.java
+++ b/java/com/android/vcard/VCardParserImpl_V21.java
@@ -874,14 +874,32 @@ import java.util.Set;
}
protected String getBase64(String firstString) throws IOException, VCardException {
- StringBuilder builder = new StringBuilder();
+ final StringBuilder builder = new StringBuilder();
builder.append(firstString);
while (true) {
- String line = getLine();
+ final String line = peekLine();
if (line == null) {
throw new VCardException("File ended during parsing BASE64 binary");
}
+
+ // vCard 2.1 requires two spaces at the end of BASE64 strings, but some vCard doesn't
+ // have them. We try to detect those cases using semi-colon, given BASE64 doesn't
+ // contain it. Specifically BASE64 doesn't have semi-colon in it, so we should be able
+ // to detect the case safely.
+ if (line.contains(":")) {
+ if (getKnownPropertyNameSet().contains(
+ line.substring(0, line.indexOf(":")).toUpperCase())) {
+ Log.w(LOG_TAG, "Found a next property during parsing a BASE64 string, " +
+ "which must not contain semi-colon. Treat the line as next property.");
+ Log.w(LOG_TAG, "Problematic line: " + line.trim());
+ break;
+ }
+ }
+
+ // Consume the line.
+ getLine();
+
if (line.length() == 0) {
break;
}
diff --git a/java/com/android/vcard/VCardParser_V21.java b/java/com/android/vcard/VCardParser_V21.java
index 7aa7a82..9c43332 100644
--- a/java/com/android/vcard/VCardParser_V21.java
+++ b/java/com/android/vcard/VCardParser_V21.java
@@ -46,7 +46,7 @@ public final class VCardParser_V21 implements VCardParser {
*/
/* package */ static final Set<String> sKnownPropertyNameSet =
Collections.unmodifiableSet(new HashSet<String>(
- Arrays.asList("BEGIN", "LOGO", "PHOTO", "LABEL", "FN", "TITLE", "SOUND",
+ Arrays.asList("BEGIN", "END", "LOGO", "PHOTO", "LABEL", "FN", "TITLE", "SOUND",
"VERSION", "TEL", "EMAIL", "TZ", "GEO", "NOTE", "URL",
"BDAY", "ROLE", "REV", "UID", "KEY", "MAILER")));
@@ -98,11 +98,13 @@ public final class VCardParser_V21 implements VCardParser {
mVCardParserImpl = new VCardParserImpl_V21(vcardType);
}
+ @Override
public void parse(InputStream is, VCardInterpreter interepreter)
throws IOException, VCardException {
mVCardParserImpl.parse(is, interepreter);
}
+ @Override
public void cancel() {
mVCardParserImpl.cancel();
}
diff --git a/java/com/android/vcard/VCardParser_V30.java b/java/com/android/vcard/VCardParser_V30.java
index 711a00e..91dc35f 100644
--- a/java/com/android/vcard/VCardParser_V30.java
+++ b/java/com/android/vcard/VCardParser_V30.java
@@ -41,7 +41,7 @@ import java.util.Set;
public class VCardParser_V30 implements VCardParser {
/* package */ static final Set<String> sKnownPropertyNameSet =
Collections.unmodifiableSet(new HashSet<String>(Arrays.asList(
- "BEGIN", "LOGO", "PHOTO", "LABEL", "FN", "TITLE", "SOUND",
+ "BEGIN", "END", "LOGO", "PHOTO", "LABEL", "FN", "TITLE", "SOUND",
"VERSION", "TEL", "EMAIL", "TZ", "GEO", "NOTE", "URL",
"BDAY", "ROLE", "REV", "UID", "KEY", "MAILER", // 2.1
"NAME", "PROFILE", "SOURCE", "NICKNAME", "CLASS",
@@ -77,11 +77,13 @@ public class VCardParser_V30 implements VCardParser {
mVCardParserImpl = new VCardParserImpl_V30(vcardType);
}
+ @Override
public void parse(InputStream is, VCardInterpreter interepreter)
throws IOException, VCardException {
mVCardParserImpl.parse(is, interepreter);
}
+ @Override
public void cancel() {
mVCardParserImpl.cancel();
}
diff --git a/tests/res/raw/v21_base64_no_2_crlf.vcf b/tests/res/raw/v21_base64_no_2_crlf.vcf
new file mode 100644
index 0000000..1e047f6
--- /dev/null
+++ b/tests/res/raw/v21_base64_no_2_crlf.vcf
@@ -0,0 +1,78 @@
+BEGIN:VCARD
+VERSION:2.1
+N:name
+FN:fullname
+PHOTO;ENCODING=BASE64;TYPE=JPEG:
+ /9j/4QoPRXhpZgAATU0AKgAAAAgADQEOAAIAAAAPAAAAqgEPAAIAAAAHAAAAugEQAAIAAAAG
+ AAAAwgESAAMAAAABAAEAAAEaAAUAAAABAAAAyAEbAAUAAAABAAAA0AEoAAMAAAABAAIAAAEx
+ AAIAAAAOAAAA2AEyAAIAAAAUAAAA5gITAAMAAAABAAEAAIKYAAIAAAAOAAAA+odpAAQAAAAB
+ AAABhMSlAAcAAAB8AAABCAAABB4yMDA4MTAyOTEzNTUzMQAARG9Db01vAABEOTA1aQAAAABI
+ AAAAAQAAAEgAAAABRDkwNWkgVmVyMS4wMAAyMDA4OjEwOjI5IDEzOjU1OjQ3ACAgICAgICAg
+ ICAgICAAUHJpbnRJTQAwMzAwAAAABgABABQAFAACAQAAAAADAAAANAEABQAAAAEBAQAAAAEQ
+ gAAAAAAAEQkAACcQAAAPCwAAJxAAAAWXAAAnEAAACLAAACcQAAAcAQAAJxAAAAJeAAAnEAAA
+ AIsAACcQAAADywAAJxAAABvlAAAnEAAogpoABQAAAAEAAANqgp0ABQAAAAEAAANyiCIAAwAA
+ AAEAAgAAkAAABwAAAAQwMjIwkAMAAgAAABQAAAN6kAQAAgAAABQAAAOOkQEABwAAAAQBAgMA
+ kQIABQAAAAEAAAOikgEACgAAAAEAAAOqkgIABQAAAAEAAAOykgQACgAAAAEAAAO6kgUABQAA
+ AAEAAAPCkgcAAwAAAAEAAgAAkggAAwAAAAEAAAAAkgkAAwAAAAEAAAAAkgoABQAAAAEAAAPK
+ knwABwAAAAEAAAAAkoYABwAAABYAAAPSoAAABwAAAAQwMTAwoAEAAwAAAAEAAQAAoAIAAwAA
+ AAEAYAAAoAMAAwAAAAEASAAAoAUABAAAAAEAAAQAog4ABQAAAAEAAAPoog8ABQAAAAEAAAPw
+ ohAAAwAAAAEAAgAAohcAAwAAAAEAAgAAowAABwAAAAEDAAAAowEABwAAAAEBAAAApAEAAwAA
+ AAEAAAAApAIAAwAAAAEAAAAApAMAAwAAAAEAAAAApAQABQAAAAEAAAP4pAUAAwAAAAEAHQAA
+ pAYAAwAAAAEAAAAApAcAAwAAAAEAAAAApAgAAwAAAAEAAAAApAkAAwAAAAEAAAAApAoAAwAA
+ AAEAAAAApAwAAwAAAAEAAgAAAAAAAAAAAFMAACcQAAABXgAAAGQyMDA4OjEwOjI5IDEzOjU1
+ OjMxADIwMDg6MTA6MjkgMTM6NTU6NDcAAAApiAAAGwAAAAKyAAAAZAAAAV4AAABkAAAAAAAA
+ AGQAAAAlAAAACgAADpIAAAPoAAAAAAAAAAAyMDA4MTAyOTEzNTUzMQAAICoAAAAKAAAq4gAA
+ AAoAAAAAAAAAAQACAAEAAgAAAARSOTgAAAIABwAAAAQwMTAwAAAAAAAGAQMAAwAAAAEABgAA
+ ARoABQAAAAEAAARsARsABQAAAAEAAAR0ASgAAwAAAAEAAgAAAgEABAAAAAEAAAR8AgIABAAA
+ AAEAAAWLAAAAAAAAAEgAAAABAAAASAAAAAH/2P/bAIQAIBYYHBgUIBwaHCQiICYwUDQwLCww
+ YkZKOlB0Znp4cmZwboCQuJyAiK6KbnCg2qKuvsTO0M58muLy4MjwuMrOxgEiJCQwKjBeNDRe
+ xoRwhMbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbG
+ /8AAEQgAeACgAwEhAAIRAQMRAf/EAaIAAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKCxAA
+ AgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkK
+ FhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWG
+ h4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl
+ 5ufo6erx8vP09fb3+Pn6AQADAQEBAQEBAQEBAAAAAAAAAQIDBAUGBwgJCgsRAAIBAgQEAwQH
+ BQQEAAECdwABAgMRBAUhMQYSQVEHYXETIjKBCBRCkaGxwQkjM1LwFWJy0QoWJDThJfEXGBka
+ JicoKSo1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoKDhIWGh4iJipKT
+ lJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uLj5OXm5+jp6vLz
+ 9PX29/j5+v/aAAwDAQACEQMRAD8AFFSqKkZIoqRVpgSKKeBTEOApwFADsUYpgIRSEUANIppF
+ ICNhUTCgCMio2FICJhULCgC0oqVaAJFFSqKBkgFOApiHCnCgB2KMUCENJQA0imEUDGMKiYUA
+ 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
+END:VCARD
diff --git a/tests/src/com/android/vcard/tests/VCardImporterTests.java b/tests/src/com/android/vcard/tests/VCardImporterTests.java
index 716c866..631e8f2 100644
--- a/tests/src/com/android/vcard/tests/VCardImporterTests.java
+++ b/tests/src/com/android/vcard/tests/VCardImporterTests.java
@@ -1203,4 +1203,14 @@ public class VCardImporterTests extends VCardTestsBase {
.put(Email.LABEL, "CUSTOMPROPERTYWITHOUTX")
.put(Email.ADDRESS, "email2@example.com");
}
+
+ public void testBase64Without2CrLf_Parse() {
+ mVerifier.initForImportTest(V21, R.raw.v21_base64_no_2_crlf);
+ mVerifier.addPropertyNodesVerifierElem()
+ .addExpectedNodeWithOrder("N", "name")
+ .addExpectedNodeWithOrder("FN", "fullname")
+ .addExpectedNodeWithOrder("PHOTO", null,
+ null, sPhotoByteArrayForComplicatedCase, mContentValuesForBase64V21,
+ new TypeSet("JPEG"), null);
+ }
}