mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-03 14:28:39 +09:00
Merge remote-tracking branch 'origin/master' into custom
This commit is contained in:
commit
6d191b58d4
64 changed files with 532 additions and 20498 deletions
|
|
@ -682,6 +682,15 @@ pref("plugins.update.notifyUser", false);
|
|||
//Enable tri-state option (Always/Never/Ask)
|
||||
pref("plugins.click_to_play", true);
|
||||
|
||||
// Platform pref is to enable all plugins by default.
|
||||
// Uncomment this pref to default to click-to-play
|
||||
// pref("plugin.default.state", 1);
|
||||
|
||||
// Don't load plugin instances with no src declared.
|
||||
// These prefs are documented in detail in all.js.
|
||||
pref("plugins.favorfallback.mode", "follow-ctp");
|
||||
pref("plugins.favorfallback.rules", "nosrc");
|
||||
|
||||
#ifdef XP_WIN
|
||||
pref("browser.preferences.instantApply", false);
|
||||
#else
|
||||
|
|
|
|||
|
|
@ -361,10 +361,10 @@ set_config('LIB', lib_path)
|
|||
|
||||
option(env='MT', nargs=1, help='Path to the Microsoft Manifest Tool')
|
||||
|
||||
@depends_win(valid_windows_sdk_dir)
|
||||
@depends_win(valid_windows_sdk_dir, valid_ucrt_sdk_dir)
|
||||
@imports(_from='os', _import='environ')
|
||||
@imports('platform')
|
||||
def sdk_bin_path(valid_windows_sdk_dir):
|
||||
def sdk_bin_path(valid_windows_sdk_dir, valid_ucrt_sdk_dir):
|
||||
if not valid_windows_sdk_dir:
|
||||
return
|
||||
|
||||
|
|
@ -373,13 +373,17 @@ def sdk_bin_path(valid_windows_sdk_dir):
|
|||
'AMD64': 'x64',
|
||||
}.get(platform.machine())
|
||||
|
||||
# From version 10.0.15063.0 onwards the bin path contains the version number.
|
||||
versioned_bin = ('bin' if valid_ucrt_sdk_dir.version < '10.0.15063.0'
|
||||
else os.path.join('bin', str(valid_ucrt_sdk_dir.version)))
|
||||
|
||||
result = [
|
||||
environ['PATH'],
|
||||
os.path.join(valid_windows_sdk_dir.path, 'bin', vc_host)
|
||||
os.path.join(valid_windows_sdk_dir.path, versioned_bin, vc_host)
|
||||
]
|
||||
if vc_host == 'x64':
|
||||
result.append(
|
||||
os.path.join(valid_windows_sdk_dir.path, 'bin', 'x86'))
|
||||
os.path.join(valid_windows_sdk_dir.path, versioned_bin, 'x86'))
|
||||
return result
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -718,9 +718,9 @@ nsObjectLoadingContent::UnbindFromTree(bool aDeep, bool aNullParent)
|
|||
if (mType == eType_Plugin) {
|
||||
nsIDocument* doc = thisContent->GetComposedDoc();
|
||||
if (doc && doc->IsActive()) {
|
||||
nsCOMPtr<nsIRunnable> ev = new nsSimplePluginEvent(doc,
|
||||
NS_LITERAL_STRING("PluginRemoved"));
|
||||
NS_DispatchToCurrentThread(ev);
|
||||
nsCOMPtr<nsIRunnable> ev = new nsSimplePluginEvent(doc,
|
||||
NS_LITERAL_STRING("PluginRemoved"));
|
||||
NS_DispatchToCurrentThread(ev);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3628,6 +3628,14 @@ nsObjectLoadingContent::HasGoodFallback() {
|
|||
}
|
||||
}
|
||||
|
||||
// RULE "nosrc":
|
||||
// Use fallback content if the object has not specified a src URI.
|
||||
if (rulesList[i].EqualsLiteral("nosrc")) {
|
||||
if (!mOriginalURI) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// RULE "adobelink":
|
||||
// Don't use fallback content when it has a link to adobe's website.
|
||||
if (rulesList[i].EqualsLiteral("adobelink")) {
|
||||
|
|
|
|||
|
|
@ -659,7 +659,7 @@ ImageDocument::CreateSyntheticDocument()
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Add the image element
|
||||
Element* body = GetBodyElement();
|
||||
RefPtr<Element> body = GetBodyElement();
|
||||
if (!body) {
|
||||
NS_WARNING("no body on image document!");
|
||||
return NS_ERROR_FAILURE;
|
||||
|
|
|
|||
|
|
@ -206,7 +206,7 @@ PluginDocument::CreateSyntheticPluginDocument()
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
// then attach our plugin
|
||||
|
||||
Element* body = GetBodyElement();
|
||||
RefPtr<Element> body = GetBodyElement();
|
||||
if (!body) {
|
||||
NS_WARNING("no body on plugin document!");
|
||||
return NS_ERROR_FAILURE;
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ VideoDocument::CreateSyntheticVideoDocument(nsIChannel* aChannel,
|
|||
nsresult rv = MediaDocument::CreateSyntheticDocument();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
Element* body = GetBodyElement();
|
||||
RefPtr<Element> body = GetBodyElement();
|
||||
if (!body) {
|
||||
NS_WARNING("no body on video document!");
|
||||
return NS_ERROR_FAILURE;
|
||||
|
|
|
|||
|
|
@ -430,7 +430,7 @@ IDBCursor::Continue(JSContext* aCx,
|
|||
}
|
||||
|
||||
Key key;
|
||||
aRv = key.SetFromJSVal(aCx, aKey);
|
||||
aRv = key.SetFromJSVal(aCx, aKey, /* aCallGetters */ true);
|
||||
if (aRv.Failed()) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -536,7 +536,7 @@ IDBCursor::ContinuePrimaryKey(JSContext* aCx,
|
|||
}
|
||||
|
||||
Key key;
|
||||
aRv = key.SetFromJSVal(aCx, aKey);
|
||||
aRv = key.SetFromJSVal(aCx, aKey, /* aCallGetters */ true);
|
||||
if (aRv.Failed()) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -558,7 +558,7 @@ IDBCursor::ContinuePrimaryKey(JSContext* aCx,
|
|||
}
|
||||
|
||||
Key primaryKey;
|
||||
aRv = primaryKey.SetFromJSVal(aCx, aPrimaryKey);
|
||||
aRv = primaryKey.SetFromJSVal(aCx, aPrimaryKey, /* aCallGetters */ true);
|
||||
if (aRv.Failed()) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -718,7 +718,7 @@ IDBCursor::Update(JSContext* aCx, JS::Handle<JS::Value> aValue,
|
|||
const KeyPath& keyPath = objectStore->GetKeyPath();
|
||||
Key key;
|
||||
|
||||
aRv = keyPath.ExtractKey(aCx, aValue, key);
|
||||
aRv = keyPath.ExtractKey(aCx, aValue, key, /* aCallGetters */ false);
|
||||
if (aRv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -482,13 +482,13 @@ IDBFactory::Cmp(JSContext* aCx, JS::Handle<JS::Value> aFirst,
|
|||
JS::Handle<JS::Value> aSecond, ErrorResult& aRv)
|
||||
{
|
||||
Key first, second;
|
||||
nsresult rv = first.SetFromJSVal(aCx, aFirst);
|
||||
nsresult rv = first.SetFromJSVal(aCx, aFirst, /* aCallGetters */ true);
|
||||
if (NS_FAILED(rv)) {
|
||||
aRv.Throw(rv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
rv = second.SetFromJSVal(aCx, aSecond);
|
||||
rv = second.SetFromJSVal(aCx, aSecond, /* aCallGetters */ true);
|
||||
if (NS_FAILED(rv)) {
|
||||
aRv.Throw(rv);
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ GetKeyFromJSVal(JSContext* aCx,
|
|||
JS::Handle<JS::Value> aVal,
|
||||
Key& aKey)
|
||||
{
|
||||
nsresult rv = aKey.SetFromJSVal(aCx, aVal);
|
||||
nsresult rv = aKey.SetFromJSVal(aCx, aVal, /* aCallGetters */ true);
|
||||
if (NS_FAILED(rv)) {
|
||||
MOZ_ASSERT(NS_ERROR_GET_MODULE(rv) == NS_ERROR_MODULE_DOM_INDEXEDDB);
|
||||
return rv;
|
||||
|
|
|
|||
|
|
@ -1084,7 +1084,7 @@ IDBObjectStore::AppendIndexUpdateInfo(
|
|||
|
||||
if (!aMultiEntry) {
|
||||
Key key;
|
||||
rv = aKeyPath.ExtractKey(aCx, aVal, key);
|
||||
rv = aKeyPath.ExtractKey(aCx, aVal, key, /* aCallGetters */ false);
|
||||
|
||||
// If an index's keyPath doesn't match an object, we ignore that object.
|
||||
if (rv == NS_ERROR_DOM_INDEXEDDB_DATA_ERR || key.IsUnset()) {
|
||||
|
|
@ -1128,13 +1128,13 @@ IDBObjectStore::AppendIndexUpdateInfo(
|
|||
|
||||
for (uint32_t arrayIndex = 0; arrayIndex < arrayLength; arrayIndex++) {
|
||||
JS::Rooted<JS::Value> arrayItem(aCx);
|
||||
if (NS_WARN_IF(!JS_GetElement(aCx, array, arrayIndex, &arrayItem))) {
|
||||
if (NS_WARN_IF(!JS_GetOwnElement(aCx, array, arrayIndex, &arrayItem))) {
|
||||
IDB_REPORT_INTERNAL_ERR();
|
||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||
}
|
||||
|
||||
Key value;
|
||||
if (NS_FAILED(value.SetFromJSVal(aCx, arrayItem)) ||
|
||||
if (NS_FAILED(value.SetFromJSVal(aCx, arrayItem, /* aCallGetters */ false)) ||
|
||||
value.IsUnset()) {
|
||||
// Not a value we can do anything with, ignore it.
|
||||
continue;
|
||||
|
|
@ -1153,7 +1153,7 @@ IDBObjectStore::AppendIndexUpdateInfo(
|
|||
}
|
||||
else {
|
||||
Key value;
|
||||
if (NS_FAILED(value.SetFromJSVal(aCx, val)) ||
|
||||
if (NS_FAILED(value.SetFromJSVal(aCx, val, /* aCallGetters */ false)) ||
|
||||
value.IsUnset()) {
|
||||
// Not a value we can do anything with, ignore it.
|
||||
return NS_OK;
|
||||
|
|
@ -1324,12 +1324,12 @@ IDBObjectStore::GetAddInfo(JSContext* aCx,
|
|||
|
||||
if (!HasValidKeyPath()) {
|
||||
// Out-of-line keys must be passed in.
|
||||
rv = aKey.SetFromJSVal(aCx, aKeyVal);
|
||||
rv = aKey.SetFromJSVal(aCx, aKeyVal, /* aCallGetters */ true);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
} else if (!isAutoIncrement) {
|
||||
rv = GetKeyPath().ExtractKey(aCx, aValue, aKey);
|
||||
rv = GetKeyPath().ExtractKey(aCx, aValue, aKey, /* aCallGetters */ false);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
|
@ -1368,7 +1368,8 @@ IDBObjectStore::GetAddInfo(JSContext* aCx,
|
|||
aValue,
|
||||
aKey,
|
||||
&GetAddInfoCallback,
|
||||
&data);
|
||||
&data,
|
||||
/* aCallGetters */ false);
|
||||
} else {
|
||||
rv = GetAddInfoCallback(aCx, &data);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -201,8 +201,11 @@ Key::ToLocaleBasedKey(Key& aTarget, const nsCString& aLocale) const
|
|||
}
|
||||
|
||||
nsresult
|
||||
Key::EncodeJSValInternal(JSContext* aCx, JS::Handle<JS::Value> aVal,
|
||||
uint8_t aTypeOffset, uint16_t aRecursionDepth)
|
||||
Key::EncodeJSValInternal(JSContext* aCx,
|
||||
JS::Handle<JS::Value> aVal,
|
||||
uint8_t aTypeOffset,
|
||||
uint16_t aRecursionDepth,
|
||||
bool aCallGetters)
|
||||
{
|
||||
static_assert(eMaxType * kMaxArrayCollapse < 256,
|
||||
"Unable to encode jsvals.");
|
||||
|
|
@ -257,13 +260,18 @@ Key::EncodeJSValInternal(JSContext* aCx, JS::Handle<JS::Value> aVal,
|
|||
|
||||
for (uint32_t index = 0; index < length; index++) {
|
||||
JS::Rooted<JS::Value> val(aCx);
|
||||
if (!JS_GetElement(aCx, obj, index, &val)) {
|
||||
bool ok = aCallGetters ? JS_GetElement(aCx, obj, index, &val)
|
||||
: JS_GetOwnElement(aCx, obj, index, &val);
|
||||
if (!ok) {
|
||||
IDB_REPORT_INTERNAL_ERR();
|
||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||
}
|
||||
|
||||
nsresult rv = EncodeJSValInternal(aCx, val, aTypeOffset,
|
||||
aRecursionDepth + 1);
|
||||
nsresult rv = EncodeJSValInternal(aCx,
|
||||
val,
|
||||
aTypeOffset,
|
||||
aRecursionDepth + 1,
|
||||
aCallGetters);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
|
@ -406,9 +414,10 @@ Key::DecodeJSValInternal(const unsigned char*& aPos, const unsigned char* aEnd,
|
|||
nsresult
|
||||
Key::EncodeJSVal(JSContext* aCx,
|
||||
JS::Handle<JS::Value> aVal,
|
||||
uint8_t aTypeOffset)
|
||||
uint8_t aTypeOffset,
|
||||
bool aCallGetters)
|
||||
{
|
||||
return EncodeJSValInternal(aCx, aVal, aTypeOffset, 0);
|
||||
return EncodeJSValInternal(aCx, aVal, aTypeOffset, 0, aCallGetters);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -741,7 +750,8 @@ Key::SetFromValueArray(mozIStorageValueArray* aValues,
|
|||
|
||||
nsresult
|
||||
Key::SetFromJSVal(JSContext* aCx,
|
||||
JS::Handle<JS::Value> aVal)
|
||||
JS::Handle<JS::Value> aVal,
|
||||
bool aCallGetters)
|
||||
{
|
||||
mBuffer.Truncate();
|
||||
|
||||
|
|
@ -750,7 +760,7 @@ Key::SetFromJSVal(JSContext* aCx,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult rv = EncodeJSVal(aCx, aVal, 0);
|
||||
nsresult rv = EncodeJSVal(aCx, aVal, 0, aCallGetters);
|
||||
if (NS_FAILED(rv)) {
|
||||
Unset();
|
||||
return rv;
|
||||
|
|
@ -793,9 +803,15 @@ Key::ToJSVal(JSContext* aCx,
|
|||
}
|
||||
|
||||
nsresult
|
||||
Key::AppendItem(JSContext* aCx, bool aFirstOfArray, JS::Handle<JS::Value> aVal)
|
||||
Key::AppendItem(JSContext* aCx,
|
||||
bool aFirstOfArray,
|
||||
JS::Handle<JS::Value> aVal,
|
||||
bool aCallGetters)
|
||||
{
|
||||
nsresult rv = EncodeJSVal(aCx, aVal, aFirstOfArray ? eMaxType : 0);
|
||||
nsresult rv = EncodeJSVal(aCx,
|
||||
aVal,
|
||||
aFirstOfArray ? eMaxType : 0,
|
||||
aCallGetters);
|
||||
if (NS_FAILED(rv)) {
|
||||
Unset();
|
||||
return rv;
|
||||
|
|
|
|||
|
|
@ -203,7 +203,7 @@ public:
|
|||
}
|
||||
|
||||
nsresult
|
||||
SetFromJSVal(JSContext* aCx, JS::Handle<JS::Value> aVal);
|
||||
SetFromJSVal(JSContext* aCx, JS::Handle<JS::Value> aVal, bool aCallGetters);
|
||||
|
||||
nsresult
|
||||
ToJSVal(JSContext* aCx, JS::MutableHandle<JS::Value> aVal) const;
|
||||
|
|
@ -212,7 +212,10 @@ public:
|
|||
ToJSVal(JSContext* aCx, JS::Heap<JS::Value>& aVal) const;
|
||||
|
||||
nsresult
|
||||
AppendItem(JSContext* aCx, bool aFirstOfArray, JS::Handle<JS::Value> aVal);
|
||||
AppendItem(JSContext* aCx,
|
||||
bool aFirstOfArray,
|
||||
JS::Handle<JS::Value> aVal,
|
||||
bool aCallGetters);
|
||||
|
||||
nsresult
|
||||
ToLocaleBasedKey(Key& aTarget, const nsCString& aLocale) const;
|
||||
|
|
@ -283,7 +286,10 @@ private:
|
|||
|
||||
// Encoding functions. These append the encoded value to the end of mBuffer
|
||||
nsresult
|
||||
EncodeJSVal(JSContext* aCx, JS::Handle<JS::Value> aVal, uint8_t aTypeOffset);
|
||||
EncodeJSVal(JSContext* aCx,
|
||||
JS::Handle<JS::Value> aVal,
|
||||
uint8_t aTypeOffset,
|
||||
bool aCallGetters);
|
||||
|
||||
void
|
||||
EncodeString(const nsAString& aString, uint8_t aTypeOffset);
|
||||
|
|
@ -331,7 +337,8 @@ private:
|
|||
EncodeJSValInternal(JSContext* aCx,
|
||||
JS::Handle<JS::Value> aVal,
|
||||
uint8_t aTypeOffset,
|
||||
uint16_t aRecursionDepth);
|
||||
uint16_t aRecursionDepth,
|
||||
bool aCallGetters);
|
||||
|
||||
static nsresult
|
||||
DecodeJSValInternal(const unsigned char*& aPos,
|
||||
|
|
|
|||
|
|
@ -372,11 +372,13 @@ KeyPath::AppendStringWithValidation(const nsAString& aString)
|
|||
}
|
||||
|
||||
nsresult
|
||||
KeyPath::ExtractKey(JSContext* aCx, const JS::Value& aValue, Key& aKey) const
|
||||
KeyPath::ExtractKey(JSContext* aCx,
|
||||
const JS::Value& aValue,
|
||||
Key& aKey,
|
||||
bool aCallGetters) const
|
||||
{
|
||||
uint32_t len = mStrings.Length();
|
||||
JS::Rooted<JS::Value> value(aCx);
|
||||
|
||||
aKey.Unset();
|
||||
|
||||
for (uint32_t i = 0; i < len; ++i) {
|
||||
|
|
@ -388,7 +390,10 @@ KeyPath::ExtractKey(JSContext* aCx, const JS::Value& aValue, Key& aKey) const
|
|||
return rv;
|
||||
}
|
||||
|
||||
if (NS_FAILED(aKey.AppendItem(aCx, IsArray() && i == 0, value))) {
|
||||
if (NS_FAILED(aKey.AppendItem(aCx,
|
||||
IsArray() && i == 0,
|
||||
value,
|
||||
aCallGetters))) {
|
||||
NS_ASSERTION(aKey.IsUnset(), "Encoding error should unset");
|
||||
return NS_ERROR_DOM_INDEXEDDB_DATA_ERR;
|
||||
}
|
||||
|
|
@ -437,9 +442,12 @@ KeyPath::ExtractKeyAsJSVal(JSContext* aCx, const JS::Value& aValue,
|
|||
}
|
||||
|
||||
nsresult
|
||||
KeyPath::ExtractOrCreateKey(JSContext* aCx, const JS::Value& aValue,
|
||||
Key& aKey, ExtractOrCreateKeyCallback aCallback,
|
||||
void* aClosure) const
|
||||
KeyPath::ExtractOrCreateKey(JSContext* aCx,
|
||||
const JS::Value& aValue,
|
||||
Key& aKey,
|
||||
ExtractOrCreateKeyCallback aCallback,
|
||||
void* aClosure,
|
||||
bool aCallGetters) const
|
||||
{
|
||||
NS_ASSERTION(IsString(), "This doesn't make sense!");
|
||||
|
||||
|
|
@ -455,7 +463,7 @@ KeyPath::ExtractOrCreateKey(JSContext* aCx, const JS::Value& aValue,
|
|||
return rv;
|
||||
}
|
||||
|
||||
if (NS_FAILED(aKey.AppendItem(aCx, false, value))) {
|
||||
if (NS_FAILED(aKey.AppendItem(aCx, false, value, aCallGetters))) {
|
||||
NS_ASSERTION(aKey.IsUnset(), "Should be unset");
|
||||
return value.isUndefined() ? NS_OK : NS_ERROR_DOM_INDEXEDDB_DATA_ERR;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -72,7 +72,10 @@ public:
|
|||
Parse(const Nullable<OwningStringOrStringSequence>& aValue, KeyPath* aKeyPath);
|
||||
|
||||
nsresult
|
||||
ExtractKey(JSContext* aCx, const JS::Value& aValue, Key& aKey) const;
|
||||
ExtractKey(JSContext* aCx,
|
||||
const JS::Value& aValue,
|
||||
Key& aKey,
|
||||
bool aCallGetters) const;
|
||||
|
||||
nsresult
|
||||
ExtractKeyAsJSVal(JSContext* aCx, const JS::Value& aValue,
|
||||
|
|
@ -82,9 +85,12 @@ public:
|
|||
(*ExtractOrCreateKeyCallback)(JSContext* aCx, void* aClosure);
|
||||
|
||||
nsresult
|
||||
ExtractOrCreateKey(JSContext* aCx, const JS::Value& aValue, Key& aKey,
|
||||
ExtractOrCreateKey(JSContext* aCx,
|
||||
const JS::Value& aValue,
|
||||
Key& aKey,
|
||||
ExtractOrCreateKeyCallback aCallback,
|
||||
void* aClosure) const;
|
||||
void* aClosure,
|
||||
bool aCallGetters) const;
|
||||
|
||||
inline bool IsValid() const {
|
||||
return mType != NONEXISTENT;
|
||||
|
|
|
|||
|
|
@ -513,8 +513,19 @@ nsCSPContext::GetAllowsInline(nsContentPolicyType aContentType,
|
|||
for (uint32_t i = 0; i < mPolicies.Length(); i++) {
|
||||
bool allowed =
|
||||
mPolicies[i]->allows(aContentType, CSP_UNSAFE_INLINE, EmptyString(), aParserCreated) ||
|
||||
mPolicies[i]->allows(aContentType, CSP_NONCE, aNonce, aParserCreated) ||
|
||||
mPolicies[i]->allows(aContentType, CSP_HASH, aContent, aParserCreated);
|
||||
mPolicies[i]->allows(aContentType, CSP_NONCE, aNonce, aParserCreated);
|
||||
|
||||
// If the inlined script or style is allowed by either unsafe-inline or the
|
||||
// nonce, go ahead and shortcut this loop.
|
||||
if (allowed) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check if the csp-hash matches against the hash of the script.
|
||||
// If we don't have any content to check, block the script.
|
||||
if (!aContent.IsEmpty()) {
|
||||
allowed = mPolicies[i]->allows(aContentType, CSP_HASH, aContent, aParserCreated);
|
||||
}
|
||||
|
||||
if (!allowed) {
|
||||
// policy is violoated: deny the load unless policy is report only and
|
||||
|
|
|
|||
|
|
@ -641,13 +641,22 @@ nsCSPHostSrc::permits(nsIURI* aUri, const nsAString& aNonce, bool aWasRedirected
|
|||
// just a specific scheme, the parser should generate a nsCSPSchemeSource.
|
||||
NS_ASSERTION((!mHost.IsEmpty()), "host can not be the empty string");
|
||||
|
||||
// Before we can check if the host matches, we have to
|
||||
// extract the host part from aUri.
|
||||
nsAutoCString uriHost;
|
||||
nsresult rv = aUri->GetAsciiHost(uriHost);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
|
||||
nsString decodedUriHost;
|
||||
CSP_PercentDecodeStr(NS_ConvertUTF8toUTF16(uriHost), decodedUriHost);
|
||||
|
||||
// 2) host matching: Enforce a single *
|
||||
if (mHost.EqualsASCII("*")) {
|
||||
// The single ASTERISK character (*) does not match a URI's scheme of a type
|
||||
// designating a globally unique identifier (such as blob:, data:, or filesystem:)
|
||||
// At the moment firefox does not support filesystem; but for future compatibility
|
||||
// At the moment UXP does not support "filesystem:" but for future compatibility
|
||||
// we support it in CSP according to the spec, see: 4.2.2 Matching Source Expressions
|
||||
// Note, that whitelisting any of these schemes would call nsCSPSchemeSrc::permits().
|
||||
// Note: whitelisting any of these schemes would call nsCSPSchemeSrc::permits().
|
||||
bool isBlobScheme =
|
||||
(NS_SUCCEEDED(aUri->SchemeIs("blob", &isBlobScheme)) && isBlobScheme);
|
||||
bool isDataScheme =
|
||||
|
|
@ -658,20 +667,15 @@ nsCSPHostSrc::permits(nsIURI* aUri, const nsAString& aNonce, bool aWasRedirected
|
|||
if (isBlobScheme || isDataScheme || isFileScheme) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
// If no scheme is present there also won't be a port and folder to check
|
||||
// which means we can return early.
|
||||
if (mScheme.IsEmpty()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Before we can check if the host matches, we have to
|
||||
// extract the host part from aUri.
|
||||
nsAutoCString uriHost;
|
||||
nsresult rv = aUri->GetAsciiHost(uriHost);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
|
||||
nsString decodedUriHost;
|
||||
CSP_PercentDecodeStr(NS_ConvertUTF8toUTF16(uriHost), decodedUriHost);
|
||||
|
||||
// 4.5) host matching: Check if the allowed host starts with a wilcard.
|
||||
if (mHost.First() == '*') {
|
||||
else if (mHost.First() == '*') {
|
||||
NS_ASSERTION(mHost[1] == '.', "Second character needs to be '.' whenever host starts with '*'");
|
||||
|
||||
// Eliminate leading "*", but keeping the FULL STOP (.) thereafter before checking
|
||||
|
|
|
|||
|
|
@ -723,7 +723,7 @@ public:
|
|||
* The resulting vertices are populated in aVerts. aVerts must be
|
||||
* pre-allocated to hold at least kTransformAndClipRectMaxVerts Points.
|
||||
* The vertex count is returned by TransformAndClipRect. It is possible to
|
||||
* emit fewer that 3 vertices, indicating that aRect will not be visible
|
||||
* emit fewer than 3 vertices, indicating that aRect will not be visible
|
||||
* within aClip.
|
||||
*/
|
||||
template<class F>
|
||||
|
|
@ -734,7 +734,8 @@ public:
|
|||
// Initialize a double-buffered array of points in homogenous space with
|
||||
// the input rectangle, aRect.
|
||||
Point4DTyped<UnknownUnits, F> points[2][kTransformAndClipRectMaxVerts];
|
||||
Point4DTyped<UnknownUnits, F>* dstPoint = points[0];
|
||||
Point4DTyped<UnknownUnits, F>* dstPointStart = points[0];
|
||||
Point4DTyped<UnknownUnits, F>* dstPoint = dstPointStart;
|
||||
|
||||
*dstPoint++ = TransformPoint(Point4DTyped<UnknownUnits, F>(aRect.x, aRect.y, 0, 1));
|
||||
*dstPoint++ = TransformPoint(Point4DTyped<UnknownUnits, F>(aRect.XMost(), aRect.y, 0, 1));
|
||||
|
|
@ -750,16 +751,26 @@ public:
|
|||
planeNormals[3] = Point4DTyped<UnknownUnits, F>(0.0, -1.0, 0.0, aClip.YMost());
|
||||
|
||||
// Iterate through each clipping plane and clip the polygon.
|
||||
// In each pass, we double buffer, alternating between points[0] and
|
||||
// points[1].
|
||||
// For each clipping plane, we intersect the plane with all polygon edges.
|
||||
// Each pass can increase or decrease the number of points that make up the
|
||||
// current clipped polygon. We double buffer that set of points, alternating
|
||||
// between points[0] and points[1].
|
||||
for (int plane=0; plane < 4; plane++) {
|
||||
planeNormals[plane].Normalize();
|
||||
Point4DTyped<UnknownUnits, F>* srcPoint = points[plane & 1];
|
||||
Point4DTyped<UnknownUnits, F>* srcPoint = dstPointStart;
|
||||
Point4DTyped<UnknownUnits, F>* srcPointEnd = dstPoint;
|
||||
|
||||
dstPoint = points[~plane & 1];
|
||||
Point4DTyped<UnknownUnits, F>* dstPointStart = dstPoint;
|
||||
dstPointStart = points[~plane & 1];
|
||||
dstPoint = dstPointStart;
|
||||
|
||||
// Iterate over the polygon edges. In each iteration the current edge is
|
||||
// the edge from prevPoint to srcPoint. If the two end points lie on
|
||||
// different sides of the plane, we have an intersection. Otherwise, the
|
||||
// edge is either completely "inside" the half-space created by the
|
||||
// clipping plane, and we add srcPoint, or it is completely "outside", and
|
||||
// we discard srcPoint.
|
||||
// We may create duplicated points in the polygon. We keep those around
|
||||
// until all clipping is done and then filter out duplicates at the end.
|
||||
Point4DTyped<UnknownUnits, F>* prevPoint = srcPointEnd - 1;
|
||||
F prevDot = planeNormals[plane].DotProduct(*prevPoint);
|
||||
while (srcPoint < srcPointEnd && ((dstPoint - dstPointStart) < kTransformAndClipRectMaxVerts)) {
|
||||
|
|
@ -783,14 +794,16 @@ public:
|
|||
}
|
||||
|
||||
if (dstPoint == dstPointStart) {
|
||||
// No polygon points were produced, so the polygon has been
|
||||
// completely clipped away by the current clipping plane. Exit.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
size_t dstPointCount = 0;
|
||||
size_t srcPointCount = dstPoint - points[0];
|
||||
for (Point4DTyped<UnknownUnits, F>* srcPoint = points[0]; srcPoint < points[0] + srcPointCount; srcPoint++) {
|
||||
|
||||
Point4DTyped<UnknownUnits, F>* srcPoint = dstPointStart;
|
||||
Point4DTyped<UnknownUnits, F>* srcPointEnd = dstPoint;
|
||||
size_t vertCount = 0;
|
||||
while (srcPoint < srcPointEnd) {
|
||||
PointTyped<TargetUnits, F> p;
|
||||
if (srcPoint->w == 0.0) {
|
||||
// If a point lies on the intersection of the clipping planes at
|
||||
|
|
@ -800,12 +813,13 @@ public:
|
|||
p = srcPoint->As2DPoint();
|
||||
}
|
||||
// Emit only unique points
|
||||
if (dstPointCount == 0 || p != aVerts[dstPointCount - 1]) {
|
||||
aVerts[dstPointCount++] = p;
|
||||
if (vertCount == 0 || p != aVerts[vertCount - 1]) {
|
||||
aVerts[vertCount++] = p;
|
||||
}
|
||||
srcPoint++;
|
||||
}
|
||||
|
||||
return dstPointCount;
|
||||
return vertCount;
|
||||
}
|
||||
|
||||
static const int kTransformAndClipRectMaxVerts = 32;
|
||||
|
|
|
|||
61
gfx/tests/gtest/TestMatrix.cpp
Normal file
61
gfx/tests/gtest/TestMatrix.cpp
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "mozilla/gfx/Matrix.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::gfx;
|
||||
|
||||
static Rect NudgedToInt(const Rect& aRect) {
|
||||
Rect r(aRect);
|
||||
r.NudgeToIntegers();
|
||||
return r;
|
||||
}
|
||||
|
||||
TEST(Matrix, TransformAndClipRect)
|
||||
{
|
||||
Rect c(100, 100, 100, 100);
|
||||
Matrix4x4 m;
|
||||
EXPECT_TRUE(m.TransformAndClipBounds(Rect(50, 50, 20, 20), c).IsEmpty());
|
||||
EXPECT_TRUE(m.TransformAndClipBounds(Rect(250, 50, 20, 20), c).IsEmpty());
|
||||
EXPECT_TRUE(m.TransformAndClipBounds(Rect(250, 250, 20, 20), c).IsEmpty());
|
||||
EXPECT_TRUE(m.TransformAndClipBounds(Rect(50, 250, 20, 20), c).IsEmpty());
|
||||
|
||||
EXPECT_TRUE(m.TransformAndClipBounds(Rect(50, 50, 100, 20), c).IsEmpty());
|
||||
EXPECT_TRUE(m.TransformAndClipBounds(Rect(150, 50, 100, 20), c).IsEmpty());
|
||||
EXPECT_TRUE(m.TransformAndClipBounds(Rect(50, 250, 100, 20), c).IsEmpty());
|
||||
EXPECT_TRUE(m.TransformAndClipBounds(Rect(150, 250, 100, 20), c).IsEmpty());
|
||||
|
||||
EXPECT_TRUE(m.TransformAndClipBounds(Rect(50, 50, 20, 100), c).IsEmpty());
|
||||
EXPECT_TRUE(m.TransformAndClipBounds(Rect(50, 150, 20, 100), c).IsEmpty());
|
||||
EXPECT_TRUE(m.TransformAndClipBounds(Rect(250, 50, 20, 100), c).IsEmpty());
|
||||
EXPECT_TRUE(m.TransformAndClipBounds(Rect(250, 150, 20, 100), c).IsEmpty());
|
||||
|
||||
EXPECT_TRUE(NudgedToInt(m.TransformAndClipBounds(Rect(50, 50, 100, 100), c))
|
||||
.IsEqualInterior(Rect(100, 100, 50, 50)));
|
||||
EXPECT_TRUE(NudgedToInt(m.TransformAndClipBounds(Rect(150, 50, 100, 100), c))
|
||||
.IsEqualInterior(Rect(150, 100, 50, 50)));
|
||||
EXPECT_TRUE(NudgedToInt(m.TransformAndClipBounds(Rect(150, 150, 100, 100), c))
|
||||
.IsEqualInterior(Rect(150, 150, 50, 50)));
|
||||
EXPECT_TRUE(NudgedToInt(m.TransformAndClipBounds(Rect(50, 150, 100, 100), c))
|
||||
.IsEqualInterior(Rect(100, 150, 50, 50)));
|
||||
|
||||
EXPECT_TRUE(NudgedToInt(m.TransformAndClipBounds(Rect(110, 110, 80, 80), c))
|
||||
.IsEqualInterior(Rect(110, 110, 80, 80)));
|
||||
|
||||
EXPECT_TRUE(NudgedToInt(m.TransformAndClipBounds(Rect(50, 50, 200, 200), c))
|
||||
.IsEqualInterior(Rect(100, 100, 100, 100)));
|
||||
|
||||
EXPECT_TRUE(NudgedToInt(m.TransformAndClipBounds(Rect(50, 50, 200, 100), c))
|
||||
.IsEqualInterior(Rect(100, 100, 100, 50)));
|
||||
EXPECT_TRUE(NudgedToInt(m.TransformAndClipBounds(Rect(50, 150, 200, 100), c))
|
||||
.IsEqualInterior(Rect(100, 150, 100, 50)));
|
||||
EXPECT_TRUE(NudgedToInt(m.TransformAndClipBounds(Rect(50, 50, 100, 200), c))
|
||||
.IsEqualInterior(Rect(100, 100, 50, 100)));
|
||||
EXPECT_TRUE(NudgedToInt(m.TransformAndClipBounds(Rect(150, 50, 100, 200), c))
|
||||
.IsEqualInterior(Rect(150, 100, 50, 100)));
|
||||
}
|
||||
|
|
@ -17,6 +17,7 @@ UNIFIED_SOURCES += [
|
|||
'TestGfxWidgets.cpp',
|
||||
'TestJobScheduler.cpp',
|
||||
'TestLayers.cpp',
|
||||
'TestMatrix.cpp',
|
||||
'TestMoz2D.cpp',
|
||||
'TestPolygon.cpp',
|
||||
'TestQcms.cpp',
|
||||
|
|
|
|||
|
|
@ -4005,7 +4005,7 @@ jit::ConvertLinearInequality(TempAllocator& alloc, MBasicBlock* block, const Lin
|
|||
}
|
||||
|
||||
static bool
|
||||
AnalyzePoppedThis(JSContext* cx, ObjectGroup* group,
|
||||
AnalyzePoppedThis(JSContext* cx, DPAConstraintInfo& constraintInfo, ObjectGroup* group,
|
||||
MDefinition* thisValue, MInstruction* ins, bool definitelyExecuted,
|
||||
HandlePlainObject baseobj,
|
||||
Vector<TypeNewScript::Initializer>* initializerList,
|
||||
|
|
@ -4046,7 +4046,12 @@ AnalyzePoppedThis(JSContext* cx, ObjectGroup* group,
|
|||
return true;
|
||||
|
||||
RootedId id(cx, NameToId(setprop->name()));
|
||||
if (!AddClearDefiniteGetterSetterForPrototypeChain(cx, group, id)) {
|
||||
bool added = false;
|
||||
if (!AddClearDefiniteGetterSetterForPrototypeChain(cx, constraintInfo,
|
||||
group, id, &added)) {
|
||||
return false;
|
||||
}
|
||||
if (!added) {
|
||||
// The prototype chain already contains a getter/setter for this
|
||||
// property, or type information is too imprecise.
|
||||
return true;
|
||||
|
|
@ -4106,7 +4111,12 @@ AnalyzePoppedThis(JSContext* cx, ObjectGroup* group,
|
|||
if (!baseobj->lookup(cx, id) && !accessedProperties->append(get->name()))
|
||||
return false;
|
||||
|
||||
if (!AddClearDefiniteGetterSetterForPrototypeChain(cx, group, id)) {
|
||||
bool added = false;
|
||||
if (!AddClearDefiniteGetterSetterForPrototypeChain(cx, constraintInfo,
|
||||
group, id, &added)) {
|
||||
return false;
|
||||
}
|
||||
if (!added) {
|
||||
// The |this| value can escape if any property reads it does go
|
||||
// through a getter.
|
||||
return true;
|
||||
|
|
@ -4132,8 +4142,11 @@ CmpInstructions(const void* a, const void* b)
|
|||
}
|
||||
|
||||
bool
|
||||
jit::AnalyzeNewScriptDefiniteProperties(JSContext* cx, HandleFunction fun,
|
||||
ObjectGroup* group, HandlePlainObject baseobj,
|
||||
jit::AnalyzeNewScriptDefiniteProperties(JSContext* cx,
|
||||
DPAConstraintInfo& constraintInfo,
|
||||
HandleFunction fun,
|
||||
ObjectGroup* group,
|
||||
HandlePlainObject baseobj,
|
||||
Vector<TypeNewScript::Initializer>* initializerList)
|
||||
{
|
||||
MOZ_ASSERT(cx->zone()->types.activeAnalysis);
|
||||
|
|
@ -4293,7 +4306,7 @@ jit::AnalyzeNewScriptDefiniteProperties(JSContext* cx, HandleFunction fun,
|
|||
|
||||
bool handled = false;
|
||||
size_t slotSpan = baseobj->slotSpan();
|
||||
if (!AnalyzePoppedThis(cx, group, thisValue, ins, definitelyExecuted,
|
||||
if (!AnalyzePoppedThis(cx, constraintInfo, group, thisValue, ins, definitelyExecuted,
|
||||
baseobj, initializerList, &accessedProperties, &handled))
|
||||
{
|
||||
return false;
|
||||
|
|
@ -4312,7 +4325,6 @@ jit::AnalyzeNewScriptDefiniteProperties(JSContext* cx, HandleFunction fun,
|
|||
// contingent on the correct frames being inlined. Add constraints to
|
||||
// invalidate the definite properties if additional functions could be
|
||||
// called at the inline frame sites.
|
||||
Vector<MBasicBlock*> exitBlocks(cx);
|
||||
for (MBasicBlockIterator block(graph.begin()); block != graph.end(); block++) {
|
||||
// Inlining decisions made after the last new property was added to
|
||||
// the object don't need to be frozen.
|
||||
|
|
@ -4320,9 +4332,11 @@ jit::AnalyzeNewScriptDefiniteProperties(JSContext* cx, HandleFunction fun,
|
|||
break;
|
||||
if (MResumePoint* rp = block->callerResumePoint()) {
|
||||
if (block->numPredecessors() == 1 && block->getPredecessor(0) == rp->block()) {
|
||||
JSScript* script = rp->block()->info().script();
|
||||
if (!AddClearDefiniteFunctionUsesInScript(cx, group, script, block->info().script()))
|
||||
JSScript* caller = rp->block()->info().script();
|
||||
JSScript* callee = block->info().script();
|
||||
if (!constraintInfo.addInliningConstraint(caller, callee)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -196,8 +196,11 @@ MCompare*
|
|||
ConvertLinearInequality(TempAllocator& alloc, MBasicBlock* block, const LinearSum& sum);
|
||||
|
||||
MOZ_MUST_USE bool
|
||||
AnalyzeNewScriptDefiniteProperties(JSContext* cx, HandleFunction fun,
|
||||
ObjectGroup* group, HandlePlainObject baseobj,
|
||||
AnalyzeNewScriptDefiniteProperties(JSContext* cx,
|
||||
DPAConstraintInfo& constraintInfo,
|
||||
HandleFunction fun,
|
||||
ObjectGroup* group,
|
||||
HandlePlainObject baseobj,
|
||||
Vector<TypeNewScript::Initializer>* initializerList);
|
||||
|
||||
MOZ_MUST_USE bool
|
||||
|
|
|
|||
|
|
@ -2010,6 +2010,28 @@ JS_GetOwnUCPropertyDescriptor(JSContext* cx, HandleObject obj, const char16_t* n
|
|||
return JS_GetOwnPropertyDescriptorById(cx, obj, id, desc);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS_GetOwnElement(JSContext* cx, JS::HandleObject obj, uint32_t index, JS::MutableHandleValue vp)
|
||||
{
|
||||
RootedId id(cx);
|
||||
if (!IndexToId(cx, index, &id)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Rooted<PropertyDescriptor> desc(cx);
|
||||
if (!JS_GetOwnPropertyDescriptorById(cx, obj, id, &desc)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (desc.object() && desc.isDataDescriptor()) {
|
||||
vp.set(desc.value());
|
||||
} else {
|
||||
vp.setUndefined();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS_GetPropertyDescriptorById(JSContext* cx, HandleObject obj, HandleId id,
|
||||
MutableHandle<PropertyDescriptor> desc)
|
||||
|
|
|
|||
|
|
@ -2922,6 +2922,9 @@ extern JS_PUBLIC_API(bool)
|
|||
JS_GetOwnUCPropertyDescriptor(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen,
|
||||
JS::MutableHandle<JS::PropertyDescriptor> desc);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_GetOwnElement(JSContext* cx, JS::HandleObject obj, uint32_t index, JS::MutableHandleValue vp);
|
||||
|
||||
/**
|
||||
* Like JS_GetOwnPropertyDescriptorById, but also searches the prototype chain
|
||||
* if no own property is found directly on obj. The object on which the
|
||||
|
|
|
|||
|
|
@ -3084,29 +3084,39 @@ class TypeConstraintClearDefiniteGetterSetter : public TypeConstraint
|
|||
};
|
||||
|
||||
bool
|
||||
js::AddClearDefiniteGetterSetterForPrototypeChain(JSContext* cx, ObjectGroup* group, HandleId id)
|
||||
js::AddClearDefiniteGetterSetterForPrototypeChain(JSContext* cx,
|
||||
DPAConstraintInfo& constraintInfo,
|
||||
ObjectGroup* group,
|
||||
HandleId id,
|
||||
bool* added)
|
||||
{
|
||||
/*
|
||||
* Ensure that if the properties named here could have a getter, setter or
|
||||
* a permanent property in any transitive prototype, the definite
|
||||
* properties get cleared from the group.
|
||||
*/
|
||||
|
||||
*added = false;
|
||||
|
||||
RootedObject proto(cx, group->proto().toObjectOrNull());
|
||||
while (proto) {
|
||||
ObjectGroup* protoGroup = JSObject::getGroup(cx, proto);
|
||||
if (!protoGroup) {
|
||||
cx->recoverFromOutOfMemory();
|
||||
return false;
|
||||
}
|
||||
if (protoGroup->unknownProperties())
|
||||
return false;
|
||||
return true;
|
||||
HeapTypeSet* protoTypes = protoGroup->getProperty(cx, proto, id);
|
||||
if (!protoTypes || protoTypes->nonDataProperty() || protoTypes->nonWritableProperty())
|
||||
if (!protoTypes)
|
||||
return false;
|
||||
if (!protoTypes->addConstraint(cx, cx->typeLifoAlloc().new_<TypeConstraintClearDefiniteGetterSetter>(group)))
|
||||
if (protoTypes->nonDataProperty() || protoTypes->nonWritableProperty())
|
||||
return true;
|
||||
if (!constraintInfo.addProtoConstraint(proto, id))
|
||||
return false;
|
||||
proto = proto->staticPrototype();
|
||||
}
|
||||
|
||||
*added = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -3612,6 +3622,43 @@ struct DestroyTypeNewScript
|
|||
|
||||
} // namespace
|
||||
|
||||
bool DPAConstraintInfo::finishConstraints(JSContext* cx, ObjectGroup* group) {
|
||||
for (const ProtoConstraint& constraint : protoConstraints_) {
|
||||
ObjectGroup* protoGroup = constraint.proto->group();
|
||||
|
||||
// Note: we rely on the group's type information being unchanged since
|
||||
// AddClearDefiniteGetterSetterForPrototypeChain.
|
||||
|
||||
bool unknownProperties = protoGroup->unknownProperties();
|
||||
MOZ_RELEASE_ASSERT(!unknownProperties);
|
||||
|
||||
HeapTypeSet* protoTypes =
|
||||
protoGroup->getProperty(cx, constraint.proto, constraint.id);
|
||||
MOZ_RELEASE_ASSERT(protoTypes);
|
||||
|
||||
MOZ_ASSERT(!protoTypes->nonDataProperty());
|
||||
MOZ_ASSERT(!protoTypes->nonWritableProperty());
|
||||
|
||||
if (!protoTypes->addConstraint(
|
||||
cx,
|
||||
cx->typeLifoAlloc().new_<TypeConstraintClearDefiniteGetterSetter>(
|
||||
group))) {
|
||||
ReportOutOfMemory(cx);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for (const InliningConstraint& constraint : inliningConstraints_) {
|
||||
if (!AddClearDefiniteFunctionUsesInScript(cx, group, constraint.caller,
|
||||
constraint.callee)) {
|
||||
ReportOutOfMemory(cx);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TypeNewScript::maybeAnalyze(JSContext* cx, ObjectGroup* group, bool* regenerate, bool force)
|
||||
{
|
||||
|
|
@ -3715,10 +3762,17 @@ TypeNewScript::maybeAnalyze(JSContext* cx, ObjectGroup* group, bool* regenerate,
|
|||
return false;
|
||||
|
||||
Vector<Initializer> initializerVector(cx);
|
||||
|
||||
DPAConstraintInfo constraintInfo(cx);
|
||||
|
||||
RootedPlainObject templateRoot(cx, templateObject());
|
||||
RootedFunction fun(cx, function());
|
||||
if (!jit::AnalyzeNewScriptDefiniteProperties(cx, fun, group, templateRoot, &initializerVector))
|
||||
if (!jit::AnalyzeNewScriptDefiniteProperties(cx,
|
||||
constraintInfo,
|
||||
fun,
|
||||
group,
|
||||
templateRoot,
|
||||
&initializerVector))
|
||||
return false;
|
||||
|
||||
if (!group->newScript())
|
||||
|
|
@ -3772,6 +3826,14 @@ TypeNewScript::maybeAnalyze(JSContext* cx, ObjectGroup* group, bool* regenerate,
|
|||
// The definite properties analysis found exactly the properties that
|
||||
// are held in common by the preliminary objects. No further analysis
|
||||
// is needed.
|
||||
|
||||
if (!constraintInfo.finishConstraints(cx, group)) {
|
||||
return false;
|
||||
}
|
||||
if (!group->newScript()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
group->addDefiniteProperties(cx, templateObject()->lastProperty());
|
||||
|
||||
destroyNewScript.group = nullptr;
|
||||
|
|
@ -3792,6 +3854,16 @@ TypeNewScript::maybeAnalyze(JSContext* cx, ObjectGroup* group, bool* regenerate,
|
|||
initialFlags);
|
||||
if (!initialGroup)
|
||||
return false;
|
||||
|
||||
// Add the constraints. Use the initialGroup as group referenced by the
|
||||
// constraints because that's the group that will have the TypeNewScript
|
||||
// associated with it. See the detachNewScript and setNewScript calls below.
|
||||
if (!constraintInfo.finishConstraints(cx, initialGroup)) {
|
||||
return false;
|
||||
}
|
||||
if (!group->newScript()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
initialGroup->addDefiniteProperties(cx, templateObject()->lastProperty());
|
||||
group->addDefiniteProperties(cx, prefixShape);
|
||||
|
|
|
|||
|
|
@ -789,8 +789,65 @@ class TemporaryTypeSet : public TypeSet
|
|||
TypedArraySharedness* sharedness);
|
||||
};
|
||||
|
||||
// Stack class to record information about constraints that need to be added
|
||||
// after finishing the Definite Properties Analysis. When the analysis succeeds,
|
||||
// the |finishConstraints| method must be called to add the constraints to the
|
||||
// TypeSets.
|
||||
//
|
||||
// There are two constraint types managed here:
|
||||
//
|
||||
// 1. Proto constraints for HeapTypeSets, to guard against things like getters
|
||||
// and setters on the proto chain.
|
||||
//
|
||||
// 2. Inlining constraints for StackTypeSets, to invalidate when additional
|
||||
// functions could be called at call sites where we inlined a function.
|
||||
//
|
||||
// This class uses bare GC-thing pointers because GC is suppressed when the
|
||||
// analysis runs.
|
||||
class MOZ_RAII DPAConstraintInfo {
|
||||
struct ProtoConstraint {
|
||||
JSObject* proto;
|
||||
jsid id;
|
||||
ProtoConstraint(JSObject* proto, jsid id) : proto(proto), id(id) {}
|
||||
};
|
||||
struct InliningConstraint {
|
||||
JSScript* caller;
|
||||
JSScript* callee;
|
||||
InliningConstraint(JSScript* caller, JSScript* callee)
|
||||
: caller(caller), callee(callee) {}
|
||||
};
|
||||
|
||||
JS::AutoCheckCannotGC nogc_;
|
||||
Vector<ProtoConstraint, 8> protoConstraints_;
|
||||
Vector<InliningConstraint, 4> inliningConstraints_;
|
||||
|
||||
public:
|
||||
explicit DPAConstraintInfo(JSContext* cx)
|
||||
: nogc_(cx)
|
||||
, protoConstraints_(cx)
|
||||
, inliningConstraints_(cx)
|
||||
{
|
||||
}
|
||||
|
||||
DPAConstraintInfo(const DPAConstraintInfo&) = delete;
|
||||
void operator=(const DPAConstraintInfo&) = delete;
|
||||
|
||||
MOZ_MUST_USE bool addProtoConstraint(JSObject* proto, jsid id) {
|
||||
return protoConstraints_.emplaceBack(proto, id);
|
||||
}
|
||||
MOZ_MUST_USE bool addInliningConstraint(JSScript* caller, JSScript* callee) {
|
||||
return inliningConstraints_.emplaceBack(caller, callee);
|
||||
}
|
||||
|
||||
MOZ_MUST_USE bool finishConstraints(JSContext* cx, ObjectGroup* group);
|
||||
};
|
||||
|
||||
bool
|
||||
AddClearDefiniteGetterSetterForPrototypeChain(JSContext* cx, ObjectGroup* group, HandleId id);
|
||||
AddClearDefiniteGetterSetterForPrototypeChain(JSContext* cx,
|
||||
DPAConstraintInfo& constraintInfo,
|
||||
ObjectGroup* group,
|
||||
HandleId id,
|
||||
bool* added);
|
||||
|
||||
bool
|
||||
AddClearDefiniteFunctionUsesInScript(JSContext* cx, ObjectGroup* group,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2008-2015 Mozilla Foundation
|
||||
* Copyright (c) 2019 Moonchild Productions
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
|
|
@ -44,32 +45,66 @@ struct staticJArray {
|
|||
}
|
||||
};
|
||||
|
||||
template<class T, class L>
|
||||
struct jArray {
|
||||
template <class T, class L>
|
||||
class autoJArray;
|
||||
|
||||
template <class T, class L>
|
||||
class jArray {
|
||||
friend class autoJArray<T, L>;
|
||||
|
||||
private:
|
||||
T* arr;
|
||||
|
||||
public:
|
||||
L length;
|
||||
|
||||
static jArray<T,L> newJArray(L const len) {
|
||||
MOZ_ASSERT(len >= 0, "Negative length.");
|
||||
jArray<T,L> newArray = { new T[size_t(len)], len };
|
||||
return newArray;
|
||||
}
|
||||
|
||||
static jArray<T,L> newFallibleJArray(L const len) {
|
||||
MOZ_ASSERT(len >= 0, "Negative length.");
|
||||
T* a = new (mozilla::fallible) T[size_t(len)];
|
||||
jArray<T,L> newArray = { a, a ? len : 0 };
|
||||
return newArray;
|
||||
}
|
||||
operator T*() { return arr; }
|
||||
|
||||
operator T*() {
|
||||
return arr;
|
||||
}
|
||||
|
||||
T& operator[] (L const index) {
|
||||
MOZ_ASSERT(index >= 0, "Array access with negative index.");
|
||||
MOZ_ASSERT(index < length, "Array index out of bounds.");
|
||||
return arr[index];
|
||||
}
|
||||
|
||||
void operator=(staticJArray<T,L>& other) {
|
||||
arr = (T*)other.arr;
|
||||
length = other.length;
|
||||
}
|
||||
};
|
||||
|
||||
MOZ_IMPLICIT jArray(decltype(nullptr))
|
||||
: arr(nullptr)
|
||||
, length(0)
|
||||
{
|
||||
}
|
||||
|
||||
jArray()
|
||||
: arr(nullptr)
|
||||
, length(0)
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
jArray(T* aArr, L aLength)
|
||||
: arr(aArr)
|
||||
, length(aLength)
|
||||
{
|
||||
}
|
||||
}; // class jArray
|
||||
|
||||
template<class T, class L>
|
||||
class autoJArray {
|
||||
|
|
|
|||
|
|
@ -1,59 +0,0 @@
|
|||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
libs:: translator
|
||||
|
||||
translator:: javaparser \
|
||||
; mkdir -p htmlparser/bin && \
|
||||
find htmlparser/translator-src/nu/validator/htmlparser -name "*.java" | \
|
||||
xargs javac -cp javaparser.jar -g -d htmlparser/bin && \
|
||||
jar cfm translator.jar manifest.txt -C htmlparser/bin .
|
||||
|
||||
javaparser:: \
|
||||
; mkdir -p javaparser/bin && \
|
||||
find javaparser/src -name "*.java" | \
|
||||
xargs javac -encoding ISO-8859-1 -g -d javaparser/bin && \
|
||||
jar cf javaparser.jar -C javaparser/bin .
|
||||
|
||||
sync_javaparser:: \
|
||||
; if [ ! -d javaparser/.git ] ; \
|
||||
then rm -rf javaparser ; \
|
||||
git clone https://github.com/javaparser/javaparser.git ; \
|
||||
fi ; \
|
||||
cd javaparser ; git checkout javaparser-1.0.6 ; cd ..
|
||||
|
||||
sync_htmlparser:: \
|
||||
; if [ -d htmlparser/.hg ] ; \
|
||||
then cd htmlparser ; hg pull --rebase ; cd .. ; \
|
||||
else \
|
||||
rm -rf htmlparser ; \
|
||||
hg clone https://hg.mozilla.org/projects/htmlparser ; \
|
||||
fi
|
||||
|
||||
sync:: sync_javaparser sync_htmlparser
|
||||
|
||||
translate:: translator \
|
||||
; mkdir -p ../javasrc ; \
|
||||
java -jar translator.jar \
|
||||
htmlparser/src/nu/validator/htmlparser/impl \
|
||||
.. ../nsHtml5AtomList.h
|
||||
|
||||
translate_from_snapshot:: translator \
|
||||
; mkdir -p ../javasrc ; \
|
||||
java -jar translator.jar \
|
||||
../javasrc \
|
||||
.. ../nsHtml5AtomList.h
|
||||
|
||||
named_characters:: translator \
|
||||
; java -cp translator.jar \
|
||||
nu.validator.htmlparser.generator.GenerateNamedCharactersCpp \
|
||||
named-character-references.html ../
|
||||
|
||||
clean_javaparser:: \
|
||||
; rm -rf javaparser/bin javaparser.jar
|
||||
|
||||
clean_htmlparser:: \
|
||||
; rm -rf htmlparser/bin translator.jar
|
||||
|
||||
clean:: clean_javaparser clean_htmlparser
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
If this is your first time building the HTML5 parser, you need to execute the
|
||||
following commands (from this directory) to bootstrap the translation:
|
||||
|
||||
make sync # fetch remote source files and licenses
|
||||
make translate # perform the Java-to-C++ translation from the remote
|
||||
# sources
|
||||
make named_characters # Generate tables for named character tokenization
|
||||
|
||||
If you make changes to the translator or the javaparser, you can rebuild by
|
||||
retyping 'make' in this directory. If you make changes to the HTML5 Java
|
||||
implementation, you can retranslate the Java sources from the htmlparser
|
||||
repository by retyping 'make translate' in this directory.
|
||||
|
||||
The makefile supports the following targets:
|
||||
|
||||
sync_htmlparser:
|
||||
Retrieves the HTML parser and Java to C++ translator sources from Mozilla's
|
||||
htmlparser repository.
|
||||
sync_javaparser:
|
||||
Retrieves the javaparser sources from GitHub.
|
||||
sync:
|
||||
Runs both sync_javaparser and sync_htmlparser.
|
||||
javaparser:
|
||||
Builds the javaparser library retrieved earlier by sync_javaparser.
|
||||
translator:
|
||||
Runs the javaparser target and then builds the Java to C++ translator from
|
||||
sources retrieved earlier by sync_htmlparser.
|
||||
libs:
|
||||
The default target. Alias for translator
|
||||
translate:
|
||||
Runs the translator target and then translates the HTML parser sources
|
||||
retrieved by sync_htmlparser copying the Java sources to ../javasrc.
|
||||
translate_from_snapshot:
|
||||
Runs the translator target and then translates the HTML parser sources
|
||||
stored in ../javasrc.
|
||||
named_characters:
|
||||
Generates data tables for named character tokenization.
|
||||
clean_javaparser:
|
||||
Removes the build products of the javaparser target.
|
||||
clean_htmlparser:
|
||||
Removes the build products of the translator target.
|
||||
clean:
|
||||
Runs both clean_javaparser and clean_htmlparser.
|
||||
|
||||
Ben Newman (23 September 2009)
|
||||
Henri Sivonen (11 August 2016)
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
Main-Class: nu.validator.htmlparser.cpptranslate.Main
|
||||
Class-Path: javaparser.jar
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -1,618 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2007 Henri Sivonen
|
||||
* Copyright (c) 2008-2011 Mozilla Foundation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package nu.validator.htmlparser.impl;
|
||||
|
||||
import nu.validator.htmlparser.annotation.Auto;
|
||||
import nu.validator.htmlparser.annotation.IdType;
|
||||
import nu.validator.htmlparser.annotation.Local;
|
||||
import nu.validator.htmlparser.annotation.NsUri;
|
||||
import nu.validator.htmlparser.annotation.Prefix;
|
||||
import nu.validator.htmlparser.annotation.QName;
|
||||
import nu.validator.htmlparser.common.Interner;
|
||||
import nu.validator.htmlparser.common.XmlViolationPolicy;
|
||||
|
||||
import org.xml.sax.Attributes;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
/**
|
||||
* Be careful with this class. QName is the name in from HTML tokenization.
|
||||
* Otherwise, please refer to the interface doc.
|
||||
*
|
||||
* @version $Id: AttributesImpl.java 206 2008-03-20 14:09:29Z hsivonen $
|
||||
* @author hsivonen
|
||||
*/
|
||||
public final class HtmlAttributes implements Attributes {
|
||||
|
||||
// [NOCPP[
|
||||
|
||||
private static final AttributeName[] EMPTY_ATTRIBUTENAMES = new AttributeName[0];
|
||||
|
||||
private static final String[] EMPTY_STRINGS = new String[0];
|
||||
|
||||
// ]NOCPP]
|
||||
|
||||
public static final HtmlAttributes EMPTY_ATTRIBUTES = new HtmlAttributes(
|
||||
AttributeName.HTML);
|
||||
|
||||
private int mode;
|
||||
|
||||
private int length;
|
||||
|
||||
private @Auto AttributeName[] names;
|
||||
|
||||
private @Auto String[] values; // XXX perhaps make this @NoLength?
|
||||
|
||||
// CPPONLY: private @Auto int[] lines; // XXX perhaps make this @NoLength?
|
||||
|
||||
// [NOCPP[
|
||||
|
||||
private String idValue;
|
||||
|
||||
private int xmlnsLength;
|
||||
|
||||
private AttributeName[] xmlnsNames;
|
||||
|
||||
private String[] xmlnsValues;
|
||||
|
||||
// ]NOCPP]
|
||||
|
||||
public HtmlAttributes(int mode) {
|
||||
this.mode = mode;
|
||||
this.length = 0;
|
||||
/*
|
||||
* The length of 5 covers covers 98.3% of elements
|
||||
* according to Hixie, but lets round to the next power of two for
|
||||
* jemalloc.
|
||||
*/
|
||||
this.names = new AttributeName[8];
|
||||
this.values = new String[8];
|
||||
// CPPONLY: this.lines = new int[8];
|
||||
|
||||
// [NOCPP[
|
||||
|
||||
this.idValue = null;
|
||||
|
||||
this.xmlnsLength = 0;
|
||||
|
||||
this.xmlnsNames = HtmlAttributes.EMPTY_ATTRIBUTENAMES;
|
||||
|
||||
this.xmlnsValues = HtmlAttributes.EMPTY_STRINGS;
|
||||
|
||||
// ]NOCPP]
|
||||
}
|
||||
/*
|
||||
public HtmlAttributes(HtmlAttributes other) {
|
||||
this.mode = other.mode;
|
||||
this.length = other.length;
|
||||
this.names = new AttributeName[other.length];
|
||||
this.values = new String[other.length];
|
||||
// [NOCPP[
|
||||
this.idValue = other.idValue;
|
||||
this.xmlnsLength = other.xmlnsLength;
|
||||
this.xmlnsNames = new AttributeName[other.xmlnsLength];
|
||||
this.xmlnsValues = new String[other.xmlnsLength];
|
||||
// ]NOCPP]
|
||||
}
|
||||
*/
|
||||
|
||||
void destructor() {
|
||||
clear(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Only use with a static argument
|
||||
*
|
||||
* @param name
|
||||
* @return
|
||||
*/
|
||||
public int getIndex(AttributeName name) {
|
||||
for (int i = 0; i < length; i++) {
|
||||
if (names[i] == name) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Only use with static argument.
|
||||
*
|
||||
* @see org.xml.sax.Attributes#getValue(java.lang.String)
|
||||
*/
|
||||
public String getValue(AttributeName name) {
|
||||
int index = getIndex(name);
|
||||
if (index == -1) {
|
||||
return null;
|
||||
} else {
|
||||
return getValueNoBoundsCheck(index);
|
||||
}
|
||||
}
|
||||
|
||||
public int getLength() {
|
||||
return length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Variant of <code>getLocalName(int index)</code> without bounds check.
|
||||
* @param index a valid attribute index
|
||||
* @return the local name at index
|
||||
*/
|
||||
public @Local String getLocalNameNoBoundsCheck(int index) {
|
||||
// CPPONLY: assert index < length && index >= 0: "Index out of bounds";
|
||||
return names[index].getLocal(mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Variant of <code>getURI(int index)</code> without bounds check.
|
||||
* @param index a valid attribute index
|
||||
* @return the namespace URI at index
|
||||
*/
|
||||
public @NsUri String getURINoBoundsCheck(int index) {
|
||||
// CPPONLY: assert index < length && index >= 0: "Index out of bounds";
|
||||
return names[index].getUri(mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Variant of <code>getPrefix(int index)</code> without bounds check.
|
||||
* @param index a valid attribute index
|
||||
* @return the namespace prefix at index
|
||||
*/
|
||||
public @Prefix String getPrefixNoBoundsCheck(int index) {
|
||||
// CPPONLY: assert index < length && index >= 0: "Index out of bounds";
|
||||
return names[index].getPrefix(mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Variant of <code>getValue(int index)</code> without bounds check.
|
||||
* @param index a valid attribute index
|
||||
* @return the attribute value at index
|
||||
*/
|
||||
public String getValueNoBoundsCheck(int index) {
|
||||
// CPPONLY: assert index < length && index >= 0: "Index out of bounds";
|
||||
return values[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* Variant of <code>getAttributeName(int index)</code> without bounds check.
|
||||
* @param index a valid attribute index
|
||||
* @return the attribute name at index
|
||||
*/
|
||||
public AttributeName getAttributeNameNoBoundsCheck(int index) {
|
||||
// CPPONLY: assert index < length && index >= 0: "Index out of bounds";
|
||||
return names[index];
|
||||
}
|
||||
|
||||
// CPPONLY: /**
|
||||
// CPPONLY: * Obtains a line number without bounds check.
|
||||
// CPPONLY: * @param index a valid attribute index
|
||||
// CPPONLY: * @return the line number at index or -1 if unknown
|
||||
// CPPONLY: */
|
||||
// CPPONLY: public int getLineNoBoundsCheck(int index) {
|
||||
// CPPONLY: assert index < length && index >= 0: "Index out of bounds";
|
||||
// CPPONLY: return lines[index];
|
||||
// CPPONLY: }
|
||||
|
||||
// [NOCPP[
|
||||
|
||||
/**
|
||||
* Variant of <code>getQName(int index)</code> without bounds check.
|
||||
* @param index a valid attribute index
|
||||
* @return the QName at index
|
||||
*/
|
||||
public @QName String getQNameNoBoundsCheck(int index) {
|
||||
return names[index].getQName(mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Variant of <code>getType(int index)</code> without bounds check.
|
||||
* @param index a valid attribute index
|
||||
* @return the attribute type at index
|
||||
*/
|
||||
public @IdType String getTypeNoBoundsCheck(int index) {
|
||||
return (names[index] == AttributeName.ID) ? "ID" : "CDATA";
|
||||
}
|
||||
|
||||
public int getIndex(String qName) {
|
||||
for (int i = 0; i < length; i++) {
|
||||
if (names[i].getQName(mode).equals(qName)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public int getIndex(String uri, String localName) {
|
||||
for (int i = 0; i < length; i++) {
|
||||
if (names[i].getLocal(mode).equals(localName)
|
||||
&& names[i].getUri(mode).equals(uri)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public @IdType String getType(String qName) {
|
||||
int index = getIndex(qName);
|
||||
if (index == -1) {
|
||||
return null;
|
||||
} else {
|
||||
return getType(index);
|
||||
}
|
||||
}
|
||||
|
||||
public @IdType String getType(String uri, String localName) {
|
||||
int index = getIndex(uri, localName);
|
||||
if (index == -1) {
|
||||
return null;
|
||||
} else {
|
||||
return getType(index);
|
||||
}
|
||||
}
|
||||
|
||||
public String getValue(String qName) {
|
||||
int index = getIndex(qName);
|
||||
if (index == -1) {
|
||||
return null;
|
||||
} else {
|
||||
return getValue(index);
|
||||
}
|
||||
}
|
||||
|
||||
public String getValue(String uri, String localName) {
|
||||
int index = getIndex(uri, localName);
|
||||
if (index == -1) {
|
||||
return null;
|
||||
} else {
|
||||
return getValue(index);
|
||||
}
|
||||
}
|
||||
|
||||
public @Local String getLocalName(int index) {
|
||||
if (index < length && index >= 0) {
|
||||
return names[index].getLocal(mode);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public @QName String getQName(int index) {
|
||||
if (index < length && index >= 0) {
|
||||
return names[index].getQName(mode);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public @IdType String getType(int index) {
|
||||
if (index < length && index >= 0) {
|
||||
return (names[index] == AttributeName.ID) ? "ID" : "CDATA";
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public AttributeName getAttributeName(int index) {
|
||||
if (index < length && index >= 0) {
|
||||
return names[index];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public @NsUri String getURI(int index) {
|
||||
if (index < length && index >= 0) {
|
||||
return names[index].getUri(mode);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public @Prefix String getPrefix(int index) {
|
||||
if (index < length && index >= 0) {
|
||||
return names[index].getPrefix(mode);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public String getValue(int index) {
|
||||
if (index < length && index >= 0) {
|
||||
return values[index];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return idValue;
|
||||
}
|
||||
|
||||
public int getXmlnsLength() {
|
||||
return xmlnsLength;
|
||||
}
|
||||
|
||||
public @Local String getXmlnsLocalName(int index) {
|
||||
if (index < xmlnsLength && index >= 0) {
|
||||
return xmlnsNames[index].getLocal(mode);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public @NsUri String getXmlnsURI(int index) {
|
||||
if (index < xmlnsLength && index >= 0) {
|
||||
return xmlnsNames[index].getUri(mode);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public String getXmlnsValue(int index) {
|
||||
if (index < xmlnsLength && index >= 0) {
|
||||
return xmlnsValues[index];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public int getXmlnsIndex(AttributeName name) {
|
||||
for (int i = 0; i < xmlnsLength; i++) {
|
||||
if (xmlnsNames[i] == name) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public String getXmlnsValue(AttributeName name) {
|
||||
int index = getXmlnsIndex(name);
|
||||
if (index == -1) {
|
||||
return null;
|
||||
} else {
|
||||
return getXmlnsValue(index);
|
||||
}
|
||||
}
|
||||
|
||||
public AttributeName getXmlnsAttributeName(int index) {
|
||||
if (index < xmlnsLength && index >= 0) {
|
||||
return xmlnsNames[index];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// ]NOCPP]
|
||||
|
||||
void addAttribute(AttributeName name, String value
|
||||
// [NOCPP[
|
||||
, XmlViolationPolicy xmlnsPolicy
|
||||
// ]NOCPP]
|
||||
// CPPONLY: , int line
|
||||
) throws SAXException {
|
||||
// [NOCPP[
|
||||
if (name == AttributeName.ID) {
|
||||
idValue = value;
|
||||
}
|
||||
|
||||
if (name.isXmlns()) {
|
||||
if (xmlnsNames.length == xmlnsLength) {
|
||||
int newLen = xmlnsLength == 0 ? 2 : xmlnsLength << 1;
|
||||
AttributeName[] newNames = new AttributeName[newLen];
|
||||
System.arraycopy(xmlnsNames, 0, newNames, 0, xmlnsNames.length);
|
||||
xmlnsNames = newNames;
|
||||
String[] newValues = new String[newLen];
|
||||
System.arraycopy(xmlnsValues, 0, newValues, 0, xmlnsValues.length);
|
||||
xmlnsValues = newValues;
|
||||
}
|
||||
xmlnsNames[xmlnsLength] = name;
|
||||
xmlnsValues[xmlnsLength] = value;
|
||||
xmlnsLength++;
|
||||
switch (xmlnsPolicy) {
|
||||
case FATAL:
|
||||
// this is ugly
|
||||
throw new SAXException("Saw an xmlns attribute.");
|
||||
case ALTER_INFOSET:
|
||||
return;
|
||||
case ALLOW:
|
||||
// fall through
|
||||
}
|
||||
}
|
||||
|
||||
// ]NOCPP]
|
||||
|
||||
if (names.length == length) {
|
||||
int newLen = length << 1; // The first growth covers virtually
|
||||
// 100% of elements according to
|
||||
// Hixie
|
||||
AttributeName[] newNames = new AttributeName[newLen];
|
||||
System.arraycopy(names, 0, newNames, 0, names.length);
|
||||
names = newNames;
|
||||
String[] newValues = new String[newLen];
|
||||
System.arraycopy(values, 0, newValues, 0, values.length);
|
||||
values = newValues;
|
||||
// CPPONLY: int[] newLines = new int[newLen];
|
||||
// CPPONLY: System.arraycopy(lines, 0, newLines, 0, lines.length);
|
||||
// CPPONLY: lines = newLines;
|
||||
}
|
||||
names[length] = name;
|
||||
values[length] = value;
|
||||
// CPPONLY: lines[length] = line;
|
||||
length++;
|
||||
}
|
||||
|
||||
void clear(int m) {
|
||||
for (int i = 0; i < length; i++) {
|
||||
names[i].release();
|
||||
names[i] = null;
|
||||
Portability.releaseString(values[i]);
|
||||
values[i] = null;
|
||||
}
|
||||
length = 0;
|
||||
mode = m;
|
||||
// [NOCPP[
|
||||
idValue = null;
|
||||
for (int i = 0; i < xmlnsLength; i++) {
|
||||
xmlnsNames[i] = null;
|
||||
xmlnsValues[i] = null;
|
||||
}
|
||||
xmlnsLength = 0;
|
||||
// ]NOCPP]
|
||||
}
|
||||
|
||||
/**
|
||||
* This is used in C++ to release special <code>isindex</code>
|
||||
* attribute values whose ownership is not transferred.
|
||||
*/
|
||||
void releaseValue(int i) {
|
||||
Portability.releaseString(values[i]);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is only used for <code>AttributeName</code> ownership transfer
|
||||
* in the isindex case to avoid freeing custom names twice in C++.
|
||||
*/
|
||||
void clearWithoutReleasingContents() {
|
||||
for (int i = 0; i < length; i++) {
|
||||
names[i] = null;
|
||||
values[i] = null;
|
||||
}
|
||||
length = 0;
|
||||
}
|
||||
|
||||
boolean contains(AttributeName name) {
|
||||
for (int i = 0; i < length; i++) {
|
||||
if (name.equalsAnother(names[i])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// [NOCPP[
|
||||
for (int i = 0; i < xmlnsLength; i++) {
|
||||
if (name.equalsAnother(xmlnsNames[i])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// ]NOCPP]
|
||||
return false;
|
||||
}
|
||||
|
||||
public void adjustForMath() {
|
||||
mode = AttributeName.MATHML;
|
||||
}
|
||||
|
||||
public void adjustForSvg() {
|
||||
mode = AttributeName.SVG;
|
||||
}
|
||||
|
||||
public HtmlAttributes cloneAttributes(Interner interner)
|
||||
throws SAXException {
|
||||
assert (length == 0
|
||||
// [NOCPP[
|
||||
&& xmlnsLength == 0
|
||||
// ]NOCPP]
|
||||
)
|
||||
|| mode == 0 || mode == 3;
|
||||
HtmlAttributes clone = new HtmlAttributes(0);
|
||||
for (int i = 0; i < length; i++) {
|
||||
clone.addAttribute(names[i].cloneAttributeName(interner),
|
||||
Portability.newStringFromString(values[i])
|
||||
// [NOCPP[
|
||||
, XmlViolationPolicy.ALLOW
|
||||
// ]NOCPP]
|
||||
// CPPONLY: , lines[i]
|
||||
);
|
||||
}
|
||||
// [NOCPP[
|
||||
for (int i = 0; i < xmlnsLength; i++) {
|
||||
clone.addAttribute(xmlnsNames[i], xmlnsValues[i],
|
||||
XmlViolationPolicy.ALLOW);
|
||||
}
|
||||
// ]NOCPP]
|
||||
return clone; // XXX!!!
|
||||
}
|
||||
|
||||
public boolean equalsAnother(HtmlAttributes other) {
|
||||
assert mode == 0 || mode == 3 : "Trying to compare attributes in foreign content.";
|
||||
int otherLength = other.getLength();
|
||||
if (length != otherLength) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < length; i++) {
|
||||
// Work around the limitations of C++
|
||||
boolean found = false;
|
||||
// The comparing just the local names is OK, since these attribute
|
||||
// holders are both supposed to belong to HTML formatting elements
|
||||
@Local String ownLocal = names[i].getLocal(AttributeName.HTML);
|
||||
for (int j = 0; j < otherLength; j++) {
|
||||
if (ownLocal == other.names[j].getLocal(AttributeName.HTML)) {
|
||||
found = true;
|
||||
if (!Portability.stringEqualsString(values[i], other.values[j])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// [NOCPP[
|
||||
|
||||
void processNonNcNames(TreeBuilder<?> treeBuilder, XmlViolationPolicy namePolicy) throws SAXException {
|
||||
for (int i = 0; i < length; i++) {
|
||||
AttributeName attName = names[i];
|
||||
if (!attName.isNcName(mode)) {
|
||||
String name = attName.getLocal(mode);
|
||||
switch (namePolicy) {
|
||||
case ALTER_INFOSET:
|
||||
names[i] = AttributeName.create(NCName.escapeName(name));
|
||||
// fall through
|
||||
case ALLOW:
|
||||
if (attName != AttributeName.XML_LANG) {
|
||||
treeBuilder.warn("Attribute \u201C" + name + "\u201D is not serializable as XML 1.0.");
|
||||
}
|
||||
break;
|
||||
case FATAL:
|
||||
treeBuilder.fatal("Attribute \u201C" + name + "\u201D is not serializable as XML 1.0.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void merge(HtmlAttributes attributes) throws SAXException {
|
||||
int len = attributes.getLength();
|
||||
for (int i = 0; i < len; i++) {
|
||||
AttributeName name = attributes.getAttributeNameNoBoundsCheck(i);
|
||||
if (!contains(name)) {
|
||||
addAttribute(name, attributes.getValueNoBoundsCheck(i), XmlViolationPolicy.ALLOW);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ]NOCPP]
|
||||
|
||||
}
|
||||
|
|
@ -1,854 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2007 Henri Sivonen
|
||||
* Copyright (c) 2008-2015 Mozilla Foundation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package nu.validator.htmlparser.impl;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import nu.validator.htmlparser.annotation.Auto;
|
||||
import nu.validator.htmlparser.annotation.Inline;
|
||||
import nu.validator.htmlparser.common.ByteReadable;
|
||||
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
public abstract class MetaScanner {
|
||||
|
||||
/**
|
||||
* Constant for "charset".
|
||||
*/
|
||||
private static final char[] CHARSET = { 'h', 'a', 'r', 's', 'e', 't' };
|
||||
|
||||
/**
|
||||
* Constant for "content".
|
||||
*/
|
||||
private static final char[] CONTENT = { 'o', 'n', 't', 'e', 'n', 't' };
|
||||
|
||||
/**
|
||||
* Constant for "http-equiv".
|
||||
*/
|
||||
private static final char[] HTTP_EQUIV = { 't', 't', 'p', '-', 'e', 'q',
|
||||
'u', 'i', 'v' };
|
||||
|
||||
/**
|
||||
* Constant for "content-type".
|
||||
*/
|
||||
private static final char[] CONTENT_TYPE = { 'c', 'o', 'n', 't', 'e', 'n',
|
||||
't', '-', 't', 'y', 'p', 'e' };
|
||||
|
||||
private static final int NO = 0;
|
||||
|
||||
private static final int M = 1;
|
||||
|
||||
private static final int E = 2;
|
||||
|
||||
private static final int T = 3;
|
||||
|
||||
private static final int A = 4;
|
||||
|
||||
private static final int DATA = 0;
|
||||
|
||||
private static final int TAG_OPEN = 1;
|
||||
|
||||
private static final int SCAN_UNTIL_GT = 2;
|
||||
|
||||
private static final int TAG_NAME = 3;
|
||||
|
||||
private static final int BEFORE_ATTRIBUTE_NAME = 4;
|
||||
|
||||
private static final int ATTRIBUTE_NAME = 5;
|
||||
|
||||
private static final int AFTER_ATTRIBUTE_NAME = 6;
|
||||
|
||||
private static final int BEFORE_ATTRIBUTE_VALUE = 7;
|
||||
|
||||
private static final int ATTRIBUTE_VALUE_DOUBLE_QUOTED = 8;
|
||||
|
||||
private static final int ATTRIBUTE_VALUE_SINGLE_QUOTED = 9;
|
||||
|
||||
private static final int ATTRIBUTE_VALUE_UNQUOTED = 10;
|
||||
|
||||
private static final int AFTER_ATTRIBUTE_VALUE_QUOTED = 11;
|
||||
|
||||
private static final int MARKUP_DECLARATION_OPEN = 13;
|
||||
|
||||
private static final int MARKUP_DECLARATION_HYPHEN = 14;
|
||||
|
||||
private static final int COMMENT_START = 15;
|
||||
|
||||
private static final int COMMENT_START_DASH = 16;
|
||||
|
||||
private static final int COMMENT = 17;
|
||||
|
||||
private static final int COMMENT_END_DASH = 18;
|
||||
|
||||
private static final int COMMENT_END = 19;
|
||||
|
||||
private static final int SELF_CLOSING_START_TAG = 20;
|
||||
|
||||
private static final int HTTP_EQUIV_NOT_SEEN = 0;
|
||||
|
||||
private static final int HTTP_EQUIV_CONTENT_TYPE = 1;
|
||||
|
||||
private static final int HTTP_EQUIV_OTHER = 2;
|
||||
|
||||
/**
|
||||
* The data source.
|
||||
*/
|
||||
protected ByteReadable readable;
|
||||
|
||||
/**
|
||||
* The state of the state machine that recognizes the tag name "meta".
|
||||
*/
|
||||
private int metaState = NO;
|
||||
|
||||
/**
|
||||
* The current position in recognizing the attribute name "content".
|
||||
*/
|
||||
private int contentIndex = Integer.MAX_VALUE;
|
||||
|
||||
/**
|
||||
* The current position in recognizing the attribute name "charset".
|
||||
*/
|
||||
private int charsetIndex = Integer.MAX_VALUE;
|
||||
|
||||
/**
|
||||
* The current position in recognizing the attribute name "http-equive".
|
||||
*/
|
||||
private int httpEquivIndex = Integer.MAX_VALUE;
|
||||
|
||||
/**
|
||||
* The current position in recognizing the attribute value "content-type".
|
||||
*/
|
||||
private int contentTypeIndex = Integer.MAX_VALUE;
|
||||
|
||||
/**
|
||||
* The tokenizer state.
|
||||
*/
|
||||
protected int stateSave = DATA;
|
||||
|
||||
/**
|
||||
* The currently filled length of strBuf.
|
||||
*/
|
||||
private int strBufLen;
|
||||
|
||||
/**
|
||||
* Accumulation buffer for attribute values.
|
||||
*/
|
||||
private @Auto char[] strBuf;
|
||||
|
||||
private String content;
|
||||
|
||||
private String charset;
|
||||
|
||||
private int httpEquivState;
|
||||
|
||||
// CPPONLY: private TreeBuilder treeBuilder;
|
||||
|
||||
public MetaScanner(
|
||||
// CPPONLY: TreeBuilder tb
|
||||
) {
|
||||
this.readable = null;
|
||||
this.metaState = NO;
|
||||
this.contentIndex = Integer.MAX_VALUE;
|
||||
this.charsetIndex = Integer.MAX_VALUE;
|
||||
this.httpEquivIndex = Integer.MAX_VALUE;
|
||||
this.contentTypeIndex = Integer.MAX_VALUE;
|
||||
this.stateSave = DATA;
|
||||
this.strBufLen = 0;
|
||||
this.strBuf = new char[36];
|
||||
this.content = null;
|
||||
this.charset = null;
|
||||
this.httpEquivState = HTTP_EQUIV_NOT_SEEN;
|
||||
// CPPONLY: this.treeBuilder = tb;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused") private void destructor() {
|
||||
Portability.releaseString(content);
|
||||
Portability.releaseString(charset);
|
||||
}
|
||||
|
||||
// [NOCPP[
|
||||
|
||||
/**
|
||||
* Reads a byte from the data source.
|
||||
*
|
||||
* -1 means end.
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
protected int read() throws IOException {
|
||||
return readable.readByte();
|
||||
}
|
||||
|
||||
// ]NOCPP]
|
||||
|
||||
// WARNING When editing this, makes sure the bytecode length shown by javap
|
||||
// stays under 8000 bytes!
|
||||
/**
|
||||
* The runs the meta scanning algorithm.
|
||||
*/
|
||||
protected final void stateLoop(int state)
|
||||
throws SAXException, IOException {
|
||||
int c = -1;
|
||||
boolean reconsume = false;
|
||||
stateloop: for (;;) {
|
||||
switch (state) {
|
||||
case DATA:
|
||||
dataloop: for (;;) {
|
||||
if (reconsume) {
|
||||
reconsume = false;
|
||||
} else {
|
||||
c = read();
|
||||
}
|
||||
switch (c) {
|
||||
case -1:
|
||||
break stateloop;
|
||||
case '<':
|
||||
state = MetaScanner.TAG_OPEN;
|
||||
break dataloop; // FALL THROUGH continue
|
||||
// stateloop;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// WARNING FALLTHRU CASE TRANSITION: DON'T REORDER
|
||||
case TAG_OPEN:
|
||||
tagopenloop: for (;;) {
|
||||
c = read();
|
||||
switch (c) {
|
||||
case -1:
|
||||
break stateloop;
|
||||
case 'm':
|
||||
case 'M':
|
||||
metaState = M;
|
||||
state = MetaScanner.TAG_NAME;
|
||||
break tagopenloop;
|
||||
// continue stateloop;
|
||||
case '!':
|
||||
state = MetaScanner.MARKUP_DECLARATION_OPEN;
|
||||
continue stateloop;
|
||||
case '?':
|
||||
case '/':
|
||||
state = MetaScanner.SCAN_UNTIL_GT;
|
||||
continue stateloop;
|
||||
case '>':
|
||||
state = MetaScanner.DATA;
|
||||
continue stateloop;
|
||||
default:
|
||||
if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) {
|
||||
metaState = NO;
|
||||
state = MetaScanner.TAG_NAME;
|
||||
break tagopenloop;
|
||||
// continue stateloop;
|
||||
}
|
||||
state = MetaScanner.DATA;
|
||||
reconsume = true;
|
||||
continue stateloop;
|
||||
}
|
||||
}
|
||||
// FALL THROUGH DON'T REORDER
|
||||
case TAG_NAME:
|
||||
tagnameloop: for (;;) {
|
||||
c = read();
|
||||
switch (c) {
|
||||
case -1:
|
||||
break stateloop;
|
||||
case ' ':
|
||||
case '\t':
|
||||
case '\n':
|
||||
case '\u000C':
|
||||
state = MetaScanner.BEFORE_ATTRIBUTE_NAME;
|
||||
break tagnameloop;
|
||||
// continue stateloop;
|
||||
case '/':
|
||||
state = MetaScanner.SELF_CLOSING_START_TAG;
|
||||
continue stateloop;
|
||||
case '>':
|
||||
state = MetaScanner.DATA;
|
||||
continue stateloop;
|
||||
case 'e':
|
||||
case 'E':
|
||||
if (metaState == M) {
|
||||
metaState = E;
|
||||
} else {
|
||||
metaState = NO;
|
||||
}
|
||||
continue;
|
||||
case 't':
|
||||
case 'T':
|
||||
if (metaState == E) {
|
||||
metaState = T;
|
||||
} else {
|
||||
metaState = NO;
|
||||
}
|
||||
continue;
|
||||
case 'a':
|
||||
case 'A':
|
||||
if (metaState == T) {
|
||||
metaState = A;
|
||||
} else {
|
||||
metaState = NO;
|
||||
}
|
||||
continue;
|
||||
default:
|
||||
metaState = NO;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// FALLTHRU DON'T REORDER
|
||||
case BEFORE_ATTRIBUTE_NAME:
|
||||
beforeattributenameloop: for (;;) {
|
||||
if (reconsume) {
|
||||
reconsume = false;
|
||||
} else {
|
||||
c = read();
|
||||
}
|
||||
/*
|
||||
* Consume the next input character:
|
||||
*/
|
||||
switch (c) {
|
||||
case -1:
|
||||
break stateloop;
|
||||
case ' ':
|
||||
case '\t':
|
||||
case '\n':
|
||||
case '\u000C':
|
||||
continue;
|
||||
case '/':
|
||||
state = MetaScanner.SELF_CLOSING_START_TAG;
|
||||
continue stateloop;
|
||||
case '>':
|
||||
if (handleTag()) {
|
||||
break stateloop;
|
||||
}
|
||||
state = DATA;
|
||||
continue stateloop;
|
||||
case 'c':
|
||||
case 'C':
|
||||
contentIndex = 0;
|
||||
charsetIndex = 0;
|
||||
httpEquivIndex = Integer.MAX_VALUE;
|
||||
contentTypeIndex = Integer.MAX_VALUE;
|
||||
state = MetaScanner.ATTRIBUTE_NAME;
|
||||
break beforeattributenameloop;
|
||||
case 'h':
|
||||
case 'H':
|
||||
contentIndex = Integer.MAX_VALUE;
|
||||
charsetIndex = Integer.MAX_VALUE;
|
||||
httpEquivIndex = 0;
|
||||
contentTypeIndex = Integer.MAX_VALUE;
|
||||
state = MetaScanner.ATTRIBUTE_NAME;
|
||||
break beforeattributenameloop;
|
||||
default:
|
||||
contentIndex = Integer.MAX_VALUE;
|
||||
charsetIndex = Integer.MAX_VALUE;
|
||||
httpEquivIndex = Integer.MAX_VALUE;
|
||||
contentTypeIndex = Integer.MAX_VALUE;
|
||||
state = MetaScanner.ATTRIBUTE_NAME;
|
||||
break beforeattributenameloop;
|
||||
// continue stateloop;
|
||||
}
|
||||
}
|
||||
// FALLTHRU DON'T REORDER
|
||||
case ATTRIBUTE_NAME:
|
||||
attributenameloop: for (;;) {
|
||||
c = read();
|
||||
switch (c) {
|
||||
case -1:
|
||||
break stateloop;
|
||||
case ' ':
|
||||
case '\t':
|
||||
case '\n':
|
||||
case '\u000C':
|
||||
state = MetaScanner.AFTER_ATTRIBUTE_NAME;
|
||||
continue stateloop;
|
||||
case '/':
|
||||
state = MetaScanner.SELF_CLOSING_START_TAG;
|
||||
continue stateloop;
|
||||
case '=':
|
||||
strBufLen = 0;
|
||||
contentTypeIndex = 0;
|
||||
state = MetaScanner.BEFORE_ATTRIBUTE_VALUE;
|
||||
break attributenameloop;
|
||||
// continue stateloop;
|
||||
case '>':
|
||||
if (handleTag()) {
|
||||
break stateloop;
|
||||
}
|
||||
state = MetaScanner.DATA;
|
||||
continue stateloop;
|
||||
default:
|
||||
if (metaState == A) {
|
||||
if (c >= 'A' && c <= 'Z') {
|
||||
c += 0x20;
|
||||
}
|
||||
if (contentIndex < CONTENT.length && c == CONTENT[contentIndex]) {
|
||||
++contentIndex;
|
||||
} else {
|
||||
contentIndex = Integer.MAX_VALUE;
|
||||
}
|
||||
if (charsetIndex < CHARSET.length && c == CHARSET[charsetIndex]) {
|
||||
++charsetIndex;
|
||||
} else {
|
||||
charsetIndex = Integer.MAX_VALUE;
|
||||
}
|
||||
if (httpEquivIndex < HTTP_EQUIV.length && c == HTTP_EQUIV[httpEquivIndex]) {
|
||||
++httpEquivIndex;
|
||||
} else {
|
||||
httpEquivIndex = Integer.MAX_VALUE;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// FALLTHRU DON'T REORDER
|
||||
case BEFORE_ATTRIBUTE_VALUE:
|
||||
beforeattributevalueloop: for (;;) {
|
||||
c = read();
|
||||
switch (c) {
|
||||
case -1:
|
||||
break stateloop;
|
||||
case ' ':
|
||||
case '\t':
|
||||
case '\n':
|
||||
case '\u000C':
|
||||
continue;
|
||||
case '"':
|
||||
state = MetaScanner.ATTRIBUTE_VALUE_DOUBLE_QUOTED;
|
||||
break beforeattributevalueloop;
|
||||
// continue stateloop;
|
||||
case '\'':
|
||||
state = MetaScanner.ATTRIBUTE_VALUE_SINGLE_QUOTED;
|
||||
continue stateloop;
|
||||
case '>':
|
||||
if (handleTag()) {
|
||||
break stateloop;
|
||||
}
|
||||
state = MetaScanner.DATA;
|
||||
continue stateloop;
|
||||
default:
|
||||
handleCharInAttributeValue(c);
|
||||
state = MetaScanner.ATTRIBUTE_VALUE_UNQUOTED;
|
||||
continue stateloop;
|
||||
}
|
||||
}
|
||||
// FALLTHRU DON'T REORDER
|
||||
case ATTRIBUTE_VALUE_DOUBLE_QUOTED:
|
||||
attributevaluedoublequotedloop: for (;;) {
|
||||
if (reconsume) {
|
||||
reconsume = false;
|
||||
} else {
|
||||
c = read();
|
||||
}
|
||||
switch (c) {
|
||||
case -1:
|
||||
break stateloop;
|
||||
case '"':
|
||||
handleAttributeValue();
|
||||
state = MetaScanner.AFTER_ATTRIBUTE_VALUE_QUOTED;
|
||||
break attributevaluedoublequotedloop;
|
||||
// continue stateloop;
|
||||
default:
|
||||
handleCharInAttributeValue(c);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// FALLTHRU DON'T REORDER
|
||||
case AFTER_ATTRIBUTE_VALUE_QUOTED:
|
||||
afterattributevaluequotedloop: for (;;) {
|
||||
c = read();
|
||||
switch (c) {
|
||||
case -1:
|
||||
break stateloop;
|
||||
case ' ':
|
||||
case '\t':
|
||||
case '\n':
|
||||
case '\u000C':
|
||||
state = MetaScanner.BEFORE_ATTRIBUTE_NAME;
|
||||
continue stateloop;
|
||||
case '/':
|
||||
state = MetaScanner.SELF_CLOSING_START_TAG;
|
||||
break afterattributevaluequotedloop;
|
||||
// continue stateloop;
|
||||
case '>':
|
||||
if (handleTag()) {
|
||||
break stateloop;
|
||||
}
|
||||
state = MetaScanner.DATA;
|
||||
continue stateloop;
|
||||
default:
|
||||
state = MetaScanner.BEFORE_ATTRIBUTE_NAME;
|
||||
reconsume = true;
|
||||
continue stateloop;
|
||||
}
|
||||
}
|
||||
// FALLTHRU DON'T REORDER
|
||||
case SELF_CLOSING_START_TAG:
|
||||
c = read();
|
||||
switch (c) {
|
||||
case -1:
|
||||
break stateloop;
|
||||
case '>':
|
||||
if (handleTag()) {
|
||||
break stateloop;
|
||||
}
|
||||
state = MetaScanner.DATA;
|
||||
continue stateloop;
|
||||
default:
|
||||
state = MetaScanner.BEFORE_ATTRIBUTE_NAME;
|
||||
reconsume = true;
|
||||
continue stateloop;
|
||||
}
|
||||
// XXX reorder point
|
||||
case ATTRIBUTE_VALUE_UNQUOTED:
|
||||
for (;;) {
|
||||
if (reconsume) {
|
||||
reconsume = false;
|
||||
} else {
|
||||
c = read();
|
||||
}
|
||||
switch (c) {
|
||||
case -1:
|
||||
break stateloop;
|
||||
case ' ':
|
||||
case '\t':
|
||||
case '\n':
|
||||
|
||||
case '\u000C':
|
||||
handleAttributeValue();
|
||||
state = MetaScanner.BEFORE_ATTRIBUTE_NAME;
|
||||
continue stateloop;
|
||||
case '>':
|
||||
handleAttributeValue();
|
||||
if (handleTag()) {
|
||||
break stateloop;
|
||||
}
|
||||
state = MetaScanner.DATA;
|
||||
continue stateloop;
|
||||
default:
|
||||
handleCharInAttributeValue(c);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// XXX reorder point
|
||||
case AFTER_ATTRIBUTE_NAME:
|
||||
for (;;) {
|
||||
c = read();
|
||||
switch (c) {
|
||||
case -1:
|
||||
break stateloop;
|
||||
case ' ':
|
||||
case '\t':
|
||||
case '\n':
|
||||
case '\u000C':
|
||||
continue;
|
||||
case '/':
|
||||
handleAttributeValue();
|
||||
state = MetaScanner.SELF_CLOSING_START_TAG;
|
||||
continue stateloop;
|
||||
case '=':
|
||||
strBufLen = 0;
|
||||
contentTypeIndex = 0;
|
||||
state = MetaScanner.BEFORE_ATTRIBUTE_VALUE;
|
||||
continue stateloop;
|
||||
case '>':
|
||||
handleAttributeValue();
|
||||
if (handleTag()) {
|
||||
break stateloop;
|
||||
}
|
||||
state = MetaScanner.DATA;
|
||||
continue stateloop;
|
||||
case 'c':
|
||||
case 'C':
|
||||
contentIndex = 0;
|
||||
charsetIndex = 0;
|
||||
state = MetaScanner.ATTRIBUTE_NAME;
|
||||
continue stateloop;
|
||||
default:
|
||||
contentIndex = Integer.MAX_VALUE;
|
||||
charsetIndex = Integer.MAX_VALUE;
|
||||
state = MetaScanner.ATTRIBUTE_NAME;
|
||||
continue stateloop;
|
||||
}
|
||||
}
|
||||
// XXX reorder point
|
||||
case MARKUP_DECLARATION_OPEN:
|
||||
markupdeclarationopenloop: for (;;) {
|
||||
c = read();
|
||||
switch (c) {
|
||||
case -1:
|
||||
break stateloop;
|
||||
case '-':
|
||||
state = MetaScanner.MARKUP_DECLARATION_HYPHEN;
|
||||
break markupdeclarationopenloop;
|
||||
// continue stateloop;
|
||||
default:
|
||||
state = MetaScanner.SCAN_UNTIL_GT;
|
||||
reconsume = true;
|
||||
continue stateloop;
|
||||
}
|
||||
}
|
||||
// FALLTHRU DON'T REORDER
|
||||
case MARKUP_DECLARATION_HYPHEN:
|
||||
markupdeclarationhyphenloop: for (;;) {
|
||||
c = read();
|
||||
switch (c) {
|
||||
case -1:
|
||||
break stateloop;
|
||||
case '-':
|
||||
state = MetaScanner.COMMENT_START;
|
||||
break markupdeclarationhyphenloop;
|
||||
// continue stateloop;
|
||||
default:
|
||||
state = MetaScanner.SCAN_UNTIL_GT;
|
||||
reconsume = true;
|
||||
continue stateloop;
|
||||
}
|
||||
}
|
||||
// FALLTHRU DON'T REORDER
|
||||
case COMMENT_START:
|
||||
commentstartloop: for (;;) {
|
||||
c = read();
|
||||
switch (c) {
|
||||
case -1:
|
||||
break stateloop;
|
||||
case '-':
|
||||
state = MetaScanner.COMMENT_START_DASH;
|
||||
continue stateloop;
|
||||
case '>':
|
||||
state = MetaScanner.DATA;
|
||||
continue stateloop;
|
||||
default:
|
||||
state = MetaScanner.COMMENT;
|
||||
break commentstartloop;
|
||||
// continue stateloop;
|
||||
}
|
||||
}
|
||||
// FALLTHRU DON'T REORDER
|
||||
case COMMENT:
|
||||
commentloop: for (;;) {
|
||||
c = read();
|
||||
switch (c) {
|
||||
case -1:
|
||||
break stateloop;
|
||||
case '-':
|
||||
state = MetaScanner.COMMENT_END_DASH;
|
||||
break commentloop;
|
||||
// continue stateloop;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// FALLTHRU DON'T REORDER
|
||||
case COMMENT_END_DASH:
|
||||
commentenddashloop: for (;;) {
|
||||
c = read();
|
||||
switch (c) {
|
||||
case -1:
|
||||
break stateloop;
|
||||
case '-':
|
||||
state = MetaScanner.COMMENT_END;
|
||||
break commentenddashloop;
|
||||
// continue stateloop;
|
||||
default:
|
||||
state = MetaScanner.COMMENT;
|
||||
continue stateloop;
|
||||
}
|
||||
}
|
||||
// FALLTHRU DON'T REORDER
|
||||
case COMMENT_END:
|
||||
for (;;) {
|
||||
c = read();
|
||||
switch (c) {
|
||||
case -1:
|
||||
break stateloop;
|
||||
case '>':
|
||||
state = MetaScanner.DATA;
|
||||
continue stateloop;
|
||||
case '-':
|
||||
continue;
|
||||
default:
|
||||
state = MetaScanner.COMMENT;
|
||||
continue stateloop;
|
||||
}
|
||||
}
|
||||
// XXX reorder point
|
||||
case COMMENT_START_DASH:
|
||||
c = read();
|
||||
switch (c) {
|
||||
case -1:
|
||||
break stateloop;
|
||||
case '-':
|
||||
state = MetaScanner.COMMENT_END;
|
||||
continue stateloop;
|
||||
case '>':
|
||||
state = MetaScanner.DATA;
|
||||
continue stateloop;
|
||||
default:
|
||||
state = MetaScanner.COMMENT;
|
||||
continue stateloop;
|
||||
}
|
||||
// XXX reorder point
|
||||
case ATTRIBUTE_VALUE_SINGLE_QUOTED:
|
||||
for (;;) {
|
||||
if (reconsume) {
|
||||
reconsume = false;
|
||||
} else {
|
||||
c = read();
|
||||
}
|
||||
switch (c) {
|
||||
case -1:
|
||||
break stateloop;
|
||||
case '\'':
|
||||
handleAttributeValue();
|
||||
state = MetaScanner.AFTER_ATTRIBUTE_VALUE_QUOTED;
|
||||
continue stateloop;
|
||||
default:
|
||||
handleCharInAttributeValue(c);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// XXX reorder point
|
||||
case SCAN_UNTIL_GT:
|
||||
for (;;) {
|
||||
if (reconsume) {
|
||||
reconsume = false;
|
||||
} else {
|
||||
c = read();
|
||||
}
|
||||
switch (c) {
|
||||
case -1:
|
||||
break stateloop;
|
||||
case '>':
|
||||
state = MetaScanner.DATA;
|
||||
continue stateloop;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
stateSave = state;
|
||||
}
|
||||
|
||||
private void handleCharInAttributeValue(int c) {
|
||||
if (metaState == A) {
|
||||
if (contentIndex == CONTENT.length || charsetIndex == CHARSET.length) {
|
||||
addToBuffer(c);
|
||||
} else if (httpEquivIndex == HTTP_EQUIV.length) {
|
||||
if (contentTypeIndex < CONTENT_TYPE.length && toAsciiLowerCase(c) == CONTENT_TYPE[contentTypeIndex]) {
|
||||
++contentTypeIndex;
|
||||
} else {
|
||||
contentTypeIndex = Integer.MAX_VALUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Inline private int toAsciiLowerCase(int c) {
|
||||
if (c >= 'A' && c <= 'Z') {
|
||||
return c + 0x20;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a character to the accumulation buffer.
|
||||
* @param c the character to add
|
||||
*/
|
||||
private void addToBuffer(int c) {
|
||||
if (strBufLen == strBuf.length) {
|
||||
char[] newBuf = new char[strBuf.length + (strBuf.length << 1)];
|
||||
System.arraycopy(strBuf, 0, newBuf, 0, strBuf.length);
|
||||
strBuf = newBuf;
|
||||
}
|
||||
strBuf[strBufLen++] = (char)c;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to extract a charset name from the accumulation buffer.
|
||||
* @return <code>true</code> if successful
|
||||
* @throws SAXException
|
||||
*/
|
||||
private void handleAttributeValue() throws SAXException {
|
||||
if (metaState != A) {
|
||||
return;
|
||||
}
|
||||
if (contentIndex == CONTENT.length && content == null) {
|
||||
content = Portability.newStringFromBuffer(strBuf, 0, strBufLen
|
||||
// CPPONLY: , treeBuilder
|
||||
);
|
||||
return;
|
||||
}
|
||||
if (charsetIndex == CHARSET.length && charset == null) {
|
||||
charset = Portability.newStringFromBuffer(strBuf, 0, strBufLen
|
||||
// CPPONLY: , treeBuilder
|
||||
);
|
||||
return;
|
||||
}
|
||||
if (httpEquivIndex == HTTP_EQUIV.length
|
||||
&& httpEquivState == HTTP_EQUIV_NOT_SEEN) {
|
||||
httpEquivState = (contentTypeIndex == CONTENT_TYPE.length) ? HTTP_EQUIV_CONTENT_TYPE
|
||||
: HTTP_EQUIV_OTHER;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean handleTag() throws SAXException {
|
||||
boolean stop = handleTagInner();
|
||||
Portability.releaseString(content);
|
||||
content = null;
|
||||
Portability.releaseString(charset);
|
||||
charset = null;
|
||||
httpEquivState = HTTP_EQUIV_NOT_SEEN;
|
||||
return stop;
|
||||
}
|
||||
|
||||
private boolean handleTagInner() throws SAXException {
|
||||
if (charset != null && tryCharset(charset)) {
|
||||
return true;
|
||||
}
|
||||
if (content != null && httpEquivState == HTTP_EQUIV_CONTENT_TYPE) {
|
||||
String extract = TreeBuilder.extractCharsetFromContent(content
|
||||
// CPPONLY: , treeBuilder
|
||||
);
|
||||
if (extract == null) {
|
||||
return false;
|
||||
}
|
||||
boolean success = tryCharset(extract);
|
||||
Portability.releaseString(extract);
|
||||
return success;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to switch to an encoding.
|
||||
*
|
||||
* @param encoding
|
||||
* @return <code>true</code> if successful
|
||||
* @throws SAXException
|
||||
*/
|
||||
protected abstract boolean tryCharset(String encoding) throws SAXException;
|
||||
|
||||
}
|
||||
|
|
@ -1,150 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2008-2015 Mozilla Foundation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package nu.validator.htmlparser.impl;
|
||||
|
||||
import nu.validator.htmlparser.annotation.Literal;
|
||||
import nu.validator.htmlparser.annotation.Local;
|
||||
import nu.validator.htmlparser.annotation.NoLength;
|
||||
import nu.validator.htmlparser.common.Interner;
|
||||
|
||||
public final class Portability {
|
||||
|
||||
// Allocating methods
|
||||
|
||||
/**
|
||||
* Allocates a new local name object. In C++, the refcount must be set up in such a way that
|
||||
* calling <code>releaseLocal</code> on the return value balances the refcount set by this method.
|
||||
*/
|
||||
public static @Local String newLocalNameFromBuffer(@NoLength char[] buf, int offset, int length, Interner interner) {
|
||||
return new String(buf, offset, length).intern();
|
||||
}
|
||||
|
||||
public static String newStringFromBuffer(@NoLength char[] buf, int offset, int length
|
||||
// CPPONLY: , TreeBuilder treeBuilder
|
||||
) {
|
||||
return new String(buf, offset, length);
|
||||
}
|
||||
|
||||
public static String newEmptyString() {
|
||||
return "";
|
||||
}
|
||||
|
||||
public static String newStringFromLiteral(@Literal String literal) {
|
||||
return literal;
|
||||
}
|
||||
|
||||
public static String newStringFromString(String string) {
|
||||
return string;
|
||||
}
|
||||
|
||||
// XXX get rid of this
|
||||
public static char[] newCharArrayFromLocal(@Local String local) {
|
||||
return local.toCharArray();
|
||||
}
|
||||
|
||||
public static char[] newCharArrayFromString(String string) {
|
||||
return string.toCharArray();
|
||||
}
|
||||
|
||||
public static @Local String newLocalFromLocal(@Local String local, Interner interner) {
|
||||
return local;
|
||||
}
|
||||
|
||||
// Deallocation methods
|
||||
|
||||
public static void releaseString(String str) {
|
||||
// No-op in Java
|
||||
}
|
||||
|
||||
// Comparison methods
|
||||
|
||||
public static boolean localEqualsBuffer(@Local String local, @NoLength char[] buf, int offset, int length) {
|
||||
if (local.length() != length) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < length; i++) {
|
||||
if (local.charAt(i) != buf[offset + i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean lowerCaseLiteralIsPrefixOfIgnoreAsciiCaseString(@Literal String lowerCaseLiteral,
|
||||
String string) {
|
||||
if (string == null) {
|
||||
return false;
|
||||
}
|
||||
if (lowerCaseLiteral.length() > string.length()) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < lowerCaseLiteral.length(); i++) {
|
||||
char c0 = lowerCaseLiteral.charAt(i);
|
||||
char c1 = string.charAt(i);
|
||||
if (c1 >= 'A' && c1 <= 'Z') {
|
||||
c1 += 0x20;
|
||||
}
|
||||
if (c0 != c1) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean lowerCaseLiteralEqualsIgnoreAsciiCaseString(@Literal String lowerCaseLiteral,
|
||||
String string) {
|
||||
if (string == null) {
|
||||
return false;
|
||||
}
|
||||
if (lowerCaseLiteral.length() != string.length()) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < lowerCaseLiteral.length(); i++) {
|
||||
char c0 = lowerCaseLiteral.charAt(i);
|
||||
char c1 = string.charAt(i);
|
||||
if (c1 >= 'A' && c1 <= 'Z') {
|
||||
c1 += 0x20;
|
||||
}
|
||||
if (c0 != c1) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean literalEqualsString(@Literal String literal, String string) {
|
||||
return literal.equals(string);
|
||||
}
|
||||
|
||||
public static boolean stringEqualsString(String one, String other) {
|
||||
return one.equals(other);
|
||||
}
|
||||
|
||||
public static void delete(Object o) {
|
||||
|
||||
}
|
||||
|
||||
public static void deleteArray(Object o) {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
The .java files in this directory were placed here by the Java-to-C++
|
||||
translator that lives in parser/html/java/translator. Together they represent
|
||||
a snapshot of the Java code that was translated to produce the corresponding
|
||||
.h and .cpp files in the parent directory. Changing these .java files is not
|
||||
worthwhile, as they will just be overwritten by the next translation. See
|
||||
parser/html/java/README.txt for information about performing the translation.
|
||||
|
|
@ -1,322 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2007 Henri Sivonen
|
||||
* Copyright (c) 2007-2011 Mozilla Foundation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package nu.validator.htmlparser.impl;
|
||||
|
||||
import nu.validator.htmlparser.annotation.Inline;
|
||||
import nu.validator.htmlparser.annotation.Local;
|
||||
import nu.validator.htmlparser.annotation.NsUri;
|
||||
|
||||
final class StackNode<T> {
|
||||
// Index where this stack node is stored in the tree builder's list of stack nodes.
|
||||
// A value of -1 indicates that the stack node is not owned by a tree builder and
|
||||
// must delete itself when its refcount reaches 0.
|
||||
final int idxInTreeBuilder;
|
||||
|
||||
int flags;
|
||||
|
||||
@Local String name;
|
||||
|
||||
@Local String popName;
|
||||
|
||||
@NsUri String ns;
|
||||
|
||||
T node;
|
||||
|
||||
// Only used on the list of formatting elements
|
||||
HtmlAttributes attributes;
|
||||
|
||||
private int refcount = 0;
|
||||
|
||||
// [NOCPP[
|
||||
|
||||
private TaintableLocatorImpl locator;
|
||||
|
||||
public TaintableLocatorImpl getLocator() {
|
||||
return locator;
|
||||
}
|
||||
|
||||
// ]NOCPP]
|
||||
|
||||
@Inline public int getFlags() {
|
||||
return flags;
|
||||
}
|
||||
|
||||
public int getGroup() {
|
||||
return flags & ElementName.GROUP_MASK;
|
||||
}
|
||||
|
||||
public boolean isScoping() {
|
||||
return (flags & ElementName.SCOPING) != 0;
|
||||
}
|
||||
|
||||
public boolean isSpecial() {
|
||||
return (flags & ElementName.SPECIAL) != 0;
|
||||
}
|
||||
|
||||
public boolean isFosterParenting() {
|
||||
return (flags & ElementName.FOSTER_PARENTING) != 0;
|
||||
}
|
||||
|
||||
public boolean isHtmlIntegrationPoint() {
|
||||
return (flags & ElementName.HTML_INTEGRATION_POINT) != 0;
|
||||
}
|
||||
|
||||
// [NOCPP[
|
||||
|
||||
public boolean isOptionalEndTag() {
|
||||
return (flags & ElementName.OPTIONAL_END_TAG) != 0;
|
||||
}
|
||||
|
||||
// ]NOCPP]
|
||||
|
||||
StackNode(int idxInTreeBuilder) {
|
||||
this.idxInTreeBuilder = idxInTreeBuilder;
|
||||
this.refcount = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for copying. This doesn't take another <code>StackNode</code>
|
||||
* because in C++ the caller is responsible for reobtaining the local names
|
||||
* from another interner.
|
||||
*
|
||||
* @param flags
|
||||
* @param ns
|
||||
* @param name
|
||||
* @param node
|
||||
* @param popName
|
||||
* @param attributes
|
||||
*/
|
||||
void setValues(int flags, @NsUri String ns, @Local String name, T node,
|
||||
@Local String popName, HtmlAttributes attributes
|
||||
// [NOCPP[
|
||||
, TaintableLocatorImpl locator
|
||||
// ]NOCPP]
|
||||
) {
|
||||
assert isUnused();
|
||||
this.flags = flags;
|
||||
this.name = name;
|
||||
this.popName = popName;
|
||||
this.ns = ns;
|
||||
this.node = node;
|
||||
this.attributes = attributes;
|
||||
this.refcount = 1;
|
||||
// [NOCPP[
|
||||
this.locator = locator;
|
||||
// ]NOCPP]
|
||||
}
|
||||
|
||||
/**
|
||||
* Short hand for well-known HTML elements.
|
||||
*
|
||||
* @param elementName
|
||||
* @param node
|
||||
*/
|
||||
void setValues(ElementName elementName, T node
|
||||
// [NOCPP[
|
||||
, TaintableLocatorImpl locator
|
||||
// ]NOCPP]
|
||||
) {
|
||||
assert isUnused();
|
||||
this.flags = elementName.getFlags();
|
||||
this.name = elementName.name;
|
||||
this.popName = elementName.name;
|
||||
this.ns = "http://www.w3.org/1999/xhtml";
|
||||
this.node = node;
|
||||
this.attributes = null;
|
||||
this.refcount = 1;
|
||||
assert !elementName.isCustom() : "Don't use this constructor for custom elements.";
|
||||
// [NOCPP[
|
||||
this.locator = locator;
|
||||
// ]NOCPP]
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for HTML formatting elements.
|
||||
*
|
||||
* @param elementName
|
||||
* @param node
|
||||
* @param attributes
|
||||
*/
|
||||
void setValues(ElementName elementName, T node, HtmlAttributes attributes
|
||||
// [NOCPP[
|
||||
, TaintableLocatorImpl locator
|
||||
// ]NOCPP]
|
||||
) {
|
||||
assert isUnused();
|
||||
this.flags = elementName.getFlags();
|
||||
this.name = elementName.name;
|
||||
this.popName = elementName.name;
|
||||
this.ns = "http://www.w3.org/1999/xhtml";
|
||||
this.node = node;
|
||||
this.attributes = attributes;
|
||||
this.refcount = 1;
|
||||
assert !elementName.isCustom() : "Don't use this constructor for custom elements.";
|
||||
// [NOCPP[
|
||||
this.locator = locator;
|
||||
// ]NOCPP]
|
||||
}
|
||||
|
||||
/**
|
||||
* The common-case HTML setter.
|
||||
*
|
||||
* @param elementName
|
||||
* @param node
|
||||
* @param popName
|
||||
*/
|
||||
void setValues(ElementName elementName, T node, @Local String popName
|
||||
// [NOCPP[
|
||||
, TaintableLocatorImpl locator
|
||||
// ]NOCPP]
|
||||
) {
|
||||
assert isUnused();
|
||||
this.flags = elementName.getFlags();
|
||||
this.name = elementName.name;
|
||||
this.popName = popName;
|
||||
this.ns = "http://www.w3.org/1999/xhtml";
|
||||
this.node = node;
|
||||
this.attributes = null;
|
||||
this.refcount = 1;
|
||||
// [NOCPP[
|
||||
this.locator = locator;
|
||||
// ]NOCPP]
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for SVG elements. Note that the order of the arguments is
|
||||
* what distinguishes this from the HTML setter. This is ugly, but
|
||||
* AFAICT the least disruptive way to make this work with Java's generics
|
||||
* and without unnecessary branches. :-(
|
||||
*
|
||||
* @param elementName
|
||||
* @param popName
|
||||
* @param node
|
||||
*/
|
||||
void setValues(ElementName elementName, @Local String popName, T node
|
||||
// [NOCPP[
|
||||
, TaintableLocatorImpl locator
|
||||
// ]NOCPP]
|
||||
) {
|
||||
assert isUnused();
|
||||
this.flags = prepareSvgFlags(elementName.getFlags());
|
||||
this.name = elementName.name;
|
||||
this.popName = popName;
|
||||
this.ns = "http://www.w3.org/2000/svg";
|
||||
this.node = node;
|
||||
this.attributes = null;
|
||||
this.refcount = 1;
|
||||
// [NOCPP[
|
||||
this.locator = locator;
|
||||
// ]NOCPP]
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for MathML.
|
||||
*
|
||||
* @param elementName
|
||||
* @param node
|
||||
* @param popName
|
||||
* @param markAsIntegrationPoint
|
||||
*/
|
||||
void setValues(ElementName elementName, T node, @Local String popName,
|
||||
boolean markAsIntegrationPoint
|
||||
// [NOCPP[
|
||||
, TaintableLocatorImpl locator
|
||||
// ]NOCPP]
|
||||
) {
|
||||
assert isUnused();
|
||||
this.flags = prepareMathFlags(elementName.getFlags(),
|
||||
markAsIntegrationPoint);
|
||||
this.name = elementName.name;
|
||||
this.popName = popName;
|
||||
this.ns = "http://www.w3.org/1998/Math/MathML";
|
||||
this.node = node;
|
||||
this.attributes = null;
|
||||
this.refcount = 1;
|
||||
// [NOCPP[
|
||||
this.locator = locator;
|
||||
// ]NOCPP]
|
||||
}
|
||||
|
||||
private static int prepareSvgFlags(int flags) {
|
||||
flags &= ~(ElementName.FOSTER_PARENTING | ElementName.SCOPING
|
||||
| ElementName.SPECIAL | ElementName.OPTIONAL_END_TAG);
|
||||
if ((flags & ElementName.SCOPING_AS_SVG) != 0) {
|
||||
flags |= (ElementName.SCOPING | ElementName.SPECIAL | ElementName.HTML_INTEGRATION_POINT);
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
|
||||
private static int prepareMathFlags(int flags,
|
||||
boolean markAsIntegrationPoint) {
|
||||
flags &= ~(ElementName.FOSTER_PARENTING | ElementName.SCOPING
|
||||
| ElementName.SPECIAL | ElementName.OPTIONAL_END_TAG);
|
||||
if ((flags & ElementName.SCOPING_AS_MATHML) != 0) {
|
||||
flags |= (ElementName.SCOPING | ElementName.SPECIAL);
|
||||
}
|
||||
if (markAsIntegrationPoint) {
|
||||
flags |= ElementName.HTML_INTEGRATION_POINT;
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused") private void destructor() {
|
||||
// The translator adds refcount debug code here.
|
||||
}
|
||||
|
||||
public void dropAttributes() {
|
||||
attributes = null;
|
||||
}
|
||||
|
||||
// [NOCPP[
|
||||
/**
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override public @Local String toString() {
|
||||
return name;
|
||||
}
|
||||
|
||||
// ]NOCPP]
|
||||
|
||||
public void retain() {
|
||||
refcount++;
|
||||
}
|
||||
|
||||
public void release(TreeBuilder<T> owningTreeBuilder) {
|
||||
refcount--;
|
||||
assert refcount >= 0;
|
||||
if (refcount == 0) {
|
||||
Portability.delete(attributes);
|
||||
if (idxInTreeBuilder >= 0) {
|
||||
owningTreeBuilder.notifyUnusedStackNode(idxInTreeBuilder);
|
||||
} else {
|
||||
assert owningTreeBuilder == null;
|
||||
Portability.delete(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boolean isUnused() {
|
||||
return refcount == 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,204 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2009-2010 Mozilla Foundation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package nu.validator.htmlparser.impl;
|
||||
|
||||
import nu.validator.htmlparser.annotation.Auto;
|
||||
|
||||
|
||||
public class StateSnapshot<T> implements TreeBuilderState<T> {
|
||||
|
||||
private final @Auto StackNode<T>[] stack;
|
||||
|
||||
private final @Auto StackNode<T>[] listOfActiveFormattingElements;
|
||||
|
||||
private final @Auto int[] templateModeStack;
|
||||
|
||||
private final T formPointer;
|
||||
|
||||
private final T headPointer;
|
||||
|
||||
private final T deepTreeSurrogateParent;
|
||||
|
||||
private final int mode;
|
||||
|
||||
private final int originalMode;
|
||||
|
||||
private final boolean framesetOk;
|
||||
|
||||
private final boolean needToDropLF;
|
||||
|
||||
private final boolean quirks;
|
||||
|
||||
/**
|
||||
* @param stack
|
||||
* @param listOfActiveFormattingElements
|
||||
* @param templateModeStack
|
||||
* @param formPointer
|
||||
* @param headPointer
|
||||
* @param deepTreeSurrogateParent
|
||||
* @param mode
|
||||
* @param originalMode
|
||||
* @param framesetOk
|
||||
* @param needToDropLF
|
||||
* @param quirks
|
||||
*/
|
||||
StateSnapshot(StackNode<T>[] stack,
|
||||
StackNode<T>[] listOfActiveFormattingElements, int[] templateModeStack, T formPointer,
|
||||
T headPointer, T deepTreeSurrogateParent, int mode, int originalMode,
|
||||
boolean framesetOk, boolean needToDropLF, boolean quirks) {
|
||||
this.stack = stack;
|
||||
this.listOfActiveFormattingElements = listOfActiveFormattingElements;
|
||||
this.templateModeStack = templateModeStack;
|
||||
this.formPointer = formPointer;
|
||||
this.headPointer = headPointer;
|
||||
this.deepTreeSurrogateParent = deepTreeSurrogateParent;
|
||||
this.mode = mode;
|
||||
this.originalMode = originalMode;
|
||||
this.framesetOk = framesetOk;
|
||||
this.needToDropLF = needToDropLF;
|
||||
this.quirks = quirks;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see nu.validator.htmlparser.impl.TreeBuilderState#getStack()
|
||||
*/
|
||||
public StackNode<T>[] getStack() {
|
||||
return stack;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see nu.validator.htmlparser.impl.TreeBuilderState#getTemplateModeStack()
|
||||
*/
|
||||
public int[] getTemplateModeStack() {
|
||||
return templateModeStack;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see nu.validator.htmlparser.impl.TreeBuilderState#getListOfActiveFormattingElements()
|
||||
*/
|
||||
public StackNode<T>[] getListOfActiveFormattingElements() {
|
||||
return listOfActiveFormattingElements;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see nu.validator.htmlparser.impl.TreeBuilderState#getFormPointer()
|
||||
*/
|
||||
public T getFormPointer() {
|
||||
return formPointer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the headPointer.
|
||||
*
|
||||
* @return the headPointer
|
||||
*/
|
||||
public T getHeadPointer() {
|
||||
return headPointer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the deepTreeSurrogateParent.
|
||||
*
|
||||
* @return the deepTreeSurrogateParent
|
||||
*/
|
||||
public T getDeepTreeSurrogateParent() {
|
||||
return deepTreeSurrogateParent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the mode.
|
||||
*
|
||||
* @return the mode
|
||||
*/
|
||||
public int getMode() {
|
||||
return mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the originalMode.
|
||||
*
|
||||
* @return the originalMode
|
||||
*/
|
||||
public int getOriginalMode() {
|
||||
return originalMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the framesetOk.
|
||||
*
|
||||
* @return the framesetOk
|
||||
*/
|
||||
public boolean isFramesetOk() {
|
||||
return framesetOk;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the needToDropLF.
|
||||
*
|
||||
* @return the needToDropLF
|
||||
*/
|
||||
public boolean isNeedToDropLF() {
|
||||
return needToDropLF;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the quirks.
|
||||
*
|
||||
* @return the quirks
|
||||
*/
|
||||
public boolean isQuirks() {
|
||||
return quirks;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see nu.validator.htmlparser.impl.TreeBuilderState#getListOfActiveFormattingElementsLength()
|
||||
*/
|
||||
public int getListOfActiveFormattingElementsLength() {
|
||||
return listOfActiveFormattingElements.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see nu.validator.htmlparser.impl.TreeBuilderState#getStackLength()
|
||||
*/
|
||||
public int getStackLength() {
|
||||
return stack.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see nu.validator.htmlparser.impl.TreeBuilderState#getTemplateModeStackLength()
|
||||
*/
|
||||
public int getTemplateModeStackLength() {
|
||||
return templateModeStack.length;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused") private void destructor() {
|
||||
for (int i = 0; i < stack.length; i++) {
|
||||
stack[i].release(null);
|
||||
}
|
||||
for (int i = 0; i < listOfActiveFormattingElements.length; i++) {
|
||||
if (listOfActiveFormattingElements[i] != null) {
|
||||
listOfActiveFormattingElements[i].release(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -1,151 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2008-2010 Mozilla Foundation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package nu.validator.htmlparser.impl;
|
||||
|
||||
import nu.validator.htmlparser.annotation.NoLength;
|
||||
|
||||
/**
|
||||
* An UTF-16 buffer that knows the start and end indeces of its unconsumed
|
||||
* content.
|
||||
*
|
||||
* @version $Id$
|
||||
* @author hsivonen
|
||||
*/
|
||||
public final class UTF16Buffer {
|
||||
|
||||
/**
|
||||
* The backing store of the buffer. May be larger than the logical content
|
||||
* of this <code>UTF16Buffer</code>.
|
||||
*/
|
||||
private final @NoLength char[] buffer;
|
||||
|
||||
/**
|
||||
* The index of the first unconsumed character in the backing buffer.
|
||||
*/
|
||||
private int start;
|
||||
|
||||
/**
|
||||
* The index of the slot immediately after the last character in the backing
|
||||
* buffer that is part of the logical content of this
|
||||
* <code>UTF16Buffer</code>.
|
||||
*/
|
||||
private int end;
|
||||
|
||||
//[NOCPP[
|
||||
|
||||
/**
|
||||
* Constructor for wrapping an existing UTF-16 code unit array.
|
||||
*
|
||||
* @param buffer
|
||||
* the backing buffer
|
||||
* @param start
|
||||
* the index of the first character to consume
|
||||
* @param end
|
||||
* the index immediately after the last character to consume
|
||||
*/
|
||||
public UTF16Buffer(@NoLength char[] buffer, int start, int end) {
|
||||
this.buffer = buffer;
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
}
|
||||
|
||||
// ]NOCPP]
|
||||
|
||||
/**
|
||||
* Returns the start index.
|
||||
*
|
||||
* @return the start index
|
||||
*/
|
||||
public int getStart() {
|
||||
return start;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the start index.
|
||||
*
|
||||
* @param start
|
||||
* the start index
|
||||
*/
|
||||
public void setStart(int start) {
|
||||
this.start = start;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the backing buffer.
|
||||
*
|
||||
* @return the backing buffer
|
||||
*/
|
||||
public @NoLength char[] getBuffer() {
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the end index.
|
||||
*
|
||||
* @return the end index
|
||||
*/
|
||||
public int getEnd() {
|
||||
return end;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the buffer has data left.
|
||||
*
|
||||
* @return <code>true</code> if there's data left
|
||||
*/
|
||||
public boolean hasMore() {
|
||||
return start < end;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>end - start</code>.
|
||||
*
|
||||
* @return <code>end - start</code>
|
||||
*/
|
||||
public int getLength() {
|
||||
return end - start;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjusts the start index to skip over the first character if it is a line
|
||||
* feed and the previous character was a carriage return.
|
||||
*
|
||||
* @param lastWasCR
|
||||
* whether the previous character was a carriage return
|
||||
*/
|
||||
public void adjust(boolean lastWasCR) {
|
||||
if (lastWasCR && buffer[start] == '\n') {
|
||||
start++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the end index.
|
||||
*
|
||||
* @param end
|
||||
* the end index
|
||||
*/
|
||||
public void setEnd(int end) {
|
||||
this.end = end;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2008 Mozilla Foundation
|
||||
* Copyright (c) 2019 Moonchild Productions
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2008-2011 Mozilla Foundation
|
||||
* Copyright (c) 2019 Moonchild Productions
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
|
|
@ -20,11 +21,6 @@
|
|||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* THIS IS A GENERATED FILE. PLEASE DO NOT EDIT.
|
||||
* Please edit AttributeName.java instead and regenerate.
|
||||
*/
|
||||
|
||||
#define nsHtml5AttributeName_cpp__
|
||||
|
||||
#include "nsIAtom.h"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2008-2011 Mozilla Foundation
|
||||
* Copyright (c) 2019 Moonchild Productions
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
|
|
@ -20,11 +21,6 @@
|
|||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* THIS IS A GENERATED FILE. PLEASE DO NOT EDIT.
|
||||
* Please edit AttributeName.java instead and regenerate.
|
||||
*/
|
||||
|
||||
#ifndef nsHtml5AttributeName_h
|
||||
#define nsHtml5AttributeName_h
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2008-2014 Mozilla Foundation
|
||||
* Copyright (c) 2019 Moonchild Productions
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
|
|
@ -20,11 +21,6 @@
|
|||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* THIS IS A GENERATED FILE. PLEASE DO NOT EDIT.
|
||||
* Please edit ElementName.java instead and regenerate.
|
||||
*/
|
||||
|
||||
#define nsHtml5ElementName_cpp__
|
||||
|
||||
#include "nsIAtom.h"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2008-2014 Mozilla Foundation
|
||||
* Copyright (c) 2019 Moonchild Productions
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
|
|
@ -20,11 +21,6 @@
|
|||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* THIS IS A GENERATED FILE. PLEASE DO NOT EDIT.
|
||||
* Please edit ElementName.java instead and regenerate.
|
||||
*/
|
||||
|
||||
#ifndef nsHtml5ElementName_h
|
||||
#define nsHtml5ElementName_h
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/*
|
||||
* Copyright (c) 2007 Henri Sivonen
|
||||
* Copyright (c) 2008-2011 Mozilla Foundation
|
||||
* Copyright (c) 2019 Moonchild Productions
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
|
|
@ -21,11 +22,6 @@
|
|||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* THIS IS A GENERATED FILE. PLEASE DO NOT EDIT.
|
||||
* Please edit HtmlAttributes.java instead and regenerate.
|
||||
*/
|
||||
|
||||
#define nsHtml5HtmlAttributes_cpp__
|
||||
|
||||
#include "nsIAtom.h"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/*
|
||||
* Copyright (c) 2007 Henri Sivonen
|
||||
* Copyright (c) 2008-2011 Mozilla Foundation
|
||||
* Copyright (c) 2019 Moonchild Productions
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
|
|
@ -21,11 +22,6 @@
|
|||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* THIS IS A GENERATED FILE. PLEASE DO NOT EDIT.
|
||||
* Please edit HtmlAttributes.java instead and regenerate.
|
||||
*/
|
||||
|
||||
#ifndef nsHtml5HtmlAttributes_h
|
||||
#define nsHtml5HtmlAttributes_h
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/*
|
||||
* Copyright (c) 2007 Henri Sivonen
|
||||
* Copyright (c) 2008-2015 Mozilla Foundation
|
||||
* Copyright (c) 2019 Moonchild Productions
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
|
|
@ -21,11 +22,6 @@
|
|||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* THIS IS A GENERATED FILE. PLEASE DO NOT EDIT.
|
||||
* Please edit MetaScanner.java instead and regenerate.
|
||||
*/
|
||||
|
||||
#define nsHtml5MetaScanner_cpp__
|
||||
|
||||
#include "nsIAtom.h"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/*
|
||||
* Copyright (c) 2007 Henri Sivonen
|
||||
* Copyright (c) 2008-2015 Mozilla Foundation
|
||||
* Copyright (c) 2019 Moonchild Productions
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
|
|
@ -21,11 +22,6 @@
|
|||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* THIS IS A GENERATED FILE. PLEASE DO NOT EDIT.
|
||||
* Please edit MetaScanner.java instead and regenerate.
|
||||
*/
|
||||
|
||||
#ifndef nsHtml5MetaScanner_h
|
||||
#define nsHtml5MetaScanner_h
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2008-2015 Mozilla Foundation
|
||||
* Copyright (c) 2019 Moonchild Productions
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
|
|
@ -20,11 +21,6 @@
|
|||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* THIS IS A GENERATED FILE. PLEASE DO NOT EDIT.
|
||||
* Please edit Portability.java instead and regenerate.
|
||||
*/
|
||||
|
||||
#ifndef nsHtml5Portability_h
|
||||
#define nsHtml5Portability_h
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/*
|
||||
* Copyright (c) 2007 Henri Sivonen
|
||||
* Copyright (c) 2007-2011 Mozilla Foundation
|
||||
* Copyright (c) 2019 Moonchild Productions
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
|
|
@ -21,11 +22,6 @@
|
|||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* THIS IS A GENERATED FILE. PLEASE DO NOT EDIT.
|
||||
* Please edit StackNode.java instead and regenerate.
|
||||
*/
|
||||
|
||||
#define nsHtml5StackNode_cpp__
|
||||
|
||||
#include "nsIAtom.h"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/*
|
||||
* Copyright (c) 2007 Henri Sivonen
|
||||
* Copyright (c) 2007-2011 Mozilla Foundation
|
||||
* Copyright (c) 2019 Moonchild Productions
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
|
|
@ -21,11 +22,6 @@
|
|||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* THIS IS A GENERATED FILE. PLEASE DO NOT EDIT.
|
||||
* Please edit StackNode.java instead and regenerate.
|
||||
*/
|
||||
|
||||
#ifndef nsHtml5StackNode_h
|
||||
#define nsHtml5StackNode_h
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2009-2010 Mozilla Foundation
|
||||
* Copyright (c) 2019 Moonchild Productions
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
|
|
@ -20,11 +21,6 @@
|
|||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* THIS IS A GENERATED FILE. PLEASE DO NOT EDIT.
|
||||
* Please edit StateSnapshot.java instead and regenerate.
|
||||
*/
|
||||
|
||||
#define nsHtml5StateSnapshot_cpp__
|
||||
|
||||
#include "nsIAtom.h"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2009-2010 Mozilla Foundation
|
||||
* Copyright (c) 2019 Moonchild Productions
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
|
|
@ -20,11 +21,6 @@
|
|||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* THIS IS A GENERATED FILE. PLEASE DO NOT EDIT.
|
||||
* Please edit StateSnapshot.java instead and regenerate.
|
||||
*/
|
||||
|
||||
#ifndef nsHtml5StateSnapshot_h
|
||||
#define nsHtml5StateSnapshot_h
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/*
|
||||
* Copyright (c) 2005-2007 Henri Sivonen
|
||||
* Copyright (c) 2007-2015 Mozilla Foundation
|
||||
* Copyright (c) 2019 Moonchild Productions
|
||||
* Portions of comments Copyright 2004-2010 Apple Computer, Inc., Mozilla
|
||||
* Foundation, and Opera Software ASA.
|
||||
*
|
||||
|
|
@ -23,11 +24,6 @@
|
|||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* THIS IS A GENERATED FILE. PLEASE DO NOT EDIT.
|
||||
* Please edit Tokenizer.java instead and regenerate.
|
||||
*/
|
||||
|
||||
#define nsHtml5Tokenizer_cpp__
|
||||
|
||||
#include "nsIAtom.h"
|
||||
|
|
@ -127,15 +123,11 @@ nsHtml5Tokenizer::isViewingXmlSource()
|
|||
}
|
||||
|
||||
void
|
||||
nsHtml5Tokenizer::setStateAndEndTagExpectation(int32_t specialTokenizerState, nsIAtom* endTagExpectation)
|
||||
nsHtml5Tokenizer::setState(int32_t specialTokenizerState)
|
||||
{
|
||||
this->stateSave = specialTokenizerState;
|
||||
if (specialTokenizerState == NS_HTML5TOKENIZER_DATA) {
|
||||
return;
|
||||
}
|
||||
autoJArray<char16_t,int32_t> asArray = nsHtml5Portability::newCharArrayFromLocal(endTagExpectation);
|
||||
this->endTagExpectation = nsHtml5ElementName::elementNameByBuffer(asArray, 0, asArray.length, interner);
|
||||
endTagExpectationToArray();
|
||||
this->endTagExpectation = nullptr;
|
||||
this->endTagExpectationAsArray = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -2040,7 +2032,13 @@ nsHtml5Tokenizer::stateLoop(int32_t state, char16_t c, int32_t pos, char16_t* bu
|
|||
NS_HTML5_BREAK(stateloop);
|
||||
}
|
||||
c = checkChar(buf, pos);
|
||||
if (index < endTagExpectationAsArray.length) {
|
||||
if (!endTagExpectationAsArray) {
|
||||
tokenHandler->characters(nsHtml5Tokenizer::LT_SOLIDUS, 0, 2);
|
||||
cstart = pos;
|
||||
reconsume = true;
|
||||
state = P::transition(mViewSource, returnState, reconsume, pos);
|
||||
NS_HTML5_CONTINUE(stateloop);
|
||||
} else if (index < endTagExpectationAsArray.length) {
|
||||
char16_t e = endTagExpectationAsArray[index];
|
||||
char16_t folded = c;
|
||||
if (c >= 'A' && c <= 'Z') {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/*
|
||||
* Copyright (c) 2005-2007 Henri Sivonen
|
||||
* Copyright (c) 2007-2015 Mozilla Foundation
|
||||
* Copyright (c) 2019 Moonchild Productions
|
||||
* Portions of comments Copyright 2004-2010 Apple Computer, Inc., Mozilla
|
||||
* Foundation, and Opera Software ASA.
|
||||
*
|
||||
|
|
@ -23,11 +24,6 @@
|
|||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* THIS IS A GENERATED FILE. PLEASE DO NOT EDIT.
|
||||
* Please edit Tokenizer.java instead and regenerate.
|
||||
*/
|
||||
|
||||
#ifndef nsHtml5Tokenizer_h
|
||||
#define nsHtml5Tokenizer_h
|
||||
|
||||
|
|
@ -143,7 +139,7 @@ class nsHtml5Tokenizer
|
|||
void setInterner(nsHtml5AtomTable* interner);
|
||||
void initLocation(nsHtml5String newPublicId, nsHtml5String newSystemId);
|
||||
bool isViewingXmlSource();
|
||||
void setStateAndEndTagExpectation(int32_t specialTokenizerState, nsIAtom* endTagExpectation);
|
||||
void setState(int32_t specialTokenizerState);
|
||||
void setStateAndEndTagExpectation(int32_t specialTokenizerState, nsHtml5ElementName* endTagExpectation);
|
||||
private:
|
||||
void endTagExpectationToArray();
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/*
|
||||
* Copyright (c) 2007 Henri Sivonen
|
||||
* Copyright (c) 2007-2015 Mozilla Foundation
|
||||
* Copyright (c) 2019 Moonchild Productions
|
||||
* Portions of comments Copyright 2004-2008 Apple Computer, Inc., Mozilla
|
||||
* Foundation, and Opera Software ASA.
|
||||
*
|
||||
|
|
@ -23,11 +24,6 @@
|
|||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* THIS IS A GENERATED FILE. PLEASE DO NOT EDIT.
|
||||
* Please edit TreeBuilder.java instead and regenerate.
|
||||
*/
|
||||
|
||||
#define nsHtml5TreeBuilder_cpp__
|
||||
|
||||
#include "nsContentUtils.h"
|
||||
|
|
@ -108,7 +104,7 @@ nsHtml5TreeBuilder::startTokenization(nsHtml5Tokenizer* self)
|
|||
nsHtml5StackNode* node = createStackNode(elementName, elementName->camelCaseName, elt);
|
||||
currentPtr++;
|
||||
stack[currentPtr] = node;
|
||||
tokenizer->setStateAndEndTagExpectation(NS_HTML5TOKENIZER_DATA, contextName);
|
||||
tokenizer->setState(NS_HTML5TOKENIZER_DATA);
|
||||
mode = NS_HTML5TREE_BUILDER_FRAMESET_OK;
|
||||
} else if (contextNamespace == kNameSpaceID_MathML) {
|
||||
nsHtml5ElementName* elementName = nsHtml5ElementName::ELT_MATH;
|
||||
|
|
@ -120,7 +116,7 @@ nsHtml5TreeBuilder::startTokenization(nsHtml5Tokenizer* self)
|
|||
nsHtml5StackNode* node = createStackNode(elementName, elt, elementName->name, false);
|
||||
currentPtr++;
|
||||
stack[currentPtr] = node;
|
||||
tokenizer->setStateAndEndTagExpectation(NS_HTML5TOKENIZER_DATA, contextName);
|
||||
tokenizer->setState(NS_HTML5TOKENIZER_DATA);
|
||||
mode = NS_HTML5TREE_BUILDER_FRAMESET_OK;
|
||||
} else {
|
||||
nsHtml5StackNode* node = createStackNode(nsHtml5ElementName::ELT_HTML, elt);
|
||||
|
|
@ -132,15 +128,20 @@ nsHtml5TreeBuilder::startTokenization(nsHtml5Tokenizer* self)
|
|||
resetTheInsertionMode();
|
||||
formPointer = getFormPointerForContext(contextNode);
|
||||
if (nsHtml5Atoms::title == contextName || nsHtml5Atoms::textarea == contextName) {
|
||||
tokenizer->setStateAndEndTagExpectation(NS_HTML5TOKENIZER_RCDATA, contextName);
|
||||
} else if (nsHtml5Atoms::style == contextName || nsHtml5Atoms::xmp == contextName || nsHtml5Atoms::iframe == contextName || nsHtml5Atoms::noembed == contextName || nsHtml5Atoms::noframes == contextName || (scriptingEnabled && nsHtml5Atoms::noscript == contextName)) {
|
||||
tokenizer->setStateAndEndTagExpectation(NS_HTML5TOKENIZER_RAWTEXT, contextName);
|
||||
tokenizer->setState(NS_HTML5TOKENIZER_RCDATA);
|
||||
} else if (nsHtml5Atoms::style == contextName ||
|
||||
nsHtml5Atoms::xmp == contextName ||
|
||||
nsHtml5Atoms::iframe == contextName ||
|
||||
nsHtml5Atoms::noembed == contextName ||
|
||||
nsHtml5Atoms::noframes == contextName ||
|
||||
(scriptingEnabled && nsHtml5Atoms::noscript == contextName)) {
|
||||
tokenizer->setState(NS_HTML5TOKENIZER_RAWTEXT);
|
||||
} else if (nsHtml5Atoms::plaintext == contextName) {
|
||||
tokenizer->setStateAndEndTagExpectation(NS_HTML5TOKENIZER_PLAINTEXT, contextName);
|
||||
tokenizer->setState(NS_HTML5TOKENIZER_PLAINTEXT);
|
||||
} else if (nsHtml5Atoms::script == contextName) {
|
||||
tokenizer->setStateAndEndTagExpectation(NS_HTML5TOKENIZER_SCRIPT_DATA, contextName);
|
||||
tokenizer->setState(NS_HTML5TOKENIZER_SCRIPT_DATA);
|
||||
} else {
|
||||
tokenizer->setStateAndEndTagExpectation(NS_HTML5TOKENIZER_DATA, contextName);
|
||||
tokenizer->setState(NS_HTML5TOKENIZER_DATA);
|
||||
}
|
||||
}
|
||||
contextName = nullptr;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/*
|
||||
* Copyright (c) 2007 Henri Sivonen
|
||||
* Copyright (c) 2007-2015 Mozilla Foundation
|
||||
* Copyright (c) 2019 Moonchild Productions
|
||||
* Portions of comments Copyright 2004-2008 Apple Computer, Inc., Mozilla
|
||||
* Foundation, and Opera Software ASA.
|
||||
*
|
||||
|
|
@ -23,11 +24,6 @@
|
|||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* THIS IS A GENERATED FILE. PLEASE DO NOT EDIT.
|
||||
* Please edit TreeBuilder.java instead and regenerate.
|
||||
*/
|
||||
|
||||
#ifndef nsHtml5TreeBuilder_h
|
||||
#define nsHtml5TreeBuilder_h
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2008-2010 Mozilla Foundation
|
||||
* Copyright (c) 2019 Moonchild Productions
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
|
|
@ -20,11 +21,6 @@
|
|||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* THIS IS A GENERATED FILE. PLEASE DO NOT EDIT.
|
||||
* Please edit UTF16Buffer.java instead and regenerate.
|
||||
*/
|
||||
|
||||
#define nsHtml5UTF16Buffer_cpp__
|
||||
|
||||
#include "nsIAtom.h"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2008-2010 Mozilla Foundation
|
||||
* Copyright (c) 2019 Moonchild Productions
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
|
|
@ -20,11 +21,6 @@
|
|||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* THIS IS A GENERATED FILE. PLEASE DO NOT EDIT.
|
||||
* Please edit UTF16Buffer.java instead and regenerate.
|
||||
*/
|
||||
|
||||
#ifndef nsHtml5UTF16Buffer_h
|
||||
#define nsHtml5UTF16Buffer_h
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ namespace mozilla
|
|||
[ref] native nsCStringTArrayRef(nsTArray<nsCString>);
|
||||
[ref] native mozillaPkixTime(mozilla::pkix::Time);
|
||||
|
||||
[scriptable, uuid(275127f8-dbd7-4681-afbf-6df0c6587a01)]
|
||||
[scriptable, uuid(233908bd-6741-4474-a6e1-f298c6ce9eaf)]
|
||||
interface nsISiteSecurityService : nsISupports
|
||||
{
|
||||
const uint32_t HEADER_HSTS = 0;
|
||||
|
|
@ -98,15 +98,21 @@ interface nsISiteSecurityService : nsISupports
|
|||
* Given a header type, removes state relating to that header of a host,
|
||||
* including the includeSubdomains state that would affect subdomains.
|
||||
* This essentially removes the state for the domain tree rooted at this
|
||||
* host.
|
||||
* host. If any preloaded information is present for that host, that
|
||||
* information will then be used instead of any other previously existing
|
||||
* state, unless the force parameter is set.
|
||||
*
|
||||
* @param aType the type of security state in question
|
||||
* @param aURI the URI of the target host
|
||||
* @param aFlags options for this request as defined in nsISocketProvider:
|
||||
* NO_PERMANENT_STORAGE
|
||||
* @param force if set, forces no-HSTS state by writing a knockout value,
|
||||
* overriding any preload list state
|
||||
*/
|
||||
void removeState(in uint32_t aType,
|
||||
in nsIURI aURI,
|
||||
in uint32_t aFlags);
|
||||
in uint32_t aFlags,
|
||||
[optional] in boolean force);
|
||||
|
||||
/**
|
||||
* See isSecureURI
|
||||
|
|
|
|||
|
|
@ -330,21 +330,22 @@ nsSiteSecurityService::SetHSTSState(uint32_t aType,
|
|||
uint32_t flags,
|
||||
SecurityPropertyState aHSTSState)
|
||||
{
|
||||
// If max-age is zero, that's an indication to immediately remove the
|
||||
// security state, so here's a shortcut.
|
||||
if (!maxage) {
|
||||
return RemoveState(aType, aSourceURI, flags);
|
||||
// Exit early if STS not enabled
|
||||
if (!mUseStsService) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// If max-age is zero, the host is no longer considered HSTS. If the host was
|
||||
// preloaded, we store an entry indicating that this host is not HSTS, causing
|
||||
// the preloaded information to be ignored.
|
||||
if (maxage == 0) {
|
||||
return RemoveState(aType, aSourceURI, flags, true);
|
||||
}
|
||||
|
||||
MOZ_ASSERT((aHSTSState == SecurityPropertySet ||
|
||||
aHSTSState == SecurityPropertyNegative),
|
||||
"HSTS State must be SecurityPropertySet or SecurityPropertyNegative");
|
||||
|
||||
// Exit early if STS not enabled
|
||||
if (!mUseStsService) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
int64_t expiretime = ExpireTimeFromMaxAge(maxage);
|
||||
SiteHSTSState siteState(expiretime, aHSTSState, includeSubdomains);
|
||||
nsAutoCString stateString;
|
||||
|
|
@ -367,7 +368,7 @@ nsSiteSecurityService::SetHSTSState(uint32_t aType,
|
|||
|
||||
NS_IMETHODIMP
|
||||
nsSiteSecurityService::RemoveState(uint32_t aType, nsIURI* aURI,
|
||||
uint32_t aFlags)
|
||||
uint32_t aFlags, bool force = false)
|
||||
{
|
||||
// Child processes are not allowed direct access to this.
|
||||
if (!XRE_IsParentProcess()) {
|
||||
|
|
@ -387,8 +388,9 @@ nsSiteSecurityService::RemoveState(uint32_t aType, nsIURI* aURI,
|
|||
mozilla::DataStorageType storageType = isPrivate
|
||||
? mozilla::DataStorage_Private
|
||||
: mozilla::DataStorage_Persistent;
|
||||
// If this host is in the preload list, we have to store a knockout entry.
|
||||
if (GetPreloadListEntry(hostname.get())) {
|
||||
// If this host is in the preload list, we have to store a knockout entry
|
||||
// if it's explicitly forced to not be HSTS anymore
|
||||
if (force && GetPreloadListEntry(hostname.get())) {
|
||||
SSSLOG(("SSS: storing knockout entry for %s", hostname.get()));
|
||||
SiteHSTSState siteState(0, SecurityPropertyKnockout, false);
|
||||
nsAutoCString stateString;
|
||||
|
|
@ -769,7 +771,10 @@ nsSiteSecurityService::ProcessPKPHeader(nsIURI* aSourceURI,
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// if maxAge == 0 we must delete all state, for now no hole-punching
|
||||
// If maxAge == 0, we remove dynamic HPKP state for this host. Due to
|
||||
// architectural constraints, if this host was preloaded, any future lookups
|
||||
// will use the preloaded state (i.e. we can't store a "this host is not HPKP"
|
||||
// entry like we can for HSTS).
|
||||
if (maxAge == 0) {
|
||||
return RemoveState(aType, aSourceURI, aFlags);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -112,7 +112,9 @@ nsThreadPool::PutEvent(already_AddRefed<nsIRunnable> aEvent, uint32_t aFlags)
|
|||
bool killThread = false;
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
if (mThreads.Count() < (int32_t)mThreadLimit) {
|
||||
if (mShutdown) {
|
||||
killThread = true; // we're in shutdown, kill the thread
|
||||
} else if (mThreads.Count() < (int32_t)mThreadLimit) {
|
||||
mThreads.AppendObject(thread);
|
||||
} else {
|
||||
killThread = true; // okay, we don't need this thread anymore
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue