Sunday, December 7, 2008

FCKeditor is looking for 2 experienced JavaScript developers in Hong Kong and China

I've posted this to quite a few places so far, but got no responses. Most probably due to the rather specific and high requirements. So, here's the job, we have two vacancies for people in Hong Kong or greater China:

CompanyFCKeditor
Job TitleAdvanced JavaScript Developer
TypeFull Time, Remote Work
RequirementsBasic requirements:
  • Experience in JavaScript programming (e.g. knowledge of object oriented and functional programming styles in JavaScript);
  • In-depth knowledge of basic web standards, like XHTML, CSS and DOM, including their intrinsic implementation differences among browsers;
  • Fluent in spoken and written English.
Good to have (but not strictly required):
  • Server side programming experience with Java and Ruby on Rails;
  • Experience with FCKeditor;
  • A Bachelor's or Master's degree in Computer Science (or related subjects);
  • Knowledge of open source, and eventually love it :)
Benefits
  • Work at home - no need to spend time commuting each day;
  • 5-day work week and paid annual leaves;
  • Can enjoy Hong Kong (or China) general public holidays;
  • Excellent exposure to the international information technology industry.
SalaryDepends on ability and experience.
20k+ HKD per month for experienced JavaScript programmers.

So there you have it. It's a really good opportunity for the enterprising geeks to break out of the local tech job market.

If you're interested in the job, please send an email with your CV to jobs@fckeditor.net and cc a copy to martin@fckeditor.net. If you'd like to talk with me before applying, my Skype id is martin_kou. If you're currently studying in or working in HKUST, I can even come to meet you in person.

Friday, October 3, 2008

The irony of it all

Not only do computers screw up trying to understand human language - whoever wrote this transcript to the lecture also screwed up a little bit... or maybe he's too much into graph theory.

Friday, September 19, 2008

Yet another boost to JavaScript execution performance - Squirrelfish Extreme


In the past month we've had Mozilla's Tracemonkey and Google Chrome's V8. Today the WebKit team joined the fight with Squirrelfish Extreme, and this fish packs quite a punch.

According to the benchmarks done by Charles Ying, Squirrelfish Extreme is currently the fastest JavaScript engine out there - 54% faster than Tracemonkey and 36% faster than V8 in the SunSpider benchmark.

Not a single word about fast JavaScript engines was mentioned on IEBlog. It seems IE8 is going to hold back the world of web applications for another few years, unfortunately.

Wednesday, September 10, 2008

BarCampHK 2008


Images from laihiu's Flickr

Amazing.

It was my second time to a tech conference and the first time I spoke in a session, and quite a few people actually came in and listened to me. Seeing how well the others were doing in other sessions, my presentation skills could definitely use some improvement. Still, I was really happy to see a few audience members have already tried FCKeditor in Drupal and found it to be stable.

I also met quite a few old friends in the conference - my former FYP advisor Dr. Dekai Wu; Yusuf from Outblaze (I had a really hard time telling he was talking about Tracemonkey/Firefox3.1 and FCKeditor to me though, apparently I had a buzzword overflow problem in my brain); Edwin Chu (from secondary school) who's founding a startup right now; Eric Tang (also from my secondary school) who founded HKSUA. It seems my secondary school, QES has been making quite a few tech entrepreneurs in these years, and one of them (Dr. Alan Tam) is already quite successful. Did that entrepreneurship spirit form because... we didn't hand in our homeworks? :P

