changeset 8979:63e96de9d096 8u45-b12

Automated merge with http://hg.openjdk.java.net/openjfx/8u40/rt
author kcr
date Fri, 13 Mar 2015 12:49:46 -0700
parents eb264cdc5828 a2143d388e8b
children 93e3b40039ac 2c2927b800ee
files .hgtags
diffstat 7 files changed, 149 insertions(+), 138 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Fri Mar 13 08:22:18 2015 -0700
+++ b/.hgtags	Fri Mar 13 12:49:46 2015 -0700
@@ -213,7 +213,11 @@
 99b445f2721193142a2fd8b206b9f949c134639d 8u40-b18
 2f0d0cab40c443fa49ac7117b1f9a6b32723a958 8u40-b19
 7d93ba533809d1f247bf39beb9179b22aaa2432c 8u40-b20
+39bbac39d4ba903b2275470c67677152900a4e2b 8u45-b01
 f88433e126cd1240666ca5316cf296d94abc15c8 8u40-b21
+2fba328b97fb89614d9fe615cbc4908836e83a80 8u45-b02
+d9633ef51015b2a8e2db14cdbd17f7d4a21fb67f 8u45-b03
+e7c2b5f84b63c88b8ba2e2234c94a7756aa0e4aa 8u45-b04
 005254e22af36cea855c584b4ae4cf09f285819b 8u31-b02
 cb1597094e0803aa56013d79bd26e54b08b98cef 8u31-b03
 d865ed51c537d80655339bf01928d52bf8e59a35 8u31-b04
@@ -227,8 +231,15 @@
 ce317dfcb9a96943403d88d86abcda4c7f182ff5 8u31-b12
 f1388961b89fc39dc86992e0b9a8ffab8c75d1e5 8u31-b13
 fed0a08c47e9b9be421eb49dabc7bc872a6f7de8 8u40-b22
+e7ceb6237e1a8a6a53120ed77243611937b801b4 8u45-b05
 2c8e07ca29f358c98c2040c28cd1726d3dc6facb 8u40-b23
+12ff255c338e2a6b21ef1125aa982eea8415c086 8u45-b06
 fee546b5171799a21cd7b2dc0f5cc3447176c104 8u40-b24
+eb272f8584c8346d7438e2b23d0661980d512c07 8u45-b07
 6cc08ec1ea825b4bd1273e522e61e1b9efda4172 8u40-b25
+9a0bb4610ea0e3fe93008c8ddf2757fdb9c3be35 8u45-b08
 298ec4ec6b354f2eb74a200b3415bc4566ddc1a7 8u40-b26
+88882082520b7195b4e669955782ffc6757db7ac 8u45-b09
 e00e97499831954b5126d96da1299b1ecdf69e15 8u40-b27
+f5b6e9bfedc64c3bc27d1fdd8888f5386b9c9f36 8u45-b10
+f5b6e9bfedc64c3bc27d1fdd8888f5386b9c9f36 8u45-b11
--- a/build.properties	Fri Mar 13 08:22:18 2015 -0700
+++ b/build.properties	Fri Mar 13 12:49:46 2015 -0700
@@ -33,10 +33,10 @@
 jfx.release.milestone=fcs
 # Note: For fcs builds the suffix should be blank
 jfx.release.suffix=
-jfx.release.name=8u40
+jfx.release.name=8u45
 jfx.release.major.version=8
 jfx.release.minor.version=0
-jfx.release.micro.version=40
+jfx.release.micro.version=45
 
 ##############################################################################
 #
--- a/modules/fxpackager/src/main/java/com/oracle/tools/packager/mac/MacAppBundler.java	Fri Mar 13 08:22:18 2015 -0700
+++ b/modules/fxpackager/src/main/java/com/oracle/tools/packager/mac/MacAppBundler.java	Fri Mar 13 12:49:46 2015 -0700
@@ -557,7 +557,9 @@
         plugInsDirectory.mkdirs();
 
         File srcdir = runTime.getBaseDirectory();
