Avoid p_stream->m_user_data_length >= (OPJ_UINT64)p_stream->m_byte_offset assertion...
authorEven Rouault <even.rouault@spatialys.com>
Sun, 30 Jul 2017 14:48:15 +0000 (16:48 +0200)
committerEven Rouault <even.rouault@spatialys.com>
Sun, 30 Jul 2017 14:48:15 +0000 (16:48 +0200)
src/lib/openjp2/cio.c
src/lib/openjp2/jp2.c

index 224fdbe20b02f407651b9844dd3e2dc024a1925a..4fde9fe239b12977badb31639a525a47cd4fb672 100644 (file)
@@ -496,6 +496,26 @@ OPJ_OFF_T opj_stream_read_skip(opj_stream_private_t * p_stream,
     }
 
     while (p_size > 0) {
+        /* Check if we are going beyond the end of file. Most skip_fn do not */
+        /* check that, but we must be careful not to advance m_byte_offset */
+        /* beyond m_user_data_length, otherwise */
+        /* opj_stream_get_number_byte_left() will assert. */
+        if ((OPJ_UINT64)(p_stream->m_byte_offset + l_skip_nb_bytes + p_size) >
+                p_stream->m_user_data_length) {
+            opj_event_msg(p_event_mgr, EVT_INFO, "Stream reached its end !\n");
+
+            p_stream->m_byte_offset += l_skip_nb_bytes;
+            l_skip_nb_bytes = (OPJ_OFF_T)(p_stream->m_user_data_length -
+                                          (OPJ_UINT64)p_stream->m_byte_offset);
+
+            opj_stream_read_seek(p_stream, (OPJ_OFF_T)p_stream->m_user_data_length,
+                                 p_event_mgr);
+            p_stream->m_status |= OPJ_STREAM_STATUS_END;
+
+            /* end if stream */
+            return l_skip_nb_bytes ? l_skip_nb_bytes : (OPJ_OFF_T) - 1;
+        }
+
         /* we should do an actual skip on the media */
         l_current_skip_nb_bytes = p_stream->m_skip_fn(p_size, p_stream->m_user_data);
         if (l_current_skip_nb_bytes == (OPJ_OFF_T) - 1) {
index 904265dab1a2aceea04ede77dee9005067c93b6a..66e058a261ebc72daca1d513c349603ec3ac1391 100644 (file)
@@ -2367,10 +2367,19 @@ static OPJ_BOOL opj_jp2_read_header_procedure(opj_jp2_t *jp2,
             jp2->jp2_state |= JP2_STATE_UNKNOWN;
             if (opj_stream_skip(stream, l_current_data_size,
                                 p_manager) != l_current_data_size) {
-                opj_event_msg(p_manager, EVT_ERROR,
-                              "Problem with skipping JPEG2000 box, stream error\n");
-                opj_free(l_current_data);
-                return OPJ_FALSE;
+                if (jp2->jp2_state & JP2_STATE_CODESTREAM) {
+                    /* If we already read the codestream, do not error out */
+                    /* Needed for data/input/nonregression/issue254.jp2 */
+                    opj_event_msg(p_manager, EVT_WARNING,
+                                  "Problem with skipping JPEG2000 box, stream error\n");
+                    opj_free(l_current_data);
+                    return OPJ_TRUE;
+                } else {
+                    opj_event_msg(p_manager, EVT_ERROR,
+                                  "Problem with skipping JPEG2000 box, stream error\n");
+                    opj_free(l_current_data);
+                    return OPJ_FALSE;
+                }
             }
         }
     }