Return-Path: <awaresystems.be+caf_=filtered=awaresystems.be@gmail.com>
X-Original-To: filtered@awaresystems.be
Delivered-To: filtered@awaresystems.be
Received: from mx-k.one.com (mx-k.one.com [91.198.169.58])
	by mail9.b-one.net (Postfix) with ESMTP id 8B47F400A1D
	for <filtered@awaresystems.be>; Tue, 28 Feb 2012 21:06:21 +0100 (CET)
X-Virus-Scanned: by one.com
Received-SPF: pass (mx-k: domain of awaresystems.be+caf_=filtered=awaresystems.be@gmail.com designates 209.85.210.48 as permitted sender)
X-Greylist: whitelisted by SQLgrey-1.8.0-rc2
Received: from mail-pz0-f48.google.com (mail-pz0-f48.google.com [209.85.210.48])
	by mx-k.one.com (Postfix) with ESMTP id 0509A359F2A7
	for <filtered@awaresystems.be>; Tue, 28 Feb 2012 20:06:20 +0000 (UTC)
Received: by dadp13 with SMTP id p13so7132079dad.21
        for <filtered@awaresystems.be>; Tue, 28 Feb 2012 12:06:20 -0800 (PST)
Received: from mr.google.com ([10.68.227.105])
        by 10.68.227.105 with SMTP id rz9mr57297697pbc.98.1330459580123 (num_hops = 1);
        Tue, 28 Feb 2012 12:06:20 -0800 (PST)
Received: by 10.68.227.105 with SMTP id rz9mr48303193pbc.98.1330459579954;
        Tue, 28 Feb 2012 12:06:19 -0800 (PST)
X-Forwarded-To: filtered@awaresystems.be
X-Forwarded-For: awaresystems.be@gmail.com filtered@awaresystems.be
Delivered-To: awaresystems.be@gmail.com
Received: by 10.142.101.7 with SMTP id y7csp61146wfb;
        Tue, 28 Feb 2012 12:06:19 -0800 (PST)
Received: by 10.68.191.168 with SMTP id gz8mr48783737pbc.37.1330459579057;
        Tue, 28 Feb 2012 12:06:19 -0800 (PST)
Received-SPF: softfail (google.com: best guess record for domain of transitioning tiff-bounces@lists.maptools.org does not designate 91.198.169.57 as permitted sender) client-ip=91.198.169.57;
Received: by 10.68.141.205 with POP3 id rq13mf403322pbb.1;
        Tue, 28 Feb 2012 12:06:18 -0800 (PST)
X-Gmail-Fetch-Info: info@awaresystems.be 1 pop.awaresystems.be 110 info@awaresystems.be
X-Original-To: info@awaresystems.be
Delivered-To: info@awaresystems.be
Received: from mx-j.one.com (mx-j.one.com [91.198.169.57])
	by mail9.b-one.net (Postfix) with ESMTP id E285B400A1D
	for <info@awaresystems.be>; Tue, 28 Feb 2012 20:57:55 +0100 (CET)
X-Greylist: domain auto-whitelisted by SQLgrey-1.8.0-rc2
Received: from lists.maptools.org (lists.maptools.org [65.39.174.144])
	by mx-j.one.com (Postfix) with ESMTP id 53A233C32030
	for <info@awaresystems.be>; Tue, 28 Feb 2012 19:57:55 +0000 (UTC)
Received: from localhost.localdomain (localhost.localdomain [127.0.0.1])
	by lists.maptools.org (Postfix) with ESMTP id 939B31CC0EB;
	Tue, 28 Feb 2012 14:56:48 -0500 (EST)
Received: from sam.nabble.com (sam.nabble.com [216.139.236.26])
	by lists.maptools.org (Postfix) with ESMTPS id 85A4C1CC08F
	for <tiff@lists.maptools.org>; Tue, 28 Feb 2012 14:56:19 -0500 (EST)
Received: from isper.nabble.com ([192.168.236.156])
	by sam.nabble.com with esmtp (Exim 4.72)
	(envelope-from <bounces@nabble.com>) id 1S2T9m-0000ys-PW
	for tiff@lists.maptools.org; Tue, 28 Feb 2012 11:56:19 -0800
Message-ID: <33409332.post@talk.nabble.com>
Date: Tue, 28 Feb 2012 11:56:18 -0800 (PST)
From: BigEd781 <edwardswangren@gmail.com>
To: tiff@lists.maptools.org
MIME-Version: 1.0
X-Nabble-From: edwardswangren@gmail.com
Subject: [Tiff]  Confusion in implementing _TIFFVGetField,
 adding a custom TAG
X-BeenThere: tiff@lists.maptools.org
X-Mailman-Version: 2.1.9
Precedence: list
List-Id: TIFF and libtiff discussion <tiff.lists.maptools.org>
List-Unsubscribe: <http://lists.maptools.org/mailman/listinfo/tiff>,
	<mailto:tiff-request@lists.maptools.org?subject=unsubscribe>