-        File destDir = new File(plugInsDirectory, "Java");
+        // the name in .../Contents/PlugIns/ must have a dot to be verified 
+        // properly by the Mac App Store.
+        File destDir = new File(plugInsDirectory, "Java.runtime");
         Set<String> filesToCopy = runTime.getIncludedFiles();
 
         for (String fname : filesToCopy) {
@@ -627,7 +629,7 @@
                 COPYRIGHT.fetchFrom(params) != null ? COPYRIGHT.fetchFrom(params) : "Unknown");
         data.put("DEPLOY_LAUNCHER_NAME", getLauncherName(params));
         if (MAC_RUNTIME.fetchFrom(params) != null) {
-            data.put("DEPLOY_JAVA_RUNTIME_NAME", "$APPDIR/plugins/Java");
+            data.put("DEPLOY_JAVA_RUNTIME_NAME", "$APPDIR/PlugIns/Java.runtime");
         } else {
             data.put("DEPLOY_JAVA_RUNTIME_NAME", "");
         }
@@ -926,14 +928,6 @@
             rules.add(Rule.substrNeg("/contents/frameworks/"));
         }
         
-        // strip the link to the DLL for the plugin
-        if (isJDK) {
-            rules.add(Rule.suffixNeg("/macos/libjli.dylib"));
-        }
-        if (isJRE) {
-            rules.add(Rule.suffixNeg("/macos/javaappletplugin"));
-        }
-
         // strip out command line tools
         rules.add(Rule.suffixNeg("home/bin"));
         if (isJDK) {
--- a/modules/fxpackager/src/main/java/com/oracle/tools/packager/mac/MacBaseInstallerBundler.java	Fri Mar 13 08:22:18 2015 -0700
+++ b/modules/fxpackager/src/main/java/com/oracle/tools/packager/mac/MacBaseInstallerBundler.java	Fri Mar 13 12:49:46 2015 -0700
@@ -212,9 +212,8 @@
     }
 
     public static void signAppBundle(Map<String, ? super Object> params, File appLocation, String signingIdentity, String identifierPrefix, String entitlementsFile, String inheritedEntitlements) throws IOException {
-
         AtomicReference<IOException> toThrow = new AtomicReference<>();
-
+        String appExecutable = "/Contents/MacOS/" + APP_NAME.fetchFrom(params);
         // sign all dylibs and jars
         Files.walk(appLocation.toPath())
                 // while we are searching let's fix permissions
@@ -230,91 +229,50 @@
                         Log.debug(e);
                     }
                 })
-                // now only care about jars and dylibs
-                .filter(p -> (p.toString().endsWith(".jar")
-                                || p.toString().endsWith(".dylib"))
+                .filter(p -> Files.isRegularFile(p) && 
+                                !(p.toString().contains("/Contents/MacOS/libjli.dylib")
+                                  || p.toString().contains("/Contents/MacOS/JavaAppletPlugin")
+                                  || p.toString().endsWith(appExecutable))
                 ).forEach(p -> {
-                    //noinspection ThrowableResultOfMethodCallIgnored
-                    if (toThrow.get() != null) return;
+            //noinspection ThrowableResultOfMethodCallIgnored
+            if (toThrow.get() != null) return;
 
-                    List<String> args = new ArrayList<>();
-                    args.addAll(Arrays.asList(
-                            "codesign",
-                            "-f")); // replace all existing signatures
-                    if (signingIdentity != null) {
-                        args.add("-s");
-                        args.add(signingIdentity); // sign with this key
-                    }
-                    if (entitlementsFile != null) {
-                        args.add("--entitlements");
-                        args.add(entitlementsFile); // entitlements
-                    }
-                    args.add("-vvvv"); // super verbo1se output
-                    args.add(p.toString());
+            List<String> args = new ArrayList<>();
+            args.addAll(Arrays.asList("codesign",
+                    "-s", signingIdentity, // sign with this key
+                    "--prefix", identifierPrefix, // use the identifier as a prefix
+                    "-vvvv"));
+            if (entitlementsFile != null && 
+                    (p.toString().endsWith(".jar")
+                      || p.toString().endsWith(".dylib"))) 
+            {
+                args.add("--entitlements");
+                args.add(entitlementsFile); // entitlements
+            } else if (inheritedEntitlements != null && Files.isExecutable(p)) {
+                args.add("--entitlements");
+                args.add(inheritedEntitlements); // inherited entitlements for executable processes
+            }
+            args.add(p.toString());
 
+            try {
+                Set<PosixFilePermission> oldPermissions = Files.getPosixFilePermissions(p);
+                File f = p.toFile();
+                f.setWritable(true, true);
 
-                    try {
-                        Set<PosixFilePermission> oldPermissions = Files.getPosixFilePermissions(p);
-                        File f = p.toFile();
-                        f.setWritable(true, true);
+                ProcessBuilder pb = new ProcessBuilder(args);
+                IOUtils.exec(pb, VERBOSE.fetchFrom(params));
 
-                        ProcessBuilder pb = new ProcessBuilder(args);
-                        IOUtils.exec(pb, VERBOSE.fetchFrom(params));
-
-                        Files.setPosixFilePermissions(p, oldPermissions);
-                    } catch (IOException ioe) {
-                        toThrow.set(ioe);
-                    }
-                });
+                Files.setPosixFilePermissions(p, oldPermissions);
+            } catch (IOException ioe) {
+                toThrow.set(ioe);
+            }
+        });
 
         IOException ioe = toThrow.get();
         if (ioe != null) {
             throw ioe;
         }
 
