Ejemplo n.º 1
0
    /*static*/ CprotoentObject* CNetdbClass::getprotoent(ScriptObject* self)
    {
        struct protoent *pp;

        pp = VMPI_getprotoent();

        if( pp )
        {
            ShellToplevel* shelltop = (ShellToplevel*)self->toplevel();
            CprotoentClass *pc = shelltop->getShellClasses()->get_protoentClass();
            CprotoentObject *po = pc->constructObject();

            po->set_p_name( self->core()->newStringUTF8( pp->p_name ) );
            po->set_p_proto( pp->p_proto );

            Toplevel* toplevel = self->toplevel();
            ArrayObject *aliases = toplevel->arrayClass()->newArray();
            int count = 0;
            int i;
            for( i=0; pp->p_aliases[i] != NULL; ++i )
            {
                aliases->setUintProperty( count++, self->core()->newStringUTF8( pp->p_aliases[i] )->atom());
            }
            po->set_p_aliases( aliases );

            return po;
        }

        return NULL;
    }
Ejemplo n.º 2
0
	/**
     * Array.prototype.pop()
	 * TRANSFERABLE: Needs to support generic objects as well as Array objects
     */
	/*static*/ Atom ArrayClass::generic_pop(Toplevel* toplevel, Atom thisAtom)
    {
        ArrayObject *a = isArray(toplevel, thisAtom);

		if (a)
			return a->pop();

		if (!AvmCore::isObject(thisAtom))
			return undefinedAtom;

		// Different than Rhino (because of delete) but matches 262.pdf
		ScriptObject *d = AvmCore::atomToScriptObject(thisAtom);
		uint32 len = getLengthHelper(toplevel, d);
		if (!len)
		{
			setLengthHelper(toplevel, d, 0);
			return undefinedAtom;
		}
		else
		{
			Atom outAtom = d->getUintProperty (len-1); 
			d->delUintProperty (len - 1);
			setLengthHelper(toplevel, d, len - 1);
			return outAtom;
		}
    }
Ejemplo n.º 3
0
    /**
     * Array.prototype.reverse()
	 * TRANSFERABLE: Needs to support generic objects as well as Array objects
     */
	/*static*/ Atom ArrayClass::generic_reverse(Toplevel* toplevel, Atom thisAtom)
    {
        ArrayObject *a = isArray(toplevel, thisAtom);
	
		if (a && (a->isSimpleDense()))
		{
			a->m_denseArr.reverse();
			return thisAtom;
		}

		// generic object version
		if (!AvmCore::isObject(thisAtom))
			return thisAtom;

		ScriptObject *d = AvmCore::atomToScriptObject(thisAtom);
		uint32 j = getLengthHelper(toplevel, d);

		uint32 i = 0;
		if (j)
			j--;

		while (i < j) {
			Atom frontAtom = d->getUintProperty(i);
			Atom backAtom  = d->getUintProperty(j);

			d->setUintProperty(i++, backAtom);
			d->setUintProperty(j--, frontAtom);
		}

		return thisAtom;
	}
Ejemplo n.º 4
0
    bool SamplerScript::set_stack(ScriptObject* self, ClassFactoryClass* cf, const Sample& sample, SampleObject* sam)
    {
        if (sample.stack.depth > 0)
        {
            Toplevel* toplevel = self->toplevel();
            AvmCore* core = toplevel->core();
            Sampler* s = core->get_sampler();

            StackFrameClass* sfcc = (StackFrameClass*)cf->get_StackFrameClass();
            ArrayObject* stack = toplevel->arrayClass()->newArray(sample.stack.depth);
            StackTrace::Element* e = (StackTrace::Element*)sample.stack.trace;
            for(uint32_t i=0; i < sample.stack.depth; i++, e++)
            {
                StackFrameObject* sf = sfcc->constructObject();

                // at every allocation the sample buffer could overflow and the samples could be deleted
                // the StackTrace::Element pointer is a raw pointer into that buffer so we need to check
                // that its still around before dereferencing e
                uint32_t num;
                if (s->getSamples(num) == NULL)
                    return false;

                sf->setconst_name(e->name()); // NOT e->info()->name() because e->name() can be a fake name
                sf->setconst_file(e->filename());
                sf->setconst_line(e->linenum());
                sf->setconst_scriptID(static_cast<double>(e->functionId()));

                stack->setUintProperty(i, sf->atom());
            }
            sam->setconst_stack(stack);
        }
        return true;
    }
Ejemplo n.º 5
0
    ArrayObject * ProgramClass::_getEnviron()
    {
        Toplevel *toplevel = this->toplevel();
        AvmCore *core = this->core();

        ArrayObject *array = toplevel->arrayClass()->newArray();

        #if AVMSYSTEM_WIN32
            wchar **cur = VMPI_GetEnviron16();
            int i = 0;
            while( cur[i] )
            {
                Stringp value = core->newStringUTF16(cur[i]);
                StUTF8String valueUTF8(value);

                array->setUintProperty( i, core->newStringUTF8( valueUTF8.c_str() )->atom() );
                i++;
            }
        #else
            char **cur = VMPI_GetEnviron();
            int i = 0;
            while( cur[i] )
            {
                array->setUintProperty( i, core->newStringUTF8( cur[i] )->atom() );
                i++;
            }
        #endif
        
        return array;
    }
Ejemplo n.º 6
0
inline bool
ForOfIterator::nextFromOptimizedArray(MutableHandleValue vp, bool* done)
{
    MOZ_ASSERT(index != NOT_ARRAY);

    if (!CheckForInterrupt(cx_))
        return false;

    ArrayObject* arr = &iterator->as<ArrayObject>();

    if (index >= arr->length()) {
        vp.setUndefined();
        *done = true;
        return true;
    }
    *done = false;

    // Try to get array element via direct access.
    if (index < arr->getDenseInitializedLength()) {
        vp.set(arr->getDenseElement(index));
        if (!vp.isMagic(JS_ELEMENTS_HOLE)) {
            ++index;
            return true;
        }
    }

    return GetElement(cx_, iterator, iterator, index++, vp);
}
Ejemplo n.º 7
0
JSObject *
InitRestParameter(JSContext *cx, uint32_t length, Value *rest, HandleObject templateObj,
                  HandleObject objRes)
{
    if (objRes) {
        Rooted<ArrayObject*> arrRes(cx, &objRes->as<ArrayObject>());

        JS_ASSERT(!arrRes->getDenseInitializedLength());
        JS_ASSERT(arrRes->type() == templateObj->type());

        // Fast path: we managed to allocate the array inline; initialize the
        // slots.
        if (length > 0) {
            if (!arrRes->ensureElements(cx, length))
                return nullptr;
            arrRes->setDenseInitializedLength(length);
            arrRes->initDenseElements(0, rest, length);
            arrRes->setLengthInt32(length);
        }
        return arrRes;
    }

    NewObjectKind newKind = templateObj->type()->shouldPreTenure()
                            ? TenuredObject
                            : GenericObject;
    ArrayObject *arrRes = NewDenseCopiedArray(cx, length, rest, nullptr, newKind);
    if (arrRes)
        arrRes->setType(templateObj->type());
    return arrRes;
}
Ejemplo n.º 8
0
	static Atom twoInts(ScriptObject *obj, unsigned int high, unsigned int low) {
		Atom highatom = obj->core()->uintToAtom(high);
		Atom lowatom = obj->core()->uintToAtom(low);
		ArrayObject *ret = obj->toplevel()->arrayClass()->newArray(2);
		ret->setUintProperty(0, highatom);
		ret->setUintProperty(1, lowatom);
		return ret->atom();
	}
Ejemplo n.º 9
0
    /*static*/ ChostentObject* CNetdbClass::gethostbyname(ScriptObject* self, Stringp name)
    {
        AvmCore *core = self->core();
        Toplevel* toplevel = self->toplevel();

        if( !name )
        {
            toplevel->throwArgumentError(kNullArgumentError, "name");
        }

        struct hostent *he;
        StUTF8String nameUTF8(name);

        he = VMPI_gethostbyname( nameUTF8.c_str() );

        if( he )
        {
            ShellToplevel* shelltop = (ShellToplevel*)self->toplevel();
            ChostentClass *hc = shelltop->getShellClasses()->get_hostentClass();
            ChostentObject *ho = hc->constructObject();

            ho->set_h_name( core->newStringUTF8( he->h_name ) );
            
            ArrayObject *aliases = toplevel->arrayClass()->newArray();
            int count = 0;
            int i;
            for( i=0; he->h_aliases[i] != NULL; ++i )
            {
                aliases->setUintProperty( count++, core->newStringUTF8( he->h_aliases[i] )->atom() );
            }
            ho->set_h_aliases( aliases );

            ho->set_h_addrtype( he->h_addrtype );
            ho->set_h_length( he->h_length );

            ArrayObject *addrlist = toplevel->arrayClass()->newArray();
            count = 0;
            for( i=0; he->h_addr_list[i] != NULL; ++i )
            {
                struct in_addr in;
                memcpy(&in.s_addr, he->h_addr_list[i], sizeof (in.s_addr));

                CIn_AddrClass *ac = shelltop->getShellClasses()->get_in_addrClass();
                CIn_AddrObject *ao = ac->constructObject();

                ao->set_s_addr( in.s_addr );
                addrlist->setUintProperty( count++, ao->toAtom() );                

                //addrlist->setUintProperty( count++, core->newStringUTF8( inet_ntoa(in) )->atom() );
            }
            ho->set_h_addr_list( addrlist );

            return ho;
        }

        return NULL;
    }
Ejemplo n.º 10
0
	Atom RegExpObject::AS3_exec(Stringp subject)
	{
		if (!subject)
		{
			subject = core()->knull;
		}
		UsesUTF8String utf8Subject(subject);
		ArrayObject *result = _exec(subject, utf8Subject);
		return result ? result->atom() : nullStringAtom;
	}
Ejemplo n.º 11
0
	ArrayObject* HTTPFormClass::convertForm(std::vector<FormEntry>& vec)
	{
		AvmCore *core = this->core();
		ArrayObject *out = this->toplevel()->arrayClass->newArray();

		for (std::vector<FormEntry>::iterator it=vec.begin(); it!=vec.end(); it++)
		{
	    	ArrayObject* arr;
	    	Stringp key = core->internStringUTF8((*it).name.data(), (*it).name.length());
	    	Stringp value = core->internStringUTF8((*it).value.data(), (*it).value.length());
	    	//we have it, append
	    	if (out->hasStringProperty(key))
	    	{
	    		arr = (ArrayObject*) core->atomToScriptObject(out->getStringProperty(key));
		    	arr->setUintProperty(arr->get_length(), value->atom());
	    	}
	    	//create array
	    	else
	    	{
		    	arr = this->toplevel()->arrayClass->newArray();
		    	arr->setUintProperty(0, value->atom());
		    	out->setStringProperty(key, arr->atom());
	    	}
		}
		return out;
	}
Ejemplo n.º 12
0
    ArrayObject* StringClass::_split(Stringp in, Atom delimAtom, uint32 limit)
    {
        AvmCore* core = this->core();

        if (limit == 0)
            return toplevel()->arrayClass->newArray();

        if (in->length() == 0)
        {
            ArrayObject* out = toplevel()->arrayClass->newArray();
            out->setUintProperty(0,in->atom());
            return out;
        }

        // handle RegExp case
        if (AvmCore::istype(delimAtom, core->traits.regexp_itraits))
        {
            RegExpObject *reObj = (RegExpObject*) AvmCore::atomToScriptObject(delimAtom);
            return reObj->split(in, limit);
        }

        ArrayObject *out = toplevel()->arrayClass->newArray();
        Stringp delim = core->string(delimAtom);

        int ilen = in->length();
        int dlen = delim->length();
        int count = 0;

        if (dlen <= 0)
        {
            // delim is empty string, split on each char
            for (int i = 0; i < ilen && (unsigned)i < limit; i++)
            {
                Stringp sub = in->substr(i, 1);
                out->setUintProperty(count++, sub->atom());
            }
            return out;
        }

        int32_t start = 0;

        while (start <= in->length())
        {
            if ((limit != 0xFFFFFFFFUL) && (count >= (int) limit))
                break;
            int32_t bgn = in->indexOf(delim, start);
            if (bgn < 0)
                // not found, use the string remainder
                bgn = in->length();
            Stringp sub = in->substring(start, bgn);
            out->setUintProperty(count++, sub->atom());
            start = bgn + delim->length();
        }
        return out;
    }
Ejemplo n.º 13
0
bool
SetObject::construct(JSContext* cx, unsigned argc, Value* vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);

    if (!ThrowIfNotConstructing(cx, args, "Set"))
        return false;

    RootedObject proto(cx);
    RootedObject newTarget(cx, &args.newTarget().toObject());
    if (!GetPrototypeFromConstructor(cx, newTarget, &proto))
        return false;

    Rooted<SetObject*> obj(cx, SetObject::create(cx, proto));
    if (!obj)
        return false;

    if (!args.get(0).isNullOrUndefined()) {
        RootedValue iterable(cx, args[0]);
        bool optimized = false;
        if (!IsOptimizableInitForSet<GlobalObject::getOrCreateSetPrototype, isBuiltinAdd>(cx, obj, iterable, &optimized))
            return false;

        if (optimized) {
            RootedValue keyVal(cx);
            Rooted<HashableValue> key(cx);
            ValueSet* set = obj->getData();
            ArrayObject* array = &iterable.toObject().as<ArrayObject>();
            for (uint32_t index = 0; index < array->getDenseInitializedLength(); ++index) {
                keyVal.set(array->getDenseElement(index));
                MOZ_ASSERT(!keyVal.isMagic(JS_ELEMENTS_HOLE));

                if (!key.setValue(cx, keyVal))
                    return false;
                if (!WriteBarrierPost(cx->runtime(), obj, keyVal) ||
                    !set->put(key))
                {
                    ReportOutOfMemory(cx);
                    return false;
                }
            }
        } else {
            FixedInvokeArgs<1> args2(cx);
            args2[0].set(args[0]);

            RootedValue thisv(cx, ObjectValue(*obj));
            if (!CallSelfHostedFunction(cx, cx->names().SetConstructorInit, thisv, args2, args2.rval()))
                return false;
        }
    }

    args.rval().setObject(*obj);
    return true;
}
Ejemplo n.º 14
0
	ArrayObject* HTTPFormClass::listFileKeys()
	{
		AvmCore *core = this->core();
		ArrayObject *out = this->toplevel()->arrayClass->newArray();

		for (std::vector<FormFile>::iterator it=sapi->files.begin(); it!=sapi->files.end(); it++)
		{
	    	out->setUintProperty(out->get_length(), core->newStringUTF8((*it).name.data(), (*it).name.length())->atom());
		}
		return out;
	}
