Closed Bug 121274 Opened 23 years ago Closed 22 years ago

Mozilla won't start if locale is set to unknown name on some system

Categories

(Core :: Internationalization, defect)

All
FreeBSD
defect
Not set
major

Tracking

()

VERIFIED FIXED

People

(Reporter: shanjian, Assigned: shanjian)

References

Details

(Keywords: intl)

Attachments

(2 files)

nl_langinfo(CODESET) now is the preferred way of getting system charset. On 
some system that does not support nl_langinfo yet, we still fall back to 
locale name mapping. Some reports says if locale name is set to unknown (to 
mozilla) string, mozilla won't start. Add those name to our locale mapping 
table is necessary, but we need to handle more gracefully when locale name 
is unknown to us. Our current code suggest "ISO-8859-1" should be used in 
such situation.

From bug 117957, FreeBSD and openVMS have such problem.
Could anybody who experience such problem tell me what's exactly happening inside charset name resolution?

To do this, you need to be able to debug nsPlatformCharset::InitGetCharset in file 
/mozilla/intl/uconv/src.

I have a meeting now but can debug this later this afternoon. 
*** Bug 118988 has been marked as a duplicate of this bug. ***
Here's what was happening on OpenVMS. We don't have nl_langinfo (actually we do, 
but we weren't using it; that's another issue), and so were relying upon 
setlocale to return information about the charset. Wel, it turns out that if a 
locale has been defined, then setlocale on OpenVMS doesn't return a string 
containing the charset information as it does on UNIX. Instead on OpenVMS is 
returns "private" string. Now, in the reading the setlocale documentation you 
see that its pretty vague about what setlocale(LC_CTYPE,"") actually returns, so 
its debateable as to whether or not OpenVMS is conformant. Anyway, this is why 
we were unable to detect the charset when locale was defined on OpenVMS. 

The interesting thing is that the code which does this in InitGetCharset is 
pretty much the same for 0.9.6 and 0.9.7 if HAVE_NL_LANGINFO is not defined. On 
0.9.6 we were also failing to detect the charset but there it was NOT preventing 
Mozilla from starting up. Clearly something else changed in 0.9.7 which caused 
Mozilal to barf if we haven't got a charset defined. I don't know what that 
something is.

The solution for OpenVMS is simple. There is a different flavor of setlocale on 
OpenVMS which DOES return a UNIX style string when called with "" (I just 
learned about this). So I have modified the OpenVMS porting library so 
that Mozilla now uses this other flavor of setlocale, and Mozilla is running 
again.

Bottom line. We've always been failing to detect the charset when a locale has 
been set by the user, but starting in 0.9.7 SOMETHING is now very unhappy if we 
don't have a valid charset defined.
colin, 
Thanks a lot for looking into this problem for us. 

I believe we are using "setlocale(LC_CTYPE, nsnull)" to query current 
locale name, not "setlocale(LC_CTYPE, "")". 

The problem you observed might be caused by error return by function 
"nsPlatformCharset::Init". Could you try my patch on your machine to 
see if it can fix that problem? 

Status: NEW → ASSIGNED
Attached patch patchSplinter Review
You're right. I was thinking of nsLocaleService where setlocale is called with 
"" to set the locale from the users settings. But after setting the locale in 
nsLocaleService, it was still getting returned in the setlocale(LC_CTYPE,nsnull) 
call as a very "non=-standard" string.
With your patch it gets past the charset detection stuff, but then crashes
later, just before the Mozilla window appears. I'm not sure how much use the
OpenVMS stack trace will be to you, but I'll attach it anyway.
Attached file Stack trace
Could you set a break point in nsWindow::SetTitle and let me know what's happenning 
inside this function? Especially on which statement does the crash happen? In GTK,
we need to convert title from unicode to platform charset and then call 
gtk_window_set_title. If the platform charset is not ISO-8859-1 as we assumed, and 
the title string in iso-8859-1 encoding contains illegal code points (or byte sequences)
when interpreted as platform charset, there is possibility that crash may happen. 
If that is the case, we can do nothing but help system get the correct plafform charset.
Access violation is on this line
encoder->GetMaxLength(aTitle.get(), len, &platformLen);
http://lxr.mozilla.org/seamonkey/source/widget/src/gtk/nsWindow.cpp#2276

I presume because there's no get().

DBG> ex len
nsWindow::SetTitle::len:        20
DBG>

