Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Txt long values #23

Merged
merged 5 commits into from
Sep 25, 2023
Merged

Txt long values #23

merged 5 commits into from
Sep 25, 2023

Conversation

Nuhvi
Copy link
Contributor

@Nuhvi Nuhvi commented Sep 22, 2023

closes #22

Two changes:

  1. create TXT from a long string, and convert TXT into a String.
  2. txt.attributes() operates on the entire value, and respects ; seperators.

@@ -25,8 +25,10 @@ impl<'a> CharacterString<'a> {
if data.len() > MAX_CHARACTER_STRING_LENGTH {
return Err(SimpleDnsError::InvalidCharacterString);
}

Ok(Self { data })
match String::from_utf8(data.clone().into_owned()) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check for valid utf-8 (and add a test for it), to be able to unwrap at line 44 safely.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this check can't be used here, because a character string is not necessarily valid utf-8. If you check this section of the RFC-1035, it says that character string must be treated as binary data.

Since this library can receive records from other libraries, the safest place to check for a valid utf8 string is in the ''Into String" function, because it wouldn't impose valid utf8 when using the library to interface with something else.

@balliegojr
Copy link
Owner

Thank you very much for the PR.

I have added some suggestions and comments regarding compatibility.

BTW, sorry for taking this long to reply, I've missed the email and only saw it today

@@ -25,8 +25,10 @@ impl<'a> CharacterString<'a> {
if data.len() > MAX_CHARACTER_STRING_LENGTH {
return Err(SimpleDnsError::InvalidCharacterString);
}

Ok(Self { data })
match String::from_utf8(data.clone().into_owned()) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this check can't be used here, because a character string is not necessarily valid utf-8. If you check this section of the RFC-1035, it says that character string must be treated as binary data.

Since this library can receive records from other libraries, the safest place to check for a valid utf8 string is in the ''Into String" function, because it wouldn't impose valid utf8 when using the library to interface with something else.

},
None => continue,
};
let full_string: String = (*self).clone().into();
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it is better to create a new function, maybe long_attributes, rather than changing the existing functionality, because there may be people relying on the current behavior

Comment on lines 118 to 138
impl<'a> TryFrom<String> for TXT<'a> {
type Error = crate::SimpleDnsError;

fn try_from(value: String) -> Result<Self, Self::Error> {
let mut txt = TXT::new();

let mut start_index = 0;
let full_length = value.len();

while start_index < full_length {
let end_index = (start_index + MAX_CHARACTER_STRING_LENGTH).min(full_length);

let slice = &value[start_index..end_index];
txt.add_char_string(slice.to_string().try_into()?);

start_index = end_index;
}

Ok(txt)
}
}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be simplified if you implement for &str, and it would also avoid cloning the data

Suggested change
impl<'a> TryFrom<String> for TXT<'a> {
type Error = crate::SimpleDnsError;
fn try_from(value: String) -> Result<Self, Self::Error> {
let mut txt = TXT::new();
let mut start_index = 0;
let full_length = value.len();
while start_index < full_length {
let end_index = (start_index + MAX_CHARACTER_STRING_LENGTH).min(full_length);
let slice = &value[start_index..end_index];
txt.add_char_string(slice.to_string().try_into()?);
start_index = end_index;
}
Ok(txt)
}
}
impl<'a> TryFrom<&'a str> for TXT<'a> {
type Error = crate::SimpleDnsError;
fn try_from(value: &'a str) -> Result<Self, Self::Error> {
let mut txt = TXT::new();
for v in value.as_bytes().chunks(MAX_CHARACTER_STRING_LENGTH) {
txt.add_char_string(CharacterString::new(v)?);
}
Ok(txt)
}
}

Comment on lines 140 to 148
impl<'a> From<TXT<'a>> for String {
fn from(val: TXT<'a>) -> Self {
val.strings
.into_iter()
.map(|s| s.into())
.collect::<Vec<String>>()
.join("")
}
}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here would be the proper place to check for a valid utf8 string, something like this

Suggested change
impl<'a> From<TXT<'a>> for String {
fn from(val: TXT<'a>) -> Self {
val.strings
.into_iter()
.map(|s| s.into())
.collect::<Vec<String>>()
.join("")
}
}
impl<'a> TryFrom<TXT<'a>> for String {
type Error = std::string::FromUtf8Error;
fn try_from(val: TXT<'a>) -> Result<Self, Self::Error> {
let bytes = val
.strings
.into_iter()
.fold(Vec::with_capacity(val.len()), |mut acc, val| {
acc.extend(val.data.as_ref());
acc
});
String::from_utf8(bytes)
}
}

@Nuhvi
Copy link
Contributor Author

Nuhvi commented Sep 25, 2023

@balliegojr Thanks for the feedback, learned a lot, and surprisingly managed to apply the suggested changes without much trouble or adding even more cloning :)

Comment on lines 39 to 44
impl<'a> From<CharacterString<'a>> for String {
fn from(val: CharacterString<'a>) -> Self {
String::from_utf8(val.data.into_owned()).unwrap()
}
}

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you change this to a TryFrom implementaiton? Since it can be called in a CharacterString that is not valid utf8

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@balliegojr balliegojr merged commit 7c0bcdc into balliegojr:main Sep 25, 2023
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

TXT into a continuous string
2 participants