Plugin Directory

Changeset 3427994


Ignore:
Timestamp:
12/26/2025 09:57:53 PM (3 months ago)
Author:
stankovski
Message:

Addressed plugin check findings

Location:
muslim-prayer-times/trunk
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • muslim-prayer-times/trunk/includes/rest-api.php

    r3427919 r3427994  
    5252    // Build Info Object
    5353    $info = array(
    54         'title' => get_bloginfo('name') . ' Prayer Times',
    55         'description' => 'Islamic prayer times provided by ' . get_bloginfo('name'),
     54        'title' => sanitize_text_field(get_bloginfo('name')) . ' Prayer Times',
     55        'description' => 'Islamic prayer times provided by ' . sanitize_text_field(get_bloginfo('name')),
    5656        'version' => '1.0.0',
    5757    );
     
    5959    // Get admin email if available
    6060    $admin_email = get_option('admin_email');
    61     if ($admin_email) {
     61    if ($admin_email && is_email($admin_email)) {
    6262        $info['contact'] = array(
    63             'name' => get_bloginfo('name'),
    64             'email' => $admin_email,
     63            'name' => sanitize_text_field(get_bloginfo('name')),
     64            'email' => sanitize_email($admin_email),
    6565        );
    6666    }
    6767   
    6868    // Build Location Object
     69    // Sanitize and validate timezone
     70    $default_timezone = 'America/Los_Angeles';
     71    $timezone = isset($opts['tz']) ? sanitize_text_field($opts['tz']) : $default_timezone;
     72   
     73    // Validate timezone against PHP's list of valid timezones
     74    $valid_timezones = timezone_identifiers_list();
     75    if (!in_array($timezone, $valid_timezones, true)) {
     76        $timezone = $default_timezone;
     77    }
     78   
    6979    $location = array(
    7080        'latitude' => isset($opts['lat']) ? floatval($opts['lat']) : 47.7623,
    7181        'longitude' => isset($opts['lng']) ? floatval($opts['lng']) : -122.2054,
    72         'timezone' => isset($opts['tz']) ? $opts['tz'] : 'America/Los_Angeles',
     82        'timezone' => $timezone,
    7383        'dateFormat' => 'YYYY-MM-DD',
    7484        'timeFormat' => 'HH:mm',
     
    315325    global $wpdb;
    316326   
     327    // Check cache first
    317328    $from_date = $request->get_param('fromDate');
    318329    $to_date = $request->get_param('toDate');
     
    328339    }
    329340   
    330     // Validate date format
     341    // Validate date format and actual date validity
    331342    if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $from_date) || !preg_match('/^\d{4}-\d{2}-\d{2}$/', $to_date)) {
    332343        return new WP_Error('invalid_date', 'Date must be in YYYY-MM-DD format', array('status' => 400));
    333344    }
    334345   
     346    // Validate that dates are actually valid (e.g., not 2025-02-30)
     347    $from_date_obj = DateTime::createFromFormat('Y-m-d', $from_date);
     348    $to_date_obj = DateTime::createFromFormat('Y-m-d', $to_date);
     349   
     350    if (!$from_date_obj || $from_date_obj->format('Y-m-d') !== $from_date ||
     351        !$to_date_obj || $to_date_obj->format('Y-m-d') !== $to_date) {
     352        return new WP_Error('invalid_date', 'Invalid date provided', array('status' => 400));
     353    }
     354   
     355    // Ensure from_date is not after to_date
     356    if ($from_date_obj > $to_date_obj) {
     357        return new WP_Error('invalid_date_range', 'Start date must be before or equal to end date', array('status' => 400));
     358    }
     359   
     360    // Limit date range to prevent abuse (max 1 year)
     361    $date_diff = $from_date_obj->diff($to_date_obj);
     362    $days_diff = $date_diff->days;
     363    if ($days_diff > 366) {
     364        return new WP_Error('date_range_too_large', 'Date range cannot exceed 1 year', array('status' => 400));
     365    }
     366   
     367    // Check cache for this date range
     368    $cache_key = 'muslprti_csv_' . md5($from_date . '_' . $to_date);
     369    $cached_data = wp_cache_get($cache_key, 'muslim_prayer_times');
     370   
     371    if (false !== $cached_data) {
     372        // Return cached CSV content directly to avoid JSON encoding
     373        header('Content-Type: text/csv; charset=utf-8');
     374        header('Content-Disposition: inline; filename="prayer-times.csv"');
     375        header('Content-Length: ' . strlen($cached_data));
     376        // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
     377        echo $cached_data;
     378        exit;
     379    }
     380   
     381    // Table name is safe - MUSLPRTI_IQAMA_TABLE is a constant, not user input
    335382    $table_name = $wpdb->prefix . MUSLPRTI_IQAMA_TABLE;
    336383   
    337384    // Query prayer times from database
     385    // Note: Table name must be escaped outside of prepare() as prepare() only handles placeholders
    338386    $query = $wpdb->prepare(
    339387        "SELECT day, fajr_athan, fajr_iqama, sunrise, dhuhr_athan, dhuhr_iqama,
    340388                asr_athan, asr_iqama, maghrib_athan, maghrib_iqama, isha_athan, isha_iqama
    341          FROM {$table_name}
     389         FROM " . esc_sql($table_name) . "
    342390         WHERE day >= %s AND day <= %s
    343391         ORDER BY day ASC",
     
    352400    }
    353401   
    354     // Set proper headers for CSV output
    355     header('Content-Type: text/csv; charset=utf-8');
    356     header('Content-Disposition: inline; filename="prayer-times.csv"');
    357    
    358     // Open output stream
    359     $output = fopen('php://output', 'w');
    360    
    361     // Add header row
     402    // Build CSV content in memory without using fopen()
     403    // Define headers
    362404    $headers = array(
    363405        'day', 'fajr_athan', 'fajr_iqama', 'sunrise', 'dhuhr_athan', 'dhuhr_iqama',
    364406        'asr_athan', 'asr_iqama', 'maghrib_athan', 'maghrib_iqama', 'isha_athan', 'isha_iqama'
    365407    );
    366     fputcsv($output, $headers);
     408   
     409    // Build CSV content as string
     410    $csv_lines = array();
     411   
     412    // Add header row
     413    $csv_lines[] = implode(',', array_map(function($header) {
     414        return '"' . str_replace('"', '""', $header) . '"';
     415    }, $headers));
    367416   
    368417    // Add data rows
     
    370419        $csv_row = array();
    371420        foreach ($headers as $header) {
    372             $csv_row[] = isset($row[$header]) ? $row[$header] : '';
    373         }
    374         fputcsv($output, $csv_row);
    375     }
    376    
    377     fclose($output);
     421            $value = isset($row[$header]) ? $row[$header] : '';
     422            $csv_row[] = '"' . str_replace('"', '""', $value) . '"';
     423        }
     424        $csv_lines[] = implode(',', $csv_row);
     425    }
     426   
     427    // Combine all lines
     428    $csv_content = implode("\n", $csv_lines);
     429   
     430    // Cache the CSV content for 5 minutes
     431    wp_cache_set($cache_key, $csv_content, 'muslim_prayer_times', 300);
     432   
     433    // For CSV, we need to output directly to avoid JSON encoding
     434    // Set headers for CSV download
     435    header('Content-Type: text/csv; charset=utf-8');
     436    header('Content-Disposition: inline; filename="prayer-times.csv"');
     437    header('Content-Length: ' . strlen($csv_content));
     438   
     439    // Output CSV content and exit
     440    // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
     441    echo $csv_content;
    378442    exit;
    379443}
  • muslim-prayer-times/trunk/includes/salah-api/Calculations/TimeHelpers.php

    r3427919 r3427994  
    204204       
    205205        if (count($parts) !== 2) {
    206             throw new \InvalidArgumentException("Invalid time format: {$timeString}");
     206            throw new \InvalidArgumentException("Invalid time format: " . esc_html($timeString));
    207207        }
    208208       
  • muslim-prayer-times/trunk/includes/upgrade.php

    r3303241 r3427994  
    2222    // Only add the column if it doesn't exist
    2323    if (empty($column_exists)) {
    24         $wpdb->query("ALTER TABLE $table_name ADD COLUMN sunrise time DEFAULT NULL AFTER fajr_iqama");
     24        // Table name must be escaped separately as wpdb->prepare() doesn't handle identifiers
     25        $wpdb->query("ALTER TABLE " . esc_sql($table_name) . " ADD COLUMN sunrise time DEFAULT NULL AFTER fajr_iqama");
    2526        update_option('muslprti_db_version', '1.1');
    2627    }
  • muslim-prayer-times/trunk/muslim-prayer-times.php

    r3427919 r3427994  
    44Plugin URI: https://github.com/stankovski/wp-prayer-times
    55Description: A WordPress plugin for managing and displaying Islamic prayer times.
    6 Version: 1.2
     6Version: 1.2.1
    77Requires at least: 5.0
    88Requires PHP: 7.0
     9Tested up to: 6.9
    910Author: stankovski
    1011Author URI: https://github.com/stankovski
     
    2526
    2627// Define version for database upgrades
    27 define('MUSLPRTI_DB_VERSION', '1.2');
     28define('MUSLPRTI_DB_VERSION', '1.2.1');
    2829
    2930// Include the upgrade script
  • muslim-prayer-times/trunk/readme.txt

    r3427919 r3427994  
    33Tags: prayer times, muslim, islamic, mosque, salah
    44Requires at least: 5.0
    5 Tested up to: 6.8.3
    6 Stable tag: 1.2
     5Tested up to: 6.9
     6Stable tag: 1.2.1
    77Requires PHP: 7.0
    88License: MIT
     
    1919* Monthly prayer times calendar
    2020* Live prayer times display that updates automatically
     21* SalahAPI 1.0 support for standardized prayer times data exchange
     22* REST API endpoints for integration with other systems
    2123* Customizable calculation methods (MWL, ISNA, Egypt, etc.)
    2224* Blocks and shortcodes for easy integration
     
    139141== Changelog ==
    140142
     143= 1.2.1 =
     144* Tested with WordPress 6.9
     145* Minor bug fixes and improvements
     146
    141147= 1.2 =
    142 * Added support for SalahAPI (https://github.com/salahapi/salahapi-specification/)
     148* Added support for SalahAPI 1.0 (https://github.com/salahapi/salahapi-specification/)
    143149* REST API endpoint for standardized prayer times data exchange
    144150* CSV export endpoint for prayer times data
  • muslim-prayer-times/trunk/settings.php

    r3427919 r3427994  
    977977                                    echo sprintf(
    978978                                        'Ramadan %d: %s to %s',
    979                                         $current_year,
     979                                        esc_html($current_year),
    980980                                        esc_html(muslprti_date('F j, Y', strtotime($ramadan_dates['start']))),
    981981                                        esc_html(muslprti_date('F j, Y', strtotime($ramadan_dates['end'])))
     
    986986                                        echo sprintf(
    987987                                            'Next Ramadan (%d): %s to %s',
    988                                             $current_year + 1,
     988                                            esc_html($current_year + 1),
    989989                                            esc_html(muslprti_date('F j, Y', strtotime($ramadan_dates['start']))),
    990990                                            esc_html(muslprti_date('F j, Y', strtotime($ramadan_dates['end'])))
Note: See TracChangeset for help on using the changeset viewer.