Unterminated String Error 1033

Technical support and scripting issues

Moderators: Dorian (MJT support), JRL

chihuahualand
Junior Coder
Posts: 35
Joined: Thu Jan 12, 2006 9:20 pm
Contact:

Unterminated String Error 1033

Post by chihuahualand » Tue Feb 24, 2009 8:44 pm

or Unterminated String Constant

I get this error in Version 7.4.009 and Version 11.whatever

I'm reading the Volume Info on a DVD.
%info_2% returns with the information, but, all attempts to trim this variable (from length 255) have failed.
Various VBEvals, LET's, StringReplace, IF's have failed.
I assume the string is null terminated, but, I can't replace the null character.

My best attempt was
IF>{%m1% .lt. " "}, label2
(sorry, having troubles using the less than sign in this submission)

, which worked... other than the error dialog. In other words, it kicked out the error, but, evaluated correctly and jumped to LABEL2.

The error dialog box occurs on any VBEval, IF or complex LET.

In this example code the error occurs on the "character" just past the end on the readable volume name text returned in info_2 in the VBEval>M("%M1%"),Q statement. For instance, if the DVD label was TITANIC, the error occurs when X=8.

The code below is some incarnation of an attempt to identify the culprit.

Any suggestions?

Code: Select all

VBSTART
Function M(a)
 M = asc(a)
End Function
VBEND
VBEval>CHR(0),NullChar
LibFunc>kernel32,GetVolumeInformationA,info,S:\,str REF:0,200,REF:0,REF:0,REF:0,str REF:0,255
**BREAKPOINT**
let>t=%info_2%
let>t=%info_2%
Length>%t%,lv
let>m2=
Let>x=0
Label>Label1
Let>x=x+1
MidStr>t,x,1,M1
VBEval>M("%M1%"),Q
goto>Label1

Label>Label2
Let>lv=%lv%-2
MidStr>%info_2%,1,20,t
Length>%t%,lv
VBEval>Replace("%t%",chr(0),""),t
VBEval>Replace("%t%",chr(13),""),t
VBEval>Replace("%t%",chr(10),""),t
VBEval>Trim("%t%"),t
len>%t%,L
MessageModal> 1=%info_1%
MessageModal> len=%L%
MessageModal> Label: ~%t%~
MessageModal> s/n:%info_4%, type:%info_7%

Last edited by chihuahualand on Tue Feb 24, 2009 10:07 pm, edited 1 time in total.

User avatar
Bob Hansen
Automation Wizard
Posts: 2475
Joined: Tue Sep 24, 2002 3:47 am
Location: Salem, New Hampshire, US
Contact:

Post by Bob Hansen » Tue Feb 24, 2009 10:06 pm

Assuming this is correct:

Code: Select all

VBSTART
Function M(a)
 M = asc(a)
End Function
VBEND
VBEval>CHR(0),NullChar
LibFunc>kernel32,GetVolumeInformationA,info,S:\,str REF:0,200,REF:0,REF:0,REF:0,str REF:0,255
let>t=%info_2%
Just add:

Code: Select all

MidStr>%info_2%,1,255,vT
MessageModal>The first 255 chars are: %vT%
Here is a test of a 300 char string trimmed to 255:

Code: Select all

Let>info_2=123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789112345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678921234567890123456789012345678901234567890123456789512345678961234567897123456789812345678991234567893
Let>t=%info_2%
MidStr>%info_2%,1,255,vT
MessageModal>The first 255 chars are: %vT%
Hope this was helpful..................good luck,
Bob
A humble man and PROUD of it!

User avatar
JRL
Automation Wizard
Posts: 3526
Joined: Mon Jan 10, 2005 6:22 pm
Location: Iowa

Post by JRL » Tue Feb 24, 2009 10:21 pm

Or how about:

Code: Select all

VBSTART
VBEND
VBEval>CHR(0),NullChar

LibFunc>kernel32,GetVolumeInformationA,info,E:\,str REF:0,200,REF:0,REF:0,REF:0,str REF:0,255
Separate>%info_2%,%NullChar%,var
MDL>var_1

chihuahualand
Junior Coder
Posts: 35
Joined: Thu Jan 12, 2006 9:20 pm
Contact:

Post by chihuahualand » Tue Feb 24, 2009 10:23 pm

I'm using version 7.4.009 because that's what I own, but the trialware of the current MS reproduces the same error.

I think you suggested this...

Code: Select all

LibFunc>kernel32,GetVolumeInformationA,info,S:\,str REF:0,200,REF:0,REF:0,REF:0,str REF:0,255
//let>t=%info_2%
//let>t=%info_2%
MidStr>%info_2%,1,255,t
MidStr>%info_2%,1,255,t
Why twice do you ask??? 'cause it work transfer to %T% if I only do it once. weird.

No luck, same error. For that matter,

Code: Select all

LibFunc>kernel32,GetVolumeInformationA,info,S:\,str REF:0,200,REF:0,REF:0,REF:0,str REF:0,255
//let>t=%info_2%
//let>t=%info_2%
MidStr>%info_2%,1,30,t
MidStr>%info_2%,1,30,t
produces the same error code and dialog box. Anything that leaves the n+1 character in the string... and I'm never sure what "n" is, hence my problem.

chihuahualand
Junior Coder
Posts: 35
Joined: Thu Jan 12, 2006 9:20 pm
Contact:

Post by chihuahualand » Tue Feb 24, 2009 10:29 pm

Thank you.

This worked:

Code: Select all

Separate>%info_2%,%NullChar%,var
Separate>%info_2%,%NullChar%,var
Let>t=var_1


I still don't understand why I have to do it twice, but, that's an easy workaround.

User avatar
jpuziano
Automation Wizard
Posts: 1085
Joined: Sat Oct 30, 2004 12:00 am

Post by jpuziano » Tue Feb 24, 2009 10:38 pm

chihuahualand wrote:Thank you.

This worked:

Code: Select all

Separate>%info_2%,%NullChar%,var
Separate>%info_2%,%NullChar%,var
Let>t=var_1


I still don't understand why I have to do it twice, but, that's an easy workaround.
Need to do it twice? Odd, I would think the results would be the same after running that line just once. Maybe you found a bug? Did you step through with the debugger and watch the values change?

Can you post the whole script or at least a functional chunk so that we can see what may be happening?
jpuziano

Note: If anyone else on the planet would find the following useful...
[Open] PlayWav command that plays from embedded script data
...then please add your thoughts/support at the above post - :-)

User avatar
JRL
Automation Wizard
Posts: 3526
Joined: Mon Jan 10, 2005 6:22 pm
Location: Iowa

Post by JRL » Tue Feb 24, 2009 10:43 pm

Glad that worked.
I still don't understand why I have to do it twice
It makes no sense that you'd have to use the same line twice. Are you stepping through the script in the editor? What do the values of var_? become the first time through?

I also have a comment:
I don't like to see anyone using single characters as variable names. I have seen too many instances where that has gotten people into trouble. There are no "classes" in Macro Scheduler so setting a variable sets that text to a value other than itself. Use caution or better yet, use longer more descriptive variable names.

chihuahualand
Junior Coder
Posts: 35
Joined: Thu Jan 12, 2006 9:20 pm
Contact:

Post by chihuahualand » Tue Feb 24, 2009 11:16 pm

When I step F8
MessageModal = %var_1%

When run, MessageModal is correct.

User avatar
JRL
Automation Wizard
Posts: 3526
Joined: Mon Jan 10, 2005 6:22 pm
Location: Iowa

Post by JRL » Wed Feb 25, 2009 2:53 am

The only reason I can imagine for failure when stepping and success when running is that the stepping did not start at the first line of the script. Be sure you either pick on the first line before you begin stepping though the script, or make sure that "Run From Top" is selected under the "Debug" menu item in the editor.

