Commit 55c6ab3e authored by Pier Angelo Vendrame's avatar Pier Angelo Vendrame 🎃
Browse files

BB 43869: Hide pens with RFP.

parent a01bf048
Loading
Loading
Loading
Loading
+0 −10
Original line number Diff line number Diff line
@@ -302,11 +302,6 @@ nsDOMAttributeMap* Element::Attributes() {
}

void Element::SetPointerCapture(int32_t aPointerId, ErrorResult& aError) {
  if (OwnerDoc()->ShouldResistFingerprinting(RFPTarget::PointerId) &&
      aPointerId != PointerEventHandler::GetSpoofedPointerIdForRFP()) {
    aError.ThrowNotFoundError("Invalid pointer id");
    return;
  }
  const PointerInfo* pointerInfo =
      PointerEventHandler::GetPointerInfo(aPointerId);
  if (!pointerInfo) {
@@ -334,11 +329,6 @@ void Element::SetPointerCapture(int32_t aPointerId, ErrorResult& aError) {
}

void Element::ReleasePointerCapture(int32_t aPointerId, ErrorResult& aError) {
  if (OwnerDoc()->ShouldResistFingerprinting(RFPTarget::PointerId) &&
      aPointerId != PointerEventHandler::GetSpoofedPointerIdForRFP()) {
    aError.ThrowNotFoundError("Invalid pointer id");
    return;
  }
  if (!PointerEventHandler::GetPointerInfo(aPointerId)) {
    aError.ThrowNotFoundError("Invalid pointer id");
    return;
+85 −44
Original line number Diff line number Diff line
@@ -224,39 +224,78 @@ NS_INTERFACE_MAP_END_INHERITING(MouseEvent)
NS_IMPL_ADDREF_INHERITED(PointerEvent, MouseEvent)
NS_IMPL_RELEASE_INHERITED(PointerEvent, MouseEvent)

void PointerEvent::GetPointerType(nsAString& aPointerType) {
  if (mPointerType.isSome()) {
    aPointerType = mPointerType.value();
    return;
uint16_t PointerEvent::ResistantInputSource(CallerType aCallerType) const {
  const uint16_t inputSource = mEvent->AsPointerEvent()->mInputSource;
  if (!ShouldResistFingerprinting(aCallerType)) {
    return inputSource;
  }

  MOZ_ASSERT(IsTrusted());

  // Bug 1953665: Pen events are inconsistent between platforms.
  // They might emit touch events on Windows and Android, but only mouse events
  // in other platforms. In particular, touch is always disabled on macOS.
#if defined(XP_WIN)
  if (inputSource == MouseEvent_Binding::MOZ_SOURCE_TOUCH ||
      inputSource == MouseEvent_Binding::MOZ_SOURCE_MOUSE) {
    return inputSource;
  }
  // Similar to nsWindow::DispatchTouchEventFromWMPointer.
  switch (mEvent->mMessage) {
    case ePointerMove:
      return mEvent->AsPointerEvent()->mPressure == 0
                 ? MouseEvent_Binding::MOZ_SOURCE_MOUSE  // hover
                 : MouseEvent_Binding::MOZ_SOURCE_TOUCH;
    case ePointerUp:
    case ePointerDown:
    case ePointerCancel:
      return MouseEvent_Binding::MOZ_SOURCE_TOUCH;
    default:
      return MouseEvent_Binding::MOZ_SOURCE_MOUSE;
  }
#elif defined(MOZ_WIDGET_ANDROID)
  return inputSource == MouseEvent_Binding::MOZ_SOURCE_MOUSE
             ? MouseEvent_Binding::MOZ_SOURCE_MOUSE
             : MouseEvent_Binding::MOZ_SOURCE_TOUCH;
#elif defined(MOZ_WIDGET_GTK)
  return inputSource == MouseEvent_Binding::MOZ_SOURCE_TOUCH
             ? MouseEvent_Binding::MOZ_SOURCE_TOUCH
             : MouseEvent_Binding::MOZ_SOURCE_MOUSE;
#elif defined(MOZ_WIDGET_COCOA)
  return MouseEvent_Binding::MOZ_SOURCE_MOUSE;
#else
  return inputSource;
#endif
}

#if SPOOFED_MAX_TOUCH_POINTS <= 0
  if (ShouldResistFingerprinting()) {
    aPointerType.AssignLiteral("mouse");
void PointerEvent::GetPointerType(nsAString& aPointerType,
                                  CallerType aCallerType) {
  if (mPointerType.isSome()) {
    aPointerType = mPointerType.value();
    return;
  }
#endif

  ConvertPointerTypeToString(mEvent->AsPointerEvent()->mInputSource,
                             aPointerType);
  ConvertPointerTypeToString(ResistantInputSource(aCallerType), aPointerType);
}

int32_t PointerEvent::PointerId() {
  return (ShouldResistFingerprinting(true))
             ? PointerEventHandler::GetSpoofedPointerIdForRFP()
             : mEvent->AsPointerEvent()->pointerId;
  return mEvent->AsPointerEvent()->pointerId;
}

double PointerEvent::Width() const {
  return ShouldResistFingerprinting() ? 1.0 : mEvent->AsPointerEvent()->mWidth;
double PointerEvent::Width(CallerType aCallerType) const {
  return ShouldResistFingerprinting(aCallerType)
             ? 1.0
             : mEvent->AsPointerEvent()->mWidth;
}

double PointerEvent::Height() const {
  return ShouldResistFingerprinting() ? 1.0 : mEvent->AsPointerEvent()->mHeight;
double PointerEvent::Height(CallerType aCallerType) const {
  return ShouldResistFingerprinting(aCallerType)
             ? 1.0
             : mEvent->AsPointerEvent()->mHeight;
}

float PointerEvent::Pressure() {
  if (mEvent->mMessage == ePointerUp || !ShouldResistFingerprinting()) {
float PointerEvent::Pressure(CallerType aCallerType) {
  if (mEvent->mMessage == ePointerUp ||
      !ShouldResistFingerprinting(aCallerType)) {
    return mEvent->AsPointerEvent()->mPressure;
  }

@@ -273,14 +312,14 @@ float PointerEvent::Pressure() {
  return spoofedPressure;
}

float PointerEvent::TangentialPressure() {
  return ShouldResistFingerprinting()
float PointerEvent::TangentialPressure(CallerType aCallerType) {
  return ShouldResistFingerprinting(aCallerType)
             ? 0
             : mEvent->AsPointerEvent()->tangentialPressure;
}

int32_t PointerEvent::TiltX() {
  if (ShouldResistFingerprinting()) {
int32_t PointerEvent::TiltX(CallerType aCallerType) {
  if (ShouldResistFingerprinting(aCallerType)) {
    return 0;
  }
  if (mTiltX.isSome()) {
@@ -291,8 +330,8 @@ int32_t PointerEvent::TiltX() {
  return *mTiltX;
}

int32_t PointerEvent::TiltY() {
  if (ShouldResistFingerprinting()) {
int32_t PointerEvent::TiltY(CallerType aCallerType) {
  if (ShouldResistFingerprinting(aCallerType)) {
    return 0;
  }
  if (mTiltY.isSome()) {
@@ -303,12 +342,14 @@ int32_t PointerEvent::TiltY() {
  return *mTiltY;
}

int32_t PointerEvent::Twist() {
  return ShouldResistFingerprinting() ? 0 : mEvent->AsPointerEvent()->twist;
int32_t PointerEvent::Twist(CallerType aCallerType) {
  return ShouldResistFingerprinting(aCallerType)
             ? 0
             : mEvent->AsPointerEvent()->twist;
}

double PointerEvent::AltitudeAngle() {
  if (ShouldResistFingerprinting()) {
double PointerEvent::AltitudeAngle(CallerType aCallerType) {
  if (ShouldResistFingerprinting(aCallerType)) {
    return WidgetPointerHelper::GetDefaultAltitudeAngle();
  }
  if (mAltitudeAngle.isSome()) {
@@ -319,8 +360,8 @@ double PointerEvent::AltitudeAngle() {
  return *mAltitudeAngle;
}

double PointerEvent::AzimuthAngle() {
  if (ShouldResistFingerprinting()) {
double PointerEvent::AzimuthAngle(CallerType aCallerType) {
  if (ShouldResistFingerprinting(aCallerType)) {
    return WidgetPointerHelper::GetDefaultAzimuthAngle();
  }
  if (mAzimuthAngle.isSome()) {
@@ -421,22 +462,22 @@ void PointerEvent::GetPredictedEvents(
  aPointerEvents.AppendElements(mPredictedEvents);
}

bool PointerEvent::ShouldResistFingerprinting(bool aForPointerId) const {
  // There are three simple situations we don't need to spoof this pointer
bool PointerEvent::ShouldResistFingerprinting(CallerType aCallerType) const {
  // There are a few simple situations we don't need to spoof this pointer
  // event.
  //   1. The pref privcy.resistFingerprinting' is false, we fast return here
  //   * We are being called by a System caller
  //   * The pref privcy.resistFingerprinting' is false, we fast return here
  //     since we don't need to do any QI of following codes.
  //   2. This event is generated by scripts.
  //   3. This event is a mouse pointer event.
  //   * This event is generated by scripts.
  //   * This event is a mouse pointer event.
  //  We don't need to check for the system group since pointer events won't be
  //  dispatched to the system group.
  RFPTarget target =
      aForPointerId ? RFPTarget::PointerId : RFPTarget::PointerEvents;
  if (!nsContentUtils::ShouldResistFingerprinting("Efficiency Check", target) ||
  RFPTarget target = RFPTarget::PointerEvents;
  if (aCallerType == CallerType::System ||
      !nsContentUtils::ShouldResistFingerprinting("Efficiency Check", target) ||
      !mEvent->IsTrusted() ||
      (mEvent->AsPointerEvent()->mInputSource ==
           MouseEvent_Binding::MOZ_SOURCE_MOUSE &&
       SPOOFED_MAX_TOUCH_POINTS == 0)) {
      mEvent->AsPointerEvent()->mInputSource ==
          MouseEvent_Binding::MOZ_SOURCE_MOUSE) {
    return false;
  }

+17 −11
Original line number Diff line number Diff line
@@ -41,17 +41,19 @@ class PointerEvent : public MouseEvent {
  PointerEvent* AsPointerEvent() final { return this; }

  int32_t PointerId();
  double Width() const;
  double Height() const;
  float Pressure();
  float TangentialPressure();
  int32_t TiltX();
  int32_t TiltY();
  int32_t Twist();
  double AltitudeAngle();
  double AzimuthAngle();
  double Width(CallerType aCallerType = CallerType::System) const;
  double Height(CallerType aCallerType = CallerType::System) const;
  float Pressure(CallerType aCallerType = CallerType::System);
  float TangentialPressure(CallerType aCallerType = CallerType::System);
  int32_t TiltX(CallerType aCallerType = CallerType::System);
  int32_t TiltY(CallerType aCallerType = CallerType::System);
  int32_t Twist(CallerType aCallerType = CallerType::System);
  double AltitudeAngle(CallerType aCallerType = CallerType::System);
  double AzimuthAngle(CallerType aCallerType = CallerType::System);
  bool IsPrimary();
  void GetPointerType(nsAString& aPointerType);
  void GetPointerType(
      nsAString& aPointerType,
      mozilla::dom::CallerType aCallerType = CallerType::System);
  static bool EnableGetCoalescedEvents(JSContext* aCx, JSObject* aGlobal);
  void GetCoalescedEvents(nsTArray<RefPtr<PointerEvent>>& aPointerEvents);
  void GetPredictedEvents(nsTArray<RefPtr<PointerEvent>>& aPointerEvents);
@@ -62,7 +64,11 @@ class PointerEvent : public MouseEvent {
 private:
  // This method returns the boolean to indicate whether spoofing pointer
  // event for fingerprinting resistance.
  bool ShouldResistFingerprinting(bool aForPointerId = false) const;
  bool ShouldResistFingerprinting(
      CallerType aCallerType = CallerType::System) const;

  uint16_t ResistantInputSource(
      CallerType aCallerType = CallerType::System) const;

  // When the instance is a trusted `pointermove` event but the widget event
  // does not have proper coalesced events (typically, the event is synthesized
+0 −26
Original line number Diff line number Diff line
@@ -421,32 +421,6 @@ void PointerEventHandler::CheckPointerCaptureState(WidgetPointerEvent* aEvent) {

  PointerCaptureInfo* captureInfo = GetPointerCaptureInfo(aEvent->pointerId);

  // When fingerprinting resistance is enabled, we need to map other pointer
  // ids into the spoofed one. We don't have to do the mapping if the capture
  // info exists for the non-spoofed pointer id because of we won't allow
  // content to set pointer capture other than the spoofed one. Thus, it must be
  // from chrome if the capture info exists in this case. And we don't have to
  // do anything if the pointer id is the same as the spoofed one.
  if (nsContentUtils::ShouldResistFingerprinting("Efficiency Check",
                                                 RFPTarget::PointerId) &&
      aEvent->pointerId != (uint32_t)GetSpoofedPointerIdForRFP() &&
      !captureInfo) {
    PointerCaptureInfo* spoofedCaptureInfo =
        GetPointerCaptureInfo(GetSpoofedPointerIdForRFP());

    // We need to check the target element's document should resist
    // fingerprinting. If not, we don't need to send a capture event
    // since the capture info of the original pointer id doesn't exist
    // in this case.
    if (!spoofedCaptureInfo || !spoofedCaptureInfo->mPendingElement ||
        !spoofedCaptureInfo->mPendingElement->OwnerDoc()
             ->ShouldResistFingerprinting(RFPTarget::PointerEvents)) {
      return;
    }

    captureInfo = spoofedCaptureInfo;
  }

  if (!captureInfo ||
      captureInfo->mPendingElement == captureInfo->mOverrideElement) {
    return;
+26 −24
Original line number Diff line number Diff line
@@ -225,13 +225,16 @@ bool TouchEvent::PrefEnabled(nsIDocShell* aDocShell) {
  } else if (touchEventsOverride ==
             mozilla::dom::TouchEventsOverride::Disabled) {
    enabled = false;
  } else if (nsContentUtils::ShouldResistFingerprinting(
                 aDocShell, RFPTarget::PointerEvents)) {
#ifdef MOZ_WIDGET_COCOA
    enabled = false;
#else
    enabled = true;
#endif
  } else {
    const int32_t prefValue = StaticPrefs::dom_w3c_touch_events_enabled();
    if (prefValue == 2) {
      if (nsContentUtils::ShouldResistFingerprinting(
              aDocShell, RFPTarget::PointerEvents)) {
        enabled = SPOOFED_MAX_TOUCH_POINTS != 0;
      } else {
      enabled = PlatformSupportsTouch();

      static bool firstTime = true;
@@ -256,7 +259,6 @@ bool TouchEvent::PrefEnabled(nsIDocShell* aDocShell) {
        }
      }
#endif
      }
    } else {
      enabled = !!prefValue;
    }
Loading