Encode a UUID value (OID 2950) Binary format is 16 bytes raw UUID
(uuid_str: &str)
| 75 | /// Encode a UUID value (OID 2950) |
| 76 | /// Binary format is 16 bytes raw UUID |
| 77 | pub fn encode_uuid(uuid_str: &str) -> Result<Vec<u8>, PgSqliteError> { |
| 78 | // Input validation |
| 79 | if uuid_str.len() > 128 { |
| 80 | return Err(PgSqliteError::InvalidParameter("UUID string too long".to_string())); |
| 81 | } |
| 82 | |
| 83 | // Remove hyphens and validate format |
| 84 | let hex_str = uuid_str.replace('-', ""); |
| 85 | if hex_str.len() != 32 { |
| 86 | return Err(PgSqliteError::InvalidParameter("Invalid UUID format: must be 32 hex characters".to_string())); |
| 87 | } |
| 88 | |
| 89 | // Validate all characters are hex before processing |
| 90 | if !hex_str.chars().all(|c| c.is_ascii_hexdigit()) { |
| 91 | return Err(PgSqliteError::InvalidParameter("Invalid UUID: contains non-hex characters".to_string())); |
| 92 | } |
| 93 | |
| 94 | // Convert hex string to bytes with bounds checking |
| 95 | let mut bytes = Vec::with_capacity(16); |
| 96 | let hex_chars: Vec<char> = hex_str.chars().collect(); |
| 97 | |
| 98 | for i in (0..32).step_by(2) { |
| 99 | // Safe indexing - we've validated length is exactly 32 |
| 100 | let hex_pair: String = [hex_chars[i], hex_chars[i + 1]].iter().collect(); |
| 101 | let byte = u8::from_str_radix(&hex_pair, 16) |
| 102 | .map_err(|_| PgSqliteError::InvalidParameter("Invalid UUID hex characters".to_string()))?; |
| 103 | bytes.push(byte); |
| 104 | } |
| 105 | |
| 106 | Ok(bytes) |
| 107 | } |
| 108 | |
| 109 | /// Validate JSON string depth and structure |
| 110 | fn validate_json_security(json_str: &str) -> Result<(), PgSqliteError> { |