Bug Hunting Session
Bug 62326 - Instruction Cint fails when converting Hex strings of a negative value to a 16-bit integer value.
Summary: Instruction Cint fails when converting Hex strings of a negative value to a 1...
Status: RESOLVED FIXED
Alias: None
Product: LibreOffice
Classification: Unclassified
Component: BASIC (show other bugs)
Version:
(earliest affected)
3.3.0 release
Hardware: All All
: medium normal
Assignee: Andreas Heinisch
URL:
Whiteboard: target:6.4.0
Keywords:
Depends on:
Blocks: Macro-StarBasic
  Show dependency treegraph
 
Reported: 2013-03-14 08:45 UTC by irs
Modified: 2019-09-30 13:46 UTC (History)
6 users (show)

See Also:
Crash report or crash signature:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description irs 2013-03-14 08:45:54 UTC
Problem Statement: LibreOffice execution of a BASIC macro stream will fail upon the instruction Cint when converting Hex strings of a negative value to a 16-bit integer value.

Program execution is halted and the error message displayed is: “Inadmissible value or data type. Overflow”.

If the same BASIC code is run on Visual Basic V6.0 or the Visual Basic V6.5 included with MS Office 2003, then it executes without errors.

BASIC code that demonstrates the problem:

Sub Example_Code_For_Integer()
  dim intDecimal as integer

  ' Testing Positive Hex string converted to 16-bit integer - OK
  intDecimal = Cint(&H0)
  msgbox "Cint(&H0): " & Cstr(intDecimal) 
  'should be: 0 - OK

  intDecimal = cint(&H7FFF)
  msgbox "Cint(&H7FFF): " & Cstr(intDecimal) 
  'should be: 32767 - OK

  '=====

  ' Testing Negative Hex string converted to 16-bit integer - Fails 

  intDecimal = Cint(&HFFFF)
  msgbox "Cint(&HFFFF): " & Cstr(intDecimal) 
  'should be: -1 - Fails with Overflow error

  intDecimal = Cint(&H8000)
  msgbox "Cint(&H8000): " & Cstr(intDecimal) 
  'should be: -32768 - Fails with Overflow error

end sub

Note1: The above code was found to fail on the following LibreOffice platforms: 
LibreOffice 4.0.1.2 on WindowsXP SP3
LibreOffice 3.6.2.2 on Ubuntu 12.10 (quantal) 32-bit Linux 3.5.0-21
OpenOffice 3.2.1 on Ubuntu 10.10 (maverick) 32 bit Linux 2.6.35-22 
LibreOffice 3.3.3 Ubuntu 11.04 (natty) 32-bit Linux 2.6.38-11-generic 
LibreOffice 4.0.1.2 on Debian 6.0.7 (squeeze) 64-bit Linux 2.6.32-5-amd64.
 
Note2: I don't have a Mac to test whether or not this problem exists on the Mac / LibreOffice platform.

Note3: I have posted Bug 62323. It is similar to this bug, however it is specific to the LibreOffice Linux 64-bit/AMD release and occurs using when the Clng instruction. 

Regards, ian.
Comment 1 Joel Madero 2013-03-19 20:32:57 UTC
As you have stated the bug existed in an older release I am updating version. Our version field represents the oldest release we see the problem, not the latest it's been tested on - we use comments to say "still exists in version x.x.x.x). Thanks!
Comment 2 irs 2013-03-19 22:55:15 UTC
Hi Joel, 

Thanks for explaining the "Version" field in Bug header section and correcting it to refect the first LibreOffice version release of V3.3.0. 

Cheers, Ian.
Comment 3 Robinson Tryon (qubit) 2013-12-18 18:35:03 UTC
TESTING on LO 4.2.0.0.beta2 on Ubuntu 12.04.3

(In reply to comment #0)
>

Repro steps:
1) Open LO Writer
2) Tools -> Macros -> Organize Macros -> LibreOffice Basic
3) Click on 'Untitled 1', then the 'New' button
4) In the code window that appears, dump the BASIC code (Comment 0) into the file above the opening of the Main sub.
5) Inside the Main sub, call the function;

Sub Main
  Example_Code_For_Integer()
