Original sentence: According to this recommendation, some implementations of decoders throw exceptions on errors.An alternative practice is to replace errors with a replacement character.Early versions of Python 3.0 would exit immediately if the command line or environment variables contained invalid UTF-8, making it impossible to handle such errors from within the program.This has the disadvantage that, under certain conditions, it could turn what would otherwise be harmless errors (producing a message such as "no such file") into a denial of service
Edited sentence: An initial reaction was to design decoders to throw exceptions on errors.Carefully crafted invalid UTF-8 could make them either skip or create ASCII characters such as NUL, slash, or quotes.Early decoders would often use the same number of bytes as the lead byte indicated as the length of the error.Early versions of Python 3.0 would exit immediately if the command line or environment variables contained invalid UTF-8, making it impossible to handle such errors.It also was difficult to parse in a reverse direction.Many of the first UTF-8 decoders would decode these, ignoring incorrect bits and accepting overlong results.Modern practice is to replace errors with a replacement character, and to ensure that systems do not interpret these replacement characters in any dangerous way.The errors can be detected later when it is convenient to report an error, or display as blocks when the string is drawn for the user.The inability to deal with UTF-8 without first confirming it was valid actually greatly impeded adoption of Unicode.This can turn what would otherwise be harmless errors (producing a message such as "no such file") into a denial of service.This had the unfortunate problem that a dropped byte would cause the error to consume some of the next character(s)