Điểm:-1

How do I sanitize the uploaded files name for sending safely as email attachments?

lá cờ za

I have create a form that upload a file. This file is send as email attachment

 ..
     $form['cv'] = [
          '#type' => 'managed_file',
          '#title' => 'Votre CV',
          '#required' => true,
          '#upload_validators' => [
            'file_validate_extensions' => ['pdf doc docx odt odf'],
            'file_validate_size' => 4000,
          ],
        ];
..

on form submit

..
    $cv_id = $form_state->getValue('cv')[0];
    $cv_entity = File::load($cv_id);
    $attachments = [
      $cv_entity,       
    ];
    ..
    $result = $this->mailManager->mail($module, $key, $to, $language_code, $params, $reply, $send);
    if ($result['result'] == true) {
      $this->messenger()
        ->addMessage('Your application has been sent.');
..



 function hook_mail($key, &$message, $params) {
       $options = [
    'langcode' => $message['langcode'],
  ];

  switch ($key) {
    // Send a simple message from the contact form.
    case 'beetween_postulate':
      $from = \Drupal::config('system.site')->get('name');
      $message['subject'] = t('E-mail envoyé depuis le site @site-name', ['@site-name' => $from], $options);
      // Note that the message body is an array, not a string.
      $params = $message['params'];
      $mime_id = md5(uniqid(time() . rand(), 1));
      $headers = &$message['headers'];
      $message_content_type = $headers['Content-Type'];
      $headers['Content-Type'] = "multipart/mixed; boundary=\"$mime_id\"";
      $body = "This is a multi-part message in MIME format.\r\n";
      $body .= "--$mime_id\r\n";
      $body .= "Content-Type: $message_content_type \r\n\r\n";
      $body .= $params['body'] . "\r\n\r\n";
      if (!empty($params['attachments'])) {
        $fs_service = \Drupal::service('file_system');
        $fmtg_service = \Drupal::service('file.mime_type.guesser');
        foreach ($params['attachments'] as $file) {
          // Here we add the attachment to the message body.
          $file_name = $fs_service->basename($file);
          $mime_type = $fmtg_service->guess($file);
          $file_content = file_get_contents($file);
          $base64 = chunk_split(base64_encode($file_content));
          $body .= "--$mime_id\r\n";
          $body .= "Content-Transfer-Encoding: base64\r\n";
          $body .= "Content-Type: $mime_type;
 name=$file_name\r\n";
          $body .= "Content-Disposition: attachment;
 filename=$file_name\r\n\r\n";
          $body .= $base64 . "\r\n\r\n";
        }
      }
      $body .= '--' . $mime_id . '--';
      $message['body'] = [$body];

      break;
  }
}

it does work for most case but it does not work for some file names , although the

mailManager->mail

returns true, the email is not sent

for examples:

AMU - Réglement INDEED pour diffusion des offres d'emplois AMU.pdf

CV.dupond.pdf

How can i convert these files names to a correct format / or return a validator error on upload ?

Is this not a bug of the mail->manager method to return true in that case ?

lá cờ fr
Tệp đính kèm không được hỗ trợ bởi email Drupal cốt lõi, vậy bạn đang sử dụng mô-đun nào cho thư? Mô-đun đó sẽ mã hóa đúng tên tệp cho bạn, nhưng có vẻ như không phải vậy.
Matoeil avatar
lá cờ za
@anonymous tôi đã chỉnh sửa câu hỏi của mình
Điểm:3
lá cờ fr

Nếu bạn viết mã của riêng mình để tạo một thông báo nhiều phần ở định dạng MIME, thì bạn và một mình bạn phải đảm bảo rằng tất cả các tiêu đề tuân thủ RFC cho Mime Mail. Có RẤT NHIỀU RFC được áp dụng. Vì vậy, hãy cân nhắc sử dụng một trong nhiều mô-đun email được lưu trữ trên drupal.org sẽ thực hiện việc này cho bạn. Và nếu cái bạn sử dụng không hoạt động chính xác, hãy mở một sự cố và khắc phục sự cố đó cho mọi người.

Điều đó nói rằng, bạn có thể mã hóa UTF-8 tên tệp của mình trong các tiêu đề Kiểu nội dung và Bố trí nội dung nếu tên tệp của bạn chứa bất kỳ ký tự nào mà RFC không cho phép (thường chỉ một số ký tự ASCII được phép và không có khoảng trắng). Một lời giải thích đầy đủ có thể được tìm thấy tại https://stackoverflow.com/questions/93551/how-to-encode-the-filename-parameter-of-content-disposition-header-in-http

Matoeil avatar
lá cờ za
sử dụng phương pháp nào? utf8_encode($file_name) không có hiệu lực. rawurlencode($file_name) hoạt động và tôi hy vọng nó hoạt động trên mọi trình duyệt hiện đại
lá cờ fr
Mã hóa bạn cần được gọi là mã hóa "B" hoặc mã hóa "Q" trong RFC. Một lần nữa, RFC cho bạn biết chính xác những gì hợp lệ ở đây. Nó không chỉ đơn giản là vấn đề chuyển đổi ASCII thành UTF-8, vì các chuỗi UTF-8 không được phép trong tiêu đề. Bạn có thể sử dụng Unicode::mimeHeaderEncode() (dự kiến ​​sẽ bị xóa trong D10) hoặc một trong các lớp Symfony mới được đề cập trong tài liệu API Unicode.
Điểm:0
lá cờ za

thay vì cố gắng làm sạch tên tệp theo cách tốt nhất, tôi đã tìm thấy một tùy chọn an toàn cho trường hợp của mình:

// An toàn hơn khi để dịch vụ email đặt tên mặc định thay vì cố gắng làm sạch nó
...
 foreach ($params['attachments'] as $file) {
    $file_name = null;
...

Một tùy chọn khác mà tôi đã thử là áp dụng phương pháp đó:

$file_name = vệ sinh_file_name($file_name);

function sanitize_file_name($file_name) { 
 // trường hợp có nhiều dấu chấm
  $explode_file_name =explode('.', $file_name);
  $extension =array_pop($explode_file_name);
  $file_name_without_ext=substr($file_name, 0, strrpos( $file_name, '.') );    
  // thay thế các ký tự đặc biệt
  $tên_tệp_không_có_ext = preg_quote($tên_tệp_không_có_ext);
  $file_name_without_ext = preg_replace('/[^a-zA-Z0-9\_]/', '_', $file_name_without_ext);
  $file_name=$file_name_không_ext . '.' . phần mở rộng $;    
  trả về $file_name;
}

nhưng tôi tìm thấy một trường hợp nó không hoạt động

Đăng câu trả lời

Hầu hết mọi người không hiểu rằng việc đặt nhiều câu hỏi sẽ mở ra cơ hội học hỏi và cải thiện mối quan hệ giữa các cá nhân. Ví dụ, trong các nghiên cứu của Alison, mặc dù mọi người có thể nhớ chính xác có bao nhiêu câu hỏi đã được đặt ra trong các cuộc trò chuyện của họ, nhưng họ không trực giác nhận ra mối liên hệ giữa câu hỏi và sự yêu thích. Qua bốn nghiên cứu, trong đó những người tham gia tự tham gia vào các cuộc trò chuyện hoặc đọc bản ghi lại các cuộc trò chuyện của người khác, mọi người có xu hướng không nhận ra rằng việc đặt câu hỏi sẽ ảnh hưởng—hoặc đã ảnh hưởng—mức độ thân thiện giữa những người đối thoại.