226231
diff --git a/pngrutil.c b/pngrutil.c
226231
index 4ef05fe..f6f0864 100644
226231
--- a/pngrutil.c
226231
+++ b/pngrutil.c
226231
@@ -596,7 +596,7 @@ void /* PRIVATE */
226231
 png_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
226231
 {
226231
    png_color palette[PNG_MAX_PALETTE_LENGTH];
226231
-   int num, i;
226231
+   int max_palette_length, num, i;
226231
 #ifdef PNG_POINTER_INDEXING_SUPPORTED
226231
    png_colorp pal_ptr;
226231
 #endif
226231
@@ -648,9 +648,21 @@ png_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
226231
          png_error(png_ptr, "Invalid palette chunk");
226231
       }
226231
    }
226231
-
226231
+   /* The cast is safe because 'length' is less than 3*PNG_MAX_PALETTE_LENGTH */
226231
    num = (int)length / 3;
226231
 
226231
+   /* If the palette has 256 or fewer entries but is too large for the bit
226231
+    * depth, we don't issue an error, to preserve the behavior of previous
226231
+    * libpng versions. We silently truncate the unused extra palette entries
226231
+    * here.
226231
+    */
226231
+   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
226231
+      max_palette_length = (1 << png_ptr->bit_depth);
226231
+   else
226231
+      max_palette_length = PNG_MAX_PALETTE_LENGTH;
226231
+   if (num > max_palette_length)
226231
+      num = max_palette_length;
226231
+
226231
 #ifdef PNG_POINTER_INDEXING_SUPPORTED
226231
    for (i = 0, pal_ptr = palette; i < num; i++, pal_ptr++)
226231
    {
226231
@@ -683,7 +695,7 @@ png_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
226231
    if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
226231
 #endif
226231
    {
226231
-      png_crc_finish(png_ptr, 0);
226231
+      png_crc_finish(png_ptr, (int) length - num * 3);
226231
    }
226231
 
226231
 #ifndef PNG_READ_OPT_PLTE_SUPPORTED
226231
diff --git a/pngset.c b/pngset.c
226231
index 8e3f39a..c252088 100644
226231
--- a/pngset.c
226231
+++ b/pngset.c
226231
@@ -517,13 +517,17 @@ png_set_PLTE(png_structp png_ptr, png_infop info_ptr,
226231
     png_const_colorp palette, int num_palette)
226231
 {
226231
 
226231
+   png_uint_32 max_palette_length;
226231
+
226231
    png_debug1(1, "in %s storage function", "PLTE");
226231
 
226231
    if (png_ptr == NULL || info_ptr == NULL)
226231
       return;
226231
 
226231
-   if (num_palette < 0 || num_palette > PNG_MAX_PALETTE_LENGTH)
226231
-   {
226231
+   max_palette_length = (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ?
226231
+      (1 << info_ptr->bit_depth) : PNG_MAX_PALETTE_LENGTH;
226231
+
226231
+   if (num_palette < 0 || num_palette > (int) max_palette_length)   {
226231
       if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
226231
          png_error(png_ptr, "Invalid palette length");
226231
 
226231
@@ -551,8 +555,8 @@ png_set_PLTE(png_structp png_ptr, png_infop info_ptr,
226231
    png_free_data(png_ptr, info_ptr, PNG_FREE_PLTE, 0);
226231
 
226231
    /* Changed in libpng-1.2.1 to allocate PNG_MAX_PALETTE_LENGTH instead
226231
-    * of num_palette entries, in case of an invalid PNG file that has
226231
-    * too-large sample values.
226231
+    * of num_palette entries, in case of an invalid PNG file or incorrect
226231
+    * call to png_set_PLTE() with too-large sample values.
226231
     */
226231
    png_ptr->palette = (png_colorp)png_calloc(png_ptr,
226231
        PNG_MAX_PALETTE_LENGTH * png_sizeof(png_color));
226231
diff --git a/pngwutil.c b/pngwutil.c
226231
index 19b75af..7ecaaca 100644
226231
--- a/pngwutil.c
226231
+++ b/pngwutil.c
226231
@@ -896,17 +896,20 @@ void /* PRIVATE */
226231
 png_write_PLTE(png_structp png_ptr, png_const_colorp palette,
226231
     png_uint_32 num_pal)
226231
 {
226231
-   png_uint_32 i;
226231
+   png_uint_32 max_palette_length, i;
226231
    png_const_colorp pal_ptr;
226231
    png_byte buf[3];
226231
 
226231
+   max_palette_length = (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ?
226231
+      (1 << png_ptr->bit_depth) : PNG_MAX_PALETTE_LENGTH;
226231
+
226231
    png_debug(1, "in png_write_PLTE");
226231
 
226231
    if ((
226231
 #ifdef PNG_MNG_FEATURES_SUPPORTED
226231
        !(png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) &&
226231
 #endif
226231
-       num_pal == 0) || num_pal > 256)
226231
+       num_pal == 0) || num_pal > max_palette_length)
226231
    {
226231
       if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
226231
       {