René Scharfe <l....@web.de> writes:

>>      /*
>>       * NEEDSWORK:
>>       * There is absolutely no reason to write this as a blob object
>> -     * and create a phony cache entry just to leak.  This hack is
>> -     * primarily to get to the write_entry() machinery that massages
>> -     * the contents to work-tree format and writes out which only
>> -     * allows it for a cache entry.  The code in write_entry() needs
>> -     * to be refactored to allow us to feed a <buffer, size, mode>
>> -     * instead of a cache entry.  Such a refactoring would help
>> -     * merge_recursive as well (it also writes the merge result to the
>> -     * object database even when it may contain conflicts).
>> +     * and create a phony cache entry.  This hack is primarily to get
>> +     * to the write_entry() machinery that massages the contents to
>> +     * work-tree format and writes out which only allows it for a
>> +     * cache entry.  The code in write_entry() needs to be refactored
>> +     * to allow us to feed a <buffer, size, mode> instead of a cache
>> +     * entry.  Such a refactoring would help merge_recursive as well
>> +     * (it also writes the merge result to the object database even
>> +     * when it may contain conflicts).
>>       */
>>      if (write_sha1_file(result_buf.ptr, result_buf.size,
>>                          blob_type, oid.hash))
>
> Random observation: Using pretend_sha1_file here would at least avoid
> writing the blob.

Yup, you should have told that to me back in Aug 2008 ;-) when I did
0cf8581e ("checkout -m: recreate merge when checking out of unmerged
index", 2008-08-30); pretend_sha1_file() was available since early
2007, and there is no excuse that this codepath did not use it.
>
>> @@ -251,6 +251,7 @@ static int checkout_merged(int pos, const struct 
>> checkout *state)
>>      if (!ce)
>>              die(_("make_cache_entry failed for path '%s'"), path);
>>      status = checkout_entry(ce, state, NULL);
>> +    free(ce);
>>      return status;
>>   }
>
> I wonder if that's safe.  Why document a leak when it could have been
> plugged this easily instead?
>
> A leak is better than a use after free, so
> let's be extra careful here.  Would it leave the index inconsistent?  Or
> perhaps freeing it has become safe in the meantime?
>
> @Junio: Do you remember the reason for the leaks in 0cf8581e330
> (checkout -m: recreate merge when checking out of unmerged index).

Yes.

In the very old days it was not allowed to free(3) contents of
active_cache[] and this was an old brain fart that came out of
inertia.  We are manufacturing a brand new ce, only to feed it to
checkout_entry() without even registering it to the active_cache[]
array, and the ancient rule doesn't even apply to such a case.

So I think it was safe to free(3) even back then.

> And result_buf is still leaked here, right?

Good spotting.  It typically would make a larger leak than a single
ce, I would suppose ;-)

Reply via email to