The other sessions I attended were:
  1. Design UI from Anobii
    Anobii's speaker advocated that UI design should be started from hand-coding the HTML, and discouraged the audience from starting web UI design from Photoshop or Dreamweaver's WYSIWYG interface. Dreamweaver's WYSIWYG part sucks of course. But Photoshop? His reason was... not everything you can realize in Photoshop can be realized in HTML/JS/CSS as well. So, if you have a graphics designer working the UI from Photoshop first and then hand it to the web developers, you'll inevitably need a lot of "reconciling" between the web developers and the graphics designers in the form of meetings, arguments, infightings, smashed keyboards... and thus, wasted time.

    I have a counter argument to his point, though. No matter how you put it, it is still much easier to create and visualize a beautiful UI layout in Photoshop than in HTML/CSS. e.g. it is much easier to create and adjust a drop shadow, or a border around a round button, in Photoshop. So, I'd wager that there's good possibility that someone who started from hand coded HTML/CSS would need extra time to fine tune his layout after he coded his initial revision. A Photoshopper who already has experience in HTML/JS/CSS, however, would be able to draw and fine tune his layout easily, while making sure that it can be implemented.

    The difficulty in my scenario, would be finding the Photoshopper who's skilled in HTML/JS/CSS (or, just HTML/CSS) as well. But you don't really need a Photoshop expert to draw up a good looking UI.

  2. Technology Yesterday "Relevance"
    Images from 黛's Flickr

    A surprisingly good presentation from a psychologist. The speaker didn't spend much time talking about old technology actually. The whole session was more like a discussion forum on information technology's effect on the society, and its effects to the younger generations (i.e. Gen-Y-ers and the generation after Gen-Y-ers) who grew up with computers.

    I can imagine the recent victory of LSD (League of Social Democrats) would be a hot topic in such a forum - had it been hosted two days later - seeing the LSD is currently being supported by a lot of young Internet users. The victory of the LSD is a formal announcement to the importance of the Internet in Hong Kong's political arena - most of the promotions for the LSD were done on the Internet, via Yuk Man's YouTube videos or MyRadio.com.hk. Most of the time Yuk Man didn't even have to take part in such promotions - he spoke something interesting somewhere, one of his audience members recorded down a video of him and uploaded that to YouTube. And, bang! A lot of people saw Yuk Man's speech and rebuttals and were blown away by his impressive oratory skills. A textbook example of how viral marketing works.

    A lot of interesting Internet-based promotions in the next Legco election (2012) can be expected, I think. Those who refuse to face reality and adapt, will lose the election game, sooner or later.

  3. Converging Desktop and Web Application
    This is again, a discussion forum. Topics included the usual suspects - Google Chrome, WorkerPool API in Google Gears, JIT JavaScript engines, client side storage via DOM Storage API or SQLite, Flash and Silverlight, etc. I was quite surprised by the technical know-how of the audience there. But other than that, no surprises.

  4. Open Source + Microsoft

    The topic sounded interesting but I sat so far back in the conference room I couldn't tell what Microsoft's speaker was talking about most of the time. I could hear his point about why Microsoft is entering the open source scene though - there's money to be earned in open source software, entering the scene is just good business practice. There's no conspiracy, and thus open sourcers shouldn't be suspicious of Microsoft's motives.

    Well, but that's not gonna change my attitude towards Microsoft. How about fixing IE's standards support to begin with - not just XHTML and CSS, but also ECMAScript (aka JavaScript, e.g. where is Array::lastIndexOf() in IE?!), DOM Selection, DOM Range, XPath, DOM Parser, <canvas>, SVG, MathML, etc. Client side programming in IE sucks so much right now it's like programming with one hand tied to the back of your chair while your other hand has two fingers chopped off. I don't really hate everything that is closed source you know... I don't hate Opera for example. The thing that ticks me off with Microsoft isn't closed source, but incompetence.

  5. Drupal
    I didn't attend the whole session because I spent some time talking to Dekai about MathML and FCKeditor after my session. The presenter is a really friendly guy though, and they founded a local Drupal user group right after the session.
Need to sleep now. I'll talk about my session tomorrow or this weekend.

My opinion piece on web browsers in PC Market HK


The original piece I submitted bashed IE a lot. But the IE bashing was edited out, probably because it was too sensitive for a mainstream computer magazine. The final result looks pretty ok, still.

Sunday, August 24, 2008

Real time image editing in JavaScript, with Firefox 3.1

"JavaScript? That little glue language written by Netscape to try to glue HTML with Java? What a pathetic excuse of a language! It failed its original mission, couldn't deliver 5% of the features of Java, nor 5% of the performance of Java! It's a semi-Java, a quasi-Java, it's the instant coffee of Java, the decaf version of Java, 1mg only, not enough caffeine."

Young JavaScript programmer playing Scott Evil, "But look, Dad! I'm running a freakin' real time image editing application in a freakin' web browser! With JavaScript!"

Look! Really!

p.s. I know full well that describing JavaScript as a light weight version of Java is completely wrong.

p.p.s. Here's the demo author's blog entry about the demo, with source code. And yes, the demo DID calculate the colors of the image pixel-by-pixel.

p.p.p.s. The demo runs under Opera 9.5 as well, with similar performance to Firefox 3.0. It doesn't work in Safari 3.1. IE (even IE8 beta) doesn't support canvas and has very bad JavaScript performance in general so there's no chance it can work within a few years. Boo, Microsoft.

Thursday, August 21, 2008

Watch out for when your iPhone 3G refuses to receive calls

I went out to Hang Hau for breakfast today, with my iPhone in my pocket. When I got back home, my mom asked me why I didn't answer her phone calls.

Hmm... maybe it's because I didn't take my headphones with me this morning? The ringtone is quite hard to hear in all the traffic noise you know. But as soon as my mom did a test call to my phone, I knew the problem is with the phone.

The phone never rang.

The phone was turned on and I could run apps and go online via wifi perfectly in it. There're 2 bars of signal from 3's service. But the phone part of it was like.. disabled! I couldn't call it from landline or from other mobile phones, and it couldn't call out. Worse, while the iPhone was on but not accepting any calls, the caller wasn't able to leave voice messages either. For a moment I was suspecting it was 3's problem. But the phone worked correctly after I rebooted it. So there must be some problem with my iPhone that prevented it from receiving calls and calling out.