Ejemplo n.º 15
0
    ArrayObject * ProgramClass::_getArgv()
    {
        Toplevel *toplevel = this->toplevel();
        AvmCore *core = this->core();

        ArrayObject *array = toplevel->arrayClass()->newArray();
        for( int i=0; i<user_argc; i++ )
        {
            array->setUintProperty(i, core->newStringUTF8(user_argv[i])->atom());
        }
        
        return array;
    }
Ejemplo n.º 16
0
	ArrayObject* RegExpObject::match(Stringp subject)
	{
		UsesUTF8String utf8Subject(subject);
		if (!get_global())
		{
			return _exec(subject, utf8Subject);
		}
		else
		{
			ArrayObject *a = toplevel()->arrayClass->newArray();

			int oldLastIndex = m_lastIndex;
			m_lastIndex = 0;

			int n = 0;

			ArrayObject* matchArray;
			while (true)
			{
				int last = m_lastIndex;
				int matchIndex = 0, matchLen = 0;
				int startIndex = Utf16ToUtf8Index(subject, utf8Subject,	m_lastIndex);

				matchArray = _exec(subject,
								  utf8Subject,
								  startIndex,
								  matchIndex,
								  matchLen);
				m_lastIndex = Utf8ToUtf16Index(subject,
											   utf8Subject,
											   matchIndex+matchLen);
				
				if ((matchArray == NULL) || (last == m_lastIndex))
					break;
				a->setUintProperty(n++, matchArray->getUintProperty(0));
			}
			
			if (m_lastIndex == oldLastIndex)
			{
				m_lastIndex++;
			}
			
			return a;
		}
	}
Ejemplo n.º 17
0
    void DynamicObject::SetIsPrototype()
    {
        DynamicTypeHandler* currentTypeHandler = this->GetTypeHandler();
        Js::DynamicType* oldType = this->GetDynamicType();

#if DBG
        bool wasShared = currentTypeHandler->GetIsShared();
        bool wasPrototype = (currentTypeHandler->GetFlags() & DynamicTypeHandler::IsPrototypeFlag) != 0;
        Assert(!DynamicTypeHandler::IsolatePrototypes() || !currentTypeHandler->RespectsIsolatePrototypes() || !currentTypeHandler->GetIsOrMayBecomeShared() || !wasPrototype);
#endif

        // If this handler is not shared and it already has a prototype flag then we must have taken the required
        // type transition (if any) earlier when the singleton object first became a prototype.
        if ((currentTypeHandler->GetFlags() & (DynamicTypeHandler::IsSharedFlag | DynamicTypeHandler::IsPrototypeFlag)) == DynamicTypeHandler::IsPrototypeFlag)
        {
            Assert(this->GetObjectArray() == nullptr || (this->GetObjectArray()->GetTypeHandler()->GetFlags() & DynamicTypeHandler::IsPrototypeFlag) != 0);
            return;
        }

        currentTypeHandler->SetIsPrototype(this);
        // Get type handler again, in case it got changed by SetIsPrototype.
        currentTypeHandler = this->GetTypeHandler();

        // Set the object array as a prototype as well, so if it is an ES5 array, we will disable the array set element fast path
        ArrayObject * objectArray = this->GetObjectArray();
        if (objectArray)
        {
            objectArray->SetIsPrototype();
        }

#if DBG
        Assert(currentTypeHandler->SupportsPrototypeInstances());
        Assert(!DynamicTypeHandler::IsolatePrototypes() || !currentTypeHandler->RespectsIsolatePrototypes() || !currentTypeHandler->GetIsOrMayBecomeShared());
        Assert((wasPrototype && !wasShared) || !DynamicTypeHandler::ChangeTypeOnProto() || !currentTypeHandler->RespectsChangeTypeOnProto() || this->GetDynamicType() != oldType);
#endif

        // If we haven't changed type we must explicitly invalidate store field inline caches to avoid properties
        // getting added to this prototype object on the fast path without proper invalidation.
        if (this->GetDynamicType() == oldType)
        {
            currentTypeHandler->InvalidateStoreFieldCachesForAllProperties(this->GetScriptContext());
        }
    }
Ejemplo n.º 18
0
    ArrayObject *DomainObject::getVariables (Atom a)
    {
        ArrayObject *result = toplevel()->arrayClass->newArray(0);

        TraitsBindingsp traits = getTraits(a)->getTraitsBindings();
        int i = 0;
        while ((i = traits->next(i)) != 0) {
            Namespace *ns = traits->nsAt(i);
            Stringp name = traits->keyAt(i);
            Binding b = traits->valueAt(i);

            if (core()->isVarBinding(b) && ns->getType() == Namespace::NS_Public) {
                Atom nameAtom = core()->internString(name)->atom();
                result->push(&nameAtom, 1);
            }
        }

        return result;
    }
