* GetStyledText() is now much more forgiving when it comes to corrupted data

(ie. if the text file is cut off, it will no longer return an error, but
  load as much as possible).
* Minor cleanup.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@19831 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2007-01-16 20:50:56 +00:00
parent 84137e45f1
commit 450a5aea22
+45 -54
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2006, Haiku Inc. * Copyright 2002-2007, Haiku Inc.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
@@ -340,47 +340,46 @@ BTranslationUtils::GetStyledText(BPositionIO *fromStream, BTextView *intoView,
// make sure there is enough data to fill the stream header // make sure there is enough data to fill the stream header
const size_t kStreamHeaderSize = sizeof(TranslatorStyledTextStreamHeader); const size_t kStreamHeaderSize = sizeof(TranslatorStyledTextStreamHeader);
if (mallocIO.BufferLength() < kStreamHeaderSize) if (mallocIO.BufferLength() < kStreamHeaderSize)
return B_ERROR; return B_BAD_DATA;
// copy the stream header from the mallio buffer // copy the stream header from the mallio buffer
TranslatorStyledTextStreamHeader stm_header = TranslatorStyledTextStreamHeader header =
*(reinterpret_cast<const TranslatorStyledTextStreamHeader *>(buffer)); *(reinterpret_cast<const TranslatorStyledTextStreamHeader *>(buffer));
// convert the stm_header.header struct to the host format // convert the stm_header.header struct to the host format
const size_t kRecordHeaderSize = sizeof(TranslatorStyledTextRecordHeader); const size_t kRecordHeaderSize = sizeof(TranslatorStyledTextRecordHeader);
if (swap_data(B_UINT32_TYPE, &stm_header.header, kRecordHeaderSize, swap_data(B_UINT32_TYPE, &header.header, kRecordHeaderSize, B_SWAP_BENDIAN_TO_HOST);
B_SWAP_BENDIAN_TO_HOST) != B_OK swap_data(B_INT32_TYPE, &header.version, sizeof(int32), B_SWAP_BENDIAN_TO_HOST);
|| swap_data(B_INT32_TYPE, &stm_header.version, sizeof(int32),
B_SWAP_BENDIAN_TO_HOST) != B_OK if (header.header.magic != 'STXT')
|| stm_header.header.magic != 'STXT') return B_BAD_TYPE;
return B_ERROR;
// copy the text header from the mallocIO buffer // copy the text header from the mallocIO buffer
uint32 offset = stm_header.header.header_size + uint32 offset = header.header.header_size + header.header.data_size;
stm_header.header.data_size;
const size_t kTextHeaderSize = sizeof(TranslatorStyledTextTextHeader); const size_t kTextHeaderSize = sizeof(TranslatorStyledTextTextHeader);
if (mallocIO.BufferLength() < offset + kTextHeaderSize) if (mallocIO.BufferLength() < offset + kTextHeaderSize)
return B_ERROR; return B_BAD_DATA;
TranslatorStyledTextTextHeader textHeader = TranslatorStyledTextTextHeader textHeader =
*(const TranslatorStyledTextTextHeader *)(buffer + offset); *(const TranslatorStyledTextTextHeader *)(buffer + offset);
// convert the stm_header.header struct to the host format // convert the stm_header.header struct to the host format
if (swap_data(B_UINT32_TYPE, &textHeader.header, kRecordHeaderSize, swap_data(B_UINT32_TYPE, &textHeader.header, kRecordHeaderSize, B_SWAP_BENDIAN_TO_HOST);
B_SWAP_BENDIAN_TO_HOST) != B_OK swap_data(B_INT32_TYPE, &textHeader.charset, sizeof(int32), B_SWAP_BENDIAN_TO_HOST);
|| swap_data(B_INT32_TYPE, &textHeader.charset, sizeof(int32),
B_SWAP_BENDIAN_TO_HOST) != B_OK if (textHeader.header.magic != 'TEXT' || textHeader.charset != B_UNICODE_UTF8)
|| textHeader.header.magic != 'TEXT' return B_BAD_TYPE;
|| textHeader.charset != B_UNICODE_UTF8)
return B_ERROR;
offset += textHeader.header.header_size; offset += textHeader.header.header_size;
if (mallocIO.BufferLength() < offset + textHeader.header.data_size) if (mallocIO.BufferLength() < offset + textHeader.header.data_size) {
return B_ERROR; // text buffer misses its end; handle this gracefully
textHeader.header.data_size = mallocIO.BufferLength() - offset;
}
const char* text = (const char*)buffer + offset; const char* text = (const char*)buffer + offset;
// point text pointer at the actual character data // point text pointer at the actual character data
bool hasStyles = false;
if (mallocIO.BufferLength() > offset + textHeader.header.data_size) { if (mallocIO.BufferLength() > offset + textHeader.header.data_size) {
// If the stream contains information beyond the text data // If the stream contains information beyond the text data
@@ -389,40 +388,32 @@ BTranslationUtils::GetStyledText(BPositionIO *fromStream, BTextView *intoView,
offset += textHeader.header.data_size; offset += textHeader.header.data_size;
const size_t kStyleHeaderSize = const size_t kStyleHeaderSize =
sizeof(TranslatorStyledTextStyleHeader); sizeof(TranslatorStyledTextStyleHeader);
if (mallocIO.BufferLength() < offset + kStyleHeaderSize) if (mallocIO.BufferLength() >= offset + kStyleHeaderSize) {
return B_ERROR; TranslatorStyledTextStyleHeader styleHeader =
*(reinterpret_cast<const TranslatorStyledTextStyleHeader *>(buffer + offset));
TranslatorStyledTextStyleHeader styleHeader = swap_data(B_UINT32_TYPE, &styleHeader.header, kRecordHeaderSize, B_SWAP_BENDIAN_TO_HOST);
*(reinterpret_cast<const TranslatorStyledTextStyleHeader *>(buffer + offset)); swap_data(B_UINT32_TYPE, &styleHeader.apply_offset, sizeof(uint32), B_SWAP_BENDIAN_TO_HOST);
if (swap_data(B_UINT32_TYPE, &styleHeader.header, kRecordHeaderSize, swap_data(B_UINT32_TYPE, &styleHeader.apply_length, sizeof(uint32), B_SWAP_BENDIAN_TO_HOST);
B_SWAP_BENDIAN_TO_HOST) != B_OK if (styleHeader.header.magic == 'STYL') {
|| swap_data(B_UINT32_TYPE, &styleHeader.apply_offset, sizeof(uint32), offset += styleHeader.header.header_size;
B_SWAP_BENDIAN_TO_HOST) != B_OK if (mallocIO.BufferLength() >= offset + styleHeader.header.data_size)
|| swap_data(B_UINT32_TYPE, &styleHeader.apply_length, sizeof(uint32), hasStyles = true;
B_SWAP_BENDIAN_TO_HOST) != B_OK }
|| styleHeader.header.magic != 'STYL')
return B_ERROR;
offset += styleHeader.header.header_size;
if (mallocIO.BufferLength() < offset + styleHeader.header.data_size)
return B_ERROR;
// get the text run array
text_run_array *runArray = BTextView::UnflattenRunArray(buffer + offset);
if (runArray) {
intoView->Insert(intoView->TextLength(), text,
textHeader.header.data_size, runArray);
#ifdef HAIKU_TARGET_PLATFORM_HAIKU
BTextView::FreeRunArray(runArray);
#else
free(runArray);
#endif
} else {
// run array seems to be garbled; the text alone must be enough
intoView->Insert(intoView->TextLength(), text,
textHeader.header.data_size);
} }
}
text_run_array *runArray = NULL;
if (hasStyles)
runArray = BTextView::UnflattenRunArray(buffer + offset);
if (runArray != NULL) {
intoView->Insert(intoView->TextLength(),
text, textHeader.header.data_size, runArray);
#ifdef HAIKU_TARGET_PLATFORM_HAIKU
BTextView::FreeRunArray(runArray);
#else
free(runArray);
#endif
} else { } else {
intoView->Insert(intoView->TextLength(), text, intoView->Insert(intoView->TextLength(), text,
textHeader.header.data_size); textHeader.header.data_size);