| @@ -40,8 +40,9 @@ | ||
| 40 | 40 | var $startdate; |
| 41 | 41 | var $enddate; |
| 42 | 42 | |
| 43 | 43 | public $listOption; |
| 44 | + public $cookie_key; | |
| 44 | 45 | public $totalRow; |
| 45 | 46 | public $selectedRow; |
| 46 | 47 | public $headers; |
| 47 | 48 | |
| @@ -51,12 +52,17 @@ | ||
| 51 | 52 | * @param string $tableName Table name. |
| 52 | 53 | * @param array $arr_column Column. |
| 53 | 54 | */ |
| 54 | 55 | public function __construct( $tableName, $arr_column ) { |
| 56 | + global $wpdb; | |
| 55 | 57 | $this->table = $tableName; |
| 56 | 58 | $this->columns = $arr_column; |
| 57 | 59 | $this->rows = array(); |
| 58 | 60 | |
| 61 | + // 旧受注リストは新受注リスト(WlcOrderList)と同じ Cookie キーを共有すると, 検索条件やページング状態が | |
| 62 | + // 混在して警告や表示崩れの原因になる. 受注リストのみ専用の Cookie キーを使い, 状態を完全に分離する. | |
| 63 | + $this->cookie_key = ( $wpdb->prefix . 'usces_order' === $this->table ) ? $this->table . '_old' : $this->table; | |
| 64 | + | |
| 59 | 65 | $this->maxRow = apply_filters( 'usces_filter_orderlist_maxrow', 30 ); |
| 60 | 66 | $this->naviMaxButton = 11; |
| 61 | 67 | $this->firstPage = 1; |
| 62 | 68 | $this->action_status = 'none'; |
| @@ -272,10 +278,11 @@ | ||
| 272 | 278 | foreach ( $this->columns as $key => $value ) { |
| 273 | 279 | $this->sortSwitchs[ $value ] = 'DESC'; |
| 274 | 280 | } |
| 275 | 281 | } |
| 276 | - $this->startdate = ( isset( $_REQUEST['startdate'] ) ) ? $_REQUEST['startdate'] : ( ( isset( $this->data_cookie['startdate'] ) ) ? $this->data_cookie['startdate'] : '' ); | |
| 277 | - $this->enddate = ( isset( $_REQUEST['enddate'] ) ) ? $_REQUEST['enddate'] : ( ( isset( $this->data_cookie['enddate'] ) ) ? $this->data_cookie['enddate'] : '' ); | |
| 282 | + // startdate / enddate は画面のフォーム value や JS へ出力される. 書式外を空に落とし, 反映型 XSS を防ぐ. | |
| 283 | + $this->startdate = $this->sanitize_search_date( ( isset( $_REQUEST['startdate'] ) ) ? $_REQUEST['startdate'] : ( ( isset( $this->data_cookie['startdate'] ) ) ? $this->data_cookie['startdate'] : '' ) ); | |
| 284 | + $this->enddate = $this->sanitize_search_date( ( isset( $_REQUEST['enddate'] ) ) ? $_REQUEST['enddate'] : ( ( isset( $this->data_cookie['enddate'] ) ) ? $this->data_cookie['enddate'] : '' ) ); | |
| 278 | 285 | $this->SetTotalRow(); |
| 279 | 286 | } |
| 280 | 287 | |
| 281 | 288 | /** |
| @@ -484,8 +491,26 @@ | ||
| 484 | 491 | return str_replace( $this->placeholder_escape, '%', $query ); |
| 485 | 492 | } |
| 486 | 493 | |
| 487 | 494 | /** |
| 495 | + * 期間検索の日付をサニタイズする | |
| 496 | + * | |
| 497 | + * リクエストまたは検索条件 Cookie 由来の startdate / enddate は、 | |
| 498 | + * WHERE 句へ文字列連結される. 書式に合わない値は空文字に落とし、 | |
| 499 | + * 「日付指定なし」として扱う. | |
| 500 | + * | |
| 501 | + * @param mixed $date Date string. | |
| 502 | + * @return string | |
| 503 | + */ | |
| 504 | + private function sanitize_search_date( $date ) { | |
| 505 | + if ( ! is_scalar( $date ) ) { | |
| 506 | + return ''; | |
| 507 | + } | |
| 508 | + $date = trim( (string) $date ); | |
| 509 | + return ( preg_match( '/^\d{4}-\d{2}-\d{2}$/', $date ) ) ? $date : ''; | |
| 510 | + } | |
| 511 | + | |
| 512 | + /** | |
| 488 | 513 | * Set Total Rows. |
| 489 | 514 | */ |
| 490 | 515 | public function SetTotalRow() { |
| 491 | 516 | global $wpdb; |
| @@ -491,17 +516,17 @@ | ||
| 491 | 516 | global $wpdb; |
| 492 | 517 | $where = ''; |
| 493 | 518 | if ( $this->period_specified_index == $this->arr_search['period'] ) { |
| 494 | 519 | if ( isset( $_REQUEST['startdate'] ) ) { |
| 495 | - $startdate = $_REQUEST['startdate']; | |
| 520 | + $startdate = $this->sanitize_search_date( $_REQUEST['startdate'] ); | |
| 496 | 521 | } else { |
| 497 | - $startdate = $this->data_cookie['startdate']; | |
| 522 | + $startdate = $this->sanitize_search_date( $this->data_cookie['startdate'] ); | |
| 498 | 523 | } |
| 499 | 524 | |
| 500 | 525 | if ( isset( $_REQUEST['enddate'] ) ) { |
| 501 | - $enddate = $_REQUEST['enddate']; | |
| 526 | + $enddate = $this->sanitize_search_date( $_REQUEST['enddate'] ); | |
| 502 | 527 | } else { |
| 503 | - $enddate = $this->data_cookie['enddate']; | |
| 528 | + $enddate = $this->sanitize_search_date( $this->data_cookie['enddate'] ); | |
| 504 | 529 | } |
| 505 | 530 | if ( '' != $startdate || '' != $enddate ) { |
| 506 | 531 | if ( '' == $enddate ) { |
| 507 | 532 | $where = " WHERE order_date >= '{$startdate}'"; |
| @@ -530,17 +555,17 @@ | ||
| 530 | 555 | $str = ''; |
| 531 | 556 | $where = ''; |
| 532 | 557 | if ( $this->period_specified_index == $this->arr_search['period'] ) { |
| 533 | 558 | if ( isset( $_REQUEST['startdate'] ) ) { |
| 534 | - $startdate = $_REQUEST['startdate']; | |
| 559 | + $startdate = $this->sanitize_search_date( $_REQUEST['startdate'] ); | |
| 535 | 560 | } else { |
| 536 | - $startdate = $this->data_cookie['startdate']; | |
| 561 | + $startdate = $this->sanitize_search_date( $this->data_cookie['startdate'] ); | |
| 537 | 562 | } |
| 538 | 563 | |
| 539 | 564 | if ( isset( $_REQUEST['enddate'] ) ) { |
| 540 | - $enddate = $_REQUEST['enddate']; | |
| 565 | + $enddate = $this->sanitize_search_date( $_REQUEST['enddate'] ); | |
| 541 | 566 | } else { |
| 542 | - $enddate = $this->data_cookie['enddate']; | |
| 567 | + $enddate = $this->sanitize_search_date( $this->data_cookie['enddate'] ); | |
| 543 | 568 | } |
| 544 | 569 | if ( '' != $startdate || '' != $enddate ) { |
| 545 | 570 | if ( '' == $enddate ) { |
| 546 | 571 | $where = " WHERE order_date >= '{$startdate}'"; |
| @@ -747,9 +772,9 @@ | ||
| 747 | 772 | /** |
| 748 | 773 | * Get Cookie. |
| 749 | 774 | */ |
| 750 | 775 | public function getCookie() { |
| 751 | - $this->data_cookie = ( isset( $_COOKIE[ $this->table ] ) ) ? json_decode( str_replace( "\'", "'", str_replace( '\"', '"', $_COOKIE[ $this->table ] ) ), true ) : array(); | |
| 776 | + $this->data_cookie = ( isset( $_COOKIE[ $this->cookie_key ] ) ) ? json_decode( str_replace( "\'", "'", str_replace( '\"', '"', $_COOKIE[ $this->cookie_key ] ) ), true ) : array(); | |
| 752 | 777 | } |
| 753 | 778 | |
| 754 | 779 | /** |
| 755 | 780 | * Set Headers. |