DBG> ex aTitle
nsWindow::SetTitle::aTitle: class nsString
    inherit nsAFlatString
        inherit nsASingleFragmentString
            inherit nsAString
                __vptr: 66515240
            __vptr:     66515240
        __vptr: 66515240
    inherit nsStr
        mLength:        20
        mCapacity:      63
        union
            [Displaying union member number 1]
            mStr:       2063386828
        mCharSize:      1
        mOwnsBuffer:    0
    __vptr:     66515240
DBG>

mCharSize is 1 but the string at 2063386828 has every second byte as 0:

DBG> ex /hex 2063386828
nsXULWindow::SetTitle::title.mBuffer[0]:        4D
DBG> ex /hex 2063386829
nsXULWindow::SetTitle::title.mBuffer[1]:        00
DBG> ex /hex 2063386830
nsXULWindow::SetTitle::title.mBuffer[2]:        61
DBG> ex /hex 2063386831
nsXULWindow::SetTitle::title.mBuffer[3]:        00
DBG>

DBG> ex /az 2063386828:2063386828+38
nsXULWindow::SetTitle::title.mBuffer[0]:        "M"
nsXULWindow::SetTitle::title.mBuffer[2]:        "a"
nsXULWindow::SetTitle::title.mBuffer[4]:        "n"
nsXULWindow::SetTitle::title.mBuffer[6]:        "a"
nsXULWindow::SetTitle::title.mBuffer[8]:        "g"
nsXULWindow::SetTitle::title.mBuffer[10]:       "e"
nsXULWindow::SetTitle::title.mBuffer[12]:       " "
nsXULWindow::SetTitle::title.mBuffer[14]:       "U"
nsXULWindow::SetTitle::title.mBuffer[16]:       "s"
nsXULWindow::SetTitle::title.mBuffer[18]:       "e"
nsXULWindow::SetTitle::title.mBuffer[20]:       "r"
nsXULWindow::SetTitle::title.mBuffer[22]:       " "
nsXULWindow::SetTitle::title.mBuffer[24]:       "P"
nsXULWindow::SetTitle::title.mBuffer[26]:       "r"
nsXULWindow::SetTitle::title.mBuffer[28]:       "o"
nsXULWindow::SetTitle::title.mBuffer[30]:       "f"
nsXULWindow::SetTitle::title.mBuffer[32]:       "i"
nsXULWindow::SetTitle::title.mBuffer[34]:       "l"
nsXULWindow::SetTitle::title.mBuffer[36]:       "e"
nsXULWindow::SetTitle::title.mBuffer[38]:       "s"
DBG>

Just before this is:

  // get the encoder
  nsCOMPtr<nsICharsetConverterManager> ccm =
           do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &rv);
  rv = ccm->GetUnicodeEncoder(&platformCharset, getter_AddRefs(encoder));

which yields:

DBG> ex rv
nsWindow::SetTitle::rv: 2152726529
DBG> ex platformCharset
nsWindow::SetTitle::platformCharset: class nsAutoString
    inherit nsString
        inherit nsAFlatString
            inherit nsASingleFragmentString
                inherit nsAString
                    __vptr:     66515240
                __vptr: 66515240
            __vptr:     66515240
        inherit nsStr
            mLength:    0
            mCapacity:  63
            union
                [Displaying union member number 1]
                mStr:   2063386556
            mCharSize:  1
            mOwnsBuffer:        0
        __vptr: 66515240
    mBuffer:    ""
    __vptr:     66515240
DBG>

So we crapped out because we didn't get an encoder?

But why is the window title that its working on "Manage User Profiles"?
It shouldn't be trying to being up the profile manager. That's wrong!!!
Is the length of "platformCharset" 0? That's wrong. "platformCharsetService->GetCharset" 
should always returns a valid value. mCharset of nsPlatformCharset should at least 
be set to "ISO-8859-1". 
Keywords: intl
DBG> examine platformCharset
nsWindow::SetTitle::platformCharset: class nsAutoString
    inherit nsString
        inherit nsAFlatString
            inherit nsASingleFragmentString
                inherit nsAString
                    __vptr:     66515240
                __vptr: 66515240
            __vptr:     66515240
        inherit nsStr
            mLength:    0
            mCapacity:  63
            union
                [Displaying union member number 1]
                mStr:   2063386556
            mCharSize:  1
            mOwnsBuffer:        0
        __vptr: 66515240
    mBuffer:    ""
    __vptr:     66515240
DBG>

  nsAutoString platformCharset;
  nsCOMPtr <nsIPlatformCharset> platformCharsetService = do_GetService(NS_PLATFO
RMCHARSET_CONTRACTID, &rv);

>>> rv=0

  if (NS_SUCCEEDED(rv))
    rv = platformCharsetService->GetCharset(kPlatformCharsetSel_Menu, platformCh
arset);

>>> rv=0

>>> DBG> ex platformCharset
>>> nsWindow::SetTitle::platformCharset: class nsAutoString
>>>     inherit nsString
>>>         inherit nsAFlatString
>>>             inherit nsASingleFragmentString
>>>                 inherit nsAString
>>>                     __vptr:     66515240
>>>                 __vptr: 66515240
>>>             __vptr:     66515240
>>>         inherit nsStr
>>>             mLength:    0
>>>             mCapacity:  63
>>>             union
>>>                 [Displaying union member number 1]
>>>                 mStr:   2063386332
>>>             mCharSize:  1
>>>             mOwnsBuffer:        0
>>>         __vptr: 66515240
>>>     mBuffer:    ""
>>>     __vptr:     66515240
>>> DBG>

  // This is broken, it's just a random guess
  if (NS_FAILED(rv))
    platformCharset.AssignWithConversion("ISO-8859-1");

>>> rv was good so we didn't do the above "random guess".

Running it again and this time stepping into nsPlatformCharset::GetCharset

NS_IMETHODIMP
nsPlatformCharset::GetCharset(nsPlatformCharsetSel selector, nsAWritableString&o
Result)
{
  oResult = mCharset;
  return NS_OK;
}

DBG> ex mCharset
nsPlatformCharset::GetCharset::this->mCharset: class nsString
    inherit nsAFlatString
        inherit nsASingleFragmentString
            inherit nsAString
                __vptr: 66530200
            __vptr:     66530200
        __vptr: 66530200
    inherit nsStr
        mLength:        0
        mCapacity:      10
        union
            [Displaying union member number 1]
            mStr:       79812896
        mCharSize:      1
        mOwnsBuffer:    1
    __vptr:     66530200
DBG>

So GetCharset always returns true. So the perhaps the test in
nsWindow::SetTitle should be to check the length is non-zero instead
of looking at the value of rv.
After returning from nsPlatformCharset::GetCharset without a charset, if I 
manually force rv to -1, then I avoid the crash. But then the profile manager 
dialog comes up. Which means we're back to where we started; if the locale is 
set then we can't start Mozilla.

I wonder if other code is expecting nsPlatformCharset::GetCharset to return an 
ERROR status if there's no charset???
GetCharset appears to be the problem. With this modified code, I no longer
get the accvio OR the profile manager window - Mozilla comes up!!

NS_IMETHODIMP
nsPlatformCharset::GetCharset(nsPlatformCharsetSel selector, nsAWritableString& 
oResult)
{
  oResult = mCharset;
  if (mCharset.Length())
    return NS_OK;
  else
    return NS_ERROR_USING_FALLBACK_LOCALE;
}

Yeah, I know the error code isn't the right one, but I was just testing!!
(Thanks a lot. Would you mind nail down this problem? I can reassign this bug 
to you if you have account. Otherwise I will keep the bug and drive the patch 
in once you've got one.)

nsPlatformCharset::GetCharset must be called after "nsPlatformCharset::Init". 
If not, we have a problem. 

"nsPlatformCharset::Init" must set "mCharset" to a valid value. If not, that is 
the problem. 

So you might want to put 2 break points in "Init" and "GetCharset". "Init" should be 
called first. Step within Init and find out why mCharset come out with a invalid 
value. 
Whoa, just a sec. I just realised that I built my last test image with my 
setlocale fix. So the results of that test are INVALID.

Rebuilding again now with the setlocale fix so I can really test the theory
about nsPlatformCharset::GetCharset.
Comment 15 does NOT fix the problem completely. It does fix the access violation 
problem, but I still end up with the profile manager instead of the main Mozilla 
window.
error return code has been fixed in another bug. Mark this one as fixed. 
Status: ASSIGNED → RESOLVED
Closed: 22 years ago
Resolution: --- → FIXED
Mark as verified per comment above.
Status: RESOLVED → VERIFIED
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: