Bug with unsigned long? possible incorrect overflow check

13 views
Skip to first unread message

Zen

unread,
Feb 10, 2010, 9:49:25 AM2/10/10
to pococapsule
Hi,

Can someone working on pococapsule please confirm if there is a bug
with using type="ulong".
As far as I can tell, any value larger than LONG_MAX gets parsed as
LONG_MAX.

<method-arg type="ulong" value="2200000000"> gets parsed as 2147483647
(LONG_MAX)
probably an internal bug with regards to overflow check using
LONG_MAX instead of ULONG_MAX.

Please confirm that this is a bug or if not, show a work around.

Regards,
Zen

Ke Jin

unread,
Feb 10, 2010, 1:40:13 PM2/10/10
to pococapsule
In current release, string to integer conversions (in convert.C) are
all made using simple atol() function without error/overflow check. I
may consider to fix this in later releases.

However, the fix, if added, wouldn't be to allow integers larger than
the maximum one. Rather, the fix would merely have this reported as an
error (or exception).

One can have this error check today even without this fix. For
instance, one can write a simple XSLT stylesheet that generates an
<transform-error> node (with an 'message' attribute to report the
error) when seeing an out of range (or with invalid value) integer
attribute value. For instance:

...
<xsl:template name="method-arg">
<xsl:if test="@type='ulong'">
<xsl:if test="@value &gt; 2147483647">
<transform-error message="ulong argument value out of
range"/>
<xsl:if/>
<xsl:if/>
</xsl:template>
...

Hope this helps,
Ke

Zen

unread,
Feb 10, 2010, 2:03:14 PM2/10/10
to pococapsule

Thanks for the reply but I think you misunderstood me.
Or I'm misunderstanding you.

The problem is not with the error handling in itself.
It is that unsigned long values are automatically transformed to the
max value of signed long.
The max value of unsigned long on Win32 is at least 4294967295.
Currently, pococapsule transforms any value larger than 2147483647 to
2147483647.

So try do this:

class MyClass
{
public:
MyClass(unsigned long u) : m_u(u){};
unsigned long m_u;
};

<bean id="Id1" class="MyClass">
<method-arg type="ulong" value="2200000000" />
</bean

MyClass* m = AppCtxt->getBean("Id1");

And you will see that m->m_u will have the value of 2147483647 and not
2200000000 as expected.

Already in the _refl.cc file when extracting the parameter will it be
wrong.
setting a break point in the _refl.cc file:

unsigned long _poco_var_0 = *(double*) (_poco_params[_poco_i++]);

_poco_var_0 will here have the value of 2147483647 and not the
expected 2200000000.

So apparently, either the xml parser messes things up, or pococapsule
when storing the value in the _poco_params array.

regards,
Zen

Ke Jin

unread,
Feb 10, 2010, 3:09:56 PM2/10/10
to pococapsule
I see the problem this time. This seems to be a bug in pxgenproxy
(parser and proxy generator) utility. I will take a more close look
tonight and get back to you asap.

Ke

Ke Jin

unread,
Feb 10, 2010, 9:19:12 PM2/10/10
to pococapsule
Hi Zen,

It is strange that I am not able to reproduce this problem. With the
same xml, my generated proxy code looks perfectly like:

unsigned long _poco_var_0 = *(unsigned long*)
(_poco_params[_poco_i++]);

Certainly, my test was made on linux. However, the proxy generator is
in pure Java and should make difference due to platforms in this
trival case.

Ke

On Feb 10, 11:03 am, Zen <per.bohli...@gmail.com> wrote:

Ke Jin

unread,
Feb 10, 2010, 11:53:35 PM2/10/10
to pococapsule
Hi Zen,

After more tests, I got the following conclusion:

1. The generated code that casts from double to unsigned long is
believed to be either a typo in your post, or a result of manual
modifion on your generated code. I don't see this bug in my test,
neither see how it could be possible from the parser and proxy
generator's logic.

2. The problem of unsigned long being truncated to 2147483647 turns
out to be caused by the C function atol(). It is also reproducable on
Linux with a very simple test code like:

#include <stdio.h>
#include <stdlib.h>

main() {
const char* s = "2200000000";
unsigned long a = atol(s);
unsigned long b = strtoul(s, NULL, 0);
printf("%lu, %lu\n", a, b);
}

It prints out:

2147483647, 2200000000

I will change the code from atol() to strtoul(). Before this, you
would have to use some value less than 2G.

Thanks again for reporting this bug.
Ke

On Feb 10, 11:03 am, Zen <per.bohli...@gmail.com> wrote:

Zen

unread,
Feb 11, 2010, 6:20:42 AM2/11/10
to pococapsule

You are absolutely right. I made a typo in my post.
The generated code is of course:

unsigned long _poco_var_0 = *(unsigned long*) (_poco_params[_poco_i+
+]);

2. in your listing is as far as I can tell the correct interpretation
of the bug.

Sorry for the confusion brought on by my sloppy fingers.

I found a work around in the form of abstracting it through a
reference and a macro.
This is not the exact solution but should give people an idea. (this
code might not run)

#define CREATEULONG(x, y) ( (unsigned long) ( (unsigned long)x *
(unsigned long)y) ) )

<bean id="Id1" class="MyClass">

<method-arg ref="ULong22" />
</bean>

<bean id="ULong22" class="*unsigned long" factory-
method="CREATEULONG">
<method-arg type="ulong" value="110000000" />
<method-arg type="ulong" value="2" />
</bean>

Regards,
Zen

Ke Jin

unread,
Feb 11, 2010, 1:32:01 PM2/11/10
to pococapsule
Hi Zen,

Yes, that workaround should work. I just filed a bug: <http://
code.google.com/p/pococapsule/issues/detail?id=9>.

Thanks again!
Ke

Reply all
Reply to author
Forward
0 new messages