osCommerce 2.2 Milestone 2 Update 051112

Update Package 12th November 2005

 

 

 

 

Table of Contents

 

 

Cannot re-assign $this. 2

limit -20, 20. 3

Database Input Enhancement 4

Adding Non-Existing Products To Cart 6

Session ID XSS Issue. 11

Validate Session ID.. 12

File Manager Problem.. 14

HTTP Header Injection. 15

E-Mail Header Injection. 17

Contact Us Form XSS Issue. 20

Open Redirector 21

Extra Slashes In New Products. 22

Order Status Filtering. 24

MySQL 5.0 Compatibility. 25


Cannot re-assign $this

http://www.oscommerce.com/community/bugs,1650

 

Problem:

 

Fatal error: Cannot re-assign $this in /path/to/catalog/admin/includes/classes/upload.php on line 31

 

Solution:

 

Lines 27-34 in catalog/admin/includes/classes/upload.php must be changed from:

 

if ( ($this->parse() == true) && ($this->save() == true) ) {

  return true;

} else {

// self destruct

  $this = null;

 

  return false;

}

 

to:

 

if ( ($this->parse() == true) && ($this->save() == true) ) {

  return true;

} else {

  return false;

}


limit -20, 20

http://www.oscommerce.com/community/bugs,1605

 

Problem:

 

1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '-20, 20' at line 1

 

Solution:

 

Line 67 in catalog/includes/classes/split_page_results.php must be changed from:

 

$this->sql_query .= " limit " . $offset . ", " . $this->number_of_rows_per_page;

 

to:

 

$this->sql_query .= " limit " . max($offset, 0) . ", " . $this->number_of_rows_per_page;

 

Line 38 in catalog/admin/includes/classes/split_page_results.php must be changed from:

 

$sql_query .= " limit " . $offset . ", " . $max_rows_per_page;

 

to:

 

$sql_query .= " limit " . max($offset, 0) . ", " . $max_rows_per_page;


Database Input Enhancement

 

Problem:

 

Native MySQL functions should be used in preference to the addslashes() function, to properly protect the SQL queries being executed on the database server.

 

Solution:

 

The following function must be replaced in catalog/includes/functions/database.php.

 

Lines 126-128, from:

 

function tep_db_input($string) {

  return addslashes($string);

}

 

to:

 

function tep_db_input($string, $link = 'db_link') {
  global $$link;
 
  if (function_exists('mysql_real_escape_string')) {
    return mysql_real_escape_string($string, $$link);
  } elseif (function_exists('mysql_escape_string')) {
    return mysql_escape_string($string);
  }
 
  return addslashes($string);
}

 

The following function must be replaced in catalog/admin/includes/functions/database.php.

 

Lines 130-132, from:

 

function tep_db_input($string) {

  return addslashes($string);

}

 


to:

 

function tep_db_input($string, $link = 'db_link') {
  global $$link;
 
  if (function_exists('mysql_real_escape_string')) {
    return mysql_real_escape_string($string, $$link);
  } elseif (function_exists('mysql_escape_string')) {
    return mysql_escape_string($string);
  }
 
  return addslashes($string);
}

Adding Non-Existing Products To Cart

http://www.oscommerce.com/community/bugs,1617

 

Problem:

 

It is possible to add non-existing products into the shopping cart which may prevent customers from removing the products from their cart.

 

Solution:

 

The following functions must be replaced in catalog/includes/functions/general.php.

 

Lines 912-921, from:

 

function tep_get_uprid($prid, $params) {

  $uprid = $prid;

  if ( (is_array($params)) && (!strstr($prid, '{')) ) {

    while (list($option, $value) = each($params)) {

      $uprid = $uprid . '{' . $option . '}' . $value;

    }

  }

 

  return $uprid;

}

 

to:

 

function tep_get_uprid($prid, $params) {
  if (is_numeric($prid)) {
    $uprid = $prid;
 
    if (is_array($params) && (sizeof($params) > 0)) {
      $attributes_check = true;
      $attributes_ids = '';
 
      reset($params);
      while (list($option, $value) = each($params)) {
        if (is_numeric($option) && is_numeric($value)) {
          $attributes_ids .= '{' . (int)$option . '}' . (int)$value;
        } else {
          $attributes_check = false;
          break;
        }
      }
 
      if ($attributes_check == true) {
        $uprid .= $attributes_ids;
      }
    }
  } else {
    $uprid = tep_get_prid($prid);
 
    if (is_numeric($uprid)) {
      if (strpos($prid, '{') !== false) {
        $attributes_check = true;
        $attributes_ids = '';
 
// strpos()+1 to remove up to and including the first { which would create an empty array element in explode()
        $attributes = explode('{', substr($prid, strpos($prid, '{')+1));
 
        for ($i=0, $n=sizeof($attributes); $i<$n; $i++) {
          $pair = explode('}', $attributes[$i]);
 
          if (is_numeric($pair[0]) && is_numeric($pair[1])) {
            $attributes_ids .= '{' . (int)$pair[0] . '}' . (int)$pair[1];
          } else {
            $attributes_check = false;
            break;
          }
        }
 
        if ($attributes_check == true) {
          $uprid .= $attributes_ids;
        }
      }
    } else {
      return false;
    }
  }
 
  return $uprid;
}
 

Lines 925-929, from:

 

function tep_get_prid($uprid) {

  $pieces = explode('{', $uprid);

 

  return $pieces[0];

}

 

to:

 
function tep_get_prid($uprid) {
  $pieces = explode('{', $uprid);
 
  if (is_numeric($pieces[0])) {
    return $pieces[0];
  } else {
    return false;
  }
}
 

The following functions must be replaced in catalog/includes/classes/shopping_cart.php.

 

Lines 78-108, from:

 

function add_cart($products_id, $qty = '1', $attributes = '', $notify = true) {

  global $new_products_id_in_cart, $customer_id;

 

  $products_id = tep_get_uprid($products_id, $attributes);

  if ($notify == true) {

    $new_products_id_in_cart = $products_id;

    tep_session_register('new_products_id_in_cart');

  }

 

  if ($this->in_cart($products_id)) {

    $this->update_quantity($products_id, $qty, $attributes);

  } else {

    $this->contents[] = array($products_id);

    $this->contents[$products_id] = array('qty' => $qty);

// insert into database

    if (tep_session_is_registered('customer_id')) tep_db_query("insert into " . TABLE_CUSTOMERS_BASKET . " (customers_id, products_id, customers_basket_quantity, customers_basket_date_added) values ('" . (int)$customer_id . "', '" . tep_db_input($products_id) . "', '" . $qty . "', '" . date('Ymd') . "')");

 

    if (is_array($attributes)) {

      reset($attributes);

      while (list($option, $value) = each($attributes)) {

        $this->contents[$products_id]['attributes'][$option] = $value;

// insert into database

        if (tep_session_is_registered('customer_id')) tep_db_query("insert into " . TABLE_CUSTOMERS_BASKET_ATTRIBUTES . " (customers_id, products_id, products_options_id, products_options_value_id) values ('" . (int)$customer_id . "', '" . tep_db_input($products_id) . "', '" . (int)$option . "', '" . (int)$value . "')");

      }

    }

  }

  $this->cleanup();

 

// assign a temporary unique ID to the order contents to prevent hack attempts during the checkout procedure

  $this->cartID = $this->generate_cart_id();

}


to:

 

function add_cart($products_id, $qty = '1', $attributes = '', $notify = true) {
  global $new_products_id_in_cart, $customer_id;
 
  $products_id_string = tep_get_uprid($products_id, $attributes);
  $products_id = tep_get_prid($products_id_string);
 
  if (is_numeric($products_id) && is_numeric($qty)) {
    $check_product_query = tep_db_query("select products_status from " . TABLE_PRODUCTS . " where products_id = '" . (int)$products_id . "'");
    $check_product = tep_db_fetch_array($check_product_query);
 
    if (($check_product !== false) && ($check_product['products_status'] == '1')) {
      if ($notify == true) {
        $new_products_id_in_cart = $products_id;
        tep_session_register('new_products_id_in_cart');
      }
 
      if ($this->in_cart($products_id_string)) {
        $this->update_quantity($products_id_string, $qty, $attributes);
      } else {
        $this->contents[$products_id_string] = array('qty' => $qty);
// insert into database
        if (tep_session_is_registered('customer_id')) tep_db_query("insert into " . TABLE_CUSTOMERS_BASKET . " (customers_id, products_id, customers_basket_quantity, customers_basket_date_added) values ('" . (int)$customer_id . "', '" . tep_db_input($products_id_string) . "', '" . (int)$qty . "', '" . date('Ymd') . "')");
 
        if (is_array($attributes)) {
          reset($attributes);
          while (list($option, $value) = each($attributes)) {
            $this->contents[$products_id_string]['attributes'][$option] = $value;
// insert into database
            if (tep_session_is_registered('customer_id')) tep_db_query("insert into " . TABLE_CUSTOMERS_BASKET_ATTRIBUTES . " (customers_id, products_id, products_options_id, products_options_value_id) values ('" . (int)$customer_id . "', '" . tep_db_input($products_id_string) . "', '" . (int)$option . "', '" . (int)$value . "')");
          }
        }
      }
 
      $this->cleanup();
 
// assign a temporary unique ID to the order contents to prevent hack attempts during the checkout procedure
      $this->cartID = $this->generate_cart_id();
    }
  }
}

Lines 110-127, from:

 

