In ImageMagick before 7.0.8-25, a memory leak exists in ReadSIXELImage in coders/sixel.c.
cpe:2.3:a:imagemagick:imagemagick:*:*:*:*:*:*:*:*
E982CE9C-89F7-4A5D-B036-A9A483493D5B
6.9.10-25
cpe:2.3:a:imagemagick:imagemagick:*:*:*:*:*:*:*:*
2F7DF2A1-ADDE-48C4-BD39-CCA15D0D767A
7.0.8-25
7.0.0-0
OR
cpe:2.3:o:opensuse:leap:15.0:*:*:*:*:*:*:*
F1E78106-58E6-4D59-990F-75DA575BFAD9
OR
cpe:2.3:o:debian:debian_linux:10.0:*:*:*:*:*:*:*
07B237A9-69A3-4A9C-9DA0-4E06BD37AE73
OR
cpe:2.3:o:canonical:ubuntu_linux:16.04:*:*:*:lts:*:*:*
F7016A2A-8365-4F1A-89A2-7A19F2BCAE5B
cpe:2.3:o:canonical:ubuntu_linux:18.04:*:*:*:lts:*:*:*
23A7C53F-B80F-4E6A-AFA9-58EEA84BE11D
cpe:2.3:o:canonical:ubuntu_linux:18.10:*:*:*:*:*:*:*
07C312A0-CD2C-4B9C-B064-6409B25C278F
cpe:2.3:o:canonical:ubuntu_linux:19.04:*:*:*:*:*:*:*
CD783B0C-9246-47D9-A937-6144FE8BFF0F
OR
### Prerequisites

