{"action":"created","issue":{"url":"https://api.github.com/repos/arduino/Arduino/issues/3096","labels_url":"https://api.github.com/repos/arduino/Arduino/issues/3096/labels{/name}","comments_url":"https://api.github.com/repos/arduino/Arduino/issues/3096/comments","events_url":"https://api.github.com/repos/arduino/Arduino/issues/3096/events","html_url":"https://github.com/arduino/Arduino/pull/3096","id":73959013,"number":3096,"title":"New feature: validate function for String class.","user":{"login":"Chris--A","id":6584350,"avatar_url":"https://avatars.githubusercontent.com/u/6584350?v=3","gravatar_id":"","url":"https://api.github.com/users/Chris--A","html_url":"https://github.com/Chris--A","followers_url":"https://api.github.com/users/Chris--A/followers","following_url":"https://api.github.com/users/Chris--A/following{/other_user}","gists_url":"https://api.github.com/users/Chris--A/gists{/gist_id}","starred_url":"https://api.github.com/users/Chris--A/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Chris--A/subscriptions","organizations_url":"https://api.github.com/users/Chris--A/orgs","repos_url":"https://api.github.com/users/Chris--A/repos","events_url":"https://api.github.com/users/Chris--A/events{/privacy}","received_events_url":"https://api.github.com/users/Chris--A/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/arduino/Arduino/labels/Architecture:%20AVR","name":"Architecture: AVR","color":"fbca04"},{"url":"https://api.github.com/repos/arduino/Arduino/labels/Architecture:%20SAM","name":"Architecture: SAM","color":"fbca04"},{"url":"https://api.github.com/repos/arduino/Arduino/labels/Component:%20Core","name":"Component: Core","color":"009800"}],"state":"open","locked":false,"assignee":{"login":"cmaglie","id":423515,"avatar_url":"https://avatars.githubusercontent.com/u/423515?v=3","gravatar_id":"","url":"https://api.github.com/users/cmaglie","html_url":"https://github.com/cmaglie","followers_url":"https://api.github.com/users/cmaglie/followers","following_url":"https://api.github.com/users/cmaglie/following{/other_user}","gists_url":"https://api.github.com/users/cmaglie/gists{/gist_id}","starred_url":"https://api.github.com/users/cmaglie/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cmaglie/subscriptions","organizations_url":"https://api.github.com/users/cmaglie/orgs","repos_url":"https://api.github.com/users/cmaglie/repos","events_url":"https://api.github.com/users/cmaglie/events{/privacy}","received_events_url":"https://api.github.com/users/cmaglie/received_events","type":"User","site_admin":false},"milestone":null,"comments":3,"created_at":"2015-05-07T11:59:02Z","updated_at":"2016-01-08T14:07:08Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/arduino/Arduino/pulls/3096","html_url":"https://github.com/arduino/Arduino/pull/3096","diff_url":"https://github.com/arduino/Arduino/pull/3096.diff","patch_url":"https://github.com/arduino/Arduino/pull/3096.patch"},"body":"As people can access the internal buffer using various provided methods: `str.c_str()`, `&str[0]` It gives reason to believe that someone will modify the string externally, or provide these pointers to functions that do. It makes sense as a user can reserve memory using `str.reserve()`, or simply overwrite existing data already in the pointer.\r\n\r\nOnce this happens the String can reflect incorrect values despite having valid data inside it.\r\n\r\nTake for example, someone buffering a string to receive data provided by some source external to the library.\r\n\r\n```Arduino\r\n  String result;\r\n  result.reserve( 32 ); //Buffer enough space for the String data.\r\n\r\n  I2C_EEPROM.get( address, result.c_str(), 32 );  //'get' the data directly into the String buffer.\r\n\r\n  Serial.print( result ); //Prints an empty string.\r\n```\r\nThis problem is solved with this PR:\r\n```Arduino\r\n  String result;\r\n  result.reserve( 32 ); //Buffer enough space for the String data.\r\n\r\n  I2C_EEPROM.get( address, result.c_str(), 32 );  //'get' the data directly into the String buffer.\r\n\r\n  result.validate(); // Allow the String to detect the changed data.\r\n\r\n  Serial.print( result ); //The internal 'len' is now correct, and data is printed.\r\n```\r\n\r\nThe function simply searches for the null character. There is one parameter called `remainder` which if set to:\r\n- `true`: the function only searches the unused buffer (capacity - len).\r\n- `false`: the entire buffer is re-validated.\r\n\r\nThe default is to validate the entire buffer.\r\n\r\nThis seems important as the Print library uses the string's internal data to determine length, not the actual null character. If someone was to simply cut a string in half (`str[5] = '\\0';) then functions using the null will perform differently to what is seen in debugging (may hinder debugging as Serial.print() is affected)."},"comment":{"url":"https://api.github.com/repos/arduino/Arduino/issues/comments/170012234","html_url":"https://github.com/arduino/Arduino/pull/3096#issuecomment-170012234","issue_url":"https://api.github.com/repos/arduino/Arduino/issues/3096","id":170012234,"user":{"login":"matthijskooijman","id":194491,"avatar_url":"https://avatars.githubusercontent.com/u/194491?v=3","gravatar_id":"","url":"https://api.github.com/users/matthijskooijman","html_url":"https://github.com/matthijskooijman","followers_url":"https://api.github.com/users/matthijskooijman/followers","following_url":"https://api.github.com/users/matthijskooijman/following{/other_user}","gists_url":"https://api.github.com/users/matthijskooijman/gists{/gist_id}","starred_url":"https://api.github.com/users/matthijskooijman/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/matthijskooijman/subscriptions","organizations_url":"https://api.github.com/users/matthijskooijman/orgs","repos_url":"https://api.github.com/users/matthijskooijman/repos","events_url":"https://api.github.com/users/matthijskooijman/events{/privacy}","received_events_url":"https://api.github.com/users/matthijskooijman/received_events","type":"User","site_admin":false},"created_at":"2016-01-08T14:07:08Z","updated_at":"2016-01-08T14:07:08Z","body":"@cmaglie, that's correct, but simply doing `(char*)s.c_str()` will circumvent that limitation by removing the constness. Also, I suspect that there are other ways to get embedded nul characters, like `s.setCharAt(idx, 0)` (didn't check if this is allowed, though).\r\n\r\nSo, I can see that this new method can be useful in some cases (though probably only in unusual cases, that touch the edges of the String object interface), but I still do not believe `validate()` is the right name for it."}}