function update_quantity($products_id, $quantity = '', $attributes = '') {

  global $customer_id;

 

  if (empty($quantity)) return true; // nothing needs to be updated if theres no quantity, so we return true..

 

  $this->contents[$products_id] = array('qty' => $quantity);

// update database

  if (tep_session_is_registered('customer_id')) tep_db_query("update " . TABLE_CUSTOMERS_BASKET . " set customers_basket_quantity = '" . $quantity . "' where customers_id = '" . (int)$customer_id . "' and products_id = '" . tep_db_input($products_id) . "'");

 

  if (is_array($attributes)) {

    reset($attributes);

    while (list($option, $value) = each($attributes)) {

      $this->contents[$products_id]['attributes'][$option] = $value;

// update database

      if (tep_session_is_registered('customer_id')) tep_db_query("update " . TABLE_CUSTOMERS_BASKET_ATTRIBUTES . " set products_options_value_id = '" . (int)$value . "' where customers_id = '" . (int)$customer_id . "' and products_id = '" . tep_db_input($products_id) . "' and products_options_id = '" . (int)$option . "'");

    }

  }

}

 

to:

 

function update_quantity($products_id, $quantity = '', $attributes = '') {
  global $customer_id;
 
  $products_id_string = tep_get_uprid($products_id, $attributes);
  $products_id = tep_get_prid($products_id_string);
 
  if (is_numeric($products_id) && isset($this->contents[$products_id_string]) && is_numeric($quantity)) {
    $this->contents[$products_id_string] = array('qty' => $quantity);
// update database
    if (tep_session_is_registered('customer_id')) tep_db_query("update " . TABLE_CUSTOMERS_BASKET . " set customers_basket_quantity = '" . (int)$quantity . "' where customers_id = '" . (int)$customer_id . "' and products_id = '" . tep_db_input($products_id_string) . "'");
 
    if (is_array($attributes)) {
      reset($attributes);
      while (list($option, $value) = each($attributes)) {
        $this->contents[$products_id_string]['attributes'][$option] = $value;
// update database
        if (tep_session_is_registered('customer_id')) tep_db_query("update " . TABLE_CUSTOMERS_BASKET_ATTRIBUTES . " set products_options_value_id = '" . (int)$value . "' where customers_id = '" . (int)$customer_id . "' and products_id = '" . tep_db_input($products_id_string) . "' and products_options_id = '" . (int)$option . "'");
      }
    }
  }
}

Session ID XSS Issue

http://www.oscommerce.com/community/bugs,1546

 

Problem:

 

A cross site scripting issue exists with malformed session IDs being used in the tep_href_link() function.

 

Solution:

 

Line 66 in catalog/includes/functions/html_output.php must be changed from:

 

$link .= $separator . $_sid;

 

to:

 

$link .= $separator . tep_output_string($_sid);


Validate Session ID

 

Problem:

 

Validate the session ID and redirect to the front page when an invalid session ID is requested.

 

Solution:

 

The following function must be replaced in catalog/includes/functions/sessions.php.

 

Lines 66-68, from:

 

function tep_session_start() {

  return session_start();

}

 

to:

 

function tep_session_start() {

  global $HTTP_GET_VARS, $HTTP_POST_VARS, $HTTP_COOKIE_VARS;

 

  $sane_session_id = true;

 

  if (isset($HTTP_GET_VARS[tep_session_name()])) {

    if (preg_match('/^[a-zA-Z0-9]+$/', $HTTP_GET_VARS[tep_session_name()]) == false) {

      unset($HTTP_GET_VARS[tep_session_name()]);

 

      $sane_session_id = false;

    }

  } elseif (isset($HTTP_POST_VARS[tep_session_name()])) {

    if (preg_match('/^[a-zA-Z0-9]+$/', $HTTP_POST_VARS[tep_session_name()]) == false) {

      unset($HTTP_POST_VARS[tep_session_name()]);

 

      $sane_session_id = false;

    }

  } elseif (isset($HTTP_COOKIE_VARS[tep_session_name()])) {

    if (preg_match('/^[a-zA-Z0-9]+$/', $HTTP_COOKIE_VARS[tep_session_name()]) == false) {

      $session_data = session_get_cookie_params();

 

      setcookie(tep_session_name(), '', time()-42000, $session_data['path'], $session_data['domain']);

 

      $sane_session_id = false;

    }

  }

 

  if ($sane_session_id == false) {

    tep_redirect(tep_href_link(FILENAME_DEFAULT, '', 'NONSSL', false));

  }

 

  return session_start();

}


File Manager Problem

http://www.oscommerce.com/community/bugs,1391

 

Problem:

 

Parsing errors occur when saving edited files through the File Manager.

 

Solution:

 

Line 148 in catalog/admin/file_manager.php must be changed from:

 

$file_contents = htmlspecialchars(implode('', $file_array));

 

to:

 

$file_contents = addslashes(implode('', $file_array));

 

Note: This update also requires the Contact Us Form XSS Issue update in order to function correctly.


HTTP Header Injection

 

Problem:

 

By using malicious data it is possible to inject headers into HTTP requests.

Solution:

 