-        // sign all contained executables with an inherit entitlement
-        Files.find(appLocation.toPath().resolve("Contents"), Integer.MAX_VALUE,
-                (path, attr) -> (Files.isExecutable(path) && Files.isRegularFile(path)))
-                .filter(path -> (!path.toString().endsWith(".dylib") && !path.toString().contains("/Contents/MacOS/")))
-                .forEachOrdered(path -> {
-                    //noinspection ThrowableResultOfMethodCallIgnored
-                    if (toThrow.get() != null) return;
-
-                    List<String> args = new ArrayList<>();
-                    args.addAll(Arrays.asList("codesign",
-                            "--deep",
-//                            "--prefix", identifierPrefix, // use the identifier as a prefix
-                            "-f")); // replace all existing signatures
-                    if (signingIdentity != null) {
-                        args.add("-s");
-                        args.add(signingIdentity); // sign with this key
-                    }
-                    if (inheritedEntitlements != null) {
-                        args.add("--entitlements");
-                        args.add(inheritedEntitlements); // entitlements
-                    }
-                    args.add("-vvvv"); // super verbose output
-                    args.add(path.toString()); // this is what we are signing
-
-                    try {
-                        Set<PosixFilePermission> oldPermissions = Files.getPosixFilePermissions(path);
-                        File f = path.toFile();
-                        f.setWritable(true, true);
-
-                        ProcessBuilder pb = new ProcessBuilder(args);
-                        IOUtils.exec(pb, VERBOSE.fetchFrom(params));
-
-                        Files.setPosixFilePermissions(path, oldPermissions);
-                    } catch (IOException e) {
-                        toThrow.set(e);
-                    }
-                });
-
-        ioe = toThrow.get();
-        if (ioe != null) {
-            throw ioe;
-        }
-
         // sign all plugins and frameworks
         Consumer<? super Path> signIdentifiedByPList = path -> {
             //noinspection ThrowableResultOfMethodCallIgnored
@@ -324,17 +282,20 @@
                 List<String> args = new ArrayList<>();
                 args.addAll(Arrays.asList("codesign",
                         "-s", signingIdentity, // sign with this key
-                        "-f", // replace all existing signatures
                         "--prefix", identifierPrefix, // use the identifier as a prefix
-                        //"-i", bundleID, // sign the bundle's CFBundleIdentifier
                         "-vvvv"));
-                if (signingIdentity != null) {
-                    args.add("-s");
-                    args.add(signingIdentity); // sign with this key
-                }
                 args.add(path.toString());
                 ProcessBuilder pb = new ProcessBuilder(args);
                 IOUtils.exec(pb, VERBOSE.fetchFrom(params));
+
+                args = new ArrayList<>();
+                args.addAll(Arrays.asList("codesign",
+                        "-s", signingIdentity, // sign with this key
+                        "--prefix", identifierPrefix, // use the identifier as a prefix
+                        "-vvvv"));
+                args.add(path.toString() + "/Contents/_CodeSignature/CodeResources");
+                pb = new ProcessBuilder(args);
+                IOUtils.exec(pb, VERBOSE.fetchFrom(params));
             } catch (IOException e) {
                 toThrow.set(e);
             }
@@ -365,13 +326,11 @@
         List<String> args = new ArrayList<>();
         args.addAll(Arrays.asList("codesign",
                 "-s", signingIdentity, // sign with this key
-                "--deep", // sign deeply, including plugins
-                "-f")); // replace all existing signatures
+                "-vvvv")); // super verbose output
         if (entitlementsFile != null) {
             args.add("--entitlements");
             args.add(entitlementsFile); // entitlements
         }
