Compare commits

...
Author SHA1 Message Date
Moonchild 528db2cbd8 Issue #1818 - Remove obsolete path hack in widget code. 2022-12-16 09:13:48 +00:00
Moonchild 84e6bcc1e6 [network] Align cookie checks with RFC 6265 (bis) 2022-12-16 09:13:38 +00:00
Moonchild 0dc9ff518d [libjar] Add some extra sanity checks to our Zip reader. 2022-12-16 09:13:25 +00:00
Moonchild a2e3bd44aa [network] move some generic websocket code to the baseclass 2022-12-16 09:13:09 +00:00
Moonchild 163a0e7caf Revert "Issue #1279 - Implement regular expressions lookbehind (v2)"
This reverts commit d10e8a5b06.
2022-12-15 09:11:02 +00:00
Moonchild 49a86db5f3 Issue #2040 - Pre-multiply the alpha values in our JXL decode buffer. (uplift)
Using selective calculation (only if not opaque) and fast integer
math here should optimize well in compilers.
2022-12-15 09:09:19 +00:00
Moonchild 2640953d8b Issue #2019 - Follow-up: Make nsPluginInstanceOwner also listen to keypress events in the system event group.
nsPluginInstanceOwner only listens to keypress events in the default event group.
However, in our changed operating mode, keypress events are not fired in the
default event group if the key does not result in something printable.
This means that nsPluginInstanceOwner should also listen to keypress events
in the system event group and should handle each keypress that way, but
only once. I.e., if a printable keypress event is received in the system event
group, it should be ignored, since it would've already been handled in the
default event group in that case.
2022-11-26 18:18:09 +00:00
Moonchild 7eb7d67f7a Issue #2033 - Temporary fix of R<->B channel swap.
We have a BGR/RGB channel ordering mismatch here. to at least
provide proper display, a quick&dirty byte swap on the output
buffer will fix this for now, but we should look into seeing where
the surface mismatch is caused.
std::swap() should optimize pretty well in any of the used
compilers, but if necessary, a full buffer ASM routine can be
slotted in (although on current hardware I doubt this will be
even noticeable as it is)
2022-11-26 02:43:18 +00:00
Moonchild e28860ba7f Revert "[XPCOM] Deal with lstat potentially lying in nsLocalFileUnix."
This reverts commit c127f58ef3.
2022-11-20 14:14:48 +00:00
Moonchild 49a96b1d91 Merge branch 'master' into release 2022-11-19 20:15:23 +00:00
Moonchild 3130812693 Merge branch 'master' into release 2022-11-12 18:34:07 +00:00
Moonchild 71ae69aea8 [WebGL] Implement webgl.max-size-per-texture-mib 2022-10-26 14:50:05 +00:00
Moonchild 9e34d697c7 [XPCOM] Fix Base64 off-by-one issue and safeguard against this mistake in the future. 2022-10-26 14:49:55 +00:00
Moonchild 8fa9125d02 [No issue] Hold some strong references on nsRefreshDriver 2022-10-26 14:49:46 +00:00
Brian Smith 4b4488c3e4 Issue #2022 - Part 2 - Add Ventura version detection.
Also add Monterey and Ventura to the graphics driver blocklist.
2022-10-26 14:49:33 +00:00
Brian Smith 248db7d301 Issue #2022 - Part 1 - Fix transparent windows on MacOS 13 Ventura.
During the BaseWindow creation contenView is nil on Ventura...
So create a NSView with the requested dimensions and set is as the contenView.
2022-10-26 14:49:23 +00:00
Moonchild e199f2949b [No issue] Ensure LockImpl::Try() returns the correct bool value. 2022-10-26 14:45:39 +00:00
Moonchild 456b5450a4 Issue #2010 - Ensure raw tagnames are safe exiting internalEntityParser
This resolves #2010
2022-09-28 13:50:10 +00:00
Moonchild d8e629c4a3 Merge branch 'master' into release 2022-09-27 20:12:40 +00:00
Moonchild 4898c4f297 Merge branch 'master' into release 2022-09-24 12:16:59 +00:00
Moonchild 7cd578bbc6 Merge branch 'master' into release 2022-09-22 13:16:48 +00:00
Moonchild 1e91df628a Merge branch 'master' into release 2022-09-22 11:52:16 +00:00
Moonchild b110549cbd Merge branch 'master' into release 2022-07-27 06:07:45 +00:00
Moonchild 971047835a Merge branch 'master' into release
# Conflicts:
#	config/milestone.txt
#	toolkit/mozapps/extensions/internal/XPIProvider.jsm
2022-07-25 20:47:06 +00:00
Moonchild dd4d9eb032 [XPCOM] Crash safely when TArray replacements are OOB.
In the unlikely event of TArray element replacement calls are OOB, crash safely
with a debug breakpoint instead of corrupting memory.
2022-07-03 15:49:44 +00:00
Moonchild 8b94f1e480 [DOM] use the sanitizer to restrict href in svg:use to fragment-only URLs 2022-07-03 15:49:34 +00:00
Moonchild c89610a5c7 [network] Clear PAC loader when the load failed 2022-07-03 15:49:23 +00:00
Moonchild 217963cbed Update NSS to 3.52.7 2022-07-03 15:49:14 +00:00
Moonchild c4f4e18340 [DOM media] Remove potentially unsafe type accesses when debug logging 2022-07-03 15:49:04 +00:00
Moonchild 8a7c0e7345 [network] Clean up and update the list of external protocol handlers. 2022-07-03 15:48:54 +00:00
Moonchild 52e304d450 Issue #1053 - Follow-up: Correct conditional define on POSIX systems. (uplift)
This conditional was incorrectly changed when removing Android support.
This potentially causes issues on Linux systems by not using pthreads correctly,
which may lead to high idle CPU usage.
2022-06-28 13:28:20 +00:00
Moonchild cfc0eeca53 Revert "Issue #1909 - Guard against empty update manifest URL"
This reverts commit d7fadcdef9.
2022-06-07 11:59:07 +00:00
Moonchild ebd3dd9228 Merge branch 'master' into release 2022-06-03 21:50:44 +00:00
Moonchild cb40e4e7ef Merge branch 'master' into release 2022-06-01 13:54:11 +00:00
Moonchild 662dba55fd Merge branch 'master' into release 2022-05-29 11:13:44 +00:00
Moonchild 8760ce023c Issue #1895 - Implement queueMicroTask(callback()) (uplift) 2022-05-07 14:40:14 +00:00
Moonchild b86e148bb7 Roll back milestone version to release. 2022-05-06 12:43:43 +00:00
Moonchild 9e83721e5e Merge branch 'master' into release 2022-05-06 12:43:00 +00:00
Moonchild dc2d6c2e60 Revert "No Issue - Make content-type on JAR channels behave the same as HTTP channels."
This reverts commit 425677ada7.
2022-05-03 17:38:19 +00:00
Moonchild 4ada6f6762 Update 7zSD for v31 2022-05-03 17:38:12 +00:00
24 changed files with 235 additions and 434 deletions

No files matched your search

