DoubleQuote.php 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. <?php
  2. namespace Egulias\EmailValidator\Parser;
  3. use Egulias\EmailValidator\EmailLexer;
  4. use Egulias\EmailValidator\Result\ValidEmail;
  5. use Egulias\EmailValidator\Result\InvalidEmail;
  6. use Egulias\EmailValidator\Warning\CFWSWithFWS;
  7. use Egulias\EmailValidator\Warning\QuotedString;
  8. use Egulias\EmailValidator\Result\Reason\ExpectingATEXT;
  9. use Egulias\EmailValidator\Result\Reason\UnclosedQuotedString;
  10. use Egulias\EmailValidator\Result\Result;
  11. class DoubleQuote extends PartParser
  12. {
  13. public function parse(): Result
  14. {
  15. $validQuotedString = $this->checkDQUOTE();
  16. if ($validQuotedString->isInvalid()) {
  17. return $validQuotedString;
  18. }
  19. $special = [
  20. EmailLexer::S_CR => true,
  21. EmailLexer::S_HTAB => true,
  22. EmailLexer::S_LF => true
  23. ];
  24. $invalid = [
  25. EmailLexer::C_NUL => true,
  26. EmailLexer::S_HTAB => true,
  27. EmailLexer::S_CR => true,
  28. EmailLexer::S_LF => true
  29. ];
  30. $setSpecialsWarning = true;
  31. $this->lexer->moveNext();
  32. while (!$this->lexer->current->isA(EmailLexer::S_DQUOTE) && !$this->lexer->current->isA(EmailLexer::S_EMPTY)) {
  33. if (isset($special[$this->lexer->current->type]) && $setSpecialsWarning) {
  34. $this->warnings[CFWSWithFWS::CODE] = new CFWSWithFWS();
  35. $setSpecialsWarning = false;
  36. }
  37. if ($this->lexer->current->isA(EmailLexer::S_BACKSLASH) && $this->lexer->isNextToken(EmailLexer::S_DQUOTE)) {
  38. $this->lexer->moveNext();
  39. }
  40. $this->lexer->moveNext();
  41. if (!$this->escaped() && isset($invalid[$this->lexer->current->type])) {
  42. return new InvalidEmail(new ExpectingATEXT("Expecting ATEXT between DQUOTE"), $this->lexer->current->value);
  43. }
  44. }
  45. $prev = $this->lexer->getPrevious();
  46. if ($prev->isA(EmailLexer::S_BACKSLASH)) {
  47. $validQuotedString = $this->checkDQUOTE();
  48. if ($validQuotedString->isInvalid()) {
  49. return $validQuotedString;
  50. }
  51. }
  52. if (!$this->lexer->isNextToken(EmailLexer::S_AT) && !$prev->isA(EmailLexer::S_BACKSLASH)) {
  53. return new InvalidEmail(new ExpectingATEXT("Expecting ATEXT between DQUOTE"), $this->lexer->current->value);
  54. }
  55. return new ValidEmail();
  56. }
  57. protected function checkDQUOTE(): Result
  58. {
  59. $previous = $this->lexer->getPrevious();
  60. if ($this->lexer->isNextToken(EmailLexer::GENERIC) && $previous->isA(EmailLexer::GENERIC)) {
  61. $description = 'https://tools.ietf.org/html/rfc5322#section-3.2.4 - quoted string should be a unit';
  62. return new InvalidEmail(new ExpectingATEXT($description), $this->lexer->current->value);
  63. }
  64. try {
  65. $this->lexer->find(EmailLexer::S_DQUOTE);
  66. } catch (\Exception $e) {
  67. return new InvalidEmail(new UnclosedQuotedString(), $this->lexer->current->value);
  68. }
  69. $this->warnings[QuotedString::CODE] = new QuotedString($previous->value, $this->lexer->current->value);
  70. return new ValidEmail();
  71. }
  72. }