Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 4 Aug 2019 06:43:17 +0000 (UTC)
From:      Roman Bogorodskiy <novel@FreeBSD.org>
To:        ports-committers@freebsd.org, svn-ports-all@freebsd.org, svn-ports-head@freebsd.org
Subject:   svn commit: r508062 - in head/audio/easytag: . files
Message-ID:  <201908040643.x746hHwn038024@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: novel
Date: Sun Aug  4 06:43:17 2019
New Revision: 508062
URL: https://svnweb.freebsd.org/changeset/ports/508062

Log:
  audio/easytag: fix vorbis file corruption
  
  Tagging vorbis files with EasyTag results in corrupted files, as reported in
  https://bugzilla.gnome.org/show_bug.cgi?id=776110. Apply a fix from
  https://build.opensuse.org/request/show/596947 to overcome the issue.
  
  Reported by:	tj@mrsk.me
  Obtained from:	openSUSE

Added:
  head/audio/easytag/files/patch-src_tags_vcedit.c   (contents, props changed)
Modified:
  head/audio/easytag/Makefile

Modified: head/audio/easytag/Makefile
==============================================================================
--- head/audio/easytag/Makefile	Sun Aug  4 06:25:36 2019	(r508061)
+++ head/audio/easytag/Makefile	Sun Aug  4 06:43:17 2019	(r508062)
@@ -3,7 +3,7 @@
 
 PORTNAME=	easytag
 PORTVERSION=	2.4.3
-PORTREVISION=	2
+PORTREVISION=	3
 CATEGORIES=	audio
 MASTER_SITES=	GNOME
 

