Skip to main content

Hi Freaks

I just went crazy because something was wrong with an encryption routine.
The data is encrypted with BLOWFISH, some variables are created as RAW in between.
If you now apply the $length function to them, you get different values in UF 9 and UF 10.
Example:

9:"r|90|'{'|C{o{X|N{j|_\\0|_|m|k|[{C|K{C|){/{j.{MK{)/|+:|F|\\|'{@|@|8|P{O|a|g:|fdg{c{n|<d{h|${kD|U|e|k|6{L{`{<{q{V|1|&{R"  Len = 115

10 "r|90|'{'|C{o{X|N{j|_\\0|_|m|k|[{C|K{C|){/{j.{MK{)/|+:|F|\\|'{@|@|8|P{O|a|g:|fdg{c{n|<d{h|${kD|U|e|k|6{L{`{<{q{V|1|&{R"  Len =  64   <===

    1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345

UF 10 verwendet also
Uniface  9 : $length(v_raw) = $length_UF9(v_raw) 
UnifAce 10 : $length(v_raw) = $length_UF9($encode("ustring",v_raw))

When you loop through the variable v_raw, you find $length_UF9(v_raw) characters.
This leads to the workaround

ENTRY LF_RAW_LENGTH
  returns numeric
  params
   raw v_RAW:IN
  endparams
  variables
    numeric v_LEN
  endvariables
  v_LEN = 0
  WHILE(v_STR[v_LEN+1]!="") v_LEN+=1
  RETURN(v_LEN)
END

Is this new behavior a bug or a feature?
And will it be corrected?
But what will the colleagues who are already using the new type do :-)

Ingo



------------------------------
Ingo Stiller
Aareon Deutschland GmbH
------------------------------

Hi Freaks

I just went crazy because something was wrong with an encryption routine.
The data is encrypted with BLOWFISH, some variables are created as RAW in between.
If you now apply the $length function to them, you get different values in UF 9 and UF 10.
Example:

9:"r|90|'{'|C{o{X|N{j|_\\0|_|m|k|[{C|K{C|){/{j.{MK{)/|+:|F|\\|'{@|@|8|P{O|a|g:|fdg{c{n|<d{h|${kD|U|e|k|6{L{`{<{q{V|1|&{R"  Len = 115

10 "r|90|'{'|C{o{X|N{j|_\\0|_|m|k|[{C|K{C|){/{j.{MK{)/|+:|F|\\|'{@|@|8|P{O|a|g:|fdg{c{n|<d{h|${kD|U|e|k|6{L{`{<{q{V|1|&{R"  Len =  64   <===

    1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345

UF 10 verwendet also
Uniface  9 : $length(v_raw) = $length_UF9(v_raw) 
UnifAce 10 : $length(v_raw) = $length_UF9($encode("ustring",v_raw))

When you loop through the variable v_raw, you find $length_UF9(v_raw) characters.
This leads to the workaround

ENTRY LF_RAW_LENGTH
  returns numeric
  params
   raw v_RAW:IN
  endparams
  variables
    numeric v_LEN
  endvariables
  v_LEN = 0
  WHILE(v_STR[v_LEN+1]!="") v_LEN+=1
  RETURN(v_LEN)
END

Is this new behavior a bug or a feature?
And will it be corrected?
But what will the colleagues who are already using the new type do :-)

Ingo



------------------------------
Ingo Stiller
Aareon Deutschland GmbH
------------------------------

Case Number: 00975557
Summary: BUG in $length, wenn Datentyp raw verwendet wird
Status: Support

Comment:
Hello Norbert
 
UNI-40152 is the JIRA number for the issue we created here for this problem.
The JIRA issue are not published.
 
I have updated the testset once more to also do test with diacritics.
For
äüöÄÜÖß
the raw is
"|5{j|5|.|5|(|5{J|5{b|5{\\|5{e"
 
patch 36 says 28 for $length
patch 37 and later says 14 for $length
 
What the developer tried to explain is that 14 is the correct value:
patch 036 and before is wrong.
14 is also in line with the example in the Uniface library.
 
 
Do you have many places in your application where $length is used on a raw ?
 
Best regards
Peter Beugel
Principal Technical Support Engineer
Rocket Software B.V.



------------------------------
Norbert Lauterbach
Infraserv Gmbh & Co. Höchst Kg
Frankfurt DE
------------------------------

Case Number: 00975557
Summary: BUG in $length, wenn Datentyp raw verwendet wird
Status: Support