The following function must be replaced in catalog/includes/functions/general.php.

 

Lines 22-32, from:

 

function tep_redirect($url) {

  if ( (ENABLE_SSL == true) && (getenv('HTTPS') == 'on') ) { // We are loading an SSL page

    if (substr($url, 0, strlen(HTTP_SERVER)) == HTTP_SERVER) { // NONSSL url

      $url = HTTPS_SERVER . substr($url, strlen(HTTP_SERVER)); // Change it to SSL

    }

  }

 

  header('Location: ' . $url);

 

  tep_exit();

}

 

to:

 

function tep_redirect($url) {

  if ( (strstr($url, "\n") != false) || (strstr($url, "\r") != false) ) {

    tep_redirect(tep_href_link(FILENAME_DEFAULT, '', 'NONSSL', false));

  }

 

  if ( (ENABLE_SSL == true) && (getenv('HTTPS') == 'on') ) { // We are loading an SSL page

    if (substr($url, 0, strlen(HTTP_SERVER)) == HTTP_SERVER) { // NONSSL url

      $url = HTTPS_SERVER . substr($url, strlen(HTTP_SERVER)); // Change it to SSL

    }

  }

 

  header('Location: ' . $url);

 

  tep_exit();

}


The following function must be replaced in catalog/admin/includes/functions/general.php.

 

Lines 15-26, from:

 

function tep_redirect($url) {

  global $logger;

 

  header('Location: ' . $url);

 

  if (STORE_PAGE_PARSE_TIME == 'true') {

    if (!is_object($logger)) $logger = new logger;

    $logger->timer_stop();

  }

 

  exit;

}

 

to:

 

function tep_redirect($url) {

  global $logger;

 

  if ( (strstr($url, "\n") != false) || (strstr($url, "\r") != false) ) {

    tep_redirect(tep_href_link(FILENAME_DEFAULT, '', 'NONSSL', false));

  }

 

  header('Location: ' . $url);

 

  if (STORE_PAGE_PARSE_TIME == 'true') {

    if (!is_object($logger)) $logger = new logger;

    $logger->timer_stop();

  }

 

  exit;

}


E-Mail Header Injection

http://www.oscommerce.com/community/bugs,2488

 

Problem:

 

By using malicious data it is possible to inject headers into emails the online store sends.

 

Solution:

 

The following function must be replaced in catalog/includes/classes/email.php and catalog/admin/includes/classes/email.php.

 

Lines 473-504, from:

 

function send($to_name, $to_addr, $from_name, $from_addr, $subject = '', $headers = '') {

  $to = (($to_name != '') ? '"' . $to_name . '" <' . $to_addr . '>' : $to_addr);

  $from = (($from_name != '') ? '"' . $from_name . '" <' . $from_addr . '>' : $from_addr);

 

  if (is_string($headers)) {

    $headers = explode($this->lf, trim($headers));

  }

 

  for ($i=0; $i<count($headers); $i++) {

    if (is_array($headers[$i])) {

      for ($j=0; $j<count($headers[$i]); $j++) {

        if ($headers[$i][$j] != '') {

          $xtra_headers[] = $headers[$i][$j];

        }

      }

    }

 

    if ($headers[$i] != '') {

      $xtra_headers[] = $headers[$i];

    }

  }

 

  if (!isset($xtra_headers)) {

    $xtra_headers = array();

  }

 

  if (EMAIL_TRANSPORT == 'smtp') {

    return mail($to_addr, $subject, $this->output, 'From: ' . $from . $this->lf . 'To: ' . $to . $this->lf . implode($this->lf, $this->headers) . $this->lf . implode($this->lf, $xtra_headers));

  } else {

    return mail($to, $subject, $this->output, 'From: '.$from.$this->lf.implode($this->lf, $this->headers).$this->lf.implode($this->lf, $xtra_headers));

  }

}

 

to:

 

function send($to_name, $to_addr, $from_name, $from_addr, $subject = '', $headers = '') {
  if ((strstr($to_name, "\n") != false) || (strstr($to_name, "\r") != false)) {
    return false;
  }

  if ((strstr($to_addr, "\n") != false) || (strstr($to_addr, "\r") != false)) {
    return false;
  }

  if ((strstr($subject, "\n") != false) || (strstr($subject, "\r") != false)) {
    return false;
  }

  if ((strstr($from_name, "\n") != false) || (strstr($from_name, "\r") != false)) {
    return false;
  }

  if ((strstr($from_addr, "\n") != false) || (strstr($from_addr, "\r") != false)) {
    return false;
  }


  $to = (($to_name != '') ? '"' . $to_name . '" <' . $to_addr . '>' : $to_addr);
  $from = (($from_name != '') ? '"' . $from_name . '" <' . $from_addr . '>' : $from_addr);

  if (is_string($headers)) {
    $headers = explode($this->lf, trim($headers));
  }

  for ($i=0; $i<count($headers); $i++) {
    if (is_array($headers[$i])) {
      for ($j=0; $j<count($headers[$i]); $j++) {
        if ($headers[$i][$j] != '') {
          $xtra_headers[] = $headers[$i][$j];
        }
      }
    }

    if ($headers[$i] != '') {
      $xtra_headers[] = $headers[$i];
    }
  }

  if (!isset($xtra_headers)) {
    $xtra_headers = array();
  }

  if (EMAIL_TRANSPORT == 'smtp') {
    return mail($to_addr, $subject, $this->output, 'From: ' . $from . $this->lf . 'To: ' . $to . $this->lf . implode($this->lf, $this->headers) . $this->lf . implode($this->lf, $xtra_headers));
  } else {
    return mail($to, $subject, $this->output, 'From: '.$from.$this->lf.implode($this->lf, $this->headers).$this->lf.implode($this->lf, $xtra_headers));
  }
}