- [x] I have written a descriptive issue title
- [x] I have verified that I am using the latest version of ImageMagick
- [x] I have searched [open](https://github.com/ImageMagick/ImageMagick/issues) and [closed](https://github.com/ImageMagick/ImageMagick/issues?q=is%3Aissue+is%3Aclosed) issues to ensure it has not already been reported

### Description
<!-- A description of the bug or feature -->
potential memory leak in ReadSIXELImage in sixel.c
### Steps to Reproduce
<!-- List of steps, sample code, failing test or link to a project that reproduces the behavior.
     Make sure you place a stack trace inside a code (```) block to avoid linking unrelated issues -->
The first critical code snippet is:
https://github.com/ImageMagick/ImageMagick/blob/master/coders/sixel.c#L539
```c
if (imsx > max_x || imsy > max_y) { // line 539
        dmsx = max_x;
        dmsy = max_y;
        if (SetImageExtent(image,dmsx,dmsy,exception) == MagickFalse)
          {
            imbuf = (unsigned char *) RelinquishMagickMemory(imbuf);
            return (MagickFalse);
          }
        if ((dmbuf = (unsigned char *) AcquireQuantumMemory(dmsx , dmsy)) == NULL) { //line 547
            imbuf = (unsigned char *) RelinquishMagickMemory(imbuf);
            return (MagickFalse);
        }
        for (y = 0; y < dmsy; ++y) {
            (void) memcpy(dmbuf + dmsx * y, imbuf + imsx * y, dmsx);
        }
        imbuf = (unsigned char *) RelinquishMagickMemory(imbuf);
        imsx = dmsx;
        imsy = dmsy;
        imbuf = dmbuf;  //line 557
    }

    *pixels = imbuf;  //line 560
    *pwidth = imsx;
    *pheight = imsy;
    *ncolors = max_color_index + 1;
    *palette = (unsigned char *) AcquireQuantumMemory(*ncolors,4); // line 564
    if (*palette == (unsigned char *) NULL)
      return(MagickFalse);     // line 566
```
When condition at line **539** is satisfied and **dmbuf** is successfully allocated at line **547**, the value of dmbuf is assigned to **imbuf** at line **557** and is finally assigned to the pointer parameter **pixels** at line **560** (i.e. the buf's address is passed outside to the caller function). 

Now, when the allocation at line **564** failed, the function will return *MagickFalse* at line **566**.

Next, I searched the whole project code and only found one call to **sixel_decode** which locates in function **ReadSIXELImage** in sixel.c at line **1057** as the following. The local variable **sixel_pixels** holds the value of **dmbuf**.
https://github.com/ImageMagick/ImageMagick/blob/master/coders/sixel.c#L1057
```c
if (sixel_decode(image,(unsigned char *) sixel_buffer,&sixel_pixels,&image->columns,&image->rows,&sixel_palette,&image->colors,exception) == MagickFalse)  // line 1057
    {
      sixel_buffer=(char *) RelinquishMagickMemory(sixel_buffer);
      ThrowReaderException(CorruptImageError,"CorruptImage");
    }
  sixel_buffer=(char *) RelinquishMagickMemory(sixel_buffer);
  image->depth=24;
  image->storage_class=PseudoClass;
  status=SetImageExtent(image,image->columns,image->rows,exception);
  if (status == MagickFalse)
    {
      sixel_pixels=(unsigned char *) RelinquishMagickMemory(sixel_pixels);  // line 1068
      sixel_palette=(unsigned char *) RelinquishMagickMemory(sixel_palette);
      return(DestroyImageList(image));
    }
```
However, when function *sixel_decode* returned *MagickFalse* as described above, the memory pointed by **sixel_pixels** (i.e. the memory allocated at line 547) was not freed as done at line **1068**. As a result, a memory leak happens.

Patch Suggestion:
```c
if (sixel_decode(image,(unsigned char *) sixel_buffer,&sixel_pixels,&image->columns,&image->rows,&sixel_palette,&image->colors,exception) == MagickFalse)
    {
      sixel_buffer=(char *) RelinquishMagickMemory(sixel_buffer);
+     sixel_pixels=(unsigned char *) RelinquishMagickMemory(sixel_pixels);
      ThrowReaderException(CorruptImageError,"CorruptImage");
    }
``` 

### System Configuration
<!-- Tell us about the environment where you are experiencing the bug -->

- ImageMagick version: ImageMagick-4f0ea40e2a090e245f31d1f05247520d6e7eb4ca
- Environment (Operating system, version and so on): Ubuntu 16.04
- Additional information: 

<!-- Thanks for reporting the issue to ImageMagick! -->
Credit to Bingchang Liu at VARAS of IIE
Potential Memory Leak in ReadSIXELImage in coders/sixel.c
This is a GitHub Issue
repo:ImageMagick
owner:ImageMagick
Title : Potential Memory Leak in ReadSIXELImage in coders/sixel.c
Issue date:

--- start body ---
### Prerequisites

- [x] I have written a descriptive issue title
- [x] I have verified that I am using the latest version of ImageMagick
- [x] I have searched [open](https://github.com/ImageMagick/ImageMagick/issues) and [closed](https://github.com/ImageMagick/ImageMagick/issues?q=is%3Aissue+is%3Aclosed) issues to ensure it has not already been reported

### Description
<!-- A description of the bug or feature -->
potential memory leak in ReadSIXELImage in sixel.c
### Steps to Reproduce
<!-- List of steps, sample code, failing test or link to a project that reproduces the behavior.
     Make sure you place a stack trace inside a code (```) block to avoid linking unrelated issues -->
The first critical code snippet is:
https://github.com/ImageMagick/ImageMagick/blob/master/coders/sixel.c#L539
```c
if (imsx > max_x || imsy > max_y) { // line 539
        dmsx = max_x;
        dmsy = max_y;
        if (SetImageExtent(image,dmsx,dmsy,exception) == MagickFalse)
          {
            imbuf = (unsigned char *) RelinquishMagickMemory(imbuf);
            return (MagickFalse);
          }
        if ((dmbuf = (unsigned char *) AcquireQuantumMemory(dmsx , dmsy)) == NULL) { //line 547
            imbuf = (unsigned char *) RelinquishMagickMemory(imbuf);
            return (MagickFalse);
        }
        for (y = 0; y < dmsy; ++y) {
            (void) memcpy(dmbuf + dmsx * y, imbuf + imsx * y, dmsx);
        }
        imbuf = (unsigned char *) RelinquishMagickMemory(imbuf);
        imsx = dmsx;
        imsy = dmsy;
        imbuf = dmbuf;  //line 557
    }

    *pixels = imbuf;  //line 560
    *pwidth = imsx;
    *pheight = imsy;
    *ncolors = max_color_index + 1;
    *palette = (unsigned char *) AcquireQuantumMemory(*ncolors,4); // line 564
    if (*palette == (unsigned char *) NULL)
      return(MagickFalse);     // line 566
```
When condition at line **539** is satisfied and **dmbuf** is successfully allocated at line **547**, the value of dmbuf is assigned to **imbuf** at line **557** and is finally assigned to the pointer parameter **pixels** at line **560** (i.e. the buf's address is passed outside to the caller function). 

Now, when the allocation at line **564** failed, the function will return *MagickFalse* at line **566**.

Next, I searched the whole project code and only found one call to **sixel_decode** which locates in function **ReadSIXELImage** in sixel.c at line **1057** as the following. The local variable **sixel_pixels** holds the value of **dmbuf**.
https://github.com/ImageMagick/ImageMagick/blob/master/coders/sixel.c#L1057
```c
if (sixel_decode(image,(unsigned char *) sixel_buffer,&sixel_pixels,&image->columns,&image->rows,&sixel_palette,&image->colors,exception) == MagickFalse)  // line 1057
    {
      sixel_buffer=(char *) RelinquishMagickMemory(sixel_buffer);
      ThrowReaderException(CorruptImageError,"CorruptImage");
    }
  sixel_buffer=(char *) RelinquishMagickMemory(sixel_buffer);
  image->depth=24;
  image->storage_class=PseudoClass;
  status=SetImageExtent(image,image->columns,image->rows,exception);
  if (status == MagickFalse)
    {
      sixel_pixels=(unsigned char *) RelinquishMagickMemory(sixel_pixels);  // line 1068
      sixel_palette=(unsigned char *) RelinquishMagickMemory(sixel_palette);
      return(DestroyImageList(image));
    }
```
However, when function *sixel_decode* returned *MagickFalse* as described above, the memory pointed by **sixel_pixels** (i.e. the memory allocated at line 547) was not freed as done at line **1068**. As a result, a memory leak happens.

Patch Suggestion:
```c
if (sixel_decode(image,(unsigned char *) sixel_buffer,&sixel_pixels,&image->columns,&image->rows,&sixel_palette,&image->colors,exception) == MagickFalse)
    {
      sixel_buffer=(char *) RelinquishMagickMemory(sixel_buffer);
+     sixel_pixels=(unsigned char *) RelinquishMagickMemory(sixel_pixels);
      ThrowReaderException(CorruptImageError,"CorruptImage");
    }
``` 

### System Configuration
<!-- Tell us about the environment where you are experiencing the bug -->

- ImageMagick version: ImageMagick-4f0ea40e2a090e245f31d1f05247520d6e7eb4ca
- Environment (Operating system, version and so on): Ubuntu 16.04
- Additional information: 

<!-- Thanks for reporting the issue to ImageMagick! -->
Credit to Bingchang Liu at VARAS of IIE
--- end body ---

comments :
--- start comments ---

--- end comments ---