Binary files cannot be diffed like text, but for some binary changes,
the diff algorithm does yield binary differences as text. With this
change, the diff builder and processor are taught to render a special
message for (non-image) binary diffs, and will ignore the text
representation of the delta.
Bug: Issue 4031
Change-Id: I2dcdbe9def006de827a37c35c42606bc1c9cf4fc
This is a partial roll-forward of c/106190
This replaces all loads of iron-test-helpers with a load of a file
that wraps it, and adds that file to test files that do not currently
load iron-test-helpers.
A future CL will also install polymer-resin via common-test-helpers.html.
I tested by running
$ WCT_ARGS="-l chrome" ./polygerrit-ui/app/run_test.sh
Change-Id: Ifb3cd2c8db13d724f57e56e7e78045470d103a43
polymer-resin intercepts polymer property assignments
before they reach XSS-vulnerable sinks like `href="..."`
and text nodes in `<script>` elements.
This follows the instructions in WORKSPACE for adding a new bower
dependency with kaspern's tweak to use the dependency in a rule so
that it's found. //lib/js/bower_components.bzl has already been
rolled-back per those instructions.
The license is the polymer license as can be seen at
https://github.com/Polymer/polymer-resin/blob/master/LICENSE though
I'm not sure that //tools/js/bower2bazel.py recognizes it as such.
Docs for the added component are available at
https://github.com/Polymer/polymer-resin/blob/master/README.mdhttps://github.com/Polymer/polymer-resin/blob/master/getting-started.md
With this change, when I introduce an XSS vulnerability as below,
polymer-resin intercepts and stops it.
Patch that introduces a strawman vulnerability.
--- a/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header.js
+++ b/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header.js
@@ -55,6 +55,10 @@
url: '/q/status:abandoned',
name: 'Abandoned',
},
+ {
+ url: location.hash.replace(/^#/, '') || 'http://example.com/#fragment_echoed_here',
+ name: 'XSS Me',
+ },
],
}];
---
Address kaspern's and paladox's comments.
---
Undo version bumps for bower dependencies.
---
Change Soy index template to parallel app/index.html.
---
update polymer-resin to version 1.1.1-beta
----
Load polymer-resin into polygerrit-ui/**/*_test.html
After this, I ran the tests with
-l chrome
-l firefox
I ran a handful of tests with -p and observed that the
console shows "initResin" is called before test cases start
executing.
These changes were done programmaticly by running the script below
(approximately) thus:
```
gerrit/ $ cd polygerrit-ui/app
app/ $ find . -name \*test.html | xargs perl hack-tests.pl
```
```
use strict;
sub removeResin($) {
my $s = $_[0];
$s =~ s@<link rel="import" href="[^"]*/polymer-resin/[^"]*"[^>]*>\n?@@;
$s =~ s@<script src="[^"]*/polymer-resin/[^"]*"></script>\n?@@;
$s =~ s@<script>\s*security\.polymer_resin.*?</script>\n?@@s;
return $s;
}
for my $f (@ARGV) {
next if $f =~ m@/bower_components/|/node_modules/@;
system('git', 'checkout', $f);
print "$f\n";
my @lines = ();
open(IN, "<$f") or die "$f: $!";
my $maxLineOfMatch = 0;
while (<IN>) {
push(@lines, $_);
# Put a marker after core loading directives.
$maxLineOfMatch = scalar(@lines)
if m@/webcomponentsjs/|/polymer[.]html\b|/browser[.]js@;
}
close(IN) or die "$f: $!";
die "$f missing loading directives" unless $maxLineOfMatch;
# Given ./a/b/c/my_test.html, $pathToRoot is "../../.."
# assuming no non-leading . or .. components in the path from find.
my $pathToRoot = $f;
$pathToRoot =~ s@^\.\/@@;
$pathToRoot =~ s@^(.*?/)?app/@@;
$pathToRoot =~ s@\/[^\/]*$@@;
$pathToRoot =~ s@[^/]+@..@g;
my $nLines = scalar(@lines);
open(OUT, ">$f") or die "$f: $!";
# Output the lines up to the last polymer-resin dependency
# loaded explicitly by this test.
my $before = join '', @lines[0..($maxLineOfMatch - 1)];
$before = removeResin($before);
print OUT "$before";
# Dump out the lines that load polymer-resin and configure it for
# polygerrit.
if (1) {
print OUT qq'<link rel="import" href="$pathToRoot/bower_components/polymer-resin/standalone/polymer-resin-debug.html"/>
<script>
security.polymer_resin.install({allowedIdentifierPrefixes: [\'\']});
</script>
';
}
# Emit any remaining lines.
my $after = join '', @lines[$maxLineOfMatch..$#lines];
$after = removeResin($after);
$after =~ s/^\n*//;
print OUT "$after";
close(OUT) or die "$f: $!";
}
```
---
update polymer-resin to version 1.2.1-beta
---
update Soy index template to new style polymer-resin initialization
----
fix lint warnings
----
Load test/common-test-setup.html into *_test.html
Instead of inserting instructions to load and initialize polymer-resin into
every test file, add a common-test-setup.html that does that and also fold
iron-test-helpers loading into it.
----
imported files do not need to load webcomponentsjs
Change-Id: I71221c36ed8a0fe7f8720c1064a2fcc9555bb8df
Shared groups were broken down in I8018535ee7 to improve perceived
performance using a diff of Go's go_spec.html as a benchmark. However,
the total render time became slower with this change because the
decomposed groups thrashed the layout.
With this change, shared groups are decomposed into two groups to
achieve the same perceived responsiveness, but balance that with total
render time and avoid needless layouts.
The Maximum group size in increased to 120 to further reduce the number
of groups.
Some performance numbers for the go_spec.html benchmark diff and the
config_dump.json diff indicated in the linked issue.
+------------------+--------------+
| config_dump.json | go_spec.html |
+-----------------------+------------------+--------------+
| Content Render Before | 83877.2 ms | 7815.2 ms |
+-----------------------+------------------+--------------+
| Content Render After | 17492.0 ms | 3363.4 ms |
+-----------------------+------------------+--------------+
| Speedup Factor | ~4.8 | ~2.3 |
+-----------------------+------------------+--------------+
Further performance improvements to follow.
Bug: Issue 5778
Change-Id: I97751b7b78b821a794374cbfeecb16d59d5e1c4c
Previously there were times when binary data from an image diff would
display. This change adds a check in the diff processor for image diffs
and does not display anything other than the file line in that case.
This change also addresses an issue where the label is calculated too
soon. The image size (if it exists) is supposed to be included as part
of the label, but often this was calculated before the image was done
rendering, so it didn't display.
Bug: Issue 5887
Change-Id: I9cd1ad0c3f2603492d7d84892147bd6852bbae29
Formerly, incremental rendering had not been applied to shared chunks
because it would break context-grouping logic. However, when the context
is set to the whole file, this problem is averted because the
context-groups are not created. Apply incremental rendering to shared
chunks only when the context is set to whole file.
Change-Id: I8018535ee72e5d4ef499628181298a13e8b20d06
When the diff processor collapses shared groups based on the user
context preference, it would sometimes collapse a single line, resulting
in a common group labeled "Show 1 common line" which takes up exactly
as much space in the diff view as the line itself. Moreover, the GWT UI
does not collapse single line common sections in this way (but does when
there are two or more lines).
Sets the threshold to collapse at least two lines and encodes this in a
test.
Bug: Issue 4721
Change-Id: I8a3a8556fd66a313eacc361379612c700d7ae070
A source of latency when creating diff comments in large diffs is the
work needed to reflow the diff DOM to make room for the new comment.
This is particularly evident when adding comments to new files because
the diff is built as an addition group representing the entire file, so
the comment causes a reflow on every subsequent line.
This change optimizes this process in three ways.
* **Limit the size of ADD & REMOVE groups:** The diff processor will now
break an add or a remove chunk into a series of smaller chunks of the
same kind. This is controlled by the MAX_GROUP_SIZE constant. In this
way the number of nodes that need to be reflowed when a comment is
added to an add or remove group is limited to the number of subsequent
lines in that group plus the subsequent number of groups.
* **GPU optimize group in general:** Adds CSS properties to diff TBODY
elements (which correspond to groups, for the most part) that trigger
GPU acceleration when available.
* **Apply `table-layout: fixed;`** This style speeds up table reflow in
general.
Change-Id: Ie0e3665b7752fec67f7123cfae70ae99e6f67521
Previously each group was rendered asynchronously, i.e. deferring
control between each group render. This caused the total render time to
be ~10x slower than totally synchronous. But the advantage of this
approach was that the content at the start of the diff would be visible
as soon as possible.
This change finds a compromise by combining processing/rendering the
diff groups in larger synchronous batches which are based on the number
of lines in the groups.
Change-Id: I5d42700962f51bea0dedb05763a1d8eb1c32bfd1
Building on existing support for asynchronous diff processing, the
rendering stage is now also asynchronous. The `emitGroup` method of
gr-diff-builder (which constructs a DOM fragment and attaches it to the
document) is now called whenever the processor emits a new group, rather
than waiting for all groups to be available and looping over them.
Adds support for canceling the processor, and removes a behavior where
the diff was being re-rendered needlessly, causing visible flicker.
Updates a test that broke when rendering became asynchronous.
Change-Id: I37fcd65efc8c901b85fc93e91611c022edc10dc4
Modifies the `process` method of gr-diff-processor to traverse diff
content using an asynchronous recursive loop rather than a blocking
for-loop. The async version maintains the promise interface already
established.
Refactored to constrain side-effects to the `process` method. Whereas,
formerly, helper methods in gr-diff-processor both read and wrote the
component's internal state, they are rewritten to be more pure, making
them simpler to understand, test, and invoke asynchronously.
Documentation is added throughout as well as tests for helper functions.
Note that this change only makes the processing step asynchronous.
Upgrading the diff-rendering stage to be non-blocking will come in a
later change.
Change-Id: Ifd50eeb75797b173937890caacc92cad5675fc20
Moves the diff-processing functionality of the gr-diff-builder component
into a new gr-diff-processor component which exposes a promise-based
interface. This is step one of creating an asynchronous (non-blocking)
diff rendering system.
As much as possible, this change is a transfer of code (with tests) from
one component to another, making it easier to verify that functionality
has not changed. Cleanup of the code, and refactoring it into a
more-testable form will come with later changes.
Feature: Issue 3916
Change-Id: I875b03b20bf953b128cbe3c5001ba1f8eba12c61