rtpjpegpay: fix image corruption when compiled with MSVC on Windows

On Windows with MSVC, jpeg_header_size would end up 2 bytes larger
than it should be. This then leads to the first 2 bytes of the
actual jpeg image data to be dropped, because we think those
belong to the header, which results in an undecodable image when
reconstructed in the depayloader.

What happens is that when the compiler evaluates

  jpeg_header_size = mem.offset + read_u16_and_inc_offset_by_2(&mem);

it actually uses the mem.offset value after it has been increased
by the function call on the right hand size of the equation.

From section 6.5 of the C99 spec:

  3. The grouping of operators and operands is indicated by the syntax [74].
     Except as specified later (for the function-call (), &&, ||, ?:, and
     comma operators), the order of evaluation of subexpressions and the
     order in which side effects take place are both unspecified.

Fixes https://gitlab.freedesktop.org/gstreamer/gst-plugins-good/-/issues/889

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-good/-/merge_requests/999>
This commit is contained in:
Tim-Philipp Müller 2021-05-29 12:54:22 +01:00
parent f4049fc292
commit aa4448cdd6

View file

@ -780,8 +780,9 @@ gst_rtp_jpeg_pay_handle_buffer (GstRTPBasePayload * basepayload,
case JPEG_MARKER_SOS:
sos_found = TRUE;
GST_LOG_OBJECT (pay, "SOS found");
jpeg_header_size =
memory.offset + parse_mem_inc_offset_guint16 (&memory);
jpeg_header_size = memory.offset;
/* Do not re-combine into single statement with previous line! */
jpeg_header_size += parse_mem_inc_offset_guint16 (&memory);
break;
case JPEG_MARKER_EOI:
GST_WARNING_OBJECT (pay, "EOI reached before SOS!");