+26 -18
View File
@@ -1480,6 +1480,16 @@ nsresult nsPluginInstanceOwner::DispatchFocusToPlugin(nsIDOMEvent* aFocusEvent)
nsresult nsPluginInstanceOwner::ProcessKeyPress(nsIDOMEvent* aKeyEvent)
{
// ProcessKeyPress() may be called twice with same eKeyPress event because we
// listen in both the default and system event groups (to capture keypresses
// potentially captured by plugins that are not printable keys).
// When this is called in the latter case and the event must be fired in the
// default event group too, we don't need to do anything else and can return.
if (!aKeyEvent->WidgetEventPtr()->mFlags.mOnlySystemGroupDispatchInContent &&
aKeyEvent->WidgetEventPtr()->mFlags.mInSystemGroup) {
return NS_OK;
}
#ifdef XP_MACOSX
return DispatchKeyToPlugin(aKeyEvent);
#else
@@ -2547,6 +2557,7 @@ nsPluginInstanceOwner::Destroy()
content->RemoveEventListener(NS_LITERAL_STRING("mouseover"), this, false);
content->RemoveEventListener(NS_LITERAL_STRING("mouseout"), this, false);
content->RemoveEventListener(NS_LITERAL_STRING("keypress"), this, true);
content->RemoveSystemEventListener(NS_LITERAL_STRING("keypress"), this, true);
content->RemoveEventListener(NS_LITERAL_STRING("keydown"), this, true);
content->RemoveEventListener(NS_LITERAL_STRING("keyup"), this, true);
content->RemoveEventListener(NS_LITERAL_STRING("drop"), this, true);
@@ -2856,25 +2867,22 @@ nsresult nsPluginInstanceOwner::Init(nsIContent* aContent)
// register context menu listener
mCXMenuListener = new nsPluginDOMContextMenuListener(aContent);
aContent->AddEventListener(NS_LITERAL_STRING("focus"), this, false,
false);
aContent->AddEventListener(NS_LITERAL_STRING("blur"), this, false,
false);
aContent->AddEventListener(NS_LITERAL_STRING("mouseup"), this, false,
false);
aContent->AddEventListener(NS_LITERAL_STRING("mousedown"), this, false,
false);
aContent->AddEventListener(NS_LITERAL_STRING("mousemove"), this, false,
false);
aContent->AddEventListener(NS_LITERAL_STRING("click"), this, false,
false);
aContent->AddEventListener(NS_LITERAL_STRING("dblclick"), this, false,
false);
aContent->AddEventListener(NS_LITERAL_STRING("mouseover"), this, false,
false);
aContent->AddEventListener(NS_LITERAL_STRING("mouseout"), this, false,
false);
aContent->AddEventListener(NS_LITERAL_STRING("focus"), this, false, false);
aContent->AddEventListener(NS_LITERAL_STRING("blur"), this, false, false);
aContent->AddEventListener(NS_LITERAL_STRING("mouseup"), this, false, false);
aContent->AddEventListener(NS_LITERAL_STRING("mousedown"), this, false, false);
aContent->AddEventListener(NS_LITERAL_STRING("mousemove"), this, false, false);
aContent->AddEventListener(NS_LITERAL_STRING("click"), this, false, false);
aContent->AddEventListener(NS_LITERAL_STRING("dblclick"), this, false, false);
aContent->AddEventListener(NS_LITERAL_STRING("mouseover"), this, false, false);
aContent->AddEventListener(NS_LITERAL_STRING("mouseout"), this, false, false);
// The "keypress" event should be handled when it's in the default event group
// if the event is fired in content.
// Otherwise, it should be handled when it's in the system event group.
aContent->AddEventListener(NS_LITERAL_STRING("keypress"), this, true);
aContent->AddSystemEventListener(NS_LITERAL_STRING("keypress"), this, true);
aContent->AddEventListener(NS_LITERAL_STRING("keydown"), this, true);
aContent->AddEventListener(NS_LITERAL_STRING("keyup"), this, true);
aContent->AddEventListener(NS_LITERAL_STRING("drop"), this, true);
+11
View File
@@ -141,6 +141,17 @@ nsJXLDecoder::ReadJXLData(const char* aData, size_t aLength)
Nothing(), SurfacePipeFlags());
for (uint8_t* rowPtr = mOutBuffer.begin(); rowPtr < mOutBuffer.end();
rowPtr += mInfo.xsize * 4) {
// FIXME: Quick and dirty BGRA to RGBA conversion.
// We currently have a channel ordering mis-match here.
for (uint8_t* pixPtr = rowPtr; pixPtr < rowPtr + mInfo.xsize * 4; pixPtr+=4){
std::swap(pixPtr[0], pixPtr[2]);
// Pre-multiply, too
if (pixPtr[3] < 255) {
pixPtr[0]=((uint16_t)pixPtr[0]*(uint16_t)pixPtr[3]) >> 8;
pixPtr[1]=((uint16_t)pixPtr[1]*(uint16_t)pixPtr[3]) >> 8;
pixPtr[2]=((uint16_t)pixPtr[2]*(uint16_t)pixPtr[3]) >> 8;
}
}
pipe->WriteBuffer(reinterpret_cast<uint32_t*>(rowPtr));
}
+3 -3
View File
@@ -3827,10 +3827,10 @@ ConvertRegExpTreeToObject(JSContext* cx, irregexp::RegExpTree* tree)
return nullptr;
return obj;
}
if (tree->IsLookaround()) {
if (!StringProp(cx, obj, "type", "Lookaround"))
if (tree->IsLookahead()) {
if (!StringProp(cx, obj, "type", "Lookahead"))
return nullptr;
irregexp::RegExpLookaround* t = tree->AsLookaround();
irregexp::RegExpLookahead* t = tree->AsLookahead();
if (!BooleanProp(cx, obj, "is_positive", t->is_positive()))
return nullptr;
if (!TreeProp(cx, obj, "body", t->body()))
@@ -568,7 +568,7 @@ NativeRegExpMacroAssembler::CheckAtStart(Label* on_at_start)
}
void
NativeRegExpMacroAssembler::CheckNotAtStart(int cp_offset, Label* on_not_at_start)
NativeRegExpMacroAssembler::CheckNotAtStart(Label* on_not_at_start)
{
JitSpew(SPEW_PREFIX "CheckNotAtStart");
@@ -659,7 +659,7 @@ NativeRegExpMacroAssembler::CheckGreedyLoop(Label* on_tos_equals_current_positio
}
void
NativeRegExpMacroAssembler::CheckNotBackReference(int start_reg, bool read_backward, Label* on_no_match)
NativeRegExpMacroAssembler::CheckNotBackReference(int start_reg, Label* on_no_match)
{
JitSpew(SPEW_PREFIX "CheckNotBackReference(%d)", start_reg);
@@ -730,8 +730,8 @@ NativeRegExpMacroAssembler::CheckNotBackReference(int start_reg, bool read_backw
}
void
NativeRegExpMacroAssembler::CheckNotBackReferenceIgnoreCase(int start_reg, bool read_backward,
Label* on_no_match, bool unicode)
NativeRegExpMacroAssembler::CheckNotBackReferenceIgnoreCase(int start_reg, Label* on_no_match,
bool unicode)
{
JitSpew(SPEW_PREFIX "CheckNotBackReferenceIgnoreCase(%d, %d)", start_reg, unicode);
+3 -4
View File
@@ -104,10 +104,9 @@ class MOZ_STACK_CLASS NativeRegExpMacroAssembler final : public RegExpMacroAssem
void CheckCharacterGT(char16_t limit, jit::Label* on_greater);
void CheckCharacterLT(char16_t limit, jit::Label* on_less);
void CheckGreedyLoop(jit::Label* on_tos_equals_current_position);
void CheckNotAtStart(int cp_offset, jit::Label* on_not_at_start);
void CheckNotBackReference(int start_reg, bool read_backward, jit::Label* on_no_match);
void CheckNotBackReferenceIgnoreCase(int start_reg, bool read_backward,
jit::Label* on_no_match, bool unicode);
void CheckNotAtStart(jit::Label* on_not_at_start);
void CheckNotBackReference(int start_reg, jit::Label* on_no_match);
void CheckNotBackReferenceIgnoreCase(int start_reg, jit::Label* on_no_match, bool unicode);
void CheckNotCharacter(unsigned c, jit::Label* on_not_equal);
void CheckNotCharacterAfterAnd(unsigned c, unsigned and_with, jit::Label* on_not_equal);
void CheckNotCharacterAfterMinusAnd(char16_t c, char16_t minus, char16_t and_with,
+4 -4
View File
@@ -249,16 +249,16 @@ RegExpCapture::CaptureRegisters()
}
// ----------------------------------------------------------------------------
// RegExpLookaround
// RegExpLookahead
Interval
RegExpLookaround::CaptureRegisters()
RegExpLookahead::CaptureRegisters()
{
return body()->CaptureRegisters();
}
bool
RegExpLookaround::IsAnchoredAtStart()
RegExpLookahead::IsAnchoredAtStart()
{
return is_positive() && type() == LOOKAHEAD && body()->IsAnchoredAtStart();
return is_positive() && body()->IsAnchoredAtStart();
}
+10 -23
View File
@@ -359,7 +359,6 @@ class RegExpCapture : public RegExpTree
virtual int min_match() { return body_->min_match(); }
virtual int max_match() { return body_->max_match(); }
RegExpTree* body() { return body_; }
void set_body(RegExpTree* body) { body_ = body; }
int index() { return index_; }
static int StartRegister(int index) { return index * 2; }
static int EndRegister(int index) { return index * 2 + 1; }
@@ -369,29 +368,25 @@ class RegExpCapture : public RegExpTree
int index_;
};
class RegExpLookaround : public RegExpTree
class RegExpLookahead : public RegExpTree
{
public:
enum Type { LOOKAHEAD, LOOKBEHIND };
RegExpLookaround(RegExpTree* body,
bool is_positive,
int capture_count,
int capture_from,
Type type)
RegExpLookahead(RegExpTree* body,
bool is_positive,
int capture_count,
int capture_from)
: body_(body),
is_positive_(is_positive),
capture_count_(capture_count),
capture_from_(capture_from),
type_(type)
capture_from_(capture_from)
{}
virtual void* Accept(RegExpVisitor* visitor, void* data);
virtual RegExpNode* ToNode(RegExpCompiler* compiler,
RegExpNode* on_success);
virtual RegExpLookaround* AsLookaround();
virtual RegExpLookahead* AsLookahead();
virtual Interval CaptureRegisters();
virtual bool IsLookaround();
virtual bool IsLookahead();
virtual bool IsAnchoredAtStart();
virtual int min_match() { return 0; }
virtual int max_match() { return 0; }
@@ -399,14 +394,12 @@ class RegExpLookaround : public RegExpTree
bool is_positive() { return is_positive_; }
int capture_count() { return capture_count_; }
int capture_from() { return capture_from_; }
Type type() { return type_; }
private:
RegExpTree* body_;
bool is_positive_;
int capture_count_;
int capture_from_;
Type type_;
};
typedef InfallibleVector<RegExpCapture*, 1> RegExpCaptureVector;
@@ -423,14 +416,8 @@ class RegExpBackReference : public RegExpTree
RegExpNode* on_success);
virtual RegExpBackReference* AsBackReference();
virtual bool IsBackReference();
virtual int min_match() override { return 0; }
// The capture may not be completely parsed yet, if the reference occurs
// before the capture. In the ordinary case, nothing has been captured yet,
// so the back reference must have the length 0. If the back reference is
// inside a lookbehind, effectively making it a forward reference, we return
virtual int max_match() override {
return capture_->body() ? capture_->max_match() : 0;
}
virtual int min_match() { return 0; }
virtual int max_match() { return capture_->max_match(); }
int index() { return capture_->index(); }
RegExpCapture* capture() { return capture_; }
private:
+10 -13
View File
@@ -81,19 +81,16 @@ V(CHECK_LT, 35, 8) /* bc8 pad8 uc16 addr32 */ \
V(CHECK_GT, 36, 8) /* bc8 pad8 uc16 addr32 */ \
V(CHECK_NOT_BACK_REF, 37, 8) /* bc8 reg_idx24 addr32 */ \
V(CHECK_NOT_BACK_REF_NO_CASE, 38, 8) /* bc8 reg_idx24 addr32 */ \
V(CHECK_NOT_BACK_REF_BACKWARD, 39, 8) /* bc8 reg_idx24 addr32 */ \
V(CHECK_NOT_BACK_REF_NO_CASE_BACKWARD, 40, 8) /* bc8 reg_idx24 addr32 */ \
V(CHECK_NOT_REGS_EQUAL, 41, 12) /* bc8 regidx24 reg_idx32 addr32 */ \
V(CHECK_REGISTER_LT, 42, 12) /* bc8 reg_idx24 value32 addr32 */ \
V(CHECK_REGISTER_GE, 43, 12) /* bc8 reg_idx24 value32 addr32 */ \
V(CHECK_REGISTER_EQ_POS, 44, 8) /* bc8 reg_idx24 addr32 */ \
V(CHECK_AT_START, 45, 8) /* bc8 pad24 addr32 */ \
V(CHECK_NOT_AT_START, 46, 8) /* bc8 pad24 addr32 */ \
V(CHECK_GREEDY, 47, 8) /* bc8 pad24 addr32 */ \
V(ADVANCE_CP_AND_GOTO, 48, 8) /* bc8 offset24 addr32 */ \
V(SET_CURRENT_POSITION_FROM_END, 49, 4) /* bc8 idx24 */ \
V(CHECK_NOT_BACK_REF_NO_CASE_UNICODE, 50, 8) /* bc8 reg_idx24 addr32 */ \
V(CHECK_NOT_BACK_REF_NO_CASE_BACKWARD_UNICODE, 51, 8) /* bc8 reg_idx24 addr32 */
V(CHECK_NOT_REGS_EQUAL, 39, 12) /* bc8 regidx24 reg_idx32 addr32 */ \
V(CHECK_REGISTER_LT, 40, 12) /* bc8 reg_idx24 value32 addr32 */ \
V(CHECK_REGISTER_GE, 41, 12) /* bc8 reg_idx24 value32 addr32 */ \
V(CHECK_REGISTER_EQ_POS, 42, 8) /* bc8 reg_idx24 addr32 */ \
V(CHECK_AT_START, 43, 8) /* bc8 pad24 addr32 */ \
V(CHECK_NOT_AT_START, 44, 8) /* bc8 pad24 addr32 */ \
V(CHECK_GREEDY, 45, 8) /* bc8 pad24 addr32 */ \
V(ADVANCE_CP_AND_GOTO, 46, 8) /* bc8 offset24 addr32 */ \
V(SET_CURRENT_POSITION_FROM_END, 47, 4) /* bc8 idx24 */ \
V(CHECK_NOT_BACK_REF_NO_CASE_UNICODE, 48, 8) /* bc8 reg_idx24 addr32 */
#define DECLARE_BYTECODES(name, code, length) \
static const int BC_##name = code;
+55 -94
View File
@@ -720,8 +720,6 @@ ActionNode::EmptyMatchCheck(int start_register,
int
TextNode::EatsAtLeast(int still_to_find, int budget, bool not_at_start)
{
if (read_backward())
return 0;
int answer = Length();
if (answer >= still_to_find)
return answer;
@@ -737,7 +735,8 @@ TextNode::EatsAtLeast(int still_to_find, int budget, bool not_at_start)
int
TextNode::GreedyLoopTextLength()
{
return Length();
TextElement elm = elements()[elements().length() - 1];
return elm.cp_offset() + elm.length();
}
RegExpNode*
@@ -887,8 +886,6 @@ AssertionNode::FillInBMInfo(int offset, int budget, BoyerMooreLookahead* bm, boo
int
BackReferenceNode::EatsAtLeast(int still_to_find, int budget, bool not_at_start)
{
if (read_backward())
return 0;
if (budget <= 0)
return 0;
return on_success()->EatsAtLeast(still_to_find, budget - 1, not_at_start);
@@ -1580,9 +1577,6 @@ class irregexp::RegExpCompiler
current_expansion_factor_ = value;
}
bool read_backward() { return read_backward_; }
void set_read_backward(bool value) { read_backward_ = value; }
JSContext* cx() const { return cx_; }
LifoAlloc* alloc() const { return alloc_; }
@@ -1600,7 +1594,6 @@ class irregexp::RegExpCompiler
bool unicode_;
bool reg_exp_too_big_;
int current_expansion_factor_;
bool read_backward_;
FrequencyCollator frequency_collator_;
JSContext* cx_;
LifoAlloc* alloc_;
@@ -1630,7 +1623,6 @@ RegExpCompiler::RegExpCompiler(JSContext* cx, LifoAlloc* alloc, int capture_coun
unicode_(unicode),
reg_exp_too_big_(false),
current_expansion_factor_(1),
read_backward_(false),
frequency_collator_(),
cx_(cx),
alloc_(alloc)
@@ -1754,7 +1746,7 @@ irregexp::CompilePattern(JSContext* cx, RegExpShared* shared, RegExpCompileData*
// at the start of input.
ChoiceNode* first_step_node = alloc.newInfallible<ChoiceNode>(&alloc, 2);
RegExpNode* char_class =
alloc.newInfallible<TextNode>(alloc.newInfallible<RegExpCharacterClass>('*'), false, loop_node);
alloc.newInfallible<TextNode>(alloc.newInfallible<RegExpCharacterClass>('*'), loop_node);
first_step_node->AddAlternative(GuardedAlternative(captured_body));
first_step_node->AddAlternative(GuardedAlternative(char_class));
node = first_step_node;
@@ -1857,19 +1849,19 @@ RegExpAtom::ToNode(RegExpCompiler* compiler, RegExpNode* on_success)
TextElementVector* elms =
compiler->alloc()->newInfallible<TextElementVector>(*compiler->alloc());
elms->append(TextElement::Atom(this));
return compiler->alloc()->newInfallible<TextNode>(elms, compiler->read_backward(), on_success);
return compiler->alloc()->newInfallible<TextNode>(elms, on_success);
}
RegExpNode*
RegExpText::ToNode(RegExpCompiler* compiler, RegExpNode* on_success)
{
return compiler->alloc()->newInfallible<TextNode>(&elements_, compiler->read_backward(), on_success);
return compiler->alloc()->newInfallible<TextNode>(&elements_, on_success);
}
RegExpNode*
RegExpCharacterClass::ToNode(RegExpCompiler* compiler, RegExpNode* on_success)
{
return compiler->alloc()->newInfallible<TextNode>(this, compiler->read_backward(), on_success);
return compiler->alloc()->newInfallible<TextNode>(this, on_success);
}
RegExpNode*
@@ -2010,8 +2002,7 @@ RegExpQuantifier::ToNode(int min,
alternation->AddAlternative(GuardedAlternative(body->ToNode(compiler, answer)));
}
answer = alternation;
if (not_at_start && !compiler->read_backward())
alternation->set_not_at_start();
if (not_at_start) alternation->set_not_at_start();
}
return answer;
}
@@ -2023,9 +2014,8 @@ RegExpQuantifier::ToNode(int min,
int reg_ctr = needs_counter
? compiler->AllocateRegister()
: RegExpCompiler::kNoRegister;
LoopChoiceNode* center = alloc->newInfallible<LoopChoiceNode>(alloc, body->min_match() == 0,
compiler->read_backward());
if (not_at_start && !compiler->read_backward())
LoopChoiceNode* center = alloc->newInfallible<LoopChoiceNode>(alloc, body->min_match() == 0);
if (not_at_start)
center->set_not_at_start();
RegExpNode* loop_return = needs_counter
? static_cast<RegExpNode*>(ActionNode::IncrementRegister(reg_ctr, center))
@@ -2101,7 +2091,7 @@ RegExpAssertion::ToNode(RegExpCompiler* compiler,
CharacterRange::AddClassEscape(alloc, 'n', newline_ranges);
RegExpCharacterClass* newline_atom = alloc->newInfallible<RegExpCharacterClass>('n');
TextNode* newline_matcher =
alloc->newInfallible<TextNode>(newline_atom, false,
alloc->newInfallible<TextNode>(newline_atom,
ActionNode::PositiveSubmatchSuccess(stack_pointer_register,
position_register,
0, // No captures inside.
@@ -2133,7 +2123,6 @@ RegExpBackReference::ToNode(RegExpCompiler* compiler, RegExpNode* on_success)
{
return compiler->alloc()->newInfallible<BackReferenceNode>(RegExpCapture::StartRegister(index()),
RegExpCapture::EndRegister(index()),
compiler->read_backward(),
on_success);
}
@@ -2144,7 +2133,7 @@ RegExpEmpty::ToNode(RegExpCompiler* compiler, RegExpNode* on_success)
}
RegExpNode*
RegExpLookaround::ToNode(RegExpCompiler* compiler, RegExpNode* on_success)
RegExpLookahead::ToNode(RegExpCompiler* compiler, RegExpNode* on_success)
{
int stack_pointer_register = compiler->AllocateRegister();
int position_register = compiler->AllocateRegister();
@@ -2155,10 +2144,6 @@ RegExpLookaround::ToNode(RegExpCompiler* compiler, RegExpNode* on_success)
int register_start =
register_of_first_capture + capture_from_ * registers_per_capture;
RegExpNode* result;
bool was_reading_backward = compiler->read_backward();
compiler->set_read_backward(type() == LOOKBEHIND);
if (is_positive()) {
RegExpNode* bodyNode =
body()->ToNode(compiler,
@@ -2167,39 +2152,37 @@ RegExpLookaround::ToNode(RegExpCompiler* compiler, RegExpNode* on_success)
register_count,
register_start,
on_success));
result = ActionNode::BeginSubmatch(stack_pointer_register,
position_register,
bodyNode);
} else {
// We use a ChoiceNode for a negative lookahead because it has most of
// the characteristics we need. It has the body of the lookahead as its
// first alternative and the expression after the lookahead of the second
// alternative. If the first alternative succeeds then the
// NegativeSubmatchSuccess will unwind the stack including everything the
// choice node set up and backtrack. If the first alternative fails then
// the second alternative is tried, which is exactly the desired result
// for a negative lookahead. The NegativeLookaheadChoiceNode is a special
// ChoiceNode that knows to ignore the first exit when calculating quick
// checks.
LifoAlloc* alloc = compiler->alloc();
RegExpNode* success =
alloc->newInfallible<NegativeSubmatchSuccess>(alloc,
stack_pointer_register,
position_register,
register_count,
register_start);
GuardedAlternative body_alt(body()->ToNode(compiler, success));
ChoiceNode* choice_node =
alloc->newInfallible<NegativeLookaheadChoiceNode>(alloc, body_alt, GuardedAlternative(on_success));
result = ActionNode::BeginSubmatch(stack_pointer_register,
return ActionNode::BeginSubmatch(stack_pointer_register,
position_register,
choice_node);
bodyNode);
}
compiler->set_read_backward(was_reading_backward);
return result;
// We use a ChoiceNode for a negative lookahead because it has most of
// the characteristics we need. It has the body of the lookahead as its
// first alternative and the expression after the lookahead of the second
// alternative. If the first alternative succeeds then the
// NegativeSubmatchSuccess will unwind the stack including everything the
// choice node set up and backtrack. If the first alternative fails then
// the second alternative is tried, which is exactly the desired result
// for a negative lookahead. The NegativeLookaheadChoiceNode is a special
// ChoiceNode that knows to ignore the first exit when calculating quick
// checks.
LifoAlloc* alloc = compiler->alloc();
RegExpNode* success =
alloc->newInfallible<NegativeSubmatchSuccess>(alloc,
stack_pointer_register,
position_register,
register_count,
register_start);
GuardedAlternative body_alt(body()->ToNode(compiler, success));
ChoiceNode* choice_node =
alloc->newInfallible<NegativeLookaheadChoiceNode>(alloc, body_alt, GuardedAlternative(on_success));
return ActionNode::BeginSubmatch(stack_pointer_register,
position_register,
choice_node);
}
RegExpNode*
@@ -2214,14 +2197,8 @@ RegExpCapture::ToNode(RegExpTree* body,
RegExpCompiler* compiler,
RegExpNode* on_success)
{
MOZ_ASSERT(body);
int start_reg = RegExpCapture::StartRegister(index);
int end_reg = RegExpCapture::EndRegister(index);
if (compiler->read_backward()) {
// std::swap(start_reg, end_reg);
start_reg = RegExpCapture::EndRegister(index);
end_reg = RegExpCapture::StartRegister(index);
}
RegExpNode* store_end = ActionNode::StorePosition(end_reg, true, on_success);
RegExpNode* body_node = body->ToNode(compiler, store_end);
return ActionNode::StorePosition(start_reg, true, body_node);
@@ -2232,15 +2209,8 @@ RegExpAlternative::ToNode(RegExpCompiler* compiler, RegExpNode* on_success)
{
const RegExpTreeVector& children = nodes();
RegExpNode* current = on_success;
if (compiler->read_backward()) {
for (int i = 0; i < children.length(); i++) {
current = children[i]->ToNode(compiler, current);
}
} else {
for (int i = children.length() - 1; i >= 0; i--) {
current = children[i]->ToNode(compiler, current);
}
}
for (int i = children.length() - 1; i >= 0; i--)
current = children[i]->ToNode(compiler, current);
return current;
}
@@ -2793,6 +2763,7 @@ Trace::InvalidateCurrentCharacter()
void
Trace::AdvanceCurrentPositionInTrace(int by, RegExpCompiler* compiler)
{
MOZ_ASSERT(by > 0);
// We don't have an instruction for shifting the current character register
// down or for using a shifted value for anything so lets just forget that
// we preloaded any characters into it.
@@ -3137,9 +3108,9 @@ AssertionNode::Emit(RegExpCompiler* compiler, Trace* trace)
return;
}
if (trace->at_start() == Trace::UNKNOWN) {
assembler->CheckNotAtStart(trace->cp_offset(), trace->backtrack());
assembler->CheckNotAtStart(trace->backtrack());
Trace at_start_trace = *trace;
at_start_trace.set_at_start(Trace::TRUE_VALUE);
at_start_trace.set_at_start(true);
on_success()->Emit(compiler, &at_start_trace);
return;
}
@@ -3842,10 +3813,9 @@ TextNode::TextEmitPass(RegExpCompiler* compiler,
jit::Label* backtrack = trace->backtrack();
QuickCheckDetails* quick_check = trace->quick_check_performed();
int element_count = elements().length();
int backward_offset = read_backward() ? -Length() : 0;
for (int i = preloaded ? 0 : element_count - 1; i >= 0; i--) {
TextElement elm = elements()[i];
int cp_offset = trace->cp_offset() + elm.cp_offset() + backward_offset;
int cp_offset = trace->cp_offset() + elm.cp_offset();
if (elm.text_type() == TextElement::ATOM) {
const CharacterVector& quarks = elm.atom()->data();
for (int j = preloaded ? 0 : quarks.length() - 1; j >= 0; j--) {
@@ -3873,12 +3843,11 @@ TextNode::TextEmitPass(RegExpCompiler* compiler,
break;
}
if (emit_function != nullptr) {
bool bounds_check = *checked_up_to < cp_offset + j || read_backward();
bool bound_checked = emit_function(compiler,
quarks[j],
backtrack,
cp_offset + j,
bounds_check,
*checked_up_to < cp_offset + j,
preloaded);
if (bound_checked) UpdateBoundsCheck(cp_offset + j, checked_up_to);
}
@@ -3889,14 +3858,13 @@ TextNode::TextEmitPass(RegExpCompiler* compiler,
if (first_element_checked && i == 0) continue;
if (DeterminedAlready(quick_check, elm.cp_offset())) continue;
RegExpCharacterClass* cc = elm.char_class();
bool bounds_check = *checked_up_to < cp_offset || read_backward();
EmitCharClass(alloc(),
assembler,
cc,
ascii,
backtrack,
cp_offset,
bounds_check,
*checked_up_to < cp_offset,
preloaded);
UpdateBoundsCheck(cp_offset, checked_up_to);
}
@@ -3976,11 +3944,8 @@ TextNode::Emit(RegExpCompiler* compiler, Trace* trace)
}
Trace successor_trace(*trace);
// If we advance backward, we may end up at the start.
successor_trace.AdvanceCurrentPositionInTrace(
read_backward() ? -Length() : Length(), compiler);
successor_trace.set_at_start(read_backward() ? Trace::UNKNOWN
: Trace::FALSE_VALUE);
successor_trace.set_at_start(false);
successor_trace.AdvanceCurrentPositionInTrace(Length(), compiler);
RecursionCheck rc(compiler);
on_success()->Emit(compiler, &successor_trace);
}
@@ -4152,8 +4117,6 @@ ChoiceNode::CalculatePreloadCharacters(RegExpCompiler* compiler, int eats_at_lea
RegExpNode*
TextNode::GetSuccessorOfOmnivorousTextNode(RegExpCompiler* compiler)
{
if (read_backward()) return NULL;
if (elements().length() != 1)
return nullptr;
@@ -4201,7 +4164,7 @@ ChoiceNode::GreedyLoopTextLengthForAlternative(GuardedAlternative* alternative)
SeqRegExpNode* seq_node = static_cast<SeqRegExpNode*>(node);
node = seq_node->on_success();
}
return read_backward() ? -length : length;
return length;
}
// Creates a list of AlternativeGenerations. If the list has a reasonable
@@ -4276,7 +4239,7 @@ ChoiceNode::Emit(RegExpCompiler* compiler, Trace* trace)
jit::Label greedy_loop_label;
Trace counter_backtrack_trace;
counter_backtrack_trace.set_backtrack(&greedy_loop_label);
if (not_at_start()) counter_backtrack_trace.set_at_start(Trace::FALSE_VALUE);
if (not_at_start()) counter_backtrack_trace.set_at_start(false);
if (choice_count > 1 && text_length != kNodeIsTooComplexForGreedyLoops) {
// Here we have special handling for greedy loops containing only text nodes
@@ -4292,7 +4255,7 @@ ChoiceNode::Emit(RegExpCompiler* compiler, Trace* trace)
current_trace = &counter_backtrack_trace;
jit::Label greedy_match_failed;
Trace greedy_match_trace;
if (not_at_start()) greedy_match_trace.set_at_start(Trace::FALSE_VALUE);
if (not_at_start()) greedy_match_trace.set_at_start(false);
greedy_match_trace.set_backtrack(&greedy_match_failed);
jit::Label loop_label;
macro_assembler->Bind(&loop_label);
@@ -4641,14 +4604,11 @@ BackReferenceNode::Emit(RegExpCompiler* compiler, Trace* trace)
MOZ_ASSERT(start_reg_ + 1 == end_reg_);
if (compiler->ignore_case()) {
assembler->CheckNotBackReferenceIgnoreCase(start_reg_,
read_backward(),
trace->backtrack(),
compiler->unicode());
} else {
assembler->CheckNotBackReference(start_reg_, read_backward(), trace->backtrack());
assembler->CheckNotBackReference(start_reg_, trace->backtrack());
}
// We are going to advance backward, so we may end up at the start.
if (read_backward()) trace->set_at_start(Trace::UNKNOWN);
on_success()->Emit(compiler, trace);
}
@@ -5016,6 +4976,7 @@ QuickCheckDetails::Clear()
void
QuickCheckDetails::Advance(int by, bool ascii)
{
MOZ_ASSERT(by >= 0);
if (by >= characters_) {
Clear();
return;
+8 -23
View File
@@ -118,7 +118,7 @@ InterpretCode(JSContext* cx, const uint8_t* byteCode, const CharT* chars, size_t
VISIT(Atom) \
VISIT(Quantifier) \
VISIT(Capture) \
VISIT(Lookaround) \
VISIT(Lookahead) \
VISIT(BackReference) \
VISIT(Empty) \
VISIT(Text)
@@ -762,19 +762,15 @@ class TextNode : public SeqRegExpNode
{
public:
TextNode(TextElementVector* elements,
bool read_backward,
RegExpNode* on_success)
: SeqRegExpNode(on_success),
elements_(elements),
read_backward_(read_backward)
elements_(elements)
{}
TextNode(RegExpCharacterClass* that,
bool read_backward,
RegExpNode* on_success)
: SeqRegExpNode(on_success),
elements_(alloc()->newInfallible<TextElementVector>(*alloc())),
read_backward_(read_backward)
elements_(alloc()->newInfallible<TextElementVector>(*alloc()))
{
elements_->append(TextElement::CharClass(that));
}
@@ -787,7 +783,6 @@ class TextNode : public SeqRegExpNode
int characters_filled_in,
bool not_at_start);
TextElementVector& elements() { return *elements_; }
bool read_backward() { return read_backward_; }
void MakeCaseIndependent(bool is_ascii, bool unicode);
virtual int GreedyLoopTextLength();
virtual RegExpNode* GetSuccessorOfOmnivorousTextNode(
@@ -818,7 +813,6 @@ class TextNode : public SeqRegExpNode
int* checked_up_to);
int Length();
TextElementVector* elements_;
bool read_backward_;
};
class AssertionNode : public SeqRegExpNode
@@ -887,18 +881,15 @@ class BackReferenceNode : public SeqRegExpNode
public:
BackReferenceNode(int start_reg,
int end_reg,
bool read_backward,
RegExpNode* on_success)
: SeqRegExpNode(on_success),
start_reg_(start_reg),
end_reg_(end_reg),
read_backward_(read_backward)
end_reg_(end_reg)
{}
virtual void Accept(NodeVisitor* visitor);
int start_register() { return start_reg_; }
int end_register() { return end_reg_; }
bool read_backward() { return read_backward_; }
virtual void Emit(RegExpCompiler* compiler, Trace* trace);
virtual int EatsAtLeast(int still_to_find,
int recursion_depth,
@@ -917,7 +908,6 @@ class BackReferenceNode : public SeqRegExpNode
private:
int start_reg_;
int end_reg_;
bool read_backward_;
};
class EndNode : public RegExpNode
@@ -1062,7 +1052,6 @@ class ChoiceNode : public RegExpNode
void set_being_calculated(bool b) { being_calculated_ = b; }
virtual bool try_to_emit_quick_check_for_alternative(int i) { return true; }
virtual RegExpNode* FilterASCII(int depth, bool ignore_case, bool unicode);
virtual bool read_backward() { return false; }
protected:
int GreedyLoopTextLengthForAlternative(GuardedAlternative* alternative);
@@ -1121,13 +1110,11 @@ class NegativeLookaheadChoiceNode : public ChoiceNode
class LoopChoiceNode : public ChoiceNode
{
public:
explicit LoopChoiceNode(LifoAlloc* alloc, bool body_can_be_zero_length,
bool read_backward)
explicit LoopChoiceNode(LifoAlloc* alloc, bool body_can_be_zero_length)
: ChoiceNode(alloc, 2),
loop_node_(nullptr),
continue_node_(nullptr),
body_can_be_zero_length_(body_can_be_zero_length),
read_backward_(read_backward)
body_can_be_zero_length_(body_can_be_zero_length)
{}
void AddLoopAlternative(GuardedAlternative alt);
@@ -1145,7 +1132,6 @@ class LoopChoiceNode : public ChoiceNode
RegExpNode* loop_node() { return loop_node_; }
RegExpNode* continue_node() { return continue_node_; }
bool body_can_be_zero_length() { return body_can_be_zero_length_; }
virtual bool read_backward() { return read_backward_; }
virtual void Accept(NodeVisitor* visitor);
virtual RegExpNode* FilterASCII(int depth, bool ignore_case, bool unicode);
@@ -1160,7 +1146,6 @@ class LoopChoiceNode : public ChoiceNode
RegExpNode* loop_node_;
RegExpNode* continue_node_;
bool body_can_be_zero_length_;
bool read_backward_;
};
// Improve the speed that we scan for an initial point where a non-anchored
@@ -1436,8 +1421,8 @@ class Trace
}
TriBool at_start() { return at_start_; }
void set_at_start(TriBool at_start) {
at_start_ = at_start;
void set_at_start(bool at_start) {
at_start_ = at_start ? TRUE_VALUE : FALSE_VALUE;
}
jit::Label* backtrack() { return backtrack_; }
jit::Label* loop_label() { return loop_label_; }
+5 -69
View File
@@ -221,8 +221,8 @@ irregexp::InterpretCode(JSContext* cx, const uint8_t* byteCode, const CharT* cha
}
break;
BYTECODE(LOAD_CURRENT_CHAR) {
int pos = current + (insn >> BYTECODE_SHIFT);
if (pos >= (int)length || pos < 0) {
size_t pos = current + (insn >> BYTECODE_SHIFT);
if (pos >= length) {
pc = byteCode + Load32Aligned(pc + 4);
} else {
current_char = chars[pos];
@@ -237,8 +237,8 @@ irregexp::InterpretCode(JSContext* cx, const uint8_t* byteCode, const CharT* cha
break;
}
BYTECODE(LOAD_2_CURRENT_CHARS) {
int pos = current + (insn >> BYTECODE_SHIFT);
if (pos + 2 > (int)length || pos < 0) {
size_t pos = current + (insn >> BYTECODE_SHIFT);
if (pos + 2 > length) {
pc = byteCode + Load32Aligned(pc + 4);
} else {
CharT next = chars[pos + 1];
@@ -424,30 +424,6 @@ irregexp::InterpretCode(JSContext* cx, const uint8_t* byteCode, const CharT* cha
pc += BC_CHECK_NOT_BACK_REF_LENGTH;
break;
}
BYTECODE(CHECK_NOT_BACK_REF_BACKWARD) {
int from = registers[insn >> BYTECODE_SHIFT];
int len = registers[(insn >> BYTECODE_SHIFT) + 1] - from;
if (from < 0 || len <= 0) {
pc += BC_CHECK_NOT_BACK_REF_BACKWARD_LENGTH;
break;
}
if (int(current) - len < 0) {
pc = byteCode + Load32Aligned(pc + 4);
break;
} else {
int i;
for (i = 0; i < len; i++) {
if (chars[from + i] != chars[int(current) - len + i]) {
pc = byteCode + Load32Aligned(pc + 4);
break;
}
}
if (i < len) break;
current -= len;
}
pc += BC_CHECK_NOT_BACK_REF_BACKWARD_LENGTH;
break;
}
BYTECODE(CHECK_NOT_BACK_REF_NO_CASE) {
int from = registers[insn >> BYTECODE_SHIFT];
int len = registers[(insn >> BYTECODE_SHIFT) + 1] - from;
@@ -488,46 +464,6 @@ irregexp::InterpretCode(JSContext* cx, const uint8_t* byteCode, const CharT* cha
}
break;
}
BYTECODE(CHECK_NOT_BACK_REF_NO_CASE_BACKWARD) {
int from = registers[insn >> BYTECODE_SHIFT];
int len = registers[(insn >> BYTECODE_SHIFT) + 1] - from;
if (from < 0 || len <= 0) {
pc += BC_CHECK_NOT_BACK_REF_NO_CASE_BACKWARD_LENGTH;
break;
}
if (int(current) - len < 0) {
pc = byteCode + Load32Aligned(pc + 4);
break;
}
if (CaseInsensitiveCompareStrings(chars + from, chars + int(current) - len, len * sizeof(CharT))) {
current -= len;
pc += BC_CHECK_NOT_BACK_REF_NO_CASE_BACKWARD_LENGTH;
} else {
pc = byteCode + Load32Aligned(pc + 4);
}
break;
}
BYTECODE(CHECK_NOT_BACK_REF_NO_CASE_BACKWARD_UNICODE) {
int from = registers[insn >> BYTECODE_SHIFT];
int len = registers[(insn >> BYTECODE_SHIFT) + 1] - from;
if (from < 0 || len <= 0) {
pc += BC_CHECK_NOT_BACK_REF_NO_CASE_BACKWARD_LENGTH;
break;
}
if (int(current) - len < 0) {
pc = byteCode + Load32Aligned(pc + 4);
break;
}
if (CaseInsensitiveCompareUCStrings(chars + from, chars + int(current) - len, len * sizeof(CharT))) {
current -= len;
pc += BC_CHECK_NOT_BACK_REF_NO_CASE_BACKWARD_LENGTH;
} else {
pc = byteCode + Load32Aligned(pc + 4);
}
break;
}
BYTECODE(CHECK_AT_START)
if (current == 0)
pc = byteCode + Load32Aligned(pc + 4);
@@ -535,7 +471,7 @@ irregexp::InterpretCode(JSContext* cx, const uint8_t* byteCode, const CharT* cha
pc += BC_CHECK_AT_START_LENGTH;
break;
BYTECODE(CHECK_NOT_AT_START)
if (current + (insn >> BYTECODE_SHIFT) == 0)
if (current == 0)
pc += BC_CHECK_NOT_AT_START_LENGTH;
else
pc = byteCode + Load32Aligned(pc + 4);
+6 -11
View File
@@ -225,37 +225,32 @@ InterpretedRegExpMacroAssembler::CheckGreedyLoop(jit::Label* on_tos_equals_curre
}
void
InterpretedRegExpMacroAssembler::CheckNotAtStart(int cp_offset, jit::Label* on_not_at_start)
InterpretedRegExpMacroAssembler::CheckNotAtStart(jit::Label* on_not_at_start)
{
Emit(BC_CHECK_NOT_AT_START, cp_offset);
Emit(BC_CHECK_NOT_AT_START, 0);
EmitOrLink(on_not_at_start);
}
void
InterpretedRegExpMacroAssembler::CheckNotBackReference(int start_reg, bool read_backward,
jit::Label* on_no_match)
InterpretedRegExpMacroAssembler::CheckNotBackReference(int start_reg, jit::Label* on_no_match)
{
MOZ_ASSERT(start_reg >= 0);
MOZ_ASSERT(start_reg <= kMaxRegister);
Emit(read_backward ? BC_CHECK_NOT_BACK_REF_BACKWARD : BC_CHECK_NOT_BACK_REF,
start_reg);
Emit(BC_CHECK_NOT_BACK_REF, start_reg);
EmitOrLink(on_no_match);
}
void
InterpretedRegExpMacroAssembler::CheckNotBackReferenceIgnoreCase(int start_reg,
bool read_backward,
jit::Label* on_no_match,
bool unicode)
{
MOZ_ASSERT(start_reg >= 0);
MOZ_ASSERT(start_reg <= kMaxRegister);
if (unicode)
Emit(read_backward ? BC_CHECK_NOT_BACK_REF_NO_CASE_BACKWARD_UNICODE : BC_CHECK_NOT_BACK_REF_NO_CASE_UNICODE,
start_reg);
Emit(BC_CHECK_NOT_BACK_REF_NO_CASE_UNICODE, start_reg);
else
Emit(read_backward ? BC_CHECK_NOT_BACK_REF_NO_CASE_BACKWARD : BC_CHECK_NOT_BACK_REF_NO_CASE,
start_reg);
Emit(BC_CHECK_NOT_BACK_REF_NO_CASE, start_reg);
EmitOrLink(on_no_match);
}
+7 -8
View File
@@ -109,10 +109,10 @@ class MOZ_STACK_CLASS RegExpMacroAssembler
virtual void CheckCharacterGT(char16_t limit, jit::Label* on_greater) = 0;
virtual void CheckCharacterLT(char16_t limit, jit::Label* on_less) = 0;
virtual void CheckGreedyLoop(jit::Label* on_tos_equals_current_position) = 0;
virtual void CheckNotAtStart(int cp_offset, jit::Label* on_not_at_start) = 0;
virtual void CheckNotBackReference(int start_reg, bool read_backward, jit::Label* on_no_match) = 0;
virtual void CheckNotBackReferenceIgnoreCase(int start_reg, bool read_backward,
jit::Label* on_no_match, bool unicode) = 0;
virtual void CheckNotAtStart(jit::Label* on_not_at_start) = 0;
virtual void CheckNotBackReference(int start_reg, jit::Label* on_no_match) = 0;
virtual void CheckNotBackReferenceIgnoreCase(int start_reg, jit::Label* on_no_match,
bool unicode) = 0;
// Check the current character for a match with a literal character. If we
// fail to match then goto the on_failure label. End of input always
@@ -244,10 +244,9 @@ class MOZ_STACK_CLASS InterpretedRegExpMacroAssembler final : public RegExpMacro
void CheckCharacterGT(char16_t limit, jit::Label* on_greater);
void CheckCharacterLT(char16_t limit, jit::Label* on_less);
void CheckGreedyLoop(jit::Label* on_tos_equals_current_position);
void CheckNotAtStart(int cp_offset, jit::Label* on_not_at_start);
void CheckNotBackReference(int start_reg, bool read_backward, jit::Label* on_no_match);
void CheckNotBackReferenceIgnoreCase(int start_reg, bool read_backward,
jit::Label* on_no_match, bool unicode);
void CheckNotAtStart(jit::Label* on_not_at_start);
void CheckNotBackReference(int start_reg, jit::Label* on_no_match);
void CheckNotBackReferenceIgnoreCase(int start_reg, jit::Label* on_no_match, bool unicode);
void CheckNotCharacter(unsigned c, jit::Label* on_not_equal);
void CheckNotCharacterAfterAnd(unsigned c, unsigned and_with, jit::Label* on_not_equal);
void CheckNotCharacterAfterMinusAnd(char16_t c, char16_t minus, char16_t and_with,
+41 -89
View File
@@ -226,7 +226,6 @@ RegExpParser<CharT>::RegExpParser(frontend::TokenStream& ts, LifoAlloc* alloc,
alloc(alloc),
captures_(nullptr),
next_pos_(chars),
captures_started_(0),
end_(end),
current_(kEndMarker),
capture_count_(0),
@@ -419,8 +418,7 @@ RangeAtom(LifoAlloc* alloc, char16_t from, char16_t to)
static inline RegExpTree*
NegativeLookahead(LifoAlloc* alloc, char16_t from, char16_t to)
{
return alloc->newInfallible<RegExpLookaround>(RangeAtom(alloc, from, to), false,
0, 0, RegExpLookaround::LOOKAHEAD);
return alloc->newInfallible<RegExpLookahead>(RangeAtom(alloc, from, to), false, 0, 0);
}
static bool
@@ -1215,38 +1213,6 @@ RegExpParser<CharT>::ParseBackReferenceIndex(int* index_out)
return true;
}
template <typename CharT>
RegExpCapture*
RegExpParser<CharT>::GetCapture(int index) {
// The index for the capture groups are one-based. Its index in the list is
// zero-based.
int known_captures =
is_scanned_for_captures_ ? capture_count_ : captures_started_;
MOZ_ASSERT(index <= known_captures);
if (captures_ == NULL) {
captures_ = alloc->newInfallible<RegExpCaptureVector>(*alloc);
}
while ((int)captures_->length() < known_captures) {
RegExpCapture* capture = alloc->newInfallible<RegExpCapture>(nullptr, captures_->length() + 1);
captures_->append(capture);
}
return (*captures_)[index - 1];
}
template <typename CharT>
bool
RegExpParser<CharT>::RegExpParserState::IsInsideCaptureGroup(int index) {
for (RegExpParserState* s = this; s != NULL; s = s->previous_state()) {
if (s->group_type() != CAPTURE) continue;
// Return true if we found the matching capture index.
if (index == s->capture_index()) return true;
// Abort if index is larger than what has been parsed up till this state.
if (index > s->capture_index()) return false;
}
return false;
}
// QuantifierPrefix ::
// { DecimalDigits }
// { DecimalDigits , }
@@ -1489,24 +1455,24 @@ RegExpTree*
RegExpParser<CharT>::ParseDisjunction()
{
// Used to store current state while parsing subexpressions.
RegExpParserState initial_state(alloc, nullptr, INITIAL, RegExpLookaround::LOOKAHEAD, 0);
RegExpParserState* state = &initial_state;
RegExpParserState initial_state(alloc, nullptr, INITIAL, 0);
RegExpParserState* stored_state = &initial_state;
// Cache the builder in a local variable for quick access.
RegExpBuilder* builder = initial_state.builder();
while (true) {
switch (current()) {
case kEndMarker:
if (state->IsSubexpression()) {
if (stored_state->IsSubexpression()) {
// Inside a parenthesized group when hitting end of input.
return ReportError(JSMSG_MISSING_PAREN);
}
MOZ_ASSERT(INITIAL == state->group_type());
MOZ_ASSERT(INITIAL == stored_state->group_type());
// Parsing completed successfully.
return builder->ToRegExp();
case ')': {
if (!state->IsSubexpression())
if (!stored_state->IsSubexpression())
return ReportError(JSMSG_UNMATCHED_RIGHT_PAREN);
MOZ_ASSERT(INITIAL != state->group_type());
MOZ_ASSERT(INITIAL != stored_state->group_type());
Advance();
// End disjunction parsing and convert builder content to new single
@@ -1515,30 +1481,29 @@ RegExpParser<CharT>::ParseDisjunction()
int end_capture_index = captures_started();
int capture_index = state->capture_index();
SubexpressionType group_type = state->group_type();
int capture_index = stored_state->capture_index();
SubexpressionType group_type = stored_state->group_type();
// Restore previous state.
stored_state = stored_state->previous_state();
builder = stored_state->builder();
// Build result of subexpression.
if (group_type == CAPTURE) {
RegExpCapture* capture = GetCapture(capture_index);
capture->set_body(body);
RegExpCapture* capture = alloc->newInfallible<RegExpCapture>(body, capture_index);
(*captures_)[capture_index - 1] = capture;
body = capture;
} else if (group_type != GROUPING) {
MOZ_ASSERT(group_type == POSITIVE_LOOKAROUND ||
group_type == NEGATIVE_LOOKAROUND);
bool is_positive = (group_type == POSITIVE_LOOKAROUND);
body = alloc->newInfallible<RegExpLookaround>(body,
MOZ_ASSERT(group_type == POSITIVE_LOOKAHEAD ||
group_type == NEGATIVE_LOOKAHEAD);
bool is_positive = (group_type == POSITIVE_LOOKAHEAD);
body = alloc->newInfallible<RegExpLookahead>(body,
is_positive,
end_capture_index - capture_index,
capture_index,
state->lookaround_type());
capture_index);
}
// Restore previous state.
state = state->previous_state();
builder = state->builder();
builder->AddAtom(body);
if (unicode_ && (group_type == POSITIVE_LOOKAROUND || group_type == NEGATIVE_LOOKAROUND))
if (unicode_ && (group_type == POSITIVE_LOOKAHEAD || group_type == NEGATIVE_LOOKAHEAD))
continue;
// For compatability with JSC and ES3, we allow quantifiers after
// lookaheads, and break in all cases.
@@ -1598,7 +1563,6 @@ RegExpParser<CharT>::ParseDisjunction()
}
case '(': {
SubexpressionType subexpr_type = CAPTURE;
RegExpLookaround::Type lookaround_type = state->lookaround_type();
Advance();
if (current() == '?') {
switch (Next()) {
@@ -1606,39 +1570,26 @@ RegExpParser<CharT>::ParseDisjunction()
subexpr_type = GROUPING;
break;
case '=':
lookaround_type = RegExpLookaround::LOOKAHEAD;
subexpr_type = POSITIVE_LOOKAROUND;
subexpr_type = POSITIVE_LOOKAHEAD;
break;
case '!':
lookaround_type = RegExpLookaround::LOOKAHEAD;
subexpr_type = NEGATIVE_LOOKAROUND;
subexpr_type = NEGATIVE_LOOKAHEAD;
break;
case '<':
Advance();
lookaround_type = RegExpLookaround::LOOKBEHIND;
if (Next() == '=') {
subexpr_type = POSITIVE_LOOKAROUND;
break;
} else if (Next() == '!') {
subexpr_type = NEGATIVE_LOOKAROUND;
break;
}
// We didn't get a positive or negative after '<'.
// That's an error.
return ReportError(JSMSG_INVALID_GROUP);
default:
return ReportError(JSMSG_INVALID_GROUP);
}
Advance(2);
} else {
if (captures_ == nullptr)
captures_ = alloc->newInfallible<RegExpCaptureVector>(*alloc);
if (captures_started() >= kMaxCaptures)
return ReportError(JSMSG_TOO_MANY_PARENS);
captures_started_++;
captures_->append((RegExpCapture*) nullptr);
}
// Store current state and begin new disjunction parsing.
state = alloc->newInfallible<RegExpParserState>(alloc, state, subexpr_type,
lookaround_type, captures_started_);
builder = state->builder();
stored_state = alloc->newInfallible<RegExpParserState>(alloc, stored_state, subexpr_type,
captures_started());
builder = stored_state->builder();
continue;
}
case '[': {
@@ -1693,18 +1644,19 @@ RegExpParser<CharT>::ParseDisjunction()
case '7': case '8': case '9': {
int index = 0;
if (ParseBackReferenceIndex(&index)) {
if (state->IsInsideCaptureGroup(index)) {
// The backreference is inside the capture group it refers to.
// Nothing can possibly have been captured yet.
builder->AddEmpty();
} else {
RegExpCapture* capture = GetCapture(index);
RegExpTree* atom = alloc->newInfallible<RegExpBackReference>(capture);
if (unicode_)
builder->AddAtom(UnicodeBackReferenceAtom(alloc, atom));
else
builder->AddAtom(atom);
RegExpCapture* capture = nullptr;
if (captures_ != nullptr && index <= (int) captures_->length()) {
capture = (*captures_)[index - 1];
}
if (capture == nullptr) {
builder->AddEmpty();
break;
}
RegExpTree* atom = alloc->newInfallible<RegExpBackReference>(capture);
if (unicode_)
builder->AddAtom(UnicodeBackReferenceAtom(alloc, atom));
else
builder->AddAtom(atom);
break;
}
if (unicode_)
+3 -16
View File
@@ -228,7 +228,7 @@ class RegExpParser
bool simple() { return simple_; }
bool contains_anchor() { return contains_anchor_; }
void set_contains_anchor() { contains_anchor_ = true; }
int captures_started() { return captures_started_; }
int captures_started() { return captures_ == nullptr ? 0 : captures_->length(); }
const CharT* position() { return next_pos_ - 1; }
static const int kMaxCaptures = 1 << 16;
@@ -238,8 +238,8 @@ class RegExpParser
enum SubexpressionType {
INITIAL,
CAPTURE, // All positive values represent captures.
POSITIVE_LOOKAROUND,
NEGATIVE_LOOKAROUND,
POSITIVE_LOOKAHEAD,
NEGATIVE_LOOKAHEAD,
GROUPING
};
@@ -248,12 +248,10 @@ class RegExpParser
RegExpParserState(LifoAlloc* alloc,
RegExpParserState* previous_state,
SubexpressionType group_type,
RegExpLookaround::Type lookaround_type,
int disjunction_capture_index)
: previous_state_(previous_state),
builder_(alloc->newInfallible<RegExpBuilder>(alloc)),
group_type_(group_type),
lookaround_type_(lookaround_type),
disjunction_capture_index_(disjunction_capture_index)
{}
// Parser state of containing expression, if any.
@@ -263,16 +261,11 @@ class RegExpParser
RegExpBuilder* builder() { return builder_; }
// Type of regexp being parsed (parenthesized group or entire regexp).
SubexpressionType group_type() { return group_type_; }
// Lookahead or Lookbehind.
RegExpLookaround::Type lookaround_type() { return lookaround_type_; }
// Index in captures array of first capture in this sub-expression, if any.
// Also the capture index of this sub-expression itself, if group_type
// is CAPTURE.
int capture_index() { return disjunction_capture_index_; }
// Check whether the parser is inside a capture group with the given index.
bool IsInsideCaptureGroup(int index);
private:
// Linked list implementation of stack of states.
RegExpParserState* previous_state_;
@@ -280,15 +273,10 @@ class RegExpParser
RegExpBuilder* builder_;
// Stored disjunction type (capture, look-ahead or grouping), if any.
SubexpressionType group_type_;
// Stored read direction.
RegExpLookaround::Type lookaround_type_;
// Stored disjunction's capture index (if any).
int disjunction_capture_index_;
};
// Return the 1-indexed RegExpCapture object, allocate if necessary.
RegExpCapture* GetCapture(int index);
widechar current() { return current_; }
bool has_more() { return has_more_; }
bool has_next() { return next_pos_ < end_; }
@@ -305,7 +293,6 @@ class RegExpParser
const CharT* next_pos_;
const CharT* end_;
widechar current_;
int captures_started_;
// The capture count is only valid after we have scanned for captures.
int capture_count_;
bool has_more_;
+15 -2
View File
@@ -885,15 +885,22 @@ nsZipHandle* nsZipArchive::GetFD()
uint32_t nsZipArchive::GetDataOffset(nsZipItem* aItem)
{
MOZ_ASSERT(aItem);
uint32_t offset;
MOZ_WIN_MEM_TRY_BEGIN
//-- read local header to get variable length values and calculate
//-- the real data offset
uint32_t len = mFd->mLen;
const uint8_t* data = mFd->mFileData;
uint32_t offset = aItem->LocalOffset();
offset = aItem->LocalOffset();
if (len < ZIPLOCAL_SIZE || offset > len - ZIPLOCAL_SIZE)
return 0;
// Check there's enough space for the signature
if (offset > mFd->mLen) {
NS_WARNING("Corrupt local offset in JAR file");
return 0;
}
// -- check signature before using the structure, in case the zip file is corrupt
ZipLocal* Local = (ZipLocal*)(data + offset);
if ((xtolong(Local->signature) != LOCALSIG))
@@ -906,8 +913,14 @@ MOZ_WIN_MEM_TRY_BEGIN
xtoint(Local->filename_len) +
xtoint(Local->extrafield_len);
return offset;
// Check data points inside the file.
if (offset > mFd->mLen) {
NS_WARNING("Corrupt data offset in JAR file");
return 0;
}
MOZ_WIN_MEM_TRY_CATCH(return 0)
// Can't be 0
return offset;
}
//---------------------------------------------
+5 -16
View File
@@ -3356,25 +3356,14 @@ nsCookieService::SetCookieInternal(nsIURI *aHostURI,
// Reject cookie if value contains an RFC 6265 disallowed character.
// See RFC 6265 section 4.1.1
// XXX: For now we allow for web compatibility (see issue #357):
// 0x20 (Space)
// 0x22 (DQUOTE)
// 0x2C (Comma)
// 0x5C (Backslash)
// 0x09 (htab) Explicitly allowed per RFC 6265 (bis) section 5.6. Chrome erroneously rejects this.
// 0x3B (;) forbidden to avoid cookie-spoofing by adding a separator inside a name or value
//
// FIXME: Before removing DQUOTE from the exceptions list:
// DQUOTE *cookie-octet DQUOTE is permitted and would fail if just removed.
// This needs better checking for first and last character allowing
// DQUOTE but not in the actual value.
//
// This only applies to cookies set via the Set-Cookie header, since
// document.cookie is defined to be UTF-8.
const char illegalCharacters[] = {
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x0A, 0x0B,
0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, /* 0x20, 0x22, */
/* 0x2C, */ 0x3B, /* 0x5C, */ 0x7F, 0x00 };
if (aFromHttp && (cookieAttributes.value.FindCharInSet(illegalCharacters, 0) != -1)) {
0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x3B, 0x7F, 0x00 };
if (cookieAttributes.value.FindCharInSet(illegalCharacters, 0) != -1) {
COOKIE_LOGFAILURE(SET_COOKIE, aHostURI, savedCookieHeader, "invalid value character");
return newCookie;
}
@@ -62,6 +62,11 @@ BaseWebSocketChannel::BaseWebSocketChannel()
mSerial = (processBits << kWebSocketIDWebSocketBits) | webSocketBits;
}
BaseWebSocketChannel::~BaseWebSocketChannel() {
NS_ReleaseOnMainThread(mLoadGroup.forget());
NS_ReleaseOnMainThread(mLoadInfo.forget());
}
//-----------------------------------------------------------------------------
// BaseWebSocketChannel::nsIWebSocketChannel
//-----------------------------------------------------------------------------
@@ -79,6 +79,7 @@ class BaseWebSocketChannel : public nsIWebSocketChannel,
};
protected:
virtual ~BaseWebSocketChannel();
nsCOMPtr<nsIURI> mOriginalURI;
nsCOMPtr<nsIURI> mURI;
RefPtr<ListenerAndContextContainer> mListenerMT;
@@ -1243,8 +1243,6 @@ WebSocketChannel::~WebSocketChannel()
mListenerMT = nullptr;
NS_ReleaseOnMainThread(mLoadGroup.forget());
NS_ReleaseOnMainThread(mLoadInfo.forget());
NS_ReleaseOnMainThread(mService.forget());
}
@@ -124,7 +124,7 @@ public:
const static uint8_t kPayloadLengthBitsMask = 0x7F;
protected:
virtual ~WebSocketChannel();
~WebSocketChannel() override;
private:
friend class OutboundEnqueuer;
@@ -613,14 +613,6 @@ function UpdateParser(aId, aUpdateKey, aUrl, aObserver) {
let requireBuiltIn = Services.prefs.getBoolPref(PREF_UPDATE_REQUIREBUILTINCERTS, true);
logger.debug("Requesting " + aUrl);
if (!aUrl) {
logger.warn("Request failed: empty update manifest URL");
this._doneAt = new Error("UP_emptyManifestURL");
this.notifyError(AddonUpdateChecker.ERROR_DOWNLOAD_ERROR);
return;
}
try {
this.request = new ServiceRequest();
this.request.open("GET", this.url, true);
+8 -16
View File
@@ -367,14 +367,6 @@ HRESULT nsDataObj::CreateStream(IStream **outStream)
static GUID CLSID_nsDataObj =
{ 0x1bba7640, 0xdf52, 0x11cf, { 0x82, 0x7b, 0, 0xa0, 0x24, 0x3a, 0xe5, 0x05 } };
/*
* deliberately not using MAX_PATH. This is because on platforms < XP
* a file created with a long filename may be mishandled by the shell
* resulting in it not being able to be deleted or moved.
* See bug 250392 for more details.
*/
#define NS_MAX_FILEDESCRIPTOR 128 + 1
/*
* Class nsDataObj
*/
@@ -1190,11 +1182,11 @@ nsDataObj :: GetFileDescriptorInternetShortcutA ( FORMATETC& aFE, STGMEDIUM& aST
// get a valid filename in the following order: 1) from the page title,
// 2) localized string for an untitled page, 3) just use "Untitled.url"
if (!CreateFilenameFromTextA(title, ".url",
fileGroupDescA->fgd[0].cFileName, NS_MAX_FILEDESCRIPTOR)) {
fileGroupDescA->fgd[0].cFileName, MAX_PATH)) {
nsXPIDLString untitled;
if (!GetLocalizedString(u"noPageTitle", untitled) ||
!CreateFilenameFromTextA(untitled, ".url",
fileGroupDescA->fgd[0].cFileName, NS_MAX_FILEDESCRIPTOR)) {
fileGroupDescA->fgd[0].cFileName, MAX_PATH)) {
strcpy(fileGroupDescA->fgd[0].cFileName, "Untitled.url");
}
}
@@ -1231,11 +1223,11 @@ nsDataObj :: GetFileDescriptorInternetShortcutW ( FORMATETC& aFE, STGMEDIUM& aST
// get a valid filename in the following order: 1) from the page title,
// 2) localized string for an untitled page, 3) just use "Untitled.url"
if (!CreateFilenameFromTextW(title, L".url",
fileGroupDescW->fgd[0].cFileName, NS_MAX_FILEDESCRIPTOR)) {
fileGroupDescW->fgd[0].cFileName, MAX_PATH)) {
nsXPIDLString untitled;
if (!GetLocalizedString(u"noPageTitle", untitled) ||
!CreateFilenameFromTextW(untitled, L".url",
fileGroupDescW->fgd[0].cFileName, NS_MAX_FILEDESCRIPTOR)) {
fileGroupDescW->fgd[0].cFileName, MAX_PATH)) {
wcscpy(fileGroupDescW->fgd[0].cFileName, L"Untitled.url");
}
}
@@ -2216,8 +2208,8 @@ HRESULT nsDataObj::GetFileDescriptor_IStreamA(FORMATETC& aFE, STGMEDIUM& aSTG)
nsAutoCString nativeFileName;
NS_UTF16ToCString(wideFileName, NS_CSTRING_ENCODING_NATIVE_FILESYSTEM, nativeFileName);
strncpy(fileGroupDescA->fgd[0].cFileName, nativeFileName.get(), NS_MAX_FILEDESCRIPTOR - 1);
fileGroupDescA->fgd[0].cFileName[NS_MAX_FILEDESCRIPTOR - 1] = '\0';
strncpy(fileGroupDescA->fgd[0].cFileName, nativeFileName.get(), MAX_PATH - 1);
fileGroupDescA->fgd[0].cFileName[MAX_PATH - 1] = '\0';
// one file in the file block
fileGroupDescA->cItems = 1;
@@ -2252,8 +2244,8 @@ HRESULT nsDataObj::GetFileDescriptor_IStreamW(FORMATETC& aFE, STGMEDIUM& aSTG)
return res;
}
wcsncpy(fileGroupDescW->fgd[0].cFileName, wideFileName.get(), NS_MAX_FILEDESCRIPTOR - 1);
fileGroupDescW->fgd[0].cFileName[NS_MAX_FILEDESCRIPTOR - 1] = '\0';
wcsncpy(fileGroupDescW->fgd[0].cFileName, wideFileName.get(), MAX_PATH - 1);
fileGroupDescW->fgd[0].cFileName[MAX_PATH - 1] = '\0';
// one file in the file block
fileGroupDescW->cItems = 1;
fileGroupDescW->fgd[0].dwFlags = FD_PROGRESSUI;
+4 -10
View File
@@ -1720,14 +1720,11 @@ nsLocalFile::GetNativeTarget(nsACString& aResult)
return NS_ERROR_OUT_OF_MEMORY;
}
ssize_t written = readlink(mPath.get(), target.BeginWriting(), size_t(size));
if (written < 0) {
if (readlink(mPath.get(), target, (size_t)size) < 0) {
free(target);
return NSRESULT_FOR_ERRNO();
}
// Target might have changed since the lstat call, or lstat might lie, see bug
// 1791029.
target.Truncate(written);
target[size] = '\0';
nsresult rv = NS_OK;
nsCOMPtr<nsIFile> self(this);
@@ -1778,15 +1775,12 @@ nsLocalFile::GetNativeTarget(nsACString& aResult)
size = newSize;
}
ssize_t linkLen = readlink(flatRetval.get(), target, size);
int32_t linkLen = readlink(flatRetval.get(), target, size);
if (linkLen == -1) {
rv = NSRESULT_FOR_ERRNO();
break;
}
// Target might have changed since the lstat call, or lstat might lie, see bug
// 1791029.
newTarget.Truncate(linkLen);
target = newTarget;
target[linkLen] = '\0';
}
free(target);