Quick Search:

View

Revision:

Diff

Diff from 723 to:

Annotations

Annotate by Age | Author | Mixed | None
/fisheye/browse/osCommerce/oscommerce2/trunk/update-20060817.txt

Annotated File View

hpdl
711
1 osCommerce 2.2 Milestone 2 Update 060817
2 Update Package 17th August 2006
3
4 ------------------------------------------------------------------------------
5 Table of Contents
6 ------------------------------------------------------------------------------
7
8 ## Update 060817 (17th August 2006)
9
10 Magic Quotes Compatibility Layer Fix
11 Parse GET Variables In Cache Functions
12 PHP 3 Session ID XSS Issue
13 Product Attributes SQL Injection
14 Resize Images To Round Numbers
hpdl
714
15 Use The Correct Country Name Value When Formatting Addresses
hpdl
716
16 Prevent The Session ID Being Passed In Tell-A-Friend E-Mails
hpdl
718
17 Properly Remove Deleted Products That Exist In Shopping Carts
hpdl
711
18
19 ## Update 051113 (13th November 2005)
20
21 customer_country_id in addressbook
22
23 ## Update 051112 (12th November 2005)
24
25 Cannot re-assign $this
26 limit -20, 20
27 Database Input Enhancement
28 Adding Non-Existing Products To Cart
29 Session ID XSS Issue
30 Validate Session ID
31 File Manager Problem
32 HTTP Header Injection
33 E-Mail Header Injection
34 Contact Us Form XSS Issue
35 Open Redirector
36 Extra Slashes In New Products
37 Order Status Filtering
38 MySQL 5.0 Compatibility
39
40 ###########################
41 ###### Update 060817 ######
42 ###########################
43
44 ------------------------------------------------------------------------------
45 Magic Quotes Compatibility Layer Fix
46 http://www.oscommerce.com/community/bugs,1435
47 http://svn.oscommerce.com/trac/changeset/706
48 ------------------------------------------------------------------------------
49
50 Problem:
51
52 The Magic Quotes compatibility layer does not parse arrays within the GET/POST/COOKIE scope that can be used to inject SQL into database queries.
53
54 Solution:
55
56 The following lines must be replaced in catalog/includes/functions/compatibility.php:
57
58 Lines 22-23, from:
59
60 if (is_array($value)) {
61   do_magic_quotes_gpc($value);
62
63 to:
64
65 if (is_array($ar[$key])) {
66   do_magic_quotes_gpc($ar[$key]);
67
68 The following lines must be replaced in catalog/admin/includes/functions/compatibility.php:
69
70 Lines 22-23, from:
71
72 if (is_array($value)) {
73   do_magic_quotes_gpc($value);
74
75 to:
76
77 if (is_array($ar[$key])) {
78   do_magic_quotes_gpc($ar[$key]);
79
80 ------------------------------------------------------------------------------
81 Parse GET Variables In Cache Functions
82 http://svn.oscommerce.com/trac/changeset/708
83 ------------------------------------------------------------------------------
84
85 Problem:
86
87 The GET variables used in caching functions are not parsed.
88
89 Solution:
90
91 The following lines must be replaced in catalog/includes/functions/cache.php:
92
93 Line 121, from:
94
95 if (isset($HTTP_GET_VARS['manufactuers_id']) && tep_not_null($HTTP_GET_VARS['manufacturers_id'])) {
96
97 to:
98
99 if (isset($HTTP_GET_VARS['manufactuers_id']) && is_numeric($HTTP_GET_VARS['manufacturers_id'])) {
100
101 Lines 142-148, from:
102
103 if (($refresh == true) || !read_cache($cache_output, 'also_purchased-' . $language . '.cache' . $HTTP_GET_VARS['products_id'], $auto_expire)) {
104   ob_start();
105   include(DIR_WS_MODULES . FILENAME_ALSO_PURCHASED_PRODUCTS);
106   $cache_output = ob_get_contents();
107   ob_end_clean();
108   write_cache($cache_output, 'also_purchased-' . $language . '.cache' . $HTTP_GET_VARS['products_id']);
109 }
110
111 to:
112
113 $cache_output = '';
114
115 if (isset($HTTP_GET_VARS['products_id']) && is_numeric($HTTP_GET_VARS['products_id'])) {
116   if (($refresh == true) || !read_cache($cache_output, 'also_purchased-' . $language . '.cache' . $HTTP_GET_VARS['products_id'], $auto_expire)) {
117     ob_start();
118     include(DIR_WS_MODULES . FILENAME_ALSO_PURCHASED_PRODUCTS);
119     $cache_output = ob_get_contents();
120     ob_end_clean();
121     write_cache($cache_output, 'also_purchased-' . $language . '.cache' . $HTTP_GET_VARS['products_id']);
122   }
123 }
124
125 ------------------------------------------------------------------------------
126 PHP 3 Session ID XSS Issue
127 http://svn.oscommerce.com/trac/changeset/709
128 ------------------------------------------------------------------------------
129
130 Problem:
131
132 The session ID in the PHP 3 compatibility layer is not being parsed.
133
134 Solution:
135
136 The following lines must be added in catalog/includes/classes/sessions.php:
137
138 Line 380:
139
140 if (!empty($session->id)) {
141   if (preg_match('/^[a-zA-Z0-9]+$/', $session->id) == false) {
142     unset($session->id);
143   }
144 }
145
146 ------------------------------------------------------------------------------
147 Product Attributes SQL Injection
148 http://svn.oscommerce.com/trac/changeset/703
149 ------------------------------------------------------------------------------
150
151 Problem:
152
153 With the failure of arrays not being parsed by the magic_quotes_gpc compatibility layer, it is possible to inject SQL into database queries.
154
155 Solution:
156
157 The following lines must be replaced in catalog/includes/classes/shopping_cart.php:
158
159 Line 84, from:
160
161 if (is_numeric($products_id) && is_numeric($qty)) {
162
163 to:
164
165 $attributes_pass_check = true;
166
167 if (is_array($attributes)) {
168   reset($attributes);
169   while (list($option, $value) = each($attributes)) {
170     if (!is_numeric($option) || !is_numeric($value)) {
171       $attributes_pass_check = false;
172       break;
173     }
174   }
175 }
176
177 if (is_numeric($products_id) && is_numeric($qty) && ($attributes_pass_check == true)) {
178
179 Line 125, from:
180
181 if (is_numeric($products_id) && isset($this->contents[$products_id_string]) && is_numeric($quantity)) {
182
183 to:
184
185 $attributes_pass_check = true;
186
187 if (is_array($attributes)) {
188   reset($attributes);
189   while (list($option, $value) = each($attributes)) {
190     if (!is_numeric($option) || !is_numeric($value)) {
191       $attributes_pass_check = false;
192       break;
193     }
194   }
195 }
196
197 if (is_numeric($products_id) && isset($this->contents[$products_id_string]) && is_numeric($quantity) && ($attributes_pass_check == true)) {
198
199 The following lines must be replaced in catalog/shopping_cart.php:
200
201 Lines 84-85, from:
202
203 where pa.products_id = '" . $products[$i]['id'] . "'
204 and pa.options_id = '" . $option . "'
205
206 to:
207
208 where pa.products_id = '" . (int)$products[$i]['id'] . "'
209 and pa.options_id = '" . (int)$option . "'
210
211 Line 87, from:
212
213 and pa.options_values_id = '" . $value . "'
214
215 to:
216
217 and pa.options_values_id = '" . (int)$value . "'
218
219 Lines 89-90, from:
220
221 and popt.language_id = '" . $languages_id . "'
222 and poval.language_id = '" . $languages_id . "'");
223
224 to:
225
226 and popt.language_id = '" . (int)$languages_id . "'
227 and poval.language_id = '" . (int)$languages_id . "'");
228
229 ------------------------------------------------------------------------------
230 Resize Images To Round Numbers
231 http://www.oscommerce.com/community/bugs,1371
232 http://svn.oscommerce.com/trac/changeset/707
233 ------------------------------------------------------------------------------
234
235 Problem:
236
237 The image resizing logic may result in decimal numbers which the HTML specification does not allow.
238
239 Solution:
240
241 The following lines must be replaced in catalog/includes/functions/html_output.php:
242
243 Line 91, from:
244
245 $width = $image_size[0] * $ratio;
246
247 to:
248
249 $width = intval($image_size[0] * $ratio);
250
251 Line 94, from:
252
253 $height = $image_size[1] * $ratio;
254
255 to:
256
257 $height = intval($image_size[1] * $ratio);
258
hpdl
714
259 ------------------------------------------------------------------------------
260 Use The Correct Country Name Value When Formatting Addresses
261 http://www.oscommerce.com/community/bugs,1291
262 http://svn.oscommerce.com/trac/changeset/713
263 ------------------------------------------------------------------------------
264
265 Problem:
266
267 Depending on the values passed to tep_address_format(), an array value could be used as the country name instead of a string value.
268
269 Solution:
270
271 The following line must be replaced in catalog/includes/functions/general.php:
272
273 Line 453, from:
274
275 $country = tep_output_string_protected($address['country']);
276
277 to:
278
279 $country = tep_output_string_protected($address['country']['title']);
280
281 The following line must be removed:
282
283 Line 483:
284
285 if ($country == '') $country = tep_output_string_protected($address['country']);
286
hpdl
716
287 ------------------------------------------------------------------------------
288 Prevent The Session ID Being Passed In Tell-A-Friend E-Mails
289 http://www.oscommerce.com/community/bugs,3986
290 http://svn.oscommerce.com/trac/changeset/715
291 ------------------------------------------------------------------------------
292
293 Problem:
294
295 If the customer has cookies disabled their session ID may exist in the store URL used in tell-a-friend emails.
296
297 Solution:
298
299 The following line must be replaced in catalog/tell_a_friend.php:
300
301 Line 77, from:
302
303 $email_body .= sprintf(TEXT_EMAIL_LINK, tep_href_link(FILENAME_PRODUCT_INFO, 'products_id=' . $HTTP_GET_VARS['products_id'])) . "\n\n" .
304
305 to:
306
307 $email_body .= sprintf(TEXT_EMAIL_LINK, tep_href_link(FILENAME_PRODUCT_INFO, 'products_id=' . $HTTP_GET_VARS['products_id'], 'NONSSL', false)) . "\n\n" .
308
hpdl
718
309 ------------------------------------------------------------------------------
310 Properly Remove Deleted Products That Exist In Shopping Carts
311 http://www.oscommerce.com/community/bugs,3193
312 http://svn.oscommerce.com/trac/changeset/717
313 ------------------------------------------------------------------------------
314
315 Problem:
316
317 Deleting products via the Administration Tool would not successfully remove the product from customers shopping carts if the product had attributes.
318
319 Solution:
320
321 The following lines must be replaced in catalog/admin/includes/functions/general.php:
322
323 Lines 900-901, from:
324
325 tep_db_query("delete from " . TABLE_CUSTOMERS_BASKET . " where products_id = '" . (int)$product_id . "'");
326 tep_db_query("delete from " . TABLE_CUSTOMERS_BASKET_ATTRIBUTES . " where products_id = '" . (int)$product_id . "'");
327
328 to:
329
hpdl
723
330 tep_db_query("delete from " . TABLE_CUSTOMERS_BASKET . " where products_id = '" . (int)$product_id . "' or products_id like '" . (int)$product_id . "{%'");
331 tep_db_query("delete from " . TABLE_CUSTOMERS_BASKET_ATTRIBUTES . " where products_id = '" . (int)$product_id . "' or products_id like '" . (int)$product_id . "{%'");
hpdl
718
332
hpdl
711
333 ###########################
334 ###### Update 051113 ######
335 ###########################
336
337 ------------------------------------------------------------------------------
338 customer_country_id in addressbook
339 http://www.oscommerce.com/community/bugs,1662
340 ------------------------------------------------------------------------------
341
342 Problem:
343
344 When the customer updates their address in the My Account page, their country value is being stored in an incorrect variable that can cause an incorrect tax rate value being used in product prices.
345
346 Solution:
347
348 The following lines must be replaced in catalog/address_book_process.php:
349
350 Line 150, from:
351
352 $customer_country_id = $country_id;
353
354 to:
355
356 $customer_country_id = $country;
357
358 Line 171, from:
359
360 $customer_country_id = $country_id;
361
362 to:
363
364 $customer_country_id = $country;
365
366 ###########################
367 ###### Update 051112 ######
368 ###########################
369
370 ------------------------------------------------------------------------------
371 Cannot re-assign $this
372 http://www.oscommerce.com/community/bugs,1650
373 ------------------------------------------------------------------------------
374
375 Problem:
376
377 Fatal error: Cannot re-assign $this in /path/to/catalog/admin/includes/classes/upload.php on line 31
378
379 Solution:
380
381 Lines 27-34 in catalog/admin/includes/classes/upload.php must be changed from:
382
383 if ( ($this->parse() == true) && ($this->save() == true) ) {
384   return true;
385 } else {
386 // self destruct
387   $this = null;
388
389   return false;
390 }
391
392 to:
393
394 if ( ($this->parse() == true) && ($this->save() == true) ) {
395   return true;
396 } else {
397   return false;
398 }
399
400 ------------------------------------------------------------------------------
401 limit -20, 20
402 http://www.oscommerce.com/community/bugs,1605
403 ------------------------------------------------------------------------------
404
405 Problem:
406
407 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
408
409 Solution:
410
411 Line 67 in catalog/includes/classes/split_page_results.php must be changed from:
412
413 $this->sql_query .= " limit " . $offset . ", " . $this->number_of_rows_per_page;
414
415 to:
416
417 $this->sql_query .= " limit " . max($offset, 0) . ", " . $this->number_of_rows_per_page;
418
419 Line 38 in catalog/admin/includes/classes/split_page_results.php must be changed from:
420
421 $sql_query .= " limit " . $offset . ", " . $max_rows_per_page;
422
423 to:
424
425 $sql_query .= " limit " . max($offset, 0) . ", " . $max_rows_per_page;
426
427 ------------------------------------------------------------------------------
428 Database Input Enhancement
429 ------------------------------------------------------------------------------
430
431 Problem:
432
433 Native MySQL functions should be used in preference to the addslashes() function, to properly protect the SQL queries being executed on the database server.
434
435 Solution:
436
437 The following function must be replaced in catalog/includes/functions/database.php.
438
439 Lines 126-128, from:
440
441 function tep_db_input($string) {
442   return addslashes($string);
443 }
444
445 to:
446
447 function tep_db_input($string, $link = 'db_link') {
448   global $$link;
449
450   if (function_exists('mysql_real_escape_string')) {
451     return mysql_real_escape_string($string, $$link);
452   } elseif (function_exists('mysql_escape_string')) {
453     return mysql_escape_string($string);
454   }
455
456   return addslashes($string);
457 }
458
459 The following function must be replaced in catalog/admin/includes/functions/database.php.
460
461 Lines 130-132, from:
462
463 function tep_db_input($string) {
464   return addslashes($string);
465 }
466
467 to:
468
469 function tep_db_input($string, $link = 'db_link') {
470   global $$link;
471
472   if (function_exists('mysql_real_escape_string')) {
473     return mysql_real_escape_string($string, $$link);
474   } elseif (function_exists('mysql_escape_string')) {
475     return mysql_escape_string($string);
476   }
477
478   return addslashes($string);
479 }
480
481 ------------------------------------------------------------------------------
482 Adding Non-Existing Products To Cart
483 http://www.oscommerce.com/community/bugs,1617
484 ------------------------------------------------------------------------------
485
486 Problem:
487
488 It is possible to add non-existing products into the shopping cart which may prevent customers from removing the products from their cart.
489
490 Solution:
491
492 The following functions must be replaced in catalog/includes/functions/general.php.
493
494 Lines 912-921, from:
495
496 function tep_get_uprid($prid, $params) {
497   $uprid = $prid;
498   if ( (is_array($params)) && (!strstr($prid, '{')) ) {
499     while (list($option, $value) = each($params)) {
500       $uprid = $uprid . '{' . $option . '}' . $value;
501     }
502   }
503
504   return $uprid;
505 }
506
507 to:
508
509 function tep_get_uprid($prid, $params) {
510   if (is_numeric($prid)) {
511     $uprid = $prid;
512
513     if (is_array($params) && (sizeof($params) > 0)) {
514       $attributes_check = true;
515       $attributes_ids = '';
516
517       reset($params);
518       while (list($option, $value) = each($params)) {
519         if (is_numeric($option) && is_numeric($value)) {
520           $attributes_ids .= '{' . (int)$option . '}' . (int)$value;
521         } else {
522           $attributes_check = false;
523           break;
524         }
525       }
526
527       if ($attributes_check == true) {
528         $uprid .= $attributes_ids;
529       }
530     }
531   } else {
532     $uprid = tep_get_prid($prid);
533
534     if (is_numeric($uprid)) {
535       if (strpos($prid, '{') !== false) {
536         $attributes_check = true;
537         $attributes_ids = '';
538
539 // strpos()+1 to remove up to and including the first { which would create an empty array element in explode()
540         $attributes = explode('{', substr($prid, strpos($prid, '{')+1));
541
542         for ($i=0, $n=sizeof($attributes); $i<$n; $i++) {
543           $pair = explode('}', $attributes[$i]);
544
545           if (is_numeric($pair[0]) && is_numeric($pair[1])) {
546             $attributes_ids .= '{' . (int)$pair[0] . '}' . (int)$pair[1];
547           } else {
548             $attributes_check = false;
549             break;
550           }
551         }
552
553         if ($attributes_check == true) {
554           $uprid .= $attributes_ids;
555         }
556       }
557     } else {
558       return false;
559     }
560   }
561
562   return $uprid;
563 }
564
565 Lines 925-929, from:
566
567 function tep_get_prid($uprid) {
568   $pieces = explode('{', $uprid);
569
570   return $pieces[0];
571 }
572
573 to:
574
575 function tep_get_prid($uprid) {
576   $pieces = explode('{', $uprid);
577
578   if (is_numeric($pieces[0])) {
579     return $pieces[0];
580   } else {
581     return false;
582   }
583 }
584
585 The following functions must be replaced in catalog/includes/classes/shopping_cart.php.
586
587 Lines 78-108, from:
588
589 function add_cart($products_id, $qty = '1', $attributes = '', $notify = true) {
590   global $new_products_id_in_cart, $customer_id;
591
592   $products_id = tep_get_uprid($products_id, $attributes);
593   if ($notify == true) {
594     $new_products_id_in_cart = $products_id;
595     tep_session_register('new_products_id_in_cart');
596   }
597
598   if ($this->in_cart($products_id)) {
599     $this->update_quantity($products_id, $qty, $attributes);
600   } else {
601     $this->contents[] = array($products_id);
602     $this->contents[$products_id] = array('qty' => $qty);
603 // insert into database
604     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') . "')");
605
606     if (is_array($attributes)) {
607       reset($attributes);
608       while (list($option, $value) = each($attributes)) {
609         $this->contents[$products_id]['attributes'][$option] = $value;
610 // insert into database
611         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 . "')");
612       }
613     }
614   }
615   $this->cleanup();
616
617 // assign a temporary unique ID to the order contents to prevent hack attempts during the checkout procedure
618   $this->cartID = $this->generate_cart_id();
619 }
620
621 to:
622
623 function add_cart($products_id, $qty = '1', $attributes = '', $notify = true) {
624   global $new_products_id_in_cart, $customer_id;
625
626   $products_id_string = tep_get_uprid($products_id, $attributes);
627   $products_id = tep_get_prid($products_id_string);
628
629   if (is_numeric($products_id) && is_numeric($qty)) {
630     $check_product_query = tep_db_query("select products_status from " . TABLE_PRODUCTS . " where products_id = '" . (int)$products_id . "'");
631     $check_product = tep_db_fetch_array($check_product_query);
632
633     if (($check_product !== false) && ($check_product['products_status'] == '1')) {
634       if ($notify == true) {
635         $new_products_id_in_cart = $products_id;
636         tep_session_register('new_products_id_in_cart');
637       }
638
639       if ($this->in_cart($products_id_string)) {
640         $this->update_quantity($products_id_string, $qty, $attributes);
641       } else {
642         $this->contents[$products_id_string] = array('qty' => $qty);
643 // insert into database
644         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') . "')");
645
646         if (is_array($attributes)) {
647           reset($attributes);
648           while (list($option, $value) = each($attributes)) {
649             $this->contents[$products_id_string]['attributes'][$option] = $value;
650 // insert into database
651             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 . "')");
652           }
653         }
654       }
655
656       $this->cleanup();
657
658 // assign a temporary unique ID to the order contents to prevent hack attempts during the checkout procedure
659       $this->cartID = $this->generate_cart_id();
660     }
661   }
662 }
663
664 Lines 110-127, from:
665
666 function update_quantity($products_id, $quantity = '', $attributes = '') {
667   global $customer_id;
668
669   if (empty($quantity)) return true; // nothing needs to be updated if theres no quantity, so we return true..
670
671   $this->contents[$products_id] = array('qty' => $quantity);
672 // update database
673   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) . "'");
674
675   if (is_array($attributes)) {
676     reset($attributes);
677     while (list($option, $value) = each($attributes)) {
678       $this->contents[$products_id]['attributes'][$option] = $value;
679 // update database
680       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 . "'");
681     }
682   }
683 }
684
685 to:
686
687 function update_quantity($products_id, $quantity = '', $attributes = '') {
688   global $customer_id;
689
690   $products_id_string = tep_get_uprid($products_id, $attributes);
691   $products_id = tep_get_prid($products_id_string);
692
693   if (is_numeric($products_id) && isset($this->contents[$products_id_string]) && is_numeric($quantity)) {
694     $this->contents[$products_id_string] = array('qty' => $quantity);
695 // update database
696     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) . "'");
697
698     if (is_array($attributes)) {
699       reset($attributes);
700       while (list($option, $value) = each($attributes)) {
701         $this->contents[$products_id_string]['attributes'][$option] = $value;
702 // update database
703         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 . "'");
704       }
705     }
706   }
707 }
708
709 ------------------------------------------------------------------------------
710 Session ID XSS Issue
711 http://www.oscommerce.com/community/bugs,1546
712 ------------------------------------------------------------------------------
713
714 Problem:
715
716 A cross site scripting issue exists with malformed session IDs being used in the tep_href_link() function.
717
718 Solution:
719
720 Line 66 in catalog/includes/functions/html_output.php must be changed from:
721
722 $link .= $separator . $_sid;
723
724 to:
725
726 $link .= $separator . tep_output_string($_sid);
727
728 ------------------------------------------------------------------------------
729 Validate Session ID
730 ------------------------------------------------------------------------------
731
732 Problem:
733
734 Validate the session ID and redirect to the front page when an invalid session ID is requested.
735
736 Solution:
737
738 The following function must be replaced in catalog/includes/functions/sessions.php.
739
740 Lines 66-68, from:
741
742 function tep_session_start() {
743   return session_start();
744 }
745
746 to:
747
748 function tep_session_start() {
749   global $HTTP_GET_VARS, $HTTP_POST_VARS, $HTTP_COOKIE_VARS;
750
751   $sane_session_id = true;
752
753   if (isset($HTTP_GET_VARS[tep_session_name()])) {
754     if (preg_match('/^[a-zA-Z0-9]+$/', $HTTP_GET_VARS[tep_session_name()]) == false) {
755       unset($HTTP_GET_VARS[tep_session_name()]);
756
757       $sane_session_id = false;
758     }
759   } elseif (isset($HTTP_POST_VARS[tep_session_name()])) {
760     if (preg_match('/^[a-zA-Z0-9]+$/', $HTTP_POST_VARS[tep_session_name()]) == false) {
761       unset($HTTP_POST_VARS[tep_session_name()]);
762
763       $sane_session_id = false;
764     }
765   } elseif (isset($HTTP_COOKIE_VARS[tep_session_name()])) {
766     if (preg_match('/^[a-zA-Z0-9]+$/', $HTTP_COOKIE_VARS[tep_session_name()]) == false) {
767       $session_data = session_get_cookie_params();
768
769       setcookie(tep_session_name(), '', time()-42000, $session_data['path'], $session_data['domain']);
770
771       $sane_session_id = false;
772     }
773   }
774
775   if ($sane_session_id == false) {
776     tep_redirect(tep_href_link(FILENAME_DEFAULT, '', 'NONSSL', false));
777   }
778
779   return session_start();
780 }
781
782 ------------------------------------------------------------------------------
783 File Manager Problem
784 http://www.oscommerce.com/community/bugs,1391
785 ------------------------------------------------------------------------------
786
787 Problem:
788
789 Parsing errors occur when saving edited files through the File Manager.
790
791 Solution:
792
793 Line 148 in catalog/admin/file_manager.php must be changed from:
794
795 $file_contents = htmlspecialchars(implode('', $file_array));
796
797 to:
798
799 $file_contents = addslashes(implode('', $file_array));
800
801 Note: This update also requires the Contact Us Form XSS Issue update in order to function correctly.
802
803 ------------------------------------------------------------------------------
804 HTTP Header Injection
805 ------------------------------------------------------------------------------
806
807 Problem:
808
809 By using malicious data it is possible to inject headers into HTTP requests. 
810 Solution:
811
812 The following function must be replaced in catalog/includes/functions/general.php.
813
814 Lines 22-32, from:
815
816 function tep_redirect($url) {
817   if ( (ENABLE_SSL == true) && (getenv('HTTPS') == 'on') ) { // We are loading an SSL page
818     if (substr($url, 0, strlen(HTTP_SERVER)) == HTTP_SERVER) { // NONSSL url
819       $url = HTTPS_SERVER . substr($url, strlen(HTTP_SERVER)); // Change it to SSL
820     }
821   }
822
823   header('Location: ' . $url);
824
825   tep_exit();
826 }
827
828 to:
829
830 function tep_redirect($url) {
831   if ( (strstr($url, "\n") != false) || (strstr($url, "\r") != false) ) {
832     tep_redirect(tep_href_link(FILENAME_DEFAULT, '', 'NONSSL', false));
833   }
834
835   if ( (ENABLE_SSL == true) && (getenv('HTTPS') == 'on') ) { // We are loading an SSL page
836     if (substr($url, 0, strlen(HTTP_SERVER)) == HTTP_SERVER) { // NONSSL url
837       $url = HTTPS_SERVER . substr($url, strlen(HTTP_SERVER)); // Change it to SSL
838     }
839   }
840
841   header('Location: ' . $url);
842
843   tep_exit();
844 }
845
846 The following function must be replaced in catalog/admin/includes/functions/general.php.
847
848 Lines 15-26, from:
849
850 function tep_redirect($url) {
851   global $logger;
852
853   header('Location: ' . $url);
854
855   if (STORE_PAGE_PARSE_TIME == 'true') {
856     if (!is_object($logger)) $logger = new logger;
857     $logger->timer_stop();
858   }
859
860   exit;
861 }
862
863 to:
864
865 function tep_redirect($url) {
866   global $logger;
867
868   if ( (strstr($url, "\n") != false) || (strstr($url, "\r") != false) ) {
869     tep_redirect(tep_href_link(FILENAME_DEFAULT, '', 'NONSSL', false));
870   }
871
872   header('Location: ' . $url);
873
874   if (STORE_PAGE_PARSE_TIME == 'true') {
875     if (!is_object($logger)) $logger = new logger;
876     $logger->timer_stop();
877   }
878
879   exit;
880 }
881
882 ------------------------------------------------------------------------------
883 E-Mail Header Injection
884 http://www.oscommerce.com/community/bugs,2488
885 ------------------------------------------------------------------------------
886
887 Problem:
888
889 By using malicious data it is possible to inject headers into emails the online store sends. 
890
891 Solution:
892
893 The following function must be replaced in catalog/includes/classes/email.php and catalog/admin/includes/classes/email.php.
894
895 Lines 473-504, from:
896
897 function send($to_name, $to_addr, $from_name, $from_addr, $subject = '', $headers = '') {
898   $to = (($to_name != '') ? '"' . $to_name . '" <' . $to_addr . '>' : $to_addr);
899   $from = (($from_name != '') ? '"' . $from_name . '" <' . $from_addr . '>' : $from_addr);
900
901   if (is_string($headers)) {
902     $headers = explode($this->lf, trim($headers));
903   }
904
905   for ($i=0; $i<count($headers); $i++) {
906     if (is_array($headers[$i])) {
907       for ($j=0; $j<count($headers[$i]); $j++) {
908         if ($headers[$i][$j] != '') {
909           $xtra_headers[] = $headers[$i][$j];
910         }
911       }
912     }
913
914     if ($headers[$i] != '') {
915       $xtra_headers[] = $headers[$i];
916     }
917   }
918
919   if (!isset($xtra_headers)) {
920     $xtra_headers = array();
921   }
922
923   if (EMAIL_TRANSPORT == 'smtp') {
924     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));
925   } else {
926     return mail($to, $subject, $this->output, 'From: '.$from.$this->lf.implode($this->lf, $this->headers).$this->lf.implode($this->lf, $xtra_headers));
927   }
928 }
929
930 to:
931
932 function send($to_name, $to_addr, $from_name, $from_addr, $subject = '', $headers = '') {
933   if ((strstr($to_name, "\n") != false) || (strstr($to_name, "\r") != false)) {
934     return false;
935   }
936
937   if ((strstr($to_addr, "\n") != false) || (strstr($to_addr, "\r") != false)) {
938     return false;
939   }
940
941   if ((strstr($subject, "\n") != false) || (strstr($subject, "\r") != false)) {
942     return false;
943   }
944
945   if ((strstr($from_name, "\n") != false) || (strstr($from_name, "\r") != false)) {
946     return false;
947   }
948
949   if ((strstr($from_addr, "\n") != false) || (strstr($from_addr, "\r") != false)) {
950     return false;
951   }
952
953   $to = (($to_name != '') ? '"' . $to_name . '" <' . $to_addr . '>' : $to_addr);
954   $from = (($from_name != '') ? '"' . $from_name . '" <' . $from_addr . '>' : $from_addr);
955
956   if (is_string($headers)) {
957     $headers = explode($this->lf, trim($headers));
958   }
959
960   for ($i=0; $i<count($headers); $i++) {
961     if (is_array($headers[$i])) {
962       for ($j=0; $j<count($headers[$i]); $j++) {
963         if ($headers[$i][$j] != '') {
964           $xtra_headers[] = $headers[$i][$j];
965         }
966       }
967     }
968
969     if ($headers[$i] != '') {
970       $xtra_headers[] = $headers[$i];
971     }
972   }
973
974   if (!isset($xtra_headers)) {
975     $xtra_headers = array();
976   }
977
978   if (EMAIL_TRANSPORT == 'smtp') {
979     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));
980   } else {
981     return mail($to, $subject, $this->output, 'From: '.$from.$this->lf.implode($this->lf, $this->headers).$this->lf.implode($this->lf, $xtra_headers));
982   }
983 }
984
985 ------------------------------------------------------------------------------
986 Contact Us Form XSS Issue
987 http://www.oscommerce.com/community/bugs,2422
988 ------------------------------------------------------------------------------
989
990 Problem:
991
992 By using malicious data it is possible to inject HTML into the page. 
993
994 Solution:
995
996 Lines 221-225 in catalog/includes/functions/html_output.php must be changed from:
997
998 if ( (isset($GLOBALS[$name])) && ($reinsert_value == true) ) {
999   $field .= stripslashes($GLOBALS[$name]);
1000 } elseif (tep_not_null($text)) {
1001   $field .= $text;
1002 }
1003
1004 to:
1005
1006 if ( (isset($GLOBALS[$name])) && ($reinsert_value == true) ) {
1007   $field .= tep_output_string_protected(stripslashes($GLOBALS[$name]));
1008 } elseif (tep_not_null($text)) {
1009   $field .= tep_output_string_protected($text);
1010 }
1011
1012 Lines 244-248 in catalog/admin/includes/functions/html_output.php must be changed from:
1013
1014 if ( (isset($GLOBALS[$name])) && ($reinsert_value == true) ) {
1015   $field .= stripslashes($GLOBALS[$name]);
1016 } elseif (tep_not_null($text)) {
1017   $field .= $text;
1018 }
1019
1020 to:
1021
1022 if ( (isset($GLOBALS[$name])) && ($reinsert_value == true) ) {
1023   $field .= tep_output_string_protected(stripslashes($GLOBALS[$name]));
1024 } elseif (tep_not_null($text)) {
1025   $field .= tep_output_string_protected($text);
1026 }
1027
1028 ------------------------------------------------------------------------------
1029 Open Redirector
1030 http://www.oscommerce.com/community/bugs,2970
1031 ------------------------------------------------------------------------------
1032
1033 Problem:
1034
1035 There is no URL checking being performed on the redirection page, and allows external sources to use the page as an open redirect relay.
1036
1037 Solution:
1038
1039 Lines 27-29 in catalog/redirect.php must be changed from:
1040
1041 if (isset($HTTP_GET_VARS['goto']) && tep_not_null($HTTP_GET_VARS['goto'])) {
1042   tep_redirect('http://' . $HTTP_GET_VARS['goto']);
1043 }
1044
1045 to:
1046
1047 if (isset($HTTP_GET_VARS['goto']) && tep_not_null($HTTP_GET_VARS['goto'])) {
1048   $check_query = tep_db_query("select products_url from " . TABLE_PRODUCTS_DESCRIPTION . " where products_url = '" . tep_db_input($HTTP_GET_VARS['goto']) . "' limit 1");
1049   if (tep_db_num_rows($check_query)) {
1050     tep_redirect('http://' . $HTTP_GET_VARS['goto']);
1051   }
1052 }
1053
1054 ------------------------------------------------------------------------------
1055 Extra Slashes In New Products
1056 ------------------------------------------------------------------------------
1057
1058 Problem:
1059
1060 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.
1061
1062 Solution:
1063
1064 The following lines must be replaced in catalog/admin/categories.php:
1065
1066 Line 504, from:
1067
1068 <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>
1069
1070 to:
1071
1072 <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>
1073
1074 Line 538, from:
1075
1076 <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>
1077
1078 to:
1079
1080 <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>
1081
1082 Line 574, from:
1083
1084 <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>
1085
1086 to:
1087
1088 <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>
1089
1090 ------------------------------------------------------------------------------
1091 Order Status Filtering
1092 http://www.oscommerce.com/community/bugs,1543
1093 ------------------------------------------------------------------------------
1094
1095 Problem:
1096
1097 After changing the order status filtering on the Administration Tool -> Customers -> Orders page, selecting "All Orders" would show an empty listing of orders.
1098
1099 Solution:
1100
1101 Line 357 in catalog/admin/orders.php must be changed from:
1102
1103 } elseif (isset($HTTP_GET_VARS['status'])) {
1104
1105 to:
1106
1107 } elseif (isset($HTTP_GET_VARS['status']) && is_numeric($HTTP_GET_VARS['status']) && ($HTTP_GET_VARS['status'] > 0)) {
1108
1109 ------------------------------------------------------------------------------
1110 MySQL 5.0 Compatibility
1111 ------------------------------------------------------------------------------
1112
1113 Problem:
1114
1115 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.
1116
1117 Due to this new setting, MySQL fails on certain SQL queries and produces error messages on the screen.
1118
1119 Solution:
1120
1121 Lines 213-223 in catalog/advanced_search_result.php must be changed from:
1122
1123 $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";
1124
1125 if ( (DISPLAY_PRICE_WITH_TAX == 'true') && (tep_not_null($pfrom) || tep_not_null($pto)) ) {
1126   if (!tep_session_is_registered('customer_country_id')) {
1127     $customer_country_id = STORE_COUNTRY;
1128     $customer_zone_id = STORE_ZONE;
1129   }
1130   $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 . "')";
1131 }
1132
1133 $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 ";
1134
1135 to:
1136
1137 $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";
1138
1139 if ( (DISPLAY_PRICE_WITH_TAX == 'true') && (tep_not_null($pfrom) || tep_not_null($pto)) ) {
1140   if (!tep_session_is_registered('customer_country_id')) {
1141     $customer_country_id = STORE_COUNTRY;
1142     $customer_zone_id = STORE_ZONE;
1143   }
1144   $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 . "')";
1145 }
1146
1147 $from_str .= ", " . TABLE_PRODUCTS_DESCRIPTION . " pd, " . TABLE_CATEGORIES . " c, " . TABLE_PRODUCTS_TO_CATEGORIES . " p2c";
1148
1149 $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 ";
1150
1151 The following lines must be replaced in catalog/index.php:
1152
1153 Line 175, from:
1154
1155 $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'] . "'";
1156
1157 to:
1158
1159 $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'] . "'";
1160
1161 Line 178, from:
1162
1163 $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'] . "'";
1164
1165 to:
1166
1167 $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'] . "'";
1168
1169 Line 184, from:
1170
1171 $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 . "'";
1172
1173 to:
1174
1175 $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 . "'";
1176
1177 Line 187, from:
1178
1179 $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 . "'";
1180
1181 to:
1182
1183 $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 . "'";
1184
1185 Line 292 in catalog/admin/categories.php must be changed from:
1186
1187 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'] . "')");
1188
1189 to:
1190
1191 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'] . "')");
1192
1193 The following SQL queries need to be performed:
1194
1195 ALTER TABLE whos_online MODIFY COLUMN last_page_url VARCHAR(255) NOT NULL;
1196
1197 ALTER TABLE customers MODIFY COLUMN customers_default_address_id INTEGER;
1198
1199 ALTER TABLE customers_basket MODIFY COLUMN final_price DECIMAL(15,4);