diff options
Diffstat (limited to 'extensions/common')
-rw-r--r-- | extensions/common/DEPS (renamed from extensions/common/matcher/DEPS) | 0 | ||||
-rw-r--r-- | extensions/common/constants.h | 6 | ||||
-rw-r--r-- | extensions/common/extension_urls.cc | 16 | ||||
-rw-r--r-- | extensions/common/extension_urls.h | 20 | ||||
-rw-r--r-- | extensions/common/stack_frame.cc | 80 | ||||
-rw-r--r-- | extensions/common/stack_frame.h | 41 | ||||
-rw-r--r-- | extensions/common/stack_frame_unittest.cc | 85 |
7 files changed, 245 insertions, 3 deletions
diff --git a/extensions/common/matcher/DEPS b/extensions/common/DEPS index 972b087..972b087 100644 --- a/extensions/common/matcher/DEPS +++ b/extensions/common/DEPS diff --git a/extensions/common/constants.h b/extensions/common/constants.h index 492ddbc..648663d 100644 --- a/extensions/common/constants.h +++ b/extensions/common/constants.h @@ -12,13 +12,13 @@ namespace extensions { // Scheme we serve extension content from. extern const char kExtensionScheme[]; - // The name of the manifest inside an extension. +// The name of the manifest inside an extension. extern const base::FilePath::CharType kManifestFilename[]; - // The name of locale folder inside an extension. +// The name of locale folder inside an extension. extern const base::FilePath::CharType kLocaleFolder[]; - // The name of the messages file inside an extension. +// The name of the messages file inside an extension. extern const base::FilePath::CharType kMessagesFilename[]; // The base directory for subdirectories with platform-specific code. diff --git a/extensions/common/extension_urls.cc b/extensions/common/extension_urls.cc new file mode 100644 index 0000000..f354b6b --- /dev/null +++ b/extensions/common/extension_urls.cc @@ -0,0 +1,16 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "extensions/common/extension_urls.h" + +#include "extensions/common/constants.h" +#include "url/gurl.h" + +namespace extensions { + +bool IsSourceFromAnExtension(const base::string16& source) { + return GURL(source).SchemeIs(kExtensionScheme); +} + +} // namespace extensions diff --git a/extensions/common/extension_urls.h b/extensions/common/extension_urls.h new file mode 100644 index 0000000..7fa7e1e --- /dev/null +++ b/extensions/common/extension_urls.h @@ -0,0 +1,20 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef EXTENSIONS_COMMON_EXTENSION_URLS_H_ +#define EXTENSIONS_COMMON_EXTENSION_URLS_H_ + +#include "base/strings/string16.h" + +namespace extensions { + +// Determine whether or not a source came from an extension. |source| can link +// to a page or a script, and can be external (e.g., "http://www.google.com"), +// extension-related (e.g., "chrome-extension://<extension_id>/background.js"), +// or internal (e.g., "event_bindings" or "schemaUtils"). +bool IsSourceFromAnExtension(const base::string16& source); + +} // namespace extensions + +#endif // EXTENSIONS_COMMON_EXTENSION_URLS_H_ diff --git a/extensions/common/stack_frame.cc b/extensions/common/stack_frame.cc new file mode 100644 index 0000000..d287496 --- /dev/null +++ b/extensions/common/stack_frame.cc @@ -0,0 +1,80 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "extensions/common/stack_frame.h" + +#include <string> + +#include "base/strings/utf_string_conversions.h" +#include "third_party/re2/re2/re2.h" + +namespace extensions { + +namespace { +const char kAnonymousFunction[] = "(anonymous function)"; +} + +StackFrame::StackFrame() : line_number(1), column_number(1) { +} + +StackFrame::StackFrame(const StackFrame& frame) + : line_number(frame.line_number), + column_number(frame.column_number), + source(frame.source), + function(frame.function) { +} + +StackFrame::StackFrame(size_t line_number, + size_t column_number, + const base::string16& source, + const base::string16& function) + : line_number(line_number), + column_number(column_number), + source(source), + function(function.empty() ? base::UTF8ToUTF16(kAnonymousFunction) + : function) { +} + +StackFrame::~StackFrame() { +} + +// Create a stack frame from the passed text. The text must follow one of two +// formats: +// - "function_name (source:line_number:column_number)" +// - "source:line_number:column_number" +// (We have to recognize two formats because V8 will report stack traces in +// both ways. If we reconcile this, we can clean this up.) +// static +scoped_ptr<StackFrame> StackFrame::CreateFromText( + const base::string16& frame_text) { + // We need to use utf8 for re2 matching. + std::string text = base::UTF16ToUTF8(frame_text); + + size_t line = 1; + size_t column = 1; + std::string source; + std::string function; + if (!re2::RE2::FullMatch(text, + "(.+) \\(([^\\(\\)]+):(\\d+):(\\d+)\\)", + &function, &source, &line, &column) && + !re2::RE2::FullMatch(text, + "([^\\(\\)]+):(\\d+):(\\d+)", + &source, &line, &column)) { + return scoped_ptr<StackFrame>(); + } + + return scoped_ptr<StackFrame>(new StackFrame(line, + column, + base::UTF8ToUTF16(source), + base::UTF8ToUTF16(function))); +} + +bool StackFrame::operator==(const StackFrame& rhs) const { + return line_number == rhs.line_number && + column_number == rhs.column_number && + source == rhs.source && + function == rhs.function; +} + +} // namespace extensions diff --git a/extensions/common/stack_frame.h b/extensions/common/stack_frame.h new file mode 100644 index 0000000..7052605 --- /dev/null +++ b/extensions/common/stack_frame.h @@ -0,0 +1,41 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef EXTENSIONS_COMMON_STACK_FRAME +#define EXTENSIONS_COMMON_STACK_FRAME + +#include <vector> + +#include "base/memory/scoped_ptr.h" +#include "base/strings/string16.h" + +namespace extensions { + +struct StackFrame { + StackFrame(); + StackFrame(const StackFrame& frame); + StackFrame(size_t line_number, + size_t column_number, + const base::string16& source, + const base::string16& function); + ~StackFrame(); + + // Construct a stack frame from a reported plain-text frame. + static scoped_ptr<StackFrame> CreateFromText( + const base::string16& frame_text); + + bool operator==(const StackFrame& rhs) const; + + size_t line_number; + size_t column_number; + base::string16 source; + base::string16 function; // optional +}; + +typedef std::vector<StackFrame> StackTrace; + +} // namespace extensions + +#endif // EXTENSIONS_COMMON_STACK_FRAME + diff --git a/extensions/common/stack_frame_unittest.cc b/extensions/common/stack_frame_unittest.cc new file mode 100644 index 0000000..7dad047 --- /dev/null +++ b/extensions/common/stack_frame_unittest.cc @@ -0,0 +1,85 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "extensions/common/stack_frame.h" + +#include "base/logging.h" +#include "base/memory/scoped_ptr.h" +#include "base/strings/string16.h" +#include "base/strings/utf_string_conversions.h" +#include "testing/gtest/include/gtest/gtest.h" + +using base::UTF8ToUTF16; + +namespace extensions { + +namespace { + +void AssertStackFrameValid(const std::string& text, + size_t line, + size_t column, + const std::string& source, + const std::string& function) { + base::string16 utf16_text = UTF8ToUTF16(text); + scoped_ptr<StackFrame> frame = StackFrame::CreateFromText(utf16_text); + + ASSERT_TRUE(frame.get()) << "Failed to create frame from '" << text << "'"; + EXPECT_EQ(line, frame->line_number()); + EXPECT_EQ(column, frame->column_number()); + EXPECT_EQ(UTF8ToUTF16(source), frame->source()); + EXPECT_EQ(UTF8ToUTF16(function), frame->function()); +} + +void AssertStackFrameInvalid(const std::string& text) { + base::string16 utf16_text = UTF8ToUTF16(text); + scoped_ptr<StackFrame> frame = StackFrame::CreateFromText(utf16_text); + ASSERT_FALSE(frame.get()) << "Errantly created frame from '" << text << "'"; +} + +} // namespace + +TEST(StackFrameUnitTest, ParseStackFramesFromText) { + AssertStackFrameValid( + "function_name (https://www.url.com/foo.html:100:201)", + 100u, 201u, "https://www.url.com/foo.html", "function_name"); + AssertStackFrameValid( + "(anonymous function) (https://www.url.com/foo.html:100:201)", + 100u, 201u, "https://www.url.com/foo.html", "(anonymous function)"); + AssertStackFrameValid( + "Function.target.(anonymous function) (internals::SafeBuiltins:19:14)", + 19u, 14u, "internals::SafeBuiltins", + "Function.target.(anonymous function)"); + AssertStackFrameValid( + "internal-item:://fpgohbggpmcpeedljibghijiclejiklo/script.js:6:12", + 6u, 12u, "internal-item:://fpgohbggpmcpeedljibghijiclejiklo/script.js", + "(anonymous function)"); + + // No delimiting ':' between line/column numbers. + AssertStackFrameInvalid( + "function_name (https://www.url.com/foo.html:100201)"); + // No line number. + AssertStackFrameInvalid("function_name (https://www.url.com/foo.html::201)"); + // No line number or delimiting ':'. + AssertStackFrameInvalid("function_name (https://www.url.com/foo.html201)"); + // No leading '(' around url, line, column. + AssertStackFrameInvalid( + "function_name https://www.url.com/foo.html:100:201)"); + // No trailing ')'. + AssertStackFrameInvalid( + "function_name (https://www.url.com/foo.html:100:201"); + // Trailing ' '. + AssertStackFrameInvalid( + "function_name (https://www.url.com/foo.html:100:201) "); + // Invalid column number. + AssertStackFrameInvalid( + "function_name (https://www.url.com/foo.html:100:201a)"); + // Negative column number. + AssertStackFrameInvalid( + "function_name (https://www.url.com/foo.html:100:-201)"); + // Extra trailing ')' + AssertStackFrameInvalid( + "function_name (https://www.url.com/foo.html:100:201))"); +} + +} // namespace extensions |