int HTTPExchange_read_response_headers(HTTPExchange * exchange) { /* make sure the request went through before we try to read stuff */ int result = HTTPExchange_flush_request(exchange); if (result != 0) { return result; } result = HTTPMessage_read_start_line_and_headers(exchange->response_message); if (result != 0) { return result; } /* parse the Status-Line (RFC 2616 6.1) */ const char * status_line = HTTPMessage_get_start_line(exchange->response_message); const char * p = status_line; /* read the HTTP-Version */ if (! str_starts_with(p, "HTTP/")) { return -1; } p += 5; const char * start = p; skip_digits(&p); if (start == p) { return -1; } if (*p != '.') { return -1; } p++; start = p; skip_digits(&p); if (start == p) { return -1; } if (*p != ' ') { return -1; } exchange->response_http_version = xstrndup(status_line, p - status_line); /* skip over the space */ p++; /* read the Status-Code */ start = p; skip_digits(&p); if (p - start != 3) { return -1; } if (*p != ' ') { return -1; } exchange->status_code = strtoul(start, NULL, 10); return 0; }
static void get_microseconds(ulong *val, MYSQL_TIME_STATUS *status, uint *number_of_fields, const char **str, const char *end) { const char *start= *str; uint tmp= 0; /* For the case '10:10:10.' */ if (get_digits(&tmp, number_of_fields, str, end, 6)) status->warnings|= MYSQL_TIME_WARN_TRUNCATED; if ((status->precision= (*str - start)) < 6) *val= tmp * log_10_int[6 - (*str - start)]; else *val= tmp; if (skip_digits(str, end)) status->warnings|= MYSQL_TIME_NOTE_TRUNCATED; }
my_bool str_to_datetime(const char *str, uint length, MYSQL_TIME *l_time, ulonglong flags, MYSQL_TIME_STATUS *status) { const char *end=str+length, *pos; uint number_of_fields= 0, digits, year_length, not_zero_date; DBUG_ENTER("str_to_datetime"); bzero(l_time, sizeof(*l_time)); if (flags & TIME_TIME_ONLY) { my_bool ret= str_to_time(str, length, l_time, flags, status); DBUG_RETURN(ret); } my_time_status_init(status); /* Skip space at start */ for (; str != end && my_isspace(&my_charset_latin1, *str) ; str++) ; if (str == end || ! my_isdigit(&my_charset_latin1, *str)) { status->warnings= MYSQL_TIME_WARN_TRUNCATED; l_time->time_type= MYSQL_TIMESTAMP_NONE; DBUG_RETURN(1); } /* Calculate number of digits in first part. If length= 8 or >= 14 then year is of format YYYY. (YYYY-MM-DD, YYYYMMDD, YYYYYMMDDHHMMSS) */ pos= str; digits= skip_digits(&pos, end); if (pos < end && *pos == 'T') /* YYYYYMMDDHHMMSSThhmmss is supported too */ { pos++; digits+= skip_digits(&pos, end); } if (pos < end && *pos == '.' && digits >= 12) /* YYYYYMMDDHHMMSShhmmss.uuuuuu is supported too */ { pos++; skip_digits(&pos, end); // ignore the return value } if (pos == end) { /* Found date in internal format (only numbers like [YY]YYMMDD[T][hhmmss[.uuuuuu]]) */ year_length= (digits == 4 || digits == 8 || digits >= 14) ? 4 : 2; if (get_digits(&l_time->year, &number_of_fields, &str, end, year_length) || get_digits(&l_time->month, &number_of_fields, &str, end, 2) || get_digits(&l_time->day, &number_of_fields, &str, end, 2) || get_maybe_T(&str, end) || get_digits(&l_time->hour, &number_of_fields, &str, end, 2) || get_digits(&l_time->minute, &number_of_fields, &str, end, 2) || get_digits(&l_time->second, &number_of_fields, &str, end, 2)) status->warnings|= MYSQL_TIME_WARN_TRUNCATED; } else { const char *start= str; if (get_number(&l_time->year, &number_of_fields, &str, end)) status->warnings|= MYSQL_TIME_WARN_TRUNCATED; year_length= str - start; if (!status->warnings && (get_punct(&str, end) || get_number(&l_time->month, &number_of_fields, &str, end) || get_punct(&str, end) || get_number(&l_time->day, &number_of_fields, &str, end) || get_date_time_separator(&number_of_fields, flags, &str, end) || get_number(&l_time->hour, &number_of_fields, &str, end) || get_punct(&str, end) || get_number(&l_time->minute, &number_of_fields, &str, end) || get_punct(&str, end) || get_number(&l_time->second, &number_of_fields, &str, end))) status->warnings|= MYSQL_TIME_WARN_TRUNCATED; } /* we're ok if date part is correct. even if the rest is truncated */ if (number_of_fields < 3) { l_time->time_type= MYSQL_TIMESTAMP_NONE; status->warnings|= MYSQL_TIME_WARN_TRUNCATED; DBUG_RETURN(TRUE); } if (!status->warnings && str < end && *str == '.') { str++; get_microseconds(&l_time->second_part, status, &number_of_fields, &str, end); } not_zero_date = l_time->year || l_time->month || l_time->day || l_time->hour || l_time->minute || l_time->second || l_time->second_part; if (year_length == 2 && not_zero_date) l_time->year+= (l_time->year < YY_PART_YEAR ? 2000 : 1900); if (l_time->year > 9999 || l_time->month > 12 || l_time->day > 31 || l_time->hour > 23 || l_time->minute > 59 || l_time->second > 59) { status->warnings|= MYSQL_TIME_WARN_TRUNCATED; goto err; } if (check_date(l_time, not_zero_date, flags, &status->warnings)) goto err; l_time->time_type= (number_of_fields <= 3 ? MYSQL_TIMESTAMP_DATE : MYSQL_TIMESTAMP_DATETIME); for (; str != end ; str++) { if (!my_isspace(&my_charset_latin1,*str)) { status->warnings= MYSQL_TIME_WARN_TRUNCATED; break; } } DBUG_RETURN(FALSE); err: bzero((char*) l_time, sizeof(*l_time)); l_time->time_type= MYSQL_TIMESTAMP_ERROR; DBUG_RETURN(TRUE); }
void sc_snap_name_validate(const char *snap_name, struct sc_error **errorp) { struct sc_error *err = NULL; // Ensure that name is not NULL if (snap_name == NULL) { err = sc_error_init(SC_SNAP_DOMAIN, SC_SNAP_INVALID_NAME, "snap name cannot be NULL"); goto out; } // This is a regexp-free routine hand-codes the following pattern: // // "^([a-z0-9]+-?)*[a-z](-?[a-z0-9])*$" // // The only motivation for not using regular expressions is so that we // don't run untrusted input against a potentially complex regular // expression engine. const char *p = snap_name; if (skip_one_char(&p, '-')) { err = sc_error_init(SC_SNAP_DOMAIN, SC_SNAP_INVALID_NAME, "snap name cannot start with a dash"); goto out; } bool got_letter = false; for (; *p != '\0';) { if (skip_lowercase_letters(&p) > 0) { got_letter = true; continue; } if (skip_digits(&p) > 0) { continue; } if (skip_one_char(&p, '-') > 0) { if (*p == '\0') { err = sc_error_init(SC_SNAP_DOMAIN, SC_SNAP_INVALID_NAME, "snap name cannot end with a dash"); goto out; } if (skip_one_char(&p, '-') > 0) { err = sc_error_init(SC_SNAP_DOMAIN, SC_SNAP_INVALID_NAME, "snap name cannot contain two consecutive dashes"); goto out; } continue; } err = sc_error_init(SC_SNAP_DOMAIN, SC_SNAP_INVALID_NAME, "snap name must use lower case letters, digits or dashes"); goto out; } if (!got_letter) { err = sc_error_init(SC_SNAP_DOMAIN, SC_SNAP_INVALID_NAME, "snap name must contain at least one letter"); } out: sc_error_forward(errorp, err); }