Plugin Directory

Changeset 3389743


Ignore:
Timestamp:
11/04/2025 02:36:12 PM (5 months ago)
Author:
Milmor
Message:

Update to version 7.7.1 from GitHub

Location:
avcp
Files:
10 edited
1 copied

Legend:

Unmodified
Added
Removed
  • avcp/tags/7.7.1/avcp.php

    r3363055 r3389743  
    55Description: Generatore XML per ANAC (ex AVCP) e gestione bandi di gara e contratti (Legge 190/2012 art. 1.32 & D.Lgs 33/2013)
    66Author: Marco Milesi
    7 Version: 7.7
     7Version: 7.7.1
    88Author URI: https://www.marcomilesi.com
    99*/
     
    332332function crea_anni() {
    333333
    334     for( $x = 2013; $x <= 2028; $x++) {
     334    for( $x = 2013; $x <= 2030; $x++) {
    335335        $termcheck = term_exists( $x, 'annirif');
    336336        if ($termcheck == 0 || $termcheck == null) {
  • avcp/tags/7.7.1/avcp_metabox_generator.php

    r3363055 r3389743  
    4545  }
    4646  if (array_key_exists('avcp_data_inizio', $_POST)) {
    47     if ( date("Y", strtotime( $_POST['avcp_data_inizio'] )) > 2012 && date("Y", strtotime( $_POST['avcp_data_inizio'] )) < 2030  ) {
     47    if ( date("Y", strtotime( $_POST['avcp_data_inizio'] )) > 2012 && date("Y", strtotime( $_POST['avcp_data_inizio'] )) <= 2030  ) {
    4848      wp_set_object_terms( $post_id, date("Y", strtotime( $_POST['avcp_data_inizio'] ) ), 'annirif', true );
    4949    }
     
    5555  }
    5656  if (array_key_exists('avcp_data_fine', $_POST)) {
    57     if ( date("Y", strtotime( $_POST['avcp_data_fine'] )) > 2012 && date("Y", strtotime( $_POST['avcp_data_fine'] )) < 2030 ) {
     57    if ( date("Y", strtotime( $_POST['avcp_data_fine'] )) > 2012 && date("Y", strtotime( $_POST['avcp_data_fine'] )) <= 2030 ) {
    5858      wp_set_object_terms( $post_id, date("Y", strtotime( $_POST['avcp_data_fine'] ) ), 'annirif', true );
    5959    }
  • avcp/tags/7.7.1/avcp_xml_generator.php

    r3363055 r3389743  
    187187    $somme_liquidate[2027] = get_post_meta($post->ID, 'avcp_s_l_2027', true);
    188188    $somme_liquidate[2028] = get_post_meta($post->ID, 'avcp_s_l_2028', true);
    189 
    190     for ($i = 2013; $i < 2026; $i++) {
     189    $somme_liquidate[2029] = get_post_meta($post->ID, 'avcp_s_l_2029', true);
     190    $somme_liquidate[2030] = get_post_meta($post->ID, 'avcp_s_l_2030', true);
     191
     192    for ($i = 2013; $i <= 2030; $i++) {
    191193        if ($somme_liquidate[$i] == '') {
    192194            $somme_liquidate[$i] = '0.00';
  • avcp/tags/7.7.1/pannelli/import.php

    r2981286 r3389743  
    33function anac_import_load()
    44{
     5    // Additional security: verify user capabilities
     6    if (!current_user_can('manage_options')) {
     7        wp_die(__('You do not have sufficient permissions to access this page.'), __('Access Denied'), array('response' => 403));
     8    }
     9   
    510    if (ini_set('max_execution_time', 300) === false) {
    611        set_time_limit(0);
     
    1621
    1722    if (isset($_POST['Submit'])) {
    18 
    19         if ($_POST['importafinale'] != null) {
    20 
    21             $gare_xml = new SimpleXMLElement(stripslashes(get_option('anac_import_xml')));
    22             $dfx      = (string) $gare_xml->metadata->annoRiferimento;
     23       
     24        // CSRF protection - verify nonce
     25        if (!isset($_POST['anac_import_nonce']) || !wp_verify_nonce($_POST['anac_import_nonce'], 'anac_import_action')) {
     26            wp_die(__('Security check failed. Please try again.'), __('Security Error'), array('response' => 403));
     27        }
     28
     29        if (isset($_POST['importafinale']) && $_POST['importafinale'] != null) {
     30
     31            $stored_xml = stripslashes(get_option('anac_import_xml'));
     32            $parsing_options = LIBXML_NOCDATA | LIBXML_NOENT | LIBXML_PARSEHUGE;
     33            $gare_xml = new SimpleXMLElement($stored_xml, $parsing_options);
     34           
     35            $dfx = (string) $gare_xml->metadata->annoRiferimento;
    2336            foreach ($gare_xml->xpath('//lotto') as $lotto) {
    2437
     
    3548                    while (have_posts()):
    3649                        the_post();
    37                         echo '<span style="color:red;weight:bold;">Gara ' . (string) $lotto->oggetto . ' già presente</span><br>';
     50                        echo '<span style="color:red;weight:bold;">Gara ' . esc_html((string) $lotto->oggetto) . ' già presente</span><br>';
    3851                        continue;
    3952                    endwhile;
     
    6174                $stack_aggiudicatari = array();
    6275                foreach ($lotto->aggiudicatari->aggiudicatario as $aggiudicatario) {
    63                     array_push( $stack_aggiudicatari, (string) $aggiudicatario->codiceFiscale);
     76                    // Handle both codiceFiscale and identificativoFiscaleEstero
     77                    $codice_fiscale = isset($aggiudicatario->codiceFiscale) ?
     78                        (string) $aggiudicatario->codiceFiscale :
     79                        (string) $aggiudicatario->identificativoFiscaleEstero;
     80                    array_push( $stack_aggiudicatari, $codice_fiscale);
    6481                }
    6582
    6683                foreach ($lotto->partecipanti->partecipante as $partecipante) {
    67                     echo $partecipante->ragioneSociale . ' &bull; ' . $partecipante->codiceFiscale;
     84                    // Handle both codiceFiscale and identificativoFiscaleEstero
     85                    $codice_fiscale = isset($partecipante->codiceFiscale) ?
     86                        (string) $partecipante->codiceFiscale :
     87                        (string) $partecipante->identificativoFiscaleEstero;
     88                    echo esc_html($partecipante->ragioneSociale) . ' &bull; ' . esc_html($codice_fiscale);
    6889
    6990                    $terms         = get_terms('ditte', array(
     
    7798                        $term_meta   = get_option("taxonomy_$t_id");
    7899                        $term_return = esc_attr($term_meta['avcp_codice_fiscale']);
    79                         if ($term_return == (string) $partecipante->codiceFiscale) {
     100                        if ($term_return == $codice_fiscale) {
    80101                            $dittapresente     = true;
    81102                            $id_ditta_presente = $term->term_id;
     
    95116                            $t_id                             = $dfx2->term_id;
    96117                            $term_meta                        = get_option("taxonomy_$t_id");
    97                             $term_meta['avcp_codice_fiscale'] = (string) $partecipante->codiceFiscale;
     118                            $term_meta['avcp_codice_fiscale'] = $codice_fiscale;
    98119                            update_option("taxonomy_$t_id", $term_meta);
    99120                        }
     
    102123                    //Aggiudicatario?
    103124                    $stack_aggiudicatari_finali = array();
    104                     if (in_array( (string) $partecipante->codiceFiscale, $stack_aggiudicatari ) ) {
     125                    if (in_array( $codice_fiscale, $stack_aggiudicatari ) ) {
    105126                        array_push( $stack_aggiudicatari_finali, $id_ditta_presente );
    106127                        echo  ' &bull; <strong>(aggiudicatario)</strong>)';
     
    111132                update_post_meta($id_gara, 'avcp_aggiudicatari', $stack_aggiudicatari_finali);
    112133
    113                 echo (string) $lotto->cig . ' &bull; <strong>' . (string) $lotto->oggetto . '</strong>
    114                 <br>' . (string) $lotto->sceltaContraente . ' &bull; ' . (string) $lotto->tempiCompletamento->dataInizio . ' &bull; ' . (string) $lotto->tempiCompletamento->dataUltimazione . '<br><br>';
     134                echo esc_html((string) $lotto->cig) . ' &bull; <strong>' . esc_html((string) $lotto->oggetto) . '</strong>
     135                <br>' . esc_html((string) $lotto->sceltaContraente) . ' &bull; ' . esc_html((string) $lotto->tempiCompletamento->dataInizio) . ' &bull; ' . esc_html((string) $lotto->tempiCompletamento->dataUltimazione) . '<br><br>';
    115136
    116137                anac_add_log('Aggiunto ' . $lotto->oggetto . ' (id ' . $id_gara . ') con anno ' . $gare_xml->metadata->annoRiferimento, 0);
     
    119140            delete_option('anac_import_xml');
    120141
    121         } else if ($_POST['datasetimporta'] != null) {
    122 
    123             $gare_xml = new SimpleXMLElement(stripslashes($_POST['datasetimporta']));
    124 
    125             echo '<h3>Controlla i dati.</h3><h4>' . $gare_xml->metadata->entePubblicatore . '<br>Anno ' . $gare_xml->metadata->annoRiferimento . '<br>Aggiornato al ' . $gare_xml->metadata->dataUltimoAggiornamentoDataset . '</h4>
     142        } else if (isset($_POST['datasetimporta']) && $_POST['datasetimporta'] != null) {
     143
     144            // Sanitize and validate XML input - preserve XML structure
     145            $xml_input = wp_unslash($_POST['datasetimporta']);
     146           
     147            // Basic security: check for obvious malicious content without breaking XML structure
     148            if (stripos($xml_input, '<script') !== false ||
     149                stripos($xml_input, 'javascript:') !== false ||
     150                stripos($xml_input, 'vbscript:') !== false) {
     151                echo '<div class="error"><p><strong>Errore:</strong> Il contenuto XML contiene codice potenzialmente pericoloso.</p></div>';
     152                return;
     153            }
     154           
     155            // Validate input length to prevent DoS attacks
     156            if (strlen($xml_input) > 5000000) { // 5MB limit
     157                echo '<div class="error"><p><strong>Errore:</strong> Il file XML è troppo grande (massimo 5MB).</p></div>';
     158                return;
     159            }
     160           
     161            // Additional security: disable external entity loading
     162            libxml_disable_entity_loader(true);
     163           
     164            // Use previous errors to catch XML parsing issues
     165            $use_errors = libxml_use_internal_errors(true);
     166           
     167            try {
     168                // Try different parsing approaches
     169                $parsing_options = LIBXML_NOCDATA | LIBXML_NOENT | LIBXML_PARSEHUGE;
     170               
     171                // First attempt: standard parsing
     172                $gare_xml = new SimpleXMLElement($xml_input, $parsing_options);
     173               
     174                // Check if we have metadata as a direct child
     175                $metadata = $gare_xml->metadata;
     176               
     177                // Validate required elements exist
     178                if (!isset($metadata) || !isset($metadata->entePubblicatore) ||
     179                    !isset($metadata->annoRiferimento)) {
     180                    throw new Exception('XML structure is invalid - missing required metadata elements');
     181                }
     182               
     183            } catch (Exception $e) {
     184                $libxml_errors = libxml_get_errors();
     185                $error_messages = array($e->getMessage());
     186               
     187                if (!empty($libxml_errors)) {
     188                    foreach ($libxml_errors as $error) {
     189                        $error_messages[] = "Linea {$error->line}: {$error->message}";
     190                    }
     191                }
     192               
     193                echo '<div class="error"><p><strong>Errore XML:</strong><br>' . esc_html(implode('<br>', $error_messages)) . '</p></div>';
     194               
     195                // Debug: show a sample of the XML input
     196                echo '<div class="error"><p><strong>Inizio XML ricevuto:</strong><br><pre>' . esc_html(substr($xml_input, 0, 300)) . '...</pre></p></div>';
     197               
     198                libxml_use_internal_errors($use_errors);
     199                return;
     200            }
     201           
     202            libxml_use_internal_errors($use_errors);
     203
     204            echo '<h3>Controlla i dati.</h3><h4>' . esc_html($metadata->entePubblicatore) . '<br>Anno ' . esc_html($metadata->annoRiferimento) . '<br>Aggiornato al ' . esc_html($metadata->dataUltimoAggiornamentoDataset) . '</h4>
    126205<table class="widefat">
    127206    <thead>
     
    136215    <tbody>';
    137216
     217            $a = ''; // Initialize alternating row variable
    138218            foreach ($gare_xml->xpath('//lotto') as $lotto) {
    139219                if ($a == '') {
     
    142222                    $a = '';
    143223                }
    144                 echo '<tr' . $a . '>
    145             <td class="row-title"><label for="tablecell">' . $lotto->cig . '</label></td>
    146             <td>' . $lotto->oggetto . '
     224                echo '<tr' . esc_attr($a) . '>
     225            <td class="row-title"><label for="tablecell">' . esc_html($lotto->cig) . '</label></td>
     226            <td>' . esc_html($lotto->oggetto) . '
    147227            <table>';
    148228                foreach ($lotto->partecipanti->partecipante as $partecipante) {
    149                     echo '<tr><td>' . $partecipante->ragioneSociale . ' &bull; ' . $partecipante->codiceFiscale . '</td></tr>';
     229                    // Handle both codiceFiscale and identificativoFiscaleEstero
     230                    $codice_fiscale = isset($partecipante->codiceFiscale) ?
     231                        (string) $partecipante->codiceFiscale :
     232                        (string) $partecipante->identificativoFiscaleEstero;
     233                    echo '<tr><td>' . esc_html($partecipante->ragioneSociale) . ' &bull; ' . esc_html($codice_fiscale) . '</td></tr>';
    150234                }
    151235                echo '</table></td>
    152             <td>€ ' . $lotto->importoAggiudicazione . '</td>
    153             <td>€ ' . $lotto->importoSommeLiquidate . '</td>
    154             <td>' . $lotto->tempiCompletamento->dataInizio . ' &bull; ' . $lotto->tempiCompletamento->dataUltimazione . '</td>
     236            <td>€ ' . esc_html($lotto->importoAggiudicazione) . '</td>
     237            <td>€ ' . esc_html($lotto->importoSommeLiquidate) . '</td>
     238            <td>' . esc_html($lotto->tempiCompletamento->dataInizio) . ' &bull; ' . esc_html($lotto->tempiCompletamento->dataUltimazione) . '</td>
    155239
    156240            </tr>';
     
    160244
    161245            echo '<form method="post" name="options" target="_self">';
    162             add_option('anac_import_xml', $_POST['datasetimporta']);
     246            wp_nonce_field('anac_import_action', 'anac_import_nonce');
     247            add_option('anac_import_xml', $xml_input);
    163248            echo '
    164         <textarea name="importafinale" cols="80" rows="10" class="large-text">' . $_POST['datasetimporta'] . '</textarea>
     249        <textarea name="importafinale" cols="80" rows="10" class="large-text">' . esc_textarea($xml_input) . '</textarea>
    165250        <hr>
    166251        <p class="submit"><input type="submit" class="button-primary" name="Submit" value="Conferma" /></p>
     
    175260
    176261        echo '<form method="post" name="options" target="_self">';
     262        wp_nonce_field('anac_import_action', 'anac_import_nonce');
    177263        echo '<hr>Incolla qui il contenuto del file xml che vuoi importare:<br><br><textarea name="datasetimporta" cols="80" rows="10" class="large-text"></textarea>';
    178264        echo '<hr>
  • avcp/tags/7.7.1/readme.txt

    r3363055 r3389743  
    8484== Changelog ==
    8585> Questa è la lista completa di tutti gli aggiornamenti, test e correzioni. Ogni volta che una nuova versione viene rilasciata assicuratevi di aggiornare il prima possibile per usufruire delle ultime migliorie!
     86
     87= 7.7.1 2025-11-04 =
     88* Aggiunto supporto nativo nuove annate (2029+2030)
     89* Miglioramento sicurezza
     90* Ottimizzazione delle performance e correzione bug
    8691
    8792= 7.7 20250917 =
  • avcp/trunk/avcp.php

    r3363055 r3389743  
    55Description: Generatore XML per ANAC (ex AVCP) e gestione bandi di gara e contratti (Legge 190/2012 art. 1.32 & D.Lgs 33/2013)
    66Author: Marco Milesi
    7 Version: 7.7
     7Version: 7.7.1
    88Author URI: https://www.marcomilesi.com
    99*/
     
    332332function crea_anni() {
    333333
    334     for( $x = 2013; $x <= 2028; $x++) {
     334    for( $x = 2013; $x <= 2030; $x++) {
    335335        $termcheck = term_exists( $x, 'annirif');
    336336        if ($termcheck == 0 || $termcheck == null) {
  • avcp/trunk/avcp_metabox_generator.php

    r3363055 r3389743  
    4545  }
    4646  if (array_key_exists('avcp_data_inizio', $_POST)) {
    47     if ( date("Y", strtotime( $_POST['avcp_data_inizio'] )) > 2012 && date("Y", strtotime( $_POST['avcp_data_inizio'] )) < 2030  ) {
     47    if ( date("Y", strtotime( $_POST['avcp_data_inizio'] )) > 2012 && date("Y", strtotime( $_POST['avcp_data_inizio'] )) <= 2030  ) {
    4848      wp_set_object_terms( $post_id, date("Y", strtotime( $_POST['avcp_data_inizio'] ) ), 'annirif', true );
    4949    }
     
    5555  }
    5656  if (array_key_exists('avcp_data_fine', $_POST)) {
    57     if ( date("Y", strtotime( $_POST['avcp_data_fine'] )) > 2012 && date("Y", strtotime( $_POST['avcp_data_fine'] )) < 2030 ) {
     57    if ( date("Y", strtotime( $_POST['avcp_data_fine'] )) > 2012 && date("Y", strtotime( $_POST['avcp_data_fine'] )) <= 2030 ) {
    5858      wp_set_object_terms( $post_id, date("Y", strtotime( $_POST['avcp_data_fine'] ) ), 'annirif', true );
    5959    }
  • avcp/trunk/avcp_xml_generator.php

    r3363055 r3389743  
    187187    $somme_liquidate[2027] = get_post_meta($post->ID, 'avcp_s_l_2027', true);
    188188    $somme_liquidate[2028] = get_post_meta($post->ID, 'avcp_s_l_2028', true);
    189 
    190     for ($i = 2013; $i < 2026; $i++) {
     189    $somme_liquidate[2029] = get_post_meta($post->ID, 'avcp_s_l_2029', true);
     190    $somme_liquidate[2030] = get_post_meta($post->ID, 'avcp_s_l_2030', true);
     191
     192    for ($i = 2013; $i <= 2030; $i++) {
    191193        if ($somme_liquidate[$i] == '') {
    192194            $somme_liquidate[$i] = '0.00';
  • avcp/trunk/pannelli/import.php

    r2981286 r3389743  
    33function anac_import_load()
    44{
     5    // Additional security: verify user capabilities
     6    if (!current_user_can('manage_options')) {
     7        wp_die(__('You do not have sufficient permissions to access this page.'), __('Access Denied'), array('response' => 403));
     8    }
     9   
    510    if (ini_set('max_execution_time', 300) === false) {
    611        set_time_limit(0);
     
    1621
    1722    if (isset($_POST['Submit'])) {
    18 
    19         if ($_POST['importafinale'] != null) {
    20 
    21             $gare_xml = new SimpleXMLElement(stripslashes(get_option('anac_import_xml')));
    22             $dfx      = (string) $gare_xml->metadata->annoRiferimento;
     23       
     24        // CSRF protection - verify nonce
     25        if (!isset($_POST['anac_import_nonce']) || !wp_verify_nonce($_POST['anac_import_nonce'], 'anac_import_action')) {
     26            wp_die(__('Security check failed. Please try again.'), __('Security Error'), array('response' => 403));
     27        }
     28
     29        if (isset($_POST['importafinale']) && $_POST['importafinale'] != null) {
     30
     31            $stored_xml = stripslashes(get_option('anac_import_xml'));
     32            $parsing_options = LIBXML_NOCDATA | LIBXML_NOENT | LIBXML_PARSEHUGE;
     33            $gare_xml = new SimpleXMLElement($stored_xml, $parsing_options);
     34           
     35            $dfx = (string) $gare_xml->metadata->annoRiferimento;
    2336            foreach ($gare_xml->xpath('//lotto') as $lotto) {
    2437
     
    3548                    while (have_posts()):
    3649                        the_post();
    37                         echo '<span style="color:red;weight:bold;">Gara ' . (string) $lotto->oggetto . ' già presente</span><br>';
     50                        echo '<span style="color:red;weight:bold;">Gara ' . esc_html((string) $lotto->oggetto) . ' già presente</span><br>';
    3851                        continue;
    3952                    endwhile;
     
    6174                $stack_aggiudicatari = array();
    6275                foreach ($lotto->aggiudicatari->aggiudicatario as $aggiudicatario) {
    63                     array_push( $stack_aggiudicatari, (string) $aggiudicatario->codiceFiscale);
     76                    // Handle both codiceFiscale and identificativoFiscaleEstero
     77                    $codice_fiscale = isset($aggiudicatario->codiceFiscale) ?
     78                        (string) $aggiudicatario->codiceFiscale :
     79                        (string) $aggiudicatario->identificativoFiscaleEstero;
     80                    array_push( $stack_aggiudicatari, $codice_fiscale);
    6481                }
    6582
    6683                foreach ($lotto->partecipanti->partecipante as $partecipante) {
    67                     echo $partecipante->ragioneSociale . ' &bull; ' . $partecipante->codiceFiscale;
     84                    // Handle both codiceFiscale and identificativoFiscaleEstero
     85                    $codice_fiscale = isset($partecipante->codiceFiscale) ?
     86                        (string) $partecipante->codiceFiscale :
     87                        (string) $partecipante->identificativoFiscaleEstero;
     88                    echo esc_html($partecipante->ragioneSociale) . ' &bull; ' . esc_html($codice_fiscale);
    6889
    6990                    $terms         = get_terms('ditte', array(
     
    7798                        $term_meta   = get_option("taxonomy_$t_id");
    7899                        $term_return = esc_attr($term_meta['avcp_codice_fiscale']);
    79                         if ($term_return == (string) $partecipante->codiceFiscale) {
     100                        if ($term_return == $codice_fiscale) {
    80101                            $dittapresente     = true;
    81102                            $id_ditta_presente = $term->term_id;
     
    95116                            $t_id                             = $dfx2->term_id;
    96117                            $term_meta                        = get_option("taxonomy_$t_id");
    97                             $term_meta['avcp_codice_fiscale'] = (string) $partecipante->codiceFiscale;
     118                            $term_meta['avcp_codice_fiscale'] = $codice_fiscale;
    98119                            update_option("taxonomy_$t_id", $term_meta);
    99120                        }
     
    102123                    //Aggiudicatario?
    103124                    $stack_aggiudicatari_finali = array();
    104                     if (in_array( (string) $partecipante->codiceFiscale, $stack_aggiudicatari ) ) {
     125                    if (in_array( $codice_fiscale, $stack_aggiudicatari ) ) {
    105126                        array_push( $stack_aggiudicatari_finali, $id_ditta_presente );
    106127                        echo  ' &bull; <strong>(aggiudicatario)</strong>)';
     
    111132                update_post_meta($id_gara, 'avcp_aggiudicatari', $stack_aggiudicatari_finali);
    112133
    113                 echo (string) $lotto->cig . ' &bull; <strong>' . (string) $lotto->oggetto . '</strong>
    114                 <br>' . (string) $lotto->sceltaContraente . ' &bull; ' . (string) $lotto->tempiCompletamento->dataInizio . ' &bull; ' . (string) $lotto->tempiCompletamento->dataUltimazione . '<br><br>';
     134                echo esc_html((string) $lotto->cig) . ' &bull; <strong>' . esc_html((string) $lotto->oggetto) . '</strong>
     135                <br>' . esc_html((string) $lotto->sceltaContraente) . ' &bull; ' . esc_html((string) $lotto->tempiCompletamento->dataInizio) . ' &bull; ' . esc_html((string) $lotto->tempiCompletamento->dataUltimazione) . '<br><br>';
    115136
    116137                anac_add_log('Aggiunto ' . $lotto->oggetto . ' (id ' . $id_gara . ') con anno ' . $gare_xml->metadata->annoRiferimento, 0);
     
    119140            delete_option('anac_import_xml');
    120141
    121         } else if ($_POST['datasetimporta'] != null) {
    122 
    123             $gare_xml = new SimpleXMLElement(stripslashes($_POST['datasetimporta']));
    124 
    125             echo '<h3>Controlla i dati.</h3><h4>' . $gare_xml->metadata->entePubblicatore . '<br>Anno ' . $gare_xml->metadata->annoRiferimento . '<br>Aggiornato al ' . $gare_xml->metadata->dataUltimoAggiornamentoDataset . '</h4>
     142        } else if (isset($_POST['datasetimporta']) && $_POST['datasetimporta'] != null) {
     143
     144            // Sanitize and validate XML input - preserve XML structure
     145            $xml_input = wp_unslash($_POST['datasetimporta']);
     146           
     147            // Basic security: check for obvious malicious content without breaking XML structure
     148            if (stripos($xml_input, '<script') !== false ||
     149                stripos($xml_input, 'javascript:') !== false ||
     150                stripos($xml_input, 'vbscript:') !== false) {
     151                echo '<div class="error"><p><strong>Errore:</strong> Il contenuto XML contiene codice potenzialmente pericoloso.</p></div>';
     152                return;
     153            }
     154           
     155            // Validate input length to prevent DoS attacks
     156            if (strlen($xml_input) > 5000000) { // 5MB limit
     157                echo '<div class="error"><p><strong>Errore:</strong> Il file XML è troppo grande (massimo 5MB).</p></div>';
     158                return;
     159            }
     160           
     161            // Additional security: disable external entity loading
     162            libxml_disable_entity_loader(true);
     163           
     164            // Use previous errors to catch XML parsing issues
     165            $use_errors = libxml_use_internal_errors(true);
     166           
     167            try {
     168                // Try different parsing approaches
     169                $parsing_options = LIBXML_NOCDATA | LIBXML_NOENT | LIBXML_PARSEHUGE;
     170               
     171                // First attempt: standard parsing
     172                $gare_xml = new SimpleXMLElement($xml_input, $parsing_options);
     173               
     174                // Check if we have metadata as a direct child
     175                $metadata = $gare_xml->metadata;
     176               
     177                // Validate required elements exist
     178                if (!isset($metadata) || !isset($metadata->entePubblicatore) ||
     179                    !isset($metadata->annoRiferimento)) {
     180                    throw new Exception('XML structure is invalid - missing required metadata elements');
     181                }
     182               
     183            } catch (Exception $e) {
     184                $libxml_errors = libxml_get_errors();
     185                $error_messages = array($e->getMessage());
     186               
     187                if (!empty($libxml_errors)) {
     188                    foreach ($libxml_errors as $error) {
     189                        $error_messages[] = "Linea {$error->line}: {$error->message}";
     190                    }
     191                }
     192               
     193                echo '<div class="error"><p><strong>Errore XML:</strong><br>' . esc_html(implode('<br>', $error_messages)) . '</p></div>';
     194               
     195                // Debug: show a sample of the XML input
     196                echo '<div class="error"><p><strong>Inizio XML ricevuto:</strong><br><pre>' . esc_html(substr($xml_input, 0, 300)) . '...</pre></p></div>';
     197               
     198                libxml_use_internal_errors($use_errors);
     199                return;
     200            }
     201           
     202            libxml_use_internal_errors($use_errors);
     203
     204            echo '<h3>Controlla i dati.</h3><h4>' . esc_html($metadata->entePubblicatore) . '<br>Anno ' . esc_html($metadata->annoRiferimento) . '<br>Aggiornato al ' . esc_html($metadata->dataUltimoAggiornamentoDataset) . '</h4>
    126205<table class="widefat">
    127206    <thead>
     
    136215    <tbody>';
    137216
     217            $a = ''; // Initialize alternating row variable
    138218            foreach ($gare_xml->xpath('//lotto') as $lotto) {
    139219                if ($a == '') {
     
    142222                    $a = '';
    143223                }
    144                 echo '<tr' . $a . '>
    145             <td class="row-title"><label for="tablecell">' . $lotto->cig . '</label></td>
    146             <td>' . $lotto->oggetto . '
     224                echo '<tr' . esc_attr($a) . '>
     225            <td class="row-title"><label for="tablecell">' . esc_html($lotto->cig) . '</label></td>
     226            <td>' . esc_html($lotto->oggetto) . '
    147227            <table>';
    148228                foreach ($lotto->partecipanti->partecipante as $partecipante) {
    149                     echo '<tr><td>' . $partecipante->ragioneSociale . ' &bull; ' . $partecipante->codiceFiscale . '</td></tr>';
     229                    // Handle both codiceFiscale and identificativoFiscaleEstero
     230                    $codice_fiscale = isset($partecipante->codiceFiscale) ?
     231                        (string) $partecipante->codiceFiscale :
     232                        (string) $partecipante->identificativoFiscaleEstero;
     233                    echo '<tr><td>' . esc_html($partecipante->ragioneSociale) . ' &bull; ' . esc_html($codice_fiscale) . '</td></tr>';
    150234                }
    151235                echo '</table></td>
    152             <td>€ ' . $lotto->importoAggiudicazione . '</td>
    153             <td>€ ' . $lotto->importoSommeLiquidate . '</td>
    154             <td>' . $lotto->tempiCompletamento->dataInizio . ' &bull; ' . $lotto->tempiCompletamento->dataUltimazione . '</td>
     236            <td>€ ' . esc_html($lotto->importoAggiudicazione) . '</td>
     237            <td>€ ' . esc_html($lotto->importoSommeLiquidate) . '</td>
     238            <td>' . esc_html($lotto->tempiCompletamento->dataInizio) . ' &bull; ' . esc_html($lotto->tempiCompletamento->dataUltimazione) . '</td>
    155239
    156240            </tr>';
     
    160244
    161245            echo '<form method="post" name="options" target="_self">';
    162             add_option('anac_import_xml', $_POST['datasetimporta']);
     246            wp_nonce_field('anac_import_action', 'anac_import_nonce');
     247            add_option('anac_import_xml', $xml_input);
    163248            echo '
    164         <textarea name="importafinale" cols="80" rows="10" class="large-text">' . $_POST['datasetimporta'] . '</textarea>
     249        <textarea name="importafinale" cols="80" rows="10" class="large-text">' . esc_textarea($xml_input) . '</textarea>
    165250        <hr>
    166251        <p class="submit"><input type="submit" class="button-primary" name="Submit" value="Conferma" /></p>
     
    175260
    176261        echo '<form method="post" name="options" target="_self">';
     262        wp_nonce_field('anac_import_action', 'anac_import_nonce');
    177263        echo '<hr>Incolla qui il contenuto del file xml che vuoi importare:<br><br><textarea name="datasetimporta" cols="80" rows="10" class="large-text"></textarea>';
    178264        echo '<hr>
  • avcp/trunk/readme.txt

    r3363055 r3389743  
    8484== Changelog ==
    8585> Questa è la lista completa di tutti gli aggiornamenti, test e correzioni. Ogni volta che una nuova versione viene rilasciata assicuratevi di aggiornare il prima possibile per usufruire delle ultime migliorie!
     86
     87= 7.7.1 2025-11-04 =
     88* Aggiunto supporto nativo nuove annate (2029+2030)
     89* Miglioramento sicurezza
     90* Ottimizzazione delle performance e correzione bug
    8691
    8792= 7.7 20250917 =
Note: See TracChangeset for help on using the changeset viewer.