This patch adjusts tools/fuzzing/ in such a way that the relevant parts can be
reused in the JS engine. Changes in detail include:
* Various JS_STANDALONE checks to exclude parts that cannot be included in
those builds.
* Turn LibFuzzerRegistry and LibFuzzerRunner into generic FuzzerRegistry and
FuzzerRunner classes and use them for AFL as well. Previously, AFL was
piggy-backing on gtests which was kind of an ugly solution anyway (besides
that it can't work in JS). Now more code like registry and harness is
shared between the two and they follow almost the same call paths and entry
points. AFL macros in FuzzingInterface have been rewritten accordingly.
This also required name changes in various places. Furthermore, this unifies
the way, the fuzzing target is selected, using the FUZZER environment
variable rather than LIBFUZZER (using LIBFUZZER in browser builds will give
you a deprecation warning because I know some people are using this already
and need time to switch). Previously, AFL target had to be selected using
GTEST_FILTER, so this is also much better now.
* I had to split up FuzzingInterface* such that the STREAM parts are in a
separate set of files FuzzingInterfaceStream* because they use nsStringStream
which is not allowed to be included into the JS engine even in a full browser
build (error: "Using XPCOM strings is limited to code linked into libxul.").
I also had to pull FuzzingInterface.cpp (the RAW part only) into the header
and make it static because otherwise, would have to make not only separate
files but also separate libraries to statically link to the JS engine, which
seemed overkill for a single small function. The streaming equivalent of the
function is still in a cpp file.
* LibFuzzerRegister functions are now unique by appending the module name to
avoid redefinition errors.
MozReview-Commit-ID: 44zWCdglnHr
--HG--
rename : tools/fuzzing/libfuzzer/harness/LibFuzzerRunner.cpp => tools/fuzzing/interface/harness/FuzzerRunner.cpp
rename : tools/fuzzing/libfuzzer/harness/LibFuzzerRunner.h => tools/fuzzing/interface/harness/FuzzerRunner.h
rename : tools/fuzzing/libfuzzer/harness/LibFuzzerTestHarness.h => tools/fuzzing/interface/harness/FuzzerTestHarness.h
rename : tools/fuzzing/libfuzzer/harness/moz.build => tools/fuzzing/interface/harness/moz.build
rename : tools/fuzzing/libfuzzer/harness/LibFuzzerRegistry.cpp => tools/fuzzing/registry/FuzzerRegistry.cpp
rename : tools/fuzzing/libfuzzer/harness/LibFuzzerRegistry.h => tools/fuzzing/registry/FuzzerRegistry.h
extra : rebase_source : 7d0511ca0591dbf4d099376011402e063a79ee3b
These are all no-ops because the objects involved are already implementing one of the WebIDL interfaces that pulls in MozImageLoadingContent, and that's all script gets to see.
MozReview-Commit-ID: Io2mLHbv7qM
* changes call to use nsIURIMutator.setSpec()
* Add new NS_MutateURI constructor that takes new Mutator object
* Make nsSimpleNestedURI::Mutate() and nsNestedAboutURI::Mutate() return mutable URIs
* Make the finalizers for nsSimpleNestedURI and nsNestedAboutURI make the returned URIs immutable
MozReview-Commit-ID: 1kcv6zMxnv7
--HG--
extra : rebase_source : 99b13e9dbc8eaaa9615843b05e1539e19b527504
All of these tests have existing fuzzy annotations which cover the
differences in the WR renderings. Therefore we can remove the
fails-if(webrender) annotations and use the existing fuzzy annotations
to treat the tests as passing.
MozReview-Commit-ID: LFWha6gAP2r
--HG--
extra : rebase_source : b26a0d0cd66b6bab273251e6a2de9210417ba798
If we aren't using a downscaler we avoid this bug because the mask is either 100% transparent or 100% opaque, and in the transparent case we just set the whole pixel (32 bits) to 0.
But when we are using a downscaler we just replace the alpha values in the original surface (leaving the color values untouched).
We need to go the full premultiply route because after downscaling the mask we can have any value for alpha instead of just 0 or 255.
This removes an unnecessary level of indirection by replacing all
nsStringGlue.h instances with just nsString.h.
--HG--
extra : rebase_source : 340989240af4018f3ebfd92826ae11b0cb46d019
imgLoader::ValidateEntry would aggressively determine an entry has
expired, even when the request hasn't yet begun. This is because the
expiration time for the entry was not set unless it was for a channel
which supports caching. Now we set the expiration time for all
channels, and if it doesn't support caching, it just expires at the
current time when imgRequest::OnStartRequest is called. Additionally,
imgLoader::ValidateEntry will not consider the expiration time in the
entry until it is non-zero.
Factory::DoesBackendSupportDataDrawtarget already fulfills the same
purpose and we should use that instead, as imgFrame is the only user of
the former API. It has the added bonus of allowing us to use shared
surfaces on Linux with WebRender, and using volatile surfaces on Windows
when D2D is disabled.
The "current URL" in the spec:
https://html.spec.whatwg.org/multipage/embedded-content.html#dom-img-currentsrc
maps to imgIRequest.URI, not currentURI.
Rename imgIRequest.currentURI to finalURI to prevent such confusion.
MozReview-Commit-ID: CjBh2V4z8K9
--HG--
extra : rebase_source : 01277d16ef12845e12cc846f9dd4a21ceeca283b
This also changes URIUtils.cpp:DeserializeURI() to use the mutator to instantiate new URIs, instead of using their default constructor.
MozReview-Commit-ID: JQOvIquuQAP
--HG--
extra : rebase_source : e146624c5ae423f7f69a738aaaafaa55dd0940d9
The "current URL" in the spec:
https://html.spec.whatwg.org/multipage/embedded-content.html#dom-img-currentsrc
maps to imgIRequest.URI, not currentURI.
Rename imgIRequest.currentURI to finalURI to prevent such confusion.
MozReview-Commit-ID: CjBh2V4z8K9
--HG--
extra : rebase_source : d3047aed22f116ff9a74099b646a84e597388673
This is important because it ensures we release the shared memory handle
(although not the data itself) for the underlying surface buffer when it
turns out we will probably never need to share it. If we do need to
share the surface data with the GPU process, it will reallocate a handle
if necessary, and close it when it is finished. On some platforms we
only have a finite number of handles, so if we don't need them, we
should close them.
This is largely trivial because the meat of the implementation is
located in ImageResource and we already added GetFrameInternal.
Interestingly VectorImage::IsUnlocked does not actually check if the
image is locked, but instead only checks for animation consumers. This
is consistent with its historical behavior on when to issue an unlocked
draw event.
Note that we do not implement the original GetImageContainer and
IsImageContainerAvailable APIs. This is because the former does not
accept an SVG context and it would be best to discourage its use in old
code lest we get incorrect/unexpected results.
No functional change aside from the implementation from
VectorImage::GetFrameAtSize being repurposed for GetFrameInternal and
returning an additional error code with the surface.
Creating a DrawTarget can be an expensive operation. This is especially
true in this case because checking for a cached already decoded version
of the VectorImage is expected to be fast. Currently VectorImage::Draw
is the typical path to render these images, but in the future, getting
the frames directly or indirectly (through an ImageContainer) will
become more common.
When FLAG_HIGH_QUALITY_SCALING is used, we need to make sure we continue
using that flag when we update the container. We should also use it for
comparing whether or not an existing image container is equivalent.
This adds IsImageContainerAvailableAtSize and GetImageContainerAtSize to
the imgIContainer interface, as well as stubbing it for all of the
classes which implement it. The real implementations will follow for the
more complicated classes (RasterImage, VectorImage).
Exposure of this functionality comes in a later patch in the set.
Experimental testing with WebRender and image layers enabled suggests
most of the time we are not using more than one image container per
image, hence why mImageContainers has room for one container without a
malloc.
RasterImage::GetCurrentImage can only return a subset of the DrawResult
values, and the original RasterImage::GetImageContainer implementation
relied upon this behavior. Now we handle them all to ensure that when
other image implementations reuse it, they may return any valid
DrawResult and get the expected results.
As part of the move, we add a IntSize parameter to
ImageResource::GetCurrentImage. This is because we don't have access to
the image's size (yet) from ImageResource, but additionally because we
will need this anyways when we support multiple image containers at
different sizes.
The only change to the moved implementation is that we no longer have
access to RasterImage::mHasSize and RasterImage::mSize. Thus we rely
upon imgIContainer::IsImageContainerAvailable to perform these checks.
This state will eventually be used by VectorImage when it supports image
containers. For now, it is harmless beyond using slightly more memory
for SVGs.
An imgRequestProxy may defer notifications when it needs to block on an
imgCacheValidator. It may also be cancelled before the validator has
completed its operation, but before this change, we did not remove the
request from the set of proxies, imgCacheValidator::mProxies. When the
deferral was completed, it would assert to ensure each proxy was still
expecting a deferral before issuing the notifications. Cancelling a
request can actually reset that state, which means we fail the assert.
Failing the assert is actually harmless; in release we suffer no
negative consequences as a result of this sequence of events. Now we
just remove the proxy from the validator set to avoid asserting.
The core of this change is in gfxContext.*:
- change gfxContext::CurrentMatrix() and gfxContext::SetMatrix() to
return and take a Matrix respectively, instead of converting to
and from a gfxMatrix (which uses doubles). These functions therefore
will now match the native representation of the transform in gfxContext.
- add two new functions CurrentMatrixDouble() and SetMatrixDouble() that
do what the old CurrentMatrix() and SetMatrix() used to do, i.e.
convert between the float matrix and the double matrix.
The rest of the change is just updating the call sites to avoid round-
tripping between floats and doubles where possible. Call sites that are
hard to fix are migrated to the new XXXDouble functions which preserves
the existing behaviour.
MozReview-Commit-ID: 5sbBpLUus3U
imgRequestProxy::CancelAndForgetObserver was intended to always dispatch
any load group removals due to reentracy conflicts with the callers.
However in bug 1404422 the fact that imgRequest::RemoveProxy can
indirectly trigger a load group removal through completing an
incompleted request.
Historically imgRequestProxy::PerformClone would only add the cloned
request to the (original proxy's) document's load group if the request
was still being validated. Now it adds the cloned request to the given
document's load group before requesting the notifications, unless the
request has already been completed. We ensure that any removals from
the load group occur outside the current execution context.
Legacy listeners may use imgRequestProxy::SyncClone to request
notifications on the image state. Ideally they would not, but they do
not work as expected with the asynchronous notifications all new callers
must use. While in theory this would suggest their code is re-entrant,
not all of it is. In particular we need to be sensitive about when we
remove a request from a load group.
There should be no functional change here, but we rely upon the new
structure in the next patch in the series. This separates out the
notions of removing a request from the load group (which is always
final, and must be executed outside of synchronous calls from the owner
of the imgRequestProxy) and wanting to readd a request to the load group
as a background request (for multipart images).
The most important addition is mForceDispatchLoadGroup which if true
when imgRequestProxy::RemoveFromLoadGroup is called, will dispatch the
removal from the load group instead of executing it inline. This ensures
safety for any callers (e.g. to CancelAndForgetObserver) as above.
imgRequestProxy::SetLoadGroup did not have a predictable effect and
it appears to be unused. It is somewhat complicated to support given
we must be sensitive about what context we execute removing the
request from the original load group.
imgLoader::LoadImage now asserts in debug builds that the load group
given as a parameter matches that of the given document (if any). If
they mismatch, then we won't be blocking the document's load event as we
expect with the future removal of the imgIOnloadBlocker.
imgLoader::LoadImageWithChannel never actually added the request to the
load group at all, unless it was done as part of the validator. Now it
will consistently add the request to the channel's load group as
expected. Additionally it also asserts in debug builds that the
channel's load group matches that of the given document, as in
LoadImage.