~jconti/ubuntu/oneiric/webkit/fix_doc_path

« back to all changes in this revision

Viewing changes to WebCore/platform/win/FontDataWin.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Mike Hommey
  • Date: 2008-09-27 08:57:48 UTC
  • mfrom: (3.1.6 intrepid)
  • Revision ID: james.westby@ubuntu.com-20080927085748-yhzld00w0rekp961
Tags: 1.0.1-4
WebCore/dom/Document.*, WebCore/loader/DocLoader.*: Avoid DoS via
crafted CSS import statements. Fixes: CVE-2008-3632. Closes: #499771.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Copyright (C) 2006, 2007 Apple Inc.  All rights reserved.
3
 
 *
4
 
 * Redistribution and use in source and binary forms, with or without
5
 
 * modification, are permitted provided that the following conditions
6
 
 * are met:
7
 
 *
8
 
 * 1.  Redistributions of source code must retain the above copyright
9
 
 *     notice, this list of conditions and the following disclaimer. 
10
 
 * 2.  Redistributions in binary form must reproduce the above copyright
11
 
 *     notice, this list of conditions and the following disclaimer in the
12
 
 *     documentation and/or other materials provided with the distribution. 
13
 
 * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14
 
 *     its contributors may be used to endorse or promote products derived
15
 
 *     from this software without specific prior written permission. 
16
 
 *
17
 
 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18
 
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19
 
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20
 
 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21
 
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22
 
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23
 
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24
 
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
 
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26
 
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
 
 */
28
 
 
29
 
#include "config.h"
30
 
#include <winsock2.h>
31
 
#include "Font.h"
32
 
#include "FontCache.h"
33
 
#include "FontData.h"
34
 
#include "FloatRect.h"
35
 
#include "FontDescription.h"
36
 
#include <wtf/MathExtras.h>
37
 
#include <unicode/uchar.h>
38
 
#include <unicode/unorm.h>
39
 
#include <ApplicationServices/ApplicationServices.h>
40
 
#include <mlang.h>
41
 
#include <tchar.h>
42
 
#include <WebKitSystemInterface/WebKitSystemInterface.h>
43
 
 
44
 
namespace WebCore {
45
 
 
46
 
using std::max;
47
 
 
48
 
static inline float scaleEmToUnits(float x, unsigned unitsPerEm) { return unitsPerEm ? x / (float)unitsPerEm : x; }
49
 
 
50
 
void FontData::platformInit()
51
 
{    
52
 
    HDC dc = GetDC(0);
53
 
    SaveDC(dc);
54
 
 
55
 
    SelectObject(dc, m_font.hfont());
56
 
 
57
 
    int faceLength = GetTextFace(dc, 0, 0);
58
 
    Vector<TCHAR> faceName(faceLength);
59
 
    GetTextFace(dc, faceLength, faceName.data());
60
 
 
61
 
    m_isMLangFont = false;
62
 
 
63
 
    m_syntheticBoldOffset = m_font.syntheticBold() ? 1.0f : 0.f;
64
 
 
65
 
    CGFontRef font = m_font.cgFont();
66
 
    int iAscent = CGFontGetAscent(font);
67
 
    int iDescent = CGFontGetDescent(font);
68
 
    int iLineGap = CGFontGetLeading(font);
69
 
    unsigned unitsPerEm = CGFontGetUnitsPerEm(font);
70
 
    float pointSize = m_font.size();
71
 
    float fAscent = scaleEmToUnits(iAscent, unitsPerEm) * pointSize;
72
 
    float fDescent = -scaleEmToUnits(iDescent, unitsPerEm) * pointSize;
73
 
    float fLineGap = scaleEmToUnits(iLineGap, unitsPerEm) * pointSize;
74
 
 
75
 
    m_isSystemFont = !_tcscmp(faceName.data(), _T("Lucida Grande"));
76
 
    
77
 
    // We need to adjust Times, Helvetica, and Courier to closely match the
78
 
    // vertical metrics of their Microsoft counterparts that are the de facto
79
 
    // web standard. The AppKit adjustment of 20% is too big and is
80
 
    // incorrectly added to line spacing, so we use a 15% adjustment instead
81
 
    // and add it to the ascent.
82
 
    if (!_tcscmp(faceName.data(), _T("Times")) || !_tcscmp(faceName.data(), _T("Helvetica")) || !_tcscmp(faceName.data(), _T("Courier")))
83
 
        fAscent += floorf(((fAscent + fDescent) * 0.15f) + 0.5f);
84
 
 
85
 
    m_ascent = lroundf(fAscent);
86
 
    m_descent = lroundf(fDescent);
87
 
    m_lineGap = lroundf(fLineGap);
88
 
    m_lineSpacing = m_ascent + m_descent + m_lineGap;
89
 
 
90
 
    // Measure the actual character "x", because AppKit synthesizes X height rather than getting it from the font.
91
 
    // Unfortunately, NSFont will round this for us so we don't quite get the right value.
92
 
    Glyph xGlyph = GlyphPageTreeNode::getRootChild(this, 0)->page()->glyphDataForCharacter('x').glyph;
93
 
    if (xGlyph) {
94
 
        CGRect xBox;
95
 
        CGFontGetGlyphBBoxes(font, &xGlyph, 1, &xBox);
96
 
        // Use the maximum of either width or height because "x" is nearly square
97
 
        // and web pages that foolishly use this metric for width will be laid out
98
 
        // poorly if we return an accurate height. Classic case is Times 13 point,
99
 
        // which has an "x" that is 7x6 pixels.
100
 
        m_xHeight = scaleEmToUnits(max(CGRectGetMaxX(xBox), CGRectGetMaxY(xBox)), unitsPerEm) * pointSize;
101
 
    } else {
102
 
        int iXHeight = CGFontGetXHeight(font);
103
 
        m_xHeight = scaleEmToUnits(iXHeight, unitsPerEm) * pointSize;
104
 
    }
105
 
 
106
 
    RestoreDC(dc, -1);
107
 
    ReleaseDC(0, dc);
108
 
 
109
 
    m_scriptCache = 0;
110
 
    m_scriptFontProperties = 0;
111
 
}
112
 
 
113
 
void FontData::platformDestroy()
114
 
{
115
 
    CGFontRelease(m_font.cgFont());
116
 
 
117
 
    if (m_isMLangFont) {
118
 
        // We have to release the font instead of just deleting it, since we didn't make it.
119
 
        IMLangFontLink2* langFontLink = FontCache::getFontLinkInterface();
120
 
        if (langFontLink)
121
 
            langFontLink->ReleaseFont(m_font.hfont());
122
 
    } else
123
 
        DeleteObject(m_font.hfont());
124
 
 
125
 
    // We don't hash this on Win32, so it's effectively owned by us.
126
 
    delete m_smallCapsFontData;
127
 
 
128
 
    ScriptFreeCache(&m_scriptCache);
129
 
    delete m_scriptFontProperties;
130
 
}
131
 
 
132
 
FontData* FontData::smallCapsFontData(const FontDescription& fontDescription) const
133
 
{
134
 
    if (!m_smallCapsFontData) {
135
 
        LOGFONT winfont;
136
 
        GetObject(m_font.hfont(), sizeof(LOGFONT), &winfont);
137
 
        int smallCapsHeight = lroundf(0.70f * fontDescription.computedSize());
138
 
        winfont.lfHeight = -smallCapsHeight * 32;
139
 
        HFONT hfont = CreateFontIndirect(&winfont);
140
 
        m_smallCapsFontData = new FontData(FontPlatformData(hfont, smallCapsHeight, fontDescription.bold(), fontDescription.italic()));
141
 
    }
142
 
    return m_smallCapsFontData;
143
 
}
144
 
 
145
 
bool FontData::containsCharacters(const UChar* characters, int length) const
146
 
{
147
 
    Vector<CGGlyph> glyphBuffer(length);
148
 
    wkGetGlyphs(m_font.cgFont(), characters, glyphBuffer.data(), length);
149
 
 
150
 
    for (int i = 0; i < length; i++) {
151
 
        if (glyphBuffer[i] == 0xFFFFFFFF) {
152
 
            return false;
153
 
        }
154
 
    }
155
 
 
156
 
    return true;
157
 
}
158
 
 
159
 
void FontData::determinePitch()
160
 
{
161
 
    // TEXTMETRICS have this.  Set m_treatAsFixedPitch based off that.
162
 
    HDC dc = GetDC((HWND)0);
163
 
    SaveDC(dc);
164
 
    SelectObject(dc, m_font.hfont());
165
 
 
166
 
    // Yes, this looks backwards, but the fixed pitch bit is actually set if the font
167
 
    // is *not* fixed pitch.  Unbelievable but true.
168
 
    TEXTMETRIC tm;
169
 
    GetTextMetrics(dc, &tm);
170
 
    m_treatAsFixedPitch = ((tm.tmPitchAndFamily & TMPF_FIXED_PITCH) == 0);
171
 
 
172
 
    RestoreDC(dc, -1);
173
 
    ReleaseDC(0, dc);
174
 
}
175
 
 
176
 
float FontData::platformWidthForGlyph(Glyph glyph) const
177
 
{
178
 
    CGFontRef font = m_font.cgFont();
179
 
    float pointSize = m_font.size();
180
 
    CGSize advance;
181
 
    CGAffineTransform m = CGAffineTransformMakeScale(pointSize, pointSize);
182
 
    // FIXME: Need to add real support for printer fonts.
183
 
    bool isPrinterFont = false;
184
 
    wkGetGlyphAdvances(font, m, m_isSystemFont, isPrinterFont, glyph, advance);
185
 
    return advance.width + m_syntheticBoldOffset;
186
 
}
187
 
 
188
 
SCRIPT_FONTPROPERTIES* FontData::scriptFontProperties() const
189
 
{
190
 
    if (!m_scriptFontProperties) {
191
 
        m_scriptFontProperties = new SCRIPT_FONTPROPERTIES;
192
 
        memset(m_scriptFontProperties, 0, sizeof(SCRIPT_FONTPROPERTIES));
193
 
        m_scriptFontProperties->cBytes = sizeof(SCRIPT_FONTPROPERTIES);
194
 
        HRESULT result = ScriptGetFontProperties(0, scriptCache(), m_scriptFontProperties);
195
 
        if (result == E_PENDING) {
196
 
            HDC dc = GetDC(0);
197
 
            SaveDC(dc);
198
 
            SelectObject(dc, m_font.hfont());
199
 
            ScriptGetFontProperties(dc, scriptCache(), m_scriptFontProperties);
200
 
            RestoreDC(dc, -1);
201
 
            ReleaseDC(0, dc);
202
 
        }
203
 
    }
204
 
    return m_scriptFontProperties;
205
 
}
206
 
 
207
 
}