Ejemplo n.º 19
0
	/**
     * Array.prototype.shift()
	 * TRANSFERABLE: Needs to support generic objects as well as Array objects
     */
	/*static*/ Atom ArrayClass::generic_shift(Toplevel* toplevel, Atom thisAtom)
	{
		ArrayObject *a = isArray(toplevel, thisAtom);

		if (a && a->isSimpleDense())
		{
			if (!a->m_length)
				return undefinedAtom;

			a->m_length--;
			return (a->m_denseArr.shift());
		}

		if (!AvmCore::isObject(thisAtom))
			return undefinedAtom;

		Atom outAtom;
		ScriptObject *d = AvmCore::atomToScriptObject(thisAtom);
		uint32 len = getLengthHelper(toplevel, d);

		if (len == 0)
		{
			// set len to 0 (ecmascript spec)
			setLengthHelper(toplevel, d, 0);
			outAtom = undefinedAtom;
		}
		else
		{
			// Get the 0th element to return
			outAtom = d->getUintProperty(0);

			// Move all of the elements down
			for (uint32 i=0; i<len-1; i++) {
				d->setUintProperty(i, d->getUintProperty(i+1));
			}
			
			d->delUintProperty (len - 1);
			setLengthHelper(toplevel, d, len - 1);
		}

		return outAtom;
	}
Ejemplo n.º 20
0
    /*static*/ ChostentObject* CNetdbClass::gethostent(ScriptObject* self)
    {
        struct hostent *hh;

        hh = VMPI_gethostent();

        if( hh )
        {
            ShellToplevel* shelltop = (ShellToplevel*)self->toplevel();
            ChostentClass *hc = shelltop->getShellClasses()->get_hostentClass();
            ChostentObject *ho = hc->constructObject();

            ho->set_h_name( self->core()->newStringUTF8( hh->h_name ) );
            
            Toplevel* toplevel = self->toplevel();
            ArrayObject *aliases = toplevel->arrayClass()->newArray();
            int count = 0;
            int i;
            for( i=0; hh->h_aliases[i] != NULL; ++i )
            {
                aliases->setUintProperty( count++, self->core()->newStringUTF8( hh->h_aliases[i] )->atom());
            }
            ho->set_h_aliases( aliases );

            ho->set_h_addrtype( hh->h_addrtype );
            ho->set_h_length( hh->h_length );

            ArrayObject *addrlist = toplevel->arrayClass()->newArray();
            count = 0;
            for( i=0; hh->h_addr_list[i] != NULL; ++i )
            {
                struct in_addr in;
                memcpy(&in.s_addr, hh->h_addr_list[i], sizeof (in.s_addr));
                addrlist->setUintProperty( count++, self->core()->newStringUTF8( inet_ntoa(in) )->atom());
            }
            ho->set_h_addr_list( addrlist );

            return ho;
        }

        return NULL;
    }
Ejemplo n.º 21
0
bool
RArrayState::recover(JSContext *cx, SnapshotIterator &iter) const
{
    RootedValue result(cx);
    ArrayObject *object = &iter.read().toObject().as<ArrayObject>();
    uint32_t initLength = iter.read().toInt32();

    object->setDenseInitializedLength(initLength);
    for (size_t index = 0; index < numElements(); index++) {
        Value val = iter.read();

        if (index >= initLength) {
            MOZ_ASSERT(val.isUndefined());
            continue;
        }

        object->initDenseElement(index, val);
    }

    result.setObject(*object);
    iter.storeInstructionResult(result);
    return true;
}
Ejemplo n.º 22
0
    /**
     * Array.prototype.slice()
	 * TRANSFERABLE: Needs to support generic objects as well as Array objects
     */
	/*static*/ ArrayObject* ArrayClass::generic_slice(Toplevel* toplevel, Atom thisAtom, double A, double B)
    {
		if (!AvmCore::isObject(thisAtom))
			return 0;

		ScriptObject *d = AvmCore::atomToScriptObject(thisAtom);
		uint32 len = getLengthHelper(toplevel, d);

		// if a param is passed then the first one is A
		// if no params are passed then A = 0
		uint32 a = NativeObjectHelpers::ClampIndex(A, len);
		uint32 b = NativeObjectHelpers::ClampIndex(B, len);
		if (b < a)
			b = a;

		ArrayObject *out = toplevel->arrayClass->newArray(b-a);

		uint32 outIndex=0;
		for (uint32 i=a; i<b; i++) {
			out->setUintProperty (outIndex++, d->getUintProperty (i));
		}

		return out;
	}
