osCommerce Online Merchant v2.3.3.3

osCommerce Online Merchant v2.3.3.3 is a general maintenance release focusing on improving core features and introducing new security check modules.

This release is in preparation of and building up to v2.3.4.

Changelog Changes from v2.3.3.2

The following changes have been applied:

Title Description Bug Severity Committer
Database Query Logging (2 files) Improve database query error logging. 626 Low Harald
Administration Tool Navigation Menu (1 file) Dynamically load navigation menu boxes. Low Harald
HTTPS -> HTTP Browser Alert (2 files) Have forms posting from a HTTPS to HTTP page post to a HTTPS version to prevent the browser (Firefox) from alerting the user of being directed to an insecure page. 606 Low Harald
Currencies (1 file) Force decimal places value to an integer value. Low Harald
Action Recorder (5 files) When expiring logged entries, don't pass the database connection link to tep_db_affected_rows(). 629 Low Harald
UTF-8 Updates (4 files) Set the MySQL character set to UTF-8 after a connection is made.
Set the English locale to en_US.UTF-8, en_US.UTF8, enu_usa.
Low Harald
Date of Birth (3 files) Take the Configuration -> Minimum Values -> Date of Birth value into consideration to make the date of birth field optional. Low Harald
Administration Tool Automatic HTTP Authentication Login (1 file) Don't use the HTTP Authentication values when the login form is being submitted.
Don't show an invalid administrator notice when an automatic HTTP Authentication fails.
Don't record failed automatic HTTP Authentication logins.
Low Harald
Canonical Manufacturer ID (1 file) Force the Manufacturer ID to an integer value. Low Gary
Administration Tool -> Who's Online (3 files) Remove the session_decode() functionality and show shopping cart contents only for logged in customers.
When regenerating a session ID, update the session ID in the who's online database table to prevent duplicate entries.
Low Harald
MailChimp 360 (1 file) Fix module title. Low Foxp2
Administration Tool -> Security Checks (4 files) Introduce a new security checks page that shows the results of the security checks and extended security checks modules. Low Harald
Administration Tool -> Database Tables (4 files) Introduce a new database tables page to show information and perform actions on database tables. Low Harald
Version Update (1 file) Update version to v2.3.3.3.

New Modules

The following modules have been added:

Security Check Modules Description Committer
Extended Last Run Check Check if the extended security check modules were run in the last 30 days. Harald
Extended Security Check Modules Description Committer
admin/backups/ Directory Listing Check if the admin/backups/ directory is publicly accessible (directory listing or index.html page). Harald
admin/backups/ File Accessibility Check if a backup in admin/backups/ is publicly accessible. Harald
Administration Tool HTTP Authentication Check if a HTTP Authentication layer is active on the Administration Tool. Harald
ext/ Directory Listing Check if the ext/ directory is publicly accessible (directory listing or index.html page). Harald
MySQL UTF-8 Database Tables Check if a database table exists that does not have a utf8_unicode_ci character set. Harald
Version Check Check if a version update check was performed in the last 30 days. Harald
The Extended Security Check modules are located in a new directory in admin/includes/modules/security_check/extended/.

API Changes

The following API changes have been applied:

Title Description
New MySQLi Compatibility Functions mysqli_connect_errno(), mysqli_connect_error(), mysqli_set_charset().
Language Locale The locale defined in the main language file has changed from a LC_TIME setting to LC_ALL, and from a ISO_8859-1 character set to UTF-8.
Who's Online The shopping cart contents of guests are no longer shown on the Who's Online page due to the removal of the potentially session conflicting session_decode() function.
Who's Online New tep_whos_online_update_session_id() function to update the customers session ID in the whos_online database table when their session ID has been regenerated. This prevents duplicate entries showing in the Who's Online listing.
Administration Tool Navigation Menu The Administration Tool navigation menu now loads the boxes dynamically so column_left.php no longer needs to be edited to add a navigation menu link. The navigation links are now sorted alphabetically.
Administration Tool Extended Security Check Modules Extended Security Check modules are located in a new admin/includes/modules/security_check/extended/ directory and are not loaded with the normal security check modules on the Dashboard page due to being more resource intensive. Instead they are loaded on a new Tools -> Security Checks page together with the normal security check modules. Both module types can now have a $has_doc class property to link to the Library Wiki documentation site.

Language Definitions

The following language definitions have been modified:

Definitions Status
[admin] modules/boxes/tools_database_tables.php

MODULES_ADMIN_MENU_TOOLS_DATABASE_TABLES


New
[admin] modules/boxes/tools_security_checks.php

MODULES_ADMIN_MENU_TOOLS_SECURITY_CHECKS


New
[admin] modules/security_check/extended/admin_backup_directory_listing.php

MODULE_SECURITY_CHECK_EXTENDED_ADMIN_BACKUP_DIRECTORY_LISTING_TITLE
MODULE_SECURITY_CHECK_EXTENDED_ADMIN_BACKUP_DIRECTORY_LISTING_HTTP_200


New
New
[admin] modules/security_check/extended/admin_backup_file.php

MODULE_SECURITY_CHECK_EXTENDED_ADMIN_BACKUP_FILE_TITLE
MODULE_SECURITY_CHECK_EXTENDED_ADMIN_BACKUP_FILE_HTTP_200


New
New
[admin] modules/security_check/extended/admin_http_authentication.php

MODULE_SECURITY_CHECK_EXTENDED_ADMIN_HTTP_AUTHENTICATION_TITLE
MODULE_SECURITY_CHECK_EXTENDED_ADMIN_HTTP_AUTHENTICATION_ERROR


New
New
[admin] modules/security_check/extended/ext_directory_listing.php

MODULE_SECURITY_CHECK_EXTENDED_EXT_DIRECTORY_LISTING_TITLE
MODULE_SECURITY_CHECK_EXTENDED_EXT_DIRECTORY_LISTING_HTTP_200


New
New
[admin] modules/security_check/extended/mysql_utf8.php

MODULE_SECURITY_CHECK_EXTENDED_MYSQL_UTF8_TITLE
MODULE_SECURITY_CHECK_EXTENDED_MYSQL_UTF8_ERROR


New
New
[admin] modules/security_check/extended/version_check.php

MODULE_SECURITY_CHECK_EXTENDED_VERSION_CHECK_TITLE
MODULE_SECURITY_CHECK_EXTENDED_VERSION_CHECK_ERROR


New
New
[admin] modules/security_check/extended_last_run.php

MODULE_SECURITY_CHECK_EXTENDED_LAST_RUN_OLD


New
[admin] database_tables.php

HEADING_TITLE
TABLE_HEADING_TABLE
TABLE_HEADING_ROWS
TABLE_HEADING_SIZE
TABLE_HEADING_ENGINE
TABLE_HEADING_COLLATION
TABLE_HEADING_MSG_TYPE
TABLE_HEADING_MSG
ACTION_CHECK_TABLES
ACTION_ANALYZE_TABLES
ACTION_OPTIMIZE_TABLES
ACTION_REPAIR_TABLES
ACTION_UTF8_CONVERSION
BUTTON_ACTION_GO


New
New
New
New
New
New
New
New
New
New
New
New
New
New
[admin] security_checks.php

HEADING_TITLE
TABLE_HEADING_TITLE
TABLE_HEADING_MODULE
TABLE_HEADING_INFO


New
New
New
New

Modified Files

Files that have been modified in this release include:

Modified Files
admin/includes/functions/database.php
admin/includes/languages/english.php
admin/includes/column_left.php
admin/action_recorder.php
admin/customers.php
admin/login.php
admin/whos_online.php
includes/classes/currencies.php
includes/functions/database.php
includes/functions/sessions.php
includes/functions/whos_online.php
includes/languages/english.php
includes/modules/action_recorder/ar_admin_login.php
includes/modules/action_recorder/ar_contact_us.php
includes/modules/action_recorder/ar_reset_password.php
includes/modules/action_recorder/ar_tell_a_friend.php
includes/modules/boxes/bm_manufacturers.php
includes/modules/boxes/bm_search.php
includes/modules/header_tags/ht_canonical.php
includes/modules/header_tags/ht_mailchimp_360.php
includes/version.php
account_edit.php
create_account.php

New Files

Files that have been added to this release include:

New Files
admin/includes/boxes/tools_database_tables.php
admin/includes/boxes/tools_security_checks.php
admin/includes/languages/english/database_tables.php
admin/includes/languages/english/modules/boxes/tools_database_tables.php
admin/includes/languages/english/modules/boxes/tools_security_checks.php
admin/includes/languages/english/modules/security_check/extended/admin_backup_directory_listing.php
admin/includes/languages/english/modules/security_check/extended/admin_backup_file.php
admin/includes/languages/english/modules/security_check/extended/admin_http_authentication.php
admin/includes/languages/english/modules/security_check/extended/ext_directory_listing.php
admin/includes/languages/english/modules/security_check/extended/mysql_utf8.php
admin/includes/languages/english/modules/security_check/extended/version_check.php
admin/includes/languages/english/modules/security_check/extended_last_run.php
admin/includes/languages/english/security_checks.php
admin/includes/modules/security_check/extended/admin_backup_directory_listing.php
admin/includes/modules/security_check/extended/admin_backup_file.php
admin/includes/modules/security_check/extended/admin_http_authentication.php
admin/includes/modules/security_check/extended/ext_directory_listing.php
admin/includes/modules/security_check/extended/mysql_utf8.php
admin/includes/modules/security_check/extended/version_check.php
admin/includes/modules/security_check/extended_last_run.php
admin/database_tables.php
admin/security_checks.php

File Changes

Database Query Logging (2 files)

admin/includes/functions/database.php

change tep_db_error() from:

function tep_db_error($query, $errno, $error) { 
  die('<font color="#000000"><strong>' . $errno . ' - ' . $error . '<br /><br />' . $query . '<br /><br /><small><font color="#ff0000">[TEP STOP]</font></small><br /><br /></strong></font>');
}

to:

function tep_db_error($query, $errno, $error) {
  global $logger;

  if (defined('STORE_DB_TRANSACTIONS') && (STORE_DB_TRANSACTIONS == 'true')) {
    $logger->write('[' . $errno . '] ' . $error, 'ERROR');
  }

  die('<font color="#000000"><strong>' . $errno . ' - ' . $error . '<br /><br />' . $query . '<br /><br /><small><font color="#ff0000">[TEP STOP]</font></small><br /><br /></strong></font>');
}

change tep_db_query() from:

function tep_db_query($query, $link = 'db_link') {
  global $$link, $logger;

  if (defined('STORE_DB_TRANSACTIONS') && (STORE_DB_TRANSACTIONS == 'true')) {
    if (!is_object($logger)) $logger = new logger;
    $logger->write($query, 'QUERY');
  }

  $result = mysqli_query($$link, $query) or tep_db_error($query, mysqli_errno($$link), mysqli_error($$link));

  if (defined('STORE_DB_TRANSACTIONS') && (STORE_DB_TRANSACTIONS == 'true')) {
    if (mysqli_error($$link)) $logger->write(mysqli_error($llink), 'ERROR');
  }

  return $result;
}

to:

function tep_db_query($query, $link = 'db_link') {
  global $$link, $logger;

  if (defined('STORE_DB_TRANSACTIONS') && (STORE_DB_TRANSACTIONS == 'true')) {
    if (!is_object($logger)) $logger = new logger;
    $logger->write($query, 'QUERY');
  }

  $result = mysqli_query($$link, $query) or tep_db_error($query, mysqli_errno($$link), mysqli_error($$link));

  return $result;
}

includes/functions/database.php

change tep_db_error() from:

function tep_db_error($query, $errno, $error) { 
  die('<font color="#000000"><strong>' . $errno . ' - ' . $error . '<br /><br />' . $query . '<br /><br /><small><font color="#ff0000">[TEP STOP]</font></small><br /><br /></strong></font>');
}

to:

function tep_db_error($query, $errno, $error) { 
  if (defined('STORE_DB_TRANSACTIONS') && (STORE_DB_TRANSACTIONS == 'true')) {
    error_log('ERROR: [' . $errno . '] ' . $error . "\n", 3, STORE_PAGE_PARSE_TIME_LOG);
  }

  die('<font color="#000000"><strong>' . $errno . ' - ' . $error . '<br /><br />' . $query . '<br /><br /><small><font color="#ff0000">[TEP STOP]</font></small><br /><br /></strong></font>');
}

change tep_db_query() from:

function tep_db_query($query, $link = 'db_link') {
  global $$link;

  if (defined('STORE_DB_TRANSACTIONS') && (STORE_DB_TRANSACTIONS == 'true')) {
    error_log('QUERY ' . $query . "\n", 3, STORE_PAGE_PARSE_TIME_LOG);
  }

  $result = mysqli_query($$link, $query) or tep_db_error($query, mysqli_errno($$link), mysqli_error($$link));

  if (defined('STORE_DB_TRANSACTIONS') && (STORE_DB_TRANSACTIONS == 'true')) {
     $result_error = mysqli_error($$link);
     error_log('RESULT ' . $result . ' ' . $result_error . "\n", 3, STORE_PAGE_PARSE_TIME_LOG);
  }

  return $result;
}

to:

function tep_db_query($query, $link = 'db_link') {
  global $$link;

  if (defined('STORE_DB_TRANSACTIONS') && (STORE_DB_TRANSACTIONS == 'true')) {
    error_log('QUERY: ' . $query . "\n", 3, STORE_PAGE_PARSE_TIME_LOG);
  }

  $result = mysqli_query($$link, $query) or tep_db_error($query, mysqli_errno($$link), mysqli_error($$link));

  return $result;
}

View online at GitHub

Administration Tool Navigation Menu (1 file)

