Issue 115795 - basic: specify how to pass strings as any to declared subroutines
Summary: basic: specify how to pass strings as any to declared subroutines
Status: CLOSED FIXED
Alias: None
Product: General
Classification: Code
Component: code (show other issues)
Version: DEV300m94
Hardware: All All
: P2 Trivial (vote)
Target Milestone: 3.4.0
Assignee: b.osi.ooo
QA Contact: issues@framework
URL:
Keywords: regression
Depends on:
Blocks:
 
Reported: 2010-11-26 12:37 UTC by Stephan Bergmann
Modified: 2017-05-20 10:30 UTC (History)
5 users (show)

See Also:
Issue Type: DEFECT
Latest Confirmation in: ---
Developer Difficulty: ---


Attachments
Test script to check vbaoption related behavior (1.32 KB, text/plain)
2011-02-21 11:47 UTC, ab
no flags Details

Note You need to log in before you can comment on or make changes to this issue.
Description Stephan Bergmann 2010-11-26 12:37:47 UTC
Issue 115716 brings up the following problem:  Given

Declare Function RegSetValueExTest Lib "advapi32.dll" Alias "RegSetValueExA"
(ByVal hKey As Long, ByVal lpValueName As String, ByVal Reserved As Long, ByVal
dwType As Long, lpData As Any, ByVal cbData As Long) As Long
'...
Dim sValue As String
sValue = "THIS IS A TEST"
'...
RegSetValueExTest(hKey, "OOo_TEST_DATA", 0&, REG_SZ, sValue, Len(sValue))

how shall the string value sValue be marshaled as the lpData parameter of type
"Any"?

First interpretation:  Since the lpData parameter is implicitly declared as
"ByRef" (as there is no explicit "ByVal"), the string is marshaled as a
reference to a string, i.e., on the stack is a pointer to a pointer to character
data (char **).  This is how the current (DEV300_m94) implementation behaves. 
The old (OOo 3.2) implementation erroneously(?) always passed ByRef string
values the same way as ByVal string values (on the stack is a pointer to
character data -- char *).  So, in OOo 3.2 the above code (see issue 115716 for
the complete test code) happened to correctly pass "THIS IS A TEST" to
RegSetValueExA, while it now passes garbage.  Under this interpretation, the
above test code would be wrong, would have worked in OOo 3.2 by coincidence, and
would need to be fixed by explicitly marking the lpData parameter as "ByVal".

Second interpretation:  The lpData parameter is "ByRef", so that actual values
of, say, integer type would indeed be passed by address.  However, as a special
case, actual values of string type should not be passed as ByRef strings (i.e.,
as char **), but as ByVal strings (i.e., as char *).  Under this interpretation,
the above test code is right, and the current implementation needs to be fixed
to handle that special case correctly.

It needs to be specified which interpretation to chose, and, in case of the
second, the code needs to be fixed.
Comment 1 Mechtilde 2010-11-26 15:21:02 UTC
add to CC
Comment 2 ab 2010-12-06 10:17:12 UTC
STARTED
Comment 3 Stephan Bergmann 2011-01-20 16:13:23 UTC
@ab:  A related problem (related to how Basic generally passes ByRef strings
with "external DLL" calls, and how that changed for OOo 3.3) has come up in the
mail thread at
<http://extensions.openoffice.org/servlets/ReadMsg?list=dev&msgNo=2031>:  In the
ImportWizard.API module that is part of the standard OpenOffice.org Macros,
RegQueryValueExString is declared as an alias for RegQueryValueExA with
(implicitly ByRef) "lpData As String" parameter.  This causes code that uses
that function to fail (e.g., as explained in the mail, 'MsgBox
ImportWizard.API.QueryValue(HKEY_CURRENT_USER,
"Software\Microsoft\Notepad","szTrailer")' displays an empty string).  If the
relevant ImportWizard.API module code is changed to "ByVal lpData As String" the
given test would succeed.

The assumption might turn out wrong after all that OOo 3.2's handling ByRef
string parameters in "external DLL" calls the same as ByVal was erroneous.  (I
was not aware that the Basic "external DLL" feature was used in the standard
OpenOffice.org Macros, and apparently neither were the QA people for issue
115716 and the original Hamburg-internal issue #162141#, or else this would have
been tested.)
Comment 4 Oliver Brinzing 2011-01-20 17:02:12 UTC
.
Comment 5 Hans Zybura 2011-01-26 11:33:36 UTC
What this issue describes in a somewhat obscure way is a total block for all
calls via OOBasic to the Windows registry, which ask for string values. Our
large extension for teachers and schools relies on the functionality in the
standard module "ImportWizard.API" and now is effectively rendered useless with
OOo 3.3RC10 and presumably the final release. A lot of other extensions will be
affected.

Why has this issue priority P3, a nebulous target milestone "OOo 3.x", why is
keyword "regression" missing though Oliver Brinzing and Stephan Bergmann have
both called this a regression in a discussion on the
dev@extensions.openoffice.org mailing list?

The solution given by Stephan Bergmann

>If the relevant ImportWizard.API module code is changed to "ByVal lpData As
>String" the given test would succeed."

does not work, at least not for OOo 3.3RC10. In RC10, the following simple Basic
test lines still produce an empty message box, though the registry value is
"Seite &s" (in a German Windows, it's language specific).

Sub TestAPICall
MsgBox ImportWizard.API.QueryValue(HKEY_CURRENT_USER,
"Software\Microsoft\Notepad","szTrailer")
End Sub

Hans Zybura
Comment 6 Stephan Bergmann 2011-01-26 12:43:44 UTC
@hansz:  the workaround also requires the fix for issue 115716, which has only been fixed on 
DEV300_m98 towards OOo 3.4
Comment 7 kai.sommerfeld 2011-02-09 15:54:11 UTC
.
Comment 8 ab 2011-02-15 14:42:48 UTC
FIXED
Comment 9 Stephan Bergmann 2011-02-15 14:46:46 UTC
reviewed change
Comment 10 ab 2011-02-21 11:41:34 UTC
A LoadLibrary call should be added to the test sub:
Sub TestAPICall
BasicLibraries.LoadLibrary( "ImportWizard" )
MsgBox
ImportWizard.API.QueryValue(HKEY_CURRENT_USER,"Software\Microsoft\Notepad","szTrailer")
End Sub
Comment 11 ab 2011-02-21 11:47:01 UTC
Created attachment 75904 [details]
Test script to check vbaoption related behavior
Comment 12 ab 2011-02-21 12:05:23 UTC
ab->tbo: Please verify by using TestAPICall (should display
something reasonable like "page &p") and by using the attached
i115795_RegSetValueEx.bas macro. The latter is to test assure
that in vba mode the new behavior is still used as in this con-
text it's correct.