tokenInfo getNextToken(FILE *fp, buffer B) { // Read the input from the buffer. // Check if the buffer has enough space. Else change the buffer. if(B->fwdPointer >= BUFFERSIZE) { // Change buffers. getStream(fp, B->nextBuffer, BUFFERSIZE); // Set current buffer to next buffer if(B->nextBuffer == NULL) { return NULL; } B = B->nextBuffer; // Return next token from the next buffer. return getNextToken(fp, B); } char a = B->buff[B->fwdPointer]; // Check first for the one character tokens. if(a == '(') { tokenInfo token = makeSingleToken(B); token->token_name = OP; token->token_value = "("; return token; } else if(a == ')') { tokenInfo token = makeSingleToken(B); token->token_name = CL; token->token_value = ")"; return token; } else if(a == '[') { tokenInfo token = makeSingleToken(B); token->token_name = SQO; token->token_value = "["; return token; } else if(a == ']') { tokenInfo token = makeSingleToken(B); token->token_name = SQC; token->token_value = "]"; return token; } else if(a == ';') { tokenInfo token = makeSingleToken(B); token->token_name = SEMICOLON; token->token_value = ";"; return token; } else if(a == ',') { tokenInfo token = makeSingleToken(B); token->token_name = COMMA; token->token_value = ","; return token; } else if(a == '+') { tokenInfo token = makeSingleToken(B); token->token_name = PLUS; token->token_value = "+"; return token; } else if(a == '-') { tokenInfo token = makeSingleToken(B); token->token_name = MINUS; token->token_value = "-"; return token; } else if(a == '*') { tokenInfo token = makeSingleToken(B); token->token_name = MUL; token->token_value = "*"; return token; } else if(a == '/') { tokenInfo token = makeSingleToken(B); token->token_name = DIV; token->token_value = "/"; return token; } else if(a == '@') { tokenInfo token = makeSingleToken(B); token->token_name = SIZE; token->token_value = "@"; return token; } // Check for comments token and safely ignore else if(a == '#') { ++B->fwdPointer; while(B->fwdPointer < BUFFERSIZE && (B->buff[B->fwdPointer]!= '\n' && B->buff[B->fwdPointer]!= EOF)) { ++B->fwdPointer; } // Any of the above cases means we have reached the end of the current buffer. Check if exceeded buffer length if(B->buff[B->fwdPointer] == '\n' || B->buff[B->fwdPointer] == EOF) { // The comment has ended. Get the next token and return it. ++B->lineNumber; getStream(fp, B->nextBuffer, BUFFERSIZE); // Set current buffer to next buffer if(B->nextBuffer == NULL) { return NULL; } B = B->nextBuffer; // Keep checking for how long comments go and return next token. return getNextToken(fp, B); } if(B->fwdPointer >= BUFFERSIZE) { // The comment has overflowed to next buffer. Finish reading comment and return the next token. getStream(fp, B->nextBuffer, BUFFERSIZE); // Set current buffer to next buffer if(B->nextBuffer == NULL) { return NULL; } B = B->nextBuffer; // Keep checking for how long comments go and return next token. return getEndCommentAndNextToken(fp, B); } } else if(a == '>' || a == '<') { // Check next token. ++B->fwdPointer; tokenInfo token = malloc(sizeof(tokenStruct)); token->charNumber = B->charNumber; token->lineNumber = B->lineNumber; int curPointer = B->curPointer; // Store the current value temporarily. tokenInfo nextToken = getNextToken(fp, B); if(nextToken->token_name == ASSIGNOP) { // Assign the correct value to this token. if(a == '>') { token->token_name = GE; B->curPointer = ++B->fwdPointer; B->charNumber = B->fwdPointer; token->token_value = ">="; free(nextToken); return token; } else { token->token_name = LE; B->curPointer = ++B->fwdPointer; B->charNumber = B->fwdPointer; token->token_value = "<="; free(nextToken); return token; } } else { // Something else. Return LT or GT. // TODO: Is an error possible in this case? if(a == '>') { token->token_name = GT; // Lost the next token. Need to generate that one again. B->curPointer = curPointer + 1; B->fwdPointer = B->curPointer; B->charNumber = B->fwdPointer; token->token_value = ">"; free(nextToken); return token; } else if(a == '<') { token->token_name = LT; // Lost the next token. Need to generate that one again. B->curPointer = curPointer + 1; B->fwdPointer = B->curPointer; B->charNumber = B->fwdPointer; token->token_value = "<"; free(nextToken); return token; } } } else if(a == '=') { ++B->fwdPointer; tokenInfo token = malloc(sizeof(tokenStruct)); token->charNumber = B->charNumber; token->lineNumber = B->lineNumber; int curPointer = B->curPointer; // Temporary store. tokenInfo nextToken = getNextToken(fp, B); if(nextToken->token_name == ASSIGNOP) { // EQ token. token->token_name = EQ; token->token_value = "=="; B->charNumber = ++B->fwdPointer; free(nextToken); return token; } else if(nextToken->token_name == DIV) { // This should become a NE token if(B->buff[B->fwdPointer] == '=') { // It is the NE token. token->token_name = NE; token->token_value = "=/="; ++B->fwdPointer; ++B->curPointer; ++B->charNumber; free(nextToken); return token; } else { // Not NE token. An error // TODO: Decide error functions char *err = "Bad token. Possible Token: NE ."; showError(err, B->lineNumber); ++B->fwdPointer; ++B->curPointer; ++B->charNumber; free(nextToken); free(token); return NULL; } } else { // Something else. This is the ASSIGNOP token token->token_name = ASSIGNOP; // Lost the next token. Need to generate again. B->curPointer = ++curPointer; token->token_value = "="; B->fwdPointer = B->curPointer; B->charNumber = B->fwdPointer; free(nextToken); return token; } } else if(a == '.') { // One of the logical operators, possibly ++B->fwdPointer; tokenInfo token = malloc(sizeof(tokenStruct)); token->charNumber = B->charNumber; token->lineNumber = B->lineNumber; int curPointer = B->curPointer; tokenInfo nextToken = getNextToken(fp, B); if(nextToken->token_name == ID) { // Check which of the logical operators if(!strcmp(nextToken->token_value,"and")) { // Maybe the and operator. if(B->buff[B->fwdPointer] == '.') { // AND token. token->token_name = AND; token->token_value = ".and."; // Increment current and fwd pointer. ++B->fwdPointer; ++B->curPointer; ++B->charNumber; free(nextToken); return token; } else { // Something else. A Lexical error; char *err = "Lexical error. Possible Token: AND ."; showError(err, B->lineNumber); ++B->fwdPointer; ++B->curPointer; ++B->charNumber; free(nextToken); free(token); return NULL; } } else if(!strcmp(nextToken->token_value,"or")) { // Maybe the or operator if(B->buff[B->fwdPointer] == '.') { // OR token. token->token_name = OR; token->token_value = ".or."; ++B->fwdPointer; ++B->curPointer; ++B->charNumber; free(nextToken); return token; } else{ // Lexical error. char *err = "Lexical error. Possible token: OR ."; showError(err, B->lineNumber); ++B->fwdPointer; ++B->curPointer; ++B->charNumber; free(nextToken); free(token); return NULL; } } else if(!strcmp(nextToken->token_value,"not")) { // Maybe the not operator if(B->buff[B->fwdPointer] == '.') { // NOT token. token->token_name = NOT; token->token_value = ".not."; ++B->fwdPointer; ++B->curPointer; ++B->charNumber; free(nextToken); return token; } else{ // Lexical error. char *err = "Lexical error. Possible Token: NOT ."; showError(err, B->lineNumber); ++B->fwdPointer; ++B->curPointer; ++B->charNumber; free(nextToken); free(token); return NULL; } } else { // Some other identifier. A Lexical error; char *err = "Lexical error after ."; showError(err, B->lineNumber); B->curPointer = ++curPointer; B->fwdPointer = B->curPointer; B->charNumber = B->fwdPointer; free(nextToken); free(token); return NULL; } } else { // A Lexical error; char *err = "Lexical Error after ."; showError(err,B->lineNumber); B->curPointer = ++curPointer; B->fwdPointer = B->curPointer; B->charNumber = B->fwdPointer; free(nextToken); free(token); return NULL; } } else if(a == '_') { // A function identifier ++B->fwdPointer; tokenInfo token = malloc(sizeof(tokenStruct)); token->charNumber = B->charNumber; token->lineNumber = B->lineNumber; token->token_name = FUNID; char* funvalue = (char*)malloc((1+FUNSIZE)*sizeof(char)); funvalue[0] = '_'; if((B->buff[B->fwdPointer] >= 'a' && B->buff[B->fwdPointer] <= 'z') || (B->buff[B->fwdPointer] >= 'A' && B->buff[B->fwdPointer] <= 'Z')) { // Check for the function token. tokenInfo funToken = getFunctionToken(fp, B, FUNSIZE); strcpy(funvalue,funToken->token_value); // No need to store the underscore of the function name. tokenInfo keywordToken = checkForKeyword(funToken->token_value); if(keywordToken != NULL) { // It is a keyword token. Return as keyword. free(token); token = keywordToken; token->charNumber = B->charNumber; token->lineNumber = B->lineNumber; B->curPointer = B->fwdPointer; B->charNumber = B->fwdPointer; free(funvalue); //free(keywordToken); free(funToken); return token; } else { // It is an identifier. Return the identifier itself. token->token_value = funvalue; B->curPointer = B->fwdPointer; B->charNumber = B->fwdPointer; free(funToken); return token; } } else { // Incorrect. Show error. char *err = "Lexical Error. Function names may start only with alphabets."; showError(err, B->lineNumber); B->curPointer = B->fwdPointer; B->charNumber = B->fwdPointer; free(funvalue); free(token); return NULL; } } else if((a >= 'a' && a<= 'z') || (a >= 'A' && a<= 'Z')) { // An alphabet identifier ++B->fwdPointer; tokenInfo token = malloc(sizeof(tokenStruct)); token->charNumber = B->charNumber; token->lineNumber = B->lineNumber; token->token_name = ID; char* idvalue = (char*)malloc((1+IDSIZE)*sizeof(char)); tokenInfo idToken = getIDToken(fp, B, IDSIZE); // Check if it is a token idvalue[0] = a; if(idToken == NULL) { // Check for one alphabet identifier only. token->token_value = idvalue; B->curPointer = B->fwdPointer; B->charNumber = B->fwdPointer; free(idToken); return token; } idvalue = joinStrings(idvalue,idToken->token_value); idToken->token_value = idvalue; tokenInfo keywordToken = checkForKeyword(idToken->token_value); if(keywordToken != NULL) { // It is a keyword token. Return as keyword. free(token); token = keywordToken; token->charNumber = B->charNumber; token->lineNumber = B->lineNumber; B->curPointer = B->fwdPointer; B->charNumber = B->fwdPointer; //free(keywordToken); free(idToken); return token; } else { // It is an identifier. Return the identifier itself. token->token_value = idvalue; //printf("%s",token->token_value); B->curPointer = B->fwdPointer; B->charNumber = B->fwdPointer; free(keywordToken); free(idToken); return token; } } else if(a >= '0' && a<= '9') { // A number identifier ++B->fwdPointer; tokenInfo token = malloc(sizeof(tokenStruct)); token->charNumber = B->charNumber; token->lineNumber = B->lineNumber; char* numvalue = (char*)malloc((1+NUMSIZE)*sizeof(char)); tokenInfo numToken = getNumberToken(fp, B); token->token_name = numToken->token_name; //whether RealNum or IntNum. numvalue[0] = a; token->token_value = joinStrings(numvalue,numToken->token_value); B->curPointer = B->fwdPointer; B->charNumber = B->fwdPointer; free(numToken); return token; } else if(a == '\"') { // String type. ++B->fwdPointer; tokenInfo token = malloc(sizeof(tokenStruct)); token->charNumber = B->charNumber; token->lineNumber = B->lineNumber; token->token_name = STR; char* stringValue = (char*)malloc((IDSIZE)*sizeof(char)); tokenInfo stringToken = getStringToken(fp, B, IDSIZE); // CONSIDER: check if end of string has a '"' if(B->buff[B->fwdPointer] == '"') { // It is a string ending with the '"' strcpy(stringValue,stringToken->token_value); token->token_value = stringValue; ++B->fwdPointer; //printf("%s +++ %s",token->token_value,stringToken->token_value); B->curPointer = B->fwdPointer; B->charNumber = B->fwdPointer; free(stringToken); return token; } else { // It is not a token. Lexical error char *err = "Lexical error after \\"; showError(err,B->lineNumber); ++B->fwdPointer; B->curPointer = B->fwdPointer; B->charNumber = B->fwdPointer; free(stringToken); free(token); free(stringValue); return NULL; } } else { // All other cases. if(a == '\n') { // New line. Change values of line number and char number ++B->lineNumber; B->charNumber = 0; // Change the buffer. FILE* check = getStream(fp, B->nextBuffer, BUFFERSIZE); // Set current buffer to next buffer if(check == NULL) { return NULL; } B = B->nextBuffer; return getNextToken(fp, B); } else if(a == ' ') { ++B->fwdPointer; B->curPointer = B->fwdPointer; ++B->charNumber; return getNextToken(fp, B); } else if(a == EOF) { // End of the input file. Stop here. return NULL; } else if(a == '\t') { ++B->fwdPointer; B->curPointer = B->fwdPointer; ++B->charNumber; return getNextToken(fp, B); } else { // Don't know what type of cases come here. CONSIDER return NULL; } } return NULL; }
void WebSocket::connect(const String& url, const Vector<String>& protocols, ExceptionCode& ec) { LOG(Network, "WebSocket %p connect to %s", this, url.utf8().data()); m_url = KURL(KURL(), url); if (!m_url.isValid()) { scriptExecutionContext()->addConsoleMessage(JSMessageSource, ErrorMessageLevel, "Invalid url for WebSocket " + m_url.elidedString()); m_state = CLOSED; ec = SYNTAX_ERR; return; } if (!m_url.protocolIs("ws") && !m_url.protocolIs("wss")) { scriptExecutionContext()->addConsoleMessage(JSMessageSource, ErrorMessageLevel, "Wrong url scheme for WebSocket " + m_url.elidedString()); m_state = CLOSED; ec = SYNTAX_ERR; return; } if (m_url.hasFragmentIdentifier()) { scriptExecutionContext()->addConsoleMessage(JSMessageSource, ErrorMessageLevel, "URL has fragment component " + m_url.elidedString()); m_state = CLOSED; ec = SYNTAX_ERR; return; } if (!portAllowed(m_url)) { scriptExecutionContext()->addConsoleMessage(JSMessageSource, ErrorMessageLevel, "WebSocket port " + String::number(m_url.port()) + " blocked"); m_state = CLOSED; ec = SECURITY_ERR; return; } // FIXME: Convert this to check the isolated world's Content Security Policy once webkit.org/b/104520 is solved. bool shouldBypassMainWorldContentSecurityPolicy = false; if (scriptExecutionContext()->isDocument()) { Document* document = toDocument(scriptExecutionContext()); shouldBypassMainWorldContentSecurityPolicy = document->frame()->script()->shouldBypassMainWorldContentSecurityPolicy(); } if (!shouldBypassMainWorldContentSecurityPolicy && !scriptExecutionContext()->contentSecurityPolicy()->allowConnectToSource(m_url)) { m_state = CLOSED; // FIXME: Should this be throwing an exception? ec = SECURITY_ERR; return; } m_channel = ThreadableWebSocketChannel::create(scriptExecutionContext(), this); // FIXME: There is a disagreement about restriction of subprotocols between WebSocket API and hybi-10 protocol // draft. The former simply says "only characters in the range U+0021 to U+007E are allowed," while the latter // imposes a stricter rule: "the elements MUST be non-empty strings with characters as defined in [RFC2616], // and MUST all be unique strings." // // Here, we throw SYNTAX_ERR if the given protocols do not meet the latter criteria. This behavior does not // comply with WebSocket API specification, but it seems to be the only reasonable way to handle this conflict. for (size_t i = 0; i < protocols.size(); ++i) { if (!isValidProtocolString(protocols[i])) { scriptExecutionContext()->addConsoleMessage(JSMessageSource, ErrorMessageLevel, "Wrong protocol for WebSocket '" + encodeProtocolString(protocols[i]) + "'"); m_state = CLOSED; ec = SYNTAX_ERR; return; } } HashSet<String> visited; for (size_t i = 0; i < protocols.size(); ++i) { if (visited.contains(protocols[i])) { scriptExecutionContext()->addConsoleMessage(JSMessageSource, ErrorMessageLevel, "WebSocket protocols contain duplicates: '" + encodeProtocolString(protocols[i]) + "'"); m_state = CLOSED; ec = SYNTAX_ERR; return; } visited.add(protocols[i]); } String protocolString; if (!protocols.isEmpty()) protocolString = joinStrings(protocols, subProtocolSeperator()); m_channel->connect(m_url, protocolString); ActiveDOMObject::setPendingActivity(this); }
void WebSocket::connect(const String& url, const Vector<String>& protocols, ExceptionCode& ec) { LOG(Network, "WebSocket %p connect to %s", this, url.utf8().data()); m_url = KURL(KURL(), url); if (!m_url.isValid()) { scriptExecutionContext()->addConsoleMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, "Invalid url for WebSocket " + m_url.string(), scriptExecutionContext()->securityOrigin()->toString()); m_state = CLOSED; ec = SYNTAX_ERR; return; } if (!m_url.protocolIs("ws") && !m_url.protocolIs("wss")) { scriptExecutionContext()->addConsoleMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, "Wrong url scheme for WebSocket " + m_url.string(), scriptExecutionContext()->securityOrigin()->toString()); m_state = CLOSED; ec = SYNTAX_ERR; return; } if (m_url.hasFragmentIdentifier()) { scriptExecutionContext()->addConsoleMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, "URL has fragment component " + m_url.string(), scriptExecutionContext()->securityOrigin()->toString()); m_state = CLOSED; ec = SYNTAX_ERR; return; } if (!portAllowed(m_url)) { scriptExecutionContext()->addConsoleMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, "WebSocket port " + String::number(m_url.port()) + " blocked", scriptExecutionContext()->securityOrigin()->toString()); m_state = CLOSED; ec = SECURITY_ERR; return; } if (!scriptExecutionContext()->contentSecurityPolicy()->allowConnectFromSource(m_url)) { m_state = CLOSED; // FIXME: Should this be throwing an exception? ec = SECURITY_ERR; return; } m_channel = ThreadableWebSocketChannel::create(scriptExecutionContext(), this); m_useHixie76Protocol = m_channel->useHixie76Protocol(); String protocolString; if (m_useHixie76Protocol) { if (!protocols.isEmpty()) { // Emulate JavaScript's Array.toString() behavior. protocolString = joinStrings(protocols, ","); } if (!isValidProtocolStringHixie76(protocolString)) { scriptExecutionContext()->addConsoleMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, "Wrong protocol for WebSocket '" + encodeProtocolString(protocolString) + "'", scriptExecutionContext()->securityOrigin()->toString()); m_state = CLOSED; ec = SYNTAX_ERR; return; } } else { // FIXME: There is a disagreement about restriction of subprotocols between WebSocket API and hybi-10 protocol // draft. The former simply says "only characters in the range U+0021 to U+007E are allowed," while the latter // imposes a stricter rule: "the elements MUST be non-empty strings with characters as defined in [RFC2616], // and MUST all be unique strings." // // Here, we throw SYNTAX_ERR if the given protocols do not meet the latter criteria. This behavior does not // comply with WebSocket API specification, but it seems to be the only reasonable way to handle this conflict. for (size_t i = 0; i < protocols.size(); ++i) { if (!isValidProtocolString(protocols[i])) { scriptExecutionContext()->addConsoleMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, "Wrong protocol for WebSocket '" + encodeProtocolString(protocols[i]) + "'", scriptExecutionContext()->securityOrigin()->toString()); m_state = CLOSED; ec = SYNTAX_ERR; return; } } HashSet<String> visited; for (size_t i = 0; i < protocols.size(); ++i) { if (visited.contains(protocols[i])) { scriptExecutionContext()->addConsoleMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, "WebSocket protocols contain duplicates: '" + encodeProtocolString(protocols[i]) + "'", scriptExecutionContext()->securityOrigin()->toString()); m_state = CLOSED; ec = SYNTAX_ERR; return; } visited.add(protocols[i]); } if (!protocols.isEmpty()) protocolString = joinStrings(protocols, ", "); } m_channel->connect(m_url, protocolString); ActiveDOMObject::setPendingActivity(this); }
tokenInfo getIDToken(FILE *fp, buffer B, int i) { // Find the identifier token. Return even if it is a keyword as an identifier if(i == 0) { char *err = "Token size passed to getIDToken() is zero."; showError(err, B->lineNumber); return NULL; } tokenInfo idToken = malloc(sizeof(tokenStruct)); char* alphabet = (char*)malloc(i*sizeof(char)); // Check if the buffer has enough space. Else change the buffer. if(B->fwdPointer >= BUFFERSIZE) { // Change buffers. getStream(fp, B->nextBuffer, BUFFERSIZE); // Set current buffer to next buffer if(B->nextBuffer == NULL) { return NULL; } B = B->nextBuffer; // Return next token from the next buffer. return getIDToken(fp, B, i); } alphabet[0] = B->buff[B->fwdPointer]; if((alphabet[0] < 'a' || alphabet[0] > 'z') && (alphabet[0] < 'A' || alphabet[0] > 'Z') && (alphabet[0] < '0' || alphabet[0] > '9')) { // Function name ended on previous token. free(idToken); //free(alphabet); return NULL; } else { // It is an alphabet. Keep checking further. ++B->fwdPointer; if(alphabet[0] >= '0' && alphabet[0] <= '9') { // Last letter of the alphabet. Return it right now. idToken->token_value = alphabet; //free(alphabet); return idToken; } tokenInfo nextToken = getIDToken(fp, B, --i); if(nextToken == NULL) { idToken->token_value = alphabet; free(nextToken); //free(alphabet); return idToken; } else { idToken->token_value = joinStrings(alphabet,nextToken->token_value); free(nextToken); //free(alphabet); return idToken; } } }
std::string KeyValueTreePath::toString() const { return "/" + joinStrings(path_, "/"); }
void WebSocket::connect(const String& url, const Vector<String>& protocols, ExceptionState& exceptionState) { WTF_LOG(Network, "WebSocket %p connect() url='%s'", this, url.utf8().data()); m_url = KURL(KURL(), url); if (!m_url.isValid()) { m_state = CLOSED; exceptionState.throwDOMException(SyntaxError, "The URL '" + url + "' is invalid."); return; } if (!m_url.protocolIs("ws") && !m_url.protocolIs("wss")) { m_state = CLOSED; exceptionState.throwDOMException(SyntaxError, "The URL's scheme must be either 'ws' or 'wss'. '" + m_url.protocol() + "' is not allowed."); return; } if (MixedContentChecker::isMixedContent(executionContext()->securityOrigin(), m_url)) { // FIXME: Throw an exception and close the connection. String message = "Connecting to a non-secure WebSocket server from a secure origin is deprecated."; executionContext()->addConsoleMessage(JSMessageSource, WarningMessageLevel, message); } if (m_url.hasFragmentIdentifier()) { m_state = CLOSED; exceptionState.throwDOMException(SyntaxError, "The URL contains a fragment identifier ('" + m_url.fragmentIdentifier() + "'). Fragment identifiers are not allowed in WebSocket URLs."); return; } if (!portAllowed(m_url)) { m_state = CLOSED; exceptionState.throwSecurityError("The port " + String::number(m_url.port()) + " is not allowed."); return; } // FIXME: Convert this to check the isolated world's Content Security Policy once webkit.org/b/104520 is solved. bool shouldBypassMainWorldContentSecurityPolicy = false; if (executionContext()->isDocument()) { Document* document = toDocument(executionContext()); shouldBypassMainWorldContentSecurityPolicy = document->frame()->script().shouldBypassMainWorldContentSecurityPolicy(); } if (!shouldBypassMainWorldContentSecurityPolicy && !executionContext()->contentSecurityPolicy()->allowConnectToSource(m_url)) { m_state = CLOSED; // The URL is safe to expose to JavaScript, as this check happens synchronously before redirection. exceptionState.throwSecurityError("Refused to connect to '" + m_url.elidedString() + "' because it violates the document's Content Security Policy."); return; } m_channel = WebSocketChannel::create(executionContext(), this); // FIXME: There is a disagreement about restriction of subprotocols between WebSocket API and hybi-10 protocol // draft. The former simply says "only characters in the range U+0021 to U+007E are allowed," while the latter // imposes a stricter rule: "the elements MUST be non-empty strings with characters as defined in [RFC2616], // and MUST all be unique strings." // // Here, we throw SyntaxError if the given protocols do not meet the latter criteria. This behavior does not // comply with WebSocket API specification, but it seems to be the only reasonable way to handle this conflict. for (size_t i = 0; i < protocols.size(); ++i) { if (!isValidProtocolString(protocols[i])) { m_state = CLOSED; exceptionState.throwDOMException(SyntaxError, "The subprotocol '" + encodeProtocolString(protocols[i]) + "' is invalid."); releaseChannel(); return; } } HashSet<String> visited; for (size_t i = 0; i < protocols.size(); ++i) { if (!visited.add(protocols[i]).isNewEntry) { m_state = CLOSED; exceptionState.throwDOMException(SyntaxError, "The subprotocol '" + encodeProtocolString(protocols[i]) + "' is duplicated."); releaseChannel(); return; } } String protocolString; if (!protocols.isEmpty()) protocolString = joinStrings(protocols, subProtocolSeperator()); m_channel->connect(m_url, protocolString); }
void WebSocket::connect(const String& url, const Vector<String>& protocols, ExceptionState& exceptionState) { WTF_LOG(Network, "WebSocket %p connect() url='%s'", this, url.utf8().data()); m_url = KURL(KURL(), url); if (!m_url.isValid()) { m_state = CLOSED; exceptionState.throwDOMException(SyntaxError, "The URL '" + url + "' is invalid."); return; } if (!m_url.protocolIs("ws") && !m_url.protocolIs("wss")) { m_state = CLOSED; exceptionState.throwDOMException(SyntaxError, "The URL's scheme must be either 'ws' or 'wss'. '" + m_url.protocol() + "' is not allowed."); return; } if (m_url.hasFragmentIdentifier()) { m_state = CLOSED; exceptionState.throwDOMException(SyntaxError, "The URL contains a fragment identifier ('" + m_url.fragmentIdentifier() + "'). Fragment identifiers are not allowed in WebSocket URLs."); return; } if (!portAllowed(m_url)) { m_state = CLOSED; exceptionState.throwSecurityError("The port " + String::number(m_url.port()) + " is not allowed."); return; } // FIXME: Convert this to check the isolated world's Content Security Policy once webkit.org/b/104520 is solved. bool shouldBypassMainWorldContentSecurityPolicy = false; if (executionContext()->isDocument()) { Document* document = toDocument(executionContext()); shouldBypassMainWorldContentSecurityPolicy = document->frame()->script().shouldBypassMainWorldContentSecurityPolicy(); } if (!shouldBypassMainWorldContentSecurityPolicy && !executionContext()->contentSecurityPolicy()->allowConnectToSource(m_url)) { m_state = CLOSED; // The URL is safe to expose to JavaScript, as this check happens synchronously before redirection. exceptionState.throwSecurityError("Refused to connect to '" + m_url.elidedString() + "' because it violates the document's Content Security Policy."); return; } m_channel = createChannel(executionContext(), this); for (size_t i = 0; i < protocols.size(); ++i) { if (!isValidSubprotocolString(protocols[i])) { m_state = CLOSED; exceptionState.throwDOMException(SyntaxError, "The subprotocol '" + encodeSubprotocolString(protocols[i]) + "' is invalid."); releaseChannel(); return; } } HashSet<String> visited; for (size_t i = 0; i < protocols.size(); ++i) { if (!visited.add(protocols[i]).isNewEntry) { m_state = CLOSED; exceptionState.throwDOMException(SyntaxError, "The subprotocol '" + encodeSubprotocolString(protocols[i]) + "' is duplicated."); releaseChannel(); return; } } String protocolString; if (!protocols.isEmpty()) protocolString = joinStrings(protocols, subprotocolSeperator()); if (!m_channel->connect(m_url, protocolString)) { m_state = CLOSED; exceptionState.throwSecurityError("An insecure WebSocket connection may not be initiated from a page loaded over HTTPS."); releaseChannel(); return; } }
std::string FileNameOptionManager::completeFileName( const std::string &value, const FileNameOptionInfo &option) { const bool bAllowMissing = option.allowMissing(); const bool bInput = option.isInputFile() || option.isInputOutputFile(); // Currently, directory options are simple, and don't need any // special processing. // TODO: Consider splitting them into a separate DirectoryOption. if (option.isDirectoryOption()) { if (!impl_->bInputCheckingDisabled_ && bInput && !bAllowMissing && !Directory::exists(value)) { std::string message = formatString("Directory '%s' does not exist or is not accessible.", value.c_str()); // TODO: Get actual errno value from the attempt to open the file // to provide better feedback to the user. GMX_THROW(InvalidInputError(message)); } return value; } const int fileType = fn2ftp(value.c_str()); if (bInput && !impl_->bInputCheckingDisabled_) { if (fileType == efNR && impl_->redirector_->fileExists(value, File::throwOnError)) { ConstArrayRef<const char *> compressedExtensions(c_compressedExtensions); ConstArrayRef<const char *>::const_iterator ext; for (ext = compressedExtensions.begin(); ext != compressedExtensions.end(); ++ext) { if (endsWith(value, *ext)) { std::string newValue = value.substr(0, value.length() - std::strlen(*ext)); if (option.isValidType(fn2ftp(newValue.c_str()))) { return newValue; } else { return std::string(); } } } // VMD plugins may be able to read the file. if (option.isInputFile() && option.isTrajectoryOption()) { return value; } } else if (fileType == efNR) { const std::string processedValue = findExistingExtension(value, option, impl_->redirector_); if (!processedValue.empty()) { return processedValue; } if (bAllowMissing) { return value + option.defaultExtension(); } else if (option.isLibraryFile()) { // TODO: Treat also library files here. return value + option.defaultExtension(); } else { std::string message = formatString("File '%s' does not exist or is not accessible.\n" "The following extensions were tried to complete the file name:\n %s", value.c_str(), joinStrings(option.extensions(), ", ").c_str()); GMX_THROW(InvalidInputError(message)); } } else if (option.isValidType(fileType)) { if (option.isLibraryFile()) { // TODO: Treat also library files. } else if (!bAllowMissing) { if (!impl_->redirector_->fileExists(value, File::throwOnNotFound)) { return std::string(); } } return value; } } else // Not an input file { if (fileType == efNR) { return value + option.defaultExtension(); } else if (option.isValidType(fileType)) { return value; } } return std::string(); }
bool initSludge (char * filename) { int a = 0; mouseCursorAnim = makeNullAnim (); FILE * fp = openAndVerify (filename, 'G', 'E', ERROR_BAD_HEADER, gameVersion); if (! fp) return false; if (fgetc (fp)) { numBIFNames = get2bytes (fp); allBIFNames = new char * [numBIFNames]; if (! checkNew (allBIFNames)) return false; for (int fn = 0; fn < numBIFNames; fn ++) { allBIFNames[fn] = readString (fp); } numUserFunc = get2bytes (fp); allUserFunc = new char * [numUserFunc]; if (! checkNew (allUserFunc)) return false; for (int fn = 0; fn < numUserFunc; fn ++) { allUserFunc[fn] = readString (fp); } if (gameVersion >= VERSION(1,3)) { numResourceNames = get2bytes (fp); allResourceNames = new char * [numResourceNames]; if (! checkNew (allResourceNames)) return false; for (int fn = 0; fn < numResourceNames; fn ++) { allResourceNames[fn] = readString (fp); } } } winWidth = get2bytes (fp); winHeight = get2bytes (fp); specialSettings = fgetc (fp); desiredfps = 1000/fgetc (fp); delete[] readString (fp); // Unused - was used for registration purposes. size_t bytes_read = fread (& fileTime, sizeof (FILETIME), 1, fp); if (bytes_read != sizeof (FILETIME) && ferror (fp)) { debugOut("Reading error in initSludge.\n"); } char * dataFol = (gameVersion >= VERSION(1,3)) ? readString(fp) : joinStrings ("", ""); gameSettings.numLanguages = (gameVersion >= VERSION(1,3)) ? (fgetc (fp)) : 0; makeLanguageTable (fp); if (gameVersion >= VERSION(1,6)) { fgetc(fp); // aaLoad fgetc (fp); getFloat (fp); getFloat (fp); } char * checker = readString (fp); if (strcmp (checker, "okSoFar")) return fatal (ERROR_BAD_HEADER, filename); delete checker; checker = NULL; unsigned char customIconLogo = fgetc (fp); if (customIconLogo & 1) { // There is an icon - read it! int n; long file_pointer = ftell (fp); png_structp png_ptr; png_infop info_ptr, end_info; int fileIsPNG = true; // Is this a PNG file? char tmp[10]; bytes_read = fread(tmp, 1, 8, fp); if (bytes_read != 8 && ferror (fp)) { debugOut("Reading error in initSludge.\n"); } if (png_sig_cmp((png_byte *) tmp, 0, 8)) { // No, it's old-school HSI fileIsPNG = false; fseek(fp, file_pointer, SEEK_SET); iconW = get2bytes (fp); iconH = get2bytes (fp); } else { // Read the PNG header png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) { return false; } info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { png_destroy_read_struct(&png_ptr, (png_infopp) NULL, (png_infopp) NULL); return false; } end_info = png_create_info_struct(png_ptr); if (!end_info) { png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); return false; } png_init_io(png_ptr, fp); // Tell libpng which file to read png_set_sig_bytes(png_ptr, 8); // 8 bytes already read png_read_info(png_ptr, info_ptr); png_uint_32 width, height; int bit_depth, color_type, interlace_type, compression_type, filter_method; png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, &compression_type, &filter_method); iconW = width; iconH = height; if (bit_depth < 8) png_set_packing(png_ptr); png_set_expand(png_ptr); if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) png_set_gray_to_rgb(png_ptr); if (bit_depth == 16) png_set_strip_16(png_ptr); png_set_add_alpha(png_ptr, 0xff, PNG_FILLER_AFTER); png_read_update_info(png_ptr, info_ptr); png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, &compression_type, &filter_method); } gameIcon = new unsigned char [iconW*iconH*4]; if (! gameIcon) return fatal ("Can't reserve memory for game icon."); int32_t transCol = 63519; Uint8 *p = (Uint8 *) gameIcon; if (fileIsPNG) { unsigned char * row_pointers[iconH]; for (int i = 0; i<iconH; i++) row_pointers[i] = p + 4*i*iconW; png_read_image(png_ptr, (png_byte **) row_pointers); png_read_end(png_ptr, NULL); png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); } else { for (int t2 = 0; t2 < iconH; t2 ++) { int t1 = 0; while (t1 < iconW) { unsigned short c = (unsigned short) get2bytes (fp); if (c & 32) { n = fgetc (fp) + 1; c -= 32; } else { n = 1; } while (n --) { *p++ = (Uint8) redValue(c); *p++ = (Uint8) greenValue(c); *p++ = (Uint8) blueValue(c); *p++ = (Uint8) (c == transCol) ? 0 : 255; t1++; } } } } } if (customIconLogo & 2) { // There is an logo - read it! int n; long file_pointer = ftell (fp); png_structp png_ptr; png_infop info_ptr, end_info; int fileIsPNG = true; // Is this a PNG file? char tmp[10]; bytes_read = fread(tmp, 1, 8, fp); if (bytes_read != 8 && ferror (fp)) { debugOut("Reading error in initSludge.\n"); } if (png_sig_cmp((png_byte *) tmp, 0, 8)) { // No, it's old-school HSI fileIsPNG = false; fseek(fp, file_pointer, SEEK_SET); logoW = get2bytes (fp); logoH = get2bytes (fp); } else { // Read the PNG header png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) { return false; } info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { png_destroy_read_struct(&png_ptr, (png_infopp) NULL, (png_infopp) NULL); return false; } end_info = png_create_info_struct(png_ptr); if (!end_info) { png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); return false; } png_init_io(png_ptr, fp); // Tell libpng which file to read png_set_sig_bytes(png_ptr, 8); // 8 bytes already read png_read_info(png_ptr, info_ptr); png_uint_32 width, height; int bit_depth, color_type, interlace_type, compression_type, filter_method; png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, &compression_type, &filter_method); logoW = width; logoH = height; if (bit_depth < 8) png_set_packing(png_ptr); png_set_expand(png_ptr); if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) png_set_gray_to_rgb(png_ptr); if (bit_depth == 16) png_set_strip_16(png_ptr); #ifdef WIN32 // Windows wants a BGR bitmap if (color_type == PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_RGB_ALPHA) png_set_bgr(png_ptr); #endif png_set_add_alpha(png_ptr, 0xff, PNG_FILLER_AFTER); png_read_update_info(png_ptr, info_ptr); png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, &compression_type, &filter_method); } if ((logoW != 310) || (logoH != 88)) return fatal ("Game logo have wrong dimensions. (Should be 310x88)"); gameLogo = new unsigned char [logoW*logoH*4]; if (! gameLogo) return fatal ("Can't reserve memory for game logo."); // int32_t transCol = 63519; Uint8 *p = (Uint8 *) gameLogo; if (fileIsPNG) { unsigned char * row_pointers[logoH]; for (int i = 0; i<logoH; i++) row_pointers[i] = p + 4*i*logoW; png_read_image(png_ptr, (png_byte **) row_pointers); png_read_end(png_ptr, NULL); png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); } else { for (int t2 = 0; t2 < logoH; t2 ++) { int t1 = 0; while (t1 < logoW) { unsigned short c = (unsigned short) get2bytes (fp); if (c & 32) { n = fgetc (fp) + 1; c -= 32; } else { n = 1; } while (n --) { #ifdef WIN32 // Windows wants a BGR bitmap *p++ = (Uint8) blueValue(c); *p++ = (Uint8) greenValue(c); *p++ = (Uint8) redValue(c); #else *p++ = (Uint8) redValue(c); *p++ = (Uint8) greenValue(c); *p++ = (Uint8) blueValue(c); #endif *p++ = (Uint8) /*(c == transCol) ? 0 :*/ 255; t1++; } } } } } numGlobals = get2bytes (fp); globalVars = new variable[numGlobals]; if (! checkNew (globalVars)) return false; for (a = 0; a < numGlobals; a ++) initVarNew (globalVars[a]); // Get the original (untranslated) name of the game and convert it to Unicode. // We use this to find saved preferences and saved games. setFileIndices (fp, gameSettings.numLanguages, 0); char * gameNameOrig = getNumberedString(1); char * gameName = encodeFilename (gameNameOrig); delete gameNameOrig; changeToUserDir (); #ifdef _WIN32 mkdir (gameName); #else mkdir (gameName, 0000777); #endif if (chdir (gameName)) return fatal ("This game's preference folder is inaccessible!\nI can't access the following directory (maybe there's a file with the same name, or maybe it's read-protected):", gameName); delete [] gameName; // Get user settings readIniFile (filename); // There's no startup window on Linux and respecting this // option from the ini file would disable commandline options. #if defined __unix__ && !(defined __APPLE__) if (! showSetupWindow()) return 0; saveIniFile (filename); #else if (! gameSettings.noStartWindow) { if (! showSetupWindow()) return 0; saveIniFile (filename); } #endif // Now set file indices properly to the chosen language. languageNum = getLanguageForFileB (); if (languageNum < 0) return fatal ("Can't find the translation data specified!"); setFileIndices (NULL, gameSettings.numLanguages, languageNum); if (dataFol[0]) { char *dataFolder = encodeFilename(dataFol); #ifdef _WIN32 mkdir (dataFolder); #else mkdir (dataFolder, 0000777); #endif if (chdir (dataFolder)) return fatal ("This game's data folder is inaccessible!\nI can't access the following directory (maybe there's a file with the same name, or maybe it's read-protected):", dataFolder); delete dataFolder; } positionStatus (10, winHeight - 15); return true; }
int main(){ int *a; char *b="Hello "; char *c= "World"; char *d; char *file1="e.bin"; char *file2="text.bin"; int size; int sizes[2]; int e[4][3]={{1,2,3},{4,5,6},{7,8,9},{10,11,12}}; int **f; int **g; //1 mark //write a function "allocate10" that allocates space for 10 integer using the parameter list //in other words the function is of VOID type, takes a parameter and allocates and assigns memory to that parameter //call the function to allocate and assign memory to a //use a loop in the function to assign a[0] to a[9] to integers 0 to 9 //print the values out one per line in the main program //To be clear - the memory is allocated and assigning values happens in the function //in the main function //free the memory in a allocate10(&a); for(int i=0;i<10;i++){ printf("%d\n",a[i]); } free(a); //1 mark //Write a function "joinStrings" takes as parameters 3 strings. It joins the first 2 together and puts the result in the third string //The function allocates memory for the third string using malloc //apply the function to strings b,c, and d. After the function is done d should have memory allocated to it and contain "Hello World" //the function should not assume the sizes of b or c - it needs to be general enough for any string //after calling the function using b,c,d as parameters print out d from the main function //free the memory in d joinStrings(b,c,&d); printf("%s\n",d); free(d); //1 mark //write a function "arrayWrite" that takes as parameters an array of the same type as e, the size of the first dimension, and a string variables, binaryFilename //the function "arrayWrite" writes the values of the the array (starting from array[0][0] and ending at array[size-1][2]) to the binaryFilename //apply the function to array e and file1 size=4; arrayWrite(e,size,file1); //1 mark //write a function "binaryIO" to take as a parameter two filenames //it opens the first file which is binary reads in sizeof(int) bytes at a time //it writes value and the value squared separated by a ',' one set of values per line i.e. //0,0 //1,1 //2,4 //etc. to a the second file // //run the function with parameters file1, file2 //so at the end of this there should be two new files binaryIO(file1,file2); //2 marks //malloc and assign memory for f as a pointer to pointers to integer style array of the same size as e //malloc and assign memory for g as a pointer to pointer to integer where you assign the pointers to a block of memory the size of e //write a function "arrayCopy" that that takes parameters of the same type as e, f, and g and a sizes array parameter //sizes is an array of the dimension sizes //use for loops to copy values of e to f and g inside the function //in main print out e, f and g 0 //in main free the memory for f //in main free the memory for g f=(int**) malloc(sizeof(int*)*4); for(int i=0;i<4;i++) f[i]=(int*) malloc(sizeof(int)*3); g=(int**) malloc(sizeof(int*)*4); g[0]=malloc(12*sizeof(int)); for(int i=1;i<4;i++) g[i]=g[i-1]+3; sizes[0]=4; sizes[1]=3; arrayCopy(e,f,g,sizes); for(int i=0;i<4;i++){ for(int j=0;j<3;j++){ printf("%d %d %d\n",e[i][j],f[i][j],g[i][j]); } } for(int i=0;i<4;i++) free(f[i]); free(f); f=0; free(g[0]); free(g); g=0; return 1; }
StringInputStream::StringInputStream(ConstArrayRef<const char *> const &input) : input_(joinStrings(input.begin(), input.end(), "\n")), pos_(0) { input_.append("\n"); }