Contact Us Form XSS Issue

http://www.oscommerce.com/community/bugs,2422

 

Problem:

 

By using malicious data it is possible to inject HTML into the page.

 

Solution:

 

Lines 221-225 in catalog/includes/functions/html_output.php must be changed from:

 

if ( (isset($GLOBALS[$name])) && ($reinsert_value == true) ) {

  $field .= stripslashes($GLOBALS[$name]);

} elseif (tep_not_null($text)) {

  $field .= $text;

}

 

to:

 

if ( (isset($GLOBALS[$name])) && ($reinsert_value == true) ) {

  $field .= tep_output_string_protected(stripslashes($GLOBALS[$name]));

} elseif (tep_not_null($text)) {

  $field .= tep_output_string_protected($text);

}

 

Lines 244-248 in catalog/admin/includes/functions/html_output.php must be changed from:

 

if ( (isset($GLOBALS[$name])) && ($reinsert_value == true) ) {

  $field .= stripslashes($GLOBALS[$name]);

} elseif (tep_not_null($text)) {

  $field .= $text;

}

 

to:

 

if ( (isset($GLOBALS[$name])) && ($reinsert_value == true) ) {

  $field .= tep_output_string_protected(stripslashes($GLOBALS[$name]));

} elseif (tep_not_null($text)) {

  $field .= tep_output_string_protected($text);

}


Open Redirector

http://www.oscommerce.com/community/bugs,2970

 

Problem:

 

There is no URL checking being performed on the redirection page, and allows external sources to use the page as an open redirect relay.

 

Solution:

 

Lines 27-29 in catalog/redirect.php must be changed from:

 

if (isset($HTTP_GET_VARS['goto']) && tep_not_null($HTTP_GET_VARS['goto'])) {

  tep_redirect('http://' . $HTTP_GET_VARS['goto']);

}

 

to:

 

if (isset($HTTP_GET_VARS['goto']) && tep_not_null($HTTP_GET_VARS['goto'])) {

  $check_query = tep_db_query("select products_url from " . TABLE_PRODUCTS_DESCRIPTION . " where products_url = '" . tep_db_input($HTTP_GET_VARS['goto']) . "' limit 1");

  if (tep_db_num_rows($check_query)) {

    tep_redirect('http://' . $HTTP_GET_VARS['goto']);

  }

}


Extra Slashes In New Products

 

Problem:

 

When new products are entered and previewed, hitting the back button to edit the product data again adds extra slashes to apostrophes in the products name and description.

 

Solution:

 

Line 504 in admin/categories.php must be changed from:

 

<td class="main"><?php echo tep_image(DIR_WS_CATALOG_LANGUAGES . $languages[$i]['directory'] . '/images/' . $languages[$i]['image'], $languages[$i]['name']) . '&nbsp;' . tep_draw_input_field('products_name[' . $languages[$i]['id'] . ']', (isset($products_name[$languages[$i]['id']]) ? $products_name[$languages[$i]['id']] : tep_get_products_name($pInfo->products_id, $languages[$i]['id']))); ?></td>

 

to:

 

<td class="main"><?php echo tep_image(DIR_WS_CATALOG_LANGUAGES . $languages[$i]['directory'] . '/images/' . $languages[$i]['image'], $languages[$i]['name']) . '&nbsp;' . tep_draw_input_field('products_name[' . $languages[$i]['id'] . ']', (isset($products_name[$languages[$i]['id']]) ? stripslashes($products_name[$languages[$i]['id']]) : tep_get_products_name($pInfo->products_id, $languages[$i]['id']))); ?></td>

 

Line 538 from:

 

<td class="main"><?php echo tep_draw_textarea_field('products_description[' . $languages[$i]['id'] . ']', 'soft', '70', '15', (isset($products_description[$languages[$i]['id']]) ? $products_description[$languages[$i]['id']] : tep_get_products_description($pInfo->products_id, $languages[$i]['id']))); ?></td>

 

to:

 

