0

I am currently developing an Excel macro which allows creating Bugs in a Bugzilla instance. After some trial and error this now turns out to work fine. I wanted to enhance the client so that it's also possible to add screenshots to the newly created bug.

The environment I'm using is a little bit tricky: I have to use MS Excel for my task. As Excel does not understand XML-RPC, I downloaded an interface DLL (CookComputing.XmlRpcV2.dll from xml-rpc.net) which makes the XML-RPC interface accessible from .NET. Then I created an additional DLL which can be called from Excel macros (using COM interop).

As already mentioned, this is working fine for tasks like browsing or adding new bugs. But when adding an attachment to the bug, the image must be converted into a base64 data type. Although this seems to work fine and although the creation of the screenshot seems to succeed, the image seems to be corrupted and cannot be displayed.

Here's what I do to add the image: The Bugzilla add_attachment method accepts a struct as input: http://www.bugzilla.org/docs/4.0/en/html/api/Bugzilla/WebService/Bug.html#add_attachment. This type was defined in C# and is visible also in VBA.

This is the struct definition:

[ClassInterface(ClassInterfaceType.AutoDual)]
public class TAttachmentInputData
{
    public string[] ids;
    public string data; // base64-encoded data
    public string file_name;
    public string summary;
    public string content_type;
    public string comment;
    public bool is_patch;
    public bool is_private;

    public void addId(int id)
    {
        ids = new string[1];
        ids[0] = id.ToString();
    }

    public void addData(string strData)
    {
        try
        {
            byte[] encData_byte = new byte[strData.Length];
            encData_byte = System.Text.Encoding.ASCII.GetBytes(strData);
            string encodedData = Convert.ToBase64String(encData_byte);
            data = new Byte[System.Text.Encoding.ASCII.GetBytes(encodedData).Length];
            data = System.Text.Encoding.ASCII.GetBytes(encodedData);
        }
        catch (Exception e)
        {
            throw new Exception("Error in base64Encode" + e.Message);
        }
    }

This is the part in my macro where I would like to add the attachment:

    Dim attachmentsStruct As New TAttachmentInputData
    fname = attachmentFileName

    attachmentsStruct.file_name = GetFilenameFromPath(fname)
    attachmentsStruct.is_patch = False
    attachmentsStruct.is_private = False
    'multiple other definitions

    Open fname For Binary As #1
    attachmentsStruct.addData (Input(LOF(1), #1))
    Close #1
    attachmentsStruct.file_name = GetFilenameFromPath(fname)
    Call BugzillaClass.add_attachment(attachmentsStruct)

Where BugzillaClass it the interface exposed from my DLL to Excel VBA. The method add_attachment refers to the XML-RPC method add_attachment.

I assume that my problem is the conversion from the binary file into base64. This is done using the addData method in my C# DLL. Is the conversion done correctly there? Any idea why the images are corrupted?

TomS
  • 467
  • 9
  • 25
  • Have you manage to solve this issue of "add_attachment" method ? I am not sure if it is internal API's issue, but I've written a comment#33 in Bugzilla where they have wrote this API's method. https://bugzilla.mozilla.org/show_bug.cgi?id=412074 – Khokhar Jan 10 '14 at 14:39

1 Answers1

1

I think the issue is that you are reading in binary data in the macro, but the addData method is expecting a string. Try declaring the parameter in addData as byte[].

Wayne Allen
  • 842
  • 4
  • 12
  • But how to pass a byte[] parameter from the macro to the C# addData method? – TomS Nov 23 '12 at 09:40
  • even after I found out how to pass a byte array, I still have the same issue. The screenshot cannot be displayed. – TomS Nov 23 '12 at 12:36
  • Can you try a different approach? I.e. write the file to disk and pass the path. – Wayne Allen Nov 24 '12 at 17:25
  • not so easy. I would like to have the images controlled by bugzilla to make tasks like backup or cleanups easier. – TomS Nov 25 '12 at 19:14
  • Yes, I mean to pass the files via path to your DLL which then puts them in Bugzilla. Just trying to eliminate trying to pass a binary file through a parameter. – Wayne Allen Nov 26 '12 at 06:00
  • I'll try that, but I already tried to perform the base64 translation in the macro so that I only pass ASCII data to the DLL and that didn't work, either. But I'll try your suggestion. – TomS Nov 26 '12 at 10:58
  • Looking at your call to System.Text.Encoding.ASCII.GetBytes(strData); This is where you are messing up your file. The ASCII encoding will drop data. Instead read the file directly into a byte[] and pass it to ToBase64String. – Wayne Allen Nov 26 '12 at 23:54
  • I used the following code with the same result: `tmp = File.ReadAllBytes(attachmentFile.file); Convert.ToBase64CharArray(tmp, 0, tmp.Length, outArray, 0, Base64FormattingOptions.None);` – TomS Nov 27 '12 at 10:20
  • Maybe we need to take a step back. If you just write out the data is it a valid image? – Wayne Allen Nov 28 '12 at 15:19
  • I think that this will work. I used another approach: I read the BLOB data of the attachment into a file and saw that it was base64 encoded. After decoding it, I had a working PNG file. So, encoding seems to work fine. But for some reasons, the data is written to the database in base64, but a manually uploaded screenshot is saved as binary data. I think the question is: Why are the base64-encoded screenshots not converted back to binary after the HTTP transfer? – TomS Nov 29 '12 at 08:42
  • Looking at the docs at http://www.bugzilla.org/docs/4.2/en/html/api/Bugzilla/WebService/Bug.html#add_attachment makes me wonder what content_type you are using. – Wayne Allen Nov 30 '12 at 15:24
  • The content_type is `image/png`. I also verified (using a packet sniffer) that the XML data type of the image data is ``. – TomS Dec 01 '12 at 17:46