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 target:6.5.0 target:7.0.0
Keywords:
Depends on:
Blocks: Macro-StarBasic
  Show dependency treegraph
 
Reported: 2013-03-14 08:45 UTC by irs
Modified: 2020-03-30 06:59 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.)
Comment 30 LibreOfficiant 2019-12-20 15:18:34 UTC
(In reply to Commit Notification from comment #24)
> 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.

Can you confirm if &o (octal) notation has been provided with the same Integer/Long hi-order bits trimming logic?
Comment 31 Andreas Heinisch 2019-12-20 15:28:41 UTC
Hex and Octal strings are processed the same way.
Comment 32 LibreOfficiant 2019-12-22 09:16:41 UTC
Using latest 6.4.x alpha/beta release:

Print Typename(&h7FFF), Typename(&hFFFFF) ' outputs      Integer Double

Returning either Integer, either Long would provide better x-compatibility with VBA or other Basic-like languages such as LotusScript, QBasic, RealBasic..
Comment 33 LibreOfficiant 2019-12-22 10:02:01 UTC
(In reply to LibreOfficiant from comment #32)
> Using latest 6.4.x alpha/beta release:
> 
> Print Typename(&h7FFF), Typename(&hFFFFF) ' outputs      Integer Double
> 
> Returning either Integer, either Long would provide better x-compatibility
> with VBA or other Basic-like languages such as LotusScript, QBasic,
> RealBasic..

Same requirement for &o octal notation
Comment 34 Andreas Heinisch 2019-12-22 11:36:44 UTC
I will send a new patch relating this issue
Comment 35 Commit Notification 2019-12-23 18:33:47 UTC
LibreOfficiant committed a patch related to this issue.
It has been pushed to "master":

https://git.libreoffice.org/help/commit/32de39e587a6b4c1e51c03d0a9497e8c871ac60b

tdf#62326 &o &h literal notations
Comment 36 Andreas Heinisch 2019-12-24 08:49:19 UTC
I think there is another problem too, for instance:

Print TypeName(1048575), Typename(&hFFFFF) ' outputs      Double Double

Should we open a new bug for this one?
Comment 37 Mike Kaganski 2019-12-24 09:09:10 UTC
(In reply to Andreas Heinisch from comment #36)

Please do.
Comment 39 Commit Notification 2020-03-30 06:59:05 UTC
Andreas Heinisch committed a patch related to this issue.
It has been pushed to "master":

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

Cleanup for tdf#130476, tdf#62323 and tdf#62326

It will be available in 7.0.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.