The mobile phone part of the iPhone can crash silently. That's a big problem. I don't care too much if SFNetNews or Bloomberg crashes - though I would really appreciate it if Apple can stop them from crashing; But why can I miss calls with my phone turned on, connected with cell towers?

I tried to replicate the problem by killing the MobilePhone app in my iPhone and calling in, after the reboot. I could still hear the ringtone and answer the call, however. Something much more complicated than just an app crash must have happened this morning. Not enough memory left for the incoming call?

Wednesday, August 13, 2008

A taste of what's coming in CKEditor 3.0

CKEditor 3.0 will be a major rewrite to the very successful FCKeditor 2.6.x series. Currently it is still in the prototypal stage (read: most of the features are not done) but it's already showing some amazing functionalities.

e.g. This (sorry about the video artifacts):


You can view the screencast in its full resolution here.

It is not impossible with FCKeditor 2.6.x right now or other RTE libraries out there at the moment. But very little JavaScript trickery is needed to make it work with CKEditor 3.0, and the switching speed is very fast. Imagine a Wiki with that.

Things the iPhone 3G technical specs don't tell you...

You can get that by jailbreaking your iPhone and run sysctl -a in the terminal.

Here is what I have on my iPhone 3G. with 2.0.1 firmware:

kern.ostype = Darwin
kern.osrelease = 9.3.1
kern.osrevision = 199506
kern.version = Darwin Kernel Version 9.3.1: Sun Jun 15 21:37:01 PDT 2008; root:xnu-1228.6.76~45/RELEASE_ARM_S5L8900X
kern.maxvnodes = 640
kern.maxproc = 52
kern.maxfiles = 12288
kern.argmax = 262144
kern.securelevel = 0
kern.hostname = iPhone
kern.hostid = 0
kern.clockrate: hz = 100, tick = 10000, profhz = 100, stathz = 100
kern.posix1version = 200112
kern.ngroups = 16
kern.job_control = 1
kern.saved_ids = 1
kern.boottime = Tue Aug 12 20:13:51 2008

kern.nisdomainname =
kern.maxfilesperproc = 10240
kern.maxprocperuid = 26
kern.dummy = 0
kern.dummy = 0
kern.usrstack = 805306368
kern.dummy = 0
kern.dummy = 0
kern.dummy = 0
kern.exec: unknown type returned
kern.aiomax = 10
kern.aioprocmax = 4
kern.aiothreads = 2
kern.corefile = /cores/core.%P
kern.delayterm = 0
kern.shreg_private = 0
kern.proc_low_pri_io = 0
kern.usrstack64 = 8247063986311266304
kern.procname =
kern.speculative_reads_disabled = 0
kern.osversion = 5B108
kern.safeboot = 0
kern.rage_vnode = 0
vfs.hfs has 2 mounted instances
vfs.devfs has 1 mounted instance
hw.machine = iPhone1,2
hw.model = N82AP
hw.ncpu = 1
hw.byteorder = 1234
hw.physmem = 121634816
hw.usermem = 96317440
hw.pagesize = 4096
hw.epoch = 1
hw.vectorunit = 0
hw.busfrequency = 103000000
hw.cpufrequency = 412000000
hw.cachelinesize = 32
hw.l1icachesize = 16384
hw.l1dcachesize = 16384
hw.tbfrequency = 6000000
hw.memsize = 121634816
hw.availcpu = 1
user.cs_path = /usr/bin:/bin:/usr/sbin:/sbin
user.bc_base_max = 99
user.bc_dim_max = 2048
user.bc_scale_max = 99
user.bc_string_max = 1000
user.coll_weights_max = 2
user.expr_nest_max = 32
user.line_max = 2048
user.re_dup_max = 255
user.posix2_version = 200112
user.posix2_c_bind = 0
user.posix2_c_dev = 0
user.posix2_char_term = 0
user.posix2_fort_dev = 0
user.posix2_fort_run = 0
user.posix2_localedef = 0
user.posix2_sw_dev = 0
user.posix2_upe = 0
user.stream_max = 20
user.tzname_max = 255
kern.ostype: Darwin
kern.osrelease: 9.3.1
kern.osrevision: 199506
kern.version: Darwin Kernel Version 9.3.1: Sun Jun 15 21:37:01 PDT 2008; root:xnu-1228.6.76~45/RELEASE_ARM_S5L8900X
kern.maxvnodes: 640
kern.maxproc: 52
kern.maxfiles: 12288
kern.argmax: 262144
kern.securelevel: 0
kern.hostname: iPhone
kern.hostid: 0
kern.clockrate: { hz = 100, tick = 10000, tickadj = -1072645529, profhz = 100, stathz = 100 }
kern.posix1version: 200112
kern.ngroups: 16
kern.job_control: 1
kern.saved_ids: 1
kern.boottime: { sec = 1218543231, usec = 0 } Tue Aug 12 20:13:51 2008
kern.nisdomainname:
kern.maxfilesperproc: 10240
kern.maxprocperuid: 26
kern.ipc.maxsockbuf: 8388608
kern.ipc.sockbuf_waste_factor: 8
kern.ipc.somaxconn: 128
kern.ipc.nmbclusters: 3486
kern.ipc.soqlimitcompat: 1
kern.ipc.mb_normalized: 0
kern.ipc.sosendjcl_ignore_capab: 0
kern.ipc.sosendjcl: 1
kern.ipc.sorecvmincopy: 16384
kern.ipc.sosendminchain: 16384
kern.ipc.soqlencomp: 0
kern.ipc.njclbytes: 0
kern.ipc.njcl: 0
kern.ipc.sbspace_factor: 8
kern.ipc.maxsockets: 128
kern.dummy: 0
kern.usrstack: 805306368
kern.aiomax: 10
kern.aioprocmax: 4
kern.aiothreads: 2
kern.corefile: /cores/core.%P
kern.delayterm: 0
kern.shreg_private: 0
kern.proc_low_pri_io: 0
kern.posix.sem.max: 10000
kern.usrstack64:
kern.tfp.policy: 2
kern.procname:
kern.speculative_reads_disabled: 0
kern.osversion: 5B108
kern.safeboot: 0
kern.lctx.max: 8192
kern.lctx.count: 0
kern.lctx.last: 1
kern.rage_vnode: 0
kern.tty.ptmx_max: 127
kern.sleeptime: { sec = 1218607962, usec = 525806 } Wed Aug 13 14:12:42 2008
kern.waketime: { sec = 1218608306, usec = 11 } Wed Aug 13 14:18:26 2008
kern.hibernatefile:
kern.bootsignature:
kern.hibernatemode: 0
kern.monotonicclock: 1218648807
kern.maxnbuf: 558
kern.nbuf: 558
kern.flush_cache_on_write: 0
kern.always_do_fullfsync: 0
kern.sugid_scripts: 0
kern.affinity_sets_mapping: 1
kern.affinity_sets_enabled: 1
kern.singleuser: 0
kern.bootargs:
kern.memorystatus_kev_failure_count: 0
kern.memorystatus_level: 50
kern.msgbuf: 4096
kern.wq_timer_interval_msecs: 40
kern.wq_max_run_latency_usecs: 500
kern.wq_reduce_pool_window_usecs: 3000000
kern.wq_stalled_window_usecs: 20000
kern.secure_kernel: 1
kern.wakereason: usb
vm.loadavg: { 0.00 0.29 0.39 }
vm.swapusage: total = 0.00M used = 0.00M free = 0.00M
vm.cs_debug: 0
vm.cs_force_hard: 0
vm.cs_force_kill: 0
vm.user_wire_limit: -2302491336873346024
vm.global_user_wire_limit: -4602390231608460264
vm.cs_blob_size_max: 38768
vm.cs_blob_size_peak: 419168
vm.cs_blob_count_peak: 172
vm.cs_blob_size: 411472
vm.cs_blob_count: 164
vm.cs_validation: 1
vm.vm_page_free_target: 374
vm.shared_region_persistence: 1
vm.shared_region_version: 3
vm.shared_region_trace_level: 1
net.local.stream.recvspace: 8192
net.local.stream.sendspace: 8192
net.local.dgram.recvspace: 4096
net.local.dgram.maxdgram: 2048
net.local.inflight: 0
net.inet.ip.portrange.hilast: 65535
net.inet.ip.portrange.hifirst: 49152
net.inet.ip.portrange.last: 65535
net.inet.ip.portrange.first: 49152
net.inet.ip.portrange.lowlast: 600
net.inet.ip.portrange.lowfirst: 1023
net.inet.ip.forwarding: 0
net.inet.ip.redirect: 1
net.inet.ip.ttl: 64
net.inet.ip.rtexpire: 2400
net.inet.ip.rtminexpire: 10
net.inet.ip.rtmaxcache: 128
net.inet.ip.sourceroute: 0
net.inet.ip.intr_queue_maxlen: 50
net.inet.ip.intr_queue_drops: 0
net.inet.ip.accept_sourceroute: 0
net.inet.ip.fastforwarding: 0
net.inet.ip.keepfaith: 0
net.inet.ip.subnets_are_local: 0
net.inet.ip.use_route_genid: 1
net.inet.ip.check_route_selfref: 1
net.inet.ip.linklocal.in.allowbadttl: 1
net.inet.ip.check_interface: 0
net.inet.ip.maxfrags: 216
net.inet.ip.maxfragsperpacket: 128
net.inet.ip.maxfragpackets: 108
net.inet.ip.maxchainsent: 8
net.inet.icmp.maskrepl: 0
net.inet.icmp.icmplim: 250
net.inet.icmp.timestamp: 0
net.inet.icmp.bmcastecho: 1
net.inet.icmp.log_redirect: 0
net.inet.icmp.drop_redirect: 0
net.inet.tcp.rfc1323: 1
net.inet.tcp.rfc1644: 0
net.inet.tcp.mssdflt: 512
net.inet.tcp.keepidle: 7200000
net.inet.tcp.keepintvl: 75000
net.inet.tcp.sendspace: 131072
net.inet.tcp.recvspace: 131072
net.inet.tcp.keepinit: 75000
net.inet.tcp.rexmt_thresh: 2
net.inet.tcp.rfc3465: 1
net.inet.tcp.maxseg_unacked: 8
net.inet.tcp.slowlink_wsize: 8192
net.inet.tcp.reass.overflows: 0
net.inet.tcp.reass.cursegments: 0
net.inet.tcp.reass.maxsegments: 217
net.inet.tcp.drop_synfin: 1
net.inet.tcp.tcp_lq_overflow: 1
net.inet.tcp.delayed_ack: 3
net.inet.tcp.blackhole: 0
net.inet.tcp.log_in_vain: 0
net.inet.tcp.socket_unlocked_on_output: 1
net.inet.tcp.packetchain: 50
net.inet.tcp.ecn_negotiate_in: 0
net.inet.tcp.ecn_initiate_out: 0
net.inet.tcp.newreno: 0
net.inet.tcp.local_slowstart_flightsize: 8
net.inet.tcp.slowstart_flightsize: 1
net.inet.tcp.path_mtu_discovery: 1
net.inet.tcp.sack_globalholes: 0
net.inet.tcp.sack_globalmaxholes: 65536
net.inet.tcp.sack_maxholes: 128
net.inet.tcp.sack: 1
net.inet.tcp.rtt_min: 1
net.inet.tcp.background_io_enabled: 1
net.inet.tcp.isn_reseed_interval: 0
net.inet.tcp.strict_rfc1948: 0
net.inet.tcp.icmp_may_rst: 1
net.inet.tcp.pcbcount: 8
net.inet.tcp.do_tcpdrain: 0
net.inet.tcp.tcbhashsize: 128
net.inet.tcp.minmssoverload: 0
net.inet.tcp.minmss: 216
net.inet.tcp.always_keepalive: 0
net.inet.tcp.msl: 15000
net.inet.tcp.background_io_trigger: 5
net.inet.tcp.sockthreshold: 0
net.inet.tcp.out_sw_cksum_bytes: 2439757
net.inet.tcp.out_sw_cksum: 32018
net.inet.tcp.in_sw_cksum_bytes: 46445398
net.inet.tcp.in_sw_cksum: 41658
net.inet.tcp.win_scale_factor: 3
net.inet.udp.checksum: 1
net.inet.udp.maxdgram: 9216
net.inet.udp.recvspace: 41600
net.inet.udp.pcbcount: 5
net.inet.udp.blackhole: 0
net.inet.udp.log_in_vain: 0
net.inet.udp.out_sw_cksum_bytes: 264471
net.inet.udp.out_sw_cksum: 3750
net.inet.udp.in_sw_cksum_bytes: 376819
net.inet.udp.in_sw_cksum: 3501
net.inet.ipsec.def_policy: 1
net.inet.ipsec.esp_trans_deflev: 1
net.inet.ipsec.esp_net_deflev: 1
net.inet.ipsec.ah_trans_deflev: 1
net.inet.ipsec.ah_net_deflev: 1
net.inet.ipsec.ah_cleartos: 1
net.inet.ipsec.ah_offsetmask: 0
net.inet.ipsec.dfbit: 0
net.inet.ipsec.ecn: 0
net.inet.ipsec.debug: 0
net.inet.ipsec.esp_randpad: -1
net.inet.ipsec.esp_port: 0
net.inet.ipsec.bypass: 1
net.inet.raw.recvspace: 8192
net.inet.raw.maxdgram: 8192
net.link.ether.inet.send_conflicting_probes: 1
net.link.ether.inet.keep_announcements: 1
net.link.ether.inet.log_arp_warnings: 0
net.link.ether.inet.sendllconflict: 0
net.link.ether.inet.proxyall: 0
net.link.ether.inet.useloopback: 1
net.link.ether.inet.maxtries: 5
net.link.ether.inet.apple_hwcksum_rx: 1
net.link.ether.inet.apple_hwcksum_tx: 1
net.link.ether.inet.host_down_time: 20
net.link.ether.inet.max_age: 1200
net.link.ether.inet.prune_intvl: 300
net.key.debug: 0
net.key.spi_trycnt: 1000
net.key.spi_minval: 256
net.key.spi_maxval: 268435455
net.key.int_random: 60
net.key.larval_lifetime: 30
net.key.blockacq_count: 10
net.key.blockacq_lifetime: 20
net.key.esp_keymin: 256
net.key.esp_auth: 0
net.key.ah_keymin: 128
net.key.prefered_oldsa: 0
net.key.natt_keepalive_interval: 20
debug.wdtlog: 2114u0 2114u0 2100m0 2000m0 1914u0 1914u0 1914u0 1914u0 1900m0 1800m0 1714u0 1714u0 1714u0 1714u0 1700m0 1600m0 1514u0 1514u0 1514u0 1514u0 1500m0 1400m0 1314u0 1314u0 1314u0 1314u0 1300m0 1200m0 1110u0 1110u0 1110u0 1110u0 1100m0 1000m0 909u0 909u0 909u0 909u0 900m0 800m0 709u0 709u0 709u0 709u0 700m0 600m0 507u0 507u0 507u0 507u0 500m0 400m0 307u0 307u0 307u0 307u0 300m0 200m0 107u0 107u0 107u0 107u0 100m0 0m0
debug.marvel_debug: 136 136
debug.lowpri_max_waiting_msecs: 200
debug.lowpri_max_window_msecs: 200
debug.lowpri_IO_window_inc: 50
debug.lowpri_IO_initial_window_msecs: 100
debug.bpf_maxdevices: 256
debug.bpf_maxbufsize: 524288
debug.bpf_bufsize: 4096
debug.iokit: 0
hw.ncpu: 1
hw.byteorder: 1234
hw.memsize: 121634816
hw.activecpu: 1
hw.optional.floatingpoint: 1
hw.packages: 1
hw.tbfrequency: 6000000
hw.fixfrequency: 24000000
hw.prffrequency_max: 51500000
hw.prffrequency_min: 51500000
hw.prffrequency: 51500000
hw.memfrequency_max: 137333333
hw.memfrequency_min: 137333333
hw.memfrequency: 137333333
hw.l1dcachesize: 16384
hw.l1icachesize: 16384
hw.cachelinesize: 32
hw.cpufrequency_max: 412000000
hw.cpufrequency_min: 412000000
hw.cpufrequency: 412000000
hw.busfrequency_max: 103000000
hw.busfrequency_min: 103000000
hw.busfrequency: 103000000
hw.pagesize: 4096
hw.cachesize: 0 0 0 0 0 0 0 0 0 0
hw.cacheconfig: 0 16384 16384 1 32 4 0 0 0 0
hw.cpufamily: -1879695144
hw.cpu64bit_capable: 0
hw.cpusubtype: 6
hw.cputype: 12
hw.logicalcpu_max: 1
hw.logicalcpu: 1
hw.physicalcpu_max: 1
hw.physicalcpu: 1
machdep.alignmenttrap: 0
security.mac.seatbelt.debug: 0
security.mac.seatbelt.profile_refcount: 15
security.mac.seatbelt.qtnstate_refcount: 0
security.mac.seatbelt.cred_label_refcount: 5
security.mac.seatbelt.disable_builtins: 0
security.mac.vnode_enforce: 1
security.mac.vm_enforce: 1
security.mac.sysvshm_enforce: 1
security.mac.sysvsem_enforce: 1
security.mac.sysvmsg_enforce: 1
security.mac.system_enforce: 1
security.mac.socket_enforce: 1
security.mac.proc_enforce: 1
security.mac.posixshm_enforce: 1
security.mac.posixsem_enforce: 1
security.mac.pipe_enforce: 1
security.mac.iokit_enforce: 0
security.mac.file_enforce: 0
security.mac.device_enforce: 1
security.mac.mmap_revocation_via_cow: 0
security.mac.mmap_revocation: 0
security.mac.max_slots: 8


Interesting bits:
  1. The CPU has a maximum frequency of 412MHz, but I don't know whether it scales down its running frequency in power saving mode or not. Outside info says it's running at 620MHz.
  2. The CPU comes with 32KB of L1 cache, 16KB for data and 16KB for instructions. There's no sign of any L2 cache.
  3. Apple has chosen to run the ARM CPU in little endian mode.
  4. The CPU comes with an FPU as well.
  5. The CPU chip seems to be something called S5L8900(X?) from Samsung. Samsung's datasheet says it's an ARM CPU with built-in PowerVR MBX 3D graphics.
  6. The usable memory size is exactly 116MB. DRAM chips don't come in non-round numbers, the closest guess to the total physical DRAM size would be 128MB. So, 12MB is gone for other uses... graphics?
  7. It doesn't seem to use any swap memory at all. So if the 116MB runs out, your apps would surely crash.
  8. There're a few hw.memfrequency entries in the iPhone's sysctl listing which do not exist in Macintosh computers. It seems to indicate the iPhone's memory is running at roughtly 137MHz, I wonder if there's any DDR trickery involved.
  9. There's a "net.inet.ip.forwarding" entry which is set to 0 by default but it can be set to 1. In Linux that is the first step in making an NAT router.

Saturday, June 21, 2008

How to properly fix the Mac OS X ARDagent security hole

Slashdot posted about a root privilege escalation bug in Mac OS X a few days ago. It made quite a big fuzz among Apple users because Mac OS X, which is more UNIX than Linux; which is created, coded and certified by the infallible bearded UNIX wizards; must be... eh... infallibly secure! This seems to be not the case now, as any would-be OSX virus writer could just use this hole to gain root privileges in their creations without the user noticing.

Many blogs have posted about temporary fixes to the situation, but many of their fixes brings with problems on their own. Here're some of those half-working fixes I've seen:
  1. Remove the setuid bit in the ARDAgent executable.
    This approach actually makes a lot of sense if all you need to tackle is the security hole itself. But it breaks the Apple Remote Management service so if you try to remotely control your Mac with Apple's Remote Desktop software (you need to buy it from Apple), it will no longer work.
  2. Start up the Apple Remote Management service.
    Amazingly, actually starting up the Apple Remote Management service - the very thing that caused the security hole - seems to close the security hole! Running the dreaded exploit script osascript -e 'tell app "ARDagent" to do shell script "whoami"'after starting up ARM would give you an error message instead of the "root" message. But does this "put out fire with fire" approach make you nervous? What if it goes wrong?

    To see what happens if it goes wrong, just restart the ARM service in System Preferences, and try the exploit script again. You've been rooted! So this method does not actually work.

A better fix to the issue would be one that does not break Apple Remote Desktop, while actually preventing Apple Script from rooting your machine at the same time no matter whether the Apple Remote Management service is on or not. And here's how:
  1. Edit the file /System/Library/CoreServices/RemoteManagement/ARDAgent.app/Contents/Info.plist as root.
  2. Add the following two lines just before </dict>:
    <key>NSAppleScriptEnabled</key>
    <string>YES</string>

  3. Save it.
  4. Start and stop (or stop and start) Apple Remote Management service.
Now try the exploit script again, you should get:
23:47: execution error: ARDAgent got an error: "whoami" doesn’t understand the do shell script message. (-1708)

No matter whether ARM is started or not.

Saturday, May 17, 2008

More devils in the details

The lights.

Apparently the owner of the house thought he should live like a rich and so he installed a roof lamp with those artsy lamp shades in the living room. It looks nice but those artsy glassy lamp shades decrease the energy efficiency of the lamp dramatically. The lamp has six light bulbs, each rated at 60W (so it's a f**king 360W!), but the living room still looked dark at night. This must be one of the most ridiculous things I've seen - you use 360W and you still can't light up a <150 sq. ft. living room properly.


So I bought a floor lamp from Hung Hom, with energy-saving fluorescent bulbs. Another $600+ spent. Moving it from Hung Hom to Tai Po Tsai was NOT fun.

The new flat itself, and the little details...

The new flat is small but nice, really nice, almost too nice for its lowly monthly rent. It is visible from the drive to HKUST, one of those houses in the first row in the photo below.


The flat itself is in the back of the house so I don't get a view to Flower and Food BBQ directly out of the window. But that's simply too much to ask for with the cheap price I'm paying.

They say the devil is in the details, but for such a house I'm quite happy to deal with the details. There are a lot of such "details"...

First, the TV reception is poor.


TVB Jade is the best channel I can get here, and still the picture is not so clear. I've tried to improve the reception by buying a signal amplifier ($500) but that didn't seem to help. The TV antenna socket does not work, I only had a bare antenna cable from the window to work with, and I had to install the plug myself.


The amplifier didn't seem to work, unfortunately. It is now suspected that the antenna cable itself is broken and so I had to buy a new antenna cable from Sham Shui Po today ($900!). I've never imagined 20m of coaxial cable costs that much...

I've also noticed that Wing Shing (one of those electronics shops in SSP Ap Liu Street) lied about the signal amplifier in their receipt - the signal amplifier only has a gain of 21dB, but the receipt says it's 29dB.

The second to fourth days of moving...


I connected the ADSL modem to the telephone jack in the second day I moved in, but there was simply no signal. So for a few days I had to go to HKUST for Internet access.




While I was back home without Internet access in the few days, I tried to do some experiments with the iPhone SDK from Apple. Since I don't have an iPhone but I want to develop web applications that can be used in iPhone, I'm very interested in the Safari browser inside Apple's iPhone simulator. So I downloaded Apple's "Getting Started" videos along with the iPhone SDK while I had Internet access in HKUST.

A little JavaScript code thrown into the iPhone simulator reveals that it is actually using the Safari browser in my MacBook Pro, so it's not a separate Safari installation. This is a little bit discomforting... Would everything running ok in the simulator's Safari browser run in an actual iPhone as well?



This is where I got my Internet access in the first few days. I was usually sitting in the Library, in the Cafe or in the new wing area of HKUST (in photo). I was actually a little bit worried when I left my MBP alone while getting off for a drink or for the toilet; but then, I've done that for 3 years and my notebook never got stolen. HKUST is an incredibly nice place by the way, I would have studied my Master's here right after the Bachelor's degree if I could, but I have a family to feed. Even scholarships plus a TA job won't be enough for my family's expenditures. Being a poor man in a rich city sucks a lot.

Strangely, in the few days I sat in UST for Internet access, I've only met one familiar person. I thought I could ask some of my previous schoolmates who're taking Master's now for a lunch in those few days.

Tuesday, May 13, 2008

Things to write about in the coming days.

I have the memory of a goldfish - I forget things soon after they're spoken to me, which is why I rely on emails and IM/IRC chat logs a lot. So I'd also need a note about what to write here in the days when I have less things to do.

  1. The progress of moving.
  2. New features and important bugfixes in FCKeditor 2.5, 2.6 and the up-and-coming 2.6.1.
  3. Recent developments in the web app field:
    1. CSS transitions and animations - no JavaScript needed
    2. Client-side storage via SQL in JavaScript
    3. JavaScript dynamic linking
    4. DOM selectors and their relative performance
    5. The astute reader might have noticed some the above topics are related to HTML5
  4. Some highly aggravating IE bugs I met during FCKeditor development:
    1. Selections and non-standard-conforming ranges in IE
    2. Memory leaks - this is an old topic, but there are more leaks beyond circular references
    3. Why you should never use Microsoft-specific functions in IE - the horrible bugs and ridiculous workarounds with window.createPopup().
  5. Startup ideas (??)

First day in the new flat - continued


Without an internet connection in the new home, I can't really be spraying bugs in FCKeditor. So what's left for me to do (except moving stuff around)? How many bits are needed to perfectly encode every possible key that can be made form the key mold that this key came from?

The first day in the new flat


10th of May

The first things I moved to the new flat were my computers (there are four of them) and all my computer-related equipments, and a bed roll. That was a hell lot of equipments to move around, and my arms are still aching right now.

The new flat wouldn't have Internet connection until the 15th of May though, so all I could do with the desktops was playing games. The notebooks are much more useful now, because I can bring them to the university and go online via wifi.

There's no computer desk in the new flat, yet. So my computers are all sitting on the floor near my bedroll.

Long time no blog - moving home

It's been quite a while since the last time I wrote anything here. I've always been wanting to write about new features in FCKeditor and those pesky IE bugs but I never got the time nor the will to actually write a post for that. But now I'm on my long annual leave from the FCKeditor project, and I'm also moving to a new home. So I figured it's a good time to take up blogging again while I have nothing to do.

I've been moving home from To Kwa Wan (a poor, dirty urban district in Hong Kong) to Tai Po Tsai (a suburban village near HKUST) since the 10th of May. I moved to the To Kwa Wan flat this time last year because of the ridiculously cheap rent ($2.8k/mo), and that I wanted to save money for the future. I have to rent private flats because I'm not eligible for public housing or even semi-public housing in Hong Kong, because the government thinks I'm a "middle class"... But come on, how can someone without his own house and his own car be a middle classman?! Stupid policies... There's no wonder why Hong Kong is getting near (or is it above now?) places like Brazil in income inequality and having more than a million living in poverty these days with a government like this one.

Anyway... back to the topic. The old flat in To Kwa Wan was butt ugly. I can't regret my "save money" decision more. For HK$2.8k/month I got a tiny studio flat in a slum area to live in. I thought it was ok as long as the inside of the flat is clean but I was wrong... The nasty shitty smells from the street outside the windows and from the corridor outside the door constantly invaded the place; every corner of the corridor is filled with spiders; the staircases to the outside are often filled with the smell of urine... If you want to experience the lives of the ultra poor in Hong Kong, that is the place you want to go to, and after that you won't be able to comprehend why Hong Kong can be regarded as a first-world place, at all. The only thing worse than that is living under a bridge. Why is the government not giving me public housing... again? I'm not poor enough?

Ok, so I got fed up with that shitty (in a literal way) flat, and decided to move to somewhere clean, with sunlight and fresh air. I still need to save money up so I can't be renting those $10k+/month sea view flats even though I can afford to... So I have to look into the suburban area. And there's just one such village (the Tai Po Tsai village) just outside my previous place of study, how convenient. The new flat is a little bit larger than 300 sq. ft. - not large by any measure, but enough for me and my mom. Right outside the door is a row of tropical trees, a grass field and a BBQ place (Flower and Food BBQ) still further. A huge improvement to the dark corridor filled with sewage and spider webs that was in To Kwa Wan. If there's a smell in the new flat, it's the faint smell of barbecued food, which is quite pleasant actually.

I started moving to the new home at the 10th of May, and as of today the furniture and the broadband connection aren't moved to the new flat yet - so I'm now having to go online with the free wifi offered by HKUST - just next doors. That's still not bad.