Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(859)

Unified Diff: pdf/pdfium/pdfium_engine.cc

Issue 427583003: Fix UAF in chrome_pdf::Instance::GetURL() (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Alternative, more correct fix (but riskier). Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« pdf/instance.cc ('K') | « pdf/pdfium/pdfium_engine.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pdf/pdfium/pdfium_engine.cc
diff --git a/pdf/pdfium/pdfium_engine.cc b/pdf/pdfium/pdfium_engine.cc
index e8c164b03ac0dd2f8066ef7b385e59a8803d1449..2a128ba9e42d48b9942c2d627e655f45c93c5ac1 100644
--- a/pdf/pdfium/pdfium_engine.cc
+++ b/pdf/pdfium/pdfium_engine.cc
@@ -611,6 +611,10 @@ PDFiumEngine::~PDFiumEngine() {
FPDFAvail_Destroy(fpdf_availability_);
}
+void PDFiumEngine::ClientDestroyed() {
+ client_ = NULL;
+}
+
int PDFiumEngine::GetBlock(void* param, unsigned long position,
unsigned char* buffer, unsigned long size) {
DocumentLoader* loader = static_cast<DocumentLoader*>(param);
@@ -660,6 +664,8 @@ void PDFiumEngine::PluginSizeUpdated(const pp::Size& size) {
void PDFiumEngine::ScrolledToXPosition(int position) {
CancelPaints();
+ if (!client_)
+ return;
int old_x = position_.x();
position_.set_x(position);
@@ -669,6 +675,8 @@ void PDFiumEngine::ScrolledToXPosition(int position) {
void PDFiumEngine::ScrolledToYPosition(int position) {
CancelPaints();
+ if (!client_)
+ return;
int old_y = position_.y();
position_.set_y(position);
@@ -757,11 +765,11 @@ bool PDFiumEngine::HandleDocumentLoad(const pp::URLLoader& loader) {
}
pp::Instance* PDFiumEngine::GetPluginInstance() {
- return client_->GetPluginInstance();
+ return client_ ? client_->GetPluginInstance() : NULL;
}
pp::URLLoader PDFiumEngine::CreateURLLoader() {
- return client_->CreateURLLoader();
+ return client_ ? client_->CreateURLLoader() : pp::URLLoader();
}
void PDFiumEngine::AppendPage(PDFEngine* engine, int index) {
@@ -777,6 +785,9 @@ void PDFiumEngine::AppendPage(PDFEngine* engine, int index) {
pp::Size new_page_size = GetPageSize(index);
if (curr_page_size != new_page_size)
LoadPageInfo(true);
+ if (!client_)
+ return;
+
client_->Invalidate(GetPageScreenRect(index));
}
@@ -821,7 +832,7 @@ void PDFiumEngine::OnPendingRequestComplete() {
for (size_t i = 0; i < pending_pages_.size(); ++i) {
if (CheckPageAvailable(pending_pages_[i], &still_pending)) {
update_pages = true;
- if (IsPageVisible(pending_pages_[i]))
+ if (client_ && IsPageVisible(pending_pages_[i]))
client_->Invalidate(GetPageScreenRect(pending_pages_[i]));
}
}
@@ -831,6 +842,8 @@ void PDFiumEngine::OnPendingRequestComplete() {
}
void PDFiumEngine::OnNewDataAvailable() {
+ if (!client_)
+ return;
client_->DocumentLoadProgress(doc_loader_.GetAvailableData(),
doc_loader_.document_size());
}
@@ -852,7 +865,7 @@ void PDFiumEngine::OnDocumentComplete() {
// already downloaded.
FPDFAvail_IsPageAvail(fpdf_availability_, i, &download_hints_);
need_update = true;
- if (IsPageVisible(i))
+ if (client_ && IsPageVisible(i))
client_->Invalidate(GetPageScreenRect(i));
}
if (need_update)
@@ -875,11 +888,14 @@ void PDFiumEngine::FinishLoadingDocument() {
FORM_DoPageAAction(new_page, form_, FPDFPAGE_AACTION_OPEN);
}
- if (doc_) // This can only happen if loading |doc_| fails.
+ if (doc_ && client_) // This can only happen if loading |doc_| fails.
client_->DocumentLoadComplete(pages_.size());
}
void PDFiumEngine::UnsupportedFeature(int type) {
+ if (!client_)
+ return;
+
std::string feature;
switch (type) {
case FPDF_UNSP_DOC_XFAFORM:
@@ -985,6 +1001,9 @@ pp::Resource PDFiumEngine::PrintPages(
pp::Buffer_Dev PDFiumEngine::PrintPagesAsRasterPDF(
const PP_PrintPageNumberRange_Dev* page_ranges, uint32_t page_range_count,
const PP_PrintSettings_Dev& print_settings) {
+ if (!client_)
+ return pp::Buffer_Dev();
+
if (!page_range_count)
return pp::Buffer_Dev();
@@ -1107,6 +1126,9 @@ pp::Buffer_Dev PDFiumEngine::PrintPagesAsRasterPDF(
}
pp::Buffer_Dev PDFiumEngine::GetFlattenedPrintData(const FPDF_DOCUMENT& doc) {
+ if (!client_)
+ return pp::Buffer_Dev();
+
int page_count = FPDF_GetPageCount(doc);
bool flatten_succeeded = true;
for (int i = 0; i < page_count; ++i) {
@@ -1211,6 +1233,8 @@ void PDFiumEngine::FitContentsToPrintableAreaIfRequired(
void PDFiumEngine::SaveSelectedFormForPrint() {
FORM_ForceToKillFocus(form_);
+ if (!client_)
+ return;
client_->FormTextFieldFocusChange(false);
}
@@ -1257,6 +1281,9 @@ PDFiumPage::Area PDFiumEngine::GetCharIndex(
}
bool PDFiumEngine::OnMouseDown(const pp::MouseInputEvent& event) {
+ if (!client_)
+ return false;
+
if (event.GetButton() != PP_INPUTEVENT_MOUSEBUTTON_LEFT)
return false;
@@ -1368,6 +1395,9 @@ bool PDFiumEngine::OnMouseUp(const pp::MouseInputEvent& event) {
}
bool PDFiumEngine::OnMouseMove(const pp::MouseInputEvent& event) {
+ if (!client_)
+ return false;
+
int page_index = -1;
int char_index = -1;
PDFiumPage::Area area = GetCharIndex(event, &page_index, &char_index, NULL);
@@ -1489,6 +1519,9 @@ bool PDFiumEngine::OnMouseMove(const pp::MouseInputEvent& event) {
}
bool PDFiumEngine::OnKeyDown(const pp::KeyboardInputEvent& event) {
+ if (!client_)
+ return false;
+
if (last_page_mouse_down_ == -1)
return false;
@@ -1538,6 +1571,9 @@ bool PDFiumEngine::OnChar(const pp::KeyboardInputEvent& event) {
}
void PDFiumEngine::StartFind(const char* text, bool case_sensitive) {
+ if (!client_)
+ return;
+
// We can get a call to StartFind before we have any page information (i.e.
// before the first call to LoadDocument has happened). Handle this case.
if (pages_.empty())
@@ -1652,6 +1688,9 @@ void PDFiumEngine::SearchUsingICU(const base::string16& term,
bool first_search,
int character_to_start_searching_from,
int current_page) {
+ if (!client_)
+ return;
+
base::string16 page_text;
int text_length = pages_[current_page]->GetCharCount();
if (character_to_start_searching_from) {
@@ -1686,6 +1725,9 @@ void PDFiumEngine::SearchUsingICU(const base::string16& term,
}
void PDFiumEngine::AddFindResult(const PDFiumRange& result) {
+ if (!client_)
+ return;
+
// Figure out where to insert the new location, since we could have
// started searching midway and now we wrapped.
size_t i;
@@ -1713,6 +1755,9 @@ void PDFiumEngine::AddFindResult(const PDFiumRange& result) {
}
bool PDFiumEngine::SelectFindResult(bool forward) {
+ if (!client_)
+ return false;
+
if (find_results_.empty()) {
NOTREACHED();
return false;
@@ -1784,6 +1829,9 @@ void PDFiumEngine::StopFind() {
}
void PDFiumEngine::UpdateTickMarks() {
+ if (!client_)
+ return;
+
std::vector<pp::Rect> tickmarks;
for (size_t i = 0; i < find_results_.size(); ++i) {
pp::Rect rect;
@@ -1818,6 +1866,9 @@ void PDFiumEngine::RotateCounterclockwise() {
}
void PDFiumEngine::InvalidateAllPages() {
+ if (!client_)
+ return;
+
selection_.clear();
find_results_.clear();
@@ -1947,6 +1998,9 @@ void PDFiumEngine::SetGrayscale(bool grayscale) {
}
void PDFiumEngine::OnCallback(int id) {
+ if (!client_)
+ return;
+
if (!timers_.count(id))
return;
@@ -1977,6 +2031,8 @@ bool PDFiumEngine::GetPrintScaling() {
void PDFiumEngine::AppendBlankPages(int num_pages) {
DCHECK(num_pages != 0);
+ if (!client_)
+ return;
if (!doc_)
return;
@@ -2029,6 +2085,9 @@ void PDFiumEngine::AppendBlankPages(int num_pages) {
}
void PDFiumEngine::LoadDocument() {
+ if (!client_)
+ return;
+
// Check if the document is ready for loading. If it isn't just bail for now,
// we will call LoadDocument() again later.
if (!doc_ && !doc_loader_.IsDocumentComplete() &&
@@ -2079,6 +2138,9 @@ bool PDFiumEngine::TryLoadingDoc(bool with_password,
void PDFiumEngine::GetPasswordAndLoad() {
getting_password_ = true;
DCHECK(!doc_ && FPDF_GetLastError() == FPDF_ERR_PASSWORD);
+ if (!client_)
+ return;
+
client_->GetDocumentPassword(password_factory_.NewCallbackWithOutput(
&PDFiumEngine::OnGetPasswordComplete));
}
@@ -2100,6 +2162,9 @@ void PDFiumEngine::OnGetPasswordComplete(int32_t result,
void PDFiumEngine::ContinueLoadingDocument(
bool has_password,
const std::string& password) {
+ if (!client_)
+ return;
+
ScopedUnsupportedFeature scoped_unsupported_feature(this);
bool needs_password = false;
@@ -2148,6 +2213,9 @@ void PDFiumEngine::ContinueLoadingDocument(
}
void PDFiumEngine::LoadPageInfo(bool reload) {
+ if (!client_)
+ return;
+
pending_pages_.clear();
pp::Size old_document_size = document_size_;
document_size_ = pp::Size();
@@ -2323,6 +2391,9 @@ int PDFiumEngine::StartPaint(int page_index, const pp::Rect& dirty) {
bool PDFiumEngine::ContinuePaint(int progressive_index,
pp::ImageData* image_data) {
+ if (!client_)
+ return false;
+
#if defined(OS_LINUX)
g_last_instance_id = client_->GetPluginInstance()->pp_instance();
#endif
@@ -2353,6 +2424,9 @@ bool PDFiumEngine::ContinuePaint(int progressive_index,
void PDFiumEngine::FinishPaint(int progressive_index,
pp::ImageData* image_data) {
+ if (!client_)
+ return;
+
int page_index = progressive_paints_[progressive_index].page_index;
pp::Rect dirty_in_screen = progressive_paints_[progressive_index].rect;
FPDF_BITMAP bitmap = progressive_paints_[progressive_index].bitmap;
@@ -2546,7 +2620,7 @@ int PDFiumEngine::GetRenderingFlags() const {
int flags = FPDF_LCD_TEXT | FPDF_NO_CATCH;
if (render_grayscale_)
flags |= FPDF_GRAYSCALE;
- if (client_->IsPrintPreview())
+ if (client_ && client_->IsPrintPreview())
flags |= FPDF_PRINTING;
return flags;
}
@@ -2641,13 +2715,15 @@ PDFiumEngine::SelectionChangeInvalidator::~SelectionChangeInvalidator() {
}
}
- for (size_t i = 0; i < old_selections_.size(); ++i) {
- if (!old_selections_[i].IsEmpty())
- engine_->client_->Invalidate(old_selections_[i]);
- }
- for (size_t i = 0; i < new_selections.size(); ++i) {
- if (!new_selections[i].IsEmpty())
- engine_->client_->Invalidate(new_selections[i]);
+ if (engine_->client_) {
+ for (size_t i = 0; i < old_selections_.size(); ++i) {
+ if (!old_selections_[i].IsEmpty())
+ engine_->client_->Invalidate(old_selections_[i]);
+ }
+ for (size_t i = 0; i < new_selections.size(); ++i) {
+ if (!new_selections[i].IsEmpty())
+ engine_->client_->Invalidate(new_selections[i]);
+ }
}
engine_->OnSelectionChanged();
}
@@ -2703,6 +2779,7 @@ void PDFiumEngine::SetCurrentPage(int index) {
}
most_visible_page_ = index;
#if defined(OS_LINUX)
+ if (client_)
g_last_instance_id = client_->GetPluginInstance()->pp_instance();
#endif
if (most_visible_page_ != -1 && called_do_document_action_) {
@@ -2863,6 +2940,9 @@ void PDFiumEngine::Form_Invalidate(FPDF_FORMFILLINFO* param,
return;
}
+ if (!engine->client_)
+ return;
+
pp::Rect rect = engine->pages_[page_index]->PageToScreen(
engine->GetVisibleRect().point(), engine->current_zoom_, left, top, right,
bottom, engine->current_rotation_);
@@ -2896,6 +2976,9 @@ int PDFiumEngine::Form_SetTimer(FPDF_FORMFILLINFO* param,
int elapse,
TimerCallback timer_func) {
PDFiumEngine* engine = static_cast<PDFiumEngine*>(param);
+ if (!engine->client_)
+ return -1;
+
engine->timers_[++engine->next_timer_id_] =
std::pair<int, TimerCallback>(elapse, timer_func);
engine->client_->ScheduleCallback(engine->next_timer_id_, elapse);
@@ -2960,6 +3043,9 @@ int PDFiumEngine::Form_GetRotation(FPDF_FORMFILLINFO* param, FPDF_PAGE page) {
void PDFiumEngine::Form_ExecuteNamedAction(FPDF_FORMFILLINFO* param,
FPDF_BYTESTRING named_action) {
PDFiumEngine* engine = static_cast<PDFiumEngine*>(param);
+ if (!engine->client_)
+ return;
+
std::string action(named_action);
if (action == "Print") {
engine->client_->Print();
@@ -3004,6 +3090,8 @@ void PDFiumEngine::Form_SetTextFieldFocus(FPDF_FORMFILLINFO* param,
void PDFiumEngine::Form_DoURIAction(FPDF_FORMFILLINFO* param,
FPDF_BYTESTRING uri) {
PDFiumEngine* engine = static_cast<PDFiumEngine*>(param);
+ if (!engine->client_)
+ return;
engine->client_->NavigateTo(std::string(uri), false);
}
@@ -3013,6 +3101,8 @@ void PDFiumEngine::Form_DoGoToAction(FPDF_FORMFILLINFO* param,
float* position_array,
int size_of_array) {
PDFiumEngine* engine = static_cast<PDFiumEngine*>(param);
+ if (!engine->client_)
+ return;
engine->client_->ScrollToPage(page_index);
}
@@ -3037,6 +3127,9 @@ int PDFiumEngine::Form_Alert(IPDF_JSPLATFORM* param,
};
PDFiumEngine* engine = static_cast<PDFiumEngine*>(param);
+ if (!engine->client_)
+ return ALERT_RESULT_CANCEL;
+
std::string message_str =
base::UTF16ToUTF8(reinterpret_cast<const base::char16*>(message));
if (type == ALERT_TYPE_OK) {
@@ -3062,12 +3155,15 @@ int PDFiumEngine::Form_Response(IPDF_JSPLATFORM* param,
FPDF_BOOL password,
void* response,
int length) {
+ PDFiumEngine* engine = static_cast<PDFiumEngine*>(param);
+ if (!engine->client_)
+ return -1;
+
std::string question_str = base::UTF16ToUTF8(
reinterpret_cast<const base::char16*>(question));
std::string default_str = base::UTF16ToUTF8(
reinterpret_cast<const base::char16*>(default_response));
- PDFiumEngine* engine = static_cast<PDFiumEngine*>(param);
std::string rv = engine->client_->Prompt(question_str, default_str);
base::string16 rv_16 = base::UTF8ToUTF16(rv);
int rv_bytes = rv_16.size() * sizeof(base::char16);
@@ -3082,6 +3178,9 @@ int PDFiumEngine::Form_GetFilePath(IPDF_JSPLATFORM* param,
void* file_path,
int length) {
PDFiumEngine* engine = static_cast<PDFiumEngine*>(param);
+ if (!engine->client_)
+ return -1;
+
std::string rv = engine->client_->GetURL();
if (file_path && rv.size() <= static_cast<size_t>(length))
memcpy(file_path, rv.c_str(), rv.size());
@@ -3098,6 +3197,10 @@ void PDFiumEngine::Form_Mail(IPDF_JSPLATFORM* param,
FPDF_WIDESTRING bcc,
FPDF_WIDESTRING message) {
DCHECK(length == 0); // Don't handle attachments; no way with mailto.
+ PDFiumEngine* engine = static_cast<PDFiumEngine*>(param);
+ if (!engine->client_)
+ return;
+
std::string to_str =
base::UTF16ToUTF8(reinterpret_cast<const base::char16*>(to));
std::string cc_str =
@@ -3109,7 +3212,6 @@ void PDFiumEngine::Form_Mail(IPDF_JSPLATFORM* param,
std::string message_str =
base::UTF16ToUTF8(reinterpret_cast<const base::char16*>(message));
- PDFiumEngine* engine = static_cast<PDFiumEngine*>(param);
engine->client_->Email(to_str, cc_str, bcc_str, subject_str, message_str);
}
@@ -3125,6 +3227,8 @@ void PDFiumEngine::Form_Print(IPDF_JSPLATFORM* param,
// No way to pass the extra information to the print dialog using JavaScript.
// Just opening it is fine for now.
PDFiumEngine* engine = static_cast<PDFiumEngine*>(param);
+ if (!engine->client_)
+ return;
engine->client_->Print();
}
@@ -3132,15 +3236,19 @@ void PDFiumEngine::Form_SubmitForm(IPDF_JSPLATFORM* param,
void* form_data,
int length,
FPDF_WIDESTRING url) {
+ PDFiumEngine* engine = static_cast<PDFiumEngine*>(param);
+ if (!engine->client_)
+ return;
std::string url_str =
base::UTF16ToUTF8(reinterpret_cast<const base::char16*>(url));
- PDFiumEngine* engine = static_cast<PDFiumEngine*>(param);
engine->client_->SubmitForm(url_str, form_data, length);
}
void PDFiumEngine::Form_GotoPage(IPDF_JSPLATFORM* param,
int page_number) {
PDFiumEngine* engine = static_cast<PDFiumEngine*>(param);
+ if (!engine->client_)
+ return;
engine->client_->ScrollToPage(page_number);
}
@@ -3148,6 +3256,9 @@ int PDFiumEngine::Form_Browse(IPDF_JSPLATFORM* param,
void* file_path,
int length) {
PDFiumEngine* engine = static_cast<PDFiumEngine*>(param);
+ if (!engine->client_)
+ return -1;
+
std::string path = engine->client_->ShowFileSelectionDialog();
if (path.size() + 1 <= static_cast<size_t>(length))
memcpy(file_path, &path[0], path.size() + 1);
« pdf/instance.cc ('K') | « pdf/pdfium/pdfium_engine.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698