Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5cce4c75 authored by Elliott Hughes's avatar Elliott Hughes Committed by Gerrit Code Review
Browse files

Merge "Fix memory leak where we close the descriptor instead of the file."

parents 189bf056 c793fcb0
Loading
Loading
Loading
Loading
+15 −4
Original line number Diff line number Diff line
@@ -478,7 +478,7 @@ static jobject nativeDecodeFileDescriptor(JNIEnv* env, jobject clazz, jobject fi

    NPE_CHECK_RETURN_ZERO(env, fileDescriptor);

    jint descriptor = jniGetFDFromFileDescriptor(env, fileDescriptor);
    int descriptor = jniGetFDFromFileDescriptor(env, fileDescriptor);

    struct stat fdStat;
    if (fstat(descriptor, &fdStat) == -1) {
@@ -486,16 +486,27 @@ static jobject nativeDecodeFileDescriptor(JNIEnv* env, jobject clazz, jobject fi
        return nullObjectReturn("fstat return -1");
    }

    // Restore the descriptor's offset on exiting this function.
    // Restore the descriptor's offset on exiting this function. Even though
    // we dup the descriptor, both the original and dup refer to the same open
    // file description and changes to the file offset in one impact the other.
    AutoFDSeek autoRestore(descriptor);

    FILE* file = fdopen(descriptor, "r");
    // Duplicate the descriptor here to prevent leaking memory. A leak occurs
    // if we only close the file descriptor and not the file object it is used to
    // create.  If we don't explicitly clean up the file (which in turn closes the
    // descriptor) the buffers allocated internally by fseek will be leaked.
    int dupDescriptor = dup(descriptor);

    FILE* file = fdopen(dupDescriptor, "r");
    if (file == NULL) {
        // cleanup the duplicated descriptor since it will not be closed when the
        // file is cleaned up (fclose).
        close(dupDescriptor);
        return nullObjectReturn("Could not open file");
    }

    SkAutoTUnref<SkFILEStream> fileStream(new SkFILEStream(file,
                         SkFILEStream::kCallerRetains_Ownership));
                         SkFILEStream::kCallerPasses_Ownership));

    // Use a buffered stream. Although an SkFILEStream can be rewound, this
    // ensures that SkImageDecoder::Factory never rewinds beyond the