mirror of
https://git.freebsd.org/ports.git
synced 2025-06-05 21:00:30 -04:00
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
This commit is contained in:
parent
bd61e15d6b
commit
ee17cb7e0f
Notes:
svn2git
2021-03-31 03:12:20 +00:00
svn path=/head/; revision=508062
2 changed files with 231 additions and 1 deletions
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
PORTNAME= easytag
|
PORTNAME= easytag
|
||||||
PORTVERSION= 2.4.3
|
PORTVERSION= 2.4.3
|
||||||
PORTREVISION= 2
|
PORTREVISION= 3
|
||||||
CATEGORIES= audio
|
CATEGORIES= audio
|
||||||
MASTER_SITES= GNOME
|
MASTER_SITES= GNOME
|
||||||
|
|
||||||
|
|
230
audio/easytag/files/patch-src_tags_vcedit.c
Normal file
230
audio/easytag/files/patch-src_tags_vcedit.c
Normal file
|
@ -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;
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue