mozilla

Mozilla Nederland LogoDe Nederlandse
Mozilla-gemeenschap

Mozilla GFX: WebRender newsletter #30

Mozilla planet - do, 15/11/2018 - 11:34

Hi! This is the 30th issue of WebRender’s most famous newsletter. At the top of each newsletter I try to dedicate a few paragraphs to some historical/technical details of the project. Today I’ll write about blob images.

WebRender currently doesn’t support the full set of graphics primitives required to render all web pages. The focus so far has been on doing a good job of rendering the most common elements and providing a fall-back for the rest. We call this fall-back mechanism “blob images”.

The general idea is that when we encounter unsupported primitives during displaylist building we create an image object and instead of backing it with pixel data or a texture handle, we assign it a serialized list of drawing commands (the blob). For WebRender, blobs are just opaque buffers of bytes and a handler object is provided by the embedder (Gecko in our case) to turn this opaque buffer into actual pixels that can be used as regular images by the rest of the rendering pipeline.

This opaque blob representation and an external handler lets us implement these missing features using Skia without adding large and messy dependencies to WebRender itself. While a big part of this mechanism operates as a black box, WebRender remains responsible for scheduling the blob rasterization work at the appropriate time and synchronizing it with other updates. Our long term goal is to incrementally implement missing primitives directly in WebRender.

Notable WebRender and Gecko changes
  • Bobby keeps improving the texture cache heuristics to reduce peak GPU memory usage.
  • Bobby improved the texture cache’s debug display.
  • Jeff fixed a pair of blob image related crashes.
  • Jeff investigated content frame time telemetry data.
  • Dan improved our score on the dl_mutate talos benchmark by 20%.
  • Kats landed the async zooming changes for WebRender on Android.
  • Kats fixed a crash.
  • Kvark simplified some of the displaylist building code.
  • Matt Fixed a crash with tiled blob images.
  • Lee fixed a bug causing fonts to use the wrong DirectWrite render mode on Windows.
  • Emilio fixed a box-shadow regression.
  • Emilio switched the CI to an osmesa version that works with clang 7.
  • Glenn landed the picture caching work for text shadows.
  • Glenn refactored some of the plane splitting code to move it into the picture traversal pass.
  • Glenn removed some dead code.
  • Glenn separated brush segment descriptors form clip mask instance.
  • Glenn refactored the none-patch segment generation code.
  • Glenn removed the local_rect from PictureState.
  • Sotaro improved the frame synchronization yielding a nice performance improvement on the glterrain talos benchmark.
  • Sotaro recycled the D3D11 Query object, which improved the glterrain, tart and tscrollx talos scores on Windows.
  • Sotaro simplified some of the image sharing code.
  • The gfx team has a new manager, welcome Jessie!
Ongoing work
  • Matt and Dan are investigating performance.
  • Doug is investigating the effects of document splitting on talos scores.
  • Lee is fixing font rendering issues.
  • Kvark is making progress on the clip/scroll API refactoring.
  • Kats keeps investigating WebRender on Android.
  • Glenn is incrementally working towards picture caching for scrolled surfaces.
Enabling WebRender in Firefox Nightly

In about:config

  • set “gfx.webrender.all” to true,
  • restart Firefox.
Categorieën: Mozilla-nl planet

Nick Fitzgerald: Program Synthesis is Possible in Rust

Mozilla planet - do, 15/11/2018 - 09:00

Program synthesis is the act of automatically constructing a program that fulfills a given specification. Perhaps you are interested in sketching a program, leaving parts of it incomplete, and then having a tool fill in those missing bits for you? Or perhaps you are a compiler, and you have some instruction sequence, but you want to find an equivalent-but-better instruction sequence? Program synthesizers promise to help you out in these situations!

I recently stumbled across Adrian Sampson’s Program Synthesis is Possible blog post. Adrian describes and implements minisynth, a toy program synthesizer that generates constants for holes in a template program when given a specification. What fun! As a way to learn more about program synthesis myself, I ported minisynth to Rust.

The Language

The input language is quite simple. The only type is the signed integer and our operations are addition, subtraction, multiplication, division, negation, left- and right-shift, and if-then-else conditionals.

Here is an example:

x * 10 + y

And here is conditional expression that evaluates to 27 if x is non-zero, and 42 otherwise:

x ? 27 : 42 Abstract Syntax Tree

My representation of the AST uses an id-based arena and interns identifier strings, which is a bit overkill for such a small program, but is a pattern that has worked well for me in Rust. This pattern makes implementing the petgraph crate’s traits easy, which gets you all the graph traversals and dominator algorithms, etc that a non-toy implementation will eventually want.

The ast::Context structure contains the arena of AST nodes and the interned strings.

// src/ast.rs use id_arena::{Arena, Id}; pub type StringId = Id<String>; #[derive(Default)] pub struct Context { idents: Arena<String>, already_interned: HashMap<String, StringId>, nodes: Arena<Node>, }

The ast::Node definition is an enum with a variant for each type of expression in the language.

// src/ast.rs pub type NodeId = Id<Node>; pub enum Node { Identifier(StringId), Addition(NodeId, NodeId), Subtraction(NodeId, NodeId), Multiplication(NodeId, NodeId), Division(NodeId, NodeId), RightShift(NodeId, NodeId), LeftShift(NodeId, NodeId), Const(i64), Negation(NodeId), Conditional(NodeId, NodeId, NodeId), }

The ast::Context also has methods to allocate new ast::Nodes, get interned strings, and access allocated nodes. These definitions are straightforward, so I have elided them here. If you’re interested, you can look at the source on GitHub.

Parsing

I use the wonderful lalrpop parser generator to generate a parser for the input language. The grammar and actions are given in full below:

// src/parser/grammar.lalrpop use crate::ast; use std::str::FromStr; grammar(ctx: &mut ast::Context); Integer: i64 = <s:r"[0-9]+"> => i64::from_str(s).unwrap(); Identifier: ast::NodeId = <s:r"[a-zA-Z][a-zA-Z0-9_]*"> => ctx.new_identifier(s); Sum: ast::NodeId = { <t:Term> => t, <l:Sum> "+" <r:Term> => ctx.new_node(ast::Node::Addition(l, r)), <l:Sum> "-" <r:Term> => ctx.new_node(ast::Node::Subtraction(l, r)), }; Term: ast::NodeId = { <i:Item> => i, <l:Term> "*" <r:Item> => ctx.new_node(ast::Node::Multiplication(l, r)), <l:Term> "/" <r:Item> => ctx.new_node(ast::Node::Division(l, r)), <l:Term> ">>" <r:Item> => ctx.new_node(ast::Node::RightShift(l, r)), <l:Term> "<<" <r:Item> => ctx.new_node(ast::Node::LeftShift(l, r)), }; Item: ast::NodeId = { <n:Integer> => ctx.new_node(ast::Node::Const(n)), "-" <i:Item> => ctx.new_node(ast::Node::Negation(i)), <i:Identifier> => i, "(" <s:Start> ")" => s, }; pub Start: ast::NodeId = { <s:Sum> => s, <condition:Sum> "?" <consequent:Sum> ":" <alternative:Sum> => ctx.new_node(ast::Node::Conditional(condition, consequent, alternative)), }; Interpretation

To interpret expressions, we need a lookup function that maps identifiers to values, the ast::Context that owns the AST nodes, and the id of the node we are evaluating. We match on this node, and handle the following cases:

  • If the node represents a constant, we return that node’s associated constant value.

  • If the node represents an identifier, we get a reference to its interned identifier string from the context, and then query the lookup function for its value.

  • If the node represents an operator, we recursively evaluate its operands and then apply the operator to the operands’ values. For division, we also check for divide-by-zero return an error.

Here is our initial interpreter function:

// src/eval.rs pub fn eval<L>( ctx: &mut ast::Context, node: ast::NodeId, lookup: &mut L ) -> Result<i64> where L: for<'a> FnMut(&'a str) -> Result<i64>, { match *ctx.node_ref(node) { Node::Const(i) => Ok(i), Node::Identifier(s) => { let s = ctx.interned(s); lookup(s) } Node::Addition(lhs, rhs) => { let lhs = eval(ctx, lhs, lookup)?; let rhs = eval(ctx, rhs, lookup)?; Ok(lhs + rhs) } Node::Subtraction(lhs, rhs) => { let lhs = eval(ctx, lhs, lookup)?; let rhs = eval(ctx, rhs, lookup)?; Ok(lhs - rhs) } Node::Multiplication(lhs, rhs) => { let lhs = eval(ctx, lhs, lookup)?; let rhs = eval(ctx, rhs, lookup)?; Ok(lhs * rhs) } Node::Division(lhs, rhs) => { let lhs = eval(ctx, lhs, lookup)?; let rhs = eval(ctx, rhs, lookup)?; if rhs == 0 { bail!("divide by zero"); } Ok(lhs / rhs) } Node::RightShift(lhs, rhs) => { let lhs = eval(ctx, lhs, lookup)?; let rhs = eval(ctx, rhs, lookup)?; Ok(lhs >> rhs) } Node::LeftShift(lhs, rhs) => { let lhs = eval(ctx, lhs, lookup)?; let rhs = eval(ctx, rhs, lookup)?; Ok(lhs << rhs) } Node::Negation(n) => { let n = eval(ctx, n, lookup)?; Ok(-n) } Node::Conditional(condition, consequent, alternative) => { let condition = eval(ctx, condition, lookup)?; let consequent = eval(ctx, consequent, lookup)?; let alternative = eval(ctx, alternative, lookup)?; Ok(if condition != 0 { consequent } else { alternative }) } } } From Interpreter to Synthesizer

Our synthesizer will take a specification program and a template program. The template program may contain holes — in our system, these are variables that start with the letter “h”. Our goal is to synthesize constant values for these holes such that the template program implements the specification for all values of the non-hole variables.

Let’s consider the example from the original blog post:

// Specification: x * 10 // Template: (x << h1) + (x << h2)

Can we transform multiplication by ten into the sum of two constant left shifts? If we can find constant values for h1 and h2, then the answer is yes. Our synthesizer should answer that either h1 = 1 and h2 = 3, or that h1 = 3 and h2 = 1.

To implement synthesis, we will walk the AST and generate constraints for the Z3 SMT solver that reflect the program’s semantics. We will do this for both the specification and the template, and then constrain the results of each of them to be equal to each other for every non-hole constant variable. Finally, we ask Z3 if it can find a solution to all of the constraints. Any solution that exists will provide definitions for the holes.

That is, we are asking the solver to find a solution for

∃h1h2…hm: ∀c1c2…cn: t = s

where t is the template’s constraints, s is the specification’s constraints, hi are holes in the template, and cj are constants in the template and specification programs.

Adrian’s original Python implementation of minisynth takes advantage of Python’s dynamic nature and the Z3 Python library’s operator overloading to reuse the interpreter for constraint generation without any changes to the interpreter function. All you have to do is supply a lookup function that returns Z3 bitvector variables instead of signed integers. A neat trick!

For our Rust implementation, we want to reuse the interpreter as well, but Rust is statically typed and the z3 crate for Rust doesn’t implement operator overloading. So we will factor out an interpret function from our eval function that is generic over some abstract interpreter.

An abstract interpreter must have an associated output type. For normal evaluation, this will be an i64, and for constraints generation it will be a Z3 constraint. The abstract interpreter must have methods for evaluating each operation of the input language, taking its operands as its output type, applying the operation to them, and returning the results as its output type. It must also provide a way to translate constants and identifiers into its output type.

// src/abstract_interpret.rs pub trait AbstractInterpret { /// The output type of this interpreter. type Output; /// Create a constant output value. fn constant(&mut self, c: i64) -> Self::Output; /// `lhs + rhs` fn add(&mut self, lhs: &Self::Output, rhs: &Self::Output) -> Self::Output; /// `lhs - rhs` fn sub(&mut self, lhs: &Self::Output, rhs: &Self::Output) -> Self::Output; /// `lhs * rhs` fn mul(&mut self, lhs: &Self::Output, rhs: &Self::Output) -> Self::Output; /// `lhs / rhs`. Fails on divide by zero. fn div(&mut self, lhs: &Self::Output, rhs: &Self::Output) -> Result<Self::Output>; /// `lhs >> rhs` fn shr(&mut self, lhs: &Self::Output, rhs: &Self::Output) -> Self::Output; /// `lhs << rhs` fn shl(&mut self, lhs: &Self::Output, rhs: &Self::Output) -> Self::Output; /// `-e` fn neg(&mut self, e: &Self::Output) -> Self::Output; /// Returns `1` if `lhs == rhs`, returns `0` otherwise. fn eq(&mut self, lhs: &Self::Output, rhs: &Self::Output) -> Self::Output; /// Returns `1` if `lhs != rhs`, returns `0` otherwise. fn neq(&mut self, lhs: &Self::Output, rhs: &Self::Output) -> Self::Output; /// Perform variable lookup for the identifier `var`. fn lookup(&mut self, var: &str) -> Result<Self::Output>; }

Next we make an interpretation function that takes an abstract interpreter and uses it to interpret an expression of our input language. This looks almost the same as our original eval function, but there is one tricky bit: encoding conditional’s semantics into interpreter methods without using Rust’s control flow, which would be invisible to the solver. To do this, we multiply the activated conditional arm by one and the deactivated conditional arm by zero and then sum the products. An alternative approach would be to add a method for interpreting conditionals directly to the AbstractIntepret trait.

// src/abstract_interpret.rs pub fn interpret<A>( interpreter: &mut A, ctx: &mut ast::Context, node: ast::NodeId, ) -> Result<A::Output> where A: AbstractInterpret, { match *ctx.node_ref(node) { Node::Const(i) => Ok(interpreter.constant(i)), Node::Identifier(s) => { let s = ctx.interned(s); interpreter.lookup(s) } Node::Addition(lhs, rhs) => { let lhs = interpret(interpreter, ctx, lhs)?; let rhs = interpret(interpreter, ctx, rhs)?; Ok(interpreter.add(&lhs, &rhs)) } Node::Subtraction(lhs, rhs) => { let lhs = interpret(interpreter, ctx, lhs)?; let rhs = interpret(interpreter, ctx, rhs)?; Ok(interpreter.sub(&lhs, &rhs)) } Node::Multiplication(lhs, rhs) => { let lhs = interpret(interpreter, ctx, lhs)?; let rhs = interpret(interpreter, ctx, rhs)?; Ok(interpreter.mul(&lhs, &rhs)) } Node::Division(lhs, rhs) => { let lhs = interpret(interpreter, ctx, lhs)?; let rhs = interpret(interpreter, ctx, rhs)?; interpreter.div(&lhs, &rhs) } Node::RightShift(lhs, rhs) => { let lhs = interpret(interpreter, ctx, lhs)?; let rhs = interpret(interpreter, ctx, rhs)?; Ok(interpreter.shr(&lhs, &rhs)) } Node::LeftShift(lhs, rhs) => { let lhs = interpret(interpreter, ctx, lhs)?; let rhs = interpret(interpreter, ctx, rhs)?; Ok(interpreter.shl(&lhs, &rhs)) } Node::Negation(e) => { let e = interpret(interpreter, ctx, e)?; Ok(interpreter.neg(&e)) } Node::Conditional(condition, consequent, alternative) => { let condition = interpret(interpreter, ctx, condition)?; let consequent = interpret(interpreter, ctx, consequent)?; let alternative = interpret(interpreter, ctx, alternative)?; let zero = interpreter.constant(0); let neq_zero = interpreter.neq(&condition, &zero); let eq_zero = interpreter.eq(&condition, &zero); let consequent = interpreter.mul(&neq_zero, &consequent); let alternative = interpreter.mul(&eq_zero, &alternative); Ok(interpreter.add(&consequent, &alternative)) } } }

We refactor eval to apply an implementation of AbstractInterpret that has an i64 associated output type and directly evaluates expressions:

// src/eval.rs struct Eval<'a> { env: &'a HashMap<String, i64>, } impl<'a> AbstractInterpret for Eval<'a> { type Output = i64; fn constant(&mut self, c: i64) -> i64 { c } fn lookup(&mut self, var: &str) -> Result<i64> { self.env .get(var) .cloned() .ok_or_else(|| format_err!("undefined variable: {}", var)) } fn neg(&mut self, e: &i64) -> i64 { -e } fn add(&mut self, lhs: &i64, rhs: &i64) -> i64 { lhs + rhs } fn sub(&mut self, lhs: &i64, rhs: &i64) -> i64 { lhs - rhs } fn mul(&mut self, lhs: &i64, rhs: &i64) -> i64 { lhs * rhs } fn shr(&mut self, lhs: &i64, rhs: &i64) -> i64 { lhs >> rhs } fn shl(&mut self, lhs: &i64, rhs: &i64) -> i64 { lhs << rhs } fn div(&mut self, lhs: &i64, rhs: &i64) -> Result<i64> { if *rhs == 0 { bail!("divide by zero"); } Ok(lhs / rhs) } fn eq(&mut self, lhs: &i64, rhs: &i64) -> i64 { (lhs == rhs) as i64 } fn neq(&mut self, lhs: &i64, rhs: &i64) -> i64 { (lhs != rhs) as i64 } } pub fn eval( ctx: &mut ast::Context, node: NodeId, env: &HashMap<String, i64> ) -> Result<i64> { let eval = &mut Eval { env }; interpret(eval, ctx, node) }

Finally, we are ready to start implementing synthesis!

First we create an implementation of AbstractInterpret that builds up Z3 constraints. Its lookup method keeps track of which variables have been used, categorizes them by whether they are a hole or an unknown constant, and makes sure that subsequent lookups of the same identifier return the same Z3 variable. All other methods map straightforwardly onto Z3 method calls.

// src/synthesize.rs struct Synthesize<'a, 'ctx> where 'ctx: 'a, { ctx: &'ctx z3::Context, vars: &'a mut HashMap<String, z3::Ast<'ctx>>, holes: &'a mut HashMap<z3::Ast<'ctx>, String>, const_vars: &'a mut HashSet<z3::Ast<'ctx>>, } impl<'a, 'ctx> AbstractInterpret for Synthesize<'a, 'ctx> { type Output = z3::Ast<'ctx>; fn lookup(&mut self, var: &str) -> Result<z3::Ast<'ctx>> { if !self.vars.contains_key(var) { let c = self.ctx.fresh_bitvector_const(var, 64); self.vars.insert(var.to_string(), c.clone()); if var.starts_with("h") { self.holes.insert(c, var.to_string()); } else { self.const_vars.insert(c); } } Ok(self.vars[var].clone()) } fn constant(&mut self, c: i64) -> z3::Ast<'ctx> { z3::Ast::bitvector_from_i64(self.ctx, c as i64, 64) } fn add(&mut self, lhs: &z3::Ast<'ctx>, rhs: &z3::Ast<'ctx>) -> z3::Ast<'ctx> { lhs.bvadd(rhs) } fn sub(&mut self, lhs: &z3::Ast<'ctx>, rhs: &z3::Ast<'ctx>) -> z3::Ast<'ctx> { lhs.bvsub(rhs) } fn mul(&mut self, lhs: &z3::Ast<'ctx>, rhs: &z3::Ast<'ctx>) -> z3::Ast<'ctx> { lhs.bvmul(rhs) } fn div(&mut self, lhs: &z3::Ast<'ctx>, rhs: &z3::Ast<'ctx>) -> Result<z3::Ast<'ctx>> { Ok(lhs.bvsdiv(rhs)) } fn shr(&mut self, lhs: &z3::Ast<'ctx>, rhs: &z3::Ast<'ctx>) -> z3::Ast<'ctx> { lhs.bvlshr(&rhs) } fn shl(&mut self, lhs: &z3::Ast<'ctx>, rhs: &z3::Ast<'ctx>) -> z3::Ast<'ctx> { lhs.bvshl(&rhs) } fn neg(&mut self, e: &z3::Ast<'ctx>) -> z3::Ast<'ctx> { e.bvneg() } fn eq(&mut self, lhs: &z3::Ast<'ctx>, rhs: &z3::Ast<'ctx>) -> z3::Ast<'ctx> { lhs._eq(rhs).ite(&self.constant(1), &self.constant(0)) } fn neq(&mut self, lhs: &z3::Ast<'ctx>, rhs: &z3::Ast<'ctx>) -> z3::Ast<'ctx> { lhs._eq(rhs).not().ite(&self.constant(1), &self.constant(0)) } }

Our synthesis function will take the specification program and the template program, and then use the Synthesize abstract interpreter to generate constraints for each of them.

// src/synthesize.rs pub fn synthesize<'a>( z3_ctx: &'a z3::Context, ast_ctx: &mut ast::Context, specification: NodeId, template: NodeId, ) -> Result<HashMap<String, i64>> { let mut vars = HashMap::new(); let mut holes = HashMap::new(); let mut const_vars = HashSet::new(); let synth = &mut Synthesize { ctx: z3_ctx, vars: &mut vars, holes: &mut holes, const_vars: &mut const_vars, }; let specification = interpret(synth, ast_ctx, specification)?; if !synth.holes.is_empty() { bail!("the specification cannot have any holes!"); } let template = interpret(synth, ast_ctx, template)?; // ... }

Next, we extract the constant variables and create our goal, which is a for-all constraint. The template must be equal to the specification for all possible values these constants could take.

let const_vars: Vec<_> = const_vars.iter().collect(); let templ_eq_spec = specification._eq(&template); let goal = if const_vars.is_empty() { templ_eq_spec } else { z3::Ast::forall_const(&const_vars, &templ_eq_spec) };

Now that we have constructed our goal, we ask Z3 to solve it. If it can find an answer, we extract the values its assigned to each of the holes and return the results as a hash map.

let solver = z3::Solver::new(z3_ctx); solver.assert(&goal); if solver.check() { let model = solver.get_model(); let mut results = HashMap::new(); for (hole, name) in holes { results.insert(name, model.eval(&hole).unwrap().as_i64().unwrap()); } Ok(results) } else { bail!("no solution") }

And now we have a synthesizer!

When given

// Specification: x * 10 // Template: (x << h1) + (x << h2)

our synthesis gives the answer

{ "h1": 1, "h2": 3, }

And when given

// Specification: x * 9 // Template: x << (hb1 ? x : hn1) + (hb2 ? x : hn2)

it gives us the answer

{ "hb1": 0, "hb2": 1, "hn1": 3, "hn2": 0, } Conclusion

This was quite fun!

Thanks to Adrian Sampson for writing the original blog post and minisynth Python implementation.

If you would like to learn more, here are a few resources:

Categorieën: Mozilla-nl planet

Andy McKay: So done with the NFL

Mozilla planet - do, 15/11/2018 - 09:00

I've been an NFL for fan for a long time. It started before university when I rebelled against any sport that was vaguely popular at school (and seemed absolutely terrible). For no other reason than they did well at the time, I became a Washington Redskins fan (yes I'm old).

I started a football team at university, I was involved in it. I even heard Chuck Noll speak once. If there was a Redskins game on TV, I would go up to the local pub in my jersey and watch the game.

Over the last few years I've become pretty upset with what the NFL has become. Well the NFL has always been this way - but I didn't care. I enjoyed the game, the drama, the strategy, the rivalies, and I ignored or excused away all the problems for my own enjoyment.

Finally I realised that I couldn't keep doing this. The problems just kept increasing:

  • The Redskins is a terrible name for a team and is pretty much condemned as a racist. They need to change it, but they won't because the Redskins make lots of money for Daniel Synder (Redskins owner).

  • The treatment of players and the problems with concussions has been terrible. The NFL has swept it under the rug for so long. Yes they've introduced changes, but tried to balance the fundamental problems that constant head contact is part of the game.

  • Cheerleaders.

  • Colin Kapernick.

  • The owners siding with Trump over their players.

  • The NFL is technically taxed as a charity so it isn't a good corporate citizen.

  • The league owners hold regularly hold cities and tax payers to ransom over stadiums.

  • So many adverts.

Daniel Snyder is one such business person and I don't want to support him. I want to be proud of the thing I spend so much time following and I want to be a good example to my daughters. The only way I know how to do that is stop watching the NFL.

It's now over half way through the season, I haven't watched a game, I don't really know what's going. I've unsubscribed from all the football blogs, podcasts and tweets. They were showing the standings on the TV in a pub and it showed that the Redskins are doing quite well this year after years of being crap. But whatever, I don't care.

Perhaps something will change to make me go back, but its not the game being boring, it's the sides that the NFL takes. Somethings got to change.

Footnote: with the exception of the Green Bay Packers who are the only non-profit, community-owned major league professional sports team. Have no cheerleaders, play in all kinds of weather and are just awesome. They haven't solved the problem about treating their players properly or being in a league with other terrible people though.

Categorieën: Mozilla-nl planet

