Re: Bug 687560 "Invalid PDF if /BP pdfmarkswithnon-unique /_objdef"

"Igor Melichev" <[email protected]> Mon, 22 Nov 2004 14:14:51 +0300
Newsgroups gmane.comp.printing.ghostscript.patches
Message-ID <[email protected]>
Dear SaGS,

> From: "SaGS" <[email protected]>
> To: "gs-code-review" <[email protected]>
> Cc: "Igor V. Melichev" <[email protected]>
> Sent: Monday, November 15, 2004 12:31 AM
> Subject: Re: Bug 687560 "Invalid PDF if /BP pdfmarkswithnon-unique
> /_objdef"


> Dear Igor,
>
> I already did a few changes to the patch, but before posting a new version
> we need to agree on some of the points. So, here are some explanations and
> questions.
>
> ----- Original Message -----
> From: "Igor Melichev" <[email protected]>
> To: "SaGS" <[email protected]>; <[email protected]>
> Sent: Thursday, 4 November 2004 20:01
> Subject: Re: [gs-code-review] Fix: Bug 687560 "Invalid PDF if /BP
> pdfmarkswithnon-unique /_objdef"
>
>
>> ...
>> First of all, please follow C-style.htm about the code formatting.
>> ...
>
> OK. Also got "indent", a 98% friend.
>
>
>> ...
>> 1. The function cos_dict_rename looks some unsmooth
>> and it's name isn't enough leading. Could you please
>> replace its usage with 2 "traditional" operations :
>> remove_entry(old_name),  add_entry(new_name) ?
>> (Yes, "rename" saves a few CPU time with
>> memory allocations, but it doesn't looks so important optimization).
>> Or at least cos_dict_rename to be renamed with
>> cos_dict_rename_entry.
>
> (1.A) The name "cos_dict_rename_entry" is fine with me. I considered
> cos_dict_rename[_entry]() can be reused when (if ever) other pdfmarks will
> be fixed to deal with duplicate distill-time names. (Haven't looked
> closely,
> but it looks this is somehow random at present: /ANN raises an error, /OBJ
> implementation is entirely "original" and /NI creates an invalid PDF the
> same way as /BP and /PS do at present.)
>
> (1.B) There are already plenty of "put()". If you think that a "remove()"
> will be much more useful, then that's fine with me too and I'll change the
> code. I suggest the name "cos_dict_unadd()", as its array counterpart. The
> function will remove an entry from the dictionary, free the key if
> necessary, and return the value (the value will NOT be freed).
>
> Please decide between (1.A) and (1.B).

Well, lets go with "remove". I don't like "unadd"
for this function. A parallel with arrays isn't smooth.

>
>
>> 2. I'm unclear with the implementation of the branch
>> PDF_NAMECOLLISION_REBUILD.
>> Do you really need the "surgery" ?
>> I would recommend to do it as this :
>> 2.1. Create a new object with pdf_enter_substream;
>> 2.2. Copy all useful keys from the old cos dict to the new one;
>> 2.3. Remove the old object from the named object list,
>> and add the new one;
>> 2.4. Cancel and free the old object.
>> Note that cos_write_stream_redir, cos_stream_move_all become unnecessary.
>> (Well, my suggestion won't work if there are references to
>> the old object from others. But in this case your code
>> doesn't work also).
>
> Let not say "reference", I consider this word too imprecise. It can mean:
> (a) A C pointer. I'll name these "C-ptrs";
> (b) References based exclusively on object numbers, those "n 0 R" or
> "/Rn".
> I'll name these "n 0 Refs".
> (c) The construct "{OBJNAME}" when it appears in the value part of a
> key-value pair and the key is anything except /_objdef. I'll name these
> "{OBJRefs}". (These appear only in the source PostScript code, and are
> converted internally to "n 0 Refs", but that's not an important fact
> here.)
>
> With the latest version of the patch, "C-ptrs" remain valid because
> neither
> the old cos_object_t nor the old pdf_resource_t are freed or reallocated,
> only their contents may change. Also, the object number and name remain,
> so
> "n 0 Refs" and "{OBJRefs}" are OK too. What exactly makes you believe "in
> this case [the] code doesn't work also"?

Well, I withdraw the last sentence.

> Notes:
> - With the preceding version of the patch, "C-ptrs" didn't survive a
> PDF_NAMECOLLISION_REBUILD;
> - While I didn't find a "C-ptr" to an XObject, I'm not confident that such
> pointers don't exist, nor that they won't be used in the future; for this
> reason, I prefer not to change the patch to conform to 2.1 ... 2.4 above.
>
> Regarding the "surgery", I don't like the idea either, because it's a
> source
> of errors. In fact, in the meantime I discovered that, even if the patient
> did not die, the surgery was incomplete,
> pdev->accumulating_substream_resource needing to be patched too.
>
> Given this situation, I think the options are:
> (2.A) Change pdf_alloc_aside()

I don't like to chage basic functions,
which were created a long ago by old programmers.
I'm uneasy to foresee consequences, so we'll better keep them
as they are. Note that I keep in mind multiple projects,
and therefore I'm interested to simplify any of tham and to make
their code permanent, at least in the functtional basis.

> as it was in the preceding version of the
> patch. It will continue to output an "aside", but the added "pcofwd"
> parameter allows the caller, by setting this to !=NULL, to feed-in
> whatever
> pieces of the future "aside" are already available. This way, the right
> object is used in the first place, all those intricate connections will be
> made to the right object, and "surgery" will be unnecessary.
> (pdf_enter_substream() and pdf_open-aside() will also need this extra
> parameter, but their logic doesn't really change, they only pass this
> parameter to the next function.) A VARIATION of this: don't add an extra
> parameter, but make the existing "ppres" to be an in/out parameter rather
> than an out parameter. (In this 2nd case, I identified a few places in 4
> files - including gdevpdfm.c - where *ppres needs to be initialized to 0.)
>
> (2.B) Let the "surgery" as-is (with the rectification about
> pdev->accumulating_substream_resource I mentioned).
>
> Please take a decision on this.

Hmm, I have no time to dig into this now.
If I remove "2.4. Cancel and free the old object"
from my suggestion above, could it work ?


>
>
>>
>> 3. Please note that recently I defined pdf_forget_resource (see
>> http://www.ghostscript.com/pipermail/gs-cvs/2004-November/004992.html),
>> which may be useful for your code.
>> ...
>
> OK, it seems I can simply replace pdf_cancel_resource() with this one
> (except it returns void, not a "code").
>
>
>> 4. It would be useful to group (factor out)
>> the call to pdf_enter_substream
>> and pdev->substream_Resources = cos_dict_alloc(...)
>> into a special local function pdf_enter_BP
>> (Well, I'm not in favor with the name pdf_enter_BP,
>> fell free to improve it). The purposes are :
>> 4.1. do not distribute redundant specifics of BP through GS code;
>> 4.2. Simplify the view of the big operator "switch" you introduced;
>
> OK. For the name, I'll choose "pdf_enter_XObject" (being used not only for
> /BP, but for /PS too), unless you have another preference.
>
>> 4.3. Move /* Have no better switch*/ to a single place.
>
> While writing the new pdf_enter_XObject(), I noticed an unused parameter
> of
> start_XObject(). It looks we do have a better choice: the "compress"
> option
> passed from the caller. I'll use this, unless you find a reason not to. It
> is set by the caller to pdev->CompressPages, not pdev->CompressFonts,
> which
> looks more appropriate; and anyway it's a good idea to let the caller
> decide
> on compression. If this change is not OK with you, it's the moment to say
> so.

This change looks good, but I would not mix it within same patch.
Lets delay it for a while.

>
>
>> 5. You coded :
>>
>> +           if (!(oper &PDF_NAMECOLLISION_NONAME))
>> +               code = cos_dict_put(pdev->local_named_objects,
>> objname->data,
>> +                                   objname->size,
> cos_object_value(&value,
>> pres->object));
>> +           else
>> +               DO_NOTHING;
>> +           if (code < 0)
>> +               return code;
>> ...
>
> Stupid mistake, sorry.
>
>
> Sincerely yours,
> SaGS
>

So we more or less in a complaint except 2B.
I'm sorry that I had no more time for analyzing it.
Your contribution would be useful.

Igor.