Quick Search:

View

Revision:

Diff

Diff from 477 to:

Annotations

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

Annotated File View

hpdl
477
1 osCommerce 2.2 Milestone 2 Update 051113
2 Update Package 13th November 2005
3
4 ------------------------------------------------------------------------------
5 Table of Contents
6 ------------------------------------------------------------------------------
7
8 ## Update 051113
9
10 customer_country_id in addressbook
11
12 ## Update 051112
13
14 Cannot re-assign $this
15 limit -20, 20
16 Database Input Enhancement
17 Adding Non-Existing Products To Cart
18 Session ID XSS Issue
19 Validate Session ID
20 File Manager Problem
21 HTTP Header Injection
22 E-Mail Header Injection
23 Contact Us Form XSS Issue
24 Open Redirector
25 Extra Slashes In New Products
26 Order Status Filtering
27 MySQL 5.0 Compatibility
28
29 ------------------------------------------------------------------------------
30 customer_country_id in addressbook
31 http://www.oscommerce.com/community/bugs,1662
32 ------------------------------------------------------------------------------
33
34 Problem:
35
36 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.
37
38 Solution:
39
40 The following lines must be replaced in catalog/address_book_process.php:
41
42 Line 150, from:
43
44 $customer_country_id = $country_id;
45
46 to:
47
48 $customer_country_id = $country;
49
50 Line 171, from:
51
52 $customer_country_id = $country_id;
53
54 to:
55
56 $customer_country_id = $country;
57
58 ------------------------------------------------------------------------------
59 Cannot re-assign $this
60 http://www.oscommerce.com/community/bugs,1650
61 ------------------------------------------------------------------------------
62
63 Problem:
64
65 Fatal error: Cannot re-assign $this in /path/to/catalog/admin/includes/classes/upload.php on line 31
66
67 Solution:
68
69 Lines 27-34 in catalog/admin/includes/classes/upload.php must be changed from:
70
71 if ( ($this->parse() == true) && ($this->save() == true) ) {
72   return true;
73 } else {
74 // self destruct
75   $this = null;
76
77   return false;
78 }
79
80 to:
81
82 if ( ($this->parse() == true) && ($this->save() == true) ) {
83   return true;
84 } else {
85   return false;
86 }
87
88 ------------------------------------------------------------------------------
89 limit -20, 20
90 http://www.oscommerce.com/community/bugs,1605
91 ------------------------------------------------------------------------------
92
93 Problem:
94
95 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
96
97 Solution:
98
99 Line 67 in catalog/includes/classes/split_page_results.php must be changed from:
100
101 $this->sql_query .= " limit " . $offset . ", " . $this->number_of_rows_per_page;
102
103 to:
104
105 $this->sql_query .= " limit " . max($offset, 0) . ", " . $this->number_of_rows_per_page;
106
107 Line 38 in catalog/admin/includes/classes/split_page_results.php must be changed from:
108
109 $sql_query .= " limit " . $offset . ", " . $max_rows_per_page;
110
111 to:
112
113 $sql_query .= " limit " . max($offset, 0) . ", " . $max_rows_per_page;
114
115 ------------------------------------------------------------------------------
116 Database Input Enhancement
117 ------------------------------------------------------------------------------
118
119 Problem:
120
121 Native MySQL functions should be used in preference to the addslashes() function, to properly protect the SQL queries being executed on the database server.
122
123 Solution:
124
125 The following function must be replaced in catalog/includes/functions/database.php.
126
127 Lines 126-128, from:
128
129 function tep_db_input($string) {
130   return addslashes($string);
131 }
132
133 to:
134
135 function tep_db_input($string, $link = 'db_link') {
136   global $$link;
137
138   if (function_exists('mysql_real_escape_string')) {
139     return mysql_real_escape_string($string, $$link);
140   } elseif (function_exists('mysql_escape_string')) {
141     return mysql_escape_string($string);
142   }
143
144   return addslashes($string);
145 }
146
147 The following function must be replaced in catalog/admin/includes/functions/database.php.
148
149 Lines 130-132, from:
150
151 function tep_db_input($string) {
152   return addslashes($string);
153 }
154
155 to:
156
157 function tep_db_input($string, $link = 'db_link') {
158   global $$link;
159
160   if (function_exists('mysql_real_escape_string')) {
161     return mysql_real_escape_string($string, $$link);
162   } elseif (function_exists('mysql_escape_string')) {
163     return mysql_escape_string($string);
164   }
165
166   return addslashes($string);
167 }
168
169 ------------------------------------------------------------------------------
170 Adding Non-Existing Products To Cart
171 http://www.oscommerce.com/community/bugs,1617
172 ------------------------------------------------------------------------------
173
174 Problem:
175
176 It is possible to add non-existing products into the shopping cart which may prevent customers from removing the products from their cart.
177
178 Solution:
179
180 The following functions must be replaced in catalog/includes/functions/general.php.
181
182 Lines 912-921, from:
183
184 function tep_get_uprid($prid, $params) {
185   $uprid = $prid;
186   if ( (is_array($params)) && (!strstr($prid, '{')) ) {
187     while (list($option, $value) = each($params)) {
188       $uprid = $uprid . '{' . $option . '}' . $value;
189     }
190   }
191
192   return $uprid;
193 }
194
195 to:
196
197 function tep_get_uprid($prid, $params) {
198   if (is_numeric($prid)) {
199     $uprid = $prid;
200
201     if (is_array($params) && (sizeof($params) > 0)) {
202       $attributes_check = true;
203       $attributes_ids = '';
204
205       reset($params);
206       while (list($option, $value) = each($params)) {
207         if (is_numeric($option) && is_numeric($value)) {
208           $attributes_ids .= '{' . (int)$option . '}' . (int)$value;
209         } else {
210           $attributes_check = false;
211           break;
212         }
213       }
214
215       if ($attributes_check == true) {
216         $uprid .= $attributes_ids;
217       }
218     }
219   } else {
220     $uprid = tep_get_prid($prid);
221
222     if (is_numeric($uprid)) {
223       if (strpos($prid, '{') !== false) {
224         $attributes_check = true;
225         $attributes_ids = '';
226
227 // strpos()+1 to remove up to and including the first { which would create an empty array element in explode()
228         $attributes = explode('{', substr($prid, strpos($prid, '{')+1));
229
230         for ($i=0, $n=sizeof($attributes); $i<$n; $i++) {
231           $pair = explode('}', $attributes[$i]);
232
233           if (is_numeric($pair[0]) && is_numeric($pair[1])) {
234             $attributes_ids .= '{' . (int)$pair[0] . '}' . (int)$pair[1];
235           } else {
236             $attributes_check = false;
237             break;
238           }
239         }
240
241         if ($attributes_check == true) {
242           $uprid .= $attributes_ids;
243         }
244       }
245     } else {
246       return false;
247     }
248   }
249
250   return $uprid;
251 }
252
253 Lines 925-929, from:
254
255 function tep_get_prid($uprid) {
256   $pieces = explode('{', $uprid);
257
258   return $pieces[0];
259 }
260
261 to:
262
263 function tep_get_prid($uprid) {
264   $pieces = explode('{', $uprid);
265
266   if (is_numeric($pieces[0])) {
267     return $pieces[0];
268   } else {
269     return false;
270   }
271 }
272
273 The following functions must be replaced in catalog/includes/classes/shopping_cart.php.
274
275 Lines 78-108, from:
276
277 function add_cart($products_id, $qty = '1', $attributes = '', $notify = true) {
278   global $new_products_id_in_cart, $customer_id;
279
280   $products_id = tep_get_uprid($products_id, $attributes);
281   if ($notify == true) {
282     $new_products_id_in_cart = $products_id;
283     tep_session_register('new_products_id_in_cart');
284   }
285
286   if ($this->in_cart($products_id)) {
287     $this->update_quantity($products_id, $qty, $attributes);
288   } else {
289     $this->contents[] = array($products_id);
290     $this->contents[$products_id] = array('qty' => $qty);
291 // insert into database
292     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') . "')");
293
294     if (is_array($attributes)) {
295       reset($attributes);
296       while (list($option, $value) = each($attributes)) {
297         $this->contents[$products_id]['attributes'][$option] = $value;
298 // insert into database
299         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 . "')");
300       }
301     }
302   }
303   $this->cleanup();
304
305 // assign a temporary unique ID to the order contents to prevent hack attempts during the checkout procedure
306   $this->cartID = $this->generate_cart_id();
307 }
308
309 to:
310
311 function add_cart($products_id, $qty = '1', $attributes = '', $notify = true) {
312   global $new_products_id_in_cart, $customer_id;
313
314   $products_id_string = tep_get_uprid($products_id, $attributes);
315   $products_id = tep_get_prid($products_id_string);
316
317   if (is_numeric($products_id) && is_numeric($qty)) {
318     $check_product_query = tep_db_query("select products_status from " . TABLE_PRODUCTS . " where products_id = '" . (int)$products_id . "'");
319     $check_product = tep_db_fetch_array($check_product_query);
320
321     if (($check_product !== false) && ($check_product['products_status'] == '1')) {
322       if ($notify == true) {
323         $new_products_id_in_cart = $products_id;
324         tep_session_register('new_products_id_in_cart');
325       }
326
327       if ($this->in_cart($products_id_string)) {
328         $this->update_quantity($products_id_string, $qty, $attributes);
329       } else {
330         $this->contents[$products_id_string] = array('qty' => $qty);
331 // insert into database
332         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') . "')");
333
334         if (is_array($attributes)) {
335           reset($attributes);
336           while (list($option, $value) = each($attributes)) {
337             $this->contents[$products_id_string]['attributes'][$option] = $value;
338 // insert into database
339             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 . "')");
340           }
341         }
342       }
343
344       $this->cleanup();
345
346 // assign a temporary unique ID to the order contents to prevent hack attempts during the checkout procedure
347       $this->cartID = $this->generate_cart_id();
348     }
349   }
350 }
351
352 Lines 110-127, from:
353
354 function update_quantity($products_id, $quantity = '', $attributes = '') {
355   global $customer_id;
356
357   if (empty($quantity)) return true; // nothing needs to be updated if theres no quantity, so we return true..
358
359   $this->contents[$products_id] = array('qty' => $quantity);
360 // update database
361   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) . "'");
362
363   if (is_array($attributes)) {
364     reset($attributes);
365     while (list($option, $value) = each($attributes)) {
366       $this->contents[$products_id]['attributes'][$option] = $value;
367 // update database
368       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 . "'");
369     }
370   }
371 }
372
373 to:
374
375 function update_quantity($products_id, $quantity = '', $attributes = '') {
376   global $customer_id;
377
378   $products_id_string = tep_get_uprid($products_id, $attributes);
379   $products_id = tep_get_prid($products_id_string);
380
381   if (is_numeric($products_id) && isset($this->contents[$products_id_string]) && is_numeric($quantity)) {
382     $this->contents[$products_id_string] = array('qty' => $quantity);
383 // update database
384     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) . "'");
385
386     if (is_array($attributes)) {
387       reset($attributes);
388       while (list($option, $value) = each($attributes)) {
389         $this->contents[$products_id_string]['attributes'][$option] = $value;
390 // update database
391         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 . "'");
392       }
393     }
394   }
395 }
396
397 ------------------------------------------------------------------------------
398 Session ID XSS Issue
399 http://www.oscommerce.com/community/bugs,1546
400 ------------------------------------------------------------------------------
401
402 Problem:
403
404 A cross site scripting issue exists with malformed session IDs being used in the tep_href_link() function.
405
406 Solution:
407
408 Line 66 in catalog/includes/functions/html_output.php must be changed from:
409
410 $link .= $separator . $_sid;
411
412 to:
413
414 $link .= $separator . tep_output_string($_sid);
415
416 ------------------------------------------------------------------------------
417 Validate Session ID
418 ------------------------------------------------------------------------------
419
420 Problem:
421
422 Validate the session ID and redirect to the front page when an invalid session ID is requested.
423
424 Solution:
425
426 The following function must be replaced in catalog/includes/functions/sessions.php.
427
428 Lines 66-68, from:
429
430 function tep_session_start() {
431   return session_start();
432 }
433
434 to:
435
436 function tep_session_start() {
437   global $HTTP_GET_VARS, $HTTP_POST_VARS, $HTTP_COOKIE_VARS;
438
439   $sane_session_id = true;
440
441   if (isset($HTTP_GET_VARS[tep_session_name()])) {
442     if (preg_match('/^[a-zA-Z0-9]+$/', $HTTP_GET_VARS[tep_session_name()]) == false) {
443       unset($HTTP_GET_VARS[tep_session_name()]);
444
445       $sane_session_id = false;
446     }
447   } elseif (isset($HTTP_POST_VARS[tep_session_name()])) {
448     if (preg_match('/^[a-zA-Z0-9]+$/', $HTTP_POST_VARS[tep_session_name()]) == false) {
449       unset($HTTP_POST_VARS[tep_session_name()]);
450
451       $sane_session_id = false;
452     }
453   } elseif (isset($HTTP_COOKIE_VARS[tep_session_name()])) {
454     if (preg_match('/^[a-zA-Z0-9]+$/', $HTTP_COOKIE_VARS[tep_session_name()]) == false) {
455       $session_data = session_get_cookie_params();
456
457       setcookie(tep_session_name(), '', time()-42000, $session_data['path'], $session_data['domain']);
458
459       $sane_session_id = false;
460     }
461   }
462
463   if ($sane_session_id == false) {
464     tep_redirect(tep_href_link(FILENAME_DEFAULT, '', 'NONSSL', false));
465   }
466
467   return session_start();
468 }
469
470 ------------------------------------------------------------------------------
471 File Manager Problem
472 http://www.oscommerce.com/community/bugs,1391
473 ------------------------------------------------------------------------------
474
475 Problem:
476
477 Parsing errors occur when saving edited files through the File Manager.
478
479 Solution:
480
481 Line 148 in catalog/admin/file_manager.php must be changed from:
482
483 $file_contents = htmlspecialchars(implode('', $file_array));
484
485 to:
486
487 $file_contents = addslashes(implode('', $file_array));
488
489 Note: This update also requires the Contact Us Form XSS Issue update in order to function correctly.
490
491 ------------------------------------------------------------------------------
492 HTTP Header Injection
493 ------------------------------------------------------------------------------
494
495 Problem:
496
497 By using malicious data it is possible to inject headers into HTTP requests. 
498 Solution:
499
500 The following function must be replaced in catalog/includes/functions/general.php.
501
502 Lines 22-32, from:
503
504 function tep_redirect($url) {
505   if ( (ENABLE_SSL == true) && (getenv('HTTPS') == 'on') ) { // We are loading an SSL page
506     if (substr($url, 0, strlen(HTTP_SERVER)) == HTTP_SERVER) { // NONSSL url
507       $url = HTTPS_SERVER . substr($url, strlen(HTTP_SERVER)); // Change it to SSL
508     }
509   }
510
511   header('Location: ' . $url);
512
513   tep_exit();
514 }
515
516 to:
517
518 function tep_redirect($url) {
519   if ( (strstr($url, "\n") != false) || (strstr($url, "\r") != false) ) {
520     tep_redirect(tep_href_link(FILENAME_DEFAULT, '', 'NONSSL', false));
521   }
522
523   if ( (ENABLE_SSL == true) && (getenv('HTTPS') == 'on') ) { // We are loading an SSL page
524     if (substr($url, 0, strlen(HTTP_SERVER)) == HTTP_SERVER) { // NONSSL url
525       $url = HTTPS_SERVER . substr($url, strlen(HTTP_SERVER)); // Change it to SSL
526     }
527   }
528
529   header('Location: ' . $url);
530
531   tep_exit();
532 }
533
534 The following function must be replaced in catalog/admin/includes/functions/general.php.
535
536 Lines 15-26, from:
537
538 function tep_redirect($url) {
539   global $logger;
540
541   header('Location: ' . $url);
542
543   if (STORE_PAGE_PARSE_TIME == 'true') {
544     if (!is_object($logger)) $logger = new logger;
545     $logger->timer_stop();
546   }
547
548   exit;
549 }
550
551 to:
552
553 function tep_redirect($url) {
554   global $logger;
555
556   if ( (strstr($url, "\n") != false) || (strstr($url, "\r") != false) ) {
557     tep_redirect(tep_href_link(FILENAME_DEFAULT, '', 'NONSSL', false));
558   }
559
560   header('Location: ' . $url);
561
562   if (STORE_PAGE_PARSE_TIME == 'true') {
563     if (!is_object($logger)) $logger = new logger;
564     $logger->timer_stop();
565   }
566
567   exit;
568 }
569
570 ------------------------------------------------------------------------------
571 E-Mail Header Injection
572 http://www.oscommerce.com/community/bugs,2488
573 ------------------------------------------------------------------------------
574
575 Problem:
576
577 By using malicious data it is possible to inject headers into emails the online store sends. 
578
579 Solution:
580
581 The following function must be replaced in catalog/includes/classes/email.php and catalog/admin/includes/classes/email.php.
582
583 Lines 473-504, from:
584
585 function send($to_name, $to_addr, $from_name, $from_addr, $subject = '', $headers = '') {
586   $to = (($to_name != '') ? '"' . $to_name . '" <' . $to_addr . '>' : $to_addr);
587   $from = (($from_name != '') ? '"' . $from_name . '" <' . $from_addr . '>' : $from_addr);
588
589   if (is_string($headers)) {
590     $headers = explode($this->lf, trim($headers));
591   }
592
593   for ($i=0; $i<count($headers); $i++) {
594     if (is_array($headers[$i])) {
595       for ($j=0; $j<count($headers[$i]); $j++) {
596         if ($headers[$i][$j] != '') {
597           $xtra_headers[] = $headers[$i][$j];
598         }
599       }
600     }
601
602     if ($headers[$i] != '') {
603       $xtra_headers[] = $headers[$i];
604     }
605   }
606
607   if (!isset($xtra_headers)) {
608     $xtra_headers = array();
609   }
610
611   if (EMAIL_TRANSPORT == 'smtp') {
612     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));
613   } else {
614     return mail($to, $subject, $this->output, 'From: '.$from.$this->lf.implode($this->lf, $this->headers).$this->lf.implode($this->lf, $xtra_headers));
615   }
616 }
617
618 to:
619
620 function send($to_name, $to_addr, $from_name, $from_addr, $subject = '', $headers = '') {
621   if ((strstr($to_name, "\n") != false) || (strstr($to_name, "\r") != false)) {
622     return false;
623   }
624
625   if ((strstr($to_addr, "\n") != false) || (strstr($to_addr, "\r") != false)) {
626     return false;
627   }
628
629   if ((strstr($subject, "\n") != false) || (strstr($subject, "\r") != false)) {
630     return false;
631   }
632
633   if ((strstr($from_name, "\n") != false) || (strstr($from_name, "\r") != false)) {
634     return false;
635   }
636
637   if ((strstr($from_addr, "\n") != false) || (strstr($from_addr, "\r") != false)) {
638     return false;
639   }
640
641   $to = (($to_name != '') ? '"' . $to_name . '" <' . $to_addr . '>' : $to_addr);
642   $from = (($from_name != '') ? '"' . $from_name . '" <' . $from_addr . '>' : $from_addr);
643
644   if (is_string($headers)) {
645     $headers = explode($this->lf, trim($headers));
646   }
647
648   for ($i=0; $i<count($headers); $i++) {
649     if (is_array($headers[$i])) {
650       for ($j=0; $j<count($headers[$i]); $j++) {
651         if ($headers[$i][$j] != '') {
652           $xtra_headers[] = $headers[$i][$j];
653         }
654       }
655     }
656
657     if ($headers[$i] != '') {
658       $xtra_headers[] = $headers[$i];
659     }
660   }
661
662   if (!isset($xtra_headers)) {
663     $xtra_headers = array();
664   }
665
666   if (EMAIL_TRANSPORT == 'smtp') {
667     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));
668   } else {
669     return mail($to, $subject, $this->output, 'From: '.$from.$this->lf.implode($this->lf, $this->headers).$this->lf.implode($this->lf, $xtra_headers));
670   }
671 }
672
673 ------------------------------------------------------------------------------
674 Contact Us Form XSS Issue
675 http://www.oscommerce.com/community/bugs,2422
676 ------------------------------------------------------------------------------
677
678 Problem:
679
680 By using malicious data it is possible to inject HTML into the page. 
681
682 Solution:
683
684 Lines 221-225 in catalog/includes/functions/html_output.php must be changed from:
685
686 if ( (isset($GLOBALS[$name])) && ($reinsert_value == true) ) {
687   $field .= stripslashes($GLOBALS[$name]);
688 } elseif (tep_not_null($text)) {
689   $field .= $text;
690 }
691
692 to:
693
694 if ( (isset($GLOBALS[$name])) && ($reinsert_value == true) ) {
695   $field .= tep_output_string_protected(stripslashes($GLOBALS[$name]));
696 } elseif (tep_not_null($text)) {
697   $field .= tep_output_string_protected($text);
698 }
699
700 Lines 244-248 in catalog/admin/includes/functions/html_output.php must be changed from:
701
702 if ( (isset($GLOBALS[$name])) && ($reinsert_value == true) ) {
703   $field .= stripslashes($GLOBALS[$name]);
704 } elseif (tep_not_null($text)) {
705   $field .= $text;
706 }
707
708 to:
709
710 if ( (isset($GLOBALS[$name])) && ($reinsert_value == true) ) {
711   $field .= tep_output_string_protected(stripslashes($GLOBALS[$name]));
712 } elseif (tep_not_null($text)) {
713   $field .= tep_output_string_protected($text);
714 }
715
716 ------------------------------------------------------------------------------
717 Open Redirector
718 http://www.oscommerce.com/community/bugs,2970
719 ------------------------------------------------------------------------------
720
721 Problem:
722
723 There is no URL checking being performed on the redirection page, and allows external sources to use the page as an open redirect relay.
724
725 Solution:
726
727 Lines 27-29 in catalog/redirect.php must be changed from:
728
729 if (isset($HTTP_GET_VARS['goto']) && tep_not_null($HTTP_GET_VARS['goto'])) {
730   tep_redirect('http://' . $HTTP_GET_VARS['goto']);
731 }
732
733 to:
734
735 if (isset($HTTP_GET_VARS['goto']) && tep_not_null($HTTP_GET_VARS['goto'])) {
736   $check_query = tep_db_query("select products_url from " . TABLE_PRODUCTS_DESCRIPTION . " where products_url = '" . tep_db_input($HTTP_GET_VARS['goto']) . "' limit 1");
737   if (tep_db_num_rows($check_query)) {
738     tep_redirect('http://' . $HTTP_GET_VARS['goto']);
739   }
740 }
741
742 ------------------------------------------------------------------------------
743 Extra Slashes In New Products
744 ------------------------------------------------------------------------------
745
746 Problem:
747
748 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.
749
750 Solution:
751
752 The following lines must be replaced in catalog/admin/categories.php:
753
754 Line 504, from:
755
756 <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>
757
758 to:
759
760 <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>
761
762 Line 538, from:
763
764 <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>
765
766 to:
767
768 <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>
769
770 Line 574, from:
771
772 <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>
773
774 to:
775
776 <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>
777
778 ------------------------------------------------------------------------------
779 Order Status Filtering
780 http://www.oscommerce.com/community/bugs,1543
781 ------------------------------------------------------------------------------
782
783 Problem:
784
785 After changing the order status filtering on the Administration Tool -> Customers -> Orders page, selecting "All Orders" would show an empty listing of orders.
786
787 Solution:
788
789 Line 357 in catalog/admin/orders.php must be changed from:
790
791 } elseif (isset($HTTP_GET_VARS['status'])) {
792
793 to:
794
795 } elseif (isset($HTTP_GET_VARS['status']) && is_numeric($HTTP_GET_VARS['status']) && ($HTTP_GET_VARS['status'] > 0)) {
796
797 ------------------------------------------------------------------------------
798 MySQL 5.0 Compatibility
799 ------------------------------------------------------------------------------
800
801 Problem:
802
803 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.
804
805 Due to this new setting, MySQL fails on certain SQL queries and produces error messages on the screen.
806
807 Solution:
808
809 Lines 213-223 in catalog/advanced_search_result.php must be changed from:
810
811 $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";
812
813 if ( (DISPLAY_PRICE_WITH_TAX == 'true') && (tep_not_null($pfrom) || tep_not_null($pto)) ) {
814   if (!tep_session_is_registered('customer_country_id')) {
815     $customer_country_id = STORE_COUNTRY;
816     $customer_zone_id = STORE_ZONE;
817   }
818   $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 . "')";
819 }
820
821 $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 ";
822
823 to:
824
825 $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";
826
827 if ( (DISPLAY_PRICE_WITH_TAX == 'true') && (tep_not_null($pfrom) || tep_not_null($pto)) ) {
828   if (!tep_session_is_registered('customer_country_id')) {
829     $customer_country_id = STORE_COUNTRY;
830     $customer_zone_id = STORE_ZONE;
831   }
832   $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 . "')";
833 }
834
835 $from_str .= ", " . TABLE_PRODUCTS_DESCRIPTION . " pd, " . TABLE_CATEGORIES . " c, " . TABLE_PRODUCTS_TO_CATEGORIES . " p2c";
836
837 $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 ";
838
839 The following lines must be replaced in catalog/index.php:
840
841 Line 175, from:
842
843 $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'] . "'";
844
845 to:
846
847 $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'] . "'";
848
849 Line 178, from:
850
851 $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'] . "'";
852
853 to:
854
855 $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'] . "'";
856
857 Line 184, from:
858
859 $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 . "'";
860
861 to:
862
863 $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 . "'";
864
865 Line 187, from:
866
867 $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 . "'";
868
869 to:
870
871 $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 . "'";
872
873 Line 292 in catalog/admin/categories.php must be changed from:
874
875 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'] . "')");
876
877 to:
878
879 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'] . "')");
880
881 The following SQL queries need to be performed:
882
883 ALTER TABLE whos_online MODIFY COLUMN last_page_url VARCHAR(255) NOT NULL;
884
885 ALTER TABLE customers MODIFY COLUMN customers_default_address_id INTEGER;
886
887 ALTER TABLE customers_basket MODIFY COLUMN final_price DECIMAL(15,4);