From 44162f71e128ec940d1c8ce79103fa8b8a6f53c6 Mon Sep 17 00:00:00 2001 From: David King Date: Fri, 29 Aug 2014 12:18:19 -0700 Subject: 442726: Attachments with unicode characters in file names get submitted wrongly Change-Id: Ib46683040f56fb0d524108ada844ef0d76a06907 Task-Url: https://bugs.eclipse.org/bugs/show_bug.cgi?id=442726 Signed-off-by: David King --- .../internal/bugzilla/core/BugzillaClient.java | 4 +- .../internal/bugzilla/core/BugzillaFilePart.java | 41 +++++++++++++++++ .../tests/BugzillaAttachmentHandlerTest.java | 53 ++++++++++++++++++++++ 3 files changed, 95 insertions(+), 3 deletions(-) create mode 100644 org.eclipse.mylyn.bugzilla.core/src/org/eclipse/mylyn/internal/bugzilla/core/BugzillaFilePart.java diff --git a/org.eclipse.mylyn.bugzilla.core/src/org/eclipse/mylyn/internal/bugzilla/core/BugzillaClient.java b/org.eclipse.mylyn.bugzilla.core/src/org/eclipse/mylyn/internal/bugzilla/core/BugzillaClient.java index 4afccee7c..2f8c8e83d 100644 --- a/org.eclipse.mylyn.bugzilla.core/src/org/eclipse/mylyn/internal/bugzilla/core/BugzillaClient.java +++ b/org.eclipse.mylyn.bugzilla.core/src/org/eclipse/mylyn/internal/bugzilla/core/BugzillaClient.java @@ -55,7 +55,6 @@ import org.apache.commons.httpclient.NameValuePair; import org.apache.commons.httpclient.RedirectException; import org.apache.commons.httpclient.methods.GetMethod; import org.apache.commons.httpclient.methods.HeadMethod; -import org.apache.commons.httpclient.methods.multipart.FilePart; import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity; import org.apache.commons.httpclient.methods.multipart.Part; import org.apache.commons.httpclient.methods.multipart.PartBase; @@ -91,7 +90,6 @@ import org.eclipse.mylyn.tasks.core.RepositoryStatus; import org.eclipse.mylyn.tasks.core.TaskRepository; import org.eclipse.mylyn.tasks.core.data.AbstractTaskAttachmentSource; import org.eclipse.mylyn.tasks.core.data.TaskAttachmentMapper; -import org.eclipse.mylyn.tasks.core.data.TaskAttachmentPartSource; import org.eclipse.mylyn.tasks.core.data.TaskAttribute; import org.eclipse.mylyn.tasks.core.data.TaskAttributeMapper; import org.eclipse.mylyn.tasks.core.data.TaskData; @@ -999,7 +997,7 @@ public class BugzillaClient { if (comment != null) { parts.add(new StringPart(IBugzillaConstants.POST_INPUT_COMMENT, comment, getCharacterEncoding())); } - parts.add(new FilePart(IBugzillaConstants.POST_INPUT_DATA, new TaskAttachmentPartSource(source, filename))); + parts.add(new BugzillaFilePart(source, filename, contentType, getCharacterEncoding())); if (isPatch) { parts.add(new StringPart(ATTRIBUTE_ISPATCH, VALUE_ISPATCH)); diff --git a/org.eclipse.mylyn.bugzilla.core/src/org/eclipse/mylyn/internal/bugzilla/core/BugzillaFilePart.java b/org.eclipse.mylyn.bugzilla.core/src/org/eclipse/mylyn/internal/bugzilla/core/BugzillaFilePart.java new file mode 100644 index 000000000..9a0895dce --- /dev/null +++ b/org.eclipse.mylyn.bugzilla.core/src/org/eclipse/mylyn/internal/bugzilla/core/BugzillaFilePart.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2014 Tasktop Technologies and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Tasktop Technologies - initial API and implementation + *******************************************************************************/ + +package org.eclipse.mylyn.internal.bugzilla.core; + +import java.io.IOException; +import java.io.OutputStream; + +import org.apache.commons.httpclient.methods.multipart.FilePart; +import org.apache.commons.httpclient.util.EncodingUtil; +import org.eclipse.mylyn.tasks.core.data.AbstractTaskAttachmentSource; +import org.eclipse.mylyn.tasks.core.data.TaskAttachmentPartSource; + +public class BugzillaFilePart extends FilePart { + + private final String filename; + + public BugzillaFilePart(AbstractTaskAttachmentSource source, String filename, String contentType, String charset) { + super(IBugzillaConstants.POST_INPUT_DATA, new TaskAttachmentPartSource(source, null), contentType, charset); + this.filename = filename; + } + + @Override + protected void sendDispositionHeader(OutputStream out) throws IOException { + super.sendDispositionHeader(out); + if (filename != null) { + out.write(EncodingUtil.getAsciiBytes(FILE_NAME)); + out.write(QUOTE_BYTES); + out.write(EncodingUtil.getBytes(filename, getCharSet())); + out.write(QUOTE_BYTES); + } + } +} diff --git a/org.eclipse.mylyn.bugzilla.tests/src/org/eclipse/mylyn/bugzilla/tests/BugzillaAttachmentHandlerTest.java b/org.eclipse.mylyn.bugzilla.tests/src/org/eclipse/mylyn/bugzilla/tests/BugzillaAttachmentHandlerTest.java index 3f278c6da..4db4e8fbf 100644 --- a/org.eclipse.mylyn.bugzilla.tests/src/org/eclipse/mylyn/bugzilla/tests/BugzillaAttachmentHandlerTest.java +++ b/org.eclipse.mylyn.bugzilla.tests/src/org/eclipse/mylyn/bugzilla/tests/BugzillaAttachmentHandlerTest.java @@ -19,6 +19,7 @@ import java.io.FileOutputStream; import java.io.FileWriter; import java.io.OutputStream; import java.util.Date; +import java.util.List; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IStatus; @@ -311,6 +312,58 @@ public class BugzillaAttachmentHandlerTest extends AbstractBugzillaTest { assertTrue(attachFile.delete()); } + public void testAttachmentWithUnicode() throws Exception { + testAttachmentWithSpecialCharacters("\u00E7\u00F1\u00A5\u20AC\u00A3\u00BD\u00BC\u03B2\u03B8\u53F0\u5317\u3096\u3097\uFF73"); + } + + public void testAttachmentWithSpecialCharacters() throws Exception { + testAttachmentWithSpecialCharacters("~`!@#$%^&()_-+={[}];',"); + } + + private void testAttachmentWithSpecialCharacters(String specialCharacters) throws Exception { + TaskData taskData = BugzillaFixture.current().createTask(PrivilegeLevel.USER, null, null); + assertNotNull(taskData); + + TaskAttribute attachmentAttr = taskData.getAttributeMapper().createTaskAttachment(taskData); + TaskAttachmentMapper attachmentMapper = TaskAttachmentMapper.createFrom(attachmentAttr); + + String description = "Test attachment " + specialCharacters + System.currentTimeMillis(); + attachmentMapper.setDescription(description); + attachmentMapper.setContentType("text/plain"); + attachmentMapper.setPatch(false); + attachmentMapper.applyTo(attachmentAttr); + + String filename = "test" + specialCharacters + System.currentTimeMillis() + ".txt"; + File attachFile = new File(filename); + attachFile.createNewFile(); + attachFile.deleteOnExit(); + BufferedWriter write = new BufferedWriter(new FileWriter(attachFile)); + write.write("test file content"); + write.close(); + + FileTaskAttachmentSource attachment = new FileTaskAttachmentSource(attachFile); + attachment.setContentType("text/plain"); + attachment.setDescription(description); + attachment.setName(filename); + + client.postAttachment(taskData.getTaskId(), attachmentMapper.getComment(), attachment, attachmentAttr, + new NullProgressMonitor()); + + taskData = BugzillaFixture.current().getTask(taskData.getTaskId(), client); + assertNotNull(taskData); + List attachmentAttrs = taskData.getAttributeMapper().getAttributesByType(taskData, + TaskAttribute.TYPE_ATTACHMENT); + assertEquals(1, attachmentAttrs.size()); + + attachmentMapper = TaskAttachmentMapper.createFrom(attachmentAttrs.get(0)); + assertEquals(description, attachmentMapper.getDescription()); + assertEquals(filename, attachmentMapper.getFileName()); + assertEquals("text/plain", attachmentMapper.getContentType()); + assertEquals(Boolean.FALSE, attachmentMapper.isPatch()); + + assertTrue(attachFile.delete()); + } + private void assertFileEmptyError(Exception e) { if (BugzillaFixture.current().getBugzillaVersion().compareTo(BugzillaVersion.BUGZILLA_4_5_2) >= 0) { assertEquals("An unknown repository error has occurred: file is empty", e.getMessage()); -- cgit v1.2.3