Also, I hope you caught that I reposted your Libfunc> script line incorrectly. I changed your S:\ to my E:\ so that I could test on my computer. I neglected to return the line to your desired condition before reposting. I apologize if it caused you any inconvenience. Below is the correct script for you.

Code: Select all

VBSTART
VBEND
VBEval>CHR(0),NullChar

LibFunc>kernel32,GetVolumeInformationA,info,S:\,str REF:0,200,REF:0,REF:0,REF:0,str REF:0,255
Separate>%info_2%,%NullChar%,var
MDL>var_1

chihuahualand
Junior Coder
Posts: 35
Joined: Thu Jan 12, 2006 9:20 pm
Contact:

Post by chihuahualand » Wed Feb 25, 2009 4:15 am

I generally save the program. Re-open the editor and run the program from the first line.

I added the comment line at the top of the program to see if that would alter the behavior, it didn't.

FYI, I save the program, close the editor, and re-open the editor most times. If I don't, I risk losing program changes to the point of starting the editor... not just the last save.

This is a clean (and recent) WINXP MCE SP3 install. I am running MS v7.4.009. The MS is fairly dated, but, it does everything I need it to do.

It seems to be directly related to stepping through the program ( F8 ), so it's easily managed.
Last edited by chihuahualand on Wed Feb 25, 2009 6:00 am, edited 1 time in total.

User avatar
JRL
Automation Wizard
Posts: 3526
Joined: Mon Jan 10, 2005 6:22 pm
Location: Iowa

Post by JRL » Wed Feb 25, 2009 4:33 am

I don't have version 7.4 to test but I still have a copy of 7.3. The script runs flawlessly for me using version 7.3 both in the editor and from the main menu.

User avatar
jpuziano
Automation Wizard
Posts: 1085
Joined: Sat Oct 30, 2004 12:00 am

Post by jpuziano » Wed Feb 25, 2009 7:32 am

Hi chihuahualand,
chihuahualand wrote:This is a clean (and recent) WINXP MCE SP3 install. I am running MS v7.4.009. The MS is fairly dated, but, it does everything I need it to do.

It seems to be directly related to stepping through the program (F8), so it's easily managed.
It must be something with that old 7.4.009 version because it works fine for me in 11.1.04 even when single stepping in the debugger.

I went back and played with your original code as posted and generated the same error:
error wrote:Microsoft VBScript compilation error :1033
Unterminated string constant
Line 4, Column 3
That happened at the point where it tried to pass a null character to your VBscript function... evidently VBscript does not like that. I am not sure it if is possible to "escape" the null character and pass it anyway, probably not... but if anyone knows how, please fill us in.
chihuahualand wrote:I'm reading the Volume Info on a DVD.
%info_2% returns with the information, but, all attempts to trim this variable (from length 255) have failed.
Various VBEvals, LET's, StringReplace, IF's have failed.
I assume the string is null terminated, but, I can't replace the null character.
I tried this too and all I can say is... I feel your pain. I did manage to get it down from 255 chars to 245 chars by removing spaces... but the null characters (there are 124 of them in that variable) could not be removed or replaced by any method I tried.

The following section from this post: removing trailing ascii(0) made me think it was possible...
mtettmar wrote:0 is a null char. It normally marks the end of a string.

But, you could try:

VBSTART
VBEND
VBEval>CHR(0),NullChar

StringReplace>text,NullChar,,text
...but the Length> command showed the variable length as 255 both before and after doing the above so there was no effect.

Sidenote: Marcus... is the StringReplace> command "supposed" to be able to replace null characters within a variable? If so it doesn't but perhaps its just not possible.

Try the code below... preferably single stepping through it in the debugger. It shows an interesting limitation of the MDL> command when displaying variables containing the null character CHR(0).

Note: My DVD drive was at F:\
Before running this, change F:\ in the LinFunc> line below to whatever drive letter you are interested in.

Code: Select all

VBSTART
VBEND
VBEval>CHR(0),NullChar

// GetVolumeInformation Function: http://msdn.microsoft.com/en-us/library/aa364993(VS.85).aspx
LibFunc>kernel32,GetVolumeInformationA,info,F:\,str REF:0,200,REF:0,REF:0,REF:0,str REF:0,255