-        args.add("-vvvv"); // super verbose output
         args.add(appLocation.toString());
 
         ProcessBuilder pb = new ProcessBuilder(args.toArray(new String[args.size()]));
--- a/modules/fxpackager/src/test/java/com/oracle/tools/packager/mac/MacAppBundlerTest.java	Fri Mar 13 08:22:18 2015 -0700
+++ b/modules/fxpackager/src/test/java/com/oracle/tools/packager/mac/MacAppBundlerTest.java	Fri Mar 13 12:49:46 2015 -0700
@@ -40,8 +40,10 @@
 import org.junit.Ignore;
 import org.junit.Test;
 
+import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.IOException;
+import java.io.PrintStream;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -67,6 +69,7 @@
     static String runtimeJre;
     static Set<File> appResources;
     static boolean retain = false;
+    static boolean signingKeysPresent = false;
 
     @BeforeClass
     public static void prepareApp() {
@@ -91,6 +94,23 @@
         fakeMainJar = new File(appResourcesDir, "mainApp.jar");
 
         appResources = new HashSet<>(Arrays.asList(fakeMainJar));
+
+        String signingKeyName = MacAppStoreBundler.MAC_APP_STORE_APP_SIGNING_KEY.fetchFrom(new TreeMap<>());
+        if (signingKeyName != null) {
+            try (ByteArrayOutputStream baos = new ByteArrayOutputStream(); PrintStream ps = new PrintStream(baos)) {
+                ProcessBuilder pb = new ProcessBuilder(
+                        "security",
+                        "find-certificate", "-c", signingKeyName);
+
+                IOUtils.exec(pb, Log.isDebug(), false, ps);
+
+                String commandOutput = baos.toString();
+                Assume.assumeTrue(commandOutput.contains(signingKeyName));
+                signingKeysPresent = true;
+            } catch (Throwable t) {
+                // any exception is ignored, signing key already set to false
+            }
+        }
     }
 
     @Before
