/* like strcasecmp(s1.raw_buf(),s2.raw_buf()) but for unicode * TODO: slow! */ int tiny_string::strcasecmp(tiny_string& s2) const { char* str1 = g_utf8_casefold(this->raw_buf(),this->numBytes()); char* str2 = g_utf8_casefold(s2.raw_buf(),s2.numBytes()); int ret = g_utf8_collate(str1,str2); g_free(str1); g_free(str2); return ret; }
/* start is an index of characters. * returns index of character */ uint32_t tiny_string::find(const tiny_string& needle, uint32_t start) const { //TODO: omit copy into std::string size_t bytestart = g_utf8_offset_to_pointer(buf,start) - buf; size_t bytepos = std::string(*this).find(needle.raw_buf(),bytestart,needle.numBytes()); if(bytepos == std::string::npos) return npos; else return g_utf8_pointer_to_offset(buf,buf+bytepos); }
tiny_string Vector::toJSON(std::vector<ASObject *> &path, IFunction *replacer, const tiny_string &spaces, const tiny_string &filter) { bool ok; tiny_string res = call_toJSON(ok,path,replacer,spaces,filter); if (ok) return res; // check for cylic reference if (std::find(path.begin(),path.end(), this) != path.end()) throwError<TypeError>(kJSONCyclicStructure); path.push_back(this); res += "["; bool bfirst = true; tiny_string newline = (spaces.empty() ? "" : "\n"); for (unsigned int i =0; i < vec.size(); i++) { tiny_string subres; ASObject* o = vec[i]; if (!o) o = getSystemState()->getNullRef(); if (replacer != NULL) { ASObject* params[2]; params[0] = abstract_di(getSystemState(),i); params[0]->incRef(); params[1] = o; params[1]->incRef(); ASObject *funcret=replacer->call(getSystemState()->getNullRef(), params, 2); if (funcret) subres = funcret->toJSON(path,NULL,spaces,filter); } else { subres = o->toJSON(path,replacer,spaces,filter); } if (!subres.empty()) { if (!bfirst) res += ","; res += newline+spaces; bfirst = false; res += subres; } } if (!bfirst) res += newline+spaces.substr_bytes(0,spaces.numBytes()/2); res += "]"; path.pop_back(); return res; }
const tiny_string multiname::qualifiedString(SystemState* sys) const { assert_and_throw(ns.size()>=1); assert_and_throw(name_type==NAME_STRING); const tiny_string nsName=sys->getStringFromUniqueId(ns[0].nsNameId); const tiny_string& name=sys->getStringFromUniqueId(name_s_id); if(nsName.empty()) return name; else { tiny_string ret=nsName; ret+="::"; ret+=name; return ret; } }
tiny_string multiname::qualifiedString() const { assert_and_throw(ns.size()==1); assert_and_throw(name_type==NAME_STRING); const tiny_string nsName=ns[0].getImpl().name; const tiny_string& name=getSys()->getStringFromUniqueId(name_s_id); if(nsName.empty()) return name; else { tiny_string ret=nsName; ret+="::"; ret+=name; return ret; } }
int JSON::parseNumber(const tiny_string &jsonstring, int pos, ASObject** parent, const multiname& key) { int len = jsonstring.numBytes(); tiny_string res; bool done = false; while (!done && pos < len) { char c = jsonstring.charAt(pos); switch(c) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '-': case '+': case '.': case 'E': case 'e': res += c; pos++; break; default: done = true; break; } } ASString* numstr = Class<ASString>::getInstanceS(res); number_t num = numstr->toNumber(); if (std::isnan(num)) throwError<SyntaxError>(kJSONInvalidParseInput); if (*parent == NULL) *parent = Class<Number>::getInstanceS(num); else { (*parent)->setVariableByMultiname(key,Class<Number>::getInstanceS(num),ASObject::CONST_NOT_ALLOWED); } return pos; }
int JSON::parseArray(const tiny_string &jsonstring, int pos, ASObject** parent, const multiname& key, IFunction *reviver) { int len = jsonstring.numChars(); pos++; // ignore '[' ASObject* subobj = Class<Array>::getInstanceS(); if (*parent == NULL) *parent = subobj; else (*parent)->setVariableByMultiname(key,subobj,ASObject::CONST_NOT_ALLOWED); multiname name(NULL); name.name_type=multiname::NAME_INT; name.name_i = 0; name.ns.push_back(nsNameAndKind("",NAMESPACE)); name.isAttribute = false; bool done = false; bool needdata = false; while (!done && pos < len) { while (jsonstring.charAt(pos) == ' ' || jsonstring.charAt(pos) == '\t' || jsonstring.charAt(pos) == '\n' || jsonstring.charAt(pos) == '\r' ) pos++; char c = jsonstring.charAt(pos); switch(c) { case ']': done = true; pos++; break; case ',': name.name_i++; needdata = true; pos++; break; default: pos = parse(jsonstring,pos,&subobj,name, reviver); needdata = false; break; } } if (!done || needdata) throwError<SyntaxError>(kJSONInvalidParseInput); return pos; }
void JSON::parseAll(const tiny_string &jsonstring, ASObject** parent , const multiname& key, IFunction *reviver) { int len = jsonstring.numBytes(); int pos = 0; while (pos < len) { if (*parent && (*parent)->isPrimitive()) throwError<SyntaxError>(kJSONInvalidParseInput); pos = parse(jsonstring, pos, parent , key, reviver); while (jsonstring.charAt(pos) == ' ' || jsonstring.charAt(pos) == '\t' || jsonstring.charAt(pos) == '\n' || jsonstring.charAt(pos) == '\r' ) pos++; } }
XMLDocument::XMLDocument(Class_base* c, tiny_string s) : XMLNode(c),rootNode(NULL),ignoreWhite(false) { if(!s.empty()) { parseXMLImpl(s); } }
bool Array::isValidQName(const tiny_string& name, const tiny_string& ns, unsigned int& index) { if(ns!="") return false; assert_and_throw(!name.empty()); index=0; //First we try to convert the string name to an index, at the first non-digit //we bail out for(auto i=name.begin(); i!=name.end(); ++i) { if(!i.isdigit()) return false; index*=10; index+=i.digit_value(); } return true; }
bool Array::isIntegerWithoutLeadingZeros(const tiny_string& value) { if (value.empty()) return false; else if (value == "0") return true; bool first = true; for (CharIterator it=value.begin(); it!=value.end(); ++it) { if (!it.isdigit() || (first && *it == '0')) return false; first = false; } return true; }
CurlDownloader::CurlDownloader(const tiny_string& u) { //TODO: Url encode the string std::string tmp2; tmp2.reserve(u.len()*2); for(int i=0;i<u.len();i++) { if(u[i]==' ') { char buf[4]; sprintf(buf,"%%%x",(unsigned char)u[i]); tmp2+=buf; } else tmp2.push_back(u[i]); } url=tmp2; }
bool Array::isValidQName(const tiny_string& name, const tiny_string& ns, unsigned int& index) { if(ns!="") return false; assert_and_throw(name.len()!=0); index=0; //First we try to convert the string name to an index, at the first non-digit //we bail out for(int i=0;i<name.len();i++) { if(!isdigit(name[i])) return false; index*=10; index+=(name[i]-'0'); } return true; }
void nsPluginInstance::openLink(const tiny_string& url, const tiny_string& window) { assert(!window.empty()); linkOpenData *data = new linkOpenData; data->instance = mInstance; data->url = url; data->window = window; NPN_PluginThreadAsyncCall(mInstance, asyncOpenPage, data); }
void XMLSocket::connect(tiny_string host, int port) { if (port <= 0 || port > 65535) throw Class<SecurityError>::getInstanceS(getSystemState(),"Invalid port"); if (host.empty()) host = getSys()->mainClip->getOrigin().getHostname(); if (isConnected()) throw Class<IOError>::getInstanceS(getSystemState(),"Already connected"); // Host shouldn't contain scheme or port if (host.strchr(':') != NULL) throw Class<SecurityError>::getInstanceS(getSystemState(),"Invalid hostname"); // Check sandbox and policy file size_t buflen = host.numBytes() + 22; char *urlbuf = g_newa(char, buflen); snprintf(urlbuf, buflen, "xmlsocket://%s:%d", host.raw_buf(), port); URLInfo url(urlbuf); getSystemState()->securityManager->checkURLStaticAndThrow(url, ~(SecurityManager::LOCAL_WITH_FILE), SecurityManager::LOCAL_WITH_FILE | SecurityManager::LOCAL_TRUSTED, true); SecurityManager::EVALUATIONRESULT evaluationResult; evaluationResult = getSys()->securityManager->evaluateSocketConnection(url, true); if(evaluationResult != SecurityManager::ALLOWED) { incRef(); getVm(getSystemState())->addEvent(_MR(this), _MR(Class<SecurityErrorEvent>::getInstanceS(getSystemState(),"No policy file allows socket connection"))); return; } incRef(); XMLSocketThread *thread = new XMLSocketThread(_MR(this), host, port, timeout); getSys()->addJob(thread); job = thread; }
tiny_string XMLBase::removeWhitespace(tiny_string val) { bool bwhite = true; uint32_t start = 0; CharIterator it = val.begin(); CharIterator itend = val.begin(); while (it != val.end()) { if (!g_unichar_isspace(*it)) { itend=it; itend++; bwhite = false; } else if (bwhite) start++; it++; } if (bwhite) return ""; return val.substr(start,itend); }
const tiny_string XMLBase::encodeToXML(const tiny_string value, bool bIsAttribute) { tiny_string res; auto it = value.begin(); while (it != value.end()) { switch (*it) { case '<': res += "<"; break; case '>': res += bIsAttribute ? ">" : ">"; break; case '&': res += "&"; break; case '\"': res += bIsAttribute ? """ : "\""; break; case '\r': res += bIsAttribute ? "
" : "\r"; break; case '\n': res += bIsAttribute ? "
" : "\n"; break; case '\t': res += bIsAttribute ? "	" : "\t"; break; default: res += *it; break; } it++; } return res; }
int JSON::parseNull(const tiny_string &jsonstring, int pos,ASObject** parent,const multiname& key) { int len = jsonstring.numBytes(); if (len >= pos+4) { if (jsonstring.charAt(pos) == 'n' && jsonstring.charAt(pos + 1) == 'u' && jsonstring.charAt(pos + 2) == 'l' && jsonstring.charAt(pos + 3) == 'l') { pos += 4; if (*parent == NULL) *parent = getSys()->getNullRef(); else (*parent)->setVariableByMultiname(key,getSys()->getNullRef(),ASObject::CONST_NOT_ALLOWED); } else throwError<SyntaxError>(kJSONInvalidParseInput); } else throwError<SyntaxError>(kJSONInvalidParseInput); return pos; }
int JSON::parseTrue(const tiny_string &jsonstring, int pos,ASObject** parent,const multiname& key) { int len = jsonstring.numBytes(); if (len >= pos+4) { if (jsonstring.charAt(pos) == 't' && jsonstring.charAt(pos + 1) == 'r' && jsonstring.charAt(pos + 2) == 'u' && jsonstring.charAt(pos + 3) == 'e') { pos += 4; if (*parent == NULL) *parent = abstract_b(true); else (*parent)->setVariableByMultiname(key,abstract_b(true),ASObject::CONST_NOT_ALLOWED); } else throwError<SyntaxError>(kJSONInvalidParseInput); } else throwError<SyntaxError>(kJSONInvalidParseInput); return pos; }
bool SocketIO::connect(const tiny_string& hostname, int port) { struct addrinfo hints; struct addrinfo *servinfo; struct addrinfo *p; if (fd != -1) return false; fd = -1; if (port <= 0 || port > 65535) return false; memset(&hints, 0, sizeof hints); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; tiny_string portstr = Integer::toString(port); if (getaddrinfo(hostname.raw_buf(), portstr.raw_buf(), &hints, &servinfo) != 0) { return false; } for(p = servinfo; p != NULL; p = p->ai_next) { if ((fd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) continue; // TODO: timeout on connect if (::connect(fd, p->ai_addr, p->ai_addrlen) == -1) { ::close(fd); continue; } break; } freeaddrinfo(servinfo); if (!p) fd = -1; return fd != -1; }
void ByteArray::writeUTF(const tiny_string& str) { getBuffer(position+str.numBytes()+2,true); if(str.numBytes() > 65535) { throwError<RangeError>(kParamRangeError); } uint16_t numBytes=endianIn((uint16_t)str.numBytes()); memcpy(bytes+position,&numBytes,2); memcpy(bytes+position+2,str.raw_buf(),str.numBytes()); position+=str.numBytes()+2; }
const pugi::xml_node XMLBase::buildFromString(const tiny_string& str, unsigned int xmlparsemode, const tiny_string& default_ns) { tiny_string buf = quirkEncodeNull(removeWhitespace(str)); if (buf.numBytes() > 0 && buf.charAt(0) == '<') { pugi::xml_parse_result res = xmldoc.load_buffer((void*)buf.raw_buf(),buf.numBytes(),xmlparsemode); switch (res.status) { case pugi::status_ok: break; case pugi::status_end_element_mismatch: throwError<TypeError>(kXMLUnterminatedElementTag); break; case pugi::status_unrecognized_tag: throwError<TypeError>(kXMLMalformedElement); break; case pugi::status_bad_pi: throwError<TypeError>(kXMLUnterminatedXMLDecl); break; case pugi::status_bad_attribute: throwError<TypeError>(kXMLUnterminatedAttribute); break; case pugi::status_bad_cdata: throwError<TypeError>(kXMLUnterminatedCData); break; case pugi::status_bad_doctype: throwError<TypeError>(kXMLUnterminatedDocTypeDecl); break; case pugi::status_bad_comment: throwError<TypeError>(kXMLUnterminatedComment); break; default: LOG(LOG_ERROR,"xml parser error:"<<buf<<" "<<res.status<<" "<<res.description()); break; } } else { pugi::xml_node n = xmldoc.append_child(pugi::node_pcdata); n.set_value(str.raw_buf()); } return xmldoc.root(); }
int JSON::parse(const tiny_string &jsonstring, int pos, ASObject** parent , const multiname& key, IFunction *reviver) { while (jsonstring.charAt(pos) == ' ' || jsonstring.charAt(pos) == '\t' || jsonstring.charAt(pos) == '\n' || jsonstring.charAt(pos) == '\r' ) pos++; int len = jsonstring.numBytes(); if (pos < len) { char c = jsonstring.charAt(pos); switch(c) { case '{': pos = parseObject(jsonstring,pos,parent,key, reviver); break; case '[': pos = parseArray(jsonstring,pos,parent,key, reviver); break; case '"': pos = parseString(jsonstring,pos,parent,key); break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '-': pos = parseNumber(jsonstring,pos,parent,key); break; case 't': pos = parseTrue(jsonstring,pos,parent,key); break; case 'f': pos = parseFalse(jsonstring,pos,parent,key); break; case 'n': pos = parseNull(jsonstring,pos,parent,key); break; default: throwError<SyntaxError>(kJSONInvalidParseInput); } } if (reviver) { bool haskey = key.name_type!= multiname::NAME_OBJECT; ASObject* params[2]; if (haskey) { params[0] = Class<ASString>::getInstanceS(key.normalizedName()); if ((*parent)->hasPropertyByMultiname(key,true,false)) { params[1] = (*parent)->getVariableByMultiname(key).getPtr(); params[1]->incRef(); } else params[1] = getSys()->getNullRef(); } else { params[0] = Class<ASString>::getInstanceS(""); params[1] = *parent; params[1]->incRef(); } ASObject *funcret=reviver->call(getSys()->getNullRef(), params, 2); if(funcret) { if (haskey) { if (funcret->is<Undefined>()) { (*parent)->deleteVariableByMultiname(key); funcret->decRef(); } else { (*parent)->setVariableByMultiname(key,funcret,ASObject::CONST_NOT_ALLOWED); } } else *parent= funcret; } } return pos; }
ASString::ASString(const tiny_string& s):data(s.raw_buf()) { type=T_STRING; }
int JSON::parseObject(const tiny_string &jsonstring, int pos,ASObject** parent,const multiname& key, IFunction *reviver) { int len = jsonstring.numChars(); pos++; // ignore '{' or ',' ASObject* subobj = Class<ASObject>::getInstanceS(); if (*parent == NULL) *parent = subobj; else (*parent)->setVariableByMultiname(key,subobj,ASObject::CONST_NOT_ALLOWED); multiname name(NULL); name.name_type=multiname::NAME_STRING; name.ns.push_back(nsNameAndKind("",NAMESPACE)); name.isAttribute = false; bool done = false; bool bfirst = true; bool needkey = true; bool needvalue = false; while (!done && pos < len) { while (jsonstring.charAt(pos) == ' ' || jsonstring.charAt(pos) == '\t' || jsonstring.charAt(pos) == '\n' || jsonstring.charAt(pos) == '\r' ) pos++; char c = jsonstring.charAt(pos); switch(c) { case '}': if (!bfirst && (needkey || needvalue)) throwError<SyntaxError>(kJSONInvalidParseInput); done = true; pos++; break; case '\"': { tiny_string keyname; pos = parseString(jsonstring,pos,NULL,name,&keyname); name.name_s_id=getSys()->getUniqueStringId(keyname); needkey = false; needvalue = true; } break; case ',': if (needkey || needvalue) throwError<SyntaxError>(kJSONInvalidParseInput); pos++; name.name_s_id=0; needkey = true; break; case ':': pos++; pos = parse(jsonstring,pos,&subobj,name,reviver); needvalue = false; break; default: throwError<SyntaxError>(kJSONInvalidParseInput); } bfirst=false; } if (!done) throwError<SyntaxError>(kJSONInvalidParseInput); return pos; }
int JSON::parseString(const tiny_string &jsonstring, int pos,ASObject** parent,const multiname& key, tiny_string* result) { pos++; // ignore starting quotes int len = jsonstring.numChars(); if (pos >= len) throwError<SyntaxError>(kJSONInvalidParseInput); tiny_string sub = jsonstring.substr(pos,len-pos); tiny_string res; bool done = false; for (CharIterator it=sub.begin(); it!=sub.end(); it++) { pos++; if (*it == '\"') { done = true; break; } else if(*it == '\\') { it++; pos++; if(it == sub.end()) break; if(*it == '\"') res += '\"'; else if(*it == '\\') res += '\\'; else if(*it == '/') res += '/'; else if(*it == 'b') res += '\b'; else if(*it == 'f') res += '\f'; else if(*it == 'n') res += '\n'; else if(*it == 'r') res += '\r'; else if(*it == 't') res += '\t'; else if(*it == 'u') { tiny_string strhex; for (int i = 0; i < 4; i++) { it++; pos++; if (it==sub.end()) throwError<SyntaxError>(kJSONInvalidParseInput); switch(*it) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': strhex += *it; break; default: throwError<SyntaxError>(kJSONInvalidParseInput); } if (it==sub.end()) throwError<SyntaxError>(kJSONInvalidParseInput); } int64_t hexnum; if (Integer::fromStringFlashCompatible(strhex.raw_buf(),hexnum,16)) { if (hexnum < 0x20 && hexnum != 0xf) throwError<SyntaxError>(kJSONInvalidParseInput); res += tiny_string::fromChar(hexnum); } else break; } else throwError<SyntaxError>(kJSONInvalidParseInput); } else if (*it < 0x20) { throwError<SyntaxError>(kJSONInvalidParseInput); } else { res += *it; } } if (!done) throwError<SyntaxError>(kJSONInvalidParseInput); if (parent != NULL) { if (*parent == NULL) *parent = Class<ASString>::getInstanceS(res); else (*parent)->setVariableByMultiname(key,Class<ASString>::getInstanceS(res),ASObject::CONST_NOT_ALLOWED); } if (result) *result =res; return pos; }
void URLVariables::decode(const tiny_string& s) { const char* nameStart=NULL; const char* nameEnd=NULL; const char* valueStart=NULL; const char* valueEnd=NULL; const char* cur=s.raw_buf(); while(1) { if(nameStart==NULL) nameStart=cur; if(*cur == '=') { if(nameStart==NULL || valueStart!=NULL) //Skip this { nameStart=NULL; nameEnd=NULL; valueStart=NULL; valueEnd=NULL; cur++; continue; } nameEnd=cur; valueStart=cur+1; } else if(*cur == '&' || *cur==0) { if(nameStart==NULL || nameEnd==NULL || valueStart==NULL || valueEnd!=NULL) { nameStart=NULL; nameEnd=NULL; valueStart=NULL; valueEnd=NULL; cur++; continue; } valueEnd=cur; char* name=g_uri_unescape_segment(nameStart,nameEnd,NULL); char* value=g_uri_unescape_segment(valueStart,valueEnd,NULL); nameStart=NULL; nameEnd=NULL; valueStart=NULL; valueEnd=NULL; //Check if the variable already exists multiname propName; propName.name_type=multiname::NAME_STRING; propName.name_s=name; propName.ns.push_back(nsNameAndKind("",NAMESPACE)); ASObject* curValue=getVariableByMultiname(propName); if(curValue) { //If the variable already exists we have to create an Array of values Array* arr=NULL; if(curValue->getObjectType()!=T_ARRAY) { arr=Class<Array>::getInstanceS(); curValue->incRef(); arr->push(curValue); setVariableByMultiname(propName,arr); } else arr=Class<Array>::cast(curValue); arr->push(Class<ASString>::getInstanceS(value)); } else setVariableByMultiname(propName,Class<ASString>::getInstanceS(value)); g_free(name); g_free(value); if(*cur==0) break; } cur++; } }
/** * \brief Checks URL policy files to see if the player is allowed to send a given request header * as part of a request for the given URL * * Waits for mutex at start and releases mutex when finished * \param url The URL of the request to which the request header belongs * \param header The request header to evaluate * \param loadPendingPolicies Whether or not to load (and thus check) pending policy files * \return \c ALLOWED if allowed or otherwise \c NA_HEADER */ SecurityManager::EVALUATIONRESULT SecurityManager::evaluateHeader(const URLInfo& url, const tiny_string& header, bool loadPendingPolicies) { //This check doesn't apply to local files if(url.getProtocol() == "file" && getSys()->getOrigin().getProtocol() == "file") return ALLOWED; LOG(LOG_INFO, _("SECURITY: Evaluating header for cross domain policies ('") << header << "'):"); LOG(LOG_INFO, _("SECURITY: --> URL: ") << url); LOG(LOG_INFO, _("SECURITY: --> Origin: ") << getSys()->getOrigin()); string headerStrLower(header.raw_buf()); transform(headerStrLower.begin(), headerStrLower.end(), headerStrLower.begin(), ::tolower); string headerStr = headerStrLower; if(headerStr.find("_") != string::npos) headerStr.replace(headerStr.find("_"), 1, "-"); //Disallowed headers, in any case if(headerStr == "accept-charset" && headerStr == "accept-encoding" && headerStr == "accept-ranges" && headerStr == "age" && headerStr == "allow" && headerStr == "allowed" && headerStr == "authorization" && headerStr == "charge-to" && headerStr == "connect" && headerStr == "connection" && headerStr == "content-length" && headerStr == "content-location" && headerStr == "content-range" && headerStr == "cookie" && headerStr == "date" && headerStr == "delete" && headerStr == "etag" && headerStr == "expect" && headerStr == "get" && headerStr == "head" && headerStr == "host" && headerStr == "if-modified-since" && headerStr == "keep-alive" && headerStr == "last-modified" && headerStr == "location" && headerStr == "max-forwards" && headerStr == "options" && headerStr == "origin" && headerStr == "post" && headerStr == "proxy-authenticate" && headerStr == "proxy-authorization" && headerStr == "proxy-connection" && headerStr == "public" && headerStr == "put" && headerStr == "range" && headerStr == "referer" && headerStr == "request-range" && headerStr == "retry-after" && headerStr == "server" && headerStr == "te" && headerStr == "trace" && headerStr == "trailer" && headerStr == "transfer-encoding" && headerStr == "upgrade" && headerStr == "uri" && headerStr == "user-agent" && headerStr == "vary" && headerStr == "via" && headerStr == "warning" && headerStr == "www-authenticate" && headerStr == "x-flash-version") { LOG(LOG_INFO, _("SECURITY: DISALLOWED: Header is restricted")); return NA_HEADER; } //The URL has exactly the same domain name as the origin, always allowed if(url.getProtocol() == getSys()->getOrigin().getProtocol() && url.getHostname() == getSys()->getOrigin().getHostname()) { LOG(LOG_INFO, _("SECURITY: ALLOWED: Same hostname as origin")); return ALLOWED; } //Search for the policy files to check URLPFileList* files = searchURLPolicyFiles(url, loadPendingPolicies); RecMutex::Lock l(mutex); //Check the policy files if(files != NULL) { URLPFileListConstIt it = files->begin(); for(; it != files->end(); ++it) { if((*it)->allowsHTTPRequestHeaderFrom(getSys()->getOrigin(), url, headerStrLower)) { LOG(LOG_INFO, _("SECURITY: ALLOWED: A policy file explicitly allowed the header")); delete files; return ALLOWED; } } } LOG(LOG_INFO, _("SECURITY: DISALLOWED: No policy file explicitly allowed the header")); delete files; return NA_CROSSDOMAIN_POLICY; }