// At this point, the following variables have been created: 
// INFO_1 contains RootPathName
// INFO_2 contains VolumeNameBuffer
// INFO_3 contains VolumeNameSize
// INFO_4 contains VolumeSerialNumber
// INFO_5 contains MaximumComponentLength
// INFO_6 contains FileSystemFlags
// INFO_7 contains FileSystemNameBuffer
// INFO_8 contains FileSystemNameSize

// I wanted to display them all but this does not work, only the 1st is shown
MDL>%INFO_1% %INFO_2% %INFO_3% %INFO_4% %INFO_5% %INFO_6% %INFO_7% %INFO_8%

// I believe this is because the MDL> command quits after it runs into a null character.
// Many of the above variables actually contain multiple null characters.
// Any attempts to remove or replace the null characters in the above variables failed...
// but if someone else can manage it... I'd love to see it.

// The Separate> command however can separate out all the data between the null characters
// (leaving the null characters behind) and we can then display the values all at once.

Separate>%info_1%,%NullChar%,var1
Separate>%info_2%,%NullChar%,var2
Separate>%info_3%,%NullChar%,var3
Separate>%info_4%,%NullChar%,var4
Separate>%info_5%,%NullChar%,var5
Separate>%info_6%,%NullChar%,var6
Separate>%info_7%,%NullChar%,var7
Separate>%info_8%,%NullChar%,var8

// This works
MDL>%var1_1% %var2_1% %var3_1% %var4_1% %var5_1% %var6_1% %var7_1% %var8_1%

Let>MSG_HEIGHT=230

// With parameter names
MDL>RootPathName: %var1_1%%CRLF%VolumeNameBuffer: %var2_1%%CRLF%VolumeNameSize: %var3_1%%CRLF%VolumeSerialNumber: %var4_1%%CRLF%MaximumComponentLength: %var5_1%%CRLF%FileSystemFlags: %var6_1%%CRLF%FileSystemNameBuffer: %var7_1%%CRLF%FileSystemNameSize: %var8_1%
And here's another way to do it... without using the Separate> command:

Code: Select all

VBSTART
VBEND
VBEval>CHR(0),NullChar

// GetVolumeInformation Function: http://msdn.microsoft.com/en-us/library/aa364993(VS.85).aspx
LibFunc>kernel32,GetVolumeInformationA,info,C:\,str REF:0,200,REF:0,REF:0,REF:0,str REF:0,255

// At this point, the following variables have been created: 
// INFO_1 contains RootPathName
// INFO_2 contains VolumeNameBuffer
// INFO_3 contains VolumeNameSize
// INFO_4 contains VolumeSerialNumber
// INFO_5 contains MaximumComponentLength
// INFO_6 contains FileSystemFlags
// INFO_7 contains FileSystemNameBuffer
// INFO_8 contains FileSystemNameSize

//there's no null characters in info_4
Let>VolumeSerialNumber=info_4

//extract the data from info_2 leaving the null characters behind
Let>VolumeName=
Let>char_position=0

Label>Loop
Let>char_position=char_position+1
MidStr>info_2,char_position,1,one_char
If>one_char=NullChar,display_values
ConCat>VolumeName,one_char
Goto>Loop

Label>display_values
// display VolumeName and VolumeSerialNumber in one MDL>
MDL>VolumeName: %VolumeName%%CRLF%VolumeSerialNumber: %VolumeSerialNumber%
Finally, a challenge for the gurus out there - a bounty on null character string cleansing.

2 points goes to the first person who can take the script below and add code to strip out the null characters and any other characters not part of the actual VolumeName data in the info_2 variable... i.e. if the first MDL> shows VolumeName: My_Disk then the info_2 variable should actually be 7 chars long and the second MDL> should show VolumeName Length: 7

