From 1046b87e440fb188cab2309646bbc9e7190026c6 Mon Sep 17 00:00:00 2001 From: Brian Pepple Date: Apr 10 2008 23:01:55 +0000 Subject: - Add patch to fix memory overwrite error. (#441614) --- diff --git a/swfdec-alsa.patch b/swfdec-alsa.patch new file mode 100644 index 0000000..202fbfd --- /dev/null +++ b/swfdec-alsa.patch @@ -0,0 +1,117 @@ +diff --git a/swfdec-gtk/swfdec_playback_alsa.c b/swfdec-gtk/swfdec_playback_alsa.c +index bddd189..9d1a8f7 100644 +--- a/swfdec-gtk/swfdec_playback_alsa.c ++++ b/swfdec-gtk/swfdec_playback_alsa.c +@@ -47,14 +47,16 @@ struct _SwfdecPlayback { + GMainContext * context; /* context we work in */ + }; + +-typedef struct { ++typedef struct _Stream Stream; ++struct _Stream { + SwfdecPlayback * sound; /* reference to sound object */ + SwfdecAudio * audio; /* the audio we play back */ + snd_pcm_t * pcm; /* the pcm we play back to */ + GSource ** sources; /* sources for writing data */ + guint n_sources; /* number of sources */ + guint offset; /* offset into sound */ +-} Stream; ++ gboolean (* write) (Stream *); ++}; + + #define ALSA_TRY(func,msg) G_STMT_START{ \ + int err = func; \ +@@ -90,7 +92,7 @@ write_player (Stream *stream, const snd_pcm_channel_area_t *dst, + } + + static gboolean +-try_write (Stream *stream) ++try_write_mmap (Stream *stream) + { + snd_pcm_sframes_t avail_result; + snd_pcm_uframes_t offset, avail; +@@ -117,6 +119,31 @@ try_write (Stream *stream) + return TRUE; + } + ++static gboolean ++try_write_so_pa_gets_it (Stream *stream) ++{ ++#define STEP 1024 ++ snd_pcm_sframes_t avail, step; ++ avail = snd_pcm_avail_update (stream->pcm); ++ ALSA_ERROR (avail, "snd_pcm_avail_update failed", FALSE); ++ ++ while (avail > 0) { ++ gint16 data[2 * STEP] = { 0, }; ++ ++ step = MIN (avail, STEP); ++ swfdec_audio_render (stream->audio, data, stream->offset, step); ++ step = snd_pcm_writei (stream->pcm, data, step); ++ ALSA_ERROR (step, "snd_pcm_writei failed", FALSE); ++ avail -= step; ++ stream->offset += step; ++ } ++ ++ return TRUE; ++#undef STEP ++} ++ ++#define try_write(stream) ((stream)->write (stream)) ++ + static void + swfdec_playback_stream_remove_handlers (Stream *stream) + { +@@ -141,10 +168,10 @@ handle_stream (GIOChannel *source, GIOCondition cond, gpointer data) + state = snd_pcm_state (stream->pcm); + if (state != SND_PCM_STATE_RUNNING) { + swfdec_playback_stream_start (stream); ++ return TRUE; + } else { +- try_write (stream); ++ return try_write (stream); + } +- return TRUE; + } + + static void +@@ -185,7 +212,9 @@ swfdec_playback_stream_start (Stream *stream) + stream->offset = 0; + //g_print ("offset: %u (delay: %ld)\n", sound->offset, delay); + if (try_write (stream)) { +- ALSA_ERROR (snd_pcm_start (stream->pcm), "error starting",); ++ if (stream->write == try_write_mmap) { ++ ALSA_ERROR (snd_pcm_start (stream->pcm), "error starting",); ++ } + swfdec_playback_stream_install_handlers (stream); + } + break; +@@ -208,6 +237,7 @@ swfdec_playback_stream_open (SwfdecPlayback *sound, SwfdecAudio *audio) + snd_pcm_hw_params_t *hw_params; + guint rate; + snd_pcm_uframes_t uframes; ++ gboolean (* try_write) (Stream *); + + /* "default" uses dmix, and dmix ticks way slow, so this thingy here stutters */ + ALSA_ERROR (snd_pcm_open (&ret, "default", SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK), +@@ -218,7 +248,11 @@ swfdec_playback_stream_open (SwfdecPlayback *sound, SwfdecAudio *audio) + g_printerr ("No sound format available\n"); + return; + } +- if (snd_pcm_hw_params_set_access (ret, hw_params, SND_PCM_ACCESS_MMAP_INTERLEAVED) < 0) { ++ if (snd_pcm_hw_params_set_access (ret, hw_params, SND_PCM_ACCESS_MMAP_INTERLEAVED) >= 0) { ++ try_write = try_write_mmap; ++ } else if (snd_pcm_hw_params_set_access (ret, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED) >= 0) { ++ try_write = try_write_so_pa_gets_it; ++ } else { + g_printerr ("Failed setting access\n"); + goto fail; + } +@@ -252,6 +286,7 @@ swfdec_playback_stream_open (SwfdecPlayback *sound, SwfdecAudio *audio) + } + #endif + stream = g_new0 (Stream, 1); ++ stream->write = try_write; + stream->sound = sound; + stream->audio = g_object_ref (audio); + stream->pcm = ret; diff --git a/swfdec-memory-overwrite.patch b/swfdec-memory-overwrite.patch new file mode 100644 index 0000000..7cd1810 --- /dev/null +++ b/swfdec-memory-overwrite.patch @@ -0,0 +1,188 @@ +From a126ae9d57e0729ac758b76b4dba415a04a9221f Mon Sep 17 00:00:00 2001 +From: Benjamin Otte +Date: Thu, 10 Apr 2008 22:41:32 +0200 +Subject: [PATCH] fix memory overwrite error that could lead to segfaults + +https://bugzilla.redhat.com/show_bug.cgi?id=441614 +--- + swfdec/swfdec_image.c | 111 ++++++++++++------------------------------------ + 1 files changed, 28 insertions(+), 83 deletions(-) + +diff --git a/swfdec/swfdec_image.c b/swfdec/swfdec_image.c +index b4bff6c..fc54511 100644 +--- a/swfdec/swfdec_image.c ++++ b/swfdec/swfdec_image.c +@@ -37,9 +37,6 @@ static const cairo_user_data_key_t key; + + static void merge_alpha (SwfdecImage * image, unsigned char *image_data, + unsigned char *alpha); +-static void swfdec_image_colormap_decode (SwfdecImage * image, +- unsigned char *dest, +- unsigned char *src, unsigned char *colormap, int colormap_len); + + G_DEFINE_TYPE (SwfdecImage, swfdec_image, SWFDEC_TYPE_CACHED) + +@@ -321,7 +318,6 @@ static void + swfdec_image_lossless_load (SwfdecImage *image) + { + int format; +- guint color_table_size; + unsigned char *ptr; + SwfdecBits bits; + guint8 *data; +@@ -335,16 +331,10 @@ swfdec_image_lossless_load (SwfdecImage *image) + SWFDEC_LOG (" width = %d", image->width); + image->height = swfdec_bits_get_u16 (&bits); + SWFDEC_LOG (" height = %d", image->height); +- if (format == 3) { +- color_table_size = swfdec_bits_get_u8 (&bits) + 1; +- } else { +- color_table_size = 0; +- } + + SWFDEC_LOG ("format = %d", format); + SWFDEC_LOG ("width = %d", image->width); + SWFDEC_LOG ("height = %d", image->height); +- SWFDEC_LOG ("color_table_size = %d", color_table_size); + + if (image->width == 0 || image->height == 0) + return; +@@ -352,63 +342,55 @@ swfdec_image_lossless_load (SwfdecImage *image) + + if (format == 3) { + SwfdecBuffer *buffer; +- unsigned char *indexed_data; +- guint i; ++ guchar *indexed_data; ++ guint32 palette[256], *pixels; ++ guint i, j; ++ guint palette_size; + guint rowstride = (image->width + 3) & ~3; + ++ palette_size = swfdec_bits_get_u8 (&bits) + 1; ++ SWFDEC_LOG ("palette_size = %d", palette_size); ++ + data = g_malloc (4 * image->width * image->height); + + if (have_alpha) { +- buffer = swfdec_bits_decompress (&bits, -1, color_table_size * 4 + rowstride * image->height); ++ buffer = swfdec_bits_decompress (&bits, -1, palette_size * 4 + rowstride * image->height); + if (buffer == NULL) { + SWFDEC_ERROR ("failed to decompress data"); + memset (data, 0, 4 * image->width * image->height); + goto out; + } + ptr = buffer->data; +- for (i = 0; i < color_table_size; i++) { +-#if G_BYTE_ORDER == G_LITTLE_ENDIAN +- guint8 tmp = ptr[i * 4 + 0]; +- ptr[i * 4 + 0] = ptr[i * 4 + 2]; +- ptr[i * 4 + 2] = tmp; +-#else +- guint8 tmp = ptr[i * 4 + 3]; +- ptr[i * 4 + 3] = ptr[i * 4 + 2]; +- ptr[i * 4 + 2] = ptr[i * 4 + 1]; +- ptr[i * 4 + 1] = ptr[i * 4 + 0]; +- ptr[i * 4 + 0] = tmp; +-#endif ++ for (i = 0; i < palette_size; i++) { ++ palette[i] = SWFDEC_COLOR_COMBINE (ptr[i * 4 + 0], ptr[i * 4 + 1], ++ ptr[i * 4 + 2], ptr[i * 4 + 3]); + } +- indexed_data = ptr + color_table_size * 4; ++ indexed_data = ptr + palette_size * 4; + } else { +- buffer = swfdec_bits_decompress (&bits, -1, color_table_size * 3 + rowstride * image->height); ++ buffer = swfdec_bits_decompress (&bits, -1, palette_size * 3 + rowstride * image->height); + if (buffer == NULL) { + SWFDEC_ERROR ("failed to decompress data"); + memset (data, 0, 4 * image->width * image->height); + goto out; + } + ptr = buffer->data; +- for (i = color_table_size - 1; i < color_table_size; i--) { +- guint8 color[3]; +- color[0] = ptr[i * 3 + 0]; +- color[1] = ptr[i * 3 + 1]; +- color[2] = ptr[i * 3 + 2]; +-#if G_BYTE_ORDER == G_LITTLE_ENDIAN +- ptr[i * 4 + 0] = color[2]; +- ptr[i * 4 + 1] = color[1]; +- ptr[i * 4 + 2] = color[0]; +- ptr[i * 4 + 3] = 255; +-#else +- ptr[i * 4 + 0] = 255; +- ptr[i * 4 + 1] = color[0]; +- ptr[i * 4 + 2] = color[1]; +- ptr[i * 4 + 3] = color[2]; +-#endif ++ for (i = 0; i < palette_size; i++) { ++ palette[i] = SWFDEC_COLOR_COMBINE (ptr[i * 3 + 0], ++ ptr[i * 3 + 1], ptr[i * 3 + 2], 0xFF); ++ } ++ indexed_data = ptr + palette_size * 3; ++ } ++ if (palette_size < 256) ++ memset (palette + palette_size, 0, (256 - palette_size) * 4); ++ ++ pixels = (guint32 *) data; ++ for (j = 0; j < (guint) image->height; j++) { ++ for (i = 0; i < (guint) image->width; i++) { ++ *pixels = palette[indexed_data[i]]; ++ pixels++; + } +- indexed_data = ptr + color_table_size * 3; ++ indexed_data += rowstride; + } +- swfdec_image_colormap_decode (image, data, indexed_data, +- ptr, color_table_size); + + swfdec_buffer_unref (buffer); + } else if (format == 4) { +@@ -525,43 +507,6 @@ tag_func_define_bits_lossless_2 (SwfdecSwfDecoder * s, guint tag) + return SWFDEC_STATUS_OK; + } + +-static void +-swfdec_image_colormap_decode (SwfdecImage * image, +- unsigned char *dest, +- unsigned char *src, unsigned char *colormap, int colormap_len) +-{ +- int c; +- int i; +- int j; +- int rowstride; +- +- rowstride = (image->width + 3) & ~0x3; +- SWFDEC_DEBUG ("rowstride %d", rowstride); +- +- for (j = 0; j < image->height; j++) { +- for (i = 0; i < image->width; i++) { +- c = src[i]; +- if (colormap_len < 256 && c == 255) { +- dest[0] = 0; +- dest[1] = 0; +- dest[2] = 0; +- dest[3] = 0; +- } else if (c >= colormap_len) { +- SWFDEC_ERROR ("colormap index out of range (%d>=%d) (%d,%d)", +- c, colormap_len, i, j); +- dest[0] = 0; +- dest[1] = 0; +- dest[2] = 0; +- dest[3] = 0; +- } else { +- memmove (dest, &colormap[c*4], 4); +- } +- dest += 4; +- } +- src += rowstride; +- } +-} +- + static cairo_status_t + swfdec_image_png_read (void *bitsp, unsigned char *data, unsigned int length) + { +-- +1.5.4.5 + diff --git a/swfdec.spec b/swfdec.spec index 31bc6f9..b1789c8 100644 --- a/swfdec.spec +++ b/swfdec.spec @@ -5,16 +5,19 @@ Name: swfdec Version: %{major_version}.4 -Release: 2%{?dist} +Release: 3%{?dist} Summary: Flash animation rendering library Group: System Environment/Libraries License: LGPLv2+ URL: http://swfdec.freedesktop.org/ Source0: http://swfdec.freedesktop.org/download/%{name}/%{major_version}/%{name}-%{version}.tar.gz +Patch0: %{name}-alsa.patch +Patch1: %{name}-memory-overwrite.patch BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) -BuildRequires: pulseaudio-libs-devel +BuildRequires: alsa-lib-devel +#BuildRequires: pulseaudio-libs-devel BuildRequires: glib2-devel >= 2.16 BuildRequires: gstreamer-devel >= 0.10.11 BuildRequires: gstreamer-plugins-base-devel >= 0.10.15 @@ -75,10 +78,12 @@ files necessary to build packages and appplications that use %{name}-gtk. %prep %setup -q +%patch0 -p1 -b .alsa +%patch1 -p1 -b .memory %build -%configure --disable-static --with-audio=pa +%configure --disable-static --with-audio=alsa # remove rpath from libtool sed -i.rpath 's|^hardcode_libdir_flag_spec=.*|hardcode_libdir_flag_spec=""|g' libtool @@ -158,7 +163,12 @@ fi %changelog -* Wed Apr 9 2008 Brian Pepple - 0.6.4-2 +* Thu Apr 10 2008 Brian Pepple - 0.6.4-3 +- Add patch to fix memory overwrite error. (#441614) + +* Thu Apr 10 2008 Brian Pepple - 0.6.4-2 +- Build w/ alsa backend instead of pulse audio. +- Add patch to fix alsa support. (#441617). - Drop unnecessary BR on js-devel and gnome-vfs2-devel. - Add BR on glib2-devel.