Ian Bicking: Thoughts on the Firefox Email Tabs experiment

Mozilla planet - do, 15/11/2018 - 07:00

We recently released Email Tabs in Firefox Test Pilot. This was a project I championed, and I wanted to offer some context on it.

Email Tabs is a browser add-on that makes it easier to compose an email message from your tabs/pages. The experiment page describes how it works, but to summarize it from a technical point of view:

  • You choose some tabs
  • The add-on gets the best title and URL from the tab(s), makes a screenshot, and uses reader view to get simplified content from the tab
  • It opens a email compose page
  • It asks you what you want your email to look like (links, entire articles, screenshots)
  • It injects the HTML (somewhat brutally) into the email composition window
  • When the email is sent, if offers to close the compose window or all the tabs you’ve sent

It’s not fancy engineering. It’s just-make-it-work engineering. It does not propose a new standard for composing HTML emails. It doesn’t pay attention to your existing mail settings. It does not push forward the state of the art. It has no mobile component. Notably, no one in Mozilla ever asked us to make this thing. And yet I really like this add-on, and so I feel a need to explain why.

User Research origins

A long time ago Mozilla did research into Save/Share/Revisit. The research was based on interviews, journals, and directly watching people do work on their computers.

The results should not be surprising, but it was important to actually have them documented and backed up by research:

  • People use simple techniques
  • Everyone claims to be happy with their current processes
  • Everyone used multiple tools that typically fed into each other
  • Those processes might seem complicated and inefficient to me, but didn’t to them
  • People said they might be open to improvements in specific steps
  • People were not interested in revamping their overall processes
  • Some techniques were particularly popular:
  • Screenshots
  • URLs
  • Email
  • Texting
  • Bookmarks

Not everyone used all of these, but they were all popular.

The research made me change a page-freezing/saving tool (Page Shot) into what is now Firefox Screenshots (I didn’t intend to lose the freezing functionality along the way, but things happen when you ship).

Even if the research was fairly clear, it wasn’t prescriptive, and life moved on. But it sat in the back of my head, both email and the general question of workflows. And once I was doing less work on Screenshots I felt compelled to come back to it. Email stuck out, both because of how ubiquitous it was, and how little anyone cared about it. It seemed easy to improve on.

Email is also multipurpose. People will apologetically talk about emailing themselves something in order to save it, even though everyone does it. It can be a note for the future, something to archive for later, a message, a question, an FYI. One of the features of Email Tabs that I’m fond of is the ability to send a set of tabs, and then close those same tabs. Have a set of tabs that represent something you don’t want to forget, but don’t want to use right now? Send it to yourself. And unlike structured storage (like a bookmark folder), you can describe as much as you want about your next steps in the email itself.

Choosing to integrate with webmail

The obvious solution is to make something that emails out a page. A little web service perhaps, and you give it a URL and it fetches it, and then something that forwards the current URL to that service…

What seems simple becomes hard pretty quickly. Of course you have to fetch the page, and render it, and worry about JavaScript, and so on. But even if you skip that, then what email address will it come from? Do you integrate with a contact list? Make your own? How do you let people add a little note? A note per tab? Do you save a record?

Prepopulating an email composition answers a ton of questions:

  • All the mail infrastructure
  • From addresses, email verification, selecting your address, etc
  • To field, CC, address book
  • The editable body gives the user control and the ability to explain why they are sending something
  • It’s very transparent to the user what they are sending, and they confirm it by hitting Send

Since then I’ve come to appreciate the power of editable documents. Again it should be obvious, but there’s this draw any programmer will feel towards structured data and read-only representations of that data. The open world of an email body is refreshingly unconstrained.

Email providers & broken browsers

One downside to this integration is that we are shipping with only Gmail support. That covers most people, but it feels wrong.

This is an experiment, so keep it simple, right? And that was the plan until people from marketing kept asking over and over for us to support other clients and we thought: if they care so much maybe they are right.

We didn’t get support for other providers ready for launch, but we did get a good start on it. Along the way I saw that Yahoo Mail is broken and Outlook isn’t supported at all in Firefox (and the instructions point to a pretty unhelpful addons.mozilla.org search). That’s millions of users who aren’t getting a good experience.

Growing Firefox is a really hard problem. Of course Mozilla has also studied this quite a bit, and one of the strongest conclusions is that people change their browser when their browser breaks. People aren’t out there looking for something better, everyone has better things to do than think about their web browser. But if things don’t work people go searching.

But what does broken really mean? I suspect if we looked more closely we might be surprised. The simple answer: something is broken if it doesn’t act the way it should. But what “should” something do? If you click a link and Mail.app opens up, and you don’t use Mail.app, that’s broken. To Mozilla developers, if Mail.app is your registered default mail provider, then it “should” open up. Who’s right?

Email Tabs doesn’t offer particular insight into this, but I do like that we’ve created something with the purpose of enabling a successful workflow. Nothing is built to a spec, or to a standard, it’s only built to work. I think that process is itself revealing.

Listening to the research

Research requires interpretation. We asked questions about saving, sharing, and revisiting content, and we got back answers on those topics. Were those the right questions to ask? They seem pretty good, but there’s other pretty good questions that will lead to very different answers. What makes you worried when you use the web? What do you want from a browser? What do you think about Firefox? What do you use a browser for? What are you doing when you switch from a phone to a desktop browser? We’ve asked all these questions, and they point to different answers.

And somewhere in there you have to find an intersection between what you hear in the research and what you know how to do. There’s no right answer. But there is something different when you start from the user research, instead of using the user research. There’s a different sort of honesty to the conclusions, and I hope that comes through in the product.

I know what Email Tabs isn’t: it’s not part of any strategy. It’s not part of any kind of play for anything. There’s no ulterior motives. There’s no income potential. This makes its future very hazy. And it won’t be a blow-up success. It is merely useful. But I like it, and I hope we do more.

Categorieën: Mozilla-nl planet

The Mozilla Blog: Firefox Monitor Launches in 26 Languages and Adds New Desktop Browser Feature

Mozilla planet - do, 15/11/2018 - 04:35

Since the launch of Firefox Monitor, a free service that notifies you when your email has been part of a breach, hundreds of thousands of people have signed up.

In response to the excitement from our global audience, Firefox Monitor is now being made available in more than 26 languages. We’re excited to bring Firefox Monitor to users in their native languages and make it easier for people to learn about data breaches and take action to protect themselves.

When your personal information is possibly at risk in a data breach, reading news and information in the language you understand best helps you to feel more in control. Now, Firefox Monitor will be available in Albanian, Traditional and Simplified Chinese, Czech, Dutch, English (Canadian), French, Frisian, German, Hungarian, Indonesian, Italian, Japanese, Malay, Portuguese (Brazil), Portuguese (Portugal), Russian, Slovak, Slovenian, Spanish (Argentina, Mexico, and Spain), Swedish, Turkish, Ukranian and Welsh.

We couldn’t have accomplished this feat without our awesome Mozilla community of volunteers who worked together to make this happen. We’re so grateful for their support in making Firefox Monitor available to more than 2.5 billion non-English speakers.

Introducing Firefox Monitor Notifications

Along with making Monitor available in multiple languages, today we’re also releasing a new feature exclusively for Firefox users. Specifically, we are adding a notification to our Firefox Quantum browser that alerts desktop users when they visit a site that has had a recently reported data breach. We’re bringing this functionality to Firefox users in recognition of the growing interest in these types of privacy- and security-centric features. This new functionality will gradually roll out to Firefox users over the coming weeks.

While using the Firefox Quantum browser, when you land on a site that’s been breached, you’ll get a notification. You can click on the alert to visit Firefox Monitor and scan your email to see whether or not you were involved in that data breach. This alert will appear at most once per site and only for data breaches reported in the previous twelve months. Website owners can learn about our data breach disclosure policy here. If you do not wish to see these alerts on any site, you can simply choose to “never show Firefox Monitor alerts” by clicking the dropdown arrow on the notification.

 

You’ll be notified of a data breach when you visit a site in Firefox

 

For those new to Firefox Monitor, here’s a brief step-by-step guide on how Firefox Monitor works:

Step 1 – Visit monitor.firefox.com to see if your email has been part of a known data breach

Simply type in your email address, and it will be scanned against a database that serves as a library of known data breaches.

Step 2 – Learn about future data breaches

