Ignore:
Timestamp:
Aug 15, 2008, 12:43:48 AM (17 years ago)
Author:
[email protected]
Message:

Reviewed by Geoff Garen.

JSStringRef is created context-free, but can get linked to one via an identifier table,
breaking an implicit API contract.

Made JSStringRef point to OpaqueJSString, which is a new string object separate from UString.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/API/JSStringRef.cpp

    r35478 r35775  
    2828#include "JSStringRef.h"
    2929
    30 #include <wtf/Platform.h>
    31 
    32 #include "APICast.h"
    33 #include <kjs/JSType.h>
    34 #include <kjs/JSString.h>
    35 #include <kjs/operations.h>
    36 #include <kjs/ustring.h>
    37 #include <kjs/JSValue.h>
     30#include "OpaqueJSString.h"
    3831#include <wtf/unicode/UTF8.h>
    3932
     
    4336JSStringRef JSStringCreateWithCharacters(const JSChar* chars, size_t numChars)
    4437{
    45     return toRef(UString(chars, static_cast<int>(numChars)).rep()->ref());
     38    return OpaqueJSString::create(chars, numChars).releaseRef();
    4639}
    4740
    4841JSStringRef JSStringCreateWithUTF8CString(const char* string)
    4942{
    50     RefPtr<UString::Rep> result = UString::Rep::createFromUTF8(string);
    51     if (result.get() == &UString::Rep::null)
    52         return 0;
     43    if (string) {
     44        size_t length = strlen(string);
     45        Vector<UChar, 1024> buffer(length);
     46        UChar* p = buffer.data();
     47        if (conversionOK == convertUTF8ToUTF16(&string, string + length, &p, p + length))
     48            return OpaqueJSString::create(buffer.data(), p - buffer.data()).releaseRef();
     49    }
    5350
    54     return toRef(result.release().releaseRef());
     51    // Null string.
     52    return OpaqueJSString::create().releaseRef();
    5553}
    5654
    5755JSStringRef JSStringRetain(JSStringRef string)
    5856{
    59     UString::Rep* rep = toJS(string);
    60     return toRef(rep->ref());
     57    string->ref();
     58    return string;
    6159}
    6260
    6361void JSStringRelease(JSStringRef string)
    6462{
    65     UString::Rep* rep = toJS(string);
    66     bool needsLocking = rep->identifierTable();
    67     if (needsLocking) {
    68         // It is wasteful to take the lock for non-shared contexts, but we don't have a good way
    69         // to determine what the context is.
    70         rep->deref();
    71     } else
    72         rep->deref();
     63    string->deref();
    7364}
    7465
    7566size_t JSStringGetLength(JSStringRef string)
    7667{
    77     UString::Rep* rep = toJS(string);
    78     return rep->size();
     68    return string->length();
    7969}
    8070
    8171const JSChar* JSStringGetCharactersPtr(JSStringRef string)
    8272{
    83     UString::Rep* rep = toJS(string);
    84     return reinterpret_cast<const JSChar*>(rep->data());
     73    return string->characters();
    8574}
    8675
    8776size_t JSStringGetMaximumUTF8CStringSize(JSStringRef string)
    8877{
    89     UString::Rep* rep = toJS(string);
    90    
    9178    // Any UTF8 character > 3 bytes encodes as a UTF16 surrogate pair.
    92     return rep->size() * 3 + 1; // + 1 for terminating '\0'
     79    return string->length() * 3 + 1; // + 1 for terminating '\0'
    9380}
    9481
    9582size_t JSStringGetUTF8CString(JSStringRef string, char* buffer, size_t bufferSize)
    9683{
    97     UString::Rep* rep = toJS(string);
    98     CString cString = UString(rep).UTF8String();
     84    if (!bufferSize)
     85        return 0;
    9986
    100     size_t length = std::min(bufferSize, cString.size() + 1); // + 1 for terminating '\0'
    101     memcpy(buffer, cString.c_str(), length);
    102     return length;
     87    char* p = buffer;
     88    const UChar* d = string->characters();
     89    ConversionResult result = convertUTF16ToUTF8(&d, d + string->length(), &p, p + bufferSize - 1, true);
     90    *p++ = '\0';
     91    if (result != conversionOK && result != targetExhausted)
     92        return 0;
     93
     94    return p - buffer;
    10395}
    10496
    10597bool JSStringIsEqual(JSStringRef a, JSStringRef b)
    10698{
    107     UString::Rep* aRep = toJS(a);
    108     UString::Rep* bRep = toJS(b);
    109    
    110     return UString(aRep) == UString(bRep);
     99    unsigned len = a->length();
     100    return len == b->length() && 0 == memcmp(a->characters(), b->characters(), len * sizeof(UChar));
    111101}
    112102
Note: See TracChangeset for help on using the changeset viewer.