Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Munkeymon
Aug 14, 2003

Motherfucker's got an
armor-piercing crowbar! Rigoddamndicu𝜆ous.




Yeah, none of that is a surprise if you read the spec. The fact that it will be a surprise for anyone coming from a decent language combined with the fact that JS is becoming the most popular language in the industry is the real horror.

quote:

code:
"a".repeat(Math.pow(2,32-2)).split("").length;
probably caused by String length, rather than anything, idk though

Yep. "Invalid string length" is what I'm getting out of Chrome (on OSX).

quote:

code:
"a".repeat(Math.pow(2,32)-5).split("").length;
crashes dev tools

That's a ~8.6 GB string, so it's probably blowing the per-process memory limit.

Adbot
ADBOT LOVES YOU

nielsm
Jun 1, 2009



hackbunny posted:

The scary/cool reason for this is that index 0 contains the length of the string
Yes that was the case in "classic" pascal, but Delphi added a different type also called "string" that was not a fixed buffer with length marker.
The "classic" Pascal-string type is a 256 byte buffer, where the first entry is an unsigned byte specifying the valid length of the buffer. You can also declare buffers shorter than that, but they still have the length marker byte.
The dynamic string type introduced in Delphi is actually called AnsiString, and is a pointer to a ref-counted CoW string object, that also contains length information. You can access the string bytes by array indexing, but not the length, and it's not a real class with member functions/methods.

hackbunny posted:

This is because Pascal is not a dynamic language and type information is lost at runtime

Again except for Delphi, which has some kind of magic for IDispatch COM classes (I believe), and some other magic to access controls on dynamically created TForm instances by the Name property assigned to the controls from code.
E.g. I believe this will work (written from memory, may not compile):
code:
var
  f: TForm;
  c: TControl;
begin
  f = TForm.Create(nil);
  c = TLabel.Create(f);
  c.Name = "Foo";
  f.Foo.Caption = "wtf";
end;
Delphi really does a lot of strange things, and probably has very little to do with ISO Pascal any longer, apart from some of the basic syntax.

canis minor
May 4, 2011

Munkeymon posted:

Yeah, none of that is a surprise if you read the spec. The fact that it will be a surprise for anyone coming from a decent language combined with the fact that JS is becoming the most popular language in the industry is the real horror.

Oh, I'm not surprised by any of this - JS has it's quirks; I was just continuing the array indexes theme.

Still, this is my favorite, this time from php - http://sandbox.onlinephpfunctions.com/code/87319d093bf5bd59d28cf9c876183ee5d6c40948

code:
<?php

$index = pow(2, 63);

$array = array();
$array[$index] = "f";

var_dump($array);

$array[$index - 10] = "g";
var_dump($array);

$array[$index + 10] = "h";
var_dump($array);

var_dump(intval($index-10), intval($index), intval($index+10));

quote:

array(1) {
[-9223372036854775808]=>
string(1) "f"
}
array(1) {
[-9223372036854775808]=>
string(1) "g"
}
array(1) {
[-9223372036854775808]=>
string(1) "h"
}
int(-9223372036854775808)
int(-9223372036854775808)
int(-9223372036854775808)

Whereas going with pow(2,64) will overflow and make the $index 0

On my local:

code:
<?php

$index = pow(2, 31);

$array = array();
$array[$index] = "f";

var_dump($array);

$array[$index - 10] = "g";
var_dump($array);

$array[$index + 10] = "h";
var_dump($array);

var_dump($index-10, $index, $index+10);

quote:

array(1) { [-2147483648]=> string(1) "f" }
array(2) { [-2147483648]=> string(1) "f" [2147483638]=> string(1) "g" }
array(3) { [-2147483648]=> string(1) "f" [2147483638]=> string(1) "g" [-2147483638]=> string(1) "h" }

float(2147483638) float(2147483648) float(2147483658)


type casting is a bitch

var_dump(intval($index-10), intval($index), intval($index+10));

int(2147483638) int(-2147483648) int(-2147483638)

canis minor fucked around with this message at 20:23 on Mar 31, 2016

Zopotantor
Feb 24, 2013

...und ist er drin dann lassen wir ihn niemals wieder raus...

Shinku ABOOKEN posted:

Name and shame.

The UK also has insane libel laws, so better not.

Obsurveyor
Jan 10, 2003

canis minor posted:



type casting is a bitch


Type casting isn't a bitch, PHP is just totally insane and always will be.

No Safe Word
Feb 26, 2005

PHP and JS are both cheating in this thread tbh

Amberskin
Dec 22, 2013

We come in peace! Legit!

TheresaJayne posted:

sounds bad,

I have had the bad jobs as well, there was one who basically said i cannot have any holiday even though i was entitled and had prebooked over 3 months previously and had moved it 3 times (hospital appointment for an eye operation to prevent me going blind)
because it didnt suit him. He said i could not have holiday but i could have unpaid time off instead - also i had to use all my holiday or lose it - and he wouldnt let me use it.

When he stood up in front of everyone in the company and called me a stupid F$^%^ing Cow, I was recording it on my phone and quit there and then.

He then refused to pay any outstanding holiday pay or wages owing. and he had a top notch lawyer so got away with it all.

Unionize.

Just saying...

JawnV6
Jul 4, 2004

So hot ...

Vanadium posted:

Strings can be longer than 65536 chars!
:raise:

nielsm posted:

The "classic" Pascal-string type is a 256 byte buffer, where the first entry is an unsigned byte specifying the valid length of the buffer. You can also declare buffers shorter than that, but they still have the length marker byte.
These are so much more useful than a \0 marker at the end.

Deep Dish Fuckfest
Sep 6, 2006

Advanced
Computer Touching


Toilet Rascal

hackbunny posted:

The scary/cool reason for this is that index 0 contains the length of the string

That's kinda similar to the way dynamically allocated arrays are implemented in most C++ compilers, really. Get a block of memory slightly larger than what you need, stick the number of elements in the array at the beginning, and return a pointer to the first array element to the user.

Sometimes I kinda wish that value was accessible to programmers, but since compilers are free to implement dynamically allocated arrays however they want it probably would have been more trouble than it's worth.

sarehu
Apr 20, 2007

(call/cc call/cc)
God I was about to write a whole stupid reply to this before realizing, yeah, delete[] has to work somehow.

Vanadium
Jan 8, 2005


Longer than 65535 chars I guesss :blush:

Simulated
Sep 28, 2001
Lowtax giveth, and Lowtax taketh away.
College Slice

YeOldeButchere posted:

That's kinda similar to the way dynamically allocated arrays are implemented in most C++ compilers, really. Get a block of memory slightly larger than what you need, stick the number of elements in the array at the beginning, and return a pointer to the first array element to the user.

Sometimes I kinda wish that value was accessible to programmers, but since compilers are free to implement dynamically allocated arrays however they want it probably would have been more trouble than it's worth.

Nope, even K&R C got this mind-numbingly stupidly wrong. Arrays should be prefixed with the length and return a pointer to the first element to the user. Bonus: arrays become first-class objects you can pass between functions, rather than decaying to pointers. sizeof() allows anyone to safely iterate a received array, dynamic or stack allocated. Everyone wins!

Instead we have decades of trivial buffer overflows and stack-smashing. Thanks guys.


edit: I'm aware of some of the objections, I just don't agree. I don't believe any of the performance wins are worth Blaster, Sasser, Slammer, Code Red, Heartbleed, and a continuously growing list of literally thousands of root-level exploits across a huge variety of systems.

Heartbleed was so bad it required every single human being on the planet to change their passwords and quite possibly exposed huge volumes of SSL traffic to snooping/spying. It may have literally lead to people's deaths as bad actors (or state security agencies) took advantage of it to track dissidents or "troublesome" people.

