22 septembre 2011

Convertir la description encodée de certains objets HR Access

Depuis HRv3e, un certain nombre d'objets ont une description en base "illisible" car encodée au format MIME base64.

Ci dessous par exemple la description d'une page Web :

select ZONXML from WF25 where GPECRA||CDECRA='FPW0F703' order by NOLIG4;
 
00040018Coder-Version: 1.00037Content-Type: text/xml; charset=UTF-80033Content-Transfer-Encoding: base640034Content-Description:HRWFormEntity00005B44PD94bWwgdmVyc2lvbj0iMS4wIj8+DQo8SFJXSU5ET1cgV2lkdGg9IjEwMjQiIEhlaWdodD0iMTEwMCIgU3R5bGU9IiIgVmVyc2lvbj0iNS4wLjAiIHV1aWQ9IjlBNzMyM0Y4LTQ3MEYtNDJBMy05NzUxLTU0Q0JFRjQxNTkzRCIgQm9yZGVyPSJOb25lIiBGb290ZXJBY3Rpb25zPSJDQU5DRUwiPg0KCTxIUlBBTkVMIE1vZGU9InRhYiIgdXVpZD0iNDlFMzQ3MkItRDk2OC00NDg5LThBRTctMkNFOEQ2NTdFM0UyIiBMZWZ0PSIwIiB
...

Ci dessous un exemple de décodage de la description d'une page Web HRv5.
Il a fallu ordonner et joindre les multiples lignes de description :

echo "set lines 3900
select ZONXML||'\' from WF25 where GPECRA||CDECRA='FPW0F703'
order by NOLIG4;" |
i_sql |
sed '$s/\\$//' | sed -e :a -e '/\\$/N; s/\\\n//; ta' | sed -e 's/^.*Content-Description: HRWFormEntity........//' -e 's/^.*Encoding: base64........//' |
perl -MMIME::Base64 -ne 'print decode_base64($_)' | 
sed -e 's/é/é/g' -e 's/ê/ê/g' -e 's/à /à/g'  -e 's/è/è/g' -e 's/#@/@/g' -e 's/ô/ô/g' -e 's/î/î/g' -e 's/â/â/g' -e 's/û/û/g' -e 's/ç/ç/g' -e 's/ù/ù/g' |  tr '@' '\n'

Dans cet exemple de commande on a :
  •  i_sql qui est un utilitaire exécutant un SQLPLUS,
  •  un premier sed qui fusionne les lignes et supprime l'entête HR Access "Content-Description...base64" qui précède la description de l'objet,
  •  un perl qui décode la description,
  •  un second sed qui rétabli les caractères accentués.

ce qui donne :

<?xml version="1.0"?>
<HRWINDOW Width="1024" Height="1100" Style="" Version="5.0.0" uuid="9A7323F8-470F-42A3-9751-54CBEF41593D" Border="None" FooterActions="CANCEL">
<HRPANEL Mode="tab" uuid="49E3472B-D968-4489-8AE7-2CE8D657E3E2" Left="0" Top="0" Width="1024" Height="477" LabelContext="page" Style="PAN05" EnableContext="default">
<HRDS uuid="C2451795-82F1-4C7F-BEDB-712F11229D24" Left="0" Top="0" Width="774" Height="234" Typerep="Z" Maxrowrep="1" Maxcolrep="1" Titlerep="1" Type="normal" HideEmptyrep="0">
<HRPARAMS Left="18" Top="63" Width="738" Height="72" uuid="D21F177F-0433-4011-972E-A52577058799">
<HRPANEL Left="18" Top="63" Width="738" Height="72" Mode="simple" LabelContext="page" Style="PAN02" uuid="83BDF6FD-591F-47E5-A0D1-9ECEEFF251FB" EnableContext="default">
...