List-Archive: <http://lists.maptools.org/mailman/private/tiff>
List-Post: <mailto:tiff@lists.maptools.org>
List-Help: <mailto:tiff-request@lists.maptools.org?subject=help>
List-Subscribe: <http://lists.maptools.org/mailman/listinfo/tiff>,
	<mailto:tiff-request@lists.maptools.org?subject=subscribe>
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit
Sender: tiff-bounces@lists.maptools.org
Errors-To: tiff-bounces@lists.maptools.org


I'm new to libtiff, so I want to make sure that my assumptions are correct,
but I believe that I have stumbled across an obvious issue in the library.

I am adding my own built-in tags to the library using the documentation
here: http://libtiff.maptools.org/addingtags.html

So, I added an entry to the TIFFFieldInfo array defined at the top of
tif_dirinfo.c like so:

(not sure if code tags work here...)
[code]
{ TIFFTAG_CUSTOM_XXX, 4, 4, TIFF_SLONG, FIELD_XXX,
1, 0, "XXX" },
[/code]

I then added a field to the TIFFDirectory structure defined in tif_dir.h:

[code]
int32 td_xxx[4];
[/code]

Now I went ahead and modified _TIFFVSetField and _TIFFVGetField as
instructed.  This is where I hit a problem.

In mimicking the pattern already present in the library, I added the
following code to _TIFFVGetField:

[code]
case TIFFTAG_CUSTOM_SCANCOORDMICRONS:
	*va_arg(ap, int32*) = td->td_xxx[0];
	*va_arg(ap, int32*) = td->td_xxx[1];
	*va_arg(ap, int32*) = td->td_xxx[2];
	*va_arg(ap, int32*) = td->td_xxx[3];
	break;
[/code]

As far as I can tell this is completely incorrect.  For reference please
look to the section of the switch which deals with TIFFTAG_YCBCRSUBSAMPLING. 
This is analogous to what I am doing, i.e., populate the input based off of
an array of ints, the only difference being the size of the data type.

_TIFFVGetField is eventually called from TIFFWriteNormalTag in
tif_dirwrite.c.  The relevant code is this:

[code]
case TIFF_LONG:
	case TIFF_SLONG:
	case TIFF_IFD:
		if (fip->field_passcount) {
			uint32* lp;
			if (wc == (uint16) TIFF_VARIABLE2) {
				TIFFGetField(tif, fip->field_tag, &wc2, &lp);
				TDIRSetEntryCount(tif,dir, wc2);
			} else {	/* Assume TIFF_VARIABLE */
				TIFFGetField(tif, fip->field_tag, &wc, &lp);
				TDIRSetEntryCount(tif,dir, wc);
			}
			if (!TIFFWriteLongArray(tif, dir, lp))
				return 0;
		} else {
			if (wc == 1) {
				uint32 wp;
				/* XXX handle LONG->SHORT conversion */
				TIFFGetField(tif, fip->field_tag, &wp);
				TDIRSetEntryOff(tif,dir, wp);
			} else {
/* ----------------------------------------------- */
/* this is the code that is called when I write my file */
				uint32* lp;
				TIFFGetField(tif, fip->field_tag, &lp);
				if (!TIFFWriteLongArray(tif, dir, lp))
					return 0;
			}
		}
		break;
[/code]

So, an uninitialized pointer lp is declared and its address passed to
TIFFGetField.  This in turn sets up the va_list and calls TIFFVGetField,
which calls _TIFFVGetField with the supplied va_list and the pointer to the
unitialized pointer.  

There are two problems here.

1. This is how the library extracts the data (my code, but again, following
the pattern already present)

*va_arg(ap, int32*) = td->td_xxx[0];

This seems incorrect.  It is setting the original pointer to the value of an
int.  I reasoned that perhaps, in the example I was following
(TIFFTAG_YCBCRSUBSAMPLING), these integers were actually addresses.  even if
that's the case though there is another problem.

The next problem is that we call va_args N times, where N is the number of
elements in the array. From what I see the variable argument list only ever
contains a single argument (the address of a pointer).  This is undefined
behavior per the standard (important bit at the begining):

[b]If there is no actual next argument[/b], or if type is not compatible
with the type of
the actual next argument (as promoted according to the default
argument promotions), the behavior is undefined.

The correct version would be 

*va_arg(ap, int32**) = td_xxx;

This sets the previously uninitialized pointer to the array, which is valid. 
I don't like that it points to the data itself instead of a copy, but
whatever, at least it doesn't crash and gives me the correct result.

My concern here is that I am missing something subtle.  This software is old
and used by many, many people. As such, calling this a bug feels to me like
blaming a crash on the compiler, which is *almost* always wrong.  However, I
cannot reason out a way in which this is correct, specifically how the
library writes to what va_arg returns when called more than one time.

Any help would be greatly appreciated.  Thanks in advance.
-- 
View this message in context: http://old.nabble.com/Confusion-in-implementing-_TIFFVGetField%2C-adding-a-custom-TAG-tp33409332p33409332.html
Sent from the Tiff / LibTiff mailing list archive at Nabble.com.

_______________________________________________
Tiff mailing list: Tiff@lists.maptools.org
http://lists.maptools.org/mailman/listinfo/tiff
http://www.remotesensing.org/libtiff/