Sign up for Firefox Monitor using your email address and we will notify you about data breaches when we learn about them.

Step 3 – Use Firefox to learn about the sites you visit that have been breached

While using the Firefox browser, when you land on a site that’s been breached, you’ll get a notification to scan with Firefox Monitor whether or not you’ve been involved in that data breach.

Being part of a data breach is not fun, and we have tips and remedies in our project, Data Leeks. Through recipes and personal stories of those who’ve been affected by a data breach, we’re raising awareness about online privacy.

We invite you to take a look at Firefox Monitor to see if you’ve been part of a data breach, and sign up to be prepared for the next data breach that happens.

 

The post Firefox Monitor Launches in 26 Languages and Adds New Desktop Browser Feature appeared first on The Mozilla Blog.

Categorieën: Mozilla-nl planet

Firefox Monitor Launches in 26 Languages and Adds New Desktop Browser Feature

Mozilla Blog - do, 15/11/2018 - 04:35

Since the launch of Firefox Monitor, a free service that notifies you when your email has been part of a breach, hundreds of thousands of people have signed up.

In response to the excitement from our global audience, Firefox Monitor is now being made available in more than 26 languages. We’re excited to bring Firefox Monitor to users in their native languages and make it easier for people to learn about data breaches and take action to protect themselves.

When your personal information is possibly at risk in a data breach, reading news and information in the language you understand best helps you to feel more in control. Now, Firefox Monitor will be available in Albanian, Traditional and Simplified Chinese, Czech, Dutch, English (Canadian), French, Frisian, German, Hungarian, Indonesian, Italian, Japanese, Malay, Portuguese (Brazil), Portuguese (Portugal), Russian, Slovak, Slovenian, Spanish (Argentina, Mexico, and Spain), Swedish, Turkish, Ukranian and Welsh.

We couldn’t have accomplished this feat without our awesome Mozilla community of volunteers who worked together to make this happen. We’re so grateful for their support in making Firefox Monitor available to more than 2.5 billion non-English speakers.

Introducing Firefox Monitor Notifications

Along with making Monitor available in multiple languages, today we’re also releasing a new feature exclusively for Firefox users. Specifically, we are adding a notification to our Firefox Quantum browser that alerts desktop users when they visit a site that has had a recently reported data breach. We’re bringing this functionality to Firefox users in recognition of the growing interest in these types of privacy- and security-centric features. This new functionality will gradually roll out to Firefox users over the coming weeks.

While using the Firefox Quantum browser, when you land on a site that’s been breached, you’ll get a notification. You can click on the alert to visit Firefox Monitor and scan your email to see whether or not you were involved in that data breach. This alert will appear at most once per site and only for data breaches reported in the previous twelve months. Website owners can learn about our data breach disclosure policy here. If you do not wish to see these alerts on any site, you can simply choose to “never show Firefox Monitor alerts” by clicking the dropdown arrow on the notification.

 

You’ll be notified of a data breach when you visit a site in Firefox

 

For those new to Firefox Monitor, here’s a brief step-by-step guide on how Firefox Monitor works:

Step 1 – Visit monitor.firefox.com to see if your email has been part of a known data breach

Simply type in your email address, and it will be scanned against a database that serves as a library of known data breaches.

Step 2 – Learn about future data breaches

Sign up for Firefox Monitor using your email address and we will notify you about data breaches when we learn about them.

Step 3 – Use Firefox to learn about the sites you visit that have been breached

While using the Firefox browser, when you land on a site that’s been breached, you’ll get a notification to scan with Firefox Monitor whether or not you’ve been involved in that data breach.

Being part of a data breach is not fun, and we have tips and remedies in our project, Data Leeks. Through recipes and personal stories of those who’ve been affected by a data breach, we’re raising awareness about online privacy.

We invite you to take a look at Firefox Monitor to see if you’ve been part of a data breach, and sign up to be prepared for the next data breach that happens.

 

The post Firefox Monitor Launches in 26 Languages and Adds New Desktop Browser Feature appeared first on The Mozilla Blog.

Categorieën: Mozilla-nl planet

Mozilla Security Blog: When does Firefox alert for breached sites?

Mozilla planet - do, 15/11/2018 - 02:49
Mozilla’s Position on Data Breaches

Data breaches are common for online services. Humans make mistakes, and humans make the Internet. Some online services discover, mitigate, and disclose breaches quickly. Others go undetected for years. Recent breaches include “fresh” data, which means victims have less time to change their credentials before they are in the hands of attackers. While old breaches have had more time to make their way into scripted credential stuffing attacks. All breaches are dangerous to users.

As stated in the Mozilla Manifesto: “Individuals’ security and privacy on the internet are fundamental and must not be treated as optional.” Most people simply don’t know that a data breach has affected them. Which makes it difficult to take the first step to secure their online accounts because they don’t know they’re insecure in the first place. This is why we launched Firefox Monitor.

Informing Firefox Users

Today we are continuing to improve our Firefox Monitor service. To help users who might have otherwise missed breach news or email alerts, we are integrating alerts into Firefox that will notify users when they visit a site that has been breached in the past. This feature integrates notifications into the user’s browsing experience.

To power this feature, we use a list of breached sites provided by our partner, Have I Been Pwned (HIBP). Neither HIBP nor Mozilla can confirm that a user has changed their password after a breach, or whether they have reused a breached password elsewhere. So we do not know whether an individual user is still at risk, and cannot trigger user-specific alerts.

For our initial launch we’ve developed a simple, straightforward methodology:

  • If the user has never seen a breach alert before, Firefox shows an alert when they visit any breached site added to HIBP within the last 12 months.
  • After the user has seen their first alert, Firefox only shows an alert when they visit a breached site added to HIBP within the last 2 months.

We believe this 12-month and 2-month policy are reasonable timeframes to alert users to both the password-reuse and unchanged-password risks.  A longer alert timeframe would help us ensure we make even more users aware of the password-reuse risk. However, we don’t want to alarm users or to create noise by triggering alerts for sites that have long since taken significant steps to protect their users. That noise could decrease the value and usability of an important security feature.

Towards a more Sophisticated Approach

This is an interim approach to bring attention, awareness, and information to our users now, and to start getting their feedback. When we launched our Monitor service, we received tremendous feedback from our early users that we’re using to improve our efforts to directly address users’ top concerns for their online service accounts. For service operators, our partner, Troy Hunt, already has some great articles on how to prevent data breaches from happening, and how to quickly and effectively disclose and recover from them. Over the longer term, we want to work with our users, partners, and all service operators to develop a more sophisticated alert policy. We will base such a policy on stronger signals of individual user risk, and website mitigations.

The post When does Firefox alert for breached sites? appeared first on Mozilla Security Blog.

Categorieën: Mozilla-nl planet

Mozilla Thunderbird: The Thunderbird project is hiring: Software Engineers

Mozilla planet - wo, 14/11/2018 - 23:45
We’re Hiring Again!

You read that right, we are hiring “Software Engineers”, plural. We have some big plans for the next year and you can be a part of it!

You can find the job post below. If you are interested Email your CV/Resume and cover letter to: apply@mozillafoundation.org.

About Thunderbird

Thunderbird is an email client depended on daily by 25 million people on three platforms: Windows, Mac and Linux (and other *nix). It was developed under the Mozilla Corporation until 2014 when the project was handed over to the community.

The Thunderbird project is lead by the Thunderbird Council, a group of volunteers from the community who has a strong interest in moving Thunderbird forward. With the help of the Mozilla Foundation, Thunderbird employs about a handful of staff, and is now hiring additional developers to support the volunteer community in making Thunderbird shine.

You will join the team that is leading Thunderbird into a bright future. We are working on increasing the use of web technologies and decreasing dependencies on the internals of the Mozilla platform, to ensure independence and easier maintenance.

The Thunderbird team works openly using public bug trackers and repositories, providing you with a premier chance to show your work to the world.

About the Contract

We need your help to improve and maintain Thunderbird. Moving Thunderbird forward includes replacing/rewriting components to be based primarily on web technologies, reducing the reliance on Mozilla-internal interfaces. It also includes boosting the user experience of the product.

Maintenance involves fixing bugs and regressions, as well as addressing technical debt and enhancing performance. Most tasks have a component of both maintenance and improvement, and any new component needs careful integration with the existing system.

We have compiled a high level list of tasks here; the work assigned to you will include a subset of these items. Let us know in your cover letter where you believe you can make most impact and how.

You will work with community volunteers and other employees around the globe to advance the Thunderbird product and mission of open and secure communications.

This is a remote, hourly 6-month contract with a possibility to extend. Hours will be up to 40 per week.

Your Professional Profile

Since we are looking to fill a few positions, we are interested to hear from both junior and senior candidates who can offer the following:

  • Familiarity with open source development.
  • Solid knowledge and experience developing a large software system.
  • Strong knowledge of JavaScript, HTML and CSS, as well as at least some basic C++ skills.
  • Good debugging skills.
  • Ideally exposure to the Mozilla platform as a voluntary contributor or add-on author with knowledge of XPCOM, XUL, etc.
  • Experience using distributed version control systems (preferably Mercurial).
  • Experience developing software cross-platform applications is a plus.
  • Ability to work with a geographically distributed team and community.
  • A degree in Computer Science would be lovely; real-world experience is essential.

You should be a self-starter. In a large code-base it’s inevitable that you conduct your own research, investigation and debugging, although others in the project will of course share their knowledge.

We expect you to have excellent communication skills and coordinate your work over email, IRC, and Bugzilla as well as video conferencing.

Next Steps

If this position sounds like a good fit for you, please send us your resume and cover letter to apply@mozillafoundation.org.

A cover letter is essential to your application, as we want to know how you’d envision your contributions to the team. Tell us about why you’re passionate about Thunderbird and this position. Also include samples of your work as a programmer, either directly or a link. If you contribute to any open source software, or maintain a blog we’d love to hear about it.

You will be hired as an independent contractor through the Upwork service as a client to the Mozilla Foundation. The Thunderbird Project is separate from the Mozilla Foundation, but the Foundation acts as the project’s fiscal and legal home.

By applying for this job, you are agreeing to have your applications reviewed by Thunderbird contractors and volunteers who are a part of the hiring committee as well as by staff members of the Mozilla Foundation.

Mozilla is an equal opportunity employer. Mozilla and the Thunderbird Project value diversity and do not discriminate based on race, religion, color, national origin, gender, sexual orientation, age, marital status, veteran status, or disability status.

Categorieën: Mozilla-nl planet

Hacks.Mozilla.Org: New & Experimental Web Design Tools: Feedback Requested

Mozilla planet - wo, 14/11/2018 - 17:00
The state of design tools in Firefox

Screenshot of Grid Inspector in action
A year ago, the Firefox DevTools team formed a subgroup to focus on new tools for working in web design, CSS, and HTML. Motivated by the success of the Grid Inspector, and with help from the Developer Outreach, Gecko Platform, and Accessibility teams, we launched the Variable Fonts Editor and the Shape Path Editor, added an Accessibility Inspector, and revamped our Responsive Design Mode.

Our goal: To build empowering new tools that integrate smartly with your modern web design workflow.

Screenshot of Flexbox Inspector

We’re currently hard at work on a comprehensive Flexbox Inspector as well as CSS change-tracking. Early versions of each of these can be tried out in Firefox Nightly. (The Changes panel is hidden behind a flag in about:config: devtools.inspector.changes.enabled)

Please share your input

We’re just getting started, and now we want to learn more about you. Tell us about your biggest CSS and web design issues in the first-ever Design Tools survey! We want to hear from both web developers and designers, and not just Firefox users—Chrome, Safari, Edge, and IE users are greatly encouraged to submit your thoughts!

 We need your input! Tell us about your day-to-day work in web design and CSS (image of otter with wrench)

In early 2019, we’ll post an update with the results in order to share our data with the greater community and continue our experiment in open design.

Get in touch

Feel free to chat with the Firefox DevTools team at any time via @FirefoxDevTools on Twitter or Discourse. You can also learn more about getting involved.

The post New & Experimental Web Design Tools: Feedback Requested appeared first on Mozilla Hacks - the Web developer blog.

Categorieën: Mozilla-nl planet

Your Privacy Focused Holiday Shopping Guide

Mozilla Blog - wo, 14/11/2018 - 13:00

For the second year, Mozilla is releasing *Privacy Not Included. We’ll help you identify which connected devices provide robust privacy and security features — and which ones don’t. 

&#x1f3b6; He sees you when you’re sleeping &#x1f3b6;

&#x1f3b6; He knows when you’re awake &#x1f3b6;

&#x1f3b6; He knows if you’ve been bad or good… &#x1f3b6;

The lyrics to “Santa Claus Is Comin’ to Town” detail an omniscient Saint Nicholas. But in 2018 — in an era of always-listening products and apps — the lyrics might as well be detailing the latest connected device.

This holiday season, Mozilla is helping consumers identify which connected products are secure and trustworthy — and which aren’t. The goal: help consumers shop for gifts based on how well they protect the privacy and security of their friends and family, in addition to traditional factors like a product’s price and performance.

For the second year, we’re releasing *Privacy Not Included, a shopping guide that lists connected devices’ privacy and security traits. Mozilla researchers spent the last several months exploring whether or not products encrypt personal information, offer automatic security updates, have clear privacy policies, and more.

Our researchers focused on the season’s most popular connected devices in the United States, from Nintendo Switch and the latest Roku to Fitbits and assorted drones, smart watches, and even a smart dinosaur. This year’s guide features:

  • Mozilla researchers did not make a conclusive determination if over half of the products met Minimum Security Standards. This was based on factors including if a company did not respond to inquiries or if a company’s response conflicted with recent independent security audits or penetration tester reports.
  • Answers to important questions like, “Can this product spy on me?” “Is it tracking my location?” and “Can I control the data it collects about me?”.
  • The debut of the Creep-O-Meter, an interactive tool allowing readers to rate how creepy they think a product using a sliding scale of “Super Creepy” to “Not Creepy,”  as well to share how likely or unlikely they are to buy it. The home page of the *Privacy Not Included guide lists product based on rankings from Not Creepy to Super Creepy (Nearly 2,500 ratings were submitted by users during the guide’s beta testing period that began in late October.)

  • An assessment of how easy — or hard — it is to read a products’ privacy policies using  Carnegie Mellon’s Explore Usable Privacy project, which created an algorithm to determine reading levels. The most common reading level required is a college reading level (grade 14). Tile Mate’s privacy policy is identified as the most difficult, requiring a college graduate reading level (grade 18), while the Tractive GPS 3G Pet Tracker is identified as the easiest to read, requiring a middle school reading level (grade 8).

We soft-launched this year’s guide at MozFest in October. And already, readers are weighing in. Nintendo Switch — which features encryption and automatic security updates — has emerged as one of the more trusted devices among users in the guide, with 72% of readers saying “not creepy.” Alternatively, the FREDI Baby Monitor — which lacks encryption and has the default password “123” — has 73% of readers saying “super creepy.”

So, why does Mozilla publish *Privacy Not Included?

There’s no shortage of holiday shopping guides. But most focus on price and performance, not privacy. We believe that’s a major oversight. Each day, more and more headlines emerge about flawed connected devices. These devices can track our locations without us knowing; they can sell our data to a galaxy of advertisers; and they often can be hacked or manipulated. In recent years, even stuffed animals and a children’s doll have been compromised.

*Privacy Not Included is part of Mozilla’s work to spark mainstream conversations about online privacy and security — and to put individual internet users in control of their own data. This guide compliments other Mozilla initiatives, like our consumer privacy campaigns; our annual Internet Health Report; and our roster of Fellows who develop research, policies, and products around privacy and security.

Thanks for reading. And safe shopping!

 

The post Your Privacy Focused Holiday Shopping Guide appeared first on The Mozilla Blog.

Categorieën: Mozilla-nl planet

Robert O'Callahan: Comparing The Quality Of Debug Information Produced By Clang And Gcc

Mozilla planet - di, 13/11/2018 - 23:36

I've had an intuition that clang produces generally worse debuginfo than gcc for optimized C++ code. It seems that clang builds have more variables "optimized out" — i.e. when stopped inside a function where a variable is in scope, the compiler's generated debuginfo does not describe the value of the variable. This makes debuggers less effective, so I've attempted some qualitative analysis of the issue.

I chose to measure, for each parameter and local variable, the range of instruction bytes within its function over which the debuginfo can produce a value for this variable, and also the range of instruction bytes over which the debuginfo says the variable is in scope (i.e. the number of instruction bytes in the enclosing lexical block or function). I add those up over all variables, and compute the ratio of variable-defined-bytes to variable-in-scope-bytes. The higher this "definition coverage" ratio, the better.

This metric has some weaknesses. DWARF debuginfo doesn't give us accurate scopes for local variables; the defined-bytes for a variable defined halfway through its lexical scope will be about half of its in-scope-bytes, even if the debuginfo is perfect, so the ideal ratio is less than 1 (and unfortunately we can't compute it). In debug builds, and sometimes in optimized builds, compilers may give a single definition for the variable value that applies to the entire scope; this improves our metric even though the results are arguably worse. Sometimes compilers produce debuginfo that is simply incorrect; our metric doesn't account for that. Not all variables and functions are equally interesting for debugging, but this metric weighs them all equally. The metric assumes that the points of interest for a debugger are equally distributed over instruction bytes. On the other hand, the metric is relatively simple. It focuses on what we care about. It depends only on the debuginfo, not on the generated code or actual program executions. It's robust to constant scaling of code size. We can calculate the metric for any function or variable, which makes it easy to drill down into the results and lets us rank all functions by the quality of their debuginfo. We can compare the quality of debuginfo between different builds of the same binary at function granularity. The metric is sensitive to optimization decisions such as inlining; that's OK.

I built a debuginfo-quality tool in Rust to calculate this metric for an arbitrary ELF binary containing DWARF debuginfo. I applied it to the main Firefox binary libxul.so built with clang 8 (8.0.0-svn346538-1~exp1+0~20181109191347.1890~1.gbp6afd8e) and gcc 8 (8.2.1 20181105 (Red Hat 8.2.1-5)) using the default Mozilla build settings plus ac_add_options --enable-debug; for both compilers that sets the most relevant options to -g -Os -fno-omit-frame-pointer. I ignored the Rust compilation units in libxul since they use LLVM in both builds.

In our somewhat arbitrary metric, gcc is significantly ahead of clang for both parameters and local variables. "Parameters" includes the parameters of inlined functions. As mentioned above, the ideal ratio for local variables is actually less than 1, which explains at least part of the difference between parameters and local variables here.

gcc uses some debuginfo features that clang doesn't know about yet. An important one is DW_OP_GNU_entry_value (standardized as DW_OP_entry_value in DWARF 5). This defines a variable (usually a parameter) in terms of an expression to be evaluated at the moment the function was entered. A traditional debugger can often evaluate such expressions after entering the function, by inspecting the caller's stack frame; our Pernosco debugger has easy access to all program states, so such expressions are no problem at all. I evaluated the impact of DW_OP_GNU_entry_value and the related DW_OP_GNU_parameter_ref by configuring debuginfo-quality to treat definitions using those features as missing. (I'm assuming that gcc only uses those features when a variable value is not otherwise available.)

DW_OP_GNU_entry_value has a big impact on parameters but almost no impact on local variables. It accounts for the majority, but not all, of gcc's advantage over clang for parameters. DW_OP_GNU_parameter_ref has almost no impact at all. However, in most cases where DW_OP_GNU_entry_value would be useful, users can work around its absence by manually inspecting earlier stack frames, especially when time-travel is available. Therefore implementing DW_OP_GNU_entry_value may not be as high a priority as these numbers would suggest.

Improving the local variable numbers may be more useful. I used debuginfo-quality to compare two binaries (clang-built and gcc-built), computing, for each function, the difference in the function's definition coverage ratios, looking only at local variables and sorting functions according to that difference:

debuginfo-quality --language cpp --functions --only-locals ~/tmp/clang-8-libxul.so ~/tmp/gcc-8-libxul.soThis gives us a list of functions starting with those where clang is generating the worst local variable information compared to gcc (and ending with the reverse). There are a lot of functions where clang failed to generate any variable definitions at all while gcc managed to generate definitions covering the whole function. I wonder if anyone is interested in looking at these functions and figuring out what needs to be fixed in clang.

Designing and implementing this kind of analysis is error-prone. I've made my analysis tool source code available, so feel free to point out any improvements that could be made.

Update Helpful people on Twitter pointed me to some excellent other work in this area. Dexter is another tool for measuring debuginfo quality; it's much more thorough than my tool, but less scalable and depends on a particular program execution. I think it complements my work nicely. It has led to ongoing work to improve LLVM debuginfo. There is also CheckDebugify infrastructure in LLVM to detect loss of debuginfo, which is also driving improvements. Alexandre Oliva has an excellent writeup of what gcc does to preserve debuginfo through optimization passes.

Update #2 Turns out llvm-dwarfdump has a --statistics option which measures something very similar to what I'm measuring. One difference is that if a variable has any definitions at all, llvm-dwarfdump treats the program point where it's first defined as the start of its scope. That's an assumption I didn't want to make. There is a graph of this metric over the last 5.5 years of clang, using clang 3.4 as a benchmark. It shows that things got really bad a couple of years ago but have since been improving.

Categorieën: Mozilla-nl planet

Hacks.Mozilla.Org: Private by Design: How we built Firefox Sync

Mozilla planet - di, 13/11/2018 - 16:09
What is Firefox Sync and why would you use it

That shopping rabbit hole you started on your laptop this morning? Pick up where you left off on your phone tonight. That dinner recipe you discovered at lunchtime? Open it on your kitchen tablet, instantly. Connect your personal devices, securely. – Firefox Sync

Firefox Sync lets you share your bookmarks, browsing history, passwords and other browser data between different devices, and send tabs from one device to another. It’s a feature that millions of our users take advantage of to streamline their lives and how they interact with the web.

But on an Internet where sharing your data with a provider is the norm, we think it’s important to highlight the privacy aspects of Firefox Sync.

Firefox Sync by default protects all your synced data so Mozilla can’t read it. We built Sync this way because we put user privacy first. In this post, we take a closer look at some of the technical design choices we made and why.

When building a browser and implementing a sync service, we think it’s important to look at what one might call ‘Total Cost of Ownership’.  Not just what users get from a feature, but what they give up in exchange for ease of use.

We believe that by making the right choices to protect your privacy, we’ve also lowered the barrier to trying out Sync. When you sign up and choose a strong passphrase, your data is protected from both attackers and from Mozilla, so you can try out Sync without worry. Give it a shot, it’s right up there in the menu bar!

Sign in to Sync Button in the Firefox Menu

Why Firefox Sync is safe

Encryption allows one to protect data so that it is entirely unreadable without the key used to encrypt it. The math behind encryption is strong, has been tested for decades, and every government in the world uses it to protect its most valuable secrets.

The hard part of encryption is that key. What key do you encrypt with, where does it come from, where is it stored, and how does it move between places? Lots of cloud providers claim they encrypt your data, and they do. But they also have the key! While the encryption is not meaningless, it is a small measure, and does not protect the data against the most concerning threats.

The encryption key is the essential element. The service provider must never receive it – even temporarily – and must never know it. When you sign into your Firefox Account, you enter a username and passphrase, which are sent to the server. How is it that we can claim to never know your encryption key if that’s all you ever provide us?  The difference is in how we handle your passphrase.

A typical login flow for an internet service is to send your username and passphrase up to the server, where they hash it, compare it to a stored hash, and if correct, the server sends you your data. (Hashing refers to the activity of converting passwords into unreadable strings of characters impossible to revert.)

Typical Web Provider Login Flow

The crux of the difference in how we designed Firefox Accounts, and Firefox Sync (our underlying syncing service), is that you never send us your passphrase. We transform your passphrase on your computer into two different, unrelated values. With one value, you cannot derive the other0. We send an authentication token, derived from your passphrase, to the server as the password-equivalent. And the encryption key derived from your passphrase never leaves your computer.

Firefox Sync Login Flow

Interested in the technical details?  We use 1000 rounds of PBKDF2 to derive your passphrase into the authentication token1. On the server, we additionally hash this token with scrypt (parameters N=65536, r=8, p=1)2 to make sure our database of authentication tokens is even more difficult to crack.

We derive your passphrase into an encryption key using the same 1000 rounds of PBKDF2. It is domain-separated from your authentication token by using HKDF with separate info values. We use this key to unwrap an encryption key (which you generated during setup and which we never see unwrapped), and that encryption key is used to protect your data.  We use the key to encrypt your data using AES-256 in CBC mode, protected with an HMAC3.

This cryptographic design is solid – but the constants need to be updated. One thousand rounds of PBKDF can be improved, and we intend to do so in the future (Bug 1320222). This token is only ever sent over a HTTPS connection (with preloaded HPKP pins) and is not stored, so when we initially developed this and needed to support low-power, low-resources devices, a trade-off was made. AES-CBC + HMAC is acceptable – it would be nice to upgrade this to an authenticated mode sometime in the future.

Other approaches

This isn’t the only approach to building a browser sync feature. There are at least three other options:

Option 1: Share your data with the browser maker

In this approach, the browser maker is able to read your data, and use it to provide services to you. For example,  when you sync your browser history in Chrome it will automatically go into your Web & App Activity unless you’ve changed the default settings. As Google Chrome Help explains, “Your activity may be used to personalize your experience on other Google products, like Search or ads. For example, you may see a news story recommended in your feed based on your Chrome history.”4

Option 2: Use a separate password for sign-in and encryption

We developed Firefox Sync to be as easy to use as possible, so we designed it from the ground up to derive an authentication token and an encryption key – and we never see the passphrase or the encryption key. One cannot safely derive an encryption key from a passphrase if the passphrase is sent to the server.

One could, however, add a second passphrase that is never sent to the server, and encrypt the data using that. Chrome provides this as a non-default option5. You can sign in to sync with your Google Account credentials; but you choose a separate passphrase to encrypt your data. It’s imperative you choose a separate passphrase though.

All-in-all, we don’t care for the design that requires a second passphrase. This approach is confusing to users. It’s very easy to choose the same (or similar) passphrase and negate the security of the design. It’s hard to determine which is more confusing: to require a second passphrase or to make it optional! Making it optional means it will be used very rarely.  We don’t believe users should have to opt-in to privacy.

Option 3: Manual key synchronization

The key (pun intended) to auditing a cryptographic design is to ask about the key: “Where does it come from? Where does it go?” With the Firefox Sync design, you enter a passphrase of your choosing and it is used to derive an encryption key that never leaves your computer.

Another option for Sync is to remove user choice, and provide a passphrase for you (that never leaves your computer). This passphrase would be secure and unguessable – which is an advantage, but it would be near-impossible to remember – which is a disadvantage.

When you want to add a new device to sync to, you’d need your existing device nearby in order to manually read and type the passphrase into the new device. (You could also scan a QR code if your new device has a camera).

Other Browsers

Overall, Sync works the way it does because we feel it’s the best design choice. Options 1 and 2 don’t provide thorough user privacy protections by default. Option 3 results in lower user adoption and thus reduces the number of people we can help (more on this below).

As noted above, Chrome implements Option 1 by default, which means unless you change the settings before you enable sync, Google will see all of your browsing history and other data, and use it to market services to you. Chrome also implements Option 2 as an opt-in feature.

Opera and Vivaldi follow Chrome’s lead, implementing Option 1 by default and Option 2 as an opt-in feature. Update: Vivaldi actually prompts you for a separate password by default (Option 2), and allows you to opt-out and use your login password (Option 1).

Brave, also a privacy-focused browser, has implemented Option 3. And, in fact, Firefox also implemented a form of Option 3 in its original Sync Protocol, but we changed our design in April 2014 (Firefox 29) in response to user feedback6. For example, our original design (and Brave’s current design) makes it much harder to regain access to your data if you lose your device or it gets stolen. Passwords or passphrases make that experience substantially easier for the average user, and significantly increased Sync adoption by users.

Brave’s sync protocol has some interesting wrinkles7. One distinct minus is that you can’t change your passphrase, if it were to be stolen by malware. Another interesting wrinkle is that Brave does not keep track of how many or what types of devices you have. This is a nuanced security trade-off: having less information about the user is always desirable… The downside is that Brave can’t allow you to detect when a new device begins receiving your sync data or allow you to deauthorize it. We respect Brave’s decision. In Firefox, however, we have chosen to provide this additional security feature for users (at the cost of knowing more about their devices).

Conclusion

We designed Firefox Sync to protect your data – by default – so Mozilla can’t read it. We built it this way – despite trade-offs that make development and offering features more difficult – because we put user privacy first. At Mozilla, this priority is a core part of our mission to “ensure the Internet is a global public resource… where individuals can shape their own experience and are empowered, safe and independent.”

0 It is possible to use one to guess the other, but only if you choose a weak password.

1 You can find more details in the full protocol specification or by following the code starting at this point. There are a few details we have omitted to simplify this blog post, including the difference between kA and kB keys, and application-specific subkeys.

2 Server hashing code is located here.

3 The encryption code can be seen here.

4 https://support.google.com/chrome/answer/165139 Section “Use your Chrome history to personalize Google”

5 Chrome 71 says “For added security, Google Chrome will encrypt your data” and describes these two options as “Encrypt synced passwords with your Google username and password” and “Encrypt synced data with your own sync passphrase”.  Despite this wording, only the sync passphrase option protects your data from Google.

6 One of the original engineers of Sync has written two blog posts about the transition to the new sync protocol, and why we did it. If you’re interested in the usability aspects of cryptography, we highly recommend you read them to see what we learned.

7 You can read more about Brave sync on Brave’s Design page.

The post Private by Design: How we built Firefox Sync appeared first on Mozilla Hacks - the Web developer blog.

Categorieën: Mozilla-nl planet

Firefox Test Pilot: Shop intelligently with Price Wise

Mozilla planet - ma, 12/11/2018 - 22:13

Just in time for the holiday shopping season, we’re excited to announce the launch of Price Wise in Firefox Test Pilot.

Price Wise is a new, smart tool to help you save money online. While browsing a product of interest, add it to your watch list:

<figcaption>Tell Price Wise to keep an eye on a product, and it’s added to your watch list.</figcaption>

Price Wise will automatically monitor the prices of products on your watch list. When they drop, we’ll let you know:

<figcaption>When the price drops, Price Wise alerts you with a colorful heads-up.</figcaption>

Price checks are done locally, so your shopping data never leaves Firefox. We’re particularly excited about that; Price Wise is the first Firefox feature designed around Fathom, a toolkit for understanding the content of webpages you browse.

Existing software like this works by tracking you across the web, and it’s often run by advertisers and social networks seeking to learn more about you. Your browser can do these checks for you, while making sure the gathered information never leaves your computer. We know it’s possible to deliver great utility while protecting your privacy, and want you to get a great deal without getting a raw deal.

https://medium.com/media/d4c43d59a67397f159f15c1798de5053/href

Price Wise is launching in the U.S. (English only), and we’ll support the top 5 U.S. shopping sites: Amazon, eBay, Walmart, Best Buy, and Home Depot. We’re launching a narrow pilot to understand usage and site compatibility but plan to expand coverage to other sites, countries, and currencies.

Give Price Wise a try today on Firefox Test Pilot, and let us know what you think!

Shop intelligently with Price Wise was originally published in Firefox Test Pilot on Medium, where people are continuing the conversation by highlighting and responding to this story.

Categorieën: Mozilla-nl planet

Mozilla Reps Community: New Council Members – Fall 2018 Elections

Mozilla planet - ma, 12/11/2018 - 19:31

We are very happy to announce that our 2 new Council members Monica Bonilla and Yofie Setiawan are fully on-boarded and already working moving the Mozilla Reps program forward. A warm welcome from all of us. We we are very excited to have you and can’t wait to build the program together.

https://www.mozilla.org/media/img/mozorg/about/leadership/monica-bonilla.2fc7c83eec6a.jpg https://www.mozilla.org/media/img/mozorg/about/leadership/yofie-setiawan.2b2fde73bb65.jpg

Of course we would like to thank a lot the 2 outgoing members: Mayur Patil and Prathamesh Chavan. You have worked extremely hard to move the program forward and your input and strategic thinking have inspired the rest of the Reps.

The Mozilla Reps Council is the governing body of the Mozilla Reps Program. It provides the general vision of the program and oversees day-to-day operations globally. Currently, 7 volunteers and 2 paid staff sit on the council. Find out more on the Reps wiki.

Categorieën: Mozilla-nl planet

The Firefox Frontier: Let Price Wise track prices for you this holiday shopping season

Mozilla planet - ma, 12/11/2018 - 16:02

The online shopping experience is really geared towards purchases that are made immediately. Countless hours have been spent to get you checked out as soon as possible. If you know … Read more

The post Let Price Wise track prices for you this holiday shopping season appeared first on The Firefox Frontier.

Categorieën: Mozilla-nl planet

Pagina's