Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. The Lounge
  3. How/where to report MS bugs?

How/where to report MS bugs?

Scheduled Pinned Locked Moved The Lounge
helpquestioncsharpdotnetcom
25 Posts 8 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • K Konstantin Vasserman

    Ok. Here it goes: I need to read EXIF info out of JPEG images. There is support for it in .NET System.Drawing.Image class. The property in question is PropertyItems. This property returns an array of System.Drawing.Imaging.PropertyItem objects. A very simple code sample would be:

    Image img = Image.FromFile("mypicture.jpg");
    PropertyItem[] pitems = img.PropertyItems;

    It used to work fine. However, there is a new digital camera that was just released just a few days ago that produces images with EXIF 2.2 (updated standard) information. The camera is Sony DSC-F717. Whenever I am trying to use image out of this camera I get an exception "Value cannot be null" in the second line of the above code. Naturally, my first thought was that .NET is just not written to support newer EXIF standard. But there are 2 problems with this: a) It should not give an exception - it does not seem like a correct behavior in this case. It should report "Invalid format" or something... b) I've found images out of another brand of camera that are in EXIF 2.2 format and they work... Then I thought that Sony camera's produces invalid images (not following standard or bug in encoding), but it still should not crash the framework IMO. That is the description of my problem. I can supply a sample image that causes the error if someone cares to see it for themselves.

    S Offline
    S Offline
    Stephane Rodriguez
    wrote on last edited by
    #15

    For Image.PropertyItems, it's the same GDI+ stuff (Image::GetPropertyItem gdi+ wrapper in gdiplus.dll). I would be you, I would try to reproduce the issue using C++ alone. That said, I don't know all ins and outs about JPEG codecs, but you'll find in PlatformSDK\include\prelease\GdiplusImaging.h the GUID for the JPEG codec, and more interestingly this :

    //---------------------------------------------------------------------------
    // Property sets
    //---------------------------------------------------------------------------

    DEFINE_GUID(FormatIDImageInformation, 0xe5836cbe,0x5eef,0x4f1d,0xac,0xde,0xae,0x4c,0x43,0xb6,0x08,0xce);
    DEFINE_GUID(FormatIDJpegAppHeaders, 0x1c4afdcd,0x6177,0x43cf,0xab,0xc7,0x5f,0x51,0xaf,0x39,0xee,0x85);

    which lets me believe you can handle custom JPEG internals with the current gdiplus. Lotsa work tonight for those interested ! (sorry, I'm already falling asleep....:zzz:)


    She's so dirty, she threw a boomerang and it wouldn't even come back.

    1 Reply Last reply
    0
    • K Konstantin Vasserman

      According to my Call Stack the error occures somewhere in System.Drawing.Imaging.PropertyItemInternal class. I have posted the details in response to Stephane. Thanks.

      S Offline
      S Offline
      Stephane Rodriguez
      wrote on last edited by
      #16

      Here is the PropertyItem internal :

      public System.Drawing.Imaging.PropertyItem[] get_PropertyItems() {
      int local0;
      int local1;
      int local2;
      IntPtr local3;
      System.Drawing.Imaging.PropertyItem[] local4;

      local2 = SafeNativeMethods.GdipGetPropertyCount(this.nativeImage, local1);
      if (local2 != 0)
      	throw SafeNativeMethods.StatusException(local2);
      local2 = SafeNativeMethods.GdipGetPropertySize(this.nativeImage, local0, local1);
      if (local2 != 0)
      	throw SafeNativeMethods.StatusException(local2);
      if (local0 == 0 || local1 == 0)
      	return new PropertyItem\[0\];
      local3 = Marshal.AllocHGlobal(local0);
      local2 = SafeNativeMethods.GdipGetAllPropertyItems(this.nativeImage, local0, local1, local3);
      if (local2 != 0) {
      	Marshal.FreeHGlobal(local3);
      	throw SafeNativeMethods.StatusException(local2);
      }
      local4 = PropertyItemInternal.ConvertFromMemory(local3, local1);
      Marshal.FreeHGlobal(local3);
      GC.KeepAlive(this);
      return local4;
      

      }

      You can see the gdiplus calls. PropertyItemInternal.ConvertFromMemory :

      nternal static System.Drawing.Imaging.PropertyItem[] ConvertFromMemory(IntPtr propdata, int count) {
      System.Drawing.Imaging.PropertyItem[] local0;
      int local1;
      PropertyItemInternal local2;

      local0 = new PropertyItem\[checked((uint) count)\];
      local1 = 0;
      while (local1 < count) {
      	local2 = (PropertyItemInternal) UnsafeNativeMethods.PtrToStructure(propdata, typeof(PropertyItemInternal));
      	local0\[local1\] = new PropertyItem();
      	local0\[local1\].Id = local2.id;
      	local0\[local1\].Len = local2.len;
      	local0\[local1\].Type = local2.type;
      	local0\[local1\].Value = local2.Value;
      	propdata = 20315E582031596Cop\_Explicit20315970
      

      20315E582031596Cop_Explicit20315970
      propdata20315968 + (long) Marshal.SizeOf(typeof(PropertyItemInternal))20315968;
      local1++;
      }
      return local0;
      }


      She's so dirty, she threw a boomerang and it wouldn't even come back.

      K 1 Reply Last reply
      0
      • S Stephane Rodriguez

        Here is the PropertyItem internal :

        public System.Drawing.Imaging.PropertyItem[] get_PropertyItems() {
        int local0;
        int local1;
        int local2;
        IntPtr local3;
        System.Drawing.Imaging.PropertyItem[] local4;

        local2 = SafeNativeMethods.GdipGetPropertyCount(this.nativeImage, local1);
        if (local2 != 0)
        	throw SafeNativeMethods.StatusException(local2);
        local2 = SafeNativeMethods.GdipGetPropertySize(this.nativeImage, local0, local1);
        if (local2 != 0)
        	throw SafeNativeMethods.StatusException(local2);
        if (local0 == 0 || local1 == 0)
        	return new PropertyItem\[0\];
        local3 = Marshal.AllocHGlobal(local0);
        local2 = SafeNativeMethods.GdipGetAllPropertyItems(this.nativeImage, local0, local1, local3);
        if (local2 != 0) {
        	Marshal.FreeHGlobal(local3);
        	throw SafeNativeMethods.StatusException(local2);
        }
        local4 = PropertyItemInternal.ConvertFromMemory(local3, local1);
        Marshal.FreeHGlobal(local3);
        GC.KeepAlive(this);
        return local4;
        

        }

        You can see the gdiplus calls. PropertyItemInternal.ConvertFromMemory :

        nternal static System.Drawing.Imaging.PropertyItem[] ConvertFromMemory(IntPtr propdata, int count) {
        System.Drawing.Imaging.PropertyItem[] local0;
        int local1;
        PropertyItemInternal local2;

        local0 = new PropertyItem\[checked((uint) count)\];
        local1 = 0;
        while (local1 < count) {
        	local2 = (PropertyItemInternal) UnsafeNativeMethods.PtrToStructure(propdata, typeof(PropertyItemInternal));
        	local0\[local1\] = new PropertyItem();
        	local0\[local1\].Id = local2.id;
        	local0\[local1\].Len = local2.len;
        	local0\[local1\].Type = local2.type;
        	local0\[local1\].Value = local2.Value;
        	propdata = 20315E582031596Cop\_Explicit20315970
        

        20315E582031596Cop_Explicit20315970
        propdata20315968 + (long) Marshal.SizeOf(typeof(PropertyItemInternal))20315968;
        local1++;
        }
        return local0;
        }


        She's so dirty, she threw a boomerang and it wouldn't even come back.

        K Offline
        K Offline
        Konstantin Vasserman
        wrote on last edited by
        #17

        Yes and here is my call stack:

        mscorlib.dll!System.Runtime.InteropServices.Marshal::Copy(__int32 source = 0, unsigned char[] destination = {Length=0},
        __int32 startIndex = 0, __int32 length = 0) + 0x26 bytes

        system.drawing.dll!System.Drawing.Imaging.PropertyItemInternal::get_Value() + 0x3d bytes

        system.drawing.dll!System.Drawing.Imaging.PropertyItemInternal::ConvertFromMemory(__int32 propdata = 1541584,
        __int32 count = 49) + 0x100 bytes

        system.drawing.dll!System.Drawing.Image::get_PropertyItems() + 0xe6 bytes

        Clearly 0 is being passed as an argument to Marshal::Copy(). There is some check is missing for IntPtr == null... Chris M. is going to ban us forever for posting all this programming stuff in the lounge... :-O

        S 1 Reply Last reply
        0
        • K Konstantin Vasserman

          I am sorry if this is the wrong place to post this question. I couldn't figure out what the best forum for it would be. I think that I've ran into a bug in .NET Framework and I would like to report it to MS together with some sample code and files. I cannot seem to figure out where to send this information. After clicking for a while thru all the microsoft.com "contact us" pages I am totally lost. Any help will be greatly appreciated. TIA. Kostya.

          C Offline
          C Offline
          Chris Maunder
          wrote on last edited by
          #18

          Try this[^]. Just send Nick all your bugs (VS.NET related, .NET framework related, your homework questions...). The more the merrier. cheers, Chris Maunder

          K C 2 Replies Last reply
          0
          • T Tim Smith

            Read Nick's Semicolon article. He talks about how to report bugs. Tim Smith "Programmers are always surrounded by complexity; we can not avoid it... If our basic tool, the language in which we design and code our programs, is also complicated, the language itself becomes part of the problem rather that part of the solution." Hoare - 1980 ACM Turing Award Lecture

            C Offline
            C Offline
            Christian Graus
            wrote on last edited by
            #19

            And it's pretty obvious that his article was needed, if support was so hard to find at the Microsoft site ( I don't know, I've never looked ) Christian Hey, at least Logo had, at it's inception, a mechanical turtle. VB has always lacked even that... - Shog9 04-09-2002 During last 10 years, with invention of VB and similar programming environments, every ill-educated moron became able to develop software. - Alex E. - 12-Sept-2002

            1 Reply Last reply
            0
            • C Chris Maunder

              Try this[^]. Just send Nick all your bugs (VS.NET related, .NET framework related, your homework questions...). The more the merrier. cheers, Chris Maunder

              K Offline
              K Offline
              Konstantin Vasserman
              wrote on last edited by
              #20

              Thank you. Now, where are those homework questions I had... :)

              1 Reply Last reply
              0
              • C Chris Maunder

                Try this[^]. Just send Nick all your bugs (VS.NET related, .NET framework related, your homework questions...). The more the merrier. cheers, Chris Maunder

                C Offline
                C Offline
                Christopher Duncan
                wrote on last edited by
                #21

                Chris Maunder wrote: Just send Nick all your bugs (VS.NET related, .NET framework related, your homework questions...). The more the merrier. Ooh, Nick's gonna get you for that one. Don't forget his blackmail threat in this month's column! Chistopher Duncan Author - The Career Programmer: Guerilla Tactics for an Imperfect World (Apress)

                1 Reply Last reply
                0
                • K Konstantin Vasserman

                  Yes and here is my call stack:

                  mscorlib.dll!System.Runtime.InteropServices.Marshal::Copy(__int32 source = 0, unsigned char[] destination = {Length=0},
                  __int32 startIndex = 0, __int32 length = 0) + 0x26 bytes

                  system.drawing.dll!System.Drawing.Imaging.PropertyItemInternal::get_Value() + 0x3d bytes

                  system.drawing.dll!System.Drawing.Imaging.PropertyItemInternal::ConvertFromMemory(__int32 propdata = 1541584,
                  __int32 count = 49) + 0x100 bytes

                  system.drawing.dll!System.Drawing.Image::get_PropertyItems() + 0xe6 bytes

                  Clearly 0 is being passed as an argument to Marshal::Copy(). There is some check is missing for IntPtr == null... Chris M. is going to ban us forever for posting all this programming stuff in the lounge... :-O

                  S Offline
                  S Offline
                  Stephane Rodriguez
                  wrote on last edited by
                  #22

                  Here is the code for get_Value() :

                  public byte[] get_Value() {
                  byte[] local0;

                  local0 = new Byte\[checked((uint) this.len)\];
                  Marshal.Copy(this.value, local0, 0, this.len);
                  return local0;
                  

                  }

                  Marshal.Copy does a simple low-level buffer copy, without ptr checking. That's the reason why there is the exception. In this case, both src ptr (null) and dest ptr (result of new [0], thus null) are wrong. Here are the actual members of the PropertyItemInternal class :

                  int id;
                  int len;
                  short type;
                  IntPtr value;

                  Now when you see what ConvertFromMemory does (it creates PropertyItemInternal instances from an input propdata structure), the problem comes from either of these : - you are accessing a non-existing propertyiteminternal - propdata is actually empty (file decoding completely or partially failed due to bad format). As a conclusion, this issue is not related to the .NET framework. Yes, MS could check the ptrs before they Copy memblocks. But in the end, it's more about you using the GDI+ API for an unknown file format.


                  She's so dirty, she threw a boomerang and it wouldn't even come back.

                  K 1 Reply Last reply
                  0
                  • S Stephane Rodriguez

                    Here is the code for get_Value() :

                    public byte[] get_Value() {
                    byte[] local0;

                    local0 = new Byte\[checked((uint) this.len)\];
                    Marshal.Copy(this.value, local0, 0, this.len);
                    return local0;
                    

                    }

                    Marshal.Copy does a simple low-level buffer copy, without ptr checking. That's the reason why there is the exception. In this case, both src ptr (null) and dest ptr (result of new [0], thus null) are wrong. Here are the actual members of the PropertyItemInternal class :

                    int id;
                    int len;
                    short type;
                    IntPtr value;

                    Now when you see what ConvertFromMemory does (it creates PropertyItemInternal instances from an input propdata structure), the problem comes from either of these : - you are accessing a non-existing propertyiteminternal - propdata is actually empty (file decoding completely or partially failed due to bad format). As a conclusion, this issue is not related to the .NET framework. Yes, MS could check the ptrs before they Copy memblocks. But in the end, it's more about you using the GDI+ API for an unknown file format.


                    She's so dirty, she threw a boomerang and it wouldn't even come back.

                    K Offline
                    K Offline
                    Konstantin Vasserman
                    wrote on last edited by
                    #23

                    __Stephane Rodriguez__ wrote: But in the end, it's more about you using the GDI+ API for an unknown file format. Yes and no. Format is not unknown and it was not like a change from EXIF ver. 1 to version 2 it was from 2.1 to 2.2. Beside that, some EXIF 2.2 files are read without a problem and I have just find out that people have seen the same problem with some of the older versions of EXIF as well. Now, that fact that it is not in .NET framework per se, but in underlying GDI+ makes it even more of a problem, because now it's not only affecting managed code developers and apps, but anybody who is using GDI+ including unmanaged C++ scenarios. I have reported this problem in one of the MS newsgroups last night. One of MS employees replied and asked for sample image. I have provided them with sample image and I am still waiting to hear back from them. In the mean time 2 or 3 other guys have reported that they have been experiencing the same problem together with couple of workarounds. I'll keep you posted. Thank you for looking into it. Kostya.

                    S 1 Reply Last reply
                    0
                    • K Konstantin Vasserman

                      __Stephane Rodriguez__ wrote: But in the end, it's more about you using the GDI+ API for an unknown file format. Yes and no. Format is not unknown and it was not like a change from EXIF ver. 1 to version 2 it was from 2.1 to 2.2. Beside that, some EXIF 2.2 files are read without a problem and I have just find out that people have seen the same problem with some of the older versions of EXIF as well. Now, that fact that it is not in .NET framework per se, but in underlying GDI+ makes it even more of a problem, because now it's not only affecting managed code developers and apps, but anybody who is using GDI+ including unmanaged C++ scenarios. I have reported this problem in one of the MS newsgroups last night. One of MS employees replied and asked for sample image. I have provided them with sample image and I am still waiting to hear back from them. In the mean time 2 or 3 other guys have reported that they have been experiencing the same problem together with couple of workarounds. I'll keep you posted. Thank you for looking into it. Kostya.

                      S Offline
                      S Offline
                      Stephane Rodriguez
                      wrote on last edited by
                      #24

                      Konstantin Vasserman wrote: because now it's not only affecting managed code developers and apps, but anybody who is using GDI+ including unmanaged C++ scenarios. If MS provides an interim gdiplus.dll release, then it will work in C++ AND .NET without updating .NET


                      She's so dirty, she threw a boomerang and it wouldn't even come back.

                      K 1 Reply Last reply
                      0
                      • S Stephane Rodriguez

                        Konstantin Vasserman wrote: because now it's not only affecting managed code developers and apps, but anybody who is using GDI+ including unmanaged C++ scenarios. If MS provides an interim gdiplus.dll release, then it will work in C++ AND .NET without updating .NET


                        She's so dirty, she threw a boomerang and it wouldn't even come back.

                        K Offline
                        K Offline
                        Konstantin Vasserman
                        wrote on last edited by
                        #25

                        True. There are always pros and cons to everything... ;)

                        1 Reply Last reply
                        0
                        Reply
                        • Reply as topic
                        Log in to reply
                        • Oldest to Newest
                        • Newest to Oldest
                        • Most Votes


                        • Login

                        • Don't have an account? Register

                        • Login or register to search.
                        • First post
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • World
                        • Users
                        • Groups