Quick Search:

View

Revision:

Diff

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