Added: head/audio/easytag/files/patch-src_tags_vcedit.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/audio/easytag/files/patch-src_tags_vcedit.c	Sun Aug  4 06:43:17 2019	(r508062)
@@ -0,0 +1,230 @@
+--- src/tags/vcedit.c.orig	2016-11-09 17:47:09 UTC
++++ src/tags/vcedit.c
+@@ -35,6 +35,7 @@
+ struct _EtOggState
+ {
+     /*< private >*/
++    GFileInputStream *in;
+ #ifdef ENABLE_SPEEX
+     SpeexHeader *si;
+ #endif
+@@ -125,6 +126,11 @@ vcedit_clear_internals (EtOggState *state)
+     }
+ #endif /* ENABLE_OPUS */
+ 
++    if (state->in)
++    {
++        g_object_unref (state->in);
++    }
++
+     memset (state, 0, sizeof (*state));
+ }
+ 
+@@ -239,7 +245,6 @@ _blocksize (EtOggState *s,
+ 
+ static gboolean
+ _fetch_next_packet (EtOggState *s,
+-                    GInputStream *istream,
+                     ogg_packet *p,
+                     ogg_page *page,
+                     GError **error)
+@@ -269,8 +274,8 @@ _fetch_next_packet (EtOggState *s,
+         while (ogg_sync_pageout (s->oy, page) <= 0)
+         {
+             buffer = ogg_sync_buffer (s->oy, CHUNKSIZE);
+-            bytes = g_input_stream_read (istream, buffer, CHUNKSIZE, NULL,
+-                                         error);
++            bytes = g_input_stream_read (G_INPUT_STREAM (s->in), buffer,
++                                         CHUNKSIZE, NULL, error);
+             ogg_sync_wrote (s->oy, bytes);
+ 
+             if(bytes == 0)
+@@ -303,7 +308,7 @@ _fetch_next_packet (EtOggState *s,
+ 
+         g_assert (error == NULL || *error == NULL);
+         ogg_stream_pagein (s->os, page);
+-        return _fetch_next_packet (s, istream, p, page, error);
++        return _fetch_next_packet (s, p, page, error);
+     }
+ }
+ 
+@@ -402,13 +407,14 @@ vcedit_open (EtOggState *state,
+         return FALSE;
+     }
+ 
++    state->in = istream;
+     state->oy = g_slice_new (ogg_sync_state);
+     ogg_sync_init (state->oy);
+ 
+     while(1)
+     {
+         buffer = ogg_sync_buffer (state->oy, CHUNKSIZE);
+-        bytes = g_input_stream_read (G_INPUT_STREAM (istream), buffer,
++        bytes = g_input_stream_read (G_INPUT_STREAM (state->in), buffer,
+                                      CHUNKSIZE, NULL, error);
+         if (bytes == -1)
+         {
+@@ -648,7 +654,7 @@ vcedit_open (EtOggState *state,
+         }
+ 
+         buffer = ogg_sync_buffer (state->oy, CHUNKSIZE);
+-        bytes = g_input_stream_read (G_INPUT_STREAM (istream), buffer,
++        bytes = g_input_stream_read (G_INPUT_STREAM (state->in), buffer,
+                                      CHUNKSIZE, NULL, error);
+ 
+         if (bytes == -1)
+@@ -670,14 +676,11 @@ vcedit_open (EtOggState *state,
+ 
+     /* Headers are done! */
+     g_assert (error == NULL || *error == NULL);
+-    /* TODO: Handle error during stream close. */
+-    g_object_unref (istream);
+ 
+     return TRUE;
+ 
+ err:
+     g_assert (error == NULL || *error != NULL);
+-    g_object_unref (istream);
+     vcedit_clear_internals (state);
+     return FALSE;
+ }
+@@ -699,7 +702,6 @@ vcedit_write (EtOggState *state,
+     char *buffer;
+     int bytes;
+     int needflush = 0, needout = 0;
+-    GFileInputStream *istream;
+     GOutputStream *ostream;
+     gchar *buf;
+     gsize size;
+@@ -707,22 +709,11 @@ vcedit_write (EtOggState *state,
+ 
+     g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+ 
+-    istream = g_file_read (file, NULL, error);
+-
+-    if (!istream)
+-    {
+-        g_assert (error == NULL || *error != NULL);
+-        return FALSE;
+-    }
+-
+-    fileinfo = g_file_input_stream_query_info (istream,
+-                                               G_FILE_ATTRIBUTE_STANDARD_SIZE,
+-                                               NULL, error);
+-
++    fileinfo = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_SIZE,
++                                  G_FILE_QUERY_INFO_NONE, NULL, error);
+     if (!fileinfo)
+     {
+         g_assert (error == NULL || *error != NULL);
+-        g_object_unref (istream);
+         return FALSE;
+     }
+ 
+@@ -783,8 +774,7 @@ vcedit_write (EtOggState *state,
+         }
+     }
+ 
+-    while (_fetch_next_packet (state, G_INPUT_STREAM (istream), &op, &ogin,
+-                               error))
++    while (_fetch_next_packet (state, &op, &ogin, error))
+     {
+         if (needflush)
+         {
+@@ -960,7 +950,7 @@ vcedit_write (EtOggState *state,
+     {
+         /* We copy the rest of the stream (other logical streams)
+          * through, a page at a time. */
+-        while (1)
++        while(1)
+         {
+             result = ogg_sync_pageout (state->oy, &ogout);
+ 
+@@ -999,7 +989,7 @@ vcedit_write (EtOggState *state,
+ 
+         buffer = ogg_sync_buffer (state->oy, CHUNKSIZE);
+ 
+-        bytes = g_input_stream_read (G_INPUT_STREAM (istream), buffer,
++        bytes = g_input_stream_read (G_INPUT_STREAM (state->in), buffer,
+                                      CHUNKSIZE, NULL, error);
+ 
+         if (bytes == -1)
+@@ -1017,19 +1007,11 @@ vcedit_write (EtOggState *state,
+         }
+     }
+ 
++
+ cleanup:
+     ogg_stream_clear (&streamout);
+     ogg_packet_clear (&header_comments);
+ 
+-    if (!g_input_stream_close (G_INPUT_STREAM (istream), NULL, error))
+-    {
+-        /* Ignore the _close() failure, and try the write anyway. */
+-        g_warning ("Error closing Ogg file for reading: %s",
+-                   (*error)->message);
+-        g_clear_error (error);
+-    }
+-
+-    g_object_unref (istream);
+     g_free (state->mainbuf);
+     g_free (state->bookbuf);
+     state->mainbuf = state->bookbuf = NULL;
+@@ -1063,19 +1045,57 @@ cleanup:
+     buf = g_memory_output_stream_steal_data (G_MEMORY_OUTPUT_STREAM (ostream));
+     size = g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (ostream));
+ 
++    /* At least on Windows, writing to a file with an open-for-reading stream
++     * fails, so close the input stream before writing to the file. */
++    if (!g_input_stream_close (G_INPUT_STREAM (state->in), NULL, error))
++    {
++        /* Ignore the _close() failure, and try the write anyway. */
++        g_warning ("Error closing Ogg file for reading: %s",
++                   (*error)->message);
++        g_clear_error (error);
++    }
++
++    g_object_unref (state->in);
++    state->in = NULL;
++
+     /* Write the in-memory data back out to the original file. */
+     if (!g_file_replace_contents (file, buf, size, NULL, FALSE,
+                                   G_FILE_CREATE_NONE, NULL, NULL, error))
+     {
++        GError *tmp_error = NULL;
++
+         g_object_unref (ostream);
+         g_free (buf);
+ 
++        /* Re-open the file for reading, to keep the internal state
++         * consistent. */
++        state->in = g_file_read (file, NULL, &tmp_error);
++
++        if (!state->in)
++        {
++            g_warning ("Error opening Ogg file for reading after write failure: %s",
++                       tmp_error->message);
++            g_clear_error (&tmp_error);
++            g_assert (error == NULL || *error != NULL);
++            return FALSE;
++        }
++
+         g_assert (error == NULL || *error != NULL);
+         return FALSE;
+     }
+ 
+     g_free (buf);
+     g_object_unref (ostream);
++
++    /* Re-open the file, now that the write has completed. */
++    state->in = g_file_read (file, NULL, error);
++
++    if (!state->in)
++    {
++        g_assert (error == NULL || *error != NULL);
++        return FALSE;
++    }
++
+ 
+     return TRUE;
+ }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201908040643.x746hHwn038024>