admin/includes/column_left.php

around line 16, change from:

include(DIR_WS_BOXES . 'configuration.php');
include(DIR_WS_BOXES . 'catalog.php');
include(DIR_WS_BOXES . 'modules.php');
include(DIR_WS_BOXES . 'customers.php');
include(DIR_WS_BOXES . 'taxes.php');
include(DIR_WS_BOXES . 'localization.php');
include(DIR_WS_BOXES . 'reports.php');
include(DIR_WS_BOXES . 'tools.php');

to:

if ($dir = @dir(DIR_FS_ADMIN . 'includes/boxes')) {
  $files = array();

  while ($file = $dir->read()) {
    if (!is_dir($dir->path . '/' . $file)) {
      if (substr($file, strrpos($file, '.')) == '.php') {
        $files[] = $file;
      }
    }
  }

  $dir->close();

  natcasesort($files);

  foreach ( $files as $file ) {
    if ( file_exists(DIR_FS_ADMIN . 'includes/languages/' . $language . '/modules/boxes/' . $file) ) {
      include(DIR_FS_ADMIN . 'includes/languages/' . $language . '/modules/boxes/' . $file);
    }

    include($dir->path . '/' . $file);
  }
}

function tep_sort_admin_boxes($a, $b) {
  return strcasecmp($a['heading'], $b['heading']);
}

usort($cl_box_groups, 'tep_sort_admin_boxes');

function tep_sort_admin_boxes_links($a, $b) {
  return strcasecmp($a['title'], $b['title']);
}

foreach ( $cl_box_groups as &$group ) {
  usort($group['apps'], 'tep_sort_admin_boxes_links');
}

View online at GitHub

HTTPS -> HTTP Browser Alert (2 files)

includes/modules/boxes/bm_manufacturers.php

around line 34, change from:

global $HTTP_GET_VARS, $oscTemplate;

to:

global $HTTP_GET_VARS, $request_type, $oscTemplate;

around line 65, change from:

$content = tep_draw_form('manufacturers', tep_href_link(FILENAME_DEFAULT, '', 'NONSSL', false), 'get') .

to:

$content = tep_draw_form('manufacturers', tep_href_link(FILENAME_DEFAULT, '', $request_type, false), 'get') .

includes/modules/boxes/bm_search.php

around line 34, change from:

global $oscTemplate;

to:

global $request_type, $oscTemplate;

around line 39, change from:

'    ' . tep_draw_form('quick_find', tep_href_link(FILENAME_ADVANCED_SEARCH_RESULT, '', 'NONSSL', false), 'get') .

to:

'    ' . tep_draw_form('quick_find', tep_href_link(FILENAME_ADVANCED_SEARCH_RESULT, '', $request_type, false), 'get') .

View online at GitHub

Currencies (1 file)

includes/classes/currencies.php

around line 29, change from:

'decimal_places' => $currencies['decimal_places'],

to:

'decimal_places' => (int)$currencies['decimal_places'],

View online at GitHub

Action Recorder (5 files)

admin/action_recorder.php

around line 67, change from:

$expired_entries += tep_db_affected_rows($db_link);

to:

$expired_entries += tep_db_affected_rows();

includes/modules/action_recorder/ar_admin_login.php
includes/modules/action_recorder/ar_contact_us.php
includes/modules/action_recorder/ar_reset_password.php
includes/modules/action_recorder/ar_tell_a_friend.php

in those 4 module files, change expireEntries() from:

function expireEntries() {
  global $db_link;

  tep_db_query("delete from " . TABLE_ACTION_RECORDER . " where module = '" . $this->code . "' and date_added < date_sub(now(), interval " . (int)$this->minutes  . " minute)");

  return tep_db_affected_rows($db_link);
}

to:

function expireEntries() {
  tep_db_query("delete from " . TABLE_ACTION_RECORDER . " where module = '" . $this->code . "' and date_added < date_sub(now(), interval " . (int)$this->minutes  . " minute)");

  return tep_db_affected_rows();
}

View online at GitHub

UTF-8 Updates (4 files)

admin/includes/functions/database.php
includes/functions/database.php

in those 2 files, change tep_db_connect() from:

function tep_db_connect($server = DB_SERVER, $username = DB_SERVER_USERNAME, $password = DB_SERVER_PASSWORD, $database = DB_DATABASE, $link = 'db_link') {
  global $$link;

  if (USE_PCONNECT == 'true') {
    $server = 'p:' . $server;
  }

  $$link = mysqli_connect($server, $username, $password, $database);

  return $$link;
}

to:

function tep_db_connect($server = DB_SERVER, $username = DB_SERVER_USERNAME, $password = DB_SERVER_PASSWORD, $database = DB_DATABASE, $link = 'db_link') {
  global $$link;

  if (USE_PCONNECT == 'true') {
    $server = 'p:' . $server;
  }

  $$link = mysqli_connect($server, $username, $password, $database);

  if ( !mysqli_connect_errno() ) {
    mysqli_set_charset($$link, 'utf8');
  } 

  return $$link;
}

after the mysqli_connect() function (defined around line 178), add:

function mysqli_connect_errno($link = null) {
  return mysql_errno($link);
}

function mysqli_connect_error($link = null) {
  return mysql_error($link);
}

function mysqli_set_charset($link, $charset) {
  if ( function_exists('mysql_set_charset') ) {
    return mysql_set_charset($charset, $link);
  }
}

admin/includes/languages/english.php
includes/languages/english.php

in those 2 files, around lines 17 and 19, change from:

setlocale(LC_TIME, 'en_US.ISO_8859-1');

to:

setlocale(LC_ALL, array('en_US.UTF-8', 'en_US.UTF8', 'enu_usa'));

Please also make the same change to the main catalog and admin language files for other languages you have installed. Example language UTF-8 locales are:

  • Arabic: ar_SA.UTF-8, ar_SA.UTF8, ara_sau
  • Chinese (Simplified): zh_CN.UTF-8, zh_CN.UTF8, chs_chn
  • Chinese (Traditional): zh_TW.UTF-8, zh_TW.UTF8, cht_twn
  • Dutch: nl_NL.UTF-8, nl_NL.UTF8, nld_nld
  • French (Canada): fr_CA.UTF-8, fr_CA.UTF8, frc_can
  • French (France): fr_FR.UTF-8, fr_FR.UTF8, fra_fra
  • German: de_DE.UTF-8, de_DE.UTF8, deu_deu
  • Greek: el_GR.UTF-8, el_GR.UTF8, ell_grc
  • Hebrew: iw_IL.UTF-8, iw_IL.UTF8, heb_isr
  • Hindi: hi_IN.UTF-8, hi_IN.UTF8, hin_ind
  • Italian: it_IT.UTF-8, it_IT.UTF8, ita_ita
  • Japanese: ja_JP.UTF-8, ja_JP.UTF8, jpn_jpn
  • Korean: ko_KR.UTF-8, ko_KR.UTF8, kor_kor
  • Portuguese: pt_BR.UTF-8, pt_BR.UTF8, ptb_bra
  • Russian: ru_RU.UTF-8, ru_RU.UTF8, rus_rus
  • Spanish: es_ES.UTF-8, es_ES.UTF8, esp_esp
  • Swedish: sv_SE.UTF-8, sv_SE.UTF8, sve_swe
  • Turkish: tr_TR.UTF-8, tr_TR.UTF8, trk_tur
Please also apply the Administration Tool -> Database Tables changeset described in this release guide to be able to see the character sets of your database tables and convert non-UTF8 tables to utf8_unicode_ci.

View online at GitHub

Date of Birth (3 files)

admin/customers.php

around line 60, change from:

if (checkdate(substr(tep_date_raw($customers_dob), 4, 2), substr(tep_date_raw($customers_dob), 6, 2), substr(tep_date_raw($customers_dob), 0, 4))) {

to:

if ((strlen($customers_dob) >= ENTRY_DOB_MIN_LENGTH) && ((is_numeric(tep_date_raw($customers_dob)) && @checkdate(substr(tep_date_raw($customers_dob), 4, 2), substr(tep_date_raw($customers_dob), 6, 2), substr(tep_date_raw($customers_dob), 0, 4))) || empty($customers_dob))) {

account_edit.php

around line 55, change from:

if ((is_numeric(tep_date_raw($dob)) == false) || (@checkdate(substr(tep_date_raw($dob), 4, 2), substr(tep_date_raw($dob), 6, 2), substr(tep_date_raw($dob), 0, 4)) == false)) {

to:

if ((strlen($dob) < ENTRY_DOB_MIN_LENGTH) || (!empty($dob) && (!is_numeric(tep_date_raw($dob)) || !@checkdate(substr(tep_date_raw($dob), 4, 2), substr(tep_date_raw($dob), 6, 2), substr(tep_date_raw($dob), 0, 4))))) {

create_account.php

around line 80, change from:

if ((is_numeric(tep_date_raw($dob)) == false) || (@checkdate(substr(tep_date_raw($dob), 4, 2), substr(tep_date_raw($dob), 6, 2), substr(tep_date_raw($dob), 0, 4)) == false)) {

to:

if ((strlen($dob) < ENTRY_DOB_MIN_LENGTH) || (!empty($dob) && (!is_numeric(tep_date_raw($dob)) || !@checkdate(substr(tep_date_raw($dob), 4, 2), substr(tep_date_raw($dob), 6, 2), substr(tep_date_raw($dob), 0, 4))))) {

View online at GitHub

Administration Tool Automatic HTTP Authentication Login (1 file)

admin/login.php

around line 28, change from:

if (tep_session_is_registered('redirect_origin') && isset($redirect_origin['auth_user'])) {

to:

if (tep_session_is_registered('redirect_origin') && isset($redirect_origin['auth_user']) && !isset($HTTP_POST_VARS['username'])) {

around line 75, change from:

$messageStack->add(ERROR_INVALID_ADMINISTRATOR, 'error');

to:

if (isset($HTTP_POST_VARS['username'])) {
  $messageStack->add(ERROR_INVALID_ADMINISTRATOR, 'error');
}

around line 80, change from:

$actionRecorder->record(false);

to:

if (isset($HTTP_POST_VARS['username'])) {
  $actionRecorder->record(false);
}

View online at GitHub

Canonical Manufacturer ID (1 file)

includes/modules/header_tags/ht_canonical.php

around line 40, change from:

$oscTemplate->addBlock('<link rel="canonical" href="' . tep_href_link(FILENAME_DEFAULT, 'manufacturers_id=' . $HTTP_GET_VARS['manufacturers_id'], 'NONSSL', false) . '" />' . "\n", $this->group);

to:

$oscTemplate->addBlock('<link rel="canonical" href="' . tep_href_link(FILENAME_DEFAULT, 'manufacturers_id=' . (int)$HTTP_GET_VARS['manufacturers_id'], 'NONSSL', false) . '" />' . "\n", $this->group);

View online at GitHub

Administration Tool -> Who's Online (3 files)

admin/whos_online.php

It is safe to skip this file if your version contains customizations or modifications from an Add-On.

around line 53, change from:

$info = $whos_online['session_id'];

to:

$info = new ObjectInfo($whos_online);

around line 56, change from:

if ($whos_online['session_id'] == $info) {

to:

if (isset($info) && ($whos_online['session_id'] == $info->session_id)) {

around line 68, change from:

<td class="dataTableContent"><?php if (preg_match('/^(.*)' . tep_session_name() . '=[a-f,0-9]+[&]*(.*)/i', $whos_online['last_page_url'], $array)) { echo $array[1] . $array[2]; } else { echo $whos_online['last_page_url']; } ?>&nbsp;</td>

to:

<td class="dataTableContent"><?php if (preg_match('/^(.*)osCsid=[A-Z0-9,-]+[&]*(.*)/i', $whos_online['last_page_url'], $array)) { echo $array[1] . $array[2]; } else { echo $whos_online['last_page_url']; } ?>&nbsp;</td>

around line 81, change from:

if (isset($info)) {
  $heading[] = array('text' => '<strong>' . TABLE_HEADING_SHOPPING_CART . '</strong>');

  if (STORE_SESSIONS == 'mysql') {
    $session_data = tep_db_query("select value from " . TABLE_SESSIONS . " WHERE sesskey = '" . $info . "'");
    $session_data = tep_db_fetch_array($session_data);
    $session_data = trim($session_data['value']);
  } else {
    if ( (file_exists(tep_session_save_path() . '/sess_' . $info)) && (filesize(tep_session_save_path() . '/sess_' . $info) > 0) ) {
      $session_data = file(tep_session_save_path() . '/sess_' . $info);
      $session_data = trim(implode('', $session_data));
    }
  }

  if ($length = strlen($session_data)) {
    $start_id = strpos($session_data, 'customer_id|s');
    $start_cart = strpos($session_data, 'cart|O');
    $start_currency = strpos($session_data, 'currency|s');
    $start_country = strpos($session_data, 'customer_country_id|s');
    $start_zone = strpos($session_data, 'customer_zone_id|s');

    for ($i=$start_cart; $i<$length; $i++) {
      if ($session_data[$i] == '{') {
        if (isset($tag)) {
          $tag++;
        } else {
          $tag = 1;
        }
      } elseif ($session_data[$i] == '}') {
        $tag--;
      } elseif ( (isset($tag)) && ($tag < 1) ) {
        break;
      }
    }

    $session_data_id = substr($session_data, $start_id, (strpos($session_data, ';', $start_id) - $start_id + 1));
    $session_data_cart = substr($session_data, $start_cart, $i);
    $session_data_currency = substr($session_data, $start_currency, (strpos($session_data, ';', $start_currency) - $start_currency + 1));
    $session_data_country = substr($session_data, $start_country, (strpos($session_data, ';', $start_country) - $start_country + 1));
    $session_data_zone = substr($session_data, $start_zone, (strpos($session_data, ';', $start_zone) - $start_zone + 1));

    session_decode($session_data_id);
    session_decode($session_data_currency);
    session_decode($session_data_country);
    session_decode($session_data_zone);
    session_decode($session_data_cart);

    if (isset($cart) && is_object($cart)) {
      $products = $cart->get_products();
      for ($i = 0, $n = sizeof($products); $i < $n; $i++) {
        $contents[] = array('text' => $products[$i]['quantity'] . ' x ' . $products[$i]['name']);
      }

      if (sizeof($products) > 0) {
        $contents[] = array('text' => tep_draw_separator('pixel_black.gif', '100%', '1'));
        $contents[] = array('align' => 'right', 'text'  => TEXT_SHOPPING_CART_SUBTOTAL . ' ' . $currencies->format($cart->show_total(), true, $currency));
      } else {
        $contents[] = array('text' => '&nbsp;');
      }
    }
  }
}

to:

if (isset($info)) {
  $heading[] = array('text' => '<strong>' . TABLE_HEADING_SHOPPING_CART . '</strong>');

  if ( $info->customer_id > 0 ) {
    $products_query = tep_db_query("select cb.customers_basket_quantity, cb.products_id, pd.products_name from " . TABLE_CUSTOMERS_BASKET . " cb, " . TABLE_PRODUCTS_DESCRIPTION . " pd where cb.customers_id = '" . (int)$info->customer_id . "' and cb.products_id = pd.products_id and pd.language_id = '" . (int)$languages_id . "'");

    if ( tep_db_num_rows($products_query) ) {
      $shoppingCart = new shoppingCart();

      while ( $products = tep_db_fetch_array($products_query) ) {
        $contents[] = array('text' => $products['customers_basket_quantity'] . ' x ' . $products['products_name']);

        $attributes = array();

        if ( strpos($products['products_id'], '{') !== false ) {
          $combos = array();
          preg_match_all('/(\{[0-9]+\}[0-9]+){1}/', $products['products_id'], $combos);

          foreach ( $combos[0] as $combo ) {
            $att = array();
            preg_match('/\{([0-9]+)\}([0-9]+)/', $combo, $att);

            $attributes[$att[1]] = $att[2];
          }
        }

        $shoppingCart->add_cart(tep_get_prid($products['products_id']), $products['customers_basket_quantity'], $attributes);
      }

      $contents[] = array('text' => tep_draw_separator('pixel_black.gif', '100%', '1'));
      $contents[] = array('align' => 'right', 'text'  => TEXT_SHOPPING_CART_SUBTOTAL . ' ' . $currencies->format($shoppingCart->show_total()));
    } else {
      $contents[] = array('text' => '&nbsp;');
    }
  } else {
    $contents[] = array('text' => 'N/A');
  }
}

includes/functions/sessions.php

change tep_session_recreate() from:

function tep_session_recreate() {
  global $SID;

  if (PHP_VERSION >= 5.1) {
    session_regenerate_id(true);

    if (!empty($SID)) {
      $SID = tep_session_name() . '=' . tep_session_id();
    }
  }
}

to:

function tep_session_recreate() {
  global $SID;

  if (PHP_VERSION >= 5.1) {
    $old_id = session_id();

    session_regenerate_id(true);

    if (!empty($SID)) {
      $SID = tep_session_name() . '=' . tep_session_id();
    }

    tep_whos_online_update_session_id($old_id, tep_session_id());
  }
}

includes/functions/whos_online.php

around line 38, change from:

$stored_customer_query = tep_db_query("select count(*) as count from " . TABLE_WHOS_ONLINE . " where session_id = '" . tep_db_input($wo_session_id) . "'");
$stored_customer = tep_db_fetch_array($stored_customer_query);

if ($stored_customer['count'] > 0) {

to:

$stored_customer_query = tep_db_query("select session_id from " . TABLE_WHOS_ONLINE . " where session_id = '" . tep_db_input($wo_session_id) . "' limit 1");

if ( tep_db_num_rows($stored_customer_query) > 0 ) {

after tep_update_whos_online(), add:

function tep_whos_online_update_session_id($old_id, $new_id) {
  tep_db_query("update " . TABLE_WHOS_ONLINE . " set session_id = '" . tep_db_input($new_id) . "' where session_id = '" . tep_db_input($old_id) . "'");
}

View online at GitHub

MailChimp 360 (1 file)

includes/modules/header_tags/ht_mailchimp_360.php

around line 54, change from:

tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, date_added) values ('Enable Category Title Module', 'MODULE_HEADER_TAGS_MAILCHIMP_360_STATUS', 'True', 'Do you want to allow category titles to be added to the page title?', '6', '1', 'tep_cfg_select_option(array(\'True\', \'False\'), ', now())");

to:

tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, date_added) values ('Enable MailChimp 360 Module', 'MODULE_HEADER_TAGS_MAILCHIMP_360_STATUS', 'True', 'Do you want to activate this module in your shop?', '6', '1', 'tep_cfg_select_option(array(\'True\', \'False\'), ', now())");

View online at GitHub

Administration Tool -> Security Checks (4 files)

Copy the following files to their respective directories:

admin/includes/boxes/tools_security_checks.php
admin/includes/languages/english/modules/boxes/tools_security_checks.php
admin/includes/languages/english/security_checks.php
admin/security_checks.php

Please also copy and update the language definition file to the other languages you have installed.
This changeset should be performed after the Administration Tool Navigation Menu changeset for the link to appear automatically in the Administration Tool -> Tools menu.

View online at GitHub

Administration Tool -> Database Tables (4 files)

Copy the following files to their respective directories:

admin/includes/boxes/tools_database_tables.php
admin/includes/languages/english/modules/boxes/tools_database_tables.php
admin/includes/languages/english/database_tables.php
admin/database_tables.php

Please also copy and update the language definition file to the other languages you have installed.
This changeset should be performed after the Administration Tool Navigation Menu changeset for the link to appear automatically in the Administration Tool -> Tools menu.

View online at GitHub

Version Update (1 file)

includes/version.php

change line 1 from:

2.3.3.2

to:

2.3.3.3

View online at GitHub

Extended Last Run Check

Copy the following files to their respective directories:

admin/includes/languages/english/modules/security_check/extended_last_run.php
admin/includes/modules/security_check/extended_last_run.php

Please also copy and update the language definition file to the other languages you have installed.
After this changeset is applied, the module can be found in Administration Tool -> Tools -> Security Checks.

View online at GitHub

admin/backups/ Directory Listing

Copy the following files to their respective directories:

admin/includes/languages/english/modules/security_check/extended/admin_backup_directory_listing.php
admin/includes/modules/security_check/extended/admin_backup_directory_listing.php

Please also copy and update the language definition file to the other languages you have installed.
After this changeset is applied, the module can be found in Administration Tool -> Tools -> Security Checks.

View online at GitHub

admin/backups/ File Accessibility

Copy the following files to their respective directories:

admin/includes/languages/english/modules/security_check/extended/admin_backup_file.php
admin/includes/modules/security_check/extended/admin_backup_file.php

Please also copy and update the language definition file to the other languages you have installed.
After this changeset is applied, the module can be found in Administration Tool -> Tools -> Security Checks.

View online at GitHub

Administration Tool HTTP Authentication

Copy the following files to their respective directories:

admin/includes/languages/english/modules/security_check/extended/admin_http_authentication.php
admin/includes/modules/security_check/extended/admin_http_authentication.php

Please also copy and update the language definition file to the other languages you have installed.
After this changeset is applied, the module can be found in Administration Tool -> Tools -> Security Checks.

View online at GitHub

ext/ Directory Listing

Copy the following files to their respective directories:

admin/includes/languages/english/modules/security_check/extended/ext_directory_listing.php
admin/includes/modules/security_check/extended/ext_directory_listing.php

Please also copy and update the language definition file to the other languages you have installed.
After this changeset is applied, the module can be found in Administration Tool -> Tools -> Security Checks.

View online at GitHub

MySQL UTF-8 Database Tables

Copy the following files to their respective directories:

admin/includes/languages/english/modules/security_check/extended/mysql_utf8.php
admin/includes/modules/security_check/extended/mysql_utf8.php

Please also copy and update the language definition file to the other languages you have installed.
After this changeset is applied, the module can be found in Administration Tool -> Tools -> Security Checks.

View online at GitHub

Version Check

Copy the following files to their respective directories:

admin/includes/languages/english/modules/security_check/extended/version_check.php
admin/includes/modules/security_check/extended/version_check.php

Please also copy and update the language definition file to the other languages you have installed.
After this changeset is applied, the module can be found in Administration Tool -> Tools -> Security Checks.

View online at GitHub

Thank You!

We'd like to thank the community for their feedback on our releases. In addition, we thank the following people who participated in the development of this release.

Bug Reporters
ABS0lute
Bob Terveuren
D-BlooD
dculley
Jack_mcs
mvanderhoff
Scottyj
skleiner
t.man

Reference

A full list of source code changes can be seen at:

https://github.com/osCommerce/oscommerce2/compare/v2.3.3.2...upgrade2333