digitalmars.D.learn - Obsecure problem 1
- pascal111 (62/62) Jul 30 2022 I've typed a code to enjoy with my library "dcollect", and found
- rikki cattermole (29/29) Jul 30 2022 It is a pretty straight forward.
- pascal111 (8/38) Jul 30 2022 Your suggestion works. It seems a problem with that "for" loop,
- Salih Dincer (7/9) Jul 30 2022 I have a suggestion for you. Use modern possibilities instead of
- pascal111 (11/21) Jul 30 2022 I'm trying, really, to understand modern D features, but I'm from
- pascal111 (2/2) Jul 30 2022 Another version of the program:
- Salih Dincer (50/52) Jul 31 2022 I have a few more suggestions for you; Among them the first is on
- FeepingCreature (5/9) Jul 31 2022 Note sure if I'm misunderstanding, but: D does not copy strings
- Salih Dincer (48/52) Jul 31 2022 You got it right, but I didn't explain it right. I think you are
- pascal111 (9/64) Jul 31 2022 I don't know how "assert" works, if you explained it I'll be able
- Salih Dincer (40/47) Jul 31 2022 **// This code runs forever:**
- pascal111 (3/32) Jul 31 2022 You got the attention by the good understanding of D grammar. I
- frame (8/25) Jul 30 2022 I don't know if's "better" but there is Visual Studio Code and
- frame (7/11) Jul 30 2022 Why you don't copy the output instead?
I've typed a code to enjoy with my library "dcollect", and found non-understandable error: module main; import std.stdio; import dcollect; import std.string; import std.conv; int main(string[] args) { string sentence_x, sent_result, token2; string[] sentence_tokens; writeln(strstring(5,"*")," No tail \"s\" ",strstring(5,"*")); writeln; write("Compose a line: "); sentence_x=strip(readln()); sentence_tokens=sentence_x.d_strtok(" ,;.:!?\"'"); foreach(token; sentence_tokens){ token2=token.strrtrim; if(token2[token2.length-1]=='s') token2=strdel(token2, token2.length-1,1); sent_result~=token2~" ";} sent_result.writeln; return 0; } dcollect library: https://github.com/pascal111-fra/D/blob/main/dcollect.d I changed some data types of some functions parameters to "ulong": string strdel(const string ch, ulong x, ulong l ) { string l_ch=ch.strleft(x); string r_ch=ch.strright(ch.length-(x+l)); return (l_ch~=r_ch); } string strleft(const string ch, ulong n) { string ch_sub; ch_sub=ch[0..n]; return ch_sub; } /************************************/ string strreverse(const string ch) { string ch_rev; for(ulong i=ch.length-1; i>=0; i--) ch_rev~=ch[i]; return ch_rev; } /*********************************************/ string strright(const string ch, ulong n) { string ch_sub1, ch_sub2; ch_sub1=strreverse(ch); ch_sub2=strleft(ch_sub1, n); ch_sub1=strreverse(ch_sub2); return ch_sub1; } ==================== Running screen says: https://i.postimg.cc/G3YyCmbF/Screenshot-from-2022-07-30-23-23-59.png
Jul 30 2022
It is a pretty straight forward. You tried to access memory out of bounds of the slice. https://github.com/pascal111-fra/D/blob/main/dcollect.d#L34 That for loop is problematic in a number of ways. You should not use int, or uint to index into memory, only size_t should be used. It is an alias to either uint or ulong based upon the size of a pointer. ```d for(size_t i = ch.length - 1; i >= 0; i--) ``` Would be the corrected line. However, it is still not correct, what happens when ch.length is zero? It'll wrap around and become a very large number. That is most likely what happened here. To do this safely in D, use the foreach_reverse statement instead. There are very few reasons to use for loops in D. https://dlang.org/spec/statement.html#foreach-range-statement Adjusted: ```d foreach_reverse(i; 0 .. ch.length) ``` However this is not efficient as you are reallocating constantly. ```d char[] ch_rev; ch_rev.length = ch.length; size_t offset; foreach_reverse(c; ch) ch_rev[offset++] = c; ```
Jul 30 2022
On Saturday, 30 July 2022 at 21:48:35 UTC, rikki cattermole wrote:It is a pretty straight forward. You tried to access memory out of bounds of the slice. https://github.com/pascal111-fra/D/blob/main/dcollect.d#L34 That for loop is problematic in a number of ways. You should not use int, or uint to index into memory, only size_t should be used. It is an alias to either uint or ulong based upon the size of a pointer. ```d for(size_t i = ch.length - 1; i >= 0; i--) ``` Would be the corrected line. However, it is still not correct, what happens when ch.length is zero? It'll wrap around and become a very large number. That is most likely what happened here. To do this safely in D, use the foreach_reverse statement instead. There are very few reasons to use for loops in D. https://dlang.org/spec/statement.html#foreach-range-statement Adjusted: ```d foreach_reverse(i; 0 .. ch.length) ``` However this is not efficient as you are reallocating constantly. ```d char[] ch_rev; ch_rev.length = ch.length; size_t offset; foreach_reverse(c; ch) ch_rev[offset++] = c; ```Your suggestion works. It seems a problem with that "for" loop, but I don't know exactly from where it got a 0 or subtracted of 0. I changed data types of some parameters and for loops, and changed that for loop as you suggested: https://github.com/pascal111-fra/D/blob/main/dcollect.d The program works fine now: https://i.postimg.cc/3wkgXmVs/Screenshot-from-2022-07-31-00-04-23.png
Jul 30 2022
On Saturday, 30 July 2022 at 22:17:10 UTC, pascal111 wrote:The program works fine now: https://i.postimg.cc/3wkgXmVs/Screenshot-from-2022-07-31-00-04-23.pngI have a suggestion for you. Use modern possibilities instead of applying functions used in the past to the present. For example, in a world with UTF, ordinary string reversing can result in erroneous results. Also, please don't use pictures, use Markdown instead... SDB 79
Jul 30 2022
On Saturday, 30 July 2022 at 22:45:14 UTC, Salih Dincer wrote:On Saturday, 30 July 2022 at 22:17:10 UTC, pascal111 wrote:I'm trying, really, to understand modern D features, but I'm from old school, C pure programming and BASIC language, and such languages and styles. D as it's obvious to all of us is a multi-paradigm language and has so advanced features, even its references, I can't understand 'em well, it's 100% new modern language, but every time I'll learn a new feature of it for that I can't surround all of its techniques at once.The program works fine now: https://i.postimg.cc/3wkgXmVs/Screenshot-from-2022-07-31-00-04-23.pngI have a suggestion for you. Use modern possibilities instead of applying functions used in the past to the present. For example, in a world with UTF, ordinary string reversing can result in erroneous results.Also, please don't use pictures, use Markdown instead...Provide me a free solution better than code::blocks with available gdc compiler I found.SDB 79
Jul 30 2022
Another version of the program: https://github.com/pascal111-fra/D/blob/main/proj04.d
Jul 30 2022
On Sunday, 31 July 2022 at 00:58:47 UTC, pascal111 wrote:Another version of the program: https://github.com/pascal111-fra/D/blob/main/proj04.dI have a few more suggestions for you; Among them the first is on the following sample: ```d auto sentence_x = "she has six oxen"; auto noNeedTrim = sentence_x.d_strtok(" "); foreach(token; noNeedTrim) { //token = token.strrtrim; if(token.canFind("s")) { assert(token.length == 3); } else token.writeln; // oxen } ``` But if it's because of typos, it's ok. Lets continue... Why are you using const for strings? After all, they are protected by immutable. Moreover, since you do not use refs, copies are taken in every function and also you have created extra copy for results. ```d enum str = "five hundred twelve"; auto test = str.strltirim; assert(test == "five hundred twelve"); string strltrim(const string ch) { string ch_cpy=ch; while(ch_cpy.strleft(1)==" ") ch_cpy=ch_cpy.strdel(0,1); return ch_cpy; } ``` There are also nicer ways to delete spaces in a text. Have you ever tried using the default arguments and auto? ```d //string[] d_strtok(const string ch, const string delim) auto d_strtok(string ch, string delim = " ")//*/ { import std.functional : not; // [bonus] string[] tokens = ch. splitter!(c => delim.canFind(c)). filter!(not!empty).array; return tokens; } ``` Functions may optionally define default arguments. This avoids the tedious work of declaring redundant overloads. **[bonus]** And using selective imports where necessary is also a nice feature of D. SDB 79
Jul 31 2022
On Sunday, 31 July 2022 at 07:43:06 UTC, Salih Dincer wrote:Why are you using const for strings? After all, they are protected by immutable. Moreover, since you do not use refs, copies are taken in every function and also you have created extra copy for results.Note sure if I'm misunderstanding, but: D does not copy strings on value passing, because they're inherently reference types. You can think of a string (or any array) as a `struct { size_t length; T* ptr; }` combined with a bunch of syntax magic.
Jul 31 2022
On Sunday, 31 July 2022 at 14:52:03 UTC, FeepingCreature wrote:Note sure if I'm misunderstanding, but: D does not copy strings on value passing, because they're inherently reference types. You can think of a string (or any array) as a `struct { size_t length; T* ptr; }` combined with a bunch of syntax magic.You got it right, but I didn't explain it right. I think you are right. How could I forget! String is actually a struct, embedded in the language. For example, it has members like .dub, .ptr, capacity and .length (get/set). Of course we should get a copy with .dub to avoid side effects. But now that I've tested it, I haven't seen a problem with split() and sort() . Okay, yes sort() can have side effects, for example nums is affected by this. I also had to use to!(dchar[]) because of the UTF: ```d auto sortStr(string E)(string str) { import std.algorithm, std.conv; return str.to!(dchar[]).sort!E; } auto splitStr(string E)(string str) { import std.string; return str.split!string(E); } auto sortArray(T)(T[] arr) { import std.algorithm; return arr.sort; } void main() { import std.stdio : writeln; string test = "alphabet"; auto nums = [ 1, 9, 4, 0, 3 ]; test.sortStr!"a > b".writeln; assert(test == "alphabet"); test.splitStr!"a".writeln; assert(test == "alphabet"); test.sortStr!"a < b".writeln; assert(test == "alphabet"); nums.sortArray.writeln; assert(nums == [0, 1, 3, 4, 9]); } /* Prints: tplhebaa ["", "lph", "bet"] aabehlpt [0, 1, 3, 4, 9] */ ``` In conclusion, one has to be careful, but D is a reliable language. SDB 79
Jul 31 2022
On Sunday, 31 July 2022 at 07:43:06 UTC, Salih Dincer wrote:On Sunday, 31 July 2022 at 00:58:47 UTC, pascal111 wrote:I don't know how "assert" works, if you explained it I'll be able to get the idea of your suggestion to apply the appropriate changes on my code.Another version of the program: https://github.com/pascal111-fra/D/blob/main/proj04.dI have a few more suggestions for you; Among them the first is on the following sample: ```d auto sentence_x = "she has six oxen"; auto noNeedTrim = sentence_x.d_strtok(" "); foreach(token; noNeedTrim) { //token = token.strrtrim; if(token.canFind("s")) { assert(token.length == 3); } else token.writeln; // oxen } ```But if it's because of typos, it's ok. Lets continue...I think "typos" are mistakes of typing? I'm not sure.Why are you using const for strings? After all, they are protected by immutable. Moreover, since you do not use refs, copies are taken in every function and also you have created extra copy for results. ```d enum str = "five hundred twelve"; auto test = str.strltirim; assert(test == "five hundred twelve"); string strltrim(const string ch) { string ch_cpy=ch; while(ch_cpy.strleft(1)==" ") ch_cpy=ch_cpy.strdel(0,1); return ch_cpy; } ``` There are also nicer ways to delete spaces in a text. Have you ever tried using the default arguments and auto? ```d //string[] d_strtok(const string ch, const string delim) auto d_strtok(string ch, string delim = " ")//*/ { import std.functional : not; // [bonus] string[] tokens = ch. splitter!(c => delim.canFind(c)). filter!(not!empty).array; return tokens; } ``` Functions may optionally define default arguments. This avoids the tedious work of declaring redundant overloads. I think you are right, I'll add a default argument in "d_strtok". **[bonus]** And using selective imports where necessary is also a nice feature of D.Beginners are reading my library, so I have some limitations to provide 'em understood code, so if I'll apply a new D syntax, I'll explain it in a video before providing the beginners the code with the new syntax.SDB 79
Jul 31 2022
On Sunday, 31 July 2022 at 15:01:21 UTC, pascal111 wrote:I don't know how "assert" works, if you explained it I'll be able to get the idea of your suggestion to apply the appropriate changes on my code.**// This code runs forever:** ```d string str; assert(str is null); str = "test"; assert(str !is null); assert(str.length >= 1); str = ""; assert(str !is null); assert(str.length == 0); int count; assert(count == 0); // true assert(true); while(true) { // endless loop } ``` **// This code runs in a little bit:** ```d count = 100; //assert(count); /* or: assert(count > 1); //*/ while(--count) { } assert(count); // false and assert error ```Yes, typos == "mistakes of typing" for example: ```d void main() { import std.string : split; auto test = "I hav e a car s"; auto result = split!string(test, " "); // ["I", "hav", "e", "a", "car", "", "s"] auto tilly = result[2]; // extra character auto solecism = result[3]; // car is plural auto doubled = result[5]; // doubled separetor import std.stdio : writeln; writeln(tilly, solecism, doubled); } ``` SDB 79But if it's because of typos, it's ok. Lets continue...I think "typos" are mistakes of typing? I'm not sure.
Jul 31 2022
On Sunday, 31 July 2022 at 17:03:59 UTC, Salih Dincer wrote:On Sunday, 31 July 2022 at 15:01:21 UTC, pascal111 wrote:You got the attention by the good understanding of D grammar. I think I got the idea of "assert".I don't know how "assert" works, if you explained it I'll be able to get the idea of your suggestion to apply the appropriate changes on my code.**// This code runs forever:** ```d string str; assert(str is null); str = "test"; assert(str !is null); assert(str.length >= 1); str = ""; assert(str !is null); assert(str.length == 0); int count; assert(count == 0); // true assert(true); while(true) { // endless loop } ``` **// This code runs in a little bit:** ```d count = 100; //assert(count); /* or: assert(count > 1); //*/ while(--count) { } assert(count); // false and assert error ```SDB 79
Jul 31 2022
On Saturday, 30 July 2022 at 23:40:44 UTC, pascal111 wrote:Provide me a free solution better than code::blocks with available gdc compiler I found.I don't know if's "better" but there is Visual Studio Code and IntelliJ IDEA for example. Yeah ctrl+v doesn't work on XTERM, the middle mouse button should. I found this in the wild:SDB 79is super weird but in xterm you can copy just by selecting the text, the text is going to get copied to xwindows clipboard not to gnome one so ctrl+v or menus are not going to work for pasting you need to use the middle button of the mouse and in some windows shift+insert uses to work too. so: select the text in the terminal keep it open go to any text editor or the browser and press the middle button to paste if you are on a mac you can simulate the middle button pressing the touchpad with 3 fingers and if you have a 2 buttons mouse you can simulate the middle one pressing both at the same time. A probably more sane option would be to configure codeblocks to use gnome-terminal instead of xterm, in settings -> environment -> general settings you can change it but it seems to close as soon as you try to launch the appIf that doesn't work you have to try another keyboard layout or such configuration or bind the function to another key if your middle mouse button is not present or is not recognized properly.
Jul 30 2022
On Saturday, 30 July 2022 at 21:24:50 UTC, pascal111 wrote:I've typed a code to enjoy with my library "dcollect", and found non-understandable error:...Running screen says: https://i.postimg.cc/G3YyCmbF/Screenshot-from-2022-07-30-23-23-59.pngWhy you don't copy the output instead? A range violation is the safe error (if bound checking enabled) that is thrown if you access an index of a range or array that is out of bounds. You may try to access an index that is larger than elements in the array.
Jul 30 2022
On Saturday, 30 July 2022 at 21:52:42 UTC, frame wrote:On Saturday, 30 July 2022 at 21:24:50 UTC, pascal111 wrote:Because copying the running window contents is not allowed, I couldn't do it in Code::Blocks.I've typed a code to enjoy with my library "dcollect", and found non-understandable error:...Running screen says: https://i.postimg.cc/G3YyCmbF/Screenshot-from-2022-07-30-23-23-59.pngWhy you don't copy the output instead?A range violation is the safe error (if bound checking enabled) that is thrown if you access an index of a range or array that is out of bounds. You may try to access an index that is larger than elements in the array.I think you are right.
Jul 30 2022
On Saturday, 30 July 2022 at 22:13:55 UTC, pascal111 wrote:Because copying the running window contents is not allowed, I couldn't do it in Code::Blocks.Not allowed? o.O Did you try to select the text and insert it via middle mouse button in another window? Those terminals usually copy the text by selection automatically.
Jul 30 2022
On Saturday, 30 July 2022 at 22:28:52 UTC, frame wrote:On Saturday, 30 July 2022 at 22:13:55 UTC, pascal111 wrote:I tried what you said, and also ctrl+c doesn't work, nothing works, I can't copy the contents of this terminal.Now you have two choices, 1) I continue using pictures 2) I stop that and be unable to describe what's happening in the running time.Because copying the running window contents is not allowed, I couldn't do it in Code::Blocks.Not allowed? o.O Did you try to select the text and insert it via middle mouse button in another window? Those terminals usually copy the text by selection automatically.
Jul 30 2022