7 commentaires:

  1. hello mister D,

    Sais tu si, avec le même principe, on peut récupérer les scripts inclus dans les pages web afin de rechercher plus facilement des exemples d'utilisation de certaines fonctions ?

    D'avance merci.

    RépondreSupprimer
  2. j'ai testé sur la rubrique ZOPROC de la table SP10 mais le résultat n'est pas lisible, c'est bizarre parce que ça a l'air d'être encodé de la même façon.

    RépondreSupprimer
  3. Bonjour,

    Voici une requête sql qui permet de permet de faire ceci ;-)

    -- Lecture des scripts des pages web :
    with sp10_max as (
    select tyenti, cdentc, nuvvar, max(nolign) as nolign_max
    from sp10
    group by tyenti, cdentc, nuvvar
    ) , dephasage as (
    select distinct case when nuvvar = '4.200' then instr(zoproc,'Content-Transfer-Encoding: base64') + length('Content-Transfer-Encoding: base64') +8
    else instr(zoproc,'Content-Description: HRWScript') + length('Content-Description: HRWScript') +8
    end as dephasage, nuvvar
    from sp10 where nolign in ( '01', '001', '0001', '00001' )
    ) , sp10_ok as (
    select a.tyenti, a.cdentc, a.nuvvar, a.nolign, b.nolign_max,
    case when nolign in ( '01', '001', '0001', '00001' ) and nolign_max = nolign then substr(a.zoproc,c.dephasage)
    when nolign in ( '01', '001', '0001', '00001' ) and nolign_max != nolign then substr(a.zoproc,c.dephasage) || substr(lead(a.zoproc,1,0) over (order by a.tyenti, a.cdentc, a.nuvvar, a.nolign) ,1,mod(c.dephasage -1 ,4)) -- pour avoir un modulo 4 dans le decode
    else substr(a.zoproc, mod(c.dephasage,4)) -- pour avoir un modulo 4 dans le decode
    end as zonxml_ok
    from sp10 a inner join sp10_max b on (a.tyenti = b.tyenti and a.cdentc = b.cdentc and a.nuvvar = b.nuvvar)
    inner join dephasage c on (b.nuvvar = c.nuvvar)
    order by 1,2,3
    ), sp10_converti as (
    select tyenti , cdentc, nuvvar, nolign, -- nolig4_max, length(zonxml_ok) as l,
    convert( --'banniÚre' get rid of mojiabke
    UTL_RAW.CAST_TO_VARCHAR2(UTL_ENCODE.BASE64_DECODE(UTL_RAW.CAST_TO_RAW(coalesce(substr(zonxml_ok,1,2000), ' ')))) || -- pas plus de 2000 caractères possibles pour UTL_ENCODE /// et coalesce car le null fait une erreur
    UTL_RAW.CAST_TO_VARCHAR2(UTL_ENCODE.BASE64_DECODE(UTL_RAW.CAST_TO_RAW(coalesce(substr(zonxml_ok,2001 ), ' '))))
    ,'WE8ISO8859P15','AL32UTF8' ) as xml_converti
    from sp10_ok
    )
    select * --cdentc, substr( xml_converti, instr( xml_converti, 'hrSetValue') )
    from sp10_converti
    where xml_converti like '%function %' -- renseigner ici ce qu'on cherche
    escape '\' -- pour avoir un caractère d'échappement dans le like au-dessus
    ;

    RépondreSupprimer
  4. Ouah ... Ça pique les yeux ...
    Bravo et merci !

    RépondreSupprimer
  5. hello,
    Quelqu'un aurait une idée pour récupérer les scripts des pages web ?

    RépondreSupprimer
  6. Pour les scripts, j'ai fini par trouver la solution, ci-dessous la marche à suivre en se passant de i_sql qui n'est pas installé partout :

    spool fic_ent
    set lines 3900
    select ZOPROC||'\' from SP10 where tyenti = 'WF' and CDENTC= 'XXXXXXXX' order by NOLIGN;

    avec 'XXXXXXXX' = concat du groupe de page et du nom de la page

    sous vi virer les lignes en trop (requête sql, ligne vide, nbre lig extrait...) pour ne laisser que les lignes titre et les lignes résultats

    sed 's/[ \t]*$//' fic_ent.lst > fic_ent1
    sed -e :a -e '/\\$/N; s/\\\n//; ta' fic_ent1 > fic_ent2
    sed -e 's/^.*Content-Description: HRWFormEntity........//' -e 's/^.*Encoding: base64........//' -e 's/^.*ent-Description: HRWScript//' fic_ent2 > fic_ent3
    perl -MMIME::Base64 -ne 'print decode_base64($_)' fic_ent3 > fic_ent4
    sed -e 's/é/é/g' -e 's/ê/ê/g' -e 's/à /à/g' -e 's/è/è/g' -e 's/#@/@/g' -e 's/ô/ô/g' -e 's/î/î/g' -e 's/â/â/g' -e 's/û/û/g' -e 's/ç/ç/g' -e 's/ù/ù/g' fic_ent4 > fic_ent5
    tr '@' '\n' < fic_ent5 > fic_sortie

    RépondreSupprimer
    Réponses
    1. en reprenant la forme du POST :
      echo "set lines 3900
      select ZOPROC||'\' from SP10 where tyenti = 'WF' and CDENTC= 'WPW0F305' order by NOLIGN;" |
      i_sql |
      sed '$s/\\$//' | sed -e :a -e '/\\$/N; s/\\\n//; ta' | sed -e 's/^.*Content-Description: HRWScript........//' -e 's/^.*Encoding: base64........//' |
      perl -MMIME::Base64 -ne 'print decode_base64($_)' |
      sed -e 's/é/é/g' -e 's/ê/ê/g' -e 's/à /à/g' -e 's/Ã./è/g' -e 's/#@/@/g' -e 's/Ã./ô/g' -e 's/î/î/g' -e 's/â/â/g' -e 's/û/û/g' -e 's/ç/ç/g' -e 's/ù/ù/g' | tr '@' '\n'

      Supprimer