C could have had arrays/strings that were much safer by default. K&R made the wrong choice, and I'll stand by that statement any day of the week.

Simulated fucked around with this message at 23:17 on Apr 1, 2016

Internet Janitor
May 17, 2008

"That isn't the appropriate trash receptacle."
I've always assumed that C went with null-terminated strings because it lets you do in-place tokenization tricks and passing a pointer midway into a string without needing to reallocate anything makes writing recursive descent parsers very simple. They picked the representation that makes it easy to write a self-hosting compiler, and every other application paid the price.

Kazinsal
Dec 13, 2011

Internet Janitor posted:

I've always assumed that C went with null-terminated strings because it lets you do in-place tokenization tricks and passing a pointer midway into a string without needing to reallocate anything makes writing recursive descent parsers very simple. They picked the representation that makes it easy to write a self-hosting compiler, and every other application paid the price.

Yeah, a lot of design tricks were needed to bootstrap a self-hosting compiler for a portable language and an OS written in it on a machine that generally shipped with 24 kilobytes of RAM.

Deep Dish Fuckfest
Sep 6, 2006

Advanced
Computer Touching


Toilet Rascal

Ender.uNF posted:

Nope, even K&R C got this mind-numbingly stupidly wrong. Arrays should be prefixed with the length and return a pointer to the first element to the user. Bonus: arrays become first-class objects you can pass between functions, rather than decaying to pointers. sizeof() allows anyone to safely iterate a received array, dynamic or stack allocated. Everyone wins!

You'd still need to have some way to define arrays like the ones we have now. Say you're writing code that screws around with memory-mapped i/o (eg device driver), you don't want your array to try shoving some length value into what may very well be a control register or some unallocated page or who knows what else. Even simpler than that, just taking a sub-array from a given array now requires you to make a copy instead of just having a pointer to the first element of the sub-array with a length. That's kind of a big deal, and I'm pretty sure that anyone who writes numerical code would be very unhappy, among others.

I'm also going to assume that by "sizeof()" you mean "something like sizeof()", because having it deal with runtime type information instead of just compile time info like it does now would be unpleasant at best. sizeof returning compile-time constants is kind of useful.

b0lt
Apr 29, 2005

YeOldeButchere posted:

You'd still need to have some way to define arrays like the ones we have now. Say you're writing code that screws around with memory-mapped i/o (eg device driver), you don't want your array to try shoving some length value into what may very well be a control register or some unallocated page or who knows what else. Even simpler than that, just taking a sub-array from a given array now requires you to make a copy instead of just having a pointer to the first element of the sub-array with a length. That's kind of a big deal, and I'm pretty sure that anyone who writes numerical code would be very unhappy, among others.
Pointers could still exist in this scheme. You couldn't type pun a char pointer to a struct containing an array of stuff, but that's already littered with undefined behavior as it stands.

quote:

I'm also going to assume that by "sizeof()" you mean "something like sizeof()", because having it deal with runtime type information instead of just compile time info like it does now would be unpleasant at best. sizeof returning compile-time constants is kind of useful.

sizeof already does this. C99 isn't very pleasant. (tgmath also sucks)

Amberskin
Dec 22, 2013

We come in peace! Legit!

YeOldeButchere posted:

That's kinda similar to the way dynamically allocated arrays are implemented in most C++ compilers, really. Get a block of memory slightly larger than what you need, stick the number of elements in the array at the beginning, and return a pointer to the first array element to the user.

Sometimes I kinda wish that value was accessible to programmers, but since compilers are free to implement dynamically allocated arrays however they want it probably would have been more trouble than it's worth.