<td class="main"><?php echo tep_draw_textarea_field('products_description[' . $languages[$i]['id'] . ']', 'soft', '70', '15', (isset($products_description[$languages[$i]['id']]) ? stripslashes($products_description[$languages[$i]['id']]) : tep_get_products_description($pInfo->products_id, $languages[$i]['id']))); ?></td>


Line 574 from:

 

<td class="main"><?php echo tep_image(DIR_WS_CATALOG_LANGUAGES . $languages[$i]['directory'] . '/images/' . $languages[$i]['image'], $languages[$i]['name']) . '&nbsp;' . tep_draw_input_field('products_url[' . $languages[$i]['id'] . ']', (isset($products_url[$languages[$i]['id']]) ? $products_url[$languages[$i]['id']] : tep_get_products_url($pInfo->products_id, $languages[$i]['id']))); ?></td>

 

to:

 

<td class="main"><?php echo tep_image(DIR_WS_CATALOG_LANGUAGES . $languages[$i]['directory'] . '/images/' . $languages[$i]['image'], $languages[$i]['name']) . '&nbsp;' . tep_draw_input_field('products_url[' . $languages[$i]['id'] . ']', (isset($products_url[$languages[$i]['id']]) ? stripslashes($products_url[$languages[$i]['id']]) : tep_get_products_url($pInfo->products_id, $languages[$i]['id']))); ?></td>


Order Status Filtering

http://www.oscommerce.com/community/bugs,1543

 

Problem:

 

After changing the order status filtering on the Administration Tool -> Customers -> Orders page, selecting "All Orders" would show an empty listing of orders.

 

Solution:

 

