HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Interesting (or boring :) bits

02-10-2003, 07:36 AM#1
magnus99
(1) A bug in Warcraft III's type checker only requires the type of the last return statement in a function to conform to the delcared type of the function. The previous return statements can return a value of any type, but using the value will probably just result in garbage. E.G., it will allow:
Code:
function foo takes nothing returns integer
     local unit u
     if true then
          return u
     else
          return 10
     endif
endfunction
In fact, the function GetFadeFromSeconds in Blizzard.j exhibits the error (returns a real when it should be an integer) and if it uses that control path it will return a garbage value.

(2) Bob Fitch from Blizzard pointed out that functions can be declared as constant (prefixed with the word "constant"). This enforces that no non-constant functions can be called from within the function's body. However, they never finished implementing the semantics (you can still call "set" in the body, so arguments can still be altered and it is not really constant in the traditional sense). But it may still be a nice hint.

A couple more tiny little things like this were added to my manual: http://jass.sourceforge.net/doc/. Unfortunately, he didn't mention anything else too interesting*, so I doubt there is stuff "hidden" in the language we don't know about.

Just wanted to note these things on the off chance that they might have affected anyone. :)

magnus

* Besides that he didn't have documentation for the native functions because he was basically the only person who wrote JASS code for AIs :(. Also, the reason I2S, R2S, etc. native functions in common.j don't work in AI's is because map and AI symbol namespaces ended up being shared during compilation but not during runtime (or something like that), so those functions don't really exist when running AI scripts. So lots of native functions that are usable in a map are not usable in an AI.
02-10-2003, 12:52 PM#2
Zalamander
That might explains why you syntax checker says no errors sometimes but still the AI makes war3 crash in FATAL ERROR or just behave like syntax error :/.

Have to make some research here.
02-10-2003, 05:41 PM#3
magnus99
Yeah, unfortunately there is no formal way to catch those runtime errors at compile time, unless I just take a list of known "bad" functions and prevent people from calling them which is pretty much a big hack. But you can still cause runtime errors with things like division by 0 and referencing a null handle.

magnus
02-10-2003, 07:49 PM#4
PitzerMike
I just read your JASS Tut magnus.
It's the best one I've ever read - you don't give wrong information like all the other Tutorials do.

Havn't tried your syntax checker yet but I guess it will be very useful for me espacially for AI Scripts:D
02-10-2003, 10:17 PM#5
AIAndy
The problem with the not working common.j functions seems to be a reference problem. You can access the map function namespace from AI, but when you reference code in the AI, that actually has another meaning in the map namespace and points on something else there. Thats why you can't use the functions that take code as parameter. The basic types like integer and real are passed by value so that does not happen there. But the same problem happens with returning strings but not with passing strings. Returning strings suddenly point to something else. Handle types like units seem to be referenced the same from map and AI, so they work properly.
02-12-2003, 08:57 PM#6
Extrarius
When casting a 'complex type' to an integer, what happens? It seems logical that since all the 'complex types' are implemented via pointers that the result would be that you can get a pointer into WC3 memory that points to the data for a unit. Since you can add integers easily in Jass, you could move the pointer around, and since you can then use the same 'hack' to cast it back to a pointer, you should be able to modify arbitrary memory. Sounds like a security hole, but besides that it also sounds like it might let you change unit properties you can't otherwise change in-game via jass, like maybe max HP or max Mana.

Has anybody played around with that?
02-12-2003, 10:05 PM#7
AIAndy
It would probably be difficult to find the correct memory point for doing that, unless it is always the same offset from the unit. But it would make many things possible.
02-13-2003, 06:00 AM#8
magnus99
Except that there is no way to dereference pointers in JASS; you can only pass them to some native functions. I suppose it is possible that you could still figure out a way to make it do something cool or wierd, but it is not as easy as, say, figuring out the hitpoints (or whatever) is located at (unit_pointer+4) because you can't say *(unit_pointer+4) = blah. Devising a security exploit would probably easier if the code is indeed interpreted natively (who knows; it could be byte-code compiled and interpreted by a VM; Bob didn't say :)).

But Bob did say they would probably get this fixed by the Expansion, so there wouldn't be much time to have fun with it anyway (well... ok, maybe several months to a year, considering :).

magnus
02-13-2003, 09:40 PM#9
AIAndy
If handles are a kind of pointer and unit handles therefore point to the memory where the unit is stored then writing mana or life of a unit is a kind of way to dereference a pointer. Some of the behaviour of arrays seems near to native. There do not seem to be many checks involved.
02-14-2003, 03:30 PM#10
Extrarius
I'll have to play with it when I get home today. As magnus99 said, you can't directly dereference pointers, but you can set hitpoints which has to do so (something like *(unit pointer+x) = hp where x is the offset of the current hp in the unit struct/class). Since you don't really need to know the address itself anyways but just be able to move it around, it should be possible to find maxhp, especially since most programmers group variables by function in classes (so it should be +- a small multiple of 4 from currenthp to max). The only real problem would be virtual functions if they did a good heirarchial OO design.
If they do fix it, they should add more native functions =-)
02-15-2003, 12:30 AM#11
Extrarius
Or not - that function you showed at the top has an error (well, I modified it to take a unit instead of having a local one so it wasn't exactly the same, but very close). Seems they fixed it already =-/
02-15-2003, 05:41 PM#12
AIAndy
Did you use the right type in the last return ?
Is there a new Blizzard.j then that fixes the mentioned function ?
02-15-2003, 10:42 PM#13
magnus99
You're right. Try these instead:
Code:
function foo takes unit u returns integer
     if true then
          return u
     endif
     return 10
endfunction

function bar takes integer i returns unit
     if true then
          return i
     endif
     return null
endfunction

They worked for me.
08-12-2004, 02:32 PM#14
PitzerMike
Last weekend I played around a bit with JASS strings and here are the most intersting bits I found (I guess most are common knowledge):

STRINGS
  • All characters are allowed except null characters and escape characters in some cases
  • Through hex editing you can add whichever character you want (even below ascii value 32)
  • A null character however will indicate the end of the file even within the string qotes, carriage returns however can be placed within strings without resulting in a line break
  • The escape character ("\") is only valid before these characters: b, f, t, n, r, \, "
  • Meaning of the combinations:
    \b, \f, \t -> no apparent meaning, just removes the b, f, t from the string
    \n, \r -> line break
    \" -> to use the " character in strings ("to use these \"quotes\" within a string")
    \\ -> to use the \ character in strings
  • If the escape character is not followed by one of the above mentioned characters you will get a compile error
  • Escape character combinations count as 1 character of course (StringLength("a\\b") = 3)
  • The % character is weird (can be used and will be displayed on the screen but StringLength("a%") = 1)
  • What we all know: We can use |cAARRGGBBText|r tags to color our strings (AA = alpha, RR = red, GG = green, BB = blue, |c = open tag, |r = close tag)
  • There are no other tags to format strings
  • ExecuteFunc also works with functions that have a return value, just like when you call the function the return value will be omitted

INTEGER LITERALS ('AHbz')
  • All characters are allowed except null characters and escape characters (\)
  • Through hex editing you can add whichever character you want, null characters and carriage returns are treaten like in strings
  • The only valid lengths are 1 or 4 characters
  • The \ character can't be used and the ' character can't be used because it closes the literal
08-12-2004, 10:47 PM#15
weaaddar
I was pretty sure I've done 'FF' without a hitch but anyway..>WHY DID YOU REVIVE AN OVER A YEAR OLD THREAD!?
I mean Pitzermike what the hell!?