End Sub

6) Run the code (F5)

Result:
See dialog box: "Cint(&H0): 0" with OK button

7) click the OK button

Result:
See dialog box: "Cint(&H7FFF): 32767" with OK button

8) click the OK button

Result:
See dialog box: "Inadmissible value or data type.\nOverflow."

(At this point program execution ended, so we didn't see the last msgBox)

> Program execution is halted and the error message displayed is:
> “Inadmissible value or data type. Overflow”.

Yep.

It's not clear to me if this behavior is as-expected, or is a bug.

> If the same BASIC code is run on Visual Basic V6.0 or the Visual Basic V6.5
> included with MS Office 2003, then it executes without errors.
> 

Interoperability is a strong reason to try to accept this input, even if it does take some development and testing.
Comment 4 irs 2014-01-06 09:01:57 UTC
(In reply to comment #3)
> TESTING on LO 4.2.0.0.beta2 on Ubuntu 12.04.3
> > Program execution is halted and the error message displayed is:
> > “Inadmissible value or data type. Overflow”.
> 
> Yep.
> 
> It's not clear to me if this behavior is as-expected, or is a bug.
> 
> > If the same BASIC code is run on Visual Basic V6.0 or the Visual Basic V6.5
> > included with MS Office 2003, then it executes without errors.
> > 
> 
> Interoperability is a strong reason to try to accept this input, even if it
> does take some development and testing.


Hi Qubit,

I am pleased you can reproduce the "bug". From my latest testing using Linux (64-bit) 3.11.0-15-generic and LibreOffice 4.1.3.2 410m0(Build:2) this Cint() problem still exists.

Please note that this bug regarding the BASIC function Cint() is similar to Bug 62323 which concerned the BASIC function Clng().

Noel Power fixed the problem with Clng() converting negative hex strings by patching /basic/source/comp/scanner.cxx. Maybe additional patching to this scanner.cxx file may fix the problem.

regards, Ian.
Comment 5 tommy27 2016-04-16 07:23:02 UTC Comment hidden (obsolete)
Comment 6 QA Administrators 2017-05-22 13:22:42 UTC Comment hidden (obsolete)
Comment 7 irs 2017-11-27 23:14:11 UTC
Using LO Version: 5.4.1.2 / Build ID: 1:5.4.1-0ubuntu1 I have performed the tests that are in this bugs Description. The bug is still present and the failure messages are still the same.

Regards ian.
Comment 8 QA Administrators 2018-11-28 03:47:32 UTC Comment hidden (obsolete)
Comment 9 irs 2019-03-27 21:49:31 UTC
Hi Using the test method in the original Description posting, the problem still exists with Libreoffice:

Version: 6.0.7.3
Build ID: 1:6.0.7-0ubuntu0.18.04.2
CPU threads: 2; OS: Linux 4.15; UI render: default; VCL: gtk3; 
Locale: en-NZ (en_NZ.UTF-8); Calc: group

regards, Ian.
Comment 10 Mike Kaganski 2019-09-19 07:33:47 UTC
For the record (from IRC discussion, thanks sberg!):

CInt function help page [1] tells:
"If the Expression exceeds the value range between -32768 and 32767, LibreOffice Basic reports an overflow error".

VBA returns -1 for CInt(&HFFFF), but throws Overflow for CInt(65535).

Possibly we could treat &HFFFF (hex!) as VBA does (as the negative value), or change the treatment only for 'Option VBASupport 1' case.

[1] https://help.libreoffice.org/6.3/en-US/text/sbasic/shared/03100500.html
Comment 11 Stephan Bergmann 2019-09-19 07:50:58 UTC
(In reply to Mike Kaganski from comment #10)
> VBA returns -1 for CInt(&HFFFF), but throws Overflow for CInt(65535).

One explanation of that could be that VBA always (i.e., whether or not it is the argument to CInt) interprets the syntax "&HFFFF" as representing integral value -1.  I couldn't find a description of &H at <https://docs.microsoft.com/en-us/office/vba/api/overview/language-reference>.
Comment 12 Mike Kaganski 2019-09-19 07:52:46 UTC
VBA documentation discusses "&HXXXX" syntax with Hex function [1]. It seems to treat the &H notation as a kind of function opposite to Hex(). Testing the syntax in VBA like this:

Dim i As Long
i = &HFFFF
MsgBox i

I get "-1" in the resulting message box. So it seems that when 4 hex digits are passed to the "&H", it treats them as Integer type, and returns the signed result.

[1] https://docs.microsoft.com/en-us/office/vba/Language/Reference/user-interface-help/hex-function
Comment 13 Mike Kaganski 2019-09-19 08:05:57 UTC
And just for completeness, VBA gives these conversions:

&HF=15
&HFF=255
&HFFF=4095
&HFFFF=-1
&HFFFFF=1048575
&HFFFFFF=16777215
&HFFFFFFF=268435455
&HFFFFFFFF=-1
Comment 14 LibreOfficiant 2019-09-19 08:35:23 UTC
(In reply to Mike Kaganski from comment #10)
> For the record (from IRC discussion, thanks sberg!):
> 
> CInt function help page [1] tells:
> "If the Expression exceeds the value range between -32768 and 32767,
> LibreOffice Basic reports an overflow error".
> 
> VBA returns -1 for CInt(&HFFFF), but throws Overflow for CInt(65535).
> 
> Possibly we could treat &HFFFF (hex!) as VBA does (as the negative value),
> or change the treatment only for 'Option VBASupport 1' case.
> 
> [1] https://help.libreoffice.org/6.3/en-US/text/sbasic/shared/03100500.html

cf. https://en.wikipedia.org/wiki/Signed_number_representations
Comment 15 Mike Kaganski 2019-09-19 08:42:44 UTC
Some more observations.

There is another mention of the "&H" syntax in VBA documentation, though not strictly related - in Val() function [1]; it explicitly mentions converting *string* "&HFFFF" to -1.

The following code:

MsgBox "&H" & Hex(65535)
MsgBox "&H" & Hex(-1)

... gives "&HFFFF" both times both in VBA *and LibreOffice, regardless of VBASupport mode*.

[1] https://docs.microsoft.com/en-us/office/vba/language/reference/user-interface-help/val-function
Comment 16 LibreOfficiant 2019-09-19 08:49:34 UTC
I don't see anything wrong in Mike's above statement. Please give this code a try, may be that'll help.

In summary the high-order bit always IS a sign bit, its location differs for Int16 Int32 or Int64 formats.

Sub Macro1
	MIN_INTEGER = -32768 ' = &h8000 = -2^16
	MAX_INTEGER = +32767 ' = &h7FFF =  2^16-1
	Print Hex(-1), Hex(MIN_INTEGER), Hex(MAX_INTEGER)
	MIN_LONG = &h80000000 ' = -2^32
	MAX_LONG = &h7FFFFFFF ' =  2^32-1
	Print Hex(Clng(-1)), Clng(MIN_LONG), Clng(MAX_LONG)
End Sub
Comment 17 Stephan Bergmann 2019-09-19 09:15:32 UTC
(In reply to LibreOfficiant from comment #16)
> I don't see anything wrong in Mike's above statement. Please give this code
> a try, may be that'll help.
> 
> In summary the high-order bit always IS a sign bit, its location differs for
> Int16 Int32 or Int64 formats.

The issue (and where VBA and LO's Basic apparently differ) is in how &H... syntax is interpreted depending on the number of hex digits (ignoring leading zeroes?) present, so that VBA treats "&HFFFF" as -1 (of type Integer, presumably) and "&HFFFFF" as 1048575 (of type Long, presumably), while LO's Basic treats "&HFFFF" as 65536.
Comment 18 LibreOfficiant 2019-09-19 09:53:48 UTC
(In reply to Stephan Bergmann from comment #17)
> (In reply to LibreOfficiant from comment #16)
> > I don't see anything wrong in Mike's above statement. Please give this code
> > a try, may be that'll help.
> > 
> > In summary the high-order bit always IS a sign bit, its location differs for
> > Int16 Int32 or Int64 formats.
> 
> The issue (and where VBA and LO's Basic apparently differ) is in how &H...
> syntax is interpreted depending on the number of hex digits (ignoring
> leading zeroes?) present, so that VBA treats "&HFFFF" as -1 (of type
> Integer, presumably) and "&HFFFFF" as 1048575 (of type Long, presumably),
> while LO's Basic treats "&HFFFF" as 65536.

(In reply to Stephan Bergmann from comment #11)
> (In reply to Mike Kaganski from comment #10)
> > VBA returns -1 for CInt(&HFFFF), but throws Overflow for CInt(65535).
> 
> One explanation of that could be that VBA always (i.e., whether or not it is
> the argument to CInt) interprets the syntax "&HFFFF" as representing
> integral value -1.  I couldn't find a description of &H at
> <https://docs.microsoft.com/en-us/office/vba/api/overview/language-
> reference>.

cf. Literal number construction rules & for &H notation:
https://www.ibm.com/support/knowledgecenter/SSVRGU_9.0.1/basic/LSAZ_LITERAL_NUMBER_CONSTRUCTION_RULES.html

and Int64 derivation to express Currency in Basic:
https://docs.microsoft.com/en-us/office/vba/language/reference/user-interface-help/currency-data-type
Comment 19 Andreas Heinisch 2019-09-19 15:05:30 UTC
I am thinking of several ways in order to resolve this bug and I would appreciate some comments about my proposals:

a) Check the length of the hex string in https://opengrok.libreoffice.org/xref/core/basic/source/comp/scanner.cxx?r=09402293#492:
Determine the datatype of the argument using the length of the string removing leading zeros, so &H0FFFF would be converted to &HFFFF and then classified as SbxINTEGER where the result will be casted to sal_Int16. So the scanner classifies the strings in the range of &H8000 to &HFFFF as signed integers. If the length or the value exceeds the SbxINTEGER range it will be interpreted as long.

b) In the function at https://opengrok.libreoffice.org/xref/core/basic/source/sbx/sbxint.cxx?r=b3447222#58 in the SbxLONG case, there could be added a check where, if we are over SbxMAXINT but under SbxMAXUINT we convert it to a signed integer.

I favour option a) because it targets only this specific case of hex numbers.

What do you think?
Comment 20 LibreOfficiant 2019-09-19 15:20:14 UTC
Option a/ makes sense to me however in order to qualify option b/ I need you to explicit SbxMAXINT and SbxMAXUINT.

I suppose type enforcement suffixing is no supported. Can you confirm?
Comment 21 LibreOfficiant 2019-09-19 15:26:04 UTC
Corrected, enhanced, still unperfect Basic sample that may help 'Support' & 'QA' for extra Unit tests:

Sub Literal_Number_Construction_Rules

Int16: 'As Integer
	MIN_INTEGER = -32768 ' = &h8000 = -2^15
	MAX_INTEGER = +32767 ' = &h7FFF =  2^15-1
	Print Hex(-1), Hex(MIN_INTEGER), Hex(MAX_INTEGER)

Int32: 'As Long
	MIN_LONG = &h80000000 ' = -2^31
	MAX_LONG = &h7FFFFFFF ' =  2^31-1
	Print Hex(Clng(-1)), Clng(MIN_LONG), Clng(MAX_LONG)

Int64_divided_by_10_thousands:
	MIN_Int64 = 2^63
	MAX_Int64 =  (2^63-1)/10000	
	Print Hex(CCur(-1)), CCur(MIN_Int64/10000)," / ", Max_Int64, CCur(MAX_Int64)

End Sub
Comment 22 Andreas Heinisch 2019-09-26 09:36:59 UTC
Any thoughts about "Should this only be done in VBA-compatibility mode?"
-> gerrit.libreoffice.org/#/c/79583/
Comment 23 LibreOfficiant 2019-09-26 10:55:16 UTC
(In reply to Andreas Heinisch from comment #22)
> Any thoughts about "Should this only be done in VBA-compatibility mode?"
> -> gerrit.libreoffice.org/#/c/79583/

&Hxxx behaviour should be identical in either modes. Be they LibO Basic, with Option Compatible, or Option VBA Support 0/1.
Comment 24 Commit Notification 2019-09-27 16:23:30 UTC
Andreas Heinisch committed a patch related to this issue.
It has been pushed to "master":

https://git.libreoffice.org/core/commit/d5b7627a0e738c0866b819910153b96b611813f8

tdf#62326 - Macros: Converting Hex strings of negative value

It will be available in 6.4.0.

The patch should be included in the daily builds available at
https://dev-builds.libreoffice.org/daily/ in the next 24-48 hours. More
information about daily builds can be found at:
https://wiki.documentfoundation.org/Testing_Daily_Builds

Affected users are encouraged to test the fix and report feedback.
Comment 25 Stephan Bergmann 2019-09-27 16:38:28 UTC
(In reply to LibreOfficiant from comment #23)
> (In reply to Andreas Heinisch from comment #22)
> > Any thoughts about "Should this only be done in VBA-compatibility mode?"
> > -> gerrit.libreoffice.org/#/c/79583/
> 
> &Hxxx behaviour should be identical in either modes. Be they LibO Basic,
> with Option Compatible, or Option VBA Support 0/1.

Does that mean that there are more than two modes that LO Basic can be in and which are relevant here?  My naive understanding was that there are just two modes, a "native" and a "VBA-compatibility" one.
Comment 26 LibreOfficiant 2019-09-30 13:26:59 UTC
(In reply to Stephan Bergmann from comment #25)
> (In reply to LibreOfficiant from comment #23)
> > (In reply to Andreas Heinisch from comment #22)
> > > Any thoughts about "Should this only be done in VBA-compatibility mode?"
> > > -> gerrit.libreoffice.org/#/c/79583/
> > 
> > &Hxxx behaviour should be identical in either modes. Be they LibO Basic,
> > with Option Compatible, or Option VBA Support 0/1.
> 
> Does that mean that there are more than two modes that LO Basic can be in
> and which are relevant here?  My naive understanding was that there are just
> two modes, a "native" and a "VBA-compatibility" one.

Hi Stephan

The fact is that "Option VBASupport 1" implies "Option Compatible" and that the reverse is not true.

This leads to situations where coding CompatibilityMode(True) is more necessary at runtime in the latter that in the former.

cf. Mike comments in https://ask.libreoffice.org/en/question/166628/how-to-write-a-function-with-arbitrary-number-of-arguments/ about "Option .."

6.4 help content attempts to "clarify" this.
Comment 27 Stephan Bergmann 2019-09-30 13:32:02 UTC
(In reply to LibreOfficiant from comment #26)
> The fact is that "Option VBASupport 1" implies "Option Compatible" and that
> the reverse is not true.

Ah, so there is three modes,

* No options
* "Option Compatible"
* "Option VBASupport 1" (implies "Option Compatible")

and we need to decide how to interpret &H syntax with values in the range 8000..FFFF for each of the three modes.
Comment 28 LibreOfficiant 2019-09-30 13:40:55 UTC
(In reply to Stephan Bergmann from comment #27)
> (In reply to LibreOfficiant from comment #26)
> > The fact is that "Option VBASupport 1" implies "Option Compatible" and that
> > the reverse is not true.
> 
> Ah, so there is three modes,
> 
> * No options
> * "Option Compatible"
> * "Option VBASupport 1" (implies "Option Compatible")
> 
> and we need to decide how to interpret &H syntax with values in the range
> 8000..FFFF for each of the three modes.

cf. my recommendation in comment #23
Comment 29 Stephan Bergmann 2019-09-30 13:46:43 UTC
(In reply to LibreOfficiant from comment #28)
> (In reply to Stephan Bergmann from comment #27)
> > Ah, so there is three modes,
> > 
> > * No options
> > * "Option Compatible"
> > * "Option VBASupport 1" (implies "Option Compatible")
> > 
> > and we need to decide how to interpret &H syntax with values in the range
> > 8000..FFFF for each of the three modes.
> 
> cf. my recommendation in comment #23

...and now I understand how to parse your "&Hxxx behaviour should be identical in either modes. Be they LibO Basic, with Option Compatible, or Option VBA Support 0/1."  So you suggest to behave the same in all three modes.  (Which would mean that the commit from comment 24 is good as-is.)