Search code examples
phpvalidationemailemail-addressrfc822

How do I generate long valid email address?


What I mean:

$ php -r 'var_dump(filter_var(str_repeat("a", 64) . "@gmail.com", FILTER_VALIDATE_EMAIL));'
Command line code:1:
string(74) "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa@gmail.com"
$ php -r 'var_dump(filter_var(str_repeat("a", 65) . "@gmail.com", FILTER_VALIDATE_EMAIL));'
Command line code:1:
bool(false)

Is there a restriction on length of a mailbox name? I need an email of more than 255 characters long (for testing).

UPD Let me explain what I need this for. I'd like to ensure in my tests that user can't specify email address longer than 255 characters. That's why I need a long email address.

UPD Following Justinas suggestion:

$ php -r 'var_dump(filter_var(str_repeat("a", 64) . "@" . str_repeat("g", 63) . ".com", FILTER_VALIDATE_EMAIL));'
Command line code:1:
string(132) "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa@ggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg.com"
$ php -r 'var_dump(filter_var(str_repeat("a", 64) . "@" . str_repeat("g", 64) . ".com", FILTER_VALIDATE_EMAIL));'
Command line code:1:
bool(false)

Solution

  • To cite a little more from the link Justinas provided:

    The format of email addresses is local-part@domain where the local part may be up to 64 characters long and the domain may have a maximum of 255 characters—but the maximum of 256-character length of a forward or reverse path restricts the entire email address to be no more than 254 characters long.

    Now if we look at the filter_var's source, we'll see that there are basically two checks there:

    1. if the entire email address is longer than 320 symbols
    2. if it matches the regex (unless we specify FILTER_FLAG_EMAIL_UNICODE flag)

    The regex may be rewritten as follows:

    /^
      ### check if total length is no more than 254 symbols
      (?!
        (?:
          (?:\\x22?\\x5C[\\x00-\\x7E]\\x22?)
          |
          (?:\\x22?[^\\x5C\\x22]\\x22?)
        ){255,}
      )
      ### check if the part before @ is no more than 64 symbols
      (?!
        (?:
          (?:\\x22?\\x5C[\\x00-\\x7E]\\x22?)
          |
          (?:\\x22?[^\\x5C\\x22]\\x22?)
        ){65,}
        @
      )
      (?:
        (?:[\\x21\\x23-\\x27\\x2A\\x2B\\x2D\\x2F-\\x39\\x3D\\x3F\\x5E-\\x7E]+)
        |
        (?:\\x22(?:[\\x01-\\x08\\x0B\\x0C\\x0E-\\x1F\\x21\\x23-\\x5B\\x5D-\\x7F]|(?:\\x5C[\\x00-\\x7F]))*\\x22)
      )
      (?:
        \\.
        (?:
          (?:[\\x21\\x23-\\x27\\x2A\\x2B\\x2D\\x2F-\\x39\\x3D\\x3F\\x5E-\\x7E]+)
          |
          (?:
            \\x22
            (?:
              [\\x01-\\x08\\x0B\\x0C\\x0E-\\x1F\\x21\\x23-\\x5B\\x5D-\\x7F]
              |
              (?:\\x5C[\\x00-\\x7F])
            )*
            \\x22
          )
        )
      )*
      @
      (?:
        (?:
          ### no segment must be longer than 64 symbols
          (?!.*[^.]{64,})
          (?:
            (?:
              (?:xn--)?
              [a-z0-9]+
              (?:-+[a-z0-9]+)*
              \\.
            ){1,126}
          ){1,}
          (?:
            (?:[a-z][a-z0-9]*)
            |
            (?:(?:xn--)[a-z0-9]+)
          )
          (?:-+[a-z0-9]+)*
        )
        |
        ### ip
        (?:
          \\[
          (?:
            (?:
              IPv6:
              (?:
                (?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){7})
                |
                (?:
                  (?!(?:.*[a-f0-9][:\\]]){7,})
                  (?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,5})?
                  ::
                  (?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,5})?
                )
              )
            )
            |
            (?:
              (?:
                IPv6:
                (?:
                  (?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){5}:)
                  |
                  (?:
                    (?!(?:.*[a-f0-9]:){5,})
                    (?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,3})?
                    ::
                    (?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,3}:)?
                  )
                )
              )?
              (?:
                (?:25[0-5])
                |
                (?:2[0-4][0-9])
                |
                (?:1[0-9]{2})
                |
                (?:[1-9]?[0-9])
              )
              (?:
                \\.
                (?:
                  (?:25[0-5])
                  |
                  (?:2[0-4][0-9])
                  |
                  (?:1[0-9]{2})
                  |
                  (?:[1-9]?[0-9])
                )
              ){3}
            )
          )
          \\]
        )
      )
    $/iD
    

    Knowing that the best we can get is:

    $ php -r 'var_dump(filter_var(str_repeat("a", 64) . "@" . str_repeat(str_repeat("g", 63) . ".", 2) . str_repeat("g", 61), FILTER_VALIDATE_EMAIL));'
    Command line code:1:
    string(254) "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa@ggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg.ggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg.ggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg"
    $ php -r 'var_dump(filter_var(str_repeat("a", 64) . "@" . str_repeat(str_repeat("g", 63) . ".", 2) . str_repeat("g", 62), FILTER_VALIDATE_EMAIL));'
    Command line code:1:
    bool(false)