Commit 61d56fd0 authored by Kathleen Brade's avatar Kathleen Brade Committed by Georg Koppen
Browse files

Bug 6786: Do not expose system colors to CSS or canvas.

Restore the portion of this fix that was not upstreamed as part of
https://bugzilla.mozilla.org/show_bug.cgi?id=232227: use properly
contrasting colors if the desktop theme specifies white on black
for text colors (see bug 7920). These color choices are not exposed
to content.
parent 68d8e949
Loading
Loading
Loading
Loading
+50 −0
Original line number Diff line number Diff line
@@ -5465,13 +5465,63 @@ ShouldDarkenColors(nsPresContext* aPresContext)
nscolor
nsLayoutUtils::GetColor(nsIFrame* aFrame, nsCSSProperty aProperty)
{
  if (aProperty == eCSSProperty_color)
  {
    nscolor nativeColor = NS_RGB(0, 0, 0);
    if (GetNativeTextColor(aFrame, nativeColor))
      return nativeColor;
  }

  nscolor color = aFrame->GetVisitedDependentColor(aProperty);
  if (ShouldDarkenColors(aFrame->PresContext())) {
    color = DarkenColor(color);
  }

  return color;
}

bool
nsLayoutUtils::GetNativeTextColor(nsIFrame* aFrame, nscolor& aColor)
{
  nsPresContext *presContext = aFrame->PresContext();
  if (!presContext->IsChrome()) {
    // If native appearance was used to draw the background of the containing
    // frame, return a contrasting native foreground color instead of the
    // color from the element's style.  This avoids a problem where black
    // text was displayed on a black background when a Windows theme such as
    // "High Contrast Black" was used.  The background is drawn inside
    // nsNativeThemeWin::ClassicDrawWidgetBackground().
    //
    // Because both the background color and this foreground color are used
    // directly without exposing the colors via CSS computed styles, the
    // native colors are not leaked to content.
    nsIFrame* bgFrame =
                    nsCSSRendering::FindNonTransparentBackgroundFrame(aFrame);
    if (bgFrame) {
      const nsStyleDisplay* displayData = bgFrame->StyleDisplay();
      uint8_t widgetType = displayData->mAppearance;
      nsITheme *theme = presContext->GetTheme();
      if (theme && widgetType && theme->ThemeSupportsWidget(presContext,
                                                            bgFrame,
                                                            widgetType)) {
        bool isDisabled = false;
        nsIContent* frameContent = bgFrame->GetContent();
        if (frameContent && frameContent->IsElement()) {
          EventStates es = frameContent->AsElement()->State();
          isDisabled = es.HasState(NS_EVENT_STATE_DISABLED);
        }

        if (NS_SUCCEEDED(LookAndFeel::GetColorForNativeAppearance(widgetType,
                                                       isDisabled, &aColor))) {
            return true;
        }
      }
    }
  }

  return false;
}

gfxFloat
nsLayoutUtils::GetSnappedBaselineY(nsIFrame* aFrame, gfxContext* aContext,
                                   nscoord aY, nscoord aAscent)
+4 −0
Original line number Diff line number Diff line
@@ -1563,6 +1563,10 @@ public:
  // Get a suitable foreground color for painting aProperty for aFrame.
  static nscolor GetColor(nsIFrame* aFrame, nsCSSProperty aProperty);

  // Get the native text color if appropriate.  If false is returned, callers
  // should fallback to the CSS color.
  static bool GetNativeTextColor(nsIFrame* aFrame, nscolor& aColor);

  // Get a baseline y position in app units that is snapped to device pixels.
  static gfxFloat GetSnappedBaselineY(nsIFrame* aFrame, gfxContext* aContext,
                                      nscoord aY, nscoord aAscent);
+5 −1
Original line number Diff line number Diff line
@@ -1580,7 +1580,11 @@ nsIFrame::DisplayCaret(nsDisplayListBuilder* aBuilder,
nscolor
nsIFrame::GetCaretColorAt(int32_t aOffset)
{
  // Use text color.
  nscolor color = NS_RGB(0, 0, 0);
  if (nsLayoutUtils::GetNativeTextColor(this, color))
    return color;

  // Use CSS text color.
  return StyleColor()->mColor;
}

+3 −0
Original line number Diff line number Diff line
@@ -535,6 +535,9 @@ public:
  static nsresult GetColor(ColorID aID, bool aUseStandinsForNativeColors,
                           nscolor* aResult);

  static nsresult GetColorForNativeAppearance(uint8_t aWidgetType,
                                          bool aIsDisabled, nscolor* aResult);

  /**
   * GetInt() and GetFloat() return a int or float value for aID.  The result
   * might be distance, time, some flags or a int value which has particular
+41 −0
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@
#include "nsLookAndFeel.h"
#include "nsCRT.h"
#include "nsFont.h"
#include "nsThemeConstants.h"
#include "mozilla/dom/ContentChild.h"
#include "mozilla/Preferences.h"
#include "mozilla/gfx/2D.h"
@@ -904,6 +905,46 @@ LookAndFeel::GetColor(ColorID aID, bool aUseStandinsForNativeColors,
                                       aUseStandinsForNativeColors, *aResult);
}

// static
nsresult
LookAndFeel::GetColorForNativeAppearance(uint8_t aWidgetType, bool aIsDisabled,
                                         nscolor* aResult)
{
  NS_ENSURE_ARG_POINTER(aResult);

  ColorID colorID = eColorID_LAST_COLOR;
  switch (aWidgetType) {
    case NS_THEME_TEXTFIELD:
    case NS_THEME_TEXTFIELD_MULTILINE:
    case NS_THEME_LISTBOX:
    case NS_THEME_DROPDOWN:
    case NS_THEME_DROPDOWN_TEXTFIELD:
    case NS_THEME_TREEVIEW:
      colorID = (aIsDisabled) ? eColorID_graytext : eColorID__moz_fieldtext;
      break;

    case NS_THEME_TOOLTIP:
      colorID = eColorID_infotext;
      break;

    case NS_THEME_BUTTON:
    case NS_THEME_GROUPBOX:
    case NS_THEME_PROGRESSBAR:
    case NS_THEME_PROGRESSBAR_VERTICAL:
    case NS_THEME_TAB_PANEL:
    case NS_THEME_STATUSBAR:
    case NS_THEME_STATUSBAR_RESIZER_PANEL:
      colorID = (aIsDisabled) ? eColorID_graytext : eColorID_buttontext;
      break;
  }

  if (LookAndFeel::eColorID_LAST_COLOR == colorID)
    return NS_ERROR_FAILURE;

  *aResult = NS_RGB(0, 0, 0);
  return nsLookAndFeel::GetInstance()->NativeGetColor(colorID, *aResult);
}

// static
nsresult
LookAndFeel::GetInt(IntID aID, int32_t* aResult)