- without using the Separate> command
- without resorting to using a command like MidStr> to extract a single character substring and comparing it to a NullChar variable... over and over throughout the string like in the example above
- anything else is allowed, RegEx, StringReplace>, VBscript, etc.
- Marcus, if you have a solution, please wait until the others have had a chance

Code: Select all

LibFunc>kernel32,GetVolumeInformationA,info,C:\,str REF:0,200,REF:0,REF:0,REF:0,str REF:0,255

MDL>VolumeName: %info_2%

Length>info_2,Length_info_2

MDL>VolumeName Length: %Length_info_2%
jpuziano

Note: If anyone else on the planet would find the following useful...
[Open] PlayWav command that plays from embedded script data
...then please add your thoughts/support at the above post - :-)

User avatar
Marcus Tettmar
Site Admin
Posts: 7395
Joined: Thu Sep 19, 2002 3:00 pm
Location: Dorset, UK
Contact:

Post by Marcus Tettmar » Wed Feb 25, 2009 12:41 pm

StringReplace is not supposed to use null chars as delimiters, no.

You really want me to hold off? All you need is two lines of code.
Marcus Tettmar
http://mjtnet.com/blog/ | http://twitter.com/marcustettmar

Did you know we are now offering affordable monthly subscriptions for Macro Scheduler Standard?

chihuahualand
Junior Coder
Posts: 35
Joined: Thu Jan 12, 2006 9:20 pm
Contact:

Post by chihuahualand » Wed Feb 25, 2009 1:42 pm

wow.

you are correct about Null. Most things in MS hate them:

VBEval
IF>{}
LET>{} (complex)

Some just ignore them:
StringReplace

But oddly, this works:

Separate>%info_2%,%NullChar%,var
(as suggested by JRL)

and probably for most situations fulfills the task. This would likely only be used for something null terminated... and who would use null delimited, that would be crazy. You get %var_1% and the rest can be ignored. While a "programmers sin", it works (it can generate lots of extra unneeded variables, i.e. %var_count%=214). Side note: On the same DVD, same code, v7.4.009 shows %var_count%=214, v 11.1.04e shows %var_count%=3

I reproduced this error "Unterminated String Error 1033, Line 3, Column 3" in v7.4.009 and v11.1.04e on all on the various VBEval's I tried at the point of passing the single null character or a variable with a null character embedded.

in regards to v7.4.009 only:
As a separate topic, possibly completely separate, I have to repeat the command for the code to work while step-debugging, as in:

Separate>%info_2%,%NullChar%,var
Separate>%info_2%,%NullChar%,var

There is every indication that nothing happened on the first execution: no %var_1%, etc. in the watch list and a MessageModal>%var_1% produces "%var_1%"

again, this makes me feel dirty, but, I'll live with my dirty little secret.

Conclusion:

Use: Separate>%info_2%,%NullChar%,var
and don't sweat the details.

User avatar
Marcus Tettmar
Site Admin
Posts: 7395
Joined: Thu Sep 19, 2002 3:00 pm
Location: Dorset, UK
Contact:

Post by Marcus Tettmar » Wed Feb 25, 2009 1:53 pm

This is how I would do it (and how I would expect to see it)

VBEval>chr(0),NullChar
Pos>NullChar,info_2,1,nPos
MidStr>info_2,1,{%nPos%-1},Volume_Name

E.g.:

Code: Select all

VBSTART
VBEND

LibFunc>kernel32,GetVolumeInformationA,info,C:\,str:volname,REF:200,REF:200,REF:0,REF:0,str:sysname,255

VBEval>chr(0),NullChar
Pos>NullChar,info_2,1,nPos
MidStr>info_2,1,{%nPos%-1},Volume_Name

MessageModal>VolumeName: %Volume_Name%

Length>Volume_Name,Length_info_2
MessageModal>VolumeName Length: %Length_info_2%
Marcus Tettmar
http://mjtnet.com/blog/ | http://twitter.com/marcustettmar

Did you know we are now offering affordable monthly subscriptions for Macro Scheduler Standard?

Post Reply
cron
Sign up to our newsletter for free automation tips, tricks & discounts