Ejemplo n.º 23
0
	ArrayObject* RegExpObject::split(Stringp subject, uint32 limit)
	{
		AvmCore *core = this->core();
		ArrayObject *out = toplevel()->arrayClass->newArray();
		UsesUTF8String utf8Subject(subject);

		int startIndex=0;
		int matchIndex;
		int matchLen;
		ArrayObject* matchArray;
		unsigned n=0;
		bool isEmptyRE = m_source->length() == 0;
		while ((matchArray = _exec(subject,
								  utf8Subject,
								  startIndex,
								  matchIndex,
								  matchLen)) != NULL)
		{
			// [cn 11/22/04] when match is made, but is length 0 we've matched the empty
			//  position between characters.  Although we've "matched", its zero length so just break out.
			if (matchLen == 0 ) {
				matchLen = 0;
				matchIndex = startIndex+numBytesInUtf8Character((uint8*)(utf8Subject->c_str())+startIndex); // +1char  will advance startIndex, extract just one char
				if( !isEmptyRE )
				{
					// don't break if we're processing an empty regex - then we want to split the string into each character
					// so we want the loop to continue
					break;
				}
			}

			//[ed 8/10/04] don't go past end of string. not sure why pcre doesn't return null
			//for a match starting past the end.
			//[cn 12/3/04] because a regular expression which matches an empty position (space between characters)
			//  will match the empty position just past the last character.  This test is correct, though 
			//  it needs to come before we do any setProperties to avoid a bogus xtra result.
			if (matchIndex+matchLen > utf8Subject->length()) {
				startIndex = matchIndex+matchLen;
				break;
			} else {
				out->setUintProperty(n++,
									 (core->newString(utf8Subject->c_str()+startIndex,
													  matchIndex-startIndex))->atom());
				if (n >= limit)
					break;
				for (uint32 j=1; j<matchArray->getLength(); j++) {
					out->setUintProperty(n++, matchArray->getUintProperty(j));
					if (n >= limit)
						break;
				}
				// Advance past this match
				startIndex = matchIndex+matchLen;				
			}
		}

		// If we found no match, or we did find a match and are still under limit, and there is a remainder left, add it 
		if ((unsigned)n < limit && startIndex <= utf8Subject->length()) {
			out->setUintProperty(n++,
								 (core->newString(utf8Subject->c_str()+startIndex,
												  utf8Subject->length()-startIndex))->atom());
		}

		return out;
	}
Ejemplo n.º 24
0
    ArrayObject* RegExpObject::_exec(Stringp subject, 
									UTF8String *utf8Subject,
									int startIndex,
									int& matchIndex,
									int& matchLen)
	{
		AvmAssert(subject != NULL);
		AvmAssert(utf8Subject != NULL);
		
		int ovector[OVECTOR_SIZE];
		int results;
		int subjectLength = utf8Subject->length();

		if( startIndex < 0 ||
			startIndex > subjectLength ||
			(results = pcre_exec((pcre*)m_pcreInst,
								NULL,
								utf8Subject->c_str(),
								subjectLength,
								startIndex,
								PCRE_NO_UTF8_CHECK,
								ovector,
								OVECTOR_SIZE)) < 0)
		{
			matchIndex = 0;
			matchLen = 0;
			return NULL;
		}

		AvmCore *core = this->core();
		ArrayObject *a = toplevel()->arrayClass->newArray(results);

		a->setAtomProperty(toplevel()->regexpClass()->kindex,
			   core->intToAtom(Utf8ToUtf16Index(subject, utf8Subject, ovector[0])));
		a->setAtomProperty(toplevel()->regexpClass()->kinput,
			   subject->atom());
		a->setLength(results);

		// set array slots
		for (int i=0; i<results; i++) {
			if (ovector[i*2] > -1) {
				int length = ovector[i*2 + 1] - ovector[i*2];
				Atom match = stringFromUTF8(utf8Subject->c_str()+ovector[i*2], length);
				a->setUintProperty(i, match);
			} else {
				a->setUintProperty(i, undefinedAtom);
			}
		}

		// handle named groups
		if (m_hasNamedGroups)
		{
			int entrySize;
			pcre_fullinfo((pcre*)m_pcreInst, NULL, PCRE_INFO_NAMEENTRYSIZE, &entrySize);
	 
			int nameCount;
			pcre_fullinfo((pcre*)m_pcreInst, NULL, PCRE_INFO_NAMECOUNT, &nameCount);
	 
			// this space is freed when (pcre*)m_pcreInst is freed 
			char *nameTable;
			pcre_fullinfo((pcre*)m_pcreInst, NULL, PCRE_INFO_NAMETABLE, &nameTable);
	 
			/* nameTable is a series of fixed length entries (entrySize) 
			   the first two bytes are the index into the ovector and the result
			   is a null terminated string (the subgroup name) */
			for (int i = 0; i < nameCount; i++)
			{
				int nameIndex, length;
				nameIndex = (nameTable[0] << 8) + nameTable[1];
				length = ovector[nameIndex * 2 + 1] - ovector[ nameIndex * 2 ];

				Atom name = stringFromUTF8((char*)(nameTable+2), (uint32)strlen(nameTable+2));
				name = core->internString(name)->atom();

				Atom value = stringFromUTF8(utf8Subject->c_str()+ovector[nameIndex*2], length);

				a->setAtomProperty(name, value);

				nameTable += entrySize;
			}
		}
		
		matchIndex = ovector[0];
		matchLen = ovector[1]-ovector[0];

		return a;
	}
Ejemplo n.º 25
0
	/**
	15.4.4.4 Array.prototype.concat ( [ item1 [ , item2 [ , 
 ] ] ] )
	When the concat method is called with zero or more arguments item1, item2, etc., it returns an array containing
	the array elements of the object followed by the array elements of each argument in order.
	The following steps are taken:
	1. Let A be a new array created as if by the expression new Array().
	2. Let n be 0.
	3. Let E be this object.
	4. If E is not an Array object, go to step 16.
	5. Let k be 0.
	6. Call the [[Get]] method of E with argument "length".
	7. If k equals Result(6) go to step 19.
	8. Call ToString(k).
	9. If E has a property named by Result(8), go to step 10, 
	but if E has no property named by Result(8), go to step 13.
	10. Call ToString(n).
	11. Call the [[Get]] method of E with argument Result(8).
	12. Call the [[Put]] method of A with arguments Result(10) and Result(11).
	13. Increase n by 1.
	14. Increase k by 1.
	15. Go to step 7.
	16. Call ToString(n).
	17. Call the [[Put]] method of A with arguments Result(16) and E.
	18. Increase n by 1.
	19. Get the next argument in the argument list; if there are no more arguments, go to step 22.
	20. Let E be Result(19).
	21. Go to step 4.
	22. Call the [[Put]] method of A with arguments "length" and n.
	23. Return A.
	The length property of the concat method is 1.
	NOTE The concat function is intentionally generic; it does not require that its this value be an Array object. Therefore it can be
	transferred to other kinds of objects for use as a method. Whether the concat function can be applied successfully to a host
	object is implementation-dependent.
	*/
	/*static*/ ArrayObject* ArrayClass::generic_concat(Toplevel* toplevel, Atom thisAtom, ArrayObject* args)
    {
		AvmCore* core = toplevel->core();
		ScriptObject *d = AvmCore::isObject(thisAtom) ? AvmCore::atomToScriptObject(thisAtom) : 0;
		
		uint32 len = 0;
		if (d)
		{
			len = getLengthHelper(toplevel, d);
		}

        ArrayObject *a = isArray(toplevel, thisAtom);
		uint32 i;

		uint32 argc = args->getLength();

		int  newLength = len;
		for (i = 0; i< argc; i++) 
		{
			Atom atom = args->getUintProperty(i);
			if (AvmCore::istype(atom, ARRAY_TYPE)) 
			{
				ArrayObject *b = (ArrayObject*) AvmCore::atomToScriptObject(atom);
				newLength += b->getLength();
			}
			else
			{
				newLength++;
			}
		}

		ArrayObject *out = toplevel->arrayClass->newArray(newLength);
		int denseLength = 0;
		// Only copy over elements for Arrays, not objects according to spec
		// 4. If E is not an Array object, go to step 16.
		if (a && newLength)
		{
			denseLength = a->getDenseLength();

			// copy over our dense part
			out->m_denseArr.push (&a->m_denseArr);
			out->m_length += denseLength;

			// copy over any non-dense values (or all values if this isn't an array object)
			for (i = denseLength; i < len; i++) {
				out->setUintProperty(i, d->getUintProperty(i));
			}
		}

		for (i = 0; i< (uint32)argc; i++) 
		{
			Atom atom = args->getUintProperty(i);
			if (AvmCore::istype(atom, ARRAY_TYPE)) 
			{
				ArrayObject *b = (ArrayObject*) AvmCore::atomToScriptObject(atom);
				// copy over dense parts
				out->m_denseArr.push (&b->m_denseArr);
				out->m_length += b->getDenseLength();

				// copy over any non-dense values
				uint32 len = b->getLength();
				for (uint32 j=b->getDenseLength(); j<len; j++) {
					out->m_denseArr.push (b->getUintProperty(j));
					out->m_length++;
				}
			}
			else
			{
				out->m_denseArr.push (atom);
				out->m_length++;
			}
		}

		return out;
	}
Ejemplo n.º 26
0
    /*static*/ ArrayObject* CNetdbClass::getaddrinfo(ScriptObject* self, Stringp nodename, Stringp servname, CaddrinfoObject* hints, CEAIrrorObject* eaierr)
    {
        AvmCore *core = self->core();
        Toplevel* toplevel = self->toplevel();
        ShellToplevel* shelltop = (ShellToplevel*)self->toplevel();

        if( !hints )
        {
            CaddrinfoClass *ai_c = shelltop->getShellClasses()->get_addrinfoClass();
            CaddrinfoObject *hints = ai_c->constructObject();

            //default properties
            hints->set_ai_family( AF_UNSPEC );
            hints->set_ai_socktype( SOCK_STREAM );
        }

        StUTF8String nodenameUTF8(nodename);
        StUTF8String servnameUTF8(servname);

        //(void)hints;

        struct addrinfo h;
        VMPI_memset(&h, 0, sizeof h);
        
        h.ai_flags    = hints->get_ai_flags();
        h.ai_family   = hints->get_ai_family();
        h.ai_socktype = hints->get_ai_socktype();
        h.ai_protocol = hints->get_ai_protocol();
        //ignore other propertiess
        
        struct addrinfo *res, *p;

        int result = VMPI_getaddrinfo( nodenameUTF8.c_str(), servnameUTF8.c_str(), &h, &res );

        if( result != 0 )
        {
            //printf( "getaddrinfo: %s\n", gai_strerror(result));
            if( eaierr )
            {
                eaierr->call_apply( result );
            }

            return NULL;
        }

        ArrayObject *infolist = toplevel->arrayClass()->newArray();
        int count = 0;
        for( p = res; p != NULL; p = p->ai_next )
        {
            CaddrinfoClass *infoc = shelltop->getShellClasses()->get_addrinfoClass();
            CaddrinfoObject *info = infoc->constructObject();

            info->set_ai_flags( p->ai_flags );
            info->set_ai_family( p->ai_family );
            info->set_ai_socktype( p->ai_socktype );
            info->set_ai_protocol( p->ai_protocol );
            info->set_ai_addrlen( (int) p->ai_addrlen );
            info->set_ai_canonname( core->newStringUTF8( p->ai_canonname ) );

            if( p->ai_family == AF_INET )
            {
                struct sockaddr_in *ipv4 = (struct sockaddr_in *)p->ai_addr;
                CSockaddr_inClass *addr4c = shelltop->getShellClasses()->get_sockaddr_inClass();
                CSockaddr_inObject *addr4o = addr4c->constructObject();

                addr4o->set_sin_family( ipv4->sin_family );
                addr4o->set_sin_port( ipv4->sin_port );

                CIn_AddrClass *ac = shelltop->getShellClasses()->get_in_addrClass();
                CIn_AddrObject *ao = ac->constructObject();

                ao->set_s_addr( ipv4->sin_addr.s_addr );
                addr4o->set_sin_addr( ao );

                info->set_ai_addr( addr4o->toAtom() );
            }
            else if( p->ai_family == AF_INET6 )
            {
                struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)p->ai_addr;
                CSockaddr_in6Class *addr6c = shelltop->getShellClasses()->get_sockaddr_in6Class();
                CSockaddr_in6Object *addr6o = addr6c->constructObject();

                addr6o->set_sin6_family( ipv6->sin6_family );
                addr6o->set_sin6_port( ipv6->sin6_port );
                addr6o->set_sin6_flowinfo( ipv6->sin6_flowinfo );
                addr6o->set_sin6_scope_id( ipv6->sin6_scope_id );

                CIn6_AddrClass *ac6 = shelltop->getShellClasses()->get_in6_addrClass();
                CIn6_AddrObject *ao6 = ac6->constructObject();

                ao6->fromStruct( ipv6->sin6_addr );
                addr6o->set_sin6_addr( ao6 );

                info->set_ai_addr( addr6o->toAtom() );
            }

            infolist->setUintProperty( count++, info->toAtom() );
        }

        VMPI_freeaddrinfo( res );

        return infolist;
    }
Ejemplo n.º 27
0
    ChostentObject* CNetdbClass::gethostbyaddr4(CIn_AddrObject* addr, int type)
    {
        Toplevel* toplevel = this->toplevel();
        AvmCore* core = toplevel->core();

        if( !addr )
        {
            toplevel->throwArgumentError(kNullArgumentError, "addr");
        }

        struct hostent *he;
        struct in_addr ipv4addr;
        ipv4addr.s_addr = addr->get_s_addr(); //uint

        if( addr->call_isValid() == false )
        {
            return NULL;
        }

        he = VMPI_gethostbyaddr( (char *)&ipv4addr, sizeof ipv4addr, type );

        if( he )
        {
            ShellToplevel* shelltop = (ShellToplevel*)this->toplevel();
            ChostentClass *hc = shelltop->getShellClasses()->get_hostentClass();
            ChostentObject *ho = hc->constructObject();

            ho->set_h_name( core->newStringUTF8( he->h_name ) );
            
            ArrayObject *aliases = toplevel->arrayClass()->newArray();
            int count = 0;
            int i;
            for( i=0; he->h_aliases[i] != NULL; ++i )
            {
                aliases->setUintProperty( count++, core->newStringUTF8( he->h_aliases[i] )->atom() );
            }
            ho->set_h_aliases( aliases );

            ho->set_h_addrtype( he->h_addrtype );
            ho->set_h_length( he->h_length );

            ArrayObject *addrlist = toplevel->arrayClass()->newArray();
            count = 0;
            for( i=0; he->h_addr_list[i] != NULL; ++i )
            {
                struct in_addr in;
                memcpy(&in.s_addr, he->h_addr_list[i], sizeof (in.s_addr));

                CIn_AddrClass *ac = shelltop->getShellClasses()->get_in_addrClass();
                CIn_AddrObject *ao = ac->constructObject();

                ao->set_s_addr( in.s_addr );
                addrlist->setUintProperty( count++, ao->toAtom() );
            }
            ho->set_h_addr_list( addrlist );

            return ho;
        }

        return NULL;
    }