JDEdwards / Oracle EnterpriseOne - jdeStrncpy and jdeStrncpyTerminate
First of all, both the functions were brought into play due to Unicode. Similarly to formersizeof
, they should guarantee that the code is safe when manipulating
strings. Unfortunately, it is not always the case.Based on the documentation jdeStrncpy should be always used with
DIM()-1
while
jdeStrncpyTerminate with DIM()
as the third parameter. Unfortunately,
this works well for jdeStrncpyTerminate but not really for jdeStrncpy.Let's assume the following code:
JCHAR szTest1[2];
JCHAR szTest2[2];
JCHAR szTest3[10];
jdeStrncpy(szTest1, _J("ABCD"), DIM(szTest1)-1);
The variable
szTest1
was not reset to zeros with {0}
thefore it contains
garbage. Also the garbage could have been created by a previous logic if there was any.
The size of the variable szTest1
is 2 JCHARS so let's assume it contained "XY"
before jdeStrncpy (unterminated 2 JCHARs). The value
after the assignment is not "A" terminated with 0x00
as expected but "A" followed by "Y" (the last
JCHAR was not modified by the function!!). To make things worse the text is not terminated
therefore any subsequent logic will be wrong as well.Let's continue the code above with the following:
jdeStrncpyTerminate(szTest2, _J("1234"), DIM(szTest2));
jdeStrncpyTerminate(szTest3, szTest1, DIM(szTest3));
The assignment to
szTest2
works as expected no matter what garbage was in the variable before,
the text is properly terminated and the result is "1" (the size is 2 JCHARS, the last one is used
to terminate the string with 0x00
).However the assignment to
szTest3
, although properly coded, does not do what we expect. The result
in szTest3
afterwards could possibly be "AY1". The compiler usually allocates memory for variables
in the sequence of the declaration so we can assume (however cannot rely on) that szTest2
directly follows
szTest1
in memory. As the string in szTest1
is not terminated, it "continues" into the next variable.
Therefore the variable szTest3
is filled with an incorrect value. The cause of the
problem is in jdeStrncpy.Resolution: Either use jdeStrncpyTerminate with DIM() OR use jdeStrncpy with DIM()-1 but always make sure the variable is reset to zeros before the operation.
Replacement: If you wish to replace all jdeStrncpy with jdeStrncpyTerminate in your source code, you may use the following strings in the MS Visual Studio replacement:
Find what:
{jdeStrncpy:b*}\({[^,]*},{[:b\n]*[^,]*},{[:b\n]*[^)]*}{\):b*}{-1:b*}{\).*;}
Replace with:
jdeStrncpyTerminate(,, /* jdeStrncpy replaced with jdeStrncpyTerminate */
Find options / Use:
Regular expressions
BTW, be careful about the usage of DIM.
Back to Content
In case of any questions or suggestions please contact David Macek.