PL/I "Varying strings" are an array of chars, preceded by a 16-bit length word. That allow CHAR VAR up to 32.767 bytes (yep, for whatever reason the length word is signed). If you take a pointer to a CHAR VAR you get the address of the length prefix. That, combined with BASED storage allow the programmer to do all sorts of nasty things using varying strings. For instance, to use varying length records (remember old times operating systems had a notion of "record" beyond "arbitrary stream of bytes), overlaying a CHAR VAR with several different structures and manipulating the record length by hand

So I guess that's score one for Old Farts.

Zopotantor
Feb 24, 2013

...und ist er drin dann lassen wir ihn niemals wieder raus...

YeOldeButchere posted:

That's kinda similar to the way dynamically allocated arrays are implemented in most C++ compilers, really. Get a block of memory slightly larger than what you need, stick the number of elements in the array at the beginning, and return a pointer to the first array element to the user.

cfront on HP-UX used to do it differently. It stored the array size in a separately allocated block of memory, causing a slow memory leak when you deleted an array using the non-array delete operator. (This was ~25 years ago, I may not remember the details correctly.)

feedmegin
Jul 30, 2008

Zopotantor posted:

The UK also has insane libel laws, so better not.

Not that bad these days actually, check out https://en.wikipedia.org/wiki/Defamation_Act_2013

Similarly we no longer wear top hats, ride around in carriages or have 'pea soupers'! :wotwot:

Edit: that cfront implementation choice is exactly why delete[] exists as a separate thing in the first case, I believe.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

Ender.uNF posted:

Nope, even K&R C got this mind-numbingly stupidly wrong. Arrays should be prefixed with the length and return a pointer to the first element to the user. Bonus: arrays become first-class objects you can pass between functions, rather than decaying to pointers. sizeof() allows anyone to safely iterate a received array, dynamic or stack allocated. Everyone wins!

There are plenty of arguments to make against C arrays, but this is the stupidest idea.

Volte
Oct 4, 2004

woosh woosh

Ender.uNF posted:

Nope, even K&R C got this mind-numbingly stupidly wrong. Arrays should be prefixed with the length and return a pointer to the first element to the user. Bonus: arrays become first-class objects you can pass between functions, rather than decaying to pointers. sizeof() allows anyone to safely iterate a received array, dynamic or stack allocated. Everyone wins!

Instead we have decades of trivial buffer overflows and stack-smashing. Thanks guys.
Sounds like you want a language other than C. Not to mention you could trivially(?) create a structure that contains a size_t and a pointer that does exactly what you say. You'd need a bit of machinery to malloc/alloca your array up but if you want to be more memory-safe you can put in the effort and do it. If you want it to happen automatically, then you're barking up the wrong tree.

Deep Dish Fuckfest
Sep 6, 2006

Advanced
Computer Touching


Toilet Rascal

b0lt posted:

sizeof already does this. C99 isn't very pleasant. (tgmath also sucks)

I had no idea variable-length arrays were a thing that existed, and I think I liked it better that way.

McGlockenshire
Dec 16, 2005

GOLLOCKS!
This Perl 6 slide deck popped up on HN last night and I figured this thread would appreciate it.

Perl 6 looks like a lot of fun, but it also looks like it'll be even more write-once than ever before.

sarehu
Apr 20, 2007

(call/cc call/cc)
http://tpm2016.zoffix.com/#/40

# OUTPUT:
# 「250.42」
# sign => 「」
# digits => 「250」
# decimal => 「.42」
# digits => 「42」

More weeaboo than Ruby.

Edit: Christ, Something Awful.

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe

sarehu posted:

http://tpm2016.zoffix.com/#/40

# OUTPUT:
# 「250.42」
# sign => 「」
# digits => 「250」
# decimal => 「.42」
# digits => 「42」

More weeaboo than Ruby.

Edit: Christ, Something Awful.

lol

xzzy
Mar 5, 2009

Perl 6: hey I know, let's try to reclaim the title for more insane language from JS and PHP!

TooMuchAbstraction
Oct 14, 2012

I spent four years making
Waves of Steel
Hell yes I'm going to turn my avatar into an ad for it.
Fun Shoe

xzzy posted:

Perl 6: hey I know, let's try to reclaim the title for more insane language from JS and PHP!

Now, now, Perl mostly makes sense. It's just illegible and lets you do crazy things with it.

qntm
Jun 17, 2009
A language allowing you to do crazy things is one thing, but a language where "do the craziest things imaginable with these techniques, all the time" is the fundamental theme of every tutorial? That's where the reputation of insanity comes from. That's cultivating a culture of obfuscation even worse than Perl 5's.

Soricidus
Oct 21, 2010
freedom-hating statist shill
you can't really blame them for focusing on wacky features. they're constantly faced with the question "why should i come back to perl when i stopped caring about it 15 years ago", and "you can't write poo poo like this in whatever dull plang you use today, don't you wish you could write poo poo like this" is the answer they seem to have settled on.

CPColin
Sep 9, 2003

Big ol' smile.
I like the slide with the gears that can't possibly turn:

http://tpm2016.zoffix.com/#/43

Cuntpunch
Oct 3, 2003

A monkey in a long line of kings

sarehu posted:

http://tpm2016.zoffix.com/#/40

# OUTPUT:
# 「250.42」
# sign => 「」
# digits => 「250」
# decimal => 「.42」
# digits => 「42」

More weeaboo than Ruby.

Edit: Christ, Something Awful.

This looks a lot like Clojure's instaparse library for Context-Free Grammars. But with native language support?

Simulated
Sep 28, 2001
Lowtax giveth, and Lowtax taketh away.
College Slice

YeOldeButchere posted:

You'd still need to have some way to define arrays like the ones we have now. Say you're writing code that screws around with memory-mapped i/o (eg device driver), you don't want your array to try shoving some length value into what may very well be a control register or some unallocated page or who knows what else. Even simpler than that, just taking a sub-array from a given array now requires you to make a copy instead of just having a pointer to the first element of the sub-array with a length. That's kind of a big deal, and I'm pretty sure that anyone who writes numerical code would be very unhappy, among others.

I'm also going to assume that by "sizeof()" you mean "something like sizeof()", because having it deal with runtime type information instead of just compile time info like it does now would be unpleasant at best. sizeof returning compile-time constants is kind of useful.

That would only be true if you're storing a pointer to the subarray, otherwise the compiler can just pass the array as a pointer and add a hidden length parameter. The key there being you aren't relying on the programmer to get it right. You can bike shed the design all day but there are going to be tradeoffs. My point is that the tradeoffs would be worth it. How many billions of dollars in damages have happened due to buffer overflows? Maybe in the $trillions by now. Many, many, many RCE exploits (even ROPs) start with a simple buffer overflow.



rjmccall posted:

There are plenty of arguments to make against C arrays, but this is the stupidest idea.

Precondition: You're designing K&R C but you want to make avoiding buffer overflows easier and automatic for the common case. What do you do?



Volte posted:

Sounds like you want a language other than C. Not to mention you could trivially(?) create a structure that contains a size_t and a pointer that does exactly what you say. You'd need a bit of machinery to malloc/alloca your array up but if you want to be more memory-safe you can put in the effort and do it. If you want it to happen automatically, then you're barking up the wrong tree.

Anything that relies on humans to be less lazy and/or better programmers is destined to fail. C is worse in that it actively prevents you from designing any kind of tooling to enforce memory safety or opting-in to bounds-checked arrays even if you want to use them. Even if your own code chose to employ the solution you mention it's a non-starter because none of the libraries you rely on will adopt your bespoke array type. It wouldn't be so bad if you could just throw a compiler switch, accept a 20-30% performance hit, but know that it was almost impossible to smash the stack or run off the end of a buffer. We'd all add that flag and we'd scream at and look down on anyone who didn't because they'd be a moron to trade a small performance boost for such massive security risks except in certain limited situations (embedded micro controllers with 2k RAM for example).

My supposition is that C arrays are badly designed and actively promote security vulnerabilities while simultaneously closing off many potential mitigations even if a user of C wanted to opt in to them. So far I'm not hearing any arguments that C arrays are a good design, just that they have some performance advantages. So does running all code in Ring 0 without memory protection.

JawnV6
Jul 4, 2004

So hot ...

Ender.uNF posted:

It wouldn't be so bad if you could just throw a compiler switch, accept a 20-30% performance hit, but know that it was almost impossible to smash the stack or run off the end of a buffer. We'd all add that flag and we'd scream at and look down on anyone who didn't because they'd be a moron to trade a small performance boost for such massive security risks except in certain limited situations (embedded micro controllers with 2k RAM for example).

As much as I enjoy hearing my entire career exists in "limited situations," your compiler flag has existed for over a decade and strangely hasn't been baked into everything like you predicted.

canis minor
May 4, 2011

This is fun (again JS):

code:
for (var i=54; i<120; i++)
{
var a = Math.pow(2,i); console.log(i, a===a-Math.pow(2,i-54), a===a-(Math.pow(2,i-54)+1));
}

quote:

...
106 true false
107 true true
...

https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER

:raise:

canis minor fucked around with this message at 00:13 on Apr 2, 2016

Volguus
Mar 3, 2009
JS like JS. It's a language, it has its quirks and .. oh well, you learn to live with them. But the developers... that's the real WTF. The kids that run the npm showshit, the contributors, the lego "programmers" who write that horrifically wrong line of code that gets published without any oversight and gets used over and over again (because nobody knows any better), that's the real WTF.

And they call themselves developers. Full stack developers. They put that poo poo on the server-side where things like is_int or _is_array should have never been even questions, and yet they are. But .. I'm the old-fashioned one. Why are they even allowed anywhere close to a computer?

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

Ender.uNF posted:

Precondition: You're designing K&R C but you want to make avoiding buffer overflows easier and automatic for the common case. What do you do?

Have an array-ref type, including a dynamically-sized variant which can be dynamically constructed from a pointer and length, and have array l-values decay to that. Subscript only works on an array or array-ref, not a pointer. You can still take the address of an array element and get a pointer back.

The stupid part of your idea is just storing the length before the first element and thus preventing the builtin array support from being applied to an array not separately and specifically allocated by the programmer, not the concept of having bounds information available dynamically.

HappyHippo
Nov 19, 2003
Do you have an Air Miles Card?

canis minor posted:

This is fun (again JS):

code:
for (var i=54; i<120; i++)
{
var a = Math.pow(2,i); console.log(i, a===a-Math.pow(2,i-54), a===a-(Math.pow(2,i-54)+1));
}
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER

:raise:

Whats the problem here?

canis minor
May 4, 2011

HappyHippo posted:

Whats the problem here?

For example - 2^64 shouldn't equal (or be identical to) 2^64 - 2^10. I know that stems from how numbers are being stored, but if operations on large numbers can't be trusted, shouldn't there be an exception instead?

HappyHippo
Nov 19, 2003
Do you have an Air Miles Card?

canis minor posted:

For example - 2^64 shouldn't equal (or be identical to) 2^64 - 2^10. I know that stems from how numbers are being stored, but if operations on large numbers can't be trusted, shouldn't there be an exception instead?

Floating point errors can't be detected in that sense. Every time something is rounded there is a potential for an error like that and almost every operation results in rounding of some sort. So I don't know how you'd expect it to throw an exception.

Edit: Also this has basically nothing to do with Javascript

Adbot
ADBOT LOVES YOU

Munkeymon
Aug 14, 2003

Motherfucker's got an
armor-piercing crowbar! Rigoddamndicu𝜆ous.



These are the issues you run into when using https://en.wikipedia.org/wiki/IEEE_floating_point for numbers your ignorant users think are integers.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply