Puncte:-1

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

drapel 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 ?

drapel fr
Atașamentele nu sunt acceptate de e-mailul principal Drupal, deci ce modul utilizați pentru e-mail? Modulul respectiv ar trebui să codifice corect numele fișierelor pentru tine, dar se pare că nu este.
Matoeil avatar
drapel za
@anonymous mi-am editat întrebarea
Puncte:3
drapel fr

Dacă scrieți propriul cod pentru a genera un mesaj cu mai multe părți în format MIME, atunci depinde de dvs. și numai dvs. să vă asigurați că toate anteturile sunt conforme cu RFC-urile pentru Mime Mail. Există o mulțime de RFC care se aplică. Deci, luați în considerare utilizarea unuia dintre numeroasele module de e-mail găzduite pe drupal.org, care va face acest lucru pentru dvs. Și dacă cel pe care îl utilizați nu o face corect, deschideți o problemă și rezolvați-o pentru toată lumea.

Acestea fiind spuse, vă puteți codifica numele fișierului în UTF-8 în anteturile Content-Type și Content-Disposition dacă numele fișierului conține caractere nepermise de RFC-uri (în general sunt permise doar unele caractere ASCII și fără spații). O explicație completă poate fi găsită la https://stackoverflow.com/questions/93551/how-to-encode-the-filename-parameter-of-content-disposition-header-in-http

Matoeil avatar
drapel za
folosind ce metoda? utf8_encode($file_name) nu are efect. rawurlencode($file_name) funcționează și sper că funcționează pe fiecare browser modern
drapel fr
Codificarea de care aveți nevoie se numește codificare „B” sau codificare „Q” în RFC. Din nou, RFC vă spune exact ce este valabil aici. Nu este vorba doar de a converti ASCII în UTF-8, deoarece șirurile UTF-8 nu sunt permise în antet. Puteți utiliza Unicode::mimeHeaderEncode() (programat pentru a fi eliminat în D10) sau una dintre noile clase Symfony la care se face referire în documentația Unicode API.
Puncte:0
drapel za

în loc să încerc să dezinfectez numele fișierului în cel mai bun mod, am găsit o opțiune sigură pentru cazul meu:

// Mai sigur să părăsești serviciul de e-mail să dai nume implicite, mai degrabă decât să încerci să-l dezinfectezi
...
 foreach ($params['atașamente'] ca $fișier) {
    $file_name = null;
...

O altă opțiune pe care am încercat-o a fost să aplic această metodă:

$nume_fișier =dezinfectează_nume_fișier($nume_fișier);

funcția sanitize_file_name($file_name) { 
 // cazul mai multor puncte
  $explode_file_name =explode('.', $file_name);
  $extensie =array_pop($explode_file_name);
  $file_name_without_ext=substr($file_name, 0, strrpos( $file_name, '.') );    
  // înlocuiește caracterele speciale
  $nume_fișier_fără_ext = preg_quote($nume_fișier_fără_ext);
  $file_name_without_ext = preg_replace('/[^a-zA-Z0-9\_]/', '_', $file_name_without_ext);
  $file_name=$file_name_without_ext . '.' . $extensie;    
  returnează $file_name;
}

dar am găsit un caz în care nu funcționează

Postează un răspuns

Majoritatea oamenilor nu înțeleg că a pune multe întrebări deblochează învățarea și îmbunătățește legătura interpersonală. În studiile lui Alison, de exemplu, deși oamenii își puteau aminti cu exactitate câte întrebări au fost puse în conversațiile lor, ei nu au intuit legătura dintre întrebări și apreciere. În patru studii, în care participanții au fost implicați în conversații ei înșiși sau au citit transcrieri ale conversațiilor altora, oamenii au avut tendința să nu realizeze că întrebarea ar influența – sau ar fi influențat – nivelul de prietenie dintre conversatori.