Comment:
Hello Norbert
 
UNI-40152 is the JIRA number for the issue we created here for this problem.
The JIRA issue are not published.
 
I have updated the testset once more to also do test with diacritics.
For
äüöÄÜÖß
the raw is
"|5{j|5|.|5|(|5{J|5{b|5{\\|5{e"
 
patch 36 says 28 for $length
patch 37 and later says 14 for $length
 
What the developer tried to explain is that 14 is the correct value:
patch 036 and before is wrong.
14 is also in line with the example in the Uniface library.
 
 
Do you have many places in your application where $length is used on a raw ?
 
Best regards
Peter Beugel
Principal Technical Support Engineer
Rocket Software B.V.



------------------------------
Norbert Lauterbach
Infraserv Gmbh & Co. Höchst Kg
Frankfurt DE
------------------------------

"What the developer tried to explain is that 14 is the correct value:"
The developers of C++ have a different view :-)
https://cplusplus.com/reference/string/string/length/

On the other side, if $length returns the number of characters(codepoints), then the operator  "[pos:1]"  should also return one character and not one byte :-)

Ingo



------------------------------
Ingo Stiller
Aareon Deutschland GmbH
------------------------------

"What the developer tried to explain is that 14 is the correct value:"
The developers of C++ have a different view :-)
https://cplusplus.com/reference/string/string/length/

On the other side, if $length returns the number of characters(codepoints), then the operator  "[pos:1]"  should also return one character and not one byte :-)

Ingo



------------------------------
Ingo Stiller
Aareon Deutschland GmbH
------------------------------

Hi Ingo,

here is a binary Version:

function RAW_LENGTH
    returns numeric
    params
        raw    P_RAW    : in
    endparams
    variables
        numeric V_L, V_R, V_M
    endvariables
    V_L = 0
    if (P_RAW[1:1] != "")
        V_R = 2
        while P_RAW[V_R:1] != ""
            V_R *= 2
        endwhile
        while (V_R - V_L > 1)
            V_M = (V_L + V_R) / 2
            if (P_RAW[V_M:1] == "")
                V_R = V_M
            else
                V_L = V_M
            endif            
        endwhile        
    endif
    return V_L
end

Norbert



------------------------------
Norbert Lauterbach
Infraserv Gmbh & Co. Höchst Kg
Frankfurt DE
------------------------------


Hi Ingo,

here is a binary Version:

function RAW_LENGTH
    returns numeric
    params
        raw    P_RAW    : in
    endparams
    variables
        numeric V_L, V_R, V_M
    endvariables
    V_L = 0
    if (P_RAW[1:1] != "")
        V_R = 2
        while P_RAW[V_R:1] != ""
            V_R *= 2
        endwhile
        while (V_R - V_L > 1)
            V_M = (V_L + V_R) / 2
            if (P_RAW[V_M:1] == "")
                V_R = V_M
            else
                V_L = V_M
            endif            
        endwhile        
    endif
    return V_L
end

Norbert



------------------------------
Norbert Lauterbach
Infraserv Gmbh & Co. Höchst Kg
Frankfurt DE
------------------------------

Hi Norbert

Nice code. 
In case you will have really long strings :-)
But the multiplication and division also take a lot of time in UnifAce. I don't think Uniface recognizes the factor 2 and then performs SHIFT operations.
Maybe you should add an IF query before

Ingo

FUNCTION RAW_LENGTH
  returns numeric
  params
    raw P_RAW : in
  endparams
  variables
    numeric V_L, V_R, V_M
  endvariables
  v_L = $length(p_raw); Yes, the old one. 
  IF(v_L<=0) RETURN(0) ; Nothing to do :-)
  IF(v_L>1000) ; But this boundary is only a rule of thumb anyway
    V_L = 0
    IF(P_RAW[1:1] != "")
      V_R = 2
      WHILE P_RAW[V_R:1] != ""
        V_R *= 2
      ENDWHILE
      WHILE(V_R - V_L > 1)
        V_M = (V_L + V_R) / 2
        IF(P_RAW[V_M:1] == "")
          V_R = V_M
        ELSE
          V_L = V_M
        ENDIF
      ENDWHILE
    ENDIF
  ELSE
    v_L = 0
    WHILE(p_raw[v_L:1]!="") v_L += 1 ; Good old ASCII-Z style :)
  ENDIF
  RETURN V_L
END ; RAW_LENGTH



------------------------------
Ingo Stiller
Aareon Deutschland GmbH
------------------------------