Sorry, Mike... you're not quite correct here.
This turned out to be way long but maybe instructional? At least I hope so!
Thanks for the correction. I was almost there in my thinking... but you can't read what I was thinking only what I type. :)
Just to help me to understand. Based on the "faulty" way the program was coded...The encoded data was in req and req was 1000A variable (after the pointer was assigned). That would be correct? But it would not be correct to say that the encoded data was 1000 long because it was only as long as needed. Even thinking of req being 1000A is kind of wrong. In debug, req was not a "regular" RPG variable as it was undefined when the program first starts running (hence no initialization of values to blanks). But once the pointer gets a value, it does look at the next 1000 uninitialized bytes (except that the bytes in this program are initialized by the encoding routine)?
When I ran the program through debug several times, I was consistently seeing ALL x'00' after the encoded data in the req field. I actually thought I should see "garbage" or spaces out beyond his data but it always seems to be x'00'. So, I took a SWAG that something in the encoder allocation logic was resetting the memory to x'00' out to some magic number larger than 1000.
I couldn't figure out why this would be true and just now verified that the encoding routines only allocate memory as needed.
Except! When I wasn't paying attention to where I was in the code, I fell into a routine where alloc used 8192 for the size (ascii translation routine?). Initially this allocation has what appears to be some garbage bytes. However, the next piece of code uses memset with 0 as the second parameter and it appears to set the memory for all 8192 bytes to x'00'.
And subsequently this value 8192 seems to be used elsewhere:
Display Module Source
Program: HTTPAPIR4 Library: LIBHTTP Module: ENCODERR4
4018 callp url_encode( peEncoder
4019 : p_VarX
4020 : wwVarXLen
4021 : dsEnc_Data + dsEnc_Len
4022 : wwLenVar )
4023 eval dsEnc_Len = dsEnc_Len + wwLenVar
4024
4025 eval p_deref = dsEnc_Data + dsEnc_Len
4026 eval wwDeref = '='
4027 eval dsEnc_Len = dsEnc_Len + %len('=')
4028
4029 callp url_encode( peEncoder
4030 : p_DataX
4031 : wwDataXLen
4032 : dsEnc_Data + dsEnc_Len
More...
Debug . . .
F3=End program F6=Add/Clear breakpoint F10=Step F11=Display variable
F12=Resume F17=Watch variable F18=Work with watch F24=More keys
DSENC_SIZE = 8192 <============================
So while the url_encode routine is passing short data lengths, someplace it keeping hold of the size as 8192.
And just before there:
3993 eval dsEnc_Data = xrealloc( dsEnc_data
3994 : wwNewSize )
WWNEWSIZE = 8192
EVAL dsEnc_Data:c 1000 <=======(in theory showing more than 32 bytes of data for the pointer)
DSENC_DATA:C 1000 =
....5...10...15...20...25...30...3
1 'locpartenza=T1&NumSped=520113341 <==== I was in the second add_var routine
At this point my brain is mush from following pointers and routines around but I wonder...Is the "cleared" memory subsequently being used by the encoding routines so that based on program flow there will --most likely (but not absolutely)-- be x'00' after the encoded data? The number of bytes of cleared data is unknown and unpredictable but that might be why I consistently saw x'00' after the data?
In theory, the bytes could be anything - as I saw in the routine where 8192 bytes were allocated. The same would be true with the encoding routines. As the encoded string is built, the data following it could have anything in it. But maybe what usually happens is that the encoded string is being built in the memory that was cleared by the routine that used 8192? And since the program allocated the memory even if deallocated, the memory has become part of the protected program memory. I wonder if on a busy system and slowing down the process by using long debug steps if the memory would eventually "corrupt" beyond the encoded strings.
At least that in theory would explain the several debug sessions in a row that showed x'00' following the data.
Back in the mainline... I can do this:
EVAL myPointer:c 8000
MYPOINTER:C 8000 =
....5...10...15...20...25...30...35...40...45...50...
1 'locpartenza=T1&NumSped=520113341&CodCli=2583
I don't think I should be able to look at 8000 bytes of data unless it is program storage?
And this:
EVAL myPointer:c 10000
MYPOINTER:C 10000 =
This shows no garbage until about 9730 or so.
I can do this and see x'00' after the encoded data.
EVAL myPointer:x 8192
But adding one more byte causes a problem:
EVAL myPointer:x 8193
Domain violation occurred. (not sure if this is a display issue or a debug issue or an actual domain violation. (why 10000+ character but only 8192 hex?) There are some old PTFs regarding this error but it could be a red herring. We are v7r1 current on PTFs as of 2 weeks ago.)
So maybe, possibly, the 8192 number that is used at some point is wrong and causing "excess" memory allocations and then being carried forward in the realloc for add_var?
And to anyone not *really* following this thread...assuming x'00' beyond your data is wrong - even if it is there! Use the routines provided to get the string data back!
The encoded data is not in a 1000A variable, therefore the data that's
in his "req" variable is "unpredictable". It could be x'00' if the data
after the part he's actually using happens to be unused memory, then
this is the most likely case. But, it could contain other byte values
as well. You're right that the length of URL is 1000A, but the
length of the data that "req" points to is not -- and you should not
assume that it will be padded with any particular character.
-----------------------------------------------------------------------
This is the FTPAPI mailing list. To unsubscribe, please go to:
http://www.scottklement.com/mailman/listinfo/ftpapi
-----------------------------------------------------------------------