Introduce a feature in TextFileReader that checks whether a file seems to be binary rather than text.

Use this to make the MicroDVD (.sub) format reader check that it isn't being fed something that might actually be VobSub (.sub+.idx) which makes Aegisub crash.
Hopefully this doesn't break anything else.
Fixes #1351.

Originally committed to SVN as r5773.
This commit is contained in:
Niels Martin Hansen 2011-10-24 20:36:48 +00:00
parent e0c9f16988
commit 225832c490
3 changed files with 25 additions and 2 deletions

View File

@ -78,7 +78,7 @@ bool MicroDVDSubtitleFormat::CanReadFile(wxString filename) {
// Since there is an infinity of .sub formats, load first line and check if it's valid
TextFileReader file(filename);
if (file.HasMoreLines()) {
if (file.HasMoreLines() && !file.SmellsBinary()) {
wxRegEx exp(_T("^[\\{\\[]([0-9]+)[\\}\\]][\\{\\[]([0-9]+)[\\}\\]](.*)$"),wxRE_ADVANCED);
return exp.Matches(file.ReadLineFromFile());
}
@ -94,13 +94,18 @@ bool MicroDVDSubtitleFormat::CanWriteFile(wxString filename) {
}
DEFINE_SIMPLE_EXCEPTION(MicrodvdFormatParseError, SubtitleFormatParseError, "subtitle_io/parse/microdvd")
///////////////
// Read a file
void MicroDVDSubtitleFormat::ReadFile(wxString filename,wxString forceEncoding) {
// Load and prepare regexp
TextFileReader file(filename);
TextFileReader file(filename, forceEncoding);
wxRegEx exp(_T("^[\\{\\[]([0-9]+)[\\}\\]][\\{\\[]([0-9]+)[\\}\\]](.*)$"),wxRE_ADVANCED);
if (file.SmellsBinary())
throw new MicrodvdFormatParseError(_T("File seems to be binary. Maybe it's a VobSub format file? (Aegisub does not support VobSub format.)"), 0);
// Load default
LoadDefault(false);

View File

@ -307,6 +307,21 @@ void TextFileReader::Open() {
}
#endif
open = true;
// Check if file seems binary
size_t binaryFactor = 0;
const size_t bufsize = 512;
char buf[bufsize];
file.get(buf, bufsize);
size_t bytes_read = file.gcount();
file.seekg(0, std::ios_base::beg);
for (size_t i = 0; i < bytes_read; ++i) {
if (((unsigned char)buf[i]) < 32) {
if (buf[i] != '\r' && buf[i] != '\n' && buf[i] != '\t')
binaryFactor++;
}
}
isBinary = (binaryFactor > 8) || (binaryFactor > bytes_read/8);
}
@ -352,3 +367,4 @@ void TextFileReader::EnsureValid(wxString enc) {
wxString TextFileReader::GetCurrentEncoding() {
return encoding;
}

View File

@ -66,6 +66,7 @@ private:
bool open;
bool customConv;
bool trim;
bool isBinary;
void Open();
void Close();
@ -81,6 +82,7 @@ public:
static void EnsureValid(const wxString encoding);
wxString GetCurrentEncoding();
static wxString GetEncoding(const wxString filename);
bool SmellsBinary() { return !Is16 && isBinary; }
};