Line 357 in admin/orders.php must be changed from:

 

} elseif (isset($HTTP_GET_VARS['status'])) {

 

to:

 

} elseif (isset($HTTP_GET_VARS['status']) && is_numeric($HTTP_GET_VARS['status']) && ($HTTP_GET_VARS['status'] > 0)) {


MySQL 5.0 Compatibility

 

Problem:

 

MySQL 5.0 introduces Server SQL modes as part of its SQL 2003 standards support, and uses a more stricter approach to executing SQL queries. This is performed by default with setting STRICT_TRANS_TABLES as a Server SQL mode.

 

Due to this new setting, MySQL fails on certain SQL queries and produces error messages on the screen.

 

Solution:

 

Lines 213-223 in advanced_search_result.php must be changed from:

 

$from_str = "from " . TABLE_PRODUCTS . " p left join " . TABLE_MANUFACTURERS . " m using(manufacturers_id) left join " . TABLE_SPECIALS . " s on p.products_id = s.products_id, " . TABLE_PRODUCTS_DESCRIPTION . " pd, " . TABLE_CATEGORIES . " c, " . TABLE_PRODUCTS_TO_CATEGORIES . " p2c";

 

if ( (DISPLAY_PRICE_WITH_TAX == 'true') && (tep_not_null($pfrom) || tep_not_null($pto)) ) {

  if (!tep_session_is_registered('customer_country_id')) {

    $customer_country_id = STORE_COUNTRY;

    $customer_zone_id = STORE_ZONE;

  }

  $from_str .= " left join " . TABLE_TAX_RATES . " tr on p.products_tax_class_id = tr.tax_class_id left join " . TABLE_ZONES_TO_GEO_ZONES . " gz on tr.tax_zone_id = gz.geo_zone_id and (gz.zone_country_id is null or gz.zone_country_id = '0' or gz.zone_country_id = '" . (int)$customer_country_id . "') and (gz.zone_id is null or gz.zone_id = '0' or gz.zone_id = '" . (int)$customer_zone_id . "')";

}

 

$where_str = " where p.products_status = '1' and p.products_id = pd.products_id and pd.language_id = '" . (int)$languages_id . "' and p.products_id = p2c.products_id and p2c.categories_id = c.categories_id ";

 


to:

 

$from_str = "from " . TABLE_PRODUCTS . " p left join " . TABLE_MANUFACTURERS . " m using(manufacturers_id) left join " . TABLE_SPECIALS . " s on p.products_id = s.products_id";

 

if ( (DISPLAY_PRICE_WITH_TAX == 'true') && (tep_not_null($pfrom) || tep_not_null($pto)) ) {

  if (!tep_session_is_registered('customer_country_id')) {

    $customer_country_id = STORE_COUNTRY;

    $customer_zone_id = STORE_ZONE;

  }

  $from_str .= " left join " . TABLE_TAX_RATES . " tr on p.products_tax_class_id = tr.tax_class_id left join " . TABLE_ZONES_TO_GEO_ZONES . " gz on tr.tax_zone_id = gz.geo_zone_id and (gz.zone_country_id is null or gz.zone_country_id = '0' or gz.zone_country_id = '" . (int)$customer_country_id . "') and (gz.zone_id is null or gz.zone_id = '0' or gz.zone_id = '" . (int)$customer_zone_id . "')";

}

 

$from_str .= ", " . TABLE_PRODUCTS_DESCRIPTION . " pd, " . TABLE_CATEGORIES . " c, " . TABLE_PRODUCTS_TO_CATEGORIES . " p2c";

 

$where_str = " where p.products_status = '1' and p.products_id = pd.products_id and pd.language_id = '" . (int)$languages_id . "' and p.products_id = p2c.products_id and p2c.categories_id = c.categories_id ";

 

The following lines must be replaced in index.php:

 

Line 175, from:

 

$listing_sql = "select " . $select_column_list . " p.products_id, p.manufacturers_id, p.products_price, p.products_tax_class_id, IF(s.status, s.specials_new_products_price, NULL) as specials_new_products_price, IF(s.status, s.specials_new_products_price, p.products_price) as final_price from " . TABLE_PRODUCTS . " p, " . TABLE_PRODUCTS_DESCRIPTION . " pd, " . TABLE_MANUFACTURERS . " m, " . TABLE_PRODUCTS_TO_CATEGORIES . " p2c left join " . TABLE_SPECIALS . " s on p.products_id = s.products_id where p.products_status = '1' and p.manufacturers_id = m.manufacturers_id and m.manufacturers_id = '" . (int)$HTTP_GET_VARS['manufacturers_id'] . "' and p.products_id = p2c.products_id and pd.products_id = p2c.products_id and pd.language_id = '" . (int)$languages_id . "' and p2c.categories_id = '" . (int)$HTTP_GET_VARS['filter_id'] . "'";

 

to:

 

$listing_sql = "select " . $select_column_list . " p.products_id, p.manufacturers_id, p.products_price, p.products_tax_class_id, IF(s.status, s.specials_new_products_price, NULL) as specials_new_products_price, IF(s.status, s.specials_new_products_price, p.products_price) as final_price from " . TABLE_PRODUCTS . " p left join " . TABLE_SPECIALS . " s on p.products_id = s.products_id, " . TABLE_PRODUCTS_DESCRIPTION . " pd, " . TABLE_MANUFACTURERS . " m, " . TABLE_PRODUCTS_TO_CATEGORIES . " p2c where p.products_status = '1' and p.manufacturers_id = m.manufacturers_id and m.manufacturers_id = '" . (int)$HTTP_GET_VARS['manufacturers_id'] . "' and p.products_id = p2c.products_id and pd.products_id = p2c.products_id and pd.language_id = '" . (int)$languages_id . "' and p2c.categories_id = '" . (int)$HTTP_GET_VARS['filter_id'] . "'";

 

Line 178, from:

 

$listing_sql = "select " . $select_column_list . " p.products_id, p.manufacturers_id, p.products_price, p.products_tax_class_id, IF(s.status, s.specials_new_products_price, NULL) as specials_new_products_price, IF(s.status, s.specials_new_products_price, p.products_price) as final_price from " . TABLE_PRODUCTS . " p, " . TABLE_PRODUCTS_DESCRIPTION . " pd, " . TABLE_MANUFACTURERS . " m left join " . TABLE_SPECIALS . " s on p.products_id = s.products_id where p.products_status = '1' and pd.products_id = p.products_id and pd.language_id = '" . (int)$languages_id . "' and p.manufacturers_id = m.manufacturers_id and m.manufacturers_id = '" . (int)$HTTP_GET_VARS['manufacturers_id'] . "'";

 

to:

 

$listing_sql = "select " . $select_column_list . " p.products_id, p.manufacturers_id, p.products_price, p.products_tax_class_id, IF(s.status, s.specials_new_products_price, NULL) as specials_new_products_price, IF(s.status, s.specials_new_products_price, p.products_price) as final_price from " . TABLE_PRODUCTS . " p left join " . TABLE_SPECIALS . " s on p.products_id = s.products_id, " . TABLE_PRODUCTS_DESCRIPTION . " pd, " . TABLE_MANUFACTURERS . " m where p.products_status = '1' and pd.products_id = p.products_id and pd.language_id = '" . (int)$languages_id . "' and p.manufacturers_id = m.manufacturers_id and m.manufacturers_id = '" . (int)$HTTP_GET_VARS['manufacturers_id'] . "'";

 

Line 184, from:

 

$listing_sql = "select " . $select_column_list . " p.products_id, p.manufacturers_id, p.products_price, p.products_tax_class_id, IF(s.status, s.specials_new_products_price, NULL) as specials_new_products_price, IF(s.status, s.specials_new_products_price, p.products_price) as final_price from " . TABLE_PRODUCTS . " p, " . TABLE_PRODUCTS_DESCRIPTION . " pd, " . TABLE_MANUFACTURERS . " m, " . TABLE_PRODUCTS_TO_CATEGORIES . " p2c left join " . TABLE_SPECIALS . " s on p.products_id = s.products_id where p.products_status = '1' and p.manufacturers_id = m.manufacturers_id and m.manufacturers_id = '" . (int)$HTTP_GET_VARS['filter_id'] . "' and p.products_id = p2c.products_id and pd.products_id = p2c.products_id and pd.language_id = '" . (int)$languages_id . "' and p2c.categories_id = '" . (int)$current_category_id . "'";

 

to:

 

$listing_sql = "select " . $select_column_list . " p.products_id, p.manufacturers_id, p.products_price, p.products_tax_class_id, IF(s.status, s.specials_new_products_price, NULL) as specials_new_products_price, IF(s.status, s.specials_new_products_price, p.products_price) as final_price from " . TABLE_PRODUCTS . " p left join " . TABLE_SPECIALS . " s on p.products_id = s.products_id, " . TABLE_PRODUCTS_DESCRIPTION . " pd, " . TABLE_MANUFACTURERS . " m, " . TABLE_PRODUCTS_TO_CATEGORIES . " p2c where p.products_status = '1' and p.manufacturers_id = m.manufacturers_id and m.manufacturers_id = '" . (int)$HTTP_GET_VARS['filter_id'] . "' and p.products_id = p2c.products_id and pd.products_id = p2c.products_id and pd.language_id = '" . (int)$languages_id . "' and p2c.categories_id = '" . (int)$current_category_id . "'";

 

Line 187, from:

 

$listing_sql = "select " . $select_column_list . " p.products_id, p.manufacturers_id, p.products_price, p.products_tax_class_id, IF(s.status, s.specials_new_products_price, NULL) as specials_new_products_price, IF(s.status, s.specials_new_products_price, p.products_price) as final_price from " . TABLE_PRODUCTS_DESCRIPTION . " pd, " . TABLE_PRODUCTS . " p left join " . TABLE_MANUFACTURERS . " m on p.manufacturers_id = m.manufacturers_id, " . TABLE_PRODUCTS_TO_CATEGORIES . " p2c left join " . TABLE_SPECIALS . " s on p.products_id = s.products_id where p.products_status = '1' and p.products_id = p2c.products_id and pd.products_id = p2c.products_id and pd.language_id = '" . (int)$languages_id . "' and p2c.categories_id = '" . (int)$current_category_id . "'";

 

to:

 

$listing_sql = "select " . $select_column_list . " p.products_id, p.manufacturers_id, p.products_price, p.products_tax_class_id, IF(s.status, s.specials_new_products_price, NULL) as specials_new_products_price, IF(s.status, s.specials_new_products_price, p.products_price) as final_price from " . TABLE_PRODUCTS_DESCRIPTION . " pd, " . TABLE_PRODUCTS . " p left join " . TABLE_MANUFACTURERS . " m on p.manufacturers_id = m.manufacturers_id left join " . TABLE_SPECIALS . " s on p.products_id = s.products_id, " . TABLE_PRODUCTS_TO_CATEGORIES . " p2c where p.products_status = '1' and p.products_id = p2c.products_id and pd.products_id = p2c.products_id and pd.language_id = '" . (int)$languages_id . "' and p2c.categories_id = '" . (int)$current_category_id . "'";

 

Line 292 in admin/categories.php must be changed from:

 

tep_db_query("insert into " . TABLE_PRODUCTS . " (products_quantity, products_model,products_image, products_price, products_date_added, products_date_available, products_weight, products_status, products_tax_class_id, manufacturers_id) values ('" . tep_db_input($product['products_quantity']) . "', '" . tep_db_input($product['products_model']) . "', '" . tep_db_input($product['products_image']) . "', '" . tep_db_input($product['products_price']) . "',  now(), '" . tep_db_input($product['products_date_available']) . "', '" . tep_db_input($product['products_weight']) . "', '0', '" . (int)$product['products_tax_class_id'] . "', '" . (int)$product['manufacturers_id'] . "')");

 

to:

 

tep_db_query("insert into " . TABLE_PRODUCTS . " (products_quantity, products_model,products_image, products_price, products_date_added, products_date_available, products_weight, products_status, products_tax_class_id, manufacturers_id) values ('" . tep_db_input($product['products_quantity']) . "', '" . tep_db_input($product['products_model']) . "', '" . tep_db_input($product['products_image']) . "', '" . tep_db_input($product['products_price']) . "',  now(), " . (empty($product['products_date_available']) ? "null" : "'" . tep_db_input($product['products_date_available']) . "'") . ", '" . tep_db_input($product['products_weight']) . "', '0', '" . (int)$product['products_tax_class_id'] . "', '" . (int)$product['manufacturers_id'] . "')");

 

The following SQL queries need to be performed:

 

ALTER TABLE whos_online MODIFY COLUMN last_page_url VARCHAR(255) NOT NULL;

 

ALTER TABLE customers MODIFY COLUMN customers_default_address_id INTEGER;

 

ALTER TABLE customers_basket MODIFY COLUMN final_price DECIMAL(15,4);