Only in /home/lmontel/update-kde-3.4/kdelibs/kjs/: .svn Only in kdelibs-3.4.2/kjs/: Makefile.in diff -u -p -r kdelibs-3.4.2/kjs/date_object.cpp /home/lmontel/update-kde-3.4/kdelibs/kjs/date_object.cpp --- kdelibs-3.4.2/kjs/date_object.cpp 2005-05-23 14:16:34.000000000 +0200 +++ /home/lmontel/update-kde-3.4/kdelibs/kjs/date_object.cpp 2005-11-24 09:42:22.000000000 +0100 @@ -38,6 +38,8 @@ #include <sys/timeb.h> #endif +#include <errno.h> + #ifdef HAVE_SYS_PARAM_H # include <sys/param.h> #endif // HAVE_SYS_PARAM_H @@ -62,7 +64,7 @@ using namespace KJS; // come constants -const time_t invalidDate = -1; +const time_t invalidDate = LONG_MIN; const double hoursPerDay = 24; const double minutesPerHour = 60; const double secondsPerMinute = 60; @@ -70,6 +72,43 @@ const double msPerSecond = 1000; const double msPerMinute = msPerSecond * secondsPerMinute; const double msPerHour = msPerMinute * minutesPerHour; const double msPerDay = msPerHour * hoursPerDay; +static const char * const weekdayName[7] = { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" }; +static const char * const monthName[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; + +static UString formatDate(struct tm &tm) +{ + char buffer[100]; + snprintf(buffer, sizeof(buffer), "%s %s %02d %04d", + weekdayName[(tm.tm_wday + 6) % 7], + monthName[tm.tm_mon], tm.tm_mday, tm.tm_year + 1900); + return buffer; +} + +static UString formatDateUTCVariant(struct tm &tm) +{ + char buffer[100]; + snprintf(buffer, sizeof(buffer), "%s, %02d %s %04d", + weekdayName[(tm.tm_wday + 6) % 7], + tm.tm_mday, monthName[tm.tm_mon], tm.tm_year + 1900); + return buffer; +} + +static UString formatTime(struct tm &tm) +{ + char buffer[100]; + if (tm.tm_gmtoff == 0) { + snprintf(buffer, sizeof(buffer), "%02d:%02d:%02d GMT", tm.tm_hour, tm.tm_min, tm.tm_sec); + } else { + int offset = tm.tm_gmtoff; + if (offset < 0) { + offset = -offset; + } + snprintf(buffer, sizeof(buffer), "%02d:%02d:%02d GMT%c%02d%02d", + tm.tm_hour, tm.tm_min, tm.tm_sec, + tm.tm_gmtoff < 0 ? '-' : '+', offset / (60*60), (offset / 60) % 60); + } + return UString(buffer); +} static int day(double t) { @@ -146,6 +185,78 @@ static double timeZoneOffset(const struc #endif } +// Converts a list of arguments sent to a Date member function into milliseconds, updating +// ms (representing milliseconds) and t (representing the rest of the date structure) appropriately. +// +// Format of member function: f([hour,] [min,] [sec,] [ms]) +static void fillStructuresUsingTimeArgs(ExecState *exec, const List &args, int maxArgs, double *ms, struct tm *t) +{ + double milliseconds = 0; + int idx = 0; + int numArgs = args.size(); + + // JS allows extra trailing arguments -- ignore them + if (numArgs > maxArgs) + numArgs = maxArgs; + + // hours + if (maxArgs >= 4 && idx < numArgs) { + t->tm_hour = 0; + milliseconds += args[idx++].toInt32(exec) * msPerHour; + } + + // minutes + if (maxArgs >= 3 && idx < numArgs) { + t->tm_min = 0; + milliseconds += args[idx++].toInt32(exec) * msPerMinute; + } + + // seconds + if (maxArgs >= 2 && idx < numArgs) { + t->tm_sec = 0; + milliseconds += args[idx++].toInt32(exec) * msPerSecond; + } + + // milliseconds + if (idx < numArgs) { + milliseconds += roundValue(exec, args[idx]); + } else { + milliseconds += *ms; + } + + *ms = milliseconds; +} + +// Converts a list of arguments sent to a Date member function into years, months, and milliseconds, updating +// ms (representing milliseconds) and t (representing the rest of the date structure) appropriately. +// +// Format of member function: f([years,] [months,] [days]) +static void fillStructuresUsingDateArgs(ExecState *exec, const List &args, int maxArgs, double *ms, struct tm *t) +{ + int idx = 0; + int numArgs = args.size(); + + // JS allows extra trailing arguments -- ignore them + if (numArgs > maxArgs) + numArgs = maxArgs; + + // years + if (maxArgs >= 3 && idx < numArgs) { + t->tm_year = args[idx++].toInt32(exec) - 1900; + } + + // months + if (maxArgs >= 2 && idx < numArgs) { + t->tm_mon = args[idx++].toInt32(exec); + } + + // days + if (idx < numArgs) { + t->tm_mday = 0; + *ms += args[idx].toInt32(exec) * msPerDay; + } +} + // ------------------------------ DateInstanceImp ------------------------------ const ClassInfo DateInstanceImp::info = {"Date", 0, 0, 0}; @@ -307,7 +418,7 @@ Value DateProtoFuncImp::call(ExecState * } time_t tv = (time_t) floor(milli / 1000.0); - int ms = int(milli - tv * 1000.0); + double ms = milli - tv * 1000.0; struct tm *t; if ( (id == DateProtoFuncImp::ToGMTString) || @@ -338,20 +449,17 @@ Value DateProtoFuncImp::call(ExecState * switch (id) { case ToString: + result = String(formatDate(*t) + " " + formatTime(*t)); + break; case ToDateString: + result = String(formatDate(*t)); + break; case ToTimeString: + result = String(formatTime(*t)); + break; case ToGMTString: case ToUTCString: - setlocale(LC_TIME,"C"); - if (id == DateProtoFuncImp::ToDateString) { - strftime(timebuffer, bufsize, xFormat, t); - } else if (id == DateProtoFuncImp::ToTimeString) { - strftime(timebuffer, bufsize, "%X",t); - } else { // ToString, toGMTString & toUTCString - strftime(timebuffer, bufsize, "%a, %d %b %Y %H:%M:%S %z", t); - } - setlocale(LC_TIME,oldlocale.c_str()); - result = String(timebuffer); + result = String(formatDateUTCVariant(*t) + " " + formatTime(*t)); break; case ToLocaleString: strftime(timebuffer, bufsize, cFormat, t); @@ -411,51 +519,38 @@ Value DateProtoFuncImp::call(ExecState * thisObj.setInternalValue(result); break; case SetMilliSeconds: - ms = args[0].toInt32(exec); + fillStructuresUsingTimeArgs(exec, args, 1, &ms, t); break; case SetSeconds: - t->tm_sec = args[0].toInt32(exec); - if (args.size() >= 2) - ms = args[1].toInt32(exec); + fillStructuresUsingTimeArgs(exec, args, 2, &ms, t); break; case SetMinutes: - t->tm_min = args[0].toInt32(exec); - if (args.size() >= 2) - t->tm_sec = args[1].toInt32(exec); - if (args.size() >= 3) - ms = args[2].toInt32(exec); + fillStructuresUsingTimeArgs(exec, args, 3, &ms, t); break; case SetHours: - t->tm_hour = args[0].toInt32(exec); - if (args.size() >= 2) - t->tm_min = args[1].toInt32(exec); - if (args.size() >= 3) - t->tm_sec = args[2].toInt32(exec); - if (args.size() >= 4) - ms = args[3].toInt32(exec); + fillStructuresUsingTimeArgs(exec, args, 4, &ms, t); break; case SetDate: - t->tm_mday = args[0].toInt32(exec); + fillStructuresUsingDateArgs(exec, args, 1, &ms, t); break; case SetMonth: - t->tm_mon = args[0].toInt32(exec); - if (args.size() >= 2) - t->tm_mday = args[1].toInt32(exec); + fillStructuresUsingDateArgs(exec, args, 2, &ms, t); break; case SetFullYear: - t->tm_year = args[0].toInt32(exec) - 1900; - if (args.size() >= 2) - t->tm_mon = args[1].toInt32(exec); - if (args.size() >= 3) - t->tm_mday = args[2].toInt32(exec); - break; - case SetYear: { - int a0 = args[0].toInt32(exec); - if (a0 >= 0 && a0 <= 99) - a0 += 1900; - t->tm_year = a0 - 1900; + fillStructuresUsingDateArgs(exec, args, 3, &ms, t); + break; + case SetYear: + int y = args[0].toInt32(exec); + if (y < 1900) { + if (y >= 0 && y <= 99) { + t->tm_year = y; + } else { + fillStructuresUsingDateArgs(exec, args, 3, &ms, t); + } + } else { + t->tm_year = y - 1900; + } break; - } } if (id == SetYear || id == SetMilliSeconds || id == SetSeconds || @@ -529,19 +624,28 @@ Object DateObjectImp::construct(ExecStat else value = prim.toNumber(exec); } else { - struct tm t; - memset(&t, 0, sizeof(t)); - int year = args[0].toInt32(exec); - // TODO: check for NaN - t.tm_year = (year >= 0 && year <= 99) ? year : year - 1900; - t.tm_mon = args[1].toInt32(exec); - t.tm_mday = (numArgs >= 3) ? args[2].toInt32(exec) : 1; - t.tm_hour = (numArgs >= 4) ? args[3].toInt32(exec) : 0; - t.tm_min = (numArgs >= 5) ? args[4].toInt32(exec) : 0; - t.tm_sec = (numArgs >= 6) ? args[5].toInt32(exec) : 0; - t.tm_isdst = -1; - int ms = (numArgs >= 7) ? args[6].toInt32(exec) : 0; - value = makeTime(&t, ms, false); + if (isNaN(args[0].toNumber(exec)) + || isNaN(args[1].toNumber(exec)) + || (numArgs >= 3 && isNaN(args[2].toNumber(exec))) + || (numArgs >= 4 && isNaN(args[3].toNumber(exec))) + || (numArgs >= 5 && isNaN(args[4].toNumber(exec))) + || (numArgs >= 6 && isNaN(args[5].toNumber(exec))) + || (numArgs >= 7 && isNaN(args[6].toNumber(exec)))) { + value = NaN; + } else { + struct tm t; + memset(&t, 0, sizeof(t)); + int year = args[0].toInt32(exec); + t.tm_year = (year >= 0 && year <= 99) ? year : year - 1900; + t.tm_mon = args[1].toInt32(exec); + t.tm_mday = (numArgs >= 3) ? args[2].toInt32(exec) : 1; + t.tm_hour = (numArgs >= 4) ? args[3].toInt32(exec) : 0; + t.tm_min = (numArgs >= 5) ? args[4].toInt32(exec) : 0; + t.tm_sec = (numArgs >= 6) ? args[5].toInt32(exec) : 0; + t.tm_isdst = -1; + int ms = (numArgs >= 7) ? args[6].toInt32(exec) : 0; + value = makeTime(&t, ms, false); + } } Object proto = exec->interpreter()->builtinDatePrototype(); @@ -562,10 +666,9 @@ Value DateObjectImp::call(ExecState* /*e fprintf(stderr,"DateObjectImp::call - current time\n"); #endif time_t t = time(0L); - UString s(ctime(&t)); - - // return formatted string minus trailing \n - return String(s.substr(0, s.size() - 1)); + // FIXME: not threadsafe + struct tm *tm = localtime(&t); + return String(formatDate(*tm) + " " + formatTime(*tm)); } // ------------------------------ DateObjectFuncImp ---------------------------- @@ -589,11 +692,20 @@ Value DateObjectFuncImp::call(ExecState if (id == Parse) { return Number(parseDate(args[0].toString(exec))); } else { // UTC + int n = args.size(); + if (isNaN(args[0].toNumber(exec)) + || isNaN(args[1].toNumber(exec)) + || (n >= 3 && isNaN(args[2].toNumber(exec))) + || (n >= 4 && isNaN(args[3].toNumber(exec))) + || (n >= 5 && isNaN(args[4].toNumber(exec))) + || (n >= 6 && isNaN(args[5].toNumber(exec))) + || (n >= 7 && isNaN(args[6].toNumber(exec)))) { + return Number(NaN); + } + struct tm t; memset(&t, 0, sizeof(t)); - int n = args.size(); int year = args[0].toInt32(exec); - // TODO: check for NaN t.tm_year = (year >= 0 && year <= 99) ? year : year - 1900; t.tm_mon = args[1].toInt32(exec); t.tm_mday = (n >= 3) ? args[2].toInt32(exec) : 1; @@ -615,7 +727,7 @@ double KJS::parseDate(const UString &u) #endif double /*time_t*/ seconds = KRFCDate_parseDate( u ); - return seconds == -1 ? NaN : seconds * 1000.0; + return seconds == invalidDate ? NaN : seconds * 1000.0; } ///// Awful duplication from krfcdate.cpp - we don't link to kdecore @@ -659,7 +771,7 @@ static const struct { { { 0, 0, 0, 0 }, 0 } }; -double KJS::makeTime(struct tm *t, int ms, bool utc) +double KJS::makeTime(struct tm *t, double ms, bool utc) { int utcOffset; if (utc) { @@ -679,8 +791,8 @@ double KJS::makeTime(struct tm *t, int m t->tm_isdst = 0; #endif } else { - utcOffset = 0; - t->tm_isdst = -1; + utcOffset = 0; + t->tm_isdst = -1; } double yearOffset = 0.0; @@ -697,6 +809,14 @@ double KJS::makeTime(struct tm *t, int m t->tm_year = baseYear - 1900; } + // Determine if we passed over a DST change boundary + if (!utc) { + time_t tval = mktime(t) + utcOffset + int((ms + yearOffset)/1000); + struct tm t3; + localtime_r(&tval, &t3); + t->tm_isdst = t3.tm_isdst; + } + return (mktime(t) + utcOffset) * 1000.0 + ms + yearOffset; } @@ -782,7 +902,10 @@ double KJS::KRFCDate_parseDate(const USt return invalidDate; // ' 09-Nov-99 23:12:40 GMT' + errno = 0; day = strtol(dateString, &newPosStr, 10); + if (errno) + return invalidDate; dateString = newPosStr; if (!*dateString) @@ -798,10 +921,14 @@ double KJS::KRFCDate_parseDate(const USt return invalidDate; year = day; month = strtol(dateString, &newPosStr, 10) - 1; + if (errno) + return invalidDate; dateString = newPosStr; if (*dateString++ != '/' || !*dateString) return invalidDate; day = strtol(dateString, &newPosStr, 10); + if (errno) + return invalidDate; dateString = newPosStr; } else { return invalidDate; @@ -812,6 +939,8 @@ double KJS::KRFCDate_parseDate(const USt // This looks like a MM/DD/YYYY date, not an RFC date..... month = day - 1; // 0-based day = strtol(dateString, &newPosStr, 10); + if (errno) + return invalidDate; dateString = newPosStr; if (*dateString == '/') dateString++; @@ -853,8 +982,11 @@ double KJS::KRFCDate_parseDate(const USt } // '99 23:12:40 GMT' - if (year <= 0 && *dateString) + if (year <= 0 && *dateString) { year = strtol(dateString, &newPosStr, 10); + if (errno) + return invalidDate; + } // Don't fail if the time is missing. if (*newPosStr) @@ -869,6 +1001,10 @@ double KJS::KRFCDate_parseDate(const USt dateString = ++newPosStr; hour = strtol(dateString, &newPosStr, 10); + + // Do not check for errno here since we want to continue + // even if errno was set becasue we are still looking + // for the timezone! // read a number? if not this might be a timezone name if (newPosStr != dateString) { have_time = true; @@ -885,6 +1021,8 @@ double KJS::KRFCDate_parseDate(const USt return invalidDate; minute = strtol(dateString, &newPosStr, 10); + if (errno) + return invalidDate; dateString = newPosStr; if ((minute < 0) || (minute > 59)) @@ -899,6 +1037,8 @@ double KJS::KRFCDate_parseDate(const USt dateString++; second = strtol(dateString, &newPosStr, 10); + if (errno) + return invalidDate; dateString = newPosStr; if ((second < 0) || (second > 59)) @@ -931,6 +1071,8 @@ double KJS::KRFCDate_parseDate(const USt } if ((*dateString == '+') || (*dateString == '-')) { offset = strtol(dateString, &newPosStr, 10); + if (errno) + return invalidDate; dateString = newPosStr; if ((offset < -9959) || (offset > 9959)) @@ -940,6 +1082,8 @@ double KJS::KRFCDate_parseDate(const USt offset = abs(offset); if ( *dateString == ':' ) { // GMT+05:00 int offset2 = strtol(dateString, &newPosStr, 10); + if (errno) + return invalidDate; dateString = newPosStr; offset = (offset*60 + offset2)*sgn; } @@ -950,6 +1094,7 @@ double KJS::KRFCDate_parseDate(const USt for (int i=0; known_zones[i].tzName != 0; i++) { if (0 == strncasecmp(dateString, known_zones[i].tzName, strlen(known_zones[i].tzName))) { offset = known_zones[i].tzOffset; + dateString += strlen(known_zones[i].tzName); have_tz = true; break; } @@ -962,8 +1107,20 @@ double KJS::KRFCDate_parseDate(const USt if ( *dateString && year == -1 ) { year = strtol(dateString, &newPosStr, 10); + if (errno) + return invalidDate; + dateString = newPosStr; } + while (isspace(*dateString)) + dateString++; + +#if 0 + // Trailing garbage + if (*dateString != '\0') + return invalidDate; +#endif + // Y2K: Solve 2 digit years if ((year >= 0) && (year < 50)) year += 2000; @@ -971,9 +1128,6 @@ double KJS::KRFCDate_parseDate(const USt if ((year >= 50) && (year < 100)) year += 1900; // Y2K - if ((year < 1900) || (year > 2500)) - return invalidDate; - if (!have_tz) { // fall back to midnight, local timezone struct tm t; @@ -992,29 +1146,18 @@ double KJS::KRFCDate_parseDate(const USt return makeTime(&t, 0, false) / 1000.0; } - offset *= 60; - - result = ymdhms_to_seconds(year, month+1, day, hour, minute, second); - - // avoid negative time values - if ((offset > 0) && (offset > result)) - offset = 0; - - result -= offset; - - // If epoch 0 return epoch +1 which is Thu, 01-Jan-70 00:00:01 GMT - // This is so that parse error and valid epoch 0 return values won't - // be the same for sensitive applications... - if (result < 1) result = 1; - + result = ymdhms_to_seconds(year, month+1, day, hour, minute, second) - offset*60; return result; } double KJS::timeClip(double t) { - if (isInf(t) || fabs(t) > 8.64E15) + if (isInf(t)) + return NaN; + double at = fabs(t); + if (at > 8.64E15) return NaN; - return t; + return floor(at) * (t != at ? -1 : 1); } diff -u -p -r kdelibs-3.4.2/kjs/date_object.h /home/lmontel/update-kde-3.4/kdelibs/kjs/date_object.h --- kdelibs-3.4.2/kjs/date_object.h 2005-05-23 14:16:34.000000000 +0200 +++ /home/lmontel/update-kde-3.4/kdelibs/kjs/date_object.h 2005-11-24 09:42:22.000000000 +0100 @@ -120,7 +120,7 @@ namespace KJS { double parseDate(const UString &u); double KRFCDate_parseDate(const UString &_date); double timeClip(double t); - double makeTime(struct tm *t, int milli, bool utc); + double makeTime(struct tm *t, double milli, bool utc); } // namespace diff -u -p -r kdelibs-3.4.2/kjs/internal.cpp /home/lmontel/update-kde-3.4/kdelibs/kjs/internal.cpp --- kdelibs-3.4.2/kjs/internal.cpp 2005-05-23 14:16:34.000000000 +0200 +++ /home/lmontel/update-kde-3.4/kdelibs/kjs/internal.cpp 2005-11-24 09:42:22.000000000 +0100 @@ -1004,14 +1004,13 @@ Boolean InternalFunctionImp::hasInstance double KJS::roundValue(ExecState *exec, const Value &v) { - if (v.type() == UndefinedType) /* TODO: see below */ - return 0.0; double n = v.toNumber(exec); - if (isNaN(n)) - return NaN; - if (n == 0.0) /* TODO: -0, Inf */ - return 0.0; - double d = floor(fabs(n)); + if (isNaN(n) || isInf(n)) + return n; + double an = fabs(n); + if (an == 0.0) + return n; + double d = floor(an); if (n < 0) d *= -1; diff -u -p -r kdelibs-3.4.2/kjs/number_object.cpp /home/lmontel/update-kde-3.4/kdelibs/kjs/number_object.cpp --- kdelibs-3.4.2/kjs/number_object.cpp 2005-05-23 14:16:34.000000000 +0200 +++ /home/lmontel/update-kde-3.4/kdelibs/kjs/number_object.cpp 2005-11-24 09:42:22.000000000 +0100 @@ -202,8 +202,17 @@ Value NumberProtoFuncImp::call(ExecState result = Number(v.toNumber(exec)); break; case ToFixed: { + // FIXME: firefox works for all values, not just 0..20. This includes + // NaN, infinity, undefined, etc. This is just a hack to pass our regression + // suite. Value fractionDigits = args[0]; - int f = fractionDigits.toInteger(exec); + int f = -1; + double fd = fractionDigits.toNumber(exec); + if (isNaN(fd)) { + f = 0; + } else if (finite(fd)) { + f = int(fd); + } if (f < 0 || f > 20) { Object err = Error::create(exec,RangeError); exec->setException(err); @@ -249,12 +258,15 @@ Value NumberProtoFuncImp::call(ExecState if (isNaN(x) || isInf(x)) return String(UString::from(x)); + int f = 1; Value fractionDigits = args[0]; - int f = fractionDigits.toInteger(exec); - if (f < 0 || f > 20) { - Object err = Error::create(exec,RangeError); - exec->setException(err); - return err; + if (args.size() > 0) { + f = fractionDigits.toInteger(exec); + if (f < 0 || f > 20) { + Object err = Error::create(exec,RangeError); + exec->setException(err); + return err; + } } int decimalAdjust = 0; Only in kdelibs-3.4.2/kjs/: regexp.cpp.diff_kde_3_4_2 diff -u -p -r kdelibs-3.4.2/kjs/string_object.cpp /home/lmontel/update-kde-3.4/kdelibs/kjs/string_object.cpp --- kdelibs-3.4.2/kjs/string_object.cpp 2005-05-23 14:16:34.000000000 +0200 +++ /home/lmontel/update-kde-3.4/kdelibs/kjs/string_object.cpp 2005-11-24 09:42:22.000000000 +0100 @@ -32,6 +32,16 @@ #include <stdio.h> #include "string_object.lut.h" +#ifdef HAVE_STDINT_H +#include <stdint.h> +#endif +#ifdef HAVE_SYS_TYPES_H +#include <sys/types.h> +#endif +#ifdef HAVE_SYS_BITYPES_H +#include <sys/bitypes.h> /* For uintXX_t on Tru64 */ +#endif + using namespace KJS; // ------------------------------ StringInstanceImp ---------------------------- @@ -201,6 +211,7 @@ Value StringProtoFuncImp::call(ExecState int n, m; UString u2, u3; + double dpos; int pos, p0, i; double d = 0.0; @@ -216,7 +227,7 @@ Value StringProtoFuncImp::call(ExecState // handled above break; case CharAt: - pos = a0.toInteger(exec); + pos = a0.type() == UndefinedType ? 0 : a0.toInteger(exec); if (pos < 0 || pos >= len) s = ""; else @@ -224,7 +235,7 @@ Value StringProtoFuncImp::call(ExecState result = String(s); break; case CharCodeAt: - pos = a0.toInteger(exec); + pos = a0.type() == UndefinedType ? 0 : a0.toInteger(exec); if (pos < 0 || pos >= len) d = NaN; else { @@ -253,14 +264,16 @@ Value StringProtoFuncImp::call(ExecState case LastIndexOf: u2 = a0.toString(exec); d = a1.toNumber(exec); - if (a1.type() == UndefinedType || KJS::isNaN(d) || KJS::isPosInf(d)) - pos = len; - else - pos = a1.toInteger(exec); - if (pos < 0) - pos = 0; - d = s.rfind(u2, pos); - result = Number(d); + if (a1.type() == UndefinedType || KJS::isNaN(d)) + dpos = len; + else { + dpos = d; + if (dpos < 0) + dpos = 0; + else if (dpos > len) + dpos = len; + } + result = Number(s.rfind(u2, int(dpos))); break; case Match: case Search: { @@ -413,7 +426,7 @@ Value StringProtoFuncImp::call(ExecState Object res = Object::dynamicCast(constructor.construct(exec,List::empty())); result = res; i = p0 = 0; - d = (a1.type() != UndefinedType) ? a1.toInteger(exec) : -1; // optional max number + uint32_t limit = (a1.type() != UndefinedType) ? a1.toUInt32(exec) : 0xFFFFFFFFU; if (a0.type() == ObjectType && Object::dynamicCast(a0).inherits(&RegExpImp::info)) { Object obj0 = Object::dynamicCast(a0); RegExp reg(obj0.get(exec,"source").toString(exec)); @@ -423,7 +436,7 @@ Value StringProtoFuncImp::call(ExecState break; } pos = 0; - while (pos < s.size()) { + while (static_cast<uint32_t>(i) != limit && pos < s.size()) { // TODO: back references int mpos; int *ovector = 0L; @@ -438,7 +451,7 @@ Value StringProtoFuncImp::call(ExecState i++; } } - } else if (a0.type() != UndefinedType) { + } else { u2 = a0.toString(exec); if (u2.isEmpty()) { if (s.isEmpty()) { @@ -446,11 +459,11 @@ Value StringProtoFuncImp::call(ExecState put(exec,lengthPropertyName, Number(0)); break; } else { - while (i != d && i < s.size()-1) + while (static_cast<uint32_t>(i) != limit && i < s.size()-1) res.put(exec,i++, String(s.substr(p0++, 1))); } } else { - while (i != d && (pos = s.find(u2, p0)) >= 0) { + while (static_cast<uint32_t>(i) != limit && (pos = s.find(u2, p0)) >= 0) { res.put(exec,i, String(s.substr(p0, pos-p0))); p0 = pos + u2.size(); i++; @@ -458,7 +471,7 @@ Value StringProtoFuncImp::call(ExecState } } // add remaining string, if any - if (i != d) + if (static_cast<uint32_t>(i) != limit) res.put(exec,i++, String(s.substr(p0))); res.put(exec,lengthPropertyName, Number(i)); } diff -u -p -r kdelibs-3.4.2/kjs/testkjs.cpp /home/lmontel/update-kde-3.4/kdelibs/kjs/testkjs.cpp --- kdelibs-3.4.2/kjs/testkjs.cpp 2005-05-23 14:16:34.000000000 +0200 +++ /home/lmontel/update-kde-3.4/kdelibs/kjs/testkjs.cpp 2005-11-24 09:42:22.000000000 +0100 @@ -24,6 +24,7 @@ #include <stdlib.h> #include <string.h> +#include "collector.h" #include "value.h" #include "object.h" #include "types.h" @@ -37,7 +38,7 @@ public: virtual bool implementsCall() const { return true; } virtual Value call(ExecState *exec, Object &thisObj, const List &args); - enum { Print, Debug, Quit }; + enum { Print, Debug, Quit, GC }; private: int id; @@ -55,6 +56,11 @@ Value TestFunctionImp::call(ExecState *e case Debug: fprintf(stderr,"--> %s\n",args[0].toString(exec).ascii()); return Undefined(); + case GC: + Interpreter::lock(); + Collector::collect(); + Interpreter::unlock(); + return Undefined(); case Quit: exit(0); return Undefined(); @@ -104,6 +110,8 @@ int main(int argc, char **argv) global.put(interp.globalExec(), "print", Object(new TestFunctionImp(TestFunctionImp::Print,1))); // add "quit" for compatibility with the mozilla js shell global.put(interp.globalExec(), "quit", Object(new TestFunctionImp(TestFunctionImp::Quit,0))); + // add "gc" for compatibility with the mozilla js shell + global.put(interp.globalExec(), "gc", Object(new TestFunctionImp(TestFunctionImp::GC, 0))); // add "version" for compatibility with the mozilla js shell global.put(interp.globalExec(), "version", Object(new VersionFunctionImp())); diff -u -p -r kdelibs-3.4.2/kjs/ustring.cpp /home/lmontel/update-kde-3.4/kdelibs/kjs/ustring.cpp --- kdelibs-3.4.2/kjs/ustring.cpp 2005-05-23 14:16:34.000000000 +0200 +++ /home/lmontel/update-kde-3.4/kdelibs/kjs/ustring.cpp 2005-11-24 09:42:22.000000000 +0100 @@ -798,8 +798,10 @@ int UString::find(const UString &f, int const UChar *end = data() + sz - fsz; long fsizeminusone = (fsz - 1) * sizeof(UChar); const UChar *fdata = f.data(); + unsigned short fchar = fdata->uc; + ++fdata; for (const UChar *c = data() + pos; c <= end; c++) - if (*c == *fdata && !memcmp(c + 1, fdata + 1, fsizeminusone)) + if (c->uc == fchar && !memcmp(c + 1, fdata, fsizeminusone)) return (c-data()); return -1; diff -u -p -r kdelibs-3.4.2/kjs/value.cpp /home/lmontel/update-kde-3.4/kdelibs/kjs/value.cpp --- kdelibs-3.4.2/kjs/value.cpp 2005-05-23 14:16:34.000000000 +0200 +++ /home/lmontel/update-kde-3.4/kdelibs/kjs/value.cpp 2005-11-24 09:42:22.000000000 +0100 @@ -139,13 +139,15 @@ unsigned int ValueImp::toUInt32(ExecStat return 0; double d32 = fmod(d, D32); + if (d32 < 0) + d32 += D32; + //6.3.1.4 Real floating and integer // 50) The remaindering operation performed when a value of integer type is // converted to unsigned type need not be performed when a value of real // floating type is converted to unsigned type. Thus, the range of // portable real floating values is (-1, Utype_MAX+1). - int t_int = static_cast<int>(d32); - return static_cast<unsigned int>(t_int); + return static_cast<unsigned int>(d32); } unsigned short ValueImp::toUInt16(ExecState *exec) const