Closed Bug 136980 Opened 22 years ago Closed 20 years ago

assigning from Substring(nsACString, start, length) broken for non-flat strings (causes hang)

Categories

(Core :: XPCOM, defect)

x86
Linux
defect
Not set
critical

Tracking

()

RESOLVED FIXED

People

(Reporter: bzbarsky, Assigned: jag+mozilla)

Details

(Keywords: hang)

BUILD: 2002-04-10 build

STEPS TO REPRODUCE:
1) Call NS_NewURI with a non-flat CString for the URI (remove the "// XXX" hack
   from the patch in bug 135833, for example).
2) Watch the app go into an infinite loop, with lots of assertions in string
   code.

MORE INFO:
Putting a breakpoint in nsDebug::Assertion, we have:

#0  nsDebug::Assertion (
    aStr=0x402e9620 "You can't |write| into an |nsWritingIterator| with no space!", 
    aExpr=0x402e9603 "size_forward() > 0", 
    aFile=0x402e90c0 "../../dist/include/string/nsStringIterator.h", aLine=356)
    at nsDebug.cpp:195
#1  0x402b0974 in nsWritingIterator<char>::write (this=0xbfffc2a0, 
    s=0xbfffc544 "http://www.zbarsky.org:8000/~bzbarsky/test.html", n=11)
    at ../../dist/include/string/nsStringIterator.h:356
#2  0x402b0907 in nsCharSinkTraits<nsWritingIterator<char> >::write
(iter=@0xbfffc2a0, 
    s=0xbfffc544 "http://www.zbarsky.org:8000/~bzbarsky/test.html", n=11)
    at ../../dist/include/string/nsCharTraits.h:558
#3  0x402b088a in nsWritingIterator<char> & copy_string<nsReadingIterator<char>,
nsWritingIterator<char> > (first=@0xbfffc2c8, last=@0xbfffc2b4, result=@0xbfffc2a0)
    at ../../dist/include/string/nsAlgorithm.h:90
#4  0x402791d1 in nsACString::do_AssignFromReadable (this=0xbfffc424, 
    aReadable=@0xbfffc380) at nsAString.cpp:815
#5  0x40279050 in nsACString::AssignFromPromise (this=0xbfffc424,
aReadable=@0xbfffc380)
    at nsAString.cpp:784
#6  0x4027a337 in nsACString::Assign (this=0xbfffc424, aReadable=@0xbfffc380)
    at ../../dist/include/string/nsAString.h:665
#7  0x408f91d7 in ExtractURLScheme (inURI=@0xbfffc524, startPos=0x0, endPos=0x0, 
    scheme=0xbfffc424) at nsURLHelper.cpp:331
#8  0x408d24a5 in nsIOService::ExtractScheme (this=0x8175688, inURI=@0xbfffc524, 
    scheme=@0xbfffc424) at nsIOService.cpp:456
#9  0x408d370b in nsIOService::NewURI (this=0x8175688, aSpec=@0xbfffc524,
aCharset=0x0, 
    aBaseURI=0x0, result=0xbfffc5e0) at nsIOService.cpp:705
#10 0x4253d225 in NS_NewURI (result=0xbfffc5e0, spec=@0xbfffc524, charset=0x0, 
    baseURI=0x0, ioService=0x8175688) at
../../../../dist/include/necko/nsNetUtil.h:100
#11 0x42529f79 in nsViewSourceChannel::GetURI (this=0x8753c60, aURI=0xbfffc5e0)
    at nsViewSourceChannel.cpp:184

===NOTE: a look at some of the key frames===

(gdb) frame 11
#11 0x42529f79 in nsViewSourceChannel::GetURI (this=0x8753c60, aURI=0xbfffc5e0)
    at nsViewSourceChannel.cpp:184
184         return NS_NewURI(aURI, NS_LITERAL_CSTRING("view-source:")+spec, nsnull);

(gdb) frame 7
#7  0x408f91d7 in ExtractURLScheme (inURI=@0xbfffc524, startPos=0x0, endPos=0x0, 
    scheme=0xbfffc424) at nsURLHelper.cpp:331
331                     scheme->Assign(Substring(inURI, start, length));

(gdb) frame 4
#4  0x402791d1 in nsACString::do_AssignFromReadable (this=0xbfffc424, 
    aReadable=@0xbfffc380) at nsAString.cpp:815
815             copy_string(aReadable.BeginReading(fromBegin),
aReadable.EndReading(fromEnd), BeginWriting(toBegin));

===NOTE: here aReadable is the substring of the non-flat string we passed in===

(gdb) p fromBegin
$1 = {mFragment = {
    mStart = 0xbfffc544 "http://www.zbarsky.org:8000/~bzbarsky/test.html", 
    mEnd = 0xbfffc54f "zbarsky.org:8000/~bzbarsky/test.html", 
    mFragmentIdentifier = 0x1}, 
  mPosition = 0xbfffc544 "http://www.zbarsky.org:8000/~bzbarsky/test.html", 
  mOwningString = 0xbfffc380}

(gdb) p fromEnd
$2 = {mFragment = {mStart = 0x4254b2e0 "view-source:", mEnd = 0x4254b2eb ":", 
    mFragmentIdentifier = 0x0}, mPosition = 0x4254b2eb ":", mOwningString =
0xbfffc380}

===NOTE: fromBegin looks very wrong here... it points to the beginning of the
         _second_ fragment in the string, instead of the beginning of the first
         fragment, as it should===
Oh, for clarity... in frame 11, |spec| is
"http://www.zbarsky.org:8000/~bzbarsky/test.html"
Keywords: hang
Does this cause you to use a Substring of a Substring?  It may be a duplicate of
scc's fixing-fragment-APIs bug.
Hmm... no, there's not Substring of a Substring here.  There _is_ something like:

nsAutoString foo;
foo.Assign(Substring(a + b, 0, 10));

bug 74709 seems to be very much related, yes.... I don't know the string code
well enough to tell whether this is the same problem.
Er, I meant a concatenation of a concatenation, not a substring of a substring!
 (And it has to be the inner one on the left, rather than the right, which works
fine.)
The hang in bug 229668 seems to be caused by this bug.
is this fixed now?  or otherwise invalidated by the string rewrite?
Probably...  At this point, doing Substring(a+b) flattens out a+b (into a single
buffer, not necessarily null-terminated) before calling Substring, right?  So
the problem is probably impossible to trigger now.
(In reply to comment #8)
> Probably...  At this point, doing Substring(a+b) flattens out a+b (into a single
> buffer, not necessarily null-terminated) before calling Substring, right?  So
> the problem is probably impossible to trigger now.

Excactly.  marking FIXED as a result of the patch for bug 231995.
Status: NEW → RESOLVED
Closed: 20 years ago
Resolution: --- → FIXED
Component: String → XPCOM
You need to log in before you can comment on or make changes to this bug.