Open martin-marinov-securax opened 10 years ago
Yes, I've seen that right after posting, that's why I removed the comment
I was working on this myself. Here's what I got, a bit raw I think (need to try some IPv6 corner cases). Look out for silly pointer errors, I'm no expert in C++:
diff --git a/cassandra_statement.cpp b/cassandra_statement.cpp
index c433e81..19e4b30 100755
--- a/cassandra_statement.cpp
+++ b/cassandra_statement.cpp
@@ -243,6 +243,8 @@ static pdo_cassandra_type pdo_cassandra_get_cassandra_type(const std::string &ty
return PDO_CASSANDRA_TYPE_MAP;
if (!real_type.compare(0, 8, "ListType"))
return PDO_CASSANDRA_TYPE_LIST;
+ if (!real_type.compare("InetAddressType"))
+ return PDO_CASSANDRA_TYPE_INET;
return PDO_CASSANDRA_TYPE_UTF8;
}
/* }}} */
@@ -296,6 +298,56 @@ namespace StreamExtraction {
return x < 10 ? x + '0' : (x - 10) + 'a';
}
+ /**
+ * Evaluator: Inet (IPv4 or IPv6) extraction
+ */
+ zval *evaluate_inet(const unsigned char *binary, int size) {
+ zval *ret;
+ MAKE_STD_ZVAL(ret);
+ Z_TYPE_P(ret) = IS_STRING;
+ char *str;
+ switch (size) {
+ case 4: {
+ str = (char *) emalloc(16);
+ sprintf(str, "%d.%d.%d.%d", (int) binary[0], (int) binary[1], (int) binary[2], (int) binary[3]);
+ break;
+ }
+ default: {
+ unsigned short word = 0;
+ int empty_words = 0;
+ str = (char *) emalloc(40);
+ int writepos = 0;
+ char parsedword[5];
+ int parsedwordlen = 0;
+ for (int i = 0; i < size; i += 2) {
+ word = (i < (size - 1)) ? ((((unsigned short) binary[i]) << 8) + (unsigned short) binary[i + 1])
+ : (unsigned short) binary[i];
+ if (i && empty_words < 2) {
+ str[writepos++] = ':';
+ }
+ if (word) {
+ parsedwordlen = sprintf(parsedword, "%x", (unsigned int) word);
+ memcpy(str + writepos, parsedword, parsedwordlen);
+ writepos += parsedwordlen;
+ empty_words = 0;
+ }
+ else {
+ ++empty_words;
+ }
+ }
+ if (writepos < 2) {
+ str[writepos++] = ':';
+ }
+ str[writepos] = 0;
+ break;
+ }
+ }
+ Z_STRVAL_P(ret) = str;
+ Z_STRLEN_P(ret) = strlen(str);
+
+ return ret;
+ }
+
char *raw_uuid_to_str(const unsigned char *binary, int size) {
int size_str = size * 2 + 4;
@@ -425,6 +477,7 @@ namespace StreamExtraction {
m_evaluation_map[PDO_CASSANDRA_TYPE_BYTES] = 0;
m_evaluation_map[PDO_CASSANDRA_TYPE_ASCII] = evaluate_string;
m_evaluation_map[PDO_CASSANDRA_TYPE_UTF8] = evaluate_string;
+ m_evaluation_map[PDO_CASSANDRA_TYPE_INET] = evaluate_inet;
m_evaluation_map[PDO_CASSANDRA_TYPE_INTEGER] = evaluate_integer_type<int>;
m_evaluation_map[PDO_CASSANDRA_TYPE_LONG] = evaluate_integer_type<long>;
m_evaluation_map[PDO_CASSANDRA_TYPE_DECIMAL] = evaluate_decimal_type;
Issue: When you insert an IP address (php string) into a cassandra inet column and select it you get garbage.
My code: $ip = "127.0.0.1"; var_dump($ip); $stmt = $db->prepare("INSERT INTO test (id, ip) VALUES (1, :ip)"); $stmt->bindValue(':ip', $ip, \PDO::PARAM_STR); $stmt->execute();
Output: string(9) "127.0.0.1" array(1) { [0]=> array(2) { ["id"]=> int(1) ["ip"]=> string(4) "" } }
Table: CREATE TABLE test ( id int, ip inet, PRIMARY KEY ((id)) )
Workaround that worked for me: