Score:-1

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

ธง 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 ?

fr flag
อีเมล Drupal หลักไม่รองรับไฟล์แนบ คุณใช้โมดูลใดสำหรับอีเมล โมดูลนั้นควรเข้ารหัสชื่อไฟล์อย่างถูกต้องสำหรับคุณ แต่เห็นได้ชัดว่าไม่ใช่
Matoeil avatar
za flag
@ ไม่ระบุชื่อ ฉันได้แก้ไขคำถามของฉันแล้ว
Score:3
ธง fr

หากคุณเขียนโค้ดของคุณเองเพื่อสร้างข้อความแบบหลายส่วนในรูปแบบ MIME ก็ขึ้นอยู่กับคุณและคุณคนเดียวที่จะต้องแน่ใจว่าส่วนหัวทั้งหมดสอดคล้องกับ RFCs สำหรับ Mime Mail มี RFC จำนวนมากที่ใช้ ดังนั้น ลองพิจารณาใช้หนึ่งในโมดูลอีเมลจำนวนมากที่โฮสต์บน drupal.org ซึ่งจะทำสิ่งนี้ให้คุณ และหากสิ่งที่คุณใช้ทำงานไม่ถูกต้อง ให้เปิดปัญหาและแก้ไขปัญหานั้นให้กับทุกคน

กล่าวคือ คุณสามารถเข้ารหัส UTF-8 ชื่อไฟล์ของคุณในส่วนหัวของประเภทเนื้อหาและการจัดการเนื้อหา หากชื่อไฟล์ของคุณมีอักขระใดๆ ที่ RFC ไม่อนุญาต (โดยทั่วไปจะอนุญาตให้ใช้อักขระ ASCII บางตัวเท่านั้น และไม่เว้นวรรค) สามารถดูคำอธิบายทั้งหมดได้ที่ https://stackoverflow.com/questions/93551/how-to-encode-the-filename-parameter-of-content-disposition-header-in-http

Matoeil avatar
za flag
ใช้วิธีไหน? utf8_encode($file_name) ไม่มีผลใดๆ rawurlencode($file_name) ใช้งานได้และฉันหวังว่ามันจะใช้ได้กับทุกเบราว์เซอร์สมัยใหม่
fr flag
การเข้ารหัสที่คุณต้องการเรียกว่าการเข้ารหัส "B" หรือการเข้ารหัส "Q" ใน RFC อีกครั้ง RFC จะบอกคุณอย่างชัดเจนว่าอะไรถูกต้องที่นี่ ไม่ใช่แค่เรื่องของการแปลง ASCII เป็น UTF-8 เนื่องจากไม่อนุญาตให้ใช้สตริง UTF-8 ในส่วนหัว คุณสามารถใช้ Unicode::mimeHeaderEncode() (กำหนดให้ลบใน D10) หรือหนึ่งในคลาส Symfony ใหม่ที่อ้างถึงในเอกสาร Unicode API
Score:0
ธง za

แทนที่จะพยายามล้างชื่อไฟล์ด้วยวิธีที่ดีที่สุด ฉันพบตัวเลือกที่ปลอดภัยสำหรับกรณีของฉันแล้ว:

// ปลอดภัยกว่าที่จะออกจากบริการอีเมลโดยตั้งชื่อตามค่าเริ่มต้น แทนที่จะพยายามทำให้บริสุทธิ์
...
 foreach ($params['ไฟล์แนบ'] เป็นไฟล์ $) {
    $file_name = null;
...

ตัวเลือกอื่นที่ฉันได้ลองคือใช้วิธีนั้น:

$file_name = sanitize_file_name($file_name);

ฟังก์ชัน sanitize_file_name($file_name) { 
 // กรณีของจุดหลายจุด
  $explode_file_name =ระเบิด('.', $file_name);
  $extension =array_pop($explode_file_name);
  $file_name_without_ext=substr($file_name, 0, strrpos( $file_name, '.') );    
  // แทนที่อักขระพิเศษ
  $file_name_without_ext = preg_quote($file_name_without_ext);
  $file_name_without_ext = preg_replace('/[^a-zA-Z0-9\_]/', '_', $file_name_without_ext);
  $file_name=$file_name_without_ext '.' . $ส่วนขยาย;    
  ส่งคืน $file_name;
}

แต่ฉันพบกรณีหนึ่งที่ใช้ไม่ได้

โพสต์คำตอบ

คนส่วนใหญ่ไม่เข้าใจว่าการถามคำถามมากมายจะปลดล็อกการเรียนรู้และปรับปรุงความสัมพันธ์ระหว่างบุคคล ตัวอย่างเช่น ในการศึกษาของ Alison แม้ว่าผู้คนจะจำได้อย่างแม่นยำว่ามีคำถามกี่ข้อที่ถูกถามในการสนทนา แต่พวกเขาไม่เข้าใจความเชื่อมโยงระหว่างคำถามและความชอบ จากการศึกษาทั้ง 4 เรื่องที่ผู้เข้าร่วมมีส่วนร่วมในการสนทนาด้วยตนเองหรืออ่านบันทึกการสนทนาของผู้อื่น ผู้คนมักไม่ตระหนักว่าการถามคำถามจะมีอิทธิพลหรือมีอิทธิพลต่อระดับมิตรภาพระหว่างผู้สนทนา