@@ -383,10 +403,12 @@
     }
 
     /**
-     * Build smoke test and mark it as quarantined, possibly signed
+     * Build signed smoke test and mark it as quarantined, skip if no keys present
      */
     @Test
     public void quarantinedAppTest() throws IOException, ConfigException, UnsupportedPlatformException {
+        Assume.assumeTrue(signingKeysPresent);
+        
         AbstractBundler bundler = new MacAppBundler();
 
         assertNotNull(bundler.getName());
@@ -416,6 +438,7 @@
         System.err.println("Bundle at - " + result);
         assertNotNull(result);
         assertTrue(result.exists());
+        validateSignatures(result);
 
         // mark it as though it's been downloaded
         ProcessBuilder pb = new ProcessBuilder(
@@ -453,6 +476,9 @@
         System.err.println("Bundle at - " + output);
         assertNotNull(output);
         assertTrue(output.exists());
+        if (signingKeysPresent) {
+            validateSignatures(output);
+        }
     }
 
     /**
@@ -483,6 +509,9 @@
         System.err.println("Bundle at - " + output);
         assertNotNull(output);
         assertTrue(output.exists());
+        if (signingKeysPresent) {
+            validateSignatures(output);
+        }
     }
 
     /**
@@ -659,6 +688,9 @@
         System.err.println("Bundle at - " + output);
         assertNotNull(output);
         assertTrue(output.exists());
+        if (signingKeysPresent) {
+            validateSignatures(output);
+        }
     }
 
     /**
@@ -671,6 +703,29 @@
         assertTrue(MacBaseInstallerBundler.findKey("A completely bogus key that should never realistically exist unless we are attempting to falsely break the tests", true) == null);
     }
     
+    public void validateSignatures(File appLocation) throws IOException {
+        // shallow validation
+        ProcessBuilder pb = new ProcessBuilder(
+                "codesign", "--verify",
+                "-v", // single verbose
+                appLocation.getCanonicalPath());
+        IOUtils.exec(pb, true);
+
+        // deep validation
+        pb = new ProcessBuilder(
+                "codesign", "--verify",
+                "--deep",
+                "-v", // single verbose
+                appLocation.getCanonicalPath());
+        IOUtils.exec(pb, true);
+        
+        //spctl, this verifies gatekeeper
+        pb = new ProcessBuilder(
+                "spctl", "--assess",
+                "-v", // single verbose
+                appLocation.getCanonicalPath());
+        IOUtils.exec(pb, true);
+    }    
 
 
 }
--- a/modules/fxpackager/src/test/java/com/oracle/tools/packager/mac/MacAppStoreBundlerTest.java	Fri Mar 13 08:22:18 2015 -0700
+++ b/modules/fxpackager/src/test/java/com/oracle/tools/packager/mac/MacAppStoreBundlerTest.java	Fri Mar 13 12:49:46 2015 -0700
@@ -42,8 +42,10 @@
 import java.io.File;
 import java.io.IOException;
 import java.io.PrintStream;
+import java.text.SimpleDateFormat;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.Date;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
@@ -181,6 +183,7 @@
                 new RelativeFileSet(fakeMainJar.getParentFile(),
                         new HashSet<>(Arrays.asList(fakeMainJar)))
         );
+        bundleParams.put(MAC_CF_BUNDLE_VERSION.getID(), "1.0." + new SimpleDateFormat("YYYYMMddHHmm").format(new Date()));
         bundleParams.put(CLASSPATH.getID(), "mainApp.jar");
         bundleParams.put(IDENTIFIER.getID(), "com.example.javapacakger.hello.TestPackager");
         bundleParams.put(MacAppBundler.MAC_CATEGORY.getID(), "public.app-category.developer-tools");
--- a/modules/media/src/main/native/gstreamer/plugins/audioconverter/audioconverter.c	Fri Mar 13 08:22:18 2015 -0700
+++ b/modules/media/src/main/native/gstreamer/plugins/audioconverter/audioconverter.c	Fri Mar 13 12:49:46 2015 -0700
@@ -644,11 +644,8 @@
     // If between FLUSH_START and FLUSH_STOP, reject new buffers.
     if (decode->is_flushing)
     {
-        // Unref the input buffer.
-        // INLINE - gst_buffer_unref()
-        gst_buffer_unref(buf);
-
-        return GST_FLOW_WRONG_STATE;
+        ret = GST_FLOW_WRONG_STATE;
+        goto _exit;
     }
 
     // Reset state on discont buffer if not after FLUSH_STOP.
@@ -746,13 +743,10 @@
                                     decode->isFormatInitialized = TRUE;
                                     decode->isAudioConverterReady = TRUE;
                                 } else {
-                                    // Unref the input buffer.
-                                    // INLINE - gst_buffer_unref()
-                                    gst_buffer_unref(buf);
-
                                     gst_caps_unref(sink_peer_caps);
 
-                                    return GST_FLOW_ERROR;
+                                    ret = GST_FLOW_ERROR;
+                                    goto _exit;
                                 }
                             } else {
                                 gint layer;
@@ -786,14 +780,11 @@
                                             packetListener,
                                             audioStreamTypeHint,
                                             &decode->audioStreamID)) {
-                // Unref the input buffer.
-                // INLINE - gst_buffer_unref()
-                gst_buffer_unref(buf);
-
 #if ENABLE_PRINT_SPEW
                 g_print("AudioFileStreamOpen failed\n");
 #endif
-                return GST_FLOW_ERROR;
+                ret = GST_FLOW_ERROR;
+                goto _exit;
             }
         }
     }
@@ -814,15 +805,12 @@
 
         OSStatus result = AudioFileStreamParseBytes(decode->audioStreamID, buf_size, buf_data, parserFlags);
 
-        // Unref the input buffer.
-        // INLINE - gst_buffer_unref()
-        gst_buffer_unref(buf);
-
         if(noErr != result) {
 #if ENABLE_PRINT_SPEW
             g_print("AudioFileStreamParseBytes %d\n", result);
 #endif
-            return GST_FLOW_ERROR;
+            ret = GST_FLOW_ERROR;
+            goto _exit;
         }
     } else {
         if(!decode->is_synced && NULL != decode->audioConverter) {
@@ -836,10 +824,6 @@
 
         packetListener((void*)decode, buf_size, 1, (const void*)buf_data,
                        &packetDescriptions);
-
-        // Unref the input buffer.
-        // INLINE - gst_buffer_unref()
-        gst_buffer_unref(buf);
     }
 
     // Return without pushing a buffer if format not derived from stream parser.
@@ -849,7 +833,7 @@
 
     // Return without pushing a buffer if format is MPEG audio but no packets are enqueued.
     if(AUDIOCONVERTER_DATA_FORMAT_MPA == decode->data_format && 0 == decode->total_packets) {
-        return GST_FLOW_OK;
+        goto _exit; // GST_FLOW_OK
     }
 
     if(decode->is_synced == FALSE) {
@@ -870,15 +854,12 @@
             // Allocate memory for output packet descriptions.
             decode->outPacketDescription = g_malloc(decode->samples_per_frame*sizeof(AudioStreamPacketDescription));
             if(NULL == decode->outPacketDescription) {
-                return GST_FLOW_ERROR;
+                ret = GST_FLOW_ERROR;
+                goto _exit;
             }
 
             // Save first frame offset.
-            if (GST_BUFFER_OFFSET_IS_VALID(buf)) {
-                decode->initial_offset = GST_BUFFER_OFFSET(buf);
-            } else {
-                decode->initial_offset = 0;
-            }
+            decode->initial_offset = GST_BUFFER_OFFSET_IS_VALID(buf) ? GST_BUFFER_OFFSET(buf) : 0;
 
             // Query for the stream length if it was not set from a header.
             if (AUDIOCONVERTER_STREAM_LENGTH_UNKNOWN == decode->stream_length)
@@ -933,7 +914,8 @@
                                             "mpegversion", G_TYPE_INT, 2,
                                              NULL);
             } else {
-                return GST_FLOW_ERROR;
+                ret = GST_FLOW_ERROR;
+                goto _exit;
             }
 
             if(gst_pad_set_caps (decode->sinkpad, caps) == FALSE)
@@ -983,7 +965,7 @@
 
     if(!decode->isAudioConverterReady) {
         // Return without pushing a buffer if converter is not ready.
-        return GST_FLOW_OK;
+        goto _exit; // GST_FLOW_OK
     } else if(NULL == decode->audioConverter) {
         // Initialize the converter.
         if(noErr != AudioConverterNew(&decode->audioInputFormat,
@@ -993,7 +975,8 @@
             g_print("Failed to initialize AudioConverter\n");
 #endif
             // Return an error if converter cannot be initialized.
-            return GST_FLOW_ERROR;
+            ret = GST_FLOW_ERROR;
+            goto _exit;
         } else if(NULL != decode->cookieData && noErr != AudioConverterSetProperty(decode->audioConverter,
                                                                             kAudioConverterDecompressionMagicCookie,
                                                                             decode->cookieSize, decode->cookieData)) {
@@ -1001,7 +984,8 @@
             g_print("Failed to set AudioConverter magic cookie data\n");
 #endif
             // Return an error if converter cannot be initialized.
-            return GST_FLOW_ERROR;
+            ret = GST_FLOW_ERROR;
+            goto _exit;
         } else if(AUDIOCONVERTER_DATA_FORMAT_AAC == decode->data_format) {
             AudioConverterPrimeInfo primeInfo;
             primeInfo.leadingFrames = 0;
@@ -1023,7 +1007,7 @@
     if(decode->is_priming) {
         // Return without pushing a buffer if there are not enough packets enqueued.
         if(g_queue_get_length(decode->packetDesc) < AUDIOCONVERTER_MPEG_MIN_PACKETS) {
-            return GST_FLOW_OK;
+            goto _exit; // GST_FLOW_OK;
         } else {
             decode->is_priming = FALSE;
         }
@@ -1047,7 +1031,7 @@
                 gst_element_message_full(GST_ELEMENT(decode), GST_MESSAGE_ERROR, GST_CORE_ERROR, GST_CORE_ERROR_SEEK, g_strdup("Decoded audio buffer allocation failed"), NULL, ("audioconverter.c"), ("audioconverter_chain"), 0);
             }
 
-            return ret;
+            goto _exit;
         }
 
         AudioBufferList outputData;
@@ -1067,7 +1051,8 @@
 #endif
             // INLINE - gst_buffer_unref()
             gst_buffer_unref(outbuf);
-            return GST_FLOW_ERROR;
+            ret = GST_FLOW_ERROR;
+            goto _exit;
         }
 
         if(0 == outputDataPacketSize) {
@@ -1095,7 +1080,7 @@
 
         ret = gst_pad_push (decode->srcpad, outbuf);
         if(GST_FLOW_OK != ret) {
-            return ret;
+            goto _exit;
         }
     }
 
@@ -1108,7 +1093,11 @@
         decode->inputOffset = 0;
     }
 
-    return GST_FLOW_OK;
+_exit:
+    // Unref the input buffer.
+    // INLINE - gst_buffer_unref()
+    gst_buffer_unref(buf);
+    return ret;
 }